OSDN Git Service

freedreno: 64bit support
authorRob Clark <robclark@freedesktop.org>
Wed, 9 Nov 2016 14:02:09 +0000 (09:02 -0500)
committerRob Clark <robclark@freedesktop.org>
Sat, 26 Nov 2016 17:51:38 +0000 (12:51 -0500)
a5xx and later are 64bit devices.. make reloc's handle that.  A new
public symbol is introduced to avoid silent problems with new mesa and
old libdrm (since on 64b reloc consumes two dwords).

Signed-off-by: Rob Clark <robclark@freedesktop.org>
freedreno/freedreno-symbol-check
freedreno/freedreno_pipe.c
freedreno/freedreno_priv.h
freedreno/freedreno_ringbuffer.c
freedreno/freedreno_ringbuffer.h
freedreno/kgsl/kgsl_pipe.c
freedreno/msm/msm_ringbuffer.c

index ad367fc..42f2c43 100755 (executable)
@@ -43,6 +43,7 @@ fd_ringbuffer_flush
 fd_ringbuffer_grow
 fd_ringbuffer_new
 fd_ringbuffer_reloc
+fd_ringbuffer_reloc2
 fd_ringbuffer_reset
 fd_ringbuffer_set_parent
 fd_ringbuffer_timestamp
index 4a756d7..3f8c834 100644 (file)
@@ -37,6 +37,7 @@ struct fd_pipe *
 fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id)
 {
        struct fd_pipe *pipe = NULL;
+       uint64_t val;
 
        if (id > FD_PIPE_MAX) {
                ERROR_MSG("invalid pipe id: %d", id);
@@ -52,6 +53,9 @@ fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id)
        pipe->dev = dev;
        pipe->id = id;
 
+       fd_pipe_get_param(pipe, FD_GPU_ID, &val);
+       pipe->gpu_id = val;
+
        return pipe;
 fail:
        if (pipe)
index 86da83b..3217039 100644 (file)
@@ -123,6 +123,7 @@ struct fd_pipe_funcs {
 struct fd_pipe {
        struct fd_device *dev;
        enum fd_pipe_id id;
+       uint32_t gpu_id;
        const struct fd_pipe_funcs *funcs;
 };
 
index c132145..7310f1f 100644 (file)
@@ -115,6 +115,13 @@ uint32_t fd_ringbuffer_timestamp(struct fd_ringbuffer *ring)
 void fd_ringbuffer_reloc(struct fd_ringbuffer *ring,
                                    const struct fd_reloc *reloc)
 {
+       assert(ring->pipe->gpu_id < 500);
+       ring->funcs->emit_reloc(ring, reloc);
+}
+
+void fd_ringbuffer_reloc2(struct fd_ringbuffer *ring,
+                                    const struct fd_reloc *reloc)
+{
        ring->funcs->emit_reloc(ring, reloc);
 }
 
@@ -123,6 +130,8 @@ void fd_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,
 {
        uint32_t submit_offset, size;
 
+       /* This function is deprecated and not supported on 64b devices: */
+       assert(ring->pipe->gpu_id < 500);
        assert(target->ring == end->ring);
 
        submit_offset = offset_bytes(target->cur, target->ring->start);
index 108d5a6..c501fba 100644 (file)
@@ -78,9 +78,13 @@ struct fd_reloc {
        uint32_t offset;
        uint32_t or;
        int32_t  shift;
+       uint32_t orhi;      /* used for a5xx+ */
 };
 
-void fd_ringbuffer_reloc(struct fd_ringbuffer *ring, const struct fd_reloc *reloc);
+/* NOTE: relocs are 2 dwords on a5xx+ */
+
+void fd_ringbuffer_reloc2(struct fd_ringbuffer *ring, const struct fd_reloc *reloc);
+will_be_deprecated void fd_ringbuffer_reloc(struct fd_ringbuffer *ring, const struct fd_reloc *reloc);
 will_be_deprecated void fd_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,
                struct fd_ringmarker *target, struct fd_ringmarker *end);
 uint32_t fd_ringbuffer_cmd_count(struct fd_ringbuffer *ring);
index 3546718..8a39eb4 100644 (file)
@@ -255,6 +255,11 @@ drm_private struct fd_pipe * kgsl_pipe_new(struct fd_device *dev,
        GETPROP(fd, VERSION,     kgsl_pipe->version);
        GETPROP(fd, DEVICE_INFO, kgsl_pipe->devinfo);
 
+       if (kgsl_pipe->devinfo.gpu_id >= 500) {
+               ERROR_MSG("64b unsupported with kgsl");
+               goto fail;
+       }
+
        INFO_MSG("Pipe Info:");
        INFO_MSG(" Device:          %s", paths[id]);
        INFO_MSG(" Chip-id:         %d.%d.%d.%d",
index 5117df1..17194f4 100644 (file)
@@ -487,11 +487,32 @@ static void msm_ringbuffer_emit_reloc(struct fd_ringbuffer *ring,
        reloc->submit_offset = offset_bytes(ring->cur, ring->start);
 
        addr = msm_bo->presumed;
-       if (r->shift < 0)
-               addr >>= -r->shift;
+       if (reloc->shift < 0)
+               addr >>= -reloc->shift;
        else
-               addr <<= r->shift;
+               addr <<= reloc->shift;
        (*ring->cur++) = addr | r->or;
+
+       if (ring->pipe->gpu_id >= 500) {
+               struct drm_msm_gem_submit_reloc *reloc_hi;
+
+               idx = APPEND(cmd, relocs);
+
+               reloc_hi = &cmd->relocs[idx];
+
+               reloc_hi->reloc_idx = reloc->reloc_idx;
+               reloc_hi->reloc_offset = r->offset;
+               reloc_hi->or = r->orhi;
+               reloc_hi->shift = r->shift - 32;
+               reloc_hi->submit_offset = offset_bytes(ring->cur, ring->start);
+
+               addr = msm_bo->presumed >> 32;
+               if (reloc_hi->shift < 0)
+                       addr >>= -reloc_hi->shift;
+               else
+                       addr <<= reloc_hi->shift;
+               (*ring->cur++) = addr | r->orhi;
+       }
 }
 
 static uint32_t msm_ringbuffer_emit_reloc_ring(struct fd_ringbuffer *ring,