From c93fe3de85c36c3f333ad6b92356d670a68d0a77 Mon Sep 17 00:00:00 2001 From: Xiaomeng Hou Date: Thu, 10 Dec 2020 20:18:23 +0800 Subject: drm/amdgpu/sdma5.2: soft reset sdma blocks before setup and start sdma Without doing the soft reset, register mmSDMA0_GFX_RB_WPTR's value could not be reset to 0 when sdma block resumes. That would cause the ring buffer's read and write pointers not equal and ring test fail. So add the soft reset step. Signed-off-by: Xiaomeng Hou Reviewed-by: Huang Rui Acked-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 39 ++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c index 39e17aae655f..5c4ac176b7e4 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c @@ -807,6 +807,37 @@ static int sdma_v5_2_load_microcode(struct amdgpu_device *adev) return 0; } +static int sdma_v5_2_soft_reset(void *handle) +{ + struct amdgpu_device *adev = (struct amdgpu_device *)handle; + u32 grbm_soft_reset; + u32 tmp; + int i; + + for (i = 0; i < adev->sdma.num_instances; i++) { + grbm_soft_reset = REG_SET_FIELD(0, + GRBM_SOFT_RESET, SOFT_RESET_SDMA0, + 1); + grbm_soft_reset <<= i; + + tmp = RREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET); + tmp |= grbm_soft_reset; + DRM_DEBUG("GRBM_SOFT_RESET=0x%08X\n", tmp); + WREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET, tmp); + tmp = RREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET); + + udelay(50); + + tmp &= ~grbm_soft_reset; + WREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET, tmp); + tmp = RREG32_SOC15(GC, 0, mmGRBM_SOFT_RESET); + + udelay(50); + } + + return 0; +} + /** * sdma_v5_2_start - setup and start the async dma engines * @@ -838,6 +869,7 @@ static int sdma_v5_2_start(struct amdgpu_device *adev) msleep(1000); } + sdma_v5_2_soft_reset(adev); /* unhalt the MEs */ sdma_v5_2_enable(adev, true); /* enable sdma ring preemption */ @@ -1366,13 +1398,6 @@ static int sdma_v5_2_wait_for_idle(void *handle) return -ETIMEDOUT; } -static int sdma_v5_2_soft_reset(void *handle) -{ - /* todo */ - - return 0; -} - static int sdma_v5_2_ring_preempt_ib(struct amdgpu_ring *ring) { int i, r = 0; -- cgit v1.2.3