diff options
| author | Ivan Lipski <ivan.lipski@amd.com> | 2025-09-02 16:20:09 -0400 | 
|---|---|---|
| committer | Alex Deucher <alexander.deucher@amd.com> | 2025-09-15 16:57:33 -0400 | 
| commit | 95d168b367aa28a59f94fc690ff76ebf69312c6d (patch) | |
| tree | 776589c1809277a626c510ed34093018f2fb23a1 | |
| parent | 782f0bb5a129f588dc16ad54a2e88c93ef2e079a (diff) | |
drm/amd/display: Allow RX6xxx & RX7700 to invoke amdgpu_irq_get/put
[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>
| -rw-r--r-- | drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 39 | 
1 files changed, 38 insertions, 1 deletions
| diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index fadc6098eaee..b088cb8ae780 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8796,7 +8796,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; @@ -8849,7 +8858,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);  	}  } | 
