diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.19.8/0955-drm-amd-display-Add-below-the-range-support-for-Free.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.19.8/0955-drm-amd-display-Add-below-the-range-support-for-Free.patch | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.19.8/0955-drm-amd-display-Add-below-the-range-support-for-Free.patch b/common/recipes-kernel/linux/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/common/recipes-kernel/linux/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 + |