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

Reply via email to