drm/radeon: add support for MEM_WRITE packet
Jerome Glisse [Wed, 19 Dec 2012 17:26:45 +0000 (12:26 -0500)]
To make it easier to debug some lockup from userspace add support
to MEM_WRITE packet.

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

drivers/gpu/drm/radeon/evergreen_cs.c
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/radeon_drv.c

index 74c6b42..5cea852 100644 (file)
@@ -2654,6 +2654,35 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p,
                        ib[idx+4] = upper_32_bits(offset) & 0xff;
                }
                break;
+       case PACKET3_MEM_WRITE:
+       {
+               u64 offset;
+
+               if (pkt->count != 3) {
+                       DRM_ERROR("bad MEM_WRITE (invalid count)\n");
+                       return -EINVAL;
+               }
+               r = evergreen_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       DRM_ERROR("bad MEM_WRITE (missing reloc)\n");
+                       return -EINVAL;
+               }
+               offset = radeon_get_ib_value(p, idx+0);
+               offset += ((u64)(radeon_get_ib_value(p, idx+1) & 0xff)) << 32UL;
+               if (offset & 0x7) {
+                       DRM_ERROR("bad MEM_WRITE (address not qwords aligned)\n");
+                       return -EINVAL;
+               }
+               if ((offset + 8) > radeon_bo_size(reloc->robj)) {
+                       DRM_ERROR("bad MEM_WRITE bo too small: 0x%llx, 0x%lx\n",
+                                 offset + 8, radeon_bo_size(reloc->robj));
+                       return -EINVAL;
+               }
+               offset += reloc->lobj.gpu_offset;
+               ib[idx+0] = offset;
+               ib[idx+1] = upper_32_bits(offset) & 0xff;
+               break;
+       }
        case PACKET3_COPY_DW:
                if (pkt->count != 4) {
                        DRM_ERROR("bad COPY_DW (invalid count)\n");
index 0be768b..9ea13d0 100644 (file)
@@ -2294,6 +2294,35 @@ static int r600_packet3_check(struct radeon_cs_parser *p,
                        ib[idx+4] = upper_32_bits(offset) & 0xff;
                }
                break;
+       case PACKET3_MEM_WRITE:
+       {
+               u64 offset;
+
+               if (pkt->count != 3) {
+                       DRM_ERROR("bad MEM_WRITE (invalid count)\n");
+                       return -EINVAL;
+               }
+               r = r600_cs_packet_next_reloc(p, &reloc);
+               if (r) {
+                       DRM_ERROR("bad MEM_WRITE (missing reloc)\n");
+                       return -EINVAL;
+               }
+               offset = radeon_get_ib_value(p, idx+0);
+               offset += ((u64)(radeon_get_ib_value(p, idx+1) & 0xff)) << 32UL;
+               if (offset & 0x7) {
+                       DRM_ERROR("bad MEM_WRITE (address not qwords aligned)\n");
+                       return -EINVAL;
+               }
+               if ((offset + 8) > radeon_bo_size(reloc->robj)) {
+                       DRM_ERROR("bad MEM_WRITE bo too small: 0x%llx, 0x%lx\n",
+                                 offset + 8, radeon_bo_size(reloc->robj));
+                       return -EINVAL;
+               }
+               offset += reloc->lobj.gpu_offset;
+               ib[idx+0] = offset;
+               ib[idx+1] = upper_32_bits(offset) & 0xff;
+               break;
+       }
        case PACKET3_COPY_DW:
                if (pkt->count != 4) {
                        DRM_ERROR("bad COPY_DW (invalid count)\n");
index 9b1a727..ff75934 100644 (file)
  *   2.25.0 - eg+: new info request for num SE and num SH
  *   2.26.0 - r600-eg: fix htile size computation
  *   2.27.0 - r600-SI: Add CS ioctl support for async DMA
+ *   2.28.0 - r600-eg: Add MEM_WRITE packet support
  */
 #define KMS_DRIVER_MAJOR       2
-#define KMS_DRIVER_MINOR       27
+#define KMS_DRIVER_MINOR       28
 #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);