freedreno/a3xx: enable/disable wa's based on patch-level
authorRob Clark <robclark@freedesktop.org>
Wed, 18 Jun 2014 14:24:04 +0000 (10:24 -0400)
committerRob Clark <robclark@freedesktop.org>
Fri, 25 Jul 2014 17:29:28 +0000 (13:29 -0400)
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 <robclark@freedesktop.org>
configure.ac
src/gallium/drivers/freedreno/a3xx/fd3_emit.c
src/gallium/drivers/freedreno/freedreno_draw.h
src/gallium/drivers/freedreno/freedreno_screen.c
src/gallium/drivers/freedreno/freedreno_screen.h

index 744e55ce316e9b4f0b8d773593c21968a2ef16cf..d06730d3410375c09ff7bad5ee6a4b15803bb62c 100644 (file)
@@ -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
index 6bbd9bf63309bd92eb0a6964cab4dd33778085a7..1e4de26406a8425bd068c2ed4e6f706370652231 100644 (file)
@@ -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);
index fe1c548b12efa5a12c00a91d5f453fdecac3e477..2a4fe06e3004c7d5f2c41608a726518f4e0b3ed9 100644 (file)
@@ -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);
index c574cb81f6aba076c1ac482626edfedb8066fb53..d4a928a7c1a2d052a3430966d42a41fcfaacb9bf 100644 (file)
@@ -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
index 93501e722f4572b8129d42aba47f82318f277dcf..e0377b561a9230e1b9bd41370e4e64998cc45971 100644 (file)
@@ -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_ */