drm/amdgpu/gfx10: implement gfx queue reset via MMIO
authorJesse.zhang@amd.com <Jesse.zhang@amd.com>
Fri, 10 Jan 2025 03:02:30 +0000 (11:02 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Thu, 13 Feb 2025 02:02:57 +0000 (21:02 -0500)
Using mmio to do queue reset

v2: Alignment the function with gfx9/gfx9.4.3.

Signed-off-by: Jesse Zhang <jesse.zhang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c

index d83d140283c451ae8f11da9d8da0521015897630..4b5e65affb8152decefc1b19a667fc8413974403 100644 (file)
@@ -3796,6 +3796,7 @@ static void gfx_v10_0_kiq_reset_hw_queue(struct amdgpu_ring *kiq_ring, uint32_t
 {
        struct amdgpu_device *adev = kiq_ring->adev;
        unsigned i;
+       uint32_t tmp;
 
        /* enter save mode */
        amdgpu_gfx_rlc_enter_safe_mode(adev, xcc_id);
@@ -3813,6 +3814,24 @@ static void gfx_v10_0_kiq_reset_hw_queue(struct amdgpu_ring *kiq_ring, uint32_t
                }
                if (i >= adev->usec_timeout)
                        dev_err(adev->dev, "fail to wait on hqd deactive\n");
+       } else if (queue_type == AMDGPU_RING_TYPE_GFX) {
+               WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX,
+                            (uint32_t)(0x1 << GRBM_GFX_INDEX__SE_BROADCAST_WRITES__SHIFT));
+               tmp = REG_SET_FIELD(0, CP_VMID_RESET, RESET_REQUEST, 1 << vmid);
+               if (pipe_id == 0)
+                       tmp = REG_SET_FIELD(tmp, CP_VMID_RESET, PIPE0_QUEUES, 1 << queue_id);
+               else
+                       tmp = REG_SET_FIELD(tmp, CP_VMID_RESET, PIPE1_QUEUES, 1 << queue_id);
+               WREG32_SOC15(GC, 0, mmCP_VMID_RESET, tmp);
+
+               /* wait till dequeue take effects */
+               for (i = 0; i < adev->usec_timeout; i++) {
+                       if (!(RREG32_SOC15(GC, 0, mmCP_GFX_HQD_ACTIVE) & 1))
+                               break;
+                       udelay(1);
+               }
+               if (i >= adev->usec_timeout)
+                       dev_err(adev->dev, "failed to wait on gfx hqd deactivate\n");
        } else {
                dev_err(adev->dev, "reset queue_type(%d) not supported\n", queue_type);
        }