Mesa (10.2): winsys/radeon: fix nop packet padding for hawaii

Emil Velikov evelikov at kemper.freedesktop.org
Tue Sep 2 19:53:33 UTC 2014


Module: Mesa
Branch: 10.2
Commit: c89719e955f11dd08a110dd768db5bb05a3d4cdd
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=c89719e955f11dd08a110dd768db5bb05a3d4cdd

Author: Andreas Boll <andreas.boll.dev at gmail.com>
Date:   Thu Jul 24 17:30:31 2014 -0400

winsys/radeon: fix nop packet padding for hawaii

// Marek - merged cce58147eb1450a26c03756af37da52d180580c4 into this one

The initial firmware for hawaii does not support type3 nop packet.
Detect the new hawaii firmware with query RADEON_INFO_ACCEL_WORKING2.
If the returned value is 3, then the new firmware is used.

This patch uses type2 for the old firmware and type3 for the new firmware.

It fixes the cases when the old firmware is used and the user wants to
manually enable acceleration.
The two possible scenarios are:
 - the kernel has no support for the new firmware.
 - the kernel has support for the new firmware but only the old firmware
   is available.

Additionaly this patch disables GPU acceleration on hawaii if the kernel
returns a value < 2. In this case the kernel hasn't the required fixes
for proper acceleration.

v2:
 - Fix indentation
 - Use private struct radeon_drm_winsys instead of public struct radeon_info
 - Rename r600_accel_working2 to accel_working2

v3:
 - Use type2 nop packet for returned value < 3

v4:
 - Fail to initialize winsys for returned value < 2

Cc: mesa-stable at lists.freedesktop.org
Cc: Alex Deucher <alexander.deucher at amd.com>
Cc: Jérôme Glisse <jglisse at redhat.com>
Cc: Marek Olšák <marek.olsak at amd.com>
Cc: Michel Dänzer <michel.daenzer at amd.com>
Signed-off-by: Andreas Boll <andreas.boll.dev at gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher at amd.com>
(cherry picked from commit 36771dc60fc3934b326eeff4aa6d3a4d438222eb)

Conflicts:
	src/gallium/winsys/radeon/drm/radeon_drm_winsys.c

Also squashed together with:

winsys/radeon: fix hawaii accel_working2 comment

accel_working2 returns 3 if the new firmware is used.

The comment wasn't updated in v3 of commit:
36771dc winsys/radeon: fix nop packet padding for hawaii

Signed-off-by: Andreas Boll <andreas.boll.dev at gmail.com>
Reviewed-by: Alex Deucher <alexander.deucher at amd.com>
(cherry picked from commit 64c379a3a8e397bf949705efecfc745ec4d7a843)

---

 src/gallium/winsys/radeon/drm/radeon_drm_cs.c     |   62 +++++++++++----------
 src/gallium/winsys/radeon/drm/radeon_drm_winsys.c |   10 ++++
 src/gallium/winsys/radeon/drm/radeon_drm_winsys.h |    1 +
 3 files changed, 44 insertions(+), 29 deletions(-)

diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
index 67375dc..0d22c62 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_cs.c
@@ -155,7 +155,7 @@ static struct radeon_winsys_cs *
 radeon_drm_cs_create(struct radeon_winsys *rws,
                      enum ring_type ring_type,
                      void (*flush)(void *ctx, unsigned flags,
-				   struct pipe_fence_handle **fence),
+                                   struct pipe_fence_handle **fence),
                      void *flush_ctx,
                      struct radeon_winsys_cs_handle *trace_buf)
 {
@@ -196,10 +196,10 @@ radeon_drm_cs_create(struct radeon_winsys *rws,
 #define OUT_CS(cs, value) (cs)->buf[(cs)->cdw++] = (value)
 
 static INLINE void update_reloc(struct drm_radeon_cs_reloc *reloc,
-				enum radeon_bo_domain rd,
-				enum radeon_bo_domain wd,
-				unsigned priority,
-				enum radeon_bo_domain *added_domains)
+                                enum radeon_bo_domain rd,
+                                enum radeon_bo_domain wd,
+                                unsigned priority,
+                                enum radeon_bo_domain *added_domains)
 {
     *added_domains = (rd | wd) & ~(reloc->read_domains | reloc->write_domain);
 
@@ -434,33 +434,37 @@ static void radeon_drm_cs_flush(struct radeon_winsys_cs *rcs,
 
     switch (cs->base.ring_type) {
     case RING_DMA:
-	    /* pad DMA ring to 8 DWs */
-	    if (cs->ws->info.chip_class <= SI) {
-		    while (rcs->cdw & 7)
-			    OUT_CS(&cs->base, 0xf0000000); /* NOP packet */
-	    } else {
-		    while (rcs->cdw & 7)
-			    OUT_CS(&cs->base, 0x00000000); /* NOP packet */
-	    }
-	    break;
+        /* pad DMA ring to 8 DWs */
+        if (cs->ws->info.chip_class <= SI) {
+            while (rcs->cdw & 7)
+                OUT_CS(&cs->base, 0xf0000000); /* NOP packet */
+        } else {
+            while (rcs->cdw & 7)
+                OUT_CS(&cs->base, 0x00000000); /* NOP packet */
+        }
+        break;
     case RING_GFX:
-	    /* pad DMA ring to 8 DWs to meet CP fetch alignment requirements
-	     * r6xx, requires at least 4 dw alignment to avoid a hw bug.
-	     */
-	    if (cs->ws->info.chip_class <= SI) {
-		    while (rcs->cdw & 7)
-			    OUT_CS(&cs->base, 0x80000000); /* type2 nop packet */
-	    } else {
-		    while (rcs->cdw & 7)
-			    OUT_CS(&cs->base, 0xffff1000); /* type3 nop packet */
-	    }
-	    break;
+        /* pad DMA ring to 8 DWs to meet CP fetch alignment requirements
+         * r6xx, requires at least 4 dw alignment to avoid a hw bug.
+         * hawaii with old firmware needs type2 nop packet.
+         * accel_working2 with value 3 indicates the new firmware.
+         */
+        if (cs->ws->info.chip_class <= SI ||
+            (cs->ws->info.family == CHIP_HAWAII &&
+             cs->ws->accel_working2 < 3)) {
+            while (rcs->cdw & 7)
+                OUT_CS(&cs->base, 0x80000000); /* type2 nop packet */
+        } else {
+            while (rcs->cdw & 7)
+                OUT_CS(&cs->base, 0xffff1000); /* type3 nop packet */
+        }
+        break;
     case RING_UVD:
-            while (rcs->cdw & 15)
-		OUT_CS(&cs->base, 0x80000000); /* type2 nop packet */
-	    break;
+        while (rcs->cdw & 15)
+            OUT_CS(&cs->base, 0x80000000); /* type2 nop packet */
+        break;
     default:
-	    break;
+        break;
     }
 
     if (rcs->cdw > RADEON_MAX_CMDBUF_DWORDS) {
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
index e54e79e..7033758 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.c
@@ -382,6 +382,16 @@ static boolean do_winsys_init(struct radeon_drm_winsys *ws)
     radeon_get_drm_value(ws->fd, RADEON_INFO_MAX_PIPES, NULL,
                          &ws->info.r600_max_pipes);
 
+    radeon_get_drm_value(ws->fd, RADEON_INFO_ACCEL_WORKING2, NULL,
+                         &ws->accel_working2);
+    if (ws->info.family == CHIP_HAWAII && ws->accel_working2 < 2) {
+        fprintf(stderr, "radeon: GPU acceleration for Hawaii disabled, "
+                "returned accel_working2 value %u is smaller than 2. "
+                "Please install a newer kernel.\n",
+                ws->accel_working2);
+        return FALSE;
+    }
+
     if (radeon_get_drm_value(ws->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, NULL,
                              ws->info.si_tile_mode_array)) {
         ws->info.si_tile_mode_array_valid = TRUE;
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
index 18fe0ae..1e0c632 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_winsys.h
@@ -55,6 +55,7 @@ struct radeon_drm_winsys {
     enum radeon_generation gen;
     struct radeon_info info;
     uint32_t va_start;
+    uint32_t accel_working2;
 
     struct pb_manager *kman;
     struct pb_manager *cman;




More information about the mesa-commit mailing list