From: Ville Syrjälä <ville.syrj...@linux.intel.com>

Some monitors apparently forget to mark any mode as preferred in the
EDID. In this particular case we have a very generic looking ID
"PNP Model 0 Serial Number 4" / "LVDS 800x600" so a specific quirk
doesn't seem particularly wise. Also the quirk we have
(EDID_QUIRK_FIRST_DETAILED_PREFERRED) is actually defunct so we'd
have to fix it first.

As a generic fallback let's just mark the first probed mode (which
should be the first detailed mode, assuming there are any) as
preferred.

On this particular machine the VBIOS seems to pick the 800x600
60Hz EST mode, which has the opposite sync polarities to the
800x600 60Hz detailed timings. But since it works I guess we
can ignore that slight discrepancy.

Cc: Adam Jackson <a...@redhat.com>
Cc: Roberto Viola <cagnul...@gmail.com>
Tested-by: Roberto Viola <cagnul...@gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=109780
Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
---
 drivers/gpu/drm/drm_edid.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 5f142530532a..6c6a93647686 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -1828,7 +1828,7 @@ static void edid_fixup_preferred(struct drm_connector 
*connector,
        list_for_each_entry_safe(cur_mode, t, &connector->probed_modes, head) {
                cur_mode->type &= ~DRM_MODE_TYPE_PREFERRED;
 
-               if (cur_mode == preferred_mode)
+               if (cur_mode == preferred_mode || target_refresh == 0)
                        continue;
 
                /* Largest mode is preferred */
@@ -1850,6 +1850,18 @@ static void edid_fixup_preferred(struct drm_connector 
*connector,
        preferred_mode->type |= DRM_MODE_TYPE_PREFERRED;
 }
 
+static bool preferred_mode_exists(struct drm_connector *connector)
+{
+       struct drm_display_mode *mode;
+
+       list_for_each_entry(mode, &connector->probed_modes, head) {
+               if (mode->type & DRM_MODE_TYPE_PREFERRED)
+                       return true;
+       }
+
+       return false;
+}
+
 static bool
 mode_is_rb(const struct drm_display_mode *mode)
 {
@@ -4733,7 +4745,8 @@ int drm_add_edid_modes(struct drm_connector *connector, 
struct edid *edid)
        if (edid->features & DRM_EDID_FEATURE_DEFAULT_GTF)
                num_modes += add_inferred_modes(connector, edid);
 
-       if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75))
+       if (quirks & (EDID_QUIRK_PREFER_LARGE_60 | EDID_QUIRK_PREFER_LARGE_75) 
||
+           !preferred_mode_exists(connector))
                edid_fixup_preferred(connector, quirks);
 
        if (quirks & EDID_QUIRK_FORCE_6BPC)
-- 
2.19.2

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to