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-17 11:40:31 -0400
committerAlex Deucher <alexander.deucher@amd.com>2018-08-27 12:10:55 -0400
commitbf2af91cb3a4ef1c5f9132687b9818f33d6a389f (patch)
tree13d042e2aea57732fbf91c4c495c2b888a7d683e /drivers/gpu/drm/amd/display/modules/freesync/freesync.c
parent953c2901c860da16963b48db8344bf0fd5b03040 (diff)
drm/amd/display: Correct rounding calcs in mod_freesync_is_valid_range
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.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index 349387eb9fe6..769f46777a1d 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -887,12 +887,41 @@ bool mod_freesync_is_valid_range(struct mod_freesync *mod_freesync,
887 unsigned long long nominal_field_rate_in_uhz = 887 unsigned long long nominal_field_rate_in_uhz =
888 mod_freesync_calc_nominal_field_rate(stream); 888 mod_freesync_calc_nominal_field_rate(stream);
889 889
890 /* Allow for some rounding error of actual video timing by taking ceil. 890 /* Typically nominal refresh calculated can have some fractional part.
891 * For example, 144 Hz mode timing may actually be 143.xxx Hz when 891 * Allow for some rounding error of actual video timing by taking floor
892 * calculated from pixel rate and vertical/horizontal totals, but 892 * of caps and request. Round the nominal refresh rate.
893 * this should be allowed instead of blocking FreeSync. 893 *
894 * Dividing will convert everything to units in Hz although input
895 * variable name is in uHz!
896 *
897 * Also note, this takes care of rounding error on the nominal refresh
898 * so by rounding error we only expect it to be off by a small amount,
899 * such as < 0.1 Hz. i.e. 143.9xxx or 144.1xxx.
900 *
901 * Example 1. Caps Min = 40 Hz, Max = 144 Hz
902 * Request Min = 40 Hz, Max = 144 Hz
903 * Nominal = 143.5x Hz rounded to 144 Hz
904 * This function should allow this as valid request
905 *
906 * Example 2. Caps Min = 40 Hz, Max = 144 Hz
907 * Request Min = 40 Hz, Max = 144 Hz
908 * Nominal = 144.4x Hz rounded to 144 Hz
909 * This function should allow this as valid request
910 *
911 * Example 3. Caps Min = 40 Hz, Max = 144 Hz
912 * Request Min = 40 Hz, Max = 144 Hz
913 * Nominal = 120.xx Hz rounded to 120 Hz
914 * This function should return NOT valid since the requested
915 * max is greater than current timing's nominal
916 *
917 * Example 4. Caps Min = 40 Hz, Max = 120 Hz
918 * Request Min = 40 Hz, Max = 120 Hz
919 * Nominal = 144.xx Hz rounded to 144 Hz
920 * This function should return NOT valid since the nominal
921 * is greater than the capability's max refresh
894 */ 922 */
895 nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz, 1000000); 923 nominal_field_rate_in_uhz =
924 div_u64(nominal_field_rate_in_uhz + 500000, 1000000);
896 min_refresh_cap_in_uhz /= 1000000; 925 min_refresh_cap_in_uhz /= 1000000;
897 max_refresh_cap_in_uhz /= 1000000; 926 max_refresh_cap_in_uhz /= 1000000;
898 min_refresh_request_in_uhz /= 1000000; 927 min_refresh_request_in_uhz /= 1000000;