aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0955-drm-amd-display-Add-below-the-range-support-for-Free.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0955-drm-amd-display-Add-below-the-range-support-for-Free.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0955-drm-amd-display-Add-below-the-range-support-for-Free.patch243
1 files changed, 243 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0955-drm-amd-display-Add-below-the-range-support-for-Free.patch b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0955-drm-amd-display-Add-below-the-range-support-for-Free.patch
new file mode 100644
index 00000000..ac50754f
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux-4.19/linux-yocto-4.19.8/0955-drm-amd-display-Add-below-the-range-support-for-Free.patch
@@ -0,0 +1,243 @@
+From fd86dc43369c266d7462d43b6b881b0b174454fa Mon Sep 17 00:00:00 2001
+From: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Date: Wed, 5 Dec 2018 12:08:56 -0500
+Subject: [PATCH 0955/2940] drm/amd/display: Add below the range support for
+ FreeSync
+
+[Why]
+When the flip-rate is below the minimum supported variable refresh rate
+range for the monitor the front porch wait will timeout and be
+frequently misaligned resulting in stuttering and/or flickering.
+
+The FreeSync module can still maintain a smooth and flicker free
+image when the monitor has a refresh rate range such that the maximum
+refresh > 2 * minimum refresh by utilizing low framerate compensation,
+"below the range".
+
+[How]
+Hook up the pre-flip and post-flip handlers from the FreeSync module.
+These adjust the minimum/maximum vrr range to duplicate frames
+when appropriate by tracking flip timestamps.
+
+Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
+Acked-by: Leo Li <sunpeng.li@amd.com>
+Reviewed-by: Harry Wentland <harry.wentland@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+---
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 82 ++++++++++++++-----
+ .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 2 +-
+ 2 files changed, 64 insertions(+), 20 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 61067d206caf..6c93f68f619a 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+@@ -331,12 +331,29 @@ static void dm_crtc_high_irq(void *interrupt_params)
+ struct common_irq_params *irq_params = interrupt_params;
+ struct amdgpu_device *adev = irq_params->adev;
+ struct amdgpu_crtc *acrtc;
++ struct dm_crtc_state *acrtc_state;
+
+ acrtc = get_crtc_by_otg_inst(adev, irq_params->irq_src - IRQ_TYPE_VBLANK);
+
+ if (acrtc) {
+ drm_crtc_handle_vblank(&acrtc->base);
+ amdgpu_dm_crtc_handle_crc_irq(&acrtc->base);
++
++ acrtc_state = to_dm_crtc_state(acrtc->base.state);
++
++ if (acrtc_state->stream &&
++ acrtc_state->vrr_params.supported &&
++ acrtc_state->freesync_config.state == VRR_STATE_ACTIVE_VARIABLE) {
++ 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);
++ }
+ }
+ }
+
+@@ -3027,7 +3044,7 @@ dm_crtc_duplicate_state(struct drm_crtc *crtc)
+ dc_stream_retain(state->stream);
+ }
+
+- state->adjust = cur->adjust;
++ state->vrr_params = cur->vrr_params;
+ state->vrr_infopacket = cur->vrr_infopacket;
+ state->abm_level = cur->abm_level;
+ state->vrr_supported = cur->vrr_supported;
+@@ -4488,9 +4505,11 @@ struct dc_stream_status *dc_state_get_stream_status(
+ static void update_freesync_state_on_stream(
+ struct amdgpu_display_manager *dm,
+ struct dm_crtc_state *new_crtc_state,
+- struct dc_stream_state *new_stream)
++ struct dc_stream_state *new_stream,
++ struct dc_plane_state *surface,
++ u32 flip_timestamp_in_us)
+ {
+- struct mod_vrr_params vrr = {0};
++ struct mod_vrr_params vrr_params = new_crtc_state->vrr_params;
+ struct dc_info_packet vrr_infopacket = {0};
+ struct mod_freesync_config config = new_crtc_state->freesync_config;
+
+@@ -4517,43 +4536,52 @@ static void update_freesync_state_on_stream(
+
+ mod_freesync_build_vrr_params(dm->freesync_module,
+ new_stream,
+- &config, &vrr);
++ &config, &vrr_params);
++
++ if (surface) {
++ mod_freesync_handle_preflip(
++ dm->freesync_module,
++ surface,
++ new_stream,
++ flip_timestamp_in_us,
++ &vrr_params);
++ }
+
+ mod_freesync_build_vrr_infopacket(
+ dm->freesync_module,
+ new_stream,
+- &vrr,
++ &vrr_params,
+ PACKET_TYPE_VRR,
+ TRANSFER_FUNC_UNKNOWN,
+ &vrr_infopacket);
+
+ new_crtc_state->freesync_timing_changed =
+- (memcmp(&new_crtc_state->adjust,
+- &vrr.adjust,
+- sizeof(vrr.adjust)) != 0);
++ (memcmp(&new_crtc_state->vrr_params.adjust,
++ &vrr_params.adjust,
++ sizeof(vrr_params.adjust)) != 0);
+
+ new_crtc_state->freesync_vrr_info_changed =
+ (memcmp(&new_crtc_state->vrr_infopacket,
+ &vrr_infopacket,
+ sizeof(vrr_infopacket)) != 0);
+
+- new_crtc_state->adjust = vrr.adjust;
++ new_crtc_state->vrr_params = vrr_params;
+ new_crtc_state->vrr_infopacket = vrr_infopacket;
+
+- new_stream->adjust = new_crtc_state->adjust;
++ new_stream->adjust = new_crtc_state->vrr_params.adjust;
+ new_stream->vrr_infopacket = vrr_infopacket;
+
+ if (new_crtc_state->freesync_vrr_info_changed)
+ DRM_DEBUG_KMS("VRR packet update: crtc=%u enabled=%d state=%d",
+ new_crtc_state->base.crtc->base.id,
+ (int)new_crtc_state->base.vrr_enabled,
+- (int)vrr.state);
+-
++ (int)vrr_params.state);
++
+ if (new_crtc_state->freesync_timing_changed)
+ DRM_DEBUG_KMS("VRR timing update: crtc=%u min=%u max=%u\n",
+ new_crtc_state->base.crtc->base.id,
+- vrr.adjust.v_total_min,
+- vrr.adjust.v_total_max);
++ vrr_params.adjust.v_total_min,
++ vrr_params.adjust.v_total_max);
+ }
+
+ /*
+@@ -4580,6 +4608,7 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
+ struct dc_stream_update stream_update = {0};
+ struct dm_crtc_state *acrtc_state = to_dm_crtc_state(crtc->state);
+ struct dc_stream_status *stream_status;
++ struct dc_plane_state *surface;
+
+
+ /* Prepare wait for target vblank early - before the fence-waits */
+@@ -4628,6 +4657,7 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
+ addr.address.grph.addr.low_part = lower_32_bits(afb->address);
+ addr.address.grph.addr.high_part = upper_32_bits(afb->address);
+ addr.flip_immediate = async_flip;
++ addr.flip_timestamp_in_us = ktime_get_ns() / 1000;
+
+
+ if (acrtc->base.state->event)
+@@ -4642,8 +4672,10 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
+ return;
+ }
+
+- surface_updates->surface = stream_status->plane_states[0];
+- if (!surface_updates->surface) {
++ surface = stream_status->plane_states[0];
++ surface_updates->surface = surface;
++
++ if (!surface) {
+ DRM_ERROR("No surface for CRTC: id=%d\n",
+ acrtc->crtc_id);
+ return;
+@@ -4654,7 +4686,9 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
+ update_freesync_state_on_stream(
+ &adev->dm,
+ acrtc_state,
+- acrtc_state->stream);
++ acrtc_state->stream,
++ surface,
++ addr.flip_timestamp_in_us);
+
+ if (acrtc_state->freesync_timing_changed)
+ stream_update.adjust =
+@@ -4665,7 +4699,16 @@ static void amdgpu_dm_do_flip(struct drm_crtc *crtc,
+ &acrtc_state->stream->vrr_infopacket;
+ }
+
++ /* Update surface timing information. */
++ surface->time.time_elapsed_in_us[surface->time.index] =
++ addr.flip_timestamp_in_us - surface->time.prev_update_time_in_us;
++ surface->time.prev_update_time_in_us = addr.flip_timestamp_in_us;
++ surface->time.index++;
++ if (surface->time.index >= DC_PLANE_UPDATE_TIMES_MAX)
++ surface->time.index = 0;
++
+ mutex_lock(&adev->dm.dc_lock);
++
+ dc_commit_updates_for_stream(adev->dm.dc,
+ surface_updates,
+ 1,
+@@ -5358,6 +5401,7 @@ static void get_freesync_config_for_crtc(
+ config.max_refresh_in_uhz =
+ aconnector->max_vfreq * 1000000;
+ config.vsif_supported = true;
++ config.btr = true;
+ }
+
+ new_crtc_state->freesync_config = config;
+@@ -5367,8 +5411,8 @@ static void reset_freesync_config_for_crtc(
+ struct dm_crtc_state *new_crtc_state)
+ {
+ new_crtc_state->vrr_supported = false;
+- memset(&new_crtc_state->adjust, 0,
+- sizeof(new_crtc_state->adjust));
++ memset(&new_crtc_state->vrr_params, 0,
++ sizeof(new_crtc_state->vrr_params));
+ memset(&new_crtc_state->vrr_infopacket, 0,
+ sizeof(new_crtc_state->vrr_infopacket));
+ }
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+index 67f5d7fae009..ddb0dab4f8d6 100644
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h
+@@ -265,7 +265,7 @@ struct dm_crtc_state {
+
+ bool vrr_supported;
+ struct mod_freesync_config freesync_config;
+- struct dc_crtc_timing_adjust adjust;
++ struct mod_vrr_params vrr_params;
+ struct dc_info_packet vrr_infopacket;
+
+ int abm_level;
+--
+2.17.1
+