Message ID | 20190321132446.22394-2-ville.syrjala@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [1/6] drm/i915: Refactor EDID fixed mode search | expand |
On Thu, 2019-03-21 at 15:24 +0200, Ville Syrjala wrote: > From: Ville Syrjälä <ville.syrjala@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. > > When there is no preferred mode we currently fall back to the VBT. > That approach fails us here as the VBT mode is 1024x768 whereas > the panel resolution is 800x600. So instead of falling back to the > VBT when there is no preferred mode let's just pick the first > probed mode. Only if the EDID provided no modes we fall back to > the VBT. > > For this machine the VBIOS would appear to select the 800x600 > 60Hz EST mode rather than the first detailed mode (which is > the new fallback will pick). The two modes differ only by > having opposite sync polarities, which does not seem to matter > to the panel in question. Took me a moment to realize this was only about panels on i915, and not any monitor/connector with no preferred modes. Looks sane to me though. Reviewed-by: Adam Jackson <ajax@redhat.com> - ajax
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index f42137512010..b9ee18c2dff5 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -104,11 +104,13 @@ intel_panel_edid_fixed_mode(struct intel_connector *connector) { struct drm_i915_private *dev_priv = to_i915(connector->base.dev); const struct drm_display_mode *scan; + struct drm_display_mode *fixed_mode; + + if (list_empty(&connector->base.probed_modes)) + return NULL; /* prefer fixed mode from EDID if available */ list_for_each_entry(scan, &connector->base.probed_modes, head) { - struct drm_display_mode *fixed_mode; - if ((scan->type & DRM_MODE_TYPE_PREFERRED) == 0) continue; @@ -123,7 +125,20 @@ intel_panel_edid_fixed_mode(struct intel_connector *connector) return fixed_mode; } - return NULL; + scan = list_first_entry(&connector->base.probed_modes, + typeof(*scan), head); + + fixed_mode = drm_mode_duplicate(&dev_priv->drm, scan); + if (!fixed_mode) + return NULL; + + fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; + + DRM_DEBUG_KMS("[CONNECTOR:%d:%s] using first mode from EDID: ", + connector->base.base.id, connector->base.name); + drm_mode_debug_printmodeline(fixed_mode); + + return fixed_mode; } /* adjusted_mode has been preset to be the panel's fixed mode */