]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/amd/display: Allow RX6xxx & RX7700 to invoke amdgpu_irq_get/put
authorIvan Lipski <ivan.lipski@amd.com>
Tue, 2 Sep 2025 20:20:09 +0000 (16:20 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 15 Sep 2025 21:24:42 +0000 (17:24 -0400)
[Why&How]
As reported on https://gitlab.freedesktop.org/drm/amd/-/issues/3936,
SMU hang can occur if the interrupts are not enabled appropriately,
causing a vblank timeout.

This patch reverts commit 5009628d8509 ("drm/amd/display: Remove unnecessary
amdgpu_irq_get/put"), but only for RX6xxx & RX7700 GPUs, on which the
issue was observed.

This will re-enable interrupts regardless of whether the user space needed
it or not.

Fixes: 5009628d8509 ("drm/amd/display: Remove unnecessary amdgpu_irq_get/put")
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/3936
Suggested-by: Sun peng Li <sunpeng.li@amd.com>
Reviewed-by: Sun peng Li <sunpeng.li@amd.com>
Signed-off-by: Ivan Lipski <ivan.lipski@amd.com>
Signed-off-by: Ray Wu <ray.wu@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 95d168b367aa28a59f94fc690ff76ebf69312c6d)
Cc: stable@vger.kernel.org
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c

index 4e86370ae70599259533c9743a1ddd52fe69e399..97d9eba1796357323346ecc15ba3dee00b200bb2 100644 (file)
@@ -8717,7 +8717,16 @@ static int amdgpu_dm_encoder_init(struct drm_device *dev,
 static void manage_dm_interrupts(struct amdgpu_device *adev,
                                 struct amdgpu_crtc *acrtc,
                                 struct dm_crtc_state *acrtc_state)
-{
+{      /*
+        * We cannot be sure that the frontend index maps to the same
+        * backend index - some even map to more than one.
+        * So we have to go through the CRTC to find the right IRQ.
+        */
+       int irq_type = amdgpu_display_crtc_idx_to_irq_type(
+                       adev,
+                       acrtc->crtc_id);
+       struct drm_device *dev = adev_to_drm(adev);
+
        struct drm_vblank_crtc_config config = {0};
        struct dc_crtc_timing *timing;
        int offdelay;
@@ -8770,7 +8779,35 @@ static void manage_dm_interrupts(struct amdgpu_device *adev,
 
                drm_crtc_vblank_on_config(&acrtc->base,
                                          &config);
+               /* Allow RX6xxx, RX7700, RX7800 GPUs to call amdgpu_irq_get.*/
+               switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
+               case IP_VERSION(3, 0, 0):
+               case IP_VERSION(3, 0, 2):
+               case IP_VERSION(3, 0, 3):
+               case IP_VERSION(3, 2, 0):
+                       if (amdgpu_irq_get(adev, &adev->pageflip_irq, irq_type))
+                               drm_err(dev, "DM_IRQ: Cannot get pageflip irq!\n");
+#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
+                       if (amdgpu_irq_get(adev, &adev->vline0_irq, irq_type))
+                               drm_err(dev, "DM_IRQ: Cannot get vline0 irq!\n");
+#endif
+               }
+
        } else {
+               /* Allow RX6xxx, RX7700, RX7800 GPUs to call amdgpu_irq_put.*/
+               switch (amdgpu_ip_version(adev, DCE_HWIP, 0)) {
+               case IP_VERSION(3, 0, 0):
+               case IP_VERSION(3, 0, 2):
+               case IP_VERSION(3, 0, 3):
+               case IP_VERSION(3, 2, 0):
+#if defined(CONFIG_DRM_AMD_SECURE_DISPLAY)
+                       if (amdgpu_irq_put(adev, &adev->vline0_irq, irq_type))
+                               drm_err(dev, "DM_IRQ: Cannot put vline0 irq!\n");
+#endif
+                       if (amdgpu_irq_put(adev, &adev->pageflip_irq, irq_type))
+                               drm_err(dev, "DM_IRQ: Cannot put pageflip irq!\n");
+               }
+
                drm_crtc_vblank_off(&acrtc->base);
        }
 }