From mboxrd@z Thu Jan 1 00:00:00 1970 From: Takashi Iwai Subject: Broken LVDS output at mode changes Date: Wed, 28 Mar 2012 15:29:04 +0200 Message-ID: Mime-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from mx2.suse.de (cantor2.suse.de [195.135.220.15]) by gabe.freedesktop.org (Postfix) with ESMTP id 7391B9EA03 for ; Wed, 28 Mar 2012 06:29:05 -0700 (PDT) Received: from relay2.suse.de (unknown [195.135.220.254]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 572268FA98 for ; Wed, 28 Mar 2012 15:29:04 +0200 (CEST) List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces+gcfxdi-intel-gfx=m.gmane.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+gcfxdi-intel-gfx=m.gmane.org@lists.freedesktop.org To: intel-gfx@lists.freedesktop.org List-Id: intel-gfx@lists.freedesktop.org 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); }