]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
drm/amdgpu/mes12: Implement reset sdmav7 queue function by mmio
authorJesse.zhang@amd.com <Jesse.zhang@amd.com>
Mon, 9 Dec 2024 09:23:19 +0000 (17:23 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 11 Dec 2024 22:32:06 +0000 (17:32 -0500)
Reset sdma queue through mmio based on me_id and queue_id.

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/mes_v12_0.c

index 7bf57a679aa4de8f2f1aeb20a6c764b813146d2c..f8bee49260bfb43d9feaba2eb7e842876bda6652 100644 (file)
@@ -350,6 +350,47 @@ static int mes_v12_0_remove_hw_queue(struct amdgpu_mes *mes,
                        offsetof(union MESAPI__REMOVE_QUEUE, api_status));
 }
 
+static int mes_v12_0_reset_queue_mmio(struct amdgpu_mes *mes, uint32_t queue_type,
+                                     uint32_t me_id, uint32_t pipe_id,
+                                     uint32_t queue_id, uint32_t vmid)
+{
+       struct amdgpu_device *adev = mes->adev;
+       uint32_t value, reg;
+       int i, r = 0;
+
+       amdgpu_gfx_rlc_enter_safe_mode(adev, 0);
+
+       if (queue_type == AMDGPU_RING_TYPE_SDMA) {
+               dev_info(adev->dev, "reset sdma queue (%d:%d:%d)\n",
+                        me_id, pipe_id, queue_id);
+               switch (me_id) {
+               case 1:
+                       reg = SOC15_REG_OFFSET(GC, 0, regSDMA1_QUEUE_RESET_REQ);
+                       break;
+               case 0:
+               default:
+                       reg = SOC15_REG_OFFSET(GC, 0, regSDMA0_QUEUE_RESET_REQ);
+                       break;
+               }
+
+               value = 1 << queue_id;
+               WREG32(reg, value);
+               /* wait for queue reset done */
+               for (i = 0; i < adev->usec_timeout; i++) {
+                       if (!(RREG32(reg) & value))
+                               break;
+                       udelay(1);
+               }
+               if (i >= adev->usec_timeout) {
+                       dev_err(adev->dev, "failed to wait on sdma queue reset done\n");
+                       r = -ETIMEDOUT;
+               }
+       }
+
+       amdgpu_gfx_rlc_exit_safe_mode(adev, 0);
+       return r;
+}
+
 static int mes_v12_0_reset_hw_queue(struct amdgpu_mes *mes,
                                    struct mes_reset_queue_input *input)
 {
@@ -721,6 +762,11 @@ static int mes_v12_0_reset_legacy_queue(struct amdgpu_mes *mes,
        union MESAPI__RESET mes_reset_queue_pkt;
        int pipe;
 
+       if (input->use_mmio)
+               return mes_v12_0_reset_queue_mmio(mes, input->queue_type,
+                                                 input->me_id, input->pipe_id,
+                                                 input->queue_id, input->vmid);
+
        memset(&mes_reset_queue_pkt, 0, sizeof(mes_reset_queue_pkt));
 
        mes_reset_queue_pkt.header.type = MES_API_TYPE_SCHEDULER;