Skip to content

Commit 075ad48

Browse files
Bayan Zabihiyangregkh
Bayan Zabihiyan
authored andcommitted
drm/amd/display: Fix frames_to_insert math
[ Upstream commit a463b26 ] [Why] The math on deciding on how many "frames to insert" sometimes sent us over the max refresh rate. Also integer overflow can occur if we have high refresh rates. [How] Instead of clipping the frame duration such that it doesn’t go below the min, just remove a frame from the number of frames to insert. + Use unsigned long long for intermediate calculations to prevent integer overflow. Signed-off-by: Bayan Zabihiyan <[email protected]> Reviewed-by: Aric Cyr <[email protected]> Acked-by: Leo Li <[email protected]> Signed-off-by: Alex Deucher <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 73de2ba commit 075ad48

File tree

1 file changed

+17
-10
lines changed
  • drivers/gpu/drm/amd/display/modules/freesync

1 file changed

+17
-10
lines changed

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

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,12 @@ static void apply_below_the_range(struct core_freesync *core_freesync,
433433
/* Either we've calculated the number of frames to insert,
434434
* or we need to insert min duration frames
435435
*/
436+
if (last_render_time_in_us / frames_to_insert <
437+
in_out_vrr->min_duration_in_us){
438+
frames_to_insert -= (frames_to_insert > 1) ?
439+
1 : 0;
440+
}
441+
436442
if (frames_to_insert > 0)
437443
inserted_frame_duration_in_us = last_render_time_in_us /
438444
frames_to_insert;
@@ -885,8 +891,8 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,
885891
struct core_freesync *core_freesync = NULL;
886892
unsigned long long nominal_field_rate_in_uhz = 0;
887893
unsigned int refresh_range = 0;
888-
unsigned int min_refresh_in_uhz = 0;
889-
unsigned int max_refresh_in_uhz = 0;
894+
unsigned long long min_refresh_in_uhz = 0;
895+
unsigned long long max_refresh_in_uhz = 0;
890896

891897
if (mod_freesync == NULL)
892898
return;
@@ -913,7 +919,7 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,
913919
min_refresh_in_uhz = nominal_field_rate_in_uhz;
914920

915921
if (!vrr_settings_require_update(core_freesync,
916-
in_config, min_refresh_in_uhz, max_refresh_in_uhz,
922+
in_config, (unsigned int)min_refresh_in_uhz, (unsigned int)max_refresh_in_uhz,
917923
in_out_vrr))
918924
return;
919925

@@ -929,15 +935,15 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,
929935
return;
930936

931937
} else {
932-
in_out_vrr->min_refresh_in_uhz = min_refresh_in_uhz;
938+
in_out_vrr->min_refresh_in_uhz = (unsigned int)min_refresh_in_uhz;
933939
in_out_vrr->max_duration_in_us =
934940
calc_duration_in_us_from_refresh_in_uhz(
935-
min_refresh_in_uhz);
941+
(unsigned int)min_refresh_in_uhz);
936942

937-
in_out_vrr->max_refresh_in_uhz = max_refresh_in_uhz;
943+
in_out_vrr->max_refresh_in_uhz = (unsigned int)max_refresh_in_uhz;
938944
in_out_vrr->min_duration_in_us =
939945
calc_duration_in_us_from_refresh_in_uhz(
940-
max_refresh_in_uhz);
946+
(unsigned int)max_refresh_in_uhz);
941947

942948
refresh_range = in_out_vrr->max_refresh_in_uhz -
943949
in_out_vrr->min_refresh_in_uhz;
@@ -948,17 +954,18 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,
948954
in_out_vrr->fixed.ramping_active = in_config->ramping;
949955

950956
in_out_vrr->btr.btr_enabled = in_config->btr;
957+
951958
if (in_out_vrr->max_refresh_in_uhz <
952959
2 * in_out_vrr->min_refresh_in_uhz)
953960
in_out_vrr->btr.btr_enabled = false;
961+
954962
in_out_vrr->btr.btr_active = false;
955963
in_out_vrr->btr.inserted_duration_in_us = 0;
956964
in_out_vrr->btr.frames_to_insert = 0;
957965
in_out_vrr->btr.frame_counter = 0;
958966
in_out_vrr->btr.mid_point_in_us =
959-
in_out_vrr->min_duration_in_us +
960-
(in_out_vrr->max_duration_in_us -
961-
in_out_vrr->min_duration_in_us) / 2;
967+
(in_out_vrr->min_duration_in_us +
968+
in_out_vrr->max_duration_in_us) / 2;
962969

963970
if (in_out_vrr->state == VRR_STATE_UNSUPPORTED) {
964971
in_out_vrr->adjust.v_total_min = stream->timing.v_total;

0 commit comments

Comments
 (0)