freedreno: 64bit support

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>
main
Rob Clark 2016-11-09 09:02:09 -05:00
parent d15515aea3
commit 23d10b8244
7 changed files with 49 additions and 4 deletions

View File

@ -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

View 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)

View 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;
};

View File

@ -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);

View 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);

View 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",

View 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,