Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts for vega20_ih

Port this change to vega20_ih.c:
commit afbf7955ff01 ("drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts")

Original commit message:
"Why:
Setting IH_RB_WPTR register to 0 will not clear the RB_OVERFLOW bit
if RB_ENABLE is not set.

How to fix:
Set WPTR_OVERFLOW_CLEAR bit after RB_ENABLE bit is set.
The RB_ENABLE bit is required to be set, together with
WPTR_OVERFLOW_ENABLE bit so that setting WPTR_OVERFLOW_CLEAR bit
would clear the RB_OVERFLOW."

Signed-off-by: Victor Lu <victorchengchi.lu@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Victor Lu and committed by
Alex Deucher
8b22f048 0016e870

+27
+27
drivers/gpu/drm/amd/amdgpu/vega20_ih.c
··· 114 114 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_ENABLE, (enable ? 1 : 0)); 115 115 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_GPU_TS_ENABLE, 1); 116 116 117 + if (enable) { 118 + /* Unset the CLEAR_OVERFLOW bit to make sure the next step 119 + * is switching the bit from 0 to 1 120 + */ 121 + tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); 122 + if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) { 123 + if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) 124 + return -ETIMEDOUT; 125 + } else { 126 + WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); 127 + } 128 + 129 + /* Clear RB_OVERFLOW bit */ 130 + tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1); 131 + if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) { 132 + if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp)) 133 + return -ETIMEDOUT; 134 + } else { 135 + WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp); 136 + } 137 + 138 + /* Unset the CLEAR_OVERFLOW bit immediately so new overflows 139 + * can be detected. 140 + */ 141 + tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0); 142 + } 143 + 117 144 /* enable_intr field is only valid in ring0 */ 118 145 if (ih == &adev->irq.ih) 119 146 tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));