From: Daniel Vetter Date: Mon, 26 Nov 2012 16:22:10 +0000 (+0100) Subject: drm/i915: track is_dual_link in intel_lvds X-Git-Tag: next-20130218~64^2~24^2~86 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=13c7d8703127334890c894ddab13b3a92a26580a;p=karo-tx-linux.git drm/i915: track is_dual_link in intel_lvds Yeah, all users (both the clock selection special cases and the lvds pin pair stuff) are still in common code, but this will change. v2: Rebase on top of Jani Nikula's panel rework. v3: Incorporate review from Paulo Zanoni: - s/__is_dual_link_lvds/compute_is_dual_link_lvds - kill dev_priv->lvds_val - drop spurious whitespace change v4: Add a debug printk to display the dual-link status, as suggested by Paulo Zanoni in review. Reviewed-by: Paulo Zanoni (v3) Signed-off-by: Daniel Vetter --- diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 79589bbff3db..9be7efd43c6a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -705,7 +705,6 @@ typedef struct drm_i915_private { unsigned int display_clock_mode:1; int lvds_ssc_freq; unsigned int bios_lvds_val; /* initial [PCH_]LVDS reg val in VBIOS */ - unsigned int lvds_val; /* used for checking LVDS channel mode */ struct { int rate; int lanes; diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 4158a8839433..31fdbfd48e44 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -52,6 +52,7 @@ struct intel_lvds_encoder { u32 pfit_control; u32 pfit_pgm_ratios; bool pfit_dirty; + bool is_dual_link; struct intel_lvds_connector *attached_connector; }; @@ -922,6 +923,23 @@ static const struct dmi_system_id intel_dual_link_lvds[] = { }; bool intel_is_dual_link_lvds(struct drm_device *dev) +{ + struct intel_encoder *encoder; + struct intel_lvds_encoder *lvds_encoder; + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, + base.head) { + if (encoder->type == INTEL_OUTPUT_LVDS) { + lvds_encoder = to_lvds_encoder(&encoder->base); + + return lvds_encoder->is_dual_link; + } + } + + return false; +} + +static bool compute_is_dual_link_lvds(struct drm_device *dev) { unsigned int val; struct drm_i915_private *dev_priv = dev->dev_private; @@ -940,19 +958,15 @@ bool intel_is_dual_link_lvds(struct drm_device *dev) if (dmi_check_system(intel_dual_link_lvds)) return true; - if (dev_priv->lvds_val) - val = dev_priv->lvds_val; - else { - /* BIOS should set the proper LVDS register value at boot, but - * in reality, it doesn't set the value when the lid is closed; - * we need to check "the value to be set" in VBT when LVDS - * register is uninitialized. - */ - val = I915_READ(lvds_reg); - if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED))) - val = dev_priv->bios_lvds_val; - dev_priv->lvds_val = val; - } + /* BIOS should set the proper LVDS register value at boot, but + * in reality, it doesn't set the value when the lid is closed; + * we need to check "the value to be set" in VBT when LVDS + * register is uninitialized. + */ + val = I915_READ(lvds_reg); + if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED))) + val = dev_priv->bios_lvds_val; + return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP; } @@ -1162,6 +1176,10 @@ bool intel_lvds_init(struct drm_device *dev) goto failed; out: + lvds_encoder->is_dual_link = compute_is_dual_link_lvds(dev); + DRM_DEBUG_KMS("detected %s-link lvds configuration\n", + lvds_encoder->is_dual_link ? "dual" : "single"); + /* * Unlock registers and just * leave them unlocked