The previous patch only ran on XCC0, giving us a good chance that we
don't clear the right registers on fault handling in MI3. Loop through
them all to make sure we clear them all.

Signed-off-by: Kent Russell <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c | 82 +++++++++++++++----------
 1 file changed, 49 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c
index 3cecf4ecf88f..e81044f01669 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4_2.c
@@ -724,54 +724,70 @@ static int gfx_v9_4_2_do_vgprs_init(struct amdgpu_device 
*adev)
 
 static int gfx_v9_clean_shaders(struct amdgpu_device *adev)
 {
-       int r;
+       int r = 0;
        /* CU_ID: 0~15, SIMD_ID: 0~3, WAVE_ID: 0 ~ 9 */
        int wb_size = adev->gfx.config.max_shader_engines *
                         CU_ID_MAX * SIMD_ID_MAX * WAVE_ID_MAX;
        struct amdgpu_ib disp_ib;
        struct amdgpu_ib wb_ib;
+       struct amdgpu_ring *ring;
        struct dma_fence *fence = NULL;
        u32 pattern = 0xa;
+       int xcc_id;
 
-       /* bail if the compute ring is not ready */
-       if (!adev->gfx.compute_ring[0].sched.ready)
+       if (adev->gfx.disable_kq) {
+               dev_warn(adev->dev, "Cannot run shader cleaner with kernel 
queues disabled");
                return 0;
-
-       /* allocate the write-back buffer from IB */
-       memset(&wb_ib, 0, sizeof(wb_ib));
-       r = amdgpu_ib_get(adev, NULL, (1 + wb_size) * sizeof(uint32_t),
-                         AMDGPU_IB_POOL_DIRECT, &wb_ib);
-       if (r) {
-               dev_err(adev->dev, "failed to get ib (%d) for wb.\n", r);
-               return r;
        }
-       memset(wb_ib.ptr, 0, (1 + wb_size) * sizeof(uint32_t));
 
-       r = gfx_v9_4_2_run_shader(adev,
-                       &adev->gfx.compute_ring[0],
-                       &disp_ib,
-                       fault_cleaner_compute_shader_aldebaran,
-                       sizeof(fault_cleaner_compute_shader_aldebaran),
-                       fault_cleaner_init_regs_aldebaran,
-                       ARRAY_SIZE(fault_cleaner_init_regs_aldebaran),
-                       adev->gfx.cu_info.number * 32,
-                       wb_ib.gpu_addr, pattern, &fence);
+       for_each_inst(xcc_id, adev->gfx.xcc_mask) {
+               ring = &adev->gfx.compute_ring[xcc_id * 
adev->gfx.num_compute_rings];
 
-       if (r) {
-               dev_err(adev->dev, "failed to clear MI200\n");
-               goto pro_end;
-       }
+               /* bail if the compute ring is not ready */
+               if (!ring->sched.ready)
+                       continue;
 
-       /* wait for the GPU to finish processing the IB */
-       r = dma_fence_wait(fence, false);
-       if (r)
-               dev_err(adev->dev, "timeout to clear MI200\n");
+               /* allocate the write-back buffer from IB */
+               memset(&wb_ib, 0, sizeof(wb_ib));
+               r = amdgpu_ib_get(adev, NULL, (1 + wb_size) * sizeof(uint32_t),
+                                 AMDGPU_IB_POOL_DIRECT, &wb_ib);
+               if (r) {
+                       dev_err(adev->dev, "failed to get ib (%d) for wb.\n", 
r);
+                       return r;
+               }
+               memset(wb_ib.ptr, 0, (1 + wb_size) * sizeof(uint32_t));
+
+               r = gfx_v9_4_2_run_shader(adev,
+                               ring,
+                               &disp_ib,
+                               fault_cleaner_compute_shader_aldebaran,
+                               sizeof(fault_cleaner_compute_shader_aldebaran),
+                               fault_cleaner_init_regs_aldebaran,
+                               ARRAY_SIZE(fault_cleaner_init_regs_aldebaran),
+                               adev->gfx.cu_info.number * 32,
+                               wb_ib.gpu_addr, pattern, &fence);
+
+               if (r) {
+                       dev_err(adev->dev, "failed to clear GPR on xcc %d\n", 
xcc_id);
+                       goto pro_end;
+               }
+
+               /* wait for the GPU to finish processing the IB */
+               r = dma_fence_wait(fence, false);
+               if (r)
+                       dev_err(adev->dev, "timeout to clear GPR on xcc %d\n", 
xcc_id);
 
 pro_end:
-       amdgpu_ib_free(&disp_ib, NULL);
-       if (fence)
-               dma_fence_put(fence);
-       amdgpu_ib_free(&wb_ib, NULL);
+               amdgpu_ib_free(&disp_ib, NULL);
+               if (fence) {
+                       dma_fence_put(fence);
+                       fence = NULL;
+               }
+               amdgpu_ib_free(&wb_ib, NULL);
+
+               if (r)
+                       break;
+       }
 
        if (r)
                dev_dbg(adev->dev, "Clean GPR Failed\n");
-- 
2.43.0

Reply via email to