| From ad9271bc38867e6058ffe77445fa9f884af646e2 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Tue, 25 May 2021 11:43:38 +0800 |
| Subject: drm/amdgpu: fix Navi1x tcp power gating hang when issuing lightweight |
| invalidaiton |
| |
| From: Evan Quan <evan.quan@amd.com> |
| |
| [ Upstream commit 9c26ddb1c5b6e30c6bca48b8ad9205d96efe93d0 ] |
| |
| 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> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 95 ++++++++++++++++++++++++++ |
| 1 file changed, 95 insertions(+) |
| |
| diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c |
| index 2342c5d216f9..5c40912b51d1 100644 |
| --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c |
| +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c |
| @@ -7744,6 +7744,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) |
| { |
| @@ -7760,6 +7851,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 === |
| -- |
| 2.30.2 |
| |