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 <Jack.Gui@amd.com> Reviewed-by: Feifei Xu <Feifei.Xu@amd.com> Acked-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
c652923afa
commit
5ea6f9c22c
|
@ -39,6 +39,48 @@
|
||||||
|
|
||||||
static void navi10_ih_set_interrupt_funcs(struct amdgpu_device *adev);
|
static void navi10_ih_set_interrupt_funcs(struct amdgpu_device *adev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* force_update_wptr_for_self_int - Force update the wptr for self interrupt
|
||||||
|
*
|
||||||
|
* @adev: amdgpu_device pointer
|
||||||
|
* @threshold: threshold to trigger the wptr reporting
|
||||||
|
* @timeout: timeout to trigger the wptr reporting
|
||||||
|
* @enabled: Enable/disable timeout flush mechanism
|
||||||
|
*
|
||||||
|
* threshold input range: 0 ~ 15, default 0,
|
||||||
|
* real_threshold = 2^threshold
|
||||||
|
* timeout input range: 0 ~ 20, default 8,
|
||||||
|
* real_timeout = (2^timeout) * 1024 / (socclk_freq)
|
||||||
|
*
|
||||||
|
* Force update wptr for self interrupt ( >= SIENNA_CICHLID).
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
force_update_wptr_for_self_int(struct amdgpu_device *adev,
|
||||||
|
u32 threshold, u32 timeout, bool enabled)
|
||||||
|
{
|
||||||
|
u32 ih_cntl, ih_rb_cntl;
|
||||||
|
|
||||||
|
if (adev->asic_type < CHIP_SIENNA_CICHLID)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ih_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_CNTL2);
|
||||||
|
ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1);
|
||||||
|
|
||||||
|
ih_cntl = REG_SET_FIELD(ih_cntl, IH_CNTL2,
|
||||||
|
SELF_IV_FORCE_WPTR_UPDATE_TIMEOUT, timeout);
|
||||||
|
ih_cntl = REG_SET_FIELD(ih_cntl, IH_CNTL2,
|
||||||
|
SELF_IV_FORCE_WPTR_UPDATE_ENABLE, enabled);
|
||||||
|
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING1,
|
||||||
|
RB_USED_INT_THRESHOLD, threshold);
|
||||||
|
|
||||||
|
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING1, ih_rb_cntl);
|
||||||
|
ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2);
|
||||||
|
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL_RING2,
|
||||||
|
RB_USED_INT_THRESHOLD, threshold);
|
||||||
|
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL_RING2, ih_rb_cntl);
|
||||||
|
WREG32_SOC15(OSSSYS, 0, mmIH_CNTL2, ih_cntl);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* navi10_ih_enable_interrupts - Enable the interrupt ring buffer
|
* navi10_ih_enable_interrupts - Enable the interrupt ring buffer
|
||||||
*
|
*
|
||||||
|
@ -371,6 +413,8 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev)
|
||||||
|
|
||||||
/* enable interrupts */
|
/* enable interrupts */
|
||||||
navi10_ih_enable_interrupts(adev);
|
navi10_ih_enable_interrupts(adev);
|
||||||
|
/* enable wptr force update for self int */
|
||||||
|
force_update_wptr_for_self_int(adev, 0, 8, true);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -384,6 +428,7 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev)
|
||||||
*/
|
*/
|
||||||
static void navi10_ih_irq_disable(struct amdgpu_device *adev)
|
static void navi10_ih_irq_disable(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
|
force_update_wptr_for_self_int(adev, 0, 8, false);
|
||||||
navi10_ih_disable_interrupts(adev);
|
navi10_ih_disable_interrupts(adev);
|
||||||
|
|
||||||
/* Wait and acknowledge irq */
|
/* Wait and acknowledge irq */
|
||||||
|
|
Loading…
Reference in New Issue