From: Anthony Koo <Anthony.Koo@xxxxxxx> Signed-off-by: Anthony Koo <Anthony.Koo at amd.com> Reviewed-by: Aric Cyr <Aric.Cyr at amd.com> Acked-by: Harry Wentland <harry.wentland at amd.com> --- .../amd/display/modules/freesync/freesync.c | 39 ++++++++++++++++--- 1 file 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, 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; -- 2.17.0