diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1847-drm-amd-display-Compensate-for-pre-DCE12-BTR-VRR-hw-.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1847-drm-amd-display-Compensate-for-pre-DCE12-BTR-VRR-hw-.patch | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1847-drm-amd-display-Compensate-for-pre-DCE12-BTR-VRR-hw-.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1847-drm-amd-display-Compensate-for-pre-DCE12-BTR-VRR-hw-.patch new file mode 100644 index 00000000..515a3dbc --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/1847-drm-amd-display-Compensate-for-pre-DCE12-BTR-VRR-hw-.patch @@ -0,0 +1,188 @@ +From 734b642c4329f6803ebb87b80cff85f50a55dab2 Mon Sep 17 00:00:00 2001 +From: Mario Kleiner <mario.kleiner.de@gmail.com> +Date: Fri, 26 Apr 2019 23:40:16 +0200 +Subject: [PATCH 1847/2940] drm/amd/display: Compensate for pre-DCE12 BTR-VRR + hw limitations. (v3) + +Pre-DCE12 needs special treatment for BTR / low framerate +compensation for more stable behaviour: + +According to comments in the code and some testing on DCE-8 +and DCE-11, DCE-11 and earlier only apply VTOTAL_MIN/MAX +programming with a lag of one frame, so the special BTR hw +programming for intermediate fixed duration frames must be +done inside the current frame at flip submission in atomic +commit tail, ie. one vblank earlier, and the fixed refresh +intermediate frame mode must be also terminated one vblank +earlier on pre-DCE12 display engines. + +To achieve proper termination on < DCE-12 shift the point +when the switch-back from fixed vblank duration to variable +vblank duration happens from the start of VBLANK (vblank irq, +as done on DCE-12+) to back-porch or end of VBLANK (handled +by vupdate irq handler). We must leave the switch-back code +inside VBLANK irq for DCE12+, as before. + +Doing this, we get much better behaviour of BTR for up-sweeps, +ie. going from short to long frame durations (~high to low fps) +and for constant framerate flips, as tested on DCE-8 and +DCE-11. Behaviour is still not quite as good as on DCN-1 +though. + +On down-sweeps, going from long to short frame durations +(low fps to high fps) < DCE-12 is a little bit improved, +although by far not as much as for up-sweeps and constant +fps. + +v2: Fix some wrong locking, as pointed out by Nicholas. +v3: Simplify if-condition in vupdate-irq - nit by Nicholas. +Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> +Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com> +Signed-off-by: Chaudhary Amit Kumar <Chaudharyamit.Kumar@amd.com> +--- + .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 47 +++++++++++++++++-- + 1 file changed, 43 insertions(+), 4 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 258c00f300a2..a7f9d13b41cd 100644 +--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c ++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +@@ -364,6 +364,7 @@ static void dm_vupdate_high_irq(void *interrupt_params) + struct amdgpu_device *adev = irq_params->adev; + struct amdgpu_crtc *acrtc; + struct dm_crtc_state *acrtc_state; ++ unsigned long flags; + + acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VUPDATE); + +@@ -379,8 +380,25 @@ static void dm_vupdate_high_irq(void *interrupt_params) + * page-flip completion events that have been queued to us + * if a pageflip happened inside front-porch. + */ +- if (amdgpu_dm_vrr_active(acrtc_state)) ++ if (amdgpu_dm_vrr_active(acrtc_state)) { + drm_crtc_handle_vblank(&acrtc->base); ++ ++ /* BTR processing for pre-DCE12 ASICs */ ++ if (acrtc_state->stream && ++ adev->family < AMDGPU_FAMILY_AI) { ++ spin_lock_irqsave(&adev->ddev->event_lock, flags); ++ mod_freesync_handle_v_update( ++ adev->dm.freesync_module, ++ acrtc_state->stream, ++ &acrtc_state->vrr_params); ++ ++ dc_stream_adjust_vmin_vmax( ++ adev->dm.dc, ++ acrtc_state->stream, ++ &acrtc_state->vrr_params.adjust); ++ spin_unlock_irqrestore(&adev->ddev->event_lock, flags); ++ } ++ } + } + } + +@@ -390,6 +408,7 @@ static void dm_crtc_high_irq(void *interrupt_params) + struct amdgpu_device *adev = irq_params->adev; + struct amdgpu_crtc *acrtc; + struct dm_crtc_state *acrtc_state; ++ unsigned long flags; + + acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VBLANK); + +@@ -412,9 +431,10 @@ static void dm_crtc_high_irq(void *interrupt_params) + */ + amdgpu_dm_crtc_handle_crc_irq(&acrtc->base); + +- if (acrtc_state->stream && ++ if (acrtc_state->stream && adev->family >= AMDGPU_FAMILY_AI && + acrtc_state->vrr_params.supported && + acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE) { ++ spin_lock_irqsave(&adev->ddev->event_lock, flags); + mod_freesync_handle_v_update( + adev->dm.freesync_module, + acrtc_state->stream, +@@ -424,6 +444,7 @@ static void dm_crtc_high_irq(void *interrupt_params) + adev->dm.dc, + acrtc_state->stream, + &acrtc_state->vrr_params.adjust); ++ spin_unlock_irqrestore(&adev->ddev->event_lock, flags); + } + } + } +@@ -5175,8 +5196,10 @@ static void update_freesync_state_on_stream( + struct dc_plane_state *surface, + u32 flip_timestamp_in_us) + { +- struct mod_vrr_params vrr_params = new_crtc_state->vrr_params; ++ struct mod_vrr_params vrr_params; + struct dc_info_packet vrr_infopacket = {0}; ++ struct amdgpu_device *adev = dm->adev; ++ unsigned long flags; + + if (!new_stream) + return; +@@ -5189,6 +5212,9 @@ static void update_freesync_state_on_stream( + if (!new_stream->timing.h_total || !new_stream->timing.v_total) + return; + ++ spin_lock_irqsave(&adev->ddev->event_lock, flags); ++ vrr_params = new_crtc_state->vrr_params; ++ + if (surface) { + mod_freesync_handle_preflip( + dm->freesync_module, +@@ -5196,6 +5222,11 @@ static void update_freesync_state_on_stream( + new_stream, + flip_timestamp_in_us, + &vrr_params); ++ if (adev->family < AMDGPU_FAMILY_AI && ++ amdgpu_dm_vrr_active(new_crtc_state)) { ++ mod_freesync_handle_v_update(dm->freesync_module, ++ new_stream, &vrr_params); ++ } + } + + mod_freesync_build_vrr_infopacket( +@@ -5227,6 +5258,8 @@ static void update_freesync_state_on_stream( + new_crtc_state->base.crtc->base.id, + (int)new_crtc_state->base.vrr_enabled, + (int)vrr_params.state); ++ ++ spin_unlock_irqrestore(&adev->ddev->event_lock, flags); + } + + static void pre_update_freesync_state_on_stream( +@@ -5234,8 +5267,10 @@ static void pre_update_freesync_state_on_stream( + struct dm_crtc_state *new_crtc_state) + { + struct dc_stream_state *new_stream = new_crtc_state->stream; +- struct mod_vrr_params vrr_params = new_crtc_state->vrr_params; ++ struct mod_vrr_params vrr_params; + struct mod_freesync_config config = new_crtc_state->freesync_config; ++ struct amdgpu_device *adev = dm->adev; ++ unsigned long flags; + + if (!new_stream) + return; +@@ -5247,6 +5282,9 @@ static void pre_update_freesync_state_on_stream( + if (!new_stream->timing.h_total || !new_stream->timing.v_total) + return; + ++ spin_lock_irqsave(&adev->ddev->event_lock, flags); ++ vrr_params = new_crtc_state->vrr_params; ++ + if (new_crtc_state->vrr_supported && + config.min_refresh_in_uhz && + config.max_refresh_in_uhz) { +@@ -5267,6 +5305,7 @@ static void pre_update_freesync_state_on_stream( + sizeof(vrr_params.adjust)) != 0); + + new_crtc_state->vrr_params = vrr_params; ++ spin_unlock_irqrestore(&adev->ddev->event_lock, flags); + } + + static void amdgpu_dm_handle_vrr_transition(struct dm_crtc_state *old_state, +-- +2.17.1 + |