]> www.infradead.org Git - users/hch/configfs.git/commitdiff
drm/amd/display: Let drm_crtc_vblank_on/off manage interrupts
authorLeo Li <sunpeng.li@amd.com>
Thu, 11 Jul 2024 18:31:27 +0000 (14:31 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Sat, 27 Jul 2024 21:30:38 +0000 (17:30 -0400)
[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 <sunpeng.li@amd.com>
Reviewed-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c

index fa8d455de7f5707d2765a89426991f22b977a127..42ca9b52fe5ecc497f4500aea9f96faf9be61665 100644 (file)
@@ -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,
index 99014339aaa390332dad5adae7c7b5809b0db604..1fe038616d9f304948909731653c46b90098be2c 100644 (file)
@@ -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;