summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-06-05 11:34:03 (GMT)
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-06-10 17:44:40 (GMT)
commitcdbd2316a03f68b25a135a34d1d24f01ddef0c53 (patch)
treef32daccbee3911ca8130143743dfe60727dd22d4 /drivers/gpu/drm/i915/intel_display.c
parentb6f3eff7130bbdb3d3ca5b7bbff2384b362606b4 (diff)
downloadlinux-fsl-qoriq-cdbd2316a03f68b25a135a34d1d24f01ddef0c53.tar.xz
drm/i915: fix up pch pll handling in ->mode_set
We ->mode_set is called we can't just blindly reuse an existing pll since that might be shared with a different, still active pch output. v2: Only update the pll settings when the pch pll is know to be unused, otherwise we can wreak havoc with a running pipe. Which in the case of DP will likely result in a black screen due to loss of link lock. v3: Tighten up the asserts a bit more, especially make sure that the pch pll is still enabled when we try to disable it. This would have caught the bug fixed in this patch. Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> 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.c35
1 files changed, 19 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6b37b75..1d0aa24 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1427,7 +1427,8 @@ static void ironlake_enable_pch_pll(struct intel_crtc *intel_crtc)
/* PCH refclock must be enabled first */
assert_pch_refclk_enabled(dev_priv);
- if (pll->active++ && pll->on) {
+ if (pll->active++) {
+ WARN_ON(!pll->on);
assert_pch_pll_enabled(dev_priv, pll, NULL);
return;
}
@@ -1468,10 +1469,9 @@ static void intel_disable_pch_pll(struct intel_crtc *intel_crtc)
return;
}
- if (--pll->active) {
- assert_pch_pll_enabled(dev_priv, pll, NULL);
+ assert_pch_pll_enabled(dev_priv, pll, NULL);
+ if (--pll->active)
return;
- }
DRM_DEBUG_KMS("disabling PCH PLL %x\n", pll->pll_reg);
@@ -3081,9 +3081,9 @@ static struct intel_pch_pll *intel_get_pch_pll(struct intel_crtc *intel_crtc, u3
pll = intel_crtc->pch_pll;
if (pll) {
- DRM_DEBUG_KMS("CRTC:%d reusing existing PCH PLL %x\n",
+ DRM_DEBUG_KMS("CRTC:%d dropping existing PCH PLL %x\n",
intel_crtc->base.base.id, pll->pll_reg);
- goto prepare;
+ intel_put_pch_pll(intel_crtc);
}
if (HAS_PCH_IBX(dev_priv->dev)) {
@@ -3128,19 +3128,22 @@ static struct intel_pch_pll *intel_get_pch_pll(struct intel_crtc *intel_crtc, u3
found:
intel_crtc->pch_pll = pll;
- pll->refcount++;
DRM_DEBUG_DRIVER("using pll %d for pipe %c\n", i, pipe_name(intel_crtc->pipe));
-prepare: /* separate function? */
- DRM_DEBUG_DRIVER("switching PLL %x off\n", pll->pll_reg);
+ if (pll->active == 0) {
+ DRM_DEBUG_DRIVER("setting up pll %d\n", i);
+ WARN_ON(pll->on);
+ assert_pch_pll_disabled(dev_priv, pll, NULL);
- /* Wait for the clocks to stabilize before rewriting the regs */
- I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE);
- POSTING_READ(pll->pll_reg);
- udelay(150);
+ /* Wait for the clocks to stabilize before rewriting the regs */
+ I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE);
+ POSTING_READ(pll->pll_reg);
+ udelay(150);
+
+ I915_WRITE(pll->fp0_reg, fp);
+ I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE);
+ }
+ pll->refcount++;
- I915_WRITE(pll->fp0_reg, fp);
- I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE);
- pll->on = false;
return pll;
}