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>
This commit is contained in:
Anthony Koo 2018-04-17 11:40:31 -04:00 committed by Alex Deucher
parent 953c2901c8
commit bf2af91cb3

View File

@ -887,12 +887,41 @@ bool mod_freesync_is_valid_range(struct mod_freesync *mod_freesync,
unsigned long long nominal_field_rate_in_uhz =
mod_freesync_calc_nominal_field_rate(stream);
/* Allow for some rounding error of actual video timing by taking ceil.
* For example, 144 Hz mode timing may actually be 143.xxx Hz when
* calculated from pixel rate and vertical/horizontal totals, but
* this should be allowed instead of blocking FreeSync.
/* Typically nominal refresh calculated can have some fractional part.
* Allow for some rounding error of actual video timing by taking floor
* of caps and request. Round the nominal refresh rate.
*
* Dividing will convert everything to units in Hz although input
* variable name is in uHz!
*
* Also note, this takes care of rounding error on the nominal refresh
* so by rounding error we only expect it to be off by a small amount,
* such as < 0.1 Hz. i.e. 143.9xxx or 144.1xxx.
*
* Example 1. Caps Min = 40 Hz, Max = 144 Hz
* Request Min = 40 Hz, Max = 144 Hz
* Nominal = 143.5x Hz rounded to 144 Hz
* This function should allow this as valid request
*
* Example 2. Caps Min = 40 Hz, Max = 144 Hz
* Request Min = 40 Hz, Max = 144 Hz
* Nominal = 144.4x Hz rounded to 144 Hz
* This function should allow this as valid request
*
* Example 3. Caps Min = 40 Hz, Max = 144 Hz
* Request Min = 40 Hz, Max = 144 Hz
* Nominal = 120.xx Hz rounded to 120 Hz
* This function should return NOT valid since the requested
* max is greater than current timing's nominal
*
* Example 4. Caps Min = 40 Hz, Max = 120 Hz
* Request Min = 40 Hz, Max = 120 Hz
* Nominal = 144.xx Hz rounded to 144 Hz
* This function should return NOT valid since the nominal
* is greater than the capability's max refresh
*/
nominal_field_rate_in_uhz = div_u64(nominal_field_rate_in_uhz, 1000000);
nominal_field_rate_in_uhz =
div_u64(nominal_field_rate_in_uhz + 500000, 1000000);
min_refresh_cap_in_uhz /= 1000000;
max_refresh_cap_in_uhz /= 1000000;
min_refresh_request_in_uhz /= 1000000;