From: Tom Chung <chiahsuan.ch...@amd.com>

[WHY & HOW]
IPS & self-fresh feature can cause vblank counter resets between
vblank disable and enable.
It may cause system stuck due to wait the vblank counter.

Call the drm_crtc_vblank_restore() during vblank enable to estimate
missed vblanks by using timestamps and update the vblank counter in
DRM.

It can make the vblank counter increase smoothly and resolve this issue.

Cc: Mario Limonciello <mario.limoncie...@amd.com>
Cc: Alex Deucher <alexander.deuc...@amd.com>
Cc: sta...@vger.kernel.org
Reviewed-by: Sun peng (Leo) Li <sunpeng...@amd.com>
Signed-off-by: Tom Chung <chiahsuan.ch...@amd.com>
Signed-off-by: Alex Hung <alex.h...@amd.com>
---
 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c    | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c 
b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
index 010172f930ae..45feb404b097 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
@@ -299,6 +299,25 @@ static inline int amdgpu_dm_crtc_set_vblank(struct 
drm_crtc *crtc, bool enable)
        irq_type = amdgpu_display_crtc_idx_to_irq_type(adev, acrtc->crtc_id);
 
        if (enable) {
+               struct dc *dc = adev->dm.dc;
+               struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
+               struct psr_settings *psr = 
&acrtc_state->stream->link->psr_settings;
+               struct replay_settings *pr = 
&acrtc_state->stream->link->replay_settings;
+               bool sr_supported = (psr->psr_version != 
DC_PSR_VERSION_UNSUPPORTED) ||
+                                                               
pr->config.replay_supported;
+
+               /*
+                * IPS & self-refresh feature can cause vblank counter resets 
between
+                * vblank disable and enable.
+                * It may cause system stuck due to waiting for the vblank 
counter.
+                * Call this function to estimate missed vblanks by using 
timestamps and
+                * update the vblank counter in DRM.
+                */
+               if (dc->caps.ips_support &&
+                       dc->config.disable_ips != DMUB_IPS_DISABLE_ALL &&
+                       sr_supported && vblank->config.disable_immediate)
+                       drm_crtc_vblank_restore(crtc);
+
                /* vblank irq on -> Only need vupdate irq in vrr mode */
                if (amdgpu_dm_crtc_vrr_active(acrtc_state))
                        rc = amdgpu_dm_crtc_set_vupdate_irq(crtc, true);
-- 
2.43.0

Reply via email to