Commit 7fb363c5 authored by Leo Li's avatar Leo Li Committed by Alex Deucher
Browse files

drm/amd/display: Let drm_crtc_vblank_on/off manage interrupts



[Why]
We manage interrupts for CRTCs in two places:
1. In manage_dm_interrupts(), when CRTC get enabled or disabled
2. When drm_vblank_get/put() starts or kills the vblank counter, calling
   into amdgpu_dm_crtc_set_vblank()

The interrupts managed by these twp places should be identical.

[How]
Since manage_dm_interrupts() already use drm_crtc_vblank_on/off(), just
move all CRTC interrupt management into amdgpu_dm_crtc_set_vblank().

This has the added benefit of disabling all CRTC and HUBP interrupts
when there are no vblank requestors.

Note that there is a TODO item - unchanged from when it was first
introduced - to properly identify the HUBP instance from the OTG
instance, rather than just assume direct mapping.

Signed-off-by: default avatarLeo Li <sunpeng.li@amd.com>
Reviewed-by: default avatarAurabindo Pillai <aurabindo.pillai@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarRodrigo Siqueira <rodrigo.siqueira@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent f9e67598
Loading
Loading
Loading
Loading
+2 −34
Original line number Diff line number Diff line
@@ -8246,43 +8246,11 @@ static void manage_dm_interrupts(struct amdgpu_device *adev,
				 struct amdgpu_crtc *acrtc,
				 bool enable)
{
	/*
	 * We have no guarantee that the frontend index maps to the same
	 * backend index - some even map to more than one.
	 *
	 * TODO: Use a different interrupt or check DC itself for the mapping.
	 */
	int irq_type =
		amdgpu_display_crtc_idx_to_irq_type(
			adev,
			acrtc->crtc_id);

	if (enable) {
	if (enable)
		drm_crtc_vblank_on(&acrtc->base);
		amdgpu_irq_get(
			adev,
			&adev->pageflip_irq,
			irq_type);
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
		amdgpu_irq_get(
			adev,
			&adev->vline0_irq,
			irq_type);
#endif
	} else {
#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
		amdgpu_irq_put(
			adev,
			&adev->vline0_irq,
			irq_type);
#endif
		amdgpu_irq_put(
			adev,
			&adev->pageflip_irq,
			irq_type);
	else
		drm_crtc_vblank_off(&acrtc->base);
}
}

static void dm_update_pflip_irq_state(struct amdgpu_device *adev,
				      struct amdgpu_crtc *acrtc)
+45 −3
Original line number Diff line number Diff line
@@ -286,11 +286,14 @@ static inline int amdgpu_dm_crtc_set_vblank(struct drm_crtc *crtc, bool enable)
	struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state);
	struct amdgpu_display_manager *dm = &adev->dm;
	struct vblank_control_work *work;
	int irq_type;
	int rc = 0;

	if (acrtc->otg_inst == -1)
		goto skip;

	irq_type = amdgpu_display_crtc_idx_to_irq_type(adev, acrtc->crtc_id);

	if (enable) {
		/* vblank irq on -> Only need vupdate irq in vrr mode */
		if (amdgpu_dm_crtc_vrr_active(acrtc_state))
@@ -303,13 +306,52 @@ static inline int amdgpu_dm_crtc_set_vblank(struct drm_crtc *crtc, bool enable)
	if (rc)
		return rc;

	rc = (enable)
		? amdgpu_irq_get(adev, &adev->crtc_irq, acrtc->crtc_id)
		: amdgpu_irq_put(adev, &adev->crtc_irq, acrtc->crtc_id);
	/* crtc vblank or vstartup interrupt */
	if (enable) {
		rc = amdgpu_irq_get(adev, &adev->crtc_irq, irq_type);
		drm_dbg_vbl(crtc->dev, "Get crtc_irq ret=%d\n", rc);
	} else {
		rc = amdgpu_irq_put(adev, &adev->crtc_irq, irq_type);
		drm_dbg_vbl(crtc->dev, "Put crtc_irq ret=%d\n", rc);
	}

	if (rc)
		return rc;

	/*
	 * hubp surface flip interrupt
	 *
	 * We have no guarantee that the frontend index maps to the same
	 * backend index - some even map to more than one.
	 *
	 * TODO: Use a different interrupt or check DC itself for the mapping.
	 */
	if (enable) {
		rc = amdgpu_irq_get(adev, &adev->pageflip_irq, irq_type);
		drm_dbg_vbl(crtc->dev, "Get pageflip_irq ret=%d\n", rc);
	} else {
		rc = amdgpu_irq_put(adev, &adev->pageflip_irq, irq_type);
		drm_dbg_vbl(crtc->dev, "Put pageflip_irq ret=%d\n", rc);
	}

	if (rc)
		return rc;

#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
	/* crtc vline0 interrupt, only available on DCN+ */
	if (amdgpu_ip_version(adev, DCE_HWIP, 0) != 0) {
		if (enable) {
			rc = amdgpu_irq_get(adev, &adev->vline0_irq, irq_type);
			drm_dbg_vbl(crtc->dev, "Get vline0_irq ret=%d\n", rc);
		} else {
			rc = amdgpu_irq_put(adev, &adev->vline0_irq, irq_type);
			drm_dbg_vbl(crtc->dev, "Put vline0_irq ret=%d\n", rc);
		}

		if (rc)
			return rc;
	}
#endif
skip:
	if (amdgpu_in_reset(adev))
		return 0;