Commit dd31ae9a authored by Arindam Nath's avatar Arindam Nath Committed by Alex Deucher

drm/amd/amdgpu: enable GUI idle INT after enabling CGCG

GUI idle interrupts should be enabled only after we
have enabled coarse grain clock gating (CGCG). This
prevents GFX engine generating idle interrupt even
though CGCG is not completely enabled.

Most of the time this goes un-noticed, but on some
Stoney ASICs this results in GFX engine hang after
system resumes from suspend. The issue is not
particular to Stoney though and could have occured
on any ASIC. The patch fixes this issue.
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Reported-by: default avatarSunil Uttarwar <Sunil.Uttarwar1@amd.com>
Signed-off-by: default avatarArindam Nath <arindam.nath@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
parent ecc2cf7c
...@@ -5919,29 +5919,24 @@ static void gfx_v8_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev ...@@ -5919,29 +5919,24 @@ static void gfx_v8_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev
adev->gfx.rlc.funcs->enter_safe_mode(adev); adev->gfx.rlc.funcs->enter_safe_mode(adev);
if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGCG)) { if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGCG)) {
/* 1 enable cntx_empty_int_enable/cntx_busy_int_enable/
* Cmp_busy/GFX_Idle interrupts
*/
gfx_v8_0_enable_gui_idle_interrupt(adev, true);
temp1 = data1 = RREG32(mmRLC_CGTT_MGCG_OVERRIDE); temp1 = data1 = RREG32(mmRLC_CGTT_MGCG_OVERRIDE);
data1 &= ~RLC_CGTT_MGCG_OVERRIDE__CGCG_MASK; data1 &= ~RLC_CGTT_MGCG_OVERRIDE__CGCG_MASK;
if (temp1 != data1) if (temp1 != data1)
WREG32(mmRLC_CGTT_MGCG_OVERRIDE, data1); WREG32(mmRLC_CGTT_MGCG_OVERRIDE, data1);
/* 2 wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */ /* : wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */
gfx_v8_0_wait_for_rlc_serdes(adev); gfx_v8_0_wait_for_rlc_serdes(adev);
/* 3 - clear cgcg override */ /* 2 - clear cgcg override */
gfx_v8_0_send_serdes_cmd(adev, BPM_REG_CGCG_OVERRIDE, CLE_BPM_SERDES_CMD); gfx_v8_0_send_serdes_cmd(adev, BPM_REG_CGCG_OVERRIDE, CLE_BPM_SERDES_CMD);
/* wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */ /* wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */
gfx_v8_0_wait_for_rlc_serdes(adev); gfx_v8_0_wait_for_rlc_serdes(adev);
/* 4 - write cmd to set CGLS */ /* 3 - write cmd to set CGLS */
gfx_v8_0_send_serdes_cmd(adev, BPM_REG_CGLS_EN, SET_BPM_SERDES_CMD); gfx_v8_0_send_serdes_cmd(adev, BPM_REG_CGLS_EN, SET_BPM_SERDES_CMD);
/* 5 - enable cgcg */ /* 4 - enable cgcg */
data |= RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK; data |= RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK;
if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGLS) { if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGLS) {
...@@ -5959,6 +5954,11 @@ static void gfx_v8_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev ...@@ -5959,6 +5954,11 @@ static void gfx_v8_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev
if (temp != data) if (temp != data)
WREG32(mmRLC_CGCG_CGLS_CTRL, data); WREG32(mmRLC_CGCG_CGLS_CTRL, data);
/* 5 enable cntx_empty_int_enable/cntx_busy_int_enable/
* Cmp_busy/GFX_Idle interrupts
*/
gfx_v8_0_enable_gui_idle_interrupt(adev, true);
} else { } else {
/* disable cntx_empty_int_enable & GFX Idle interrupt */ /* disable cntx_empty_int_enable & GFX Idle interrupt */
gfx_v8_0_enable_gui_idle_interrupt(adev, false); gfx_v8_0_enable_gui_idle_interrupt(adev, false);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment