[Intel-gfx] Broken LVDS output at mode changes

Takashi Iwai tiwai at suse.de
Wed Mar 28 15:29:04 CEST 2012


Hi,

we've encountered a broken LVDS output on some IVY/SNB machines when
the mode is changed (from/to native resolution).  When this happens,
the whole laptop panel gets half white and half black.  This doesn't
recover until the LVDS is turned off once.

And, there is no signficant difference between working and non-working
cases in the register dumps.  From the software POV, all looks sane.
So, we suspect this is rather specific to some panel hardware.

However, through debugging, I found that disabling LVDS at mode change
works around the problem.  A test patch is attached below.

My question now is: can this workaround have any serious drawback?
I thought of a longer blank time, but I didn't notice any difference
before and after the patch.

Or, any other suggestion as a saner fix?


thanks,

Takashi

---
---
 drivers/gpu/drm/i915/intel_lvds.c |   23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -398,6 +398,26 @@ out:
 	return true;
 }
 
+static int intel_disable_at_modeset_callback(const struct dmi_system_id *id)
+{
+	DRM_DEBUG_KMS("Disabling LVDS at modeset for %s\n", id->ident);
+	return 1;
+}
+
+/* Requires to disable LVDS for avoiding a broken screen at mode change */
+static const struct dmi_system_id intel_disable_at_modeset[] = {
+	{
+		.callback = intel_disable_at_modeset_callback,
+		.ident = "HP ProBook",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
+			DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook"),
+		},
+	},
+
+	{ }	/* terminating entry */
+};
+
 static void intel_lvds_prepare(struct drm_encoder *encoder)
 {
 	struct intel_lvds *intel_lvds = to_intel_lvds(encoder);
@@ -407,7 +427,8 @@ static void intel_lvds_prepare(struct dr
 	 * the panel fitter. However at all other times we can just reset
 	 * the registers regardless.
 	 */
-	if (!HAS_PCH_SPLIT(encoder->dev) && intel_lvds->pfit_dirty)
+	if ((!HAS_PCH_SPLIT(encoder->dev) && intel_lvds->pfit_dirty) ||
+	    dmi_check_system(intel_disable_at_modeset))
 		intel_lvds_disable(intel_lvds);
 }
 



More information about the Intel-gfx mailing list