Update the register definition for GRBM_SOFT_RESET
to match what was in the old radeon driver and use
these bits in the soft reset implementation.

Use basically the same implementation as GFX8,
except GFX6 doesn't have MQD/HQD.

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

The soft reset also calls the clock and powergating
functions of the IP block. This is necessary for
correct operation, otherwise the GPU might fall
off the PCIe bus.

Signed-off-by: Timur Kristóf <[email protected]>
---
 drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c         | 94 +++++++++++++++++++
 .../include/asic_reg/gca/gfx_6_0_sh_mask.h    | 32 +++++--
 2 files changed, 118 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c 
b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
index 7f7b81c3919a..a033da5fc307 100644
--- a/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v6_0.c
@@ -3326,6 +3326,99 @@ static int gfx_v6_0_wait_for_idle(struct amdgpu_ip_block 
*ip_block)
        return -ETIMEDOUT;
 }
 
+static int gfx_v6_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;
+       int r;
+
+       grbm_soft_reset =
+               REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_CP, 1) |
+               REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_CB, 1) |
+               REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_RLC, 1) |
+               REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_DB, 1) |
+               REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_GDS, 1) |
+               REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_PA, 1) |
+               REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_SC, 1) |
+               REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_BCI, 1) |
+               REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_SPI, 1) |
+               REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_SX, 1) |
+               REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_TC, 1) |
+               REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_TA, 1) |
+               REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_VGT, 1) |
+               REG_SET_FIELD(0, GRBM_SOFT_RESET, SOFT_RESET_IA, 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);
+
+       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(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);
+
+               udelay(100);
+
+               tmp &= ~grbm_soft_reset;
+               WREG32(mmGRBM_SOFT_RESET, tmp);
+               tmp = RREG32(mmGRBM_SOFT_RESET);
+
+               udelay(100);
+       }
+
+       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);
+
+               tmp &= ~srbm_soft_reset;
+               WREG32(mmSRBM_SOFT_RESET, tmp);
+               tmp = RREG32(mmSRBM_SOFT_RESET);
+
+               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;
+}
+
 static void gfx_v6_0_set_gfx_eop_interrupt_state(struct amdgpu_device *adev,
                                                 enum amdgpu_interrupt_state 
state)
 {
@@ -3584,6 +3677,7 @@ static const struct amd_ip_funcs gfx_v6_0_ip_funcs = {
        .resume = gfx_v6_0_resume,
        .is_idle = gfx_v6_0_is_idle,
        .wait_for_idle = gfx_v6_0_wait_for_idle,
+       .soft_reset = gfx_v6_0_soft_reset,
        .set_clockgating_state = gfx_v6_0_set_clockgating_state,
        .set_powergating_state = gfx_v6_0_set_powergating_state,
 };
diff --git a/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_6_0_sh_mask.h 
b/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_6_0_sh_mask.h
index b5e634749665..0434fc2ba710 100644
--- a/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_6_0_sh_mask.h
+++ b/drivers/gpu/drm/amd/include/asic_reg/gca/gfx_6_0_sh_mask.h
@@ -4877,18 +4877,34 @@
 #define GRBM_SKEW_CNTL__SKEW_COUNT__SHIFT 0x00000006
 #define GRBM_SKEW_CNTL__SKEW_TOP_THRESHOLD_MASK 0x0000003fL
 #define GRBM_SKEW_CNTL__SKEW_TOP_THRESHOLD__SHIFT 0x00000000
-#define GRBM_SOFT_RESET__SOFT_RESET_CPC_MASK 0x00040000L
-#define GRBM_SOFT_RESET__SOFT_RESET_CPC__SHIFT 0x00000012
-#define GRBM_SOFT_RESET__SOFT_RESET_CPF_MASK 0x00020000L
-#define GRBM_SOFT_RESET__SOFT_RESET_CPF__SHIFT 0x00000011
-#define GRBM_SOFT_RESET__SOFT_RESET_CPG_MASK 0x00080000L
-#define GRBM_SOFT_RESET__SOFT_RESET_CPG__SHIFT 0x00000013
 #define GRBM_SOFT_RESET__SOFT_RESET_CP_MASK 0x00000001L
 #define GRBM_SOFT_RESET__SOFT_RESET_CP__SHIFT 0x00000000
-#define GRBM_SOFT_RESET__SOFT_RESET_GFX_MASK 0x00010000L
-#define GRBM_SOFT_RESET__SOFT_RESET_GFX__SHIFT 0x00000010
+#define GRBM_SOFT_RESET__SOFT_RESET_CB_MASK 0x00000002L
+#define GRBM_SOFT_RESET__SOFT_RESET_CB__SHIFT 0x00000001
 #define GRBM_SOFT_RESET__SOFT_RESET_RLC_MASK 0x00000004L
 #define GRBM_SOFT_RESET__SOFT_RESET_RLC__SHIFT 0x00000002
+#define GRBM_SOFT_RESET__SOFT_RESET_DB_MASK 0x00000008L
+#define GRBM_SOFT_RESET__SOFT_RESET_DB__SHIFT 0x00000003
+#define GRBM_SOFT_RESET__SOFT_RESET_GDS_MASK 0x00000010L
+#define GRBM_SOFT_RESET__SOFT_RESET_GDS__SHIFT 0x00000004
+#define GRBM_SOFT_RESET__SOFT_RESET_PA_MASK 0x00000020L
+#define GRBM_SOFT_RESET__SOFT_RESET_PA__SHIFT 0x00000005
+#define GRBM_SOFT_RESET__SOFT_RESET_SC_MASK 0x00000040L
+#define GRBM_SOFT_RESET__SOFT_RESET_SC__SHIFT 0x00000006
+#define GRBM_SOFT_RESET__SOFT_RESET_BCI_MASK 0x00000080L
+#define GRBM_SOFT_RESET__SOFT_RESET_BCI__SHIFT 0x00000007
+#define GRBM_SOFT_RESET__SOFT_RESET_SPI_MASK 0x00000100L
+#define GRBM_SOFT_RESET__SOFT_RESET_SPI__SHIFT 0x00000008
+#define GRBM_SOFT_RESET__SOFT_RESET_SX_MASK 0x00000400L
+#define GRBM_SOFT_RESET__SOFT_RESET_SX__SHIFT 0x0000000a
+#define GRBM_SOFT_RESET__SOFT_RESET_TC_MASK 0x00000800L
+#define GRBM_SOFT_RESET__SOFT_RESET_TC__SHIFT 0x0000000b
+#define GRBM_SOFT_RESET__SOFT_RESET_TA_MASK 0x00001000L
+#define GRBM_SOFT_RESET__SOFT_RESET_TA__SHIFT 0x0000000c
+#define GRBM_SOFT_RESET__SOFT_RESET_VGT_MASK 0x00004000L
+#define GRBM_SOFT_RESET__SOFT_RESET_VGT__SHIFT 0x0000000e
+#define GRBM_SOFT_RESET__SOFT_RESET_IA_MASK 0x00008000L
+#define GRBM_SOFT_RESET__SOFT_RESET_IA__SHIFT 0x0000000f
 #define GRBM_STATUS2__CPC_BUSY_MASK 0x20000000L
 #define GRBM_STATUS2__CPC_BUSY__SHIFT 0x0000001d
 #define GRBM_STATUS2__CPF_BUSY_MASK 0x10000000L
-- 
2.55.0

Reply via email to