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
