mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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: 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>
This commit is contained in:
		
							parent
							
								
									f9e6759888
								
							
						
					
					
						commit
						7fb363c575
					
				
					 2 changed files with 47 additions and 37 deletions
				
			
		| 
						 | 
					@ -8246,42 +8246,10 @@ static void manage_dm_interrupts(struct amdgpu_device *adev,
 | 
				
			||||||
				 struct amdgpu_crtc *acrtc,
 | 
									 struct amdgpu_crtc *acrtc,
 | 
				
			||||||
				 bool enable)
 | 
									 bool enable)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	/*
 | 
						if (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) {
 | 
					 | 
				
			||||||
		drm_crtc_vblank_on(&acrtc->base);
 | 
							drm_crtc_vblank_on(&acrtc->base);
 | 
				
			||||||
		amdgpu_irq_get(
 | 
						else
 | 
				
			||||||
			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);
 | 
					 | 
				
			||||||
		drm_crtc_vblank_off(&acrtc->base);
 | 
							drm_crtc_vblank_off(&acrtc->base);
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void dm_update_pflip_irq_state(struct amdgpu_device *adev,
 | 
					static void dm_update_pflip_irq_state(struct amdgpu_device *adev,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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 dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state);
 | 
				
			||||||
	struct amdgpu_display_manager *dm = &adev->dm;
 | 
						struct amdgpu_display_manager *dm = &adev->dm;
 | 
				
			||||||
	struct vblank_control_work *work;
 | 
						struct vblank_control_work *work;
 | 
				
			||||||
 | 
						int irq_type;
 | 
				
			||||||
	int rc = 0;
 | 
						int rc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (acrtc->otg_inst == -1)
 | 
						if (acrtc->otg_inst == -1)
 | 
				
			||||||
		goto skip;
 | 
							goto skip;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						irq_type = amdgpu_display_crtc_idx_to_irq_type(adev, acrtc->crtc_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (enable) {
 | 
						if (enable) {
 | 
				
			||||||
		/* vblank irq on -> Only need vupdate irq in vrr mode */
 | 
							/* vblank irq on -> Only need vupdate irq in vrr mode */
 | 
				
			||||||
		if (amdgpu_dm_crtc_vrr_active(acrtc_state))
 | 
							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)
 | 
						if (rc)
 | 
				
			||||||
		return rc;
 | 
							return rc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc = (enable)
 | 
						/* crtc vblank or vstartup interrupt */
 | 
				
			||||||
		? amdgpu_irq_get(adev, &adev->crtc_irq, acrtc->crtc_id)
 | 
						if (enable) {
 | 
				
			||||||
		: amdgpu_irq_put(adev, &adev->crtc_irq, acrtc->crtc_id);
 | 
							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)
 | 
						if (rc)
 | 
				
			||||||
		return 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:
 | 
					skip:
 | 
				
			||||||
	if (amdgpu_in_reset(adev))
 | 
						if (amdgpu_in_reset(adev))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue