From mboxrd@z Thu Jan 1 00:00:00 1970 From: Helge Bahmann Subject: Thinkpad T420 and single/dual channel lvds Date: Wed, 14 Mar 2012 13:37:14 +0100 Message-ID: <201203141337.14798.helge.bahmann@secunet.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: Received: from a.mx.secunet.com (a.mx.secunet.com [195.81.216.161]) by gabe.freedesktop.org (Postfix) with ESMTP id F06479E7A9 for ; Wed, 14 Mar 2012 06:00:08 -0700 (PDT) Content-Disposition: inline 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 Cc: hcb@chaoticmind.net List-Id: intel-gfx@lists.freedesktop.org Hi everyone, Booting a Thinkpad T420 with the lid closed results and opening it subsequently results in an unusable picture on the panel (and no amount of resetting makes it usable): The even pixels show the nominal content of the framebuffer (with the right half missing) whlie the odd pixels show a red-/blueish flicker. A little bit of investigation revealed that with the lid closed on boot, the panel ends up driven in lvds single channel mode, which the panel probably does not like. It appears that the i915 driver relies on the BIOS setting up the PCH_LVDS register for dual channel and will otherwise not ever consider switching. While the following hack makes my display work, it is quite obviously not the right thing to do -- could you investigate if there is a "proper" way to determine whether the panel is supposed to be driven dual channel? Best regards Helge diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f851db7..2e51dc3 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -364,8 +364,8 @@ static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc, const intel_limit_t *limit; if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { - if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == - LVDS_CLKB_POWER_UP) { + if (1 || ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == + LVDS_CLKB_POWER_UP)) { /* LVDS dual channel */ if (refclk == 100000) limit = &intel_limits_ironlake_dual_lvds_100m;