From: Aric Cyr <[email protected]>

[Why]
Flickering is observed on some displays when the number of inserted BTR
frames changes frequently.

[How]
Add in a margin of drift to prevent the inserted number of frames from
jumping around too frequently.

Change-Id: I592ce229f93faa74b5baa2e43a89c9e5a6174103
Signed-off-by: Aric Cyr <[email protected]>
Reviewed-by: Nicholas Kazlauskas <[email protected]>
Acked-by: Bhawanpreet Lakha <[email protected]>
---
 .../amd/display/modules/freesync/freesync.c   | 24 +++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c 
b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index bfd27f10879e..5f493e9d6bbb 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -37,6 +37,8 @@
 #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 change BTR multiplier (to avoid frequent changes) */
+#define BTR_DRIFT_MARGIN 2000
 /*Threshold to exit fixed refresh rate*/
 #define FIXED_REFRESH_EXIT_MARGIN_IN_HZ 4
 /* Number of consecutive frames to check before entering/exiting fixed 
refresh*/
@@ -248,6 +250,7 @@ static void apply_below_the_range(struct core_freesync 
*core_freesync,
        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),
@@ -318,10 +321,27 @@ 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 (delta_from_mid_point_in_us_1 < 
delta_from_mid_point_in_us_2) {
                        frames_to_insert = mid_point_frames_ceil;
-               else
+                       delta_from_mid_point_delta_in_us = 
delta_from_mid_point_in_us_2 -
+                                       delta_from_mid_point_in_us_1;
+               } else {
                        frames_to_insert = mid_point_frames_floor;
+                       delta_from_mid_point_delta_in_us = 
delta_from_mid_point_in_us_1 -
+                                       delta_from_mid_point_in_us_2;
+               }
+
+               /* Prefer current frame multiplier when BTR is enabled unless 
it drifts
+                * too far from the midpoint
+                */
+               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) &&
+                               ((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;
+               }
 
                /* Either we've calculated the number of frames to insert,
                 * or we need to insert min duration frames
-- 
2.17.1

_______________________________________________
amd-gfx mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Reply via email to