Use basically the same implementation as GFX8,
except for the GFX7 specific MQD functions.

Reset every block using the GRBM, then proceed
to reset the GRBM and SEM blocks using the SRBM.

Remove the redundant gfx_v7_0_update_cg() function.
The soft reset now calls the clock and powergating
functions of the IP block instead.

Signed-off-by: Timur Kristóf <[email protected]>
Reviewed-by: Tvrtko Ursulin <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c | 148 +++++++++++++-------------
 1 file changed, 76 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
index dbd4667100b6..e31a2101f308 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
@@ -3616,21 +3616,6 @@ static void gfx_v7_0_enable_mgcg(struct amdgpu_device 
*adev, bool enable)
        }
 }
 
-static void gfx_v7_0_update_cg(struct amdgpu_device *adev,
-                              bool enable)
-{
-       gfx_v7_0_enable_gui_idle_interrupt(adev, false);
-       /* order matters! */
-       if (enable) {
-               gfx_v7_0_enable_mgcg(adev, true);
-               gfx_v7_0_enable_cgcg(adev, true);
-       } else {
-               gfx_v7_0_enable_cgcg(adev, false);
-               gfx_v7_0_enable_mgcg(adev, false);
-       }
-       gfx_v7_0_enable_gui_idle_interrupt(adev, true);
-}
-
 static void gfx_v7_0_enable_sclk_slowdown_on_pu(struct amdgpu_device *adev,
                                                bool enable)
 {
@@ -4549,80 +4534,99 @@ static int gfx_v7_0_wait_for_idle(struct 
amdgpu_ip_block *ip_block)
 
 static int gfx_v7_0_soft_reset(struct amdgpu_ip_block *ip_block)
 {
+       struct amdgpu_device *adev = ip_block->adev;
        u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
        u32 tmp;
-       struct amdgpu_device *adev = ip_block->adev;
+       int i;
+       int r;
 
-       /* GRBM_STATUS */
-       tmp = RREG32(mmGRBM_STATUS);
-       if (tmp & (GRBM_STATUS__PA_BUSY_MASK | GRBM_STATUS__SC_BUSY_MASK |
-                  GRBM_STATUS__BCI_BUSY_MASK | GRBM_STATUS__SX_BUSY_MASK |
-                  GRBM_STATUS__TA_BUSY_MASK | GRBM_STATUS__VGT_BUSY_MASK |
-                  GRBM_STATUS__DB_BUSY_MASK | GRBM_STATUS__CB_BUSY_MASK |
-                  GRBM_STATUS__GDS_BUSY_MASK | GRBM_STATUS__SPI_BUSY_MASK |
-                  GRBM_STATUS__IA_BUSY_MASK | 
GRBM_STATUS__IA_BUSY_NO_DMA_MASK))
-               grbm_soft_reset |= GRBM_SOFT_RESET__SOFT_RESET_CP_MASK |
-                       GRBM_SOFT_RESET__SOFT_RESET_GFX_MASK;
-
-       if (tmp & (GRBM_STATUS__CP_BUSY_MASK | 
GRBM_STATUS__CP_COHERENCY_BUSY_MASK)) {
-               grbm_soft_reset |= GRBM_SOFT_RESET__SOFT_RESET_CP_MASK;
-               srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_GRBM_MASK;
-       }
+       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);
+
+       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];
+
+               mutex_lock(&adev->srbm_mutex);
+               cik_srbm_select(adev, ring->me, ring->pipe, ring->queue, 0);
+               gfx_v7_0_deactivate_hqd(adev, 2);
+               cik_srbm_select(adev, 0, 0, 0, 0);
+               mutex_unlock(&adev->srbm_mutex);
 
-       /* GRBM_STATUS2 */
-       tmp = RREG32(mmGRBM_STATUS2);
-       if (tmp & GRBM_STATUS2__RLC_BUSY_MASK)
-               grbm_soft_reset |= GRBM_SOFT_RESET__SOFT_RESET_RLC_MASK;
+               udelay(50);
+       }
 
-       /* SRBM_STATUS */
-       tmp = RREG32(mmSRBM_STATUS);
-       if (tmp & SRBM_STATUS__GRBM_RQ_PENDING_MASK)
-               srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_GRBM_MASK;
+       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) {
-               /* disable CG/PG */
-               gfx_v7_0_fini_pg(adev);
-               gfx_v7_0_update_cg(adev, false);
+               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);
 
-               /* stop the rlc */
-               adev->gfx.rlc.funcs->stop(adev);
+               udelay(100);
+       }
 
-               /* Disable GFX parsing/prefetching */
-               WREG32(mmCP_ME_CNTL, CP_ME_CNTL__ME_HALT_MASK | 
CP_ME_CNTL__PFP_HALT_MASK | CP_ME_CNTL__CE_HALT_MASK);
+       if (grbm_soft_reset) {
+               tmp = RREG32(mmGRBM_SOFT_RESET);
+               tmp |= grbm_soft_reset;
+               dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
+               WREG32(mmGRBM_SOFT_RESET, tmp);
+               tmp = RREG32(mmGRBM_SOFT_RESET);
 
-               /* Disable MEC parsing/prefetching */
-               WREG32(mmCP_MEC_CNTL, CP_MEC_CNTL__MEC_ME1_HALT_MASK | 
CP_MEC_CNTL__MEC_ME2_HALT_MASK);
+               udelay(100);
 
-               if (grbm_soft_reset) {
-                       tmp = RREG32(mmGRBM_SOFT_RESET);
-                       tmp |= grbm_soft_reset;
-                       dev_info(adev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
-                       WREG32(mmGRBM_SOFT_RESET, tmp);
-                       tmp = RREG32(mmGRBM_SOFT_RESET);
+               tmp &= ~grbm_soft_reset;
+               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);
-               }
+       if (srbm_soft_reset) {
+               tmp = RREG32(mmSRBM_SOFT_RESET);
+               tmp |= srbm_soft_reset;
+               dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
+               WREG32(mmSRBM_SOFT_RESET, tmp);
+               tmp = RREG32(mmSRBM_SOFT_RESET);
 
-               if (srbm_soft_reset) {
-                       tmp = RREG32(mmSRBM_SOFT_RESET);
-                       tmp |= srbm_soft_reset;
-                       dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
-                       WREG32(mmSRBM_SOFT_RESET, tmp);
-                       tmp = RREG32(mmSRBM_SOFT_RESET);
+               udelay(100);
 
-                       udelay(50);
+               tmp &= ~srbm_soft_reset;
+               WREG32(mmSRBM_SOFT_RESET, tmp);
+               tmp = RREG32(mmSRBM_SOFT_RESET);
 
-                       tmp &= ~srbm_soft_reset;
-                       WREG32(mmSRBM_SOFT_RESET, tmp);
-                       tmp = RREG32(mmSRBM_SOFT_RESET);
-               }
-               /* Wait a little for things to settle down */
-               udelay(50);
+               udelay(100);
        }
+
+       if (grbm_soft_reset || srbm_soft_reset) {
+               tmp = RREG32(mmGMCON_DEBUG);
+               tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_STALL, 0);
+               tmp = REG_SET_FIELD(tmp, GMCON_DEBUG, GFX_CLEAR, 0);
+               WREG32(mmGMCON_DEBUG, tmp);
+       }
+
+       /* Wait a little for things to settle down */
+       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.55.0

Reply via email to