Skip to content

Commit

Permalink
drm/amd/display: Let drm_crtc_vblank_on/off manage interrupts
Browse files Browse the repository at this point in the history
[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: Leo Li <[email protected]>
Reviewed-by: Aurabindo Pillai <[email protected]>
Tested-by: Daniel Wheeler <[email protected]>
Signed-off-by: Rodrigo Siqueira <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
  • Loading branch information
leo-sunli1 authored and alexdeucher committed Jul 27, 2024
1 parent f9e6759 commit 7fb363c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 37 deletions.
36 changes: 2 additions & 34 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -8246,42 +8246,10 @@ 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,
Expand Down
48 changes: 45 additions & 3 deletions drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand All @@ -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;
Expand Down

0 comments on commit 7fb363c

Please sign in to comment.