Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Reinstate LFC optimization

[why]
We want to streamline the calculations made when entering LFC.
Previously, the optimizations led to screen tearing and were backed out
to unblock development.

[how]
Integrate other calculations parameters, as well as screen tearing,
fixes with the original LFC calculation optimizations.

Signed-off-by: Amanda Liu <amanda.liu@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Amanda Liu and committed by
Alex Deucher
ded6119e 993dca3e

+20 -13
+19 -13
drivers/gpu/drm/amd/display/modules/freesync/freesync.c
··· 37 37 #define STATIC_SCREEN_RAMP_DELTA_REFRESH_RATE_PER_FRAME ((1000 / 60) * 65) 38 38 /* Number of elements in the render times cache array */ 39 39 #define RENDER_TIMES_MAX_COUNT 10 40 - /* Threshold to exit BTR (to avoid frequent enter-exits at the lower limit) */ 41 - #define BTR_EXIT_MARGIN 2000 40 + /* Threshold to exit/exit BTR (to avoid frequent enter-exits at the lower limit) */ 41 + #define BTR_MAX_MARGIN 2500 42 42 /* Threshold to change BTR multiplier (to avoid frequent changes) */ 43 43 #define BTR_DRIFT_MARGIN 2000 44 44 /*Threshold to exit fixed refresh rate*/ ··· 254 254 unsigned int delta_from_mid_point_in_us_1 = 0xFFFFFFFF; 255 255 unsigned int delta_from_mid_point_in_us_2 = 0xFFFFFFFF; 256 256 unsigned int frames_to_insert = 0; 257 - unsigned int min_frame_duration_in_ns = 0; 258 - unsigned int max_render_time_in_us = in_out_vrr->max_duration_in_us; 259 257 unsigned int delta_from_mid_point_delta_in_us; 260 - 261 - min_frame_duration_in_ns = ((unsigned int) (div64_u64( 262 - (1000000000ULL * 1000000), 263 - in_out_vrr->max_refresh_in_uhz))); 258 + unsigned int max_render_time_in_us = 259 + in_out_vrr->max_duration_in_us - in_out_vrr->btr.margin_in_us; 264 260 265 261 /* Program BTR */ 266 - if (last_render_time_in_us + BTR_EXIT_MARGIN < max_render_time_in_us) { 262 + if ((last_render_time_in_us + in_out_vrr->btr.margin_in_us / 2) < max_render_time_in_us) { 267 263 /* Exit Below the Range */ 268 264 if (in_out_vrr->btr.btr_active) { 269 265 in_out_vrr->btr.frame_counter = 0; 270 266 in_out_vrr->btr.btr_active = false; 271 267 } 272 - } else if (last_render_time_in_us > max_render_time_in_us) { 268 + } else if (last_render_time_in_us > (max_render_time_in_us + in_out_vrr->btr.margin_in_us / 2)) { 273 269 /* Enter Below the Range */ 274 - in_out_vrr->btr.btr_active = true; 270 + if (!in_out_vrr->btr.btr_active) { 271 + in_out_vrr->btr.btr_active = true; 272 + } 275 273 } 276 274 277 275 /* BTR set to "not active" so disengage */ ··· 325 327 /* Choose number of frames to insert based on how close it 326 328 * can get to the mid point of the variable range. 327 329 */ 328 - if (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2) { 330 + if ((frame_time_in_us / mid_point_frames_ceil) > in_out_vrr->min_duration_in_us && 331 + (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2 || 332 + mid_point_frames_floor < 2)) { 329 333 frames_to_insert = mid_point_frames_ceil; 330 334 delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_2 - 331 335 delta_from_mid_point_in_us_1; ··· 343 343 if (in_out_vrr->btr.frames_to_insert != 0 && 344 344 delta_from_mid_point_delta_in_us < BTR_DRIFT_MARGIN) { 345 345 if (((last_render_time_in_us / in_out_vrr->btr.frames_to_insert) < 346 - in_out_vrr->max_duration_in_us) && 346 + max_render_time_in_us) && 347 347 ((last_render_time_in_us / in_out_vrr->btr.frames_to_insert) > 348 348 in_out_vrr->min_duration_in_us)) 349 349 frames_to_insert = in_out_vrr->btr.frames_to_insert; ··· 796 796 refresh_range = in_out_vrr->max_refresh_in_uhz - 797 797 in_out_vrr->min_refresh_in_uhz; 798 798 799 + in_out_vrr->btr.margin_in_us = in_out_vrr->max_duration_in_us - 800 + 2 * in_out_vrr->min_duration_in_us; 801 + if (in_out_vrr->btr.margin_in_us > BTR_MAX_MARGIN) 802 + in_out_vrr->btr.margin_in_us = BTR_MAX_MARGIN; 803 + 799 804 in_out_vrr->supported = true; 800 805 } 801 806 ··· 816 811 in_out_vrr->btr.inserted_duration_in_us = 0; 817 812 in_out_vrr->btr.frames_to_insert = 0; 818 813 in_out_vrr->btr.frame_counter = 0; 814 + 819 815 in_out_vrr->btr.mid_point_in_us = 820 816 (in_out_vrr->min_duration_in_us + 821 817 in_out_vrr->max_duration_in_us) / 2;
+1
drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
··· 92 92 uint32_t inserted_duration_in_us; 93 93 uint32_t frames_to_insert; 94 94 uint32_t frame_counter; 95 + uint32_t margin_in_us; 95 96 }; 96 97 97 98 struct mod_vrr_params_fixed_refresh {