drm/amdgpu: fix Navi1x tcp power gating hang when issuing lightweight invalidaiton
authorEvan Quan <evan.quan@amd.com>
Tue, 25 May 2021 03:43:38 +0000 (11:43 +0800)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 30 Jun 2021 04:17:47 +0000 (00:17 -0400)
Fix TCP hang when a lightweight invalidation happens on Navi1x.

Signed-off-by: Evan Quan <evan.quan@amd.com>
Reviewed-by: Lijo Lazar <lijo.lazar@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c

index ef08f29..d08a823 100644 (file)
@@ -7961,6 +7961,97 @@ static void gfx_v10_0_update_fine_grain_clock_gating(struct amdgpu_device *adev,
        }
 }
 
+static void gfx_v10_0_apply_medium_grain_clock_gating_workaround(struct amdgpu_device *adev)
+{
+       uint32_t reg_data = 0;
+       uint32_t reg_idx = 0;
+       uint32_t i;
+
+       const uint32_t tcp_ctrl_regs[] = {
+               mmCGTS_SA0_WGP00_CU0_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP00_CU1_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP01_CU0_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP01_CU1_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP02_CU0_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP02_CU1_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP10_CU0_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP10_CU1_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP11_CU0_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP11_CU1_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP12_CU0_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP12_CU1_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP00_CU0_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP00_CU1_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP01_CU0_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP01_CU1_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP02_CU0_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP02_CU1_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP10_CU0_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP10_CU1_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP11_CU0_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP11_CU1_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP12_CU0_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP12_CU1_TCP_CTRL_REG
+       };
+
+       const uint32_t tcp_ctrl_regs_nv12[] = {
+               mmCGTS_SA0_WGP00_CU0_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP00_CU1_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP01_CU0_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP01_CU1_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP02_CU0_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP02_CU1_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP10_CU0_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP10_CU1_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP11_CU0_TCP_CTRL_REG,
+               mmCGTS_SA0_WGP11_CU1_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP00_CU0_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP00_CU1_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP01_CU0_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP01_CU1_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP02_CU0_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP02_CU1_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP10_CU0_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP10_CU1_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP11_CU0_TCP_CTRL_REG,
+               mmCGTS_SA1_WGP11_CU1_TCP_CTRL_REG,
+       };
+
+       const uint32_t sm_ctlr_regs[] = {
+               mmCGTS_SA0_QUAD0_SM_CTRL_REG,
+               mmCGTS_SA0_QUAD1_SM_CTRL_REG,
+               mmCGTS_SA1_QUAD0_SM_CTRL_REG,
+               mmCGTS_SA1_QUAD1_SM_CTRL_REG
+       };
+
+       if (adev->asic_type == CHIP_NAVI12) {
+               for (i = 0; i < ARRAY_SIZE(tcp_ctrl_regs_nv12); i++) {
+                       reg_idx = adev->reg_offset[GC_HWIP][0][mmCGTS_SA0_WGP00_CU0_TCP_CTRL_REG_BASE_IDX] +
+                                 tcp_ctrl_regs_nv12[i];
+                       reg_data = RREG32(reg_idx);
+                       reg_data |= CGTS_SA0_WGP00_CU0_TCP_CTRL_REG__TCPI_LS_OVERRIDE_MASK;
+                       WREG32(reg_idx, reg_data);
+               }
+       } else {
+               for (i = 0; i < ARRAY_SIZE(tcp_ctrl_regs); i++) {
+                       reg_idx = adev->reg_offset[GC_HWIP][0][mmCGTS_SA0_WGP00_CU0_TCP_CTRL_REG_BASE_IDX] +
+                                 tcp_ctrl_regs[i];
+                       reg_data = RREG32(reg_idx);
+                       reg_data |= CGTS_SA0_WGP00_CU0_TCP_CTRL_REG__TCPI_LS_OVERRIDE_MASK;
+                       WREG32(reg_idx, reg_data);
+               }
+       }
+
+       for (i = 0; i < ARRAY_SIZE(sm_ctlr_regs); i++) {
+               reg_idx = adev->reg_offset[GC_HWIP][0][mmCGTS_SA0_QUAD0_SM_CTRL_REG_BASE_IDX] +
+                         sm_ctlr_regs[i];
+               reg_data = RREG32(reg_idx);
+               reg_data &= ~CGTS_SA0_QUAD0_SM_CTRL_REG__SM_MODE_MASK;
+               reg_data |= 2 << CGTS_SA0_QUAD0_SM_CTRL_REG__SM_MODE__SHIFT;
+               WREG32(reg_idx, reg_data);
+       }
+}
+
 static int gfx_v10_0_update_gfx_clock_gating(struct amdgpu_device *adev,
                                            bool enable)
 {
@@ -7977,6 +8068,10 @@ static int gfx_v10_0_update_gfx_clock_gating(struct amdgpu_device *adev,
                gfx_v10_0_update_3d_clock_gating(adev, enable);
                /* ===  CGCG + CGLS === */
                gfx_v10_0_update_coarse_grain_clock_gating(adev, enable);
+
+               if ((adev->asic_type >= CHIP_NAVI10) &&
+                    (adev->asic_type <= CHIP_NAVI12))
+                       gfx_v10_0_apply_medium_grain_clock_gating_workaround(adev);
        } else {
                /* CGCG/CGLS should be disabled before MGCG/MGLS
                 * ===  CGCG + CGLS ===