Skip to content

Commit 5ea6f9c

Browse files
Chengming Guialexdeucher
authored andcommitted
drm/amdgpu: add timeout flush mechanism to update wptr for self interrupt (v2)
outstanding log reaches threshold will trigger IH ring1/2's wptr reported, that will avoid generating interrupts to ring0 too frequent. But if ring1/2's wptr hasn't been increased for a long time, the outstanding log can't reach threshold so that driver can't get latest wptr info and miss some interrupts. v2: squash in warning fix Signed-off-by: Chengming Gui <[email protected]> Reviewed-by: Feifei Xu <[email protected]> Acked-by: Felix Kuehling <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent c652923 commit 5ea6f9c

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,48 @@
3939

4040
static void navi10_ih_set_interrupt_funcs(struct amdgpu_device *adev);
4141

42+
/**
43+
* force_update_wptr_for_self_int - Force update the wptr for self interrupt
44+
*
45+
* @adev: amdgpu_device pointer
46+
* @threshold: threshold to trigger the wptr reporting
47+
* @timeout: timeout to trigger the wptr reporting
48+
* @enabled: Enable/disable timeout flush mechanism
49+
*
50+
* threshold input range: 0 ~ 15, default 0,
51+
* real_threshold = 2^threshold
52+
* timeout input range: 0 ~ 20, default 8,
53+
* real_timeout = (2^timeout) * 1024 / (socclk_freq)
54+
*
55+
* Force update wptr for self interrupt ( >= SIENNA_CICHLID).
56+
*/
57+
static void
58+
force_update_wptr_for_self_int(struct amdgpu_device *adev,
59+
u32 threshold, u32 timeout, bool enabled)
60+
{
61+
u32 ih_cntl, ih_rb_cntl;
62+
63+
if (adev->asic_type < CHIP_SIENNA_CICHLID)
64+
return;
65+
66+
ih_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_CNTL2);
67+
ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
68+
69+
ih_cntl = REG_SET_FIELD(ih_cntl, IH_CNTL2,
70+
SELF_IV_FORCE_WPTR_UPDATE_TIMEOUT, timeout);
71+
ih_cntl = REG_SET_FIELD(ih_cntl, IH_CNTL2,
72+
SELF_IV_FORCE_WPTR_UPDATE_ENABLE, enabled);
73+
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
74+
RB_USED_INT_THRESHOLD, threshold);
75+
76+
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
77+
ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
78+
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
79+
RB_USED_INT_THRESHOLD, threshold);
80+
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
81+
WREG32_SOC15(OSSSYS, 0, mmIH_CNTL2, ih_cntl);
82+
}
83+
4284
/**
4385
* navi10_ih_enable_interrupts - Enable the interrupt ring buffer
4486
*
@@ -371,6 +413,8 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev)
371413

372414
/* enable interrupts */
373415
navi10_ih_enable_interrupts(adev);
416+
/* enable wptr force update for self int */
417+
force_update_wptr_for_self_int(adev, 0, 8, true);
374418

375419
return 0;
376420
}
@@ -384,6 +428,7 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev)
384428
*/
385429
static void navi10_ih_irq_disable(struct amdgpu_device *adev)
386430
{
431+
force_update_wptr_for_self_int(adev, 0, 8, false);
387432
navi10_ih_disable_interrupts(adev);
388433

389434
/* Wait and acknowledge irq */

0 commit comments

Comments
 (0)