Commit 5ea6f9c2 authored by Chengming Gui's avatar Chengming Gui Committed by Alex Deucher
Browse files

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: default avatarChengming Gui <Jack.Gui@amd.com>
Reviewed-by: default avatarFeifei Xu <Feifei.Xu@amd.com>
Acked-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c652923a
Loading
Loading
Loading
Loading
+45 −0
Original line number Diff line number Diff line
@@ -39,6 +39,48 @@

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
 *
@@ -371,6 +413,8 @@ static int navi10_ih_irq_init(struct amdgpu_device *adev)

	/* enable interrupts */
	navi10_ih_enable_interrupts(adev);
	/* enable wptr force update for self int */
	force_update_wptr_for_self_int(adev, 0, 8, true);

	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)
{
	force_update_wptr_for_self_int(adev, 0, 8, false);
	navi10_ih_disable_interrupts(adev);

	/* Wait and acknowledge irq */