|
@@ -360,6 +360,27 @@ static const intel_limit_t intel_limits_ironlake_display_port = {
|
|
.find_pll = intel_find_pll_ironlake_dp,
|
|
.find_pll = intel_find_pll_ironlake_dp,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+static bool is_dual_link_lvds(struct drm_i915_private *dev_priv,
|
|
|
|
+ unsigned int reg)
|
|
|
|
+{
|
|
|
|
+ unsigned int val;
|
|
|
|
+
|
|
|
|
+ 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(reg);
|
|
|
|
+ if (!(val & ~LVDS_DETECTED))
|
|
|
|
+ val = dev_priv->bios_lvds_val;
|
|
|
|
+ dev_priv->lvds_val = val;
|
|
|
|
+ }
|
|
|
|
+ return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP;
|
|
|
|
+}
|
|
|
|
+
|
|
static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc,
|
|
static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc,
|
|
int refclk)
|
|
int refclk)
|
|
{
|
|
{
|
|
@@ -368,8 +389,7 @@ static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc,
|
|
const intel_limit_t *limit;
|
|
const intel_limit_t *limit;
|
|
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
|
|
- if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) ==
|
|
|
|
- LVDS_CLKB_POWER_UP) {
|
|
|
|
|
|
+ if (is_dual_link_lvds(dev_priv, PCH_LVDS)) {
|
|
/* LVDS dual channel */
|
|
/* LVDS dual channel */
|
|
if (refclk == 100000)
|
|
if (refclk == 100000)
|
|
limit = &intel_limits_ironlake_dual_lvds_100m;
|
|
limit = &intel_limits_ironlake_dual_lvds_100m;
|
|
@@ -397,8 +417,7 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc)
|
|
const intel_limit_t *limit;
|
|
const intel_limit_t *limit;
|
|
|
|
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
|
|
if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) {
|
|
- if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
|
|
|
|
- LVDS_CLKB_POWER_UP)
|
|
|
|
|
|
+ if (is_dual_link_lvds(dev_priv, LVDS))
|
|
/* LVDS with dual channel */
|
|
/* LVDS with dual channel */
|
|
limit = &intel_limits_g4x_dual_channel_lvds;
|
|
limit = &intel_limits_g4x_dual_channel_lvds;
|
|
else
|
|
else
|
|
@@ -536,8 +555,7 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc,
|
|
* reliably set up different single/dual channel state, if we
|
|
* reliably set up different single/dual channel state, if we
|
|
* even can.
|
|
* even can.
|
|
*/
|
|
*/
|
|
- if ((I915_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
|
|
|
|
- LVDS_CLKB_POWER_UP)
|
|
|
|
|
|
+ if (is_dual_link_lvds(dev_priv, LVDS))
|
|
clock.p2 = limit->p2.p2_fast;
|
|
clock.p2 = limit->p2.p2_fast;
|
|
else
|
|
else
|
|
clock.p2 = limit->p2.p2_slow;
|
|
clock.p2 = limit->p2.p2_slow;
|