Skip to content

Commit afbf795

Browse files
Danijel Slivkaalexdeucher
Danijel Slivka
authored andcommitted
drm/amdgpu: clear RB_OVERFLOW bit when enabling interrupts
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: Danijel Slivka <[email protected]> Reviewed-by: Christian König <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent bf826ba commit afbf795

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

drivers/gpu/drm/amd/amdgpu/ih_v6_0.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,34 @@ static int ih_v6_0_toggle_ring_interrupts(struct amdgpu_device *adev,
135135

136136
tmp = RREG32(ih_regs->ih_rb_cntl);
137137
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, RB_ENABLE, (enable ? 1 : 0));
138+
139+
if (enable) {
140+
/* Unset the CLEAR_OVERFLOW bit to make sure the next step
141+
* is switching the bit from 0 to 1
142+
*/
143+
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
144+
if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
145+
if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp))
146+
return -ETIMEDOUT;
147+
} else {
148+
WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
149+
}
150+
151+
/* Clear RB_OVERFLOW bit */
152+
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
153+
if (amdgpu_sriov_vf(adev) && amdgpu_sriov_reg_indirect_ih(adev)) {
154+
if (psp_reg_program(&adev->psp, ih_regs->psp_reg_id, tmp))
155+
return -ETIMEDOUT;
156+
} else {
157+
WREG32_NO_KIQ(ih_regs->ih_rb_cntl, tmp);
158+
}
159+
160+
/* Unset the CLEAR_OVERFLOW bit immediately so new overflows
161+
* can be detected.
162+
*/
163+
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 0);
164+
}
165+
138166
/* enable_intr field is only valid in ring0 */
139167
if (ih == &adev->irq.ih)
140168
tmp = REG_SET_FIELD(tmp, IH_RB_CNTL, ENABLE_INTR, (enable ? 1 : 0));

0 commit comments

Comments
 (0)