diff --git a/freedreno/freedreno-symbol-check b/freedreno/freedreno-symbol-check index ad367fc3..42f2c439 100755 --- a/freedreno/freedreno-symbol-check +++ b/freedreno/freedreno-symbol-check @@ -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 diff --git a/freedreno/freedreno_pipe.c b/freedreno/freedreno_pipe.c index 4a756d70..3f8c8342 100644 --- a/freedreno/freedreno_pipe.c +++ b/freedreno/freedreno_pipe.c @@ -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) diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h index 86da83b9..32170391 100644 --- a/freedreno/freedreno_priv.h +++ b/freedreno/freedreno_priv.h @@ -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; }; diff --git a/freedreno/freedreno_ringbuffer.c b/freedreno/freedreno_ringbuffer.c index c132145a..7310f1fd 100644 --- a/freedreno/freedreno_ringbuffer.c +++ b/freedreno/freedreno_ringbuffer.c @@ -114,6 +114,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); diff --git a/freedreno/freedreno_ringbuffer.h b/freedreno/freedreno_ringbuffer.h index 108d5a6d..c501fbad 100644 --- a/freedreno/freedreno_ringbuffer.h +++ b/freedreno/freedreno_ringbuffer.h @@ -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); diff --git a/freedreno/kgsl/kgsl_pipe.c b/freedreno/kgsl/kgsl_pipe.c index 3546718d..8a39eb49 100644 --- a/freedreno/kgsl/kgsl_pipe.c +++ b/freedreno/kgsl/kgsl_pipe.c @@ -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", diff --git a/freedreno/msm/msm_ringbuffer.c b/freedreno/msm/msm_ringbuffer.c index 5117df1a..17194f4c 100644 --- a/freedreno/msm/msm_ringbuffer.c +++ b/freedreno/msm/msm_ringbuffer.c @@ -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,