Skip to content

Commit e4ed4db

Browse files
anthony-koo2alexdeucher
authored andcommitted
drm/amd/display: Fix LFC multiplier changing erratically
[Why] 1. There is a calculation that is using frame_time_in_us instead of last_render_time_in_us to calculate whether choosing an LFC multiplier would cause the inserted frame duration to be outside of range. 2. We do not handle unsigned integer subtraction correctly and it underflows to a really large value, which causes some logic errors. [How] 1. Fix logic to calculate 'within range' using last_render_time_in_us 2. Split out delta_from_mid_point_delta_in_us calculation to ensure we don't underflow and wrap around Signed-off-by: Anthony Koo <[email protected]> Reviewed-by: Aric Cyr <[email protected]> Acked-by: Qingqing Zhuo <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent a49f672 commit e4ed4db

File tree

1 file changed

+29
-7
lines changed
  • drivers/gpu/drm/amd/display/modules/freesync

1 file changed

+29
-7
lines changed

drivers/gpu/drm/amd/display/modules/freesync/freesync.c

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -324,22 +324,44 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
324324

325325
/* Choose number of frames to insert based on how close it
326326
* can get to the mid point of the variable range.
327+
* - Delta for CEIL: delta_from_mid_point_in_us_1
328+
* - Delta for FLOOR: delta_from_mid_point_in_us_2
327329
*/
328-
if ((frame_time_in_us / mid_point_frames_ceil) > in_out_vrr->min_duration_in_us &&
329-
(delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2 ||
330-
mid_point_frames_floor < 2)) {
330+
if ((last_render_time_in_us / mid_point_frames_ceil) < in_out_vrr->min_duration_in_us) {
331+
/* Check for out of range.
332+
* If using CEIL produces a value that is out of range,
333+
* then we are forced to use FLOOR.
334+
*/
335+
frames_to_insert = mid_point_frames_floor;
336+
} else if (mid_point_frames_floor < 2) {
337+
/* Check if FLOOR would result in non-LFC. In this case
338+
* choose to use CEIL
339+
*/
340+
frames_to_insert = mid_point_frames_ceil;
341+
} else if (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2) {
342+
/* If choosing CEIL results in a frame duration that is
343+
* closer to the mid point of the range.
344+
* Choose CEIL
345+
*/
331346
frames_to_insert = mid_point_frames_ceil;
332-
delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_2 -
333-
delta_from_mid_point_in_us_1;
334347
} else {
348+
/* If choosing FLOOR results in a frame duration that is
349+
* closer to the mid point of the range.
350+
* Choose FLOOR
351+
*/
335352
frames_to_insert = mid_point_frames_floor;
336-
delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_1 -
337-
delta_from_mid_point_in_us_2;
338353
}
339354

340355
/* Prefer current frame multiplier when BTR is enabled unless it drifts
341356
* too far from the midpoint
342357
*/
358+
if (delta_from_mid_point_in_us_1 < delta_from_mid_point_in_us_2) {
359+
delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_2 -
360+
delta_from_mid_point_in_us_1;
361+
} else {
362+
delta_from_mid_point_delta_in_us = delta_from_mid_point_in_us_1 -
363+
delta_from_mid_point_in_us_2;
364+
}
343365
if (in_out_vrr->btr.frames_to_insert != 0 &&
344366
delta_from_mid_point_delta_in_us < BTR_DRIFT_MARGIN) {
345367
if (((last_render_time_in_us / in_out_vrr->btr.frames_to_insert) <

0 commit comments

Comments
 (0)