diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/1710-drm-amd-display-Prevent-vblank-irq-disable-while-VRR.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/1710-drm-amd-display-Prevent-vblank-irq-disable-while-VRR.patch | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/1710-drm-amd-display-Prevent-vblank-irq-disable-while-VRR.patch b/common/recipes-kernel/linux/linux-yocto-4.19.8/1710-drm-amd-display-Prevent-vblank-irq-disable-while-VRR.patch new file mode 100644 index 00000000..c6e3513d --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.19.8/1710-drm-amd-display-Prevent-vblank-irq-disable-while-VRR.patch @@ -0,0 +1,98 @@ +From ba6f989ba71e003ead3067fea61302b7b8fac147 Mon Sep 17 00:00:00 2001 +From: Mario Kleiner <mario.kleiner.de@gmail.com> +Date: Fri, 29 Mar 2019 13:00:54 +0100 +Subject: [PATCH 1710/2940] drm/amd/display: Prevent vblank irq disable while + VRR is active. (v3) + +During VRR mode we can not allow vblank irq dis-/enable +transitions, as an enable after a disable can happen at +an arbitrary time during the video refresh cycle, e.g., +with a high likelyhood inside vblank front-porch. An +enable during front-porch would cause vblank timestamp +updates/calculations which are completely bogus, given +the code can't know when the vblank will end as long +as we are in front-porch with no page flip completed. + +Hold a permanent vblank reference on the crtc while +in active VRR mode to prevent a vblank disable, and +drop the reference again when switching back to fixed +refresh rate non-VRR mode. + +v2: Make sure transition is also handled if vrr is + disabled and stream gets disabled in the same + atomic commit by moving the call to the transition + function outside of plane commit. + Suggested by Nicholas. + +v3: Trivial rebase onto previous patch. + +Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> +Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> +--- + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 36 +++++++++++++++++++ + 1 file changed, 36 insertions(+) + +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 65da7ed1bd38..ed37a368d4fd 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -252,6 +252,12 @@ get_crtc_by_otg_inst(struct amdgpu_device *adev, + return NULL; + } + ++static inline bool amdgpu_dm_vrr_active(struct dm_crtc_state *dm_state) ++{ ++ return dm_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE || ++ dm_state->freesync_config.state == VRR_STATE_ACTIVE_FIXED; ++} ++ + static void dm_pflip_high_irq(void *interrupt_params) + { + struct amdgpu_crtc *amdgpu_crtc; +@@ -4865,6 +4871,31 @@ static void pre_update_freesync_state_on_stream( + new_crtc_state->vrr_params = vrr_params; + } + ++static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, ++ struct dm_crtc_state *new_state) ++{ ++ bool old_vrr_active = amdgpu_dm_vrr_active(old_state); ++ bool new_vrr_active = amdgpu_dm_vrr_active(new_state); ++ ++ if (!old_vrr_active && new_vrr_active) { ++ /* Transition VRR inactive -> active: ++ * While VRR is active, we must not disable vblank irq, as a ++ * reenable after disable would compute bogus vblank/pflip ++ * timestamps if it likely happened inside display front-porch. ++ */ ++ drm_crtc_vblank_get(new_state->base.crtc); ++ DRM_DEBUG_DRIVER("%s: crtc=%u VRR off->on: Get vblank ref\n", ++ __func__, new_state->base.crtc->base.id); ++ } else if (old_vrr_active && !new_vrr_active) { ++ /* Transition VRR active -> inactive: ++ * Allow vblank irq disable again for fixed refresh rate. ++ */ ++ drm_crtc_vblank_put(new_state->base.crtc); ++ DRM_DEBUG_DRIVER("%s: crtc=%u VRR on->off: Drop vblank ref\n", ++ __func__, new_state->base.crtc->base.id); ++ } ++} ++ + static void amdgpu_dm_commit_planes(struct drm_atomic_state *state, + struct dc_state *dc_state, + struct drm_device *dev, +@@ -5400,6 +5431,11 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) + + dm_new_crtc_state = to_dm_crtc_state(new_crtc_state); + dm_old_crtc_state = to_dm_crtc_state(old_crtc_state); ++ ++ /* Handle vrr on->off / off->on transitions */ ++ amdgpu_dm_handle_vrr_transition(dm_old_crtc_state, ++ dm_new_crtc_state); ++ + modeset_needed = modeset_required( + new_crtc_state, + dm_new_crtc_state->stream, +-- +2.17.1 + |