drm/amd/display: Correct rounding calcs in mod_freesync_is_valid_range
authorAnthony Koo <Anthony.Koo@amd.com>
Tue, 17 Apr 2018 15:40:31 +0000 (11:40 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 27 Aug 2018 16:10:55 +0000 (11:10 -0500)
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>
drivers/gpu/drm/amd/display/modules/freesync/freesync.c

index 349387eb9fe662733c9f5f140fc04b5eaaa6dcbd..769f46777a1d55a3a41811fdd45cddc3e39fdfdd 100644 (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;