From: Dave Airlie <airl...@redhat.com>

This adds support to the command parser for the set append counter
packet3, this is required to support atomic counters on
evergreen/cayman GPUs.

Signed-off-by: Dave Airlie <airlied at redhat.com>
---
 drivers/gpu/drm/radeon/evergreen_cs.c | 38 +++++++++++++++++++++++++++++++++++
 drivers/gpu/drm/radeon/evergreend.h   | 20 ++++++++++++++++++
 drivers/gpu/drm/radeon/radeon_drv.c   |  3 ++-
 3 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c 
b/drivers/gpu/drm/radeon/evergreen_cs.c
index 9e93205..1f618c5 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -2608,6 +2608,44 @@ static int evergreen_packet3_check(struct 
radeon_cs_parser *p,
                        }
                }
                break;
+       case PACKET3_SET_APPEND_CNT:
+       {
+               uint32_t areg;
+               if (pkt->count != 2) {
+                       DRM_ERROR("bad SET_APPEND_CNT (invalid count)\n");
+                       return -EINVAL;
+               }
+
+               areg = idx_value >> 16;
+               if (areg < 0x1cb || areg > 0x1cb + 8) {
+                       dev_warn(p->dev, "forbidden register for append cnt 
0x%08x at %d\n",
+                                areg, idx);
+                       return -EINVAL;
+               }
+
+               if ((idx_value & 0x3) == 0x3) { /* Read from memory address */
+                       uint64_t offset;
+                       uint32_t swap;
+                       r = radeon_cs_packet_next_reloc(p, &reloc, 0);
+                       if (r) {
+                               DRM_ERROR("bad SET_APPEND_CNT (missing 
reloc)\n");
+                               return -EINVAL;
+                       }
+                       offset = radeon_get_ib_value(p, idx+1);
+                       swap = offset & 0x3;
+                       offset &= ~0x3;
+
+                       offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) 
<< 32;
+
+                       offset += reloc->gpu_offset;
+                       ib[idx+1] = (offset & 0xfffffffc) | swap;
+                       ib[idx+2] = upper_32_bits(offset) & 0xff;
+               } else {
+                       DRM_ERROR("bad SET_APPEND_CNT (unsupported 
operation)\n");
+                       return -EINVAL;
+               }
+               break;
+       }
        case PACKET3_NOP:
                break;
        default:
diff --git a/drivers/gpu/drm/radeon/evergreend.h 
b/drivers/gpu/drm/radeon/evergreend.h
index 13b6029..2e2f740 100644
--- a/drivers/gpu/drm/radeon/evergreend.h
+++ b/drivers/gpu/drm/radeon/evergreend.h
@@ -1689,6 +1689,26 @@
 #define        PACKET3_SET_CONTEXT_REG_INDIRECT                0x73
 #define        PACKET3_SET_RESOURCE_INDIRECT                   0x74
 #define        PACKET3_SET_APPEND_CNT                          0x75
+/* SET_APPEND_CNT - documentation
+ * 1. header
+ * 2. COMMAND
+ *  1:0 - SOURCE SEL
+ *  15:2 - Reserved
+ *  31:16 - WR_REG_OFFSET - context register to write source data to.
+ *          (one of R_02872C_GDS_APPEND_COUNT_0-8)
+ * 3. CONTROL
+ *  (for source == mem)
+ *  31:2 SRC_ADDRESS_LO
+ *  0:1 SWAP
+ *  (for source == GDS)
+ *  31:0 GDS offset
+ *  (for source == DATA)
+ *  31:0 DATA
+ *  (for source == REG)
+ *  31:0 REG
+ * 4. SRC_ADDRESS_HI[7:0]
+ * kernel driver 2.44 only supports SRC == MEM.
+ */

 #define        SQ_RESOURCE_CONSTANT_WORD7_0                            0x3001c
 #define                S__SQ_CONSTANT_TYPE(x)                  (((x) & 3) << 
30)
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c 
b/drivers/gpu/drm/radeon/radeon_drv.c
index a4b5dbd..1f96b04 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -93,9 +93,10 @@
  *   2.41.0 - evergreen/cayman: Add SET_BASE/DRAW_INDIRECT command parsing 
support
  *   2.42.0 - Add VCE/VUI (Video Usability Information) support
  *   2.43.0 - RADEON_INFO_GPU_RESET_COUNTER
+ *   2.44.0 - SET_APPEND_CNT packet3 support
  */
 #define KMS_DRIVER_MAJOR       2
-#define KMS_DRIVER_MINOR       43
+#define KMS_DRIVER_MINOR       44
 #define KMS_DRIVER_PATCHLEVEL  0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);
-- 
2.5.5

Reply via email to