aboutsummaryrefslogtreecommitdiffstats
path: root/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3849-drm-amd-display-Improve-LFC-behaviour.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3849-drm-amd-display-Improve-LFC-behaviour.patch')
-rw-r--r--meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3849-drm-amd-display-Improve-LFC-behaviour.patch124
1 files changed, 124 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3849-drm-amd-display-Improve-LFC-behaviour.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3849-drm-amd-display-Improve-LFC-behaviour.patch
new file mode 100644
index 00000000..53bda9f3
--- /dev/null
+++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.19.8/3849-drm-amd-display-Improve-LFC-behaviour.patch
@@ -0,0 +1,124 @@
+From f689d334f54b3ed43320221ae014f13b6023f627 Mon Sep 17 00:00:00 2001
+From: Aric Cyr <aric.cyr@amd.com>
+Date: Tue, 3 Sep 2019 18:18:08 -0400
+Subject: [PATCH 3849/4256] drm/amd/display: Improve LFC behaviour
+
+[Why]
+There can be some unsynchronized frames when entering/exiting
+LFC. This may cause tearing or stuttering at such transitions.
+
+[How]
+Add a enter/exit margin to algorithm to smoothly transition into
+and out of LFC without desynchronizing frames.
+
+Signed-off-by: Aric Cyr <aric.cyr@amd.com>
+Reviewed-by: Reza Amini <Reza.Amini@amd.com>
+Acked-by: Leo Li <sunpeng.li@amd.com>
+Acked-by: Sivapiriyan Kumarasamy <Sivapiriyan.Kumarasamy@amd.com>
+---
+ .../amd/display/modules/freesync/freesync.c | 32 +++++++++++--------
+ .../amd/display/modules/inc/mod_freesync.h | 1 +
+ 2 files changed, 20 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+index 107d81ea689b..5e5ce9e5eab7 100644
+--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
++++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+@@ -35,8 +35,8 @@
+ #define STATIC_SCREEN_RAMP_DELTA_REFRESH_RATE_PER_FRAME ((1000 / 60) * 65)
+ /* Number of elements in the render times cache array */
+ #define RENDER_TIMES_MAX_COUNT 10
+-/* Threshold to exit BTR (to avoid frequent enter-exits at the lower limit) */
+-#define BTR_EXIT_MARGIN 2000
++/* Threshold to exit/exit BTR (to avoid frequent enter-exits at the lower limit) */
++#define BTR_MAX_MARGIN 2500
+ /* Threshold to change BTR multiplier (to avoid frequent changes) */
+ #define BTR_DRIFT_MARGIN 2000
+ /*Threshold to exit fixed refresh rate*/
+@@ -248,24 +248,22 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
+ unsigned int delta_from_mid_point_in_us_1 = 0xFFFFFFFF;
+ unsigned int delta_from_mid_point_in_us_2 = 0xFFFFFFFF;
+ unsigned int frames_to_insert = 0;
+- unsigned int min_frame_duration_in_ns = 0;
+- unsigned int max_render_time_in_us = in_out_vrr->max_duration_in_us;
+ unsigned int delta_from_mid_point_delta_in_us;
+-
+- min_frame_duration_in_ns = ((unsigned int) (div64_u64(
+- (1000000000ULL * 1000000),
+- in_out_vrr->max_refresh_in_uhz)));
++ unsigned int max_render_time_in_us =
++ in_out_vrr->max_duration_in_us - in_out_vrr->btr.margin_in_us;
+
+ /* Program BTR */
+- if (last_render_time_in_us + BTR_EXIT_MARGIN < max_render_time_in_us) {
++ if ((last_render_time_in_us + in_out_vrr->btr.margin_in_us / 2) < max_render_time_in_us) {
+ /* Exit Below the Range */
+ if (in_out_vrr->btr.btr_active) {
+ in_out_vrr->btr.frame_counter = 0;
+ in_out_vrr->btr.btr_active = false;
+ }
+- } else if (last_render_time_in_us > max_render_time_in_us) {
++ } else if (last_render_time_in_us > (max_render_time_in_us + in_out_vrr->btr.margin_in_us / 2)) {
+ /* Enter Below the Range */
+- in_out_vrr->btr.btr_active = true;
++ if (!in_out_vrr->btr.btr_active) {
++ in_out_vrr->btr.btr_active = true;
++ }
+ }
+
+ /* BTR set to "not active" so disengage */
+@@ -321,7 +319,9 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
+ /* Choose number of frames to insert based on how close it
+ * can get to the mid point of the variable range.
+ */
+- if (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2) {
++ if ((frame_time_in_us / mid_point_frames_ceil) > in_out_vrr->min_duration_in_us &&
++ (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2 ||
++ mid_point_frames_floor < 2)) {
+ frames_to_insert = mid_point_frames_ceil;
+ delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_2 -
+ delta_from_mid_point_in_us_1;
+@@ -337,7 +337,7 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
+ if (in_out_vrr->btr.frames_to_insert != 0 &&
+ delta_from_mid_point_delta_in_us < BTR_DRIFT_MARGIN) {
+ if (((last_render_time_in_us / in_out_vrr->btr.frames_to_insert) <
+- in_out_vrr->max_duration_in_us) &&
++ max_render_time_in_us) &&
+ ((last_render_time_in_us / in_out_vrr->btr.frames_to_insert) >
+ in_out_vrr->min_duration_in_us))
+ frames_to_insert = in_out_vrr->btr.frames_to_insert;
+@@ -786,6 +786,11 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,
+ refresh_range = in_out_vrr->max_refresh_in_uhz -
+ in_out_vrr->min_refresh_in_uhz;
+
++ in_out_vrr->btr.margin_in_us = in_out_vrr->max_duration_in_us -
++ 2 * in_out_vrr->min_duration_in_us;
++ if (in_out_vrr->btr.margin_in_us > BTR_MAX_MARGIN)
++ in_out_vrr->btr.margin_in_us = BTR_MAX_MARGIN;
++
+ in_out_vrr->supported = true;
+ }
+
+@@ -801,6 +806,7 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,
+ in_out_vrr->btr.inserted_duration_in_us = 0;
+ in_out_vrr->btr.frames_to_insert = 0;
+ in_out_vrr->btr.frame_counter = 0;
++
+ in_out_vrr->btr.mid_point_in_us =
+ (in_out_vrr->min_duration_in_us +
+ in_out_vrr->max_duration_in_us) / 2;
+diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
+index dc187844d10b..dbe7835aabcf 100644
+--- a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
++++ b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
+@@ -92,6 +92,7 @@ struct mod_vrr_params_btr {
+ uint32_t inserted_duration_in_us;
+ uint32_t frames_to_insert;
+ uint32_t frame_counter;
++ uint32_t margin_in_us;
+ };
+
+ struct mod_vrr_params_fixed_refresh {
+--
+2.17.1
+