drm/edid: compare actual vrefresh for all modes for quirks
authorAlex Deucher <alexander.deucher@amd.com>
Thu, 15 Aug 2013 15:42:14 +0000 (11:42 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 11 Nov 2013 16:08:12 +0000 (11:08 -0500)
The vrefresh field of the mode is 0 for most modes
fetched from the EDID (e.g., established timings).
When dealing with monitors that have a bogus preferred
mode, we may not always select the mode we want because
we compare the target refresh to the mode's vrefresh which
is 0 in a lot of cases.

Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
drivers/gpu/drm/drm_edid.c

index 2f325bcd07081ab290b19f85bd23a81c0dd6f36c..fb7cf0e796f668328e7a923dbcada92ba8c2f1c7 100644 (file)
@@ -1329,7 +1329,7 @@ static u32 edid_get_quirks(struct edid *edid)
 }
 
 #define MODE_SIZE(m) ((m)->hdisplay * (m)->vdisplay)
-#define MODE_REFRESH_DIFF(m,r) (abs((m)->vrefresh - target_refresh))
+#define MODE_REFRESH_DIFF(c,t) (abs((c) - (t)))
 
 /**
  * edid_fixup_preferred - set preferred modes based on quirk list
@@ -1344,6 +1344,7 @@ static void edid_fixup_preferred(struct drm_connector *connector,
 {
        struct drm_display_mode *t, *cur_mode, *preferred_mode;
        int target_refresh = 0;
+       int cur_vrefresh, preferred_vrefresh;
 
        if (list_empty(&connector->probed_modes))
                return;
@@ -1366,10 +1367,14 @@ static void edid_fixup_preferred(struct drm_connector *connector,
                if (MODE_SIZE(cur_mode) > MODE_SIZE(preferred_mode))
                        preferred_mode = cur_mode;
 
+               cur_vrefresh = cur_mode->vrefresh ?
+                       cur_mode->vrefresh : drm_mode_vrefresh(cur_mode);
+               preferred_vrefresh = preferred_mode->vrefresh ?
+                       preferred_mode->vrefresh : drm_mode_vrefresh(preferred_mode);
                /* At a given size, try to get closest to target refresh */
                if ((MODE_SIZE(cur_mode) == MODE_SIZE(preferred_mode)) &&
-                   MODE_REFRESH_DIFF(cur_mode, target_refresh) <
-                   MODE_REFRESH_DIFF(preferred_mode, target_refresh)) {
+                   MODE_REFRESH_DIFF(cur_vrefresh, target_refresh) <
+                   MODE_REFRESH_DIFF(preferred_vrefresh, target_refresh)) {
                        preferred_mode = cur_mode;
                }
        }