From d48faad3c2d7efb7f4bf727b63487071c4a75e7a Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 18 Jun 2014 10:24:04 -0400 Subject: [PATCH] freedreno/a3xx: enable/disable wa's based on patch-level It seems like for the most part, different behaviors, workarounds, etc, should be conditional on GPU patch revision (ie. a320.0 vs a320.2) rather than GPU id (a320 vs a330). Signed-off-by: Rob Clark --- configure.ac | 2 +- src/gallium/drivers/freedreno/a3xx/fd3_emit.c | 13 +++++++------ src/gallium/drivers/freedreno/freedreno_draw.h | 2 +- .../drivers/freedreno/freedreno_screen.c | 17 +++++++++++++++++ .../drivers/freedreno/freedreno_screen.h | 10 +++++++++- 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 744e55ce316..d06730d3410 100644 --- a/configure.ac +++ b/configure.ac @@ -32,7 +32,7 @@ LIBDRM_RADEON_REQUIRED=2.4.54 LIBDRM_INTEL_REQUIRED=2.4.52 LIBDRM_NVVIEUX_REQUIRED=2.4.33 LIBDRM_NOUVEAU_REQUIRED="2.4.33 libdrm >= 2.4.41" -LIBDRM_FREEDRENO_REQUIRED=2.4.51 +LIBDRM_FREEDRENO_REQUIRED=2.4.55 DRI2PROTO_REQUIRED=2.6 DRI3PROTO_REQUIRED=1.0 PRESENTPROTO_REQUIRED=1.0 diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c index 6bbd9bf6330..1e4de26406a 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c @@ -681,12 +681,13 @@ fd3_emit_restore(struct fd_context *ctx) fd_event_write(ctx, ring, CACHE_FLUSH); - /* probably only really needed on a320: */ - OUT_PKT3(ring, CP_DRAW_INDX, 3); - OUT_RING(ring, 0x00000000); - OUT_RING(ring, DRAW(1, DI_SRC_SEL_AUTO_INDEX, - INDEX_SIZE_IGN, IGNORE_VISIBILITY)); - OUT_RING(ring, 0); /* NumIndices */ + if (is_a3xx_p0(ctx->screen)) { + OUT_PKT3(ring, CP_DRAW_INDX, 3); + OUT_RING(ring, 0x00000000); + OUT_RING(ring, DRAW(1, DI_SRC_SEL_AUTO_INDEX, + INDEX_SIZE_IGN, IGNORE_VISIBILITY)); + OUT_RING(ring, 0); /* NumIndices */ + } OUT_PKT3(ring, CP_NOP, 4); OUT_RING(ring, 0x00000000); diff --git a/src/gallium/drivers/freedreno/freedreno_draw.h b/src/gallium/drivers/freedreno/freedreno_draw.h index fe1c548b12e..2a4fe06e300 100644 --- a/src/gallium/drivers/freedreno/freedreno_draw.h +++ b/src/gallium/drivers/freedreno/freedreno_draw.h @@ -61,7 +61,7 @@ fd_draw(struct fd_context *ctx, struct fd_ringbuffer *ring, */ emit_marker(ring, 7); - if (ctx->screen->gpu_id == 320) { + if (is_a3xx_p0(ctx->screen)) { /* dummy-draw workaround: */ OUT_PKT3(ring, CP_DRAW_INDX, 3); OUT_RING(ring, 0x00000000); diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index c574cb81f6a..d4a928a7c1a 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -451,6 +451,23 @@ fd_screen_create(struct fd_device *dev) } screen->gpu_id = val; + if (fd_pipe_get_param(screen->pipe, FD_CHIP_ID, &val)) { + DBG("could not get chip-id"); + /* older kernels may not have this property: */ + unsigned core = screen->gpu_id / 100; + unsigned major = (screen->gpu_id % 100) / 10; + unsigned minor = screen->gpu_id % 10; + unsigned patch = 0; /* assume the worst */ + val = (patch & 0xff) | ((minor & 0xff) << 8) | + ((major & 0xff) << 16) | ((core & 0xff) << 24); + } + screen->chip_id = val; + + DBG("Pipe Info:"); + DBG(" GPU-id: %d", screen->gpu_id); + DBG(" Chip-id: 0x%08x", screen->chip_id); + DBG(" GMEM size: 0x%08x", screen->gmemsize_bytes); + /* explicitly checking for GPU revisions that are known to work. This * may be overly conservative for a3xx, where spoofing the gpu_id with * the blob driver seems to generate identical cmdstream dumps. But diff --git a/src/gallium/drivers/freedreno/freedreno_screen.h b/src/gallium/drivers/freedreno/freedreno_screen.h index 93501e722f4..e0377b561a9 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.h +++ b/src/gallium/drivers/freedreno/freedreno_screen.h @@ -44,7 +44,8 @@ struct fd_screen { uint32_t gmemsize_bytes; uint32_t device_id; - uint32_t gpu_id; + uint32_t gpu_id; /* 220, 305, etc */ + uint32_t chip_id; /* coreid:8 majorrev:8 minorrev:8 patch:8 */ struct fd_device *dev; struct fd_pipe *pipe; @@ -68,4 +69,11 @@ struct fd_bo * fd_screen_bo_from_handle(struct pipe_screen *pscreen, struct pipe_screen * fd_screen_create(struct fd_device *dev); +/* is a3xx patch revision 0? */ +static inline boolean +is_a3xx_p0(struct fd_screen *screen) +{ + return (screen->gpu_id & 0xff0000ff) == 0x0300000000; +} + #endif /* FREEDRENO_SCREEN_H_ */ -- 2.30.2