Always reset everything in the GFX block at once as opposed to trying to figure out which blocks need to be reset based on their busy flags. This makes the reset more robust and predictable.
Increase delays when waiting for the GRBM and SRBM soft reset to complete. Call IP block suspend/resume to ensure correct operation now that we no longer have pre/post_soft_reset(). Call clock/powergating functions, otherwise power consumption will increase after the GFX IP block is soft reset. Return correct error code to signal failure in case not all rings are functional after the IP block is soft reset. Signed-off-by: Timur Kristóf <[email protected]> --- drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h | 2 -- drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c | 43 +++++++++++++++++++------ 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h index 77050f9884f2..d968e5b6725b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h @@ -479,8 +479,6 @@ struct amdgpu_gfx { const struct amdgpu_gfx_funcs *funcs; /* reset mask */ - uint32_t grbm_soft_reset; - uint32_t srbm_soft_reset; uint32_t gfx_supported_reset; uint32_t compute_supported_reset; diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c index 1366d6070481..e5b25d6b8268 100644 --- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c @@ -4904,13 +4904,19 @@ static int gfx_v8_0_soft_reset(struct amdgpu_ip_block *ip_block) u32 grbm_soft_reset = 0, srbm_soft_reset = 0; u32 tmp; int i; + int r; - if ((!adev->gfx.grbm_soft_reset) && - (!adev->gfx.srbm_soft_reset)) - return 0; + grbm_soft_reset = + REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_RLC, 1) | + REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_GFX, 1) | + REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_CP, 1) | + REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_CPF, 1) | + REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_CPC, 1) | + REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_CPG, 1); - grbm_soft_reset = adev->gfx.grbm_soft_reset; - srbm_soft_reset = adev->gfx.srbm_soft_reset; + srbm_soft_reset = + REG_SET_FIELD(0, SRBM_SOFT_RESET, SOFT_RESET_GRBM, 1) | + REG_SET_FIELD(0, SRBM_SOFT_RESET, SOFT_RESET_SEM, 1); for (i = 0; i < adev->gfx.num_compute_rings; i++) { struct amdgpu_ring *ring = &adev->gfx.compute_ring[i]; @@ -4920,14 +4926,21 @@ static int gfx_v8_0_soft_reset(struct amdgpu_ip_block *ip_block) gfx_v8_0_deactivate_hqd(adev, 2); vi_srbm_select(adev, 0, 0, 0, 0); mutex_unlock(&adev->srbm_mutex); + + udelay(50); } + ip_block->version->funcs->set_clockgating_state(ip_block, AMD_CG_STATE_UNGATE); + ip_block->version->funcs->set_powergating_state(ip_block, AMD_PG_STATE_UNGATE); + ip_block->version->funcs->suspend(ip_block); + if (grbm_soft_reset || srbm_soft_reset) { tmp = RREG32(mmGMCON_DEBUG); tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_STALL, 1); tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_CLEAR, 1); WREG32(mmGMCON_DEBUG, tmp); - udelay(50); + + udelay(100); } if (grbm_soft_reset) { @@ -4937,11 +4950,13 @@ static int gfx_v8_0_soft_reset(struct amdgpu_ip_block *ip_block) WREG32(mmGRBM_SOFT_RESET, tmp); tmp = RREG32(mmGRBM_SOFT_RESET); - udelay(50); + udelay(100); tmp &= ~grbm_soft_reset; WREG32(mmGRBM_SOFT_RESET, tmp); tmp = RREG32(mmGRBM_SOFT_RESET); + + udelay(100); } if (srbm_soft_reset) { @@ -4951,11 +4966,13 @@ static int gfx_v8_0_soft_reset(struct amdgpu_ip_block *ip_block) WREG32(mmSRBM_SOFT_RESET, tmp); tmp = RREG32(mmSRBM_SOFT_RESET); - udelay(50); + udelay(100); tmp &= ~srbm_soft_reset; WREG32(mmSRBM_SOFT_RESET, tmp); tmp = RREG32(mmSRBM_SOFT_RESET); + + udelay(100); } if (grbm_soft_reset || srbm_soft_reset) { @@ -4966,7 +4983,15 @@ static int gfx_v8_0_soft_reset(struct amdgpu_ip_block *ip_block) } /* Wait a little for things to settle down */ - udelay(50); + udelay(100); + + r = ip_block->version->funcs->resume(ip_block); + r |= ip_block->version->funcs->late_init(ip_block); + if (r) + return r; + + ip_block->version->funcs->set_clockgating_state(ip_block, AMD_CG_STATE_GATE); + ip_block->version->funcs->set_powergating_state(ip_block, AMD_PG_STATE_GATE); return 0; } -- 2.54.0
