aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
diff options
context:
space:
mode:
authorAnthony Koo <Anthony.Koo@amd.com>2018-04-04 21:01:21 -0400
committerAlex Deucher <alexander.deucher@amd.com>2018-08-27 12:10:52 -0400
commitff6014d63a87d9a801ddd9ddd10359b2dead6943 (patch)
treef1496b5e41a87c9294df6bfd4cf6427e67d883bb /drivers/gpu/drm/amd/display/modules/freesync/freesync.c
parente80e9446084168c4f186f502dd15e6241bf454a1 (diff)
drm/amd/display: Fix bug where refresh rate becomes fixed
This issue occurs if refresh rate range is very small and lfc is not used. When frame spikes occur, refresh rate becomes fixed and will not restore properly Signed-off-by: Anthony Koo <Anthony.Koo@amd.com> Reviewed-by: Aric Cyr <Aric.Cyr@amd.com> Acked-by: Harry Wentland <harry.wentland@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/modules/freesync/freesync.c')
-rw-r--r--drivers/gpu/drm/amd/display/modules/freesync/freesync.c43
1 files changed, 23 insertions, 20 deletions
diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index 4af73a72b9a9..be6a6c63b4cc 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -168,21 +168,6 @@ static unsigned int calc_v_total_from_duration(
168 return v_total; 168 return v_total;
169} 169}
170 170
171static unsigned long long calc_nominal_field_rate(const struct dc_stream_state *stream)
172{
173 unsigned long long nominal_field_rate_in_uhz = 0;
174
175 /* Calculate nominal field rate for stream */
176 nominal_field_rate_in_uhz = stream->timing.pix_clk_khz;
177 nominal_field_rate_in_uhz *= 1000ULL * 1000ULL * 1000ULL;
178 nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz,
179 stream->timing.h_total);
180 nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz,
181 stream->timing.v_total);
182
183 return nominal_field_rate_in_uhz;
184}
185
186static void update_v_total_for_static_ramp( 171static void update_v_total_for_static_ramp(
187 struct core_freesync *core_freesync, 172 struct core_freesync *core_freesync,
188 const struct dc_stream_state *stream, 173 const struct dc_stream_state *stream,
@@ -441,10 +426,11 @@ static void apply_fixed_refresh(struct core_freesync *core_freesync,
441 in_out_vrr->adjust.v_total_min; 426 in_out_vrr->adjust.v_total_min;
442 } else { 427 } else {
443 in_out_vrr->adjust.v_total_min = 428 in_out_vrr->adjust.v_total_min =
444 calc_v_total_from_refresh( 429 calc_v_total_from_refresh(stream,
445 stream, in_out_vrr->max_refresh_in_uhz); 430 in_out_vrr->max_refresh_in_uhz);
446 in_out_vrr->adjust.v_total_max = 431 in_out_vrr->adjust.v_total_max =
447 in_out_vrr->adjust.v_total_min; 432 calc_v_total_from_refresh(stream,
433 in_out_vrr->min_refresh_in_uhz);
448 } 434 }
449 } 435 }
450} 436}
@@ -638,7 +624,8 @@ void mod_freesync_build_vrr_params(struct mod_freesync *mod_freesync,
638 core_freesync = MOD_FREESYNC_TO_CORE(mod_freesync); 624 core_freesync = MOD_FREESYNC_TO_CORE(mod_freesync);
639 625
640 /* Calculate nominal field rate for stream */ 626 /* Calculate nominal field rate for stream */
641 nominal_field_rate_in_uhz = calc_nominal_field_rate(stream); 627 nominal_field_rate_in_uhz =
628 mod_freesync_calc_nominal_field_rate(stream);
642 629
643 min_refresh_in_uhz = in_config->min_refresh_in_uhz; 630 min_refresh_in_uhz = in_config->min_refresh_in_uhz;
644 max_refresh_in_uhz = in_config->max_refresh_in_uhz; 631 max_refresh_in_uhz = in_config->max_refresh_in_uhz;
@@ -888,6 +875,22 @@ void mod_freesync_get_settings(struct mod_freesync *mod_freesync,
888 } 875 }
889} 876}
890 877
878unsigned long long mod_freesync_calc_nominal_field_rate(
879 const struct dc_stream_state *stream)
880{
881 unsigned long long nominal_field_rate_in_uhz = 0;
882
883 /* Calculate nominal field rate for stream */
884 nominal_field_rate_in_uhz = stream->timing.pix_clk_khz;
885 nominal_field_rate_in_uhz *= 1000ULL * 1000ULL * 1000ULL;
886 nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz,
887 stream->timing.h_total);
888 nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz,
889 stream->timing.v_total);
890
891 return nominal_field_rate_in_uhz;
892}
893
891bool mod_freesync_is_valid_range(struct mod_freesync *mod_freesync, 894bool mod_freesync_is_valid_range(struct mod_freesync *mod_freesync,
892 const struct dc_stream_state *stream, 895 const struct dc_stream_state *stream,
893 uint32_t min_refresh_cap_in_uhz, 896 uint32_t min_refresh_cap_in_uhz,
@@ -897,7 +900,7 @@ bool mod_freesync_is_valid_range(struct mod_freesync *mod_freesync,
897{ 900{
898 /* Calculate nominal field rate for stream */ 901 /* Calculate nominal field rate for stream */
899 unsigned long long nominal_field_rate_in_uhz = 902 unsigned long long nominal_field_rate_in_uhz =
900 calc_nominal_field_rate(stream); 903 mod_freesync_calc_nominal_field_rate(stream);
901 904
902 // Check nominal is within range 905 // Check nominal is within range
903 if (nominal_field_rate_in_uhz > max_refresh_cap_in_uhz || 906 if (nominal_field_rate_in_uhz > max_refresh_cap_in_uhz ||