aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2012-03-20 08:07:05 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-03-22 18:23:45 -0400
commitb03543857fd75876b96e10d4320b775e95041bb7 (patch)
tree3866fde96f20c80b2632ec2227ce618a7d7b0d57 /drivers/gpu/drm/i915/intel_display.c
parent1a8c55d37268d8b7ab7797e6d378caa697dbd029 (diff)
drm/i915: Check VBIOS value for determining LVDS dual channel mode, too
Currently i915 driver checks [PCH_]LVDS register bits to decide whether to set up the dual-link or the single-link mode. This relies implicitly on that BIOS initializes the register properly at boot. However, BIOS doesn't initialize it always. When the machine is booted with the closed lid, BIOS skips the LVDS reg initialization. This ends up in blank output on a machine with a dual-link LVDS when you open the lid after the boot. This patch adds a workaround for that problem by checking the initial LVDS register value in VBT. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=37742 Tested-By: Paulo Zanoni <paulo.r.zanoni@intel.com> Reviewed-by: Rodrigo Vivi <rodrigo.vivi@gmail.com> Reviewed-by: Adam Jackson <ajax@redhat.com> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 683002fb63d1..a76ac2eb9938 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -360,6 +360,27 @@ static const intel_limit_t intel_limits_ironlake_display_port = {
360 .find_pll = intel_find_pll_ironlake_dp, 360 .find_pll = intel_find_pll_ironlake_dp,
361}; 361};
362 362
363static bool is_dual_link_lvds(struct drm_i915_private *dev_priv,
364 unsigned int reg)
365{
366 unsigned int val;
367
368 if (dev_priv->lvds_val)
369 val = dev_priv->lvds_val;
370 else {
371 /* BIOS should set the proper LVDS register value at boot, but
372 * in reality, it doesn't set the value when the lid is closed;
373 * we need to check "the value to be set" in VBT when LVDS
374 * register is uninitialized.
375 */
376 val = I915_READ(reg);
377 if (!(val & ~LVDS_DETECTED))
378 val = dev_priv->bios_lvds_val;
379 dev_priv->lvds_val = val;
380 }
381 return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP;
382}
383
363static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc, 384static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc,
364 int refclk) 385 int refclk)
365{ 386{
@@ -368,8 +389,7 @@ static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc,
368 const intel_limit_t *limit; 389 const intel_limit_t *limit;
369 390
370 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { 391 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
371 if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == 392 if (is_dual_link_lvds(dev_priv, PCH_LVDS)) {
372 LVDS_CLKB_POWER_UP) {
373 /* LVDS dual channel */ 393 /* LVDS dual channel */
374 if (refclk == 100000) 394 if (refclk == 100000)
375 limit = &intel_limits_ironlake_dual_lvds_100m; 395 limit = &intel_limits_ironlake_dual_lvds_100m;
@@ -397,8 +417,7 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc)
397 const intel_limit_t *limit; 417 const intel_limit_t *limit;
398 418
399 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { 419 if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
400 if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == 420 if (is_dual_link_lvds(dev_priv, LVDS))
401 LVDS_CLKB_POWER_UP)
402 /* LVDS with dual channel */ 421 /* LVDS with dual channel */
403 limit = &intel_limits_g4x_dual_channel_lvds; 422 limit = &intel_limits_g4x_dual_channel_lvds;
404 else 423 else
@@ -536,8 +555,7 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
536 * reliably set up different single/dual channel state, if we 555 * reliably set up different single/dual channel state, if we
537 * even can. 556 * even can.
538 */ 557 */
539 if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) == 558 if (is_dual_link_lvds(dev_priv, LVDS))
540 LVDS_CLKB_POWER_UP)
541 clock.p2 = limit->p2.p2_fast; 559 clock.p2 = limit->p2.p2_fast;
542 else 560 else
543 clock.p2 = limit->p2.p2_slow; 561 clock.p2 = limit->p2.p2_slow;