aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-06-16 15:24:16 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-07-01 05:27:54 -0400
commit66e3d5c09940d08d94b03e65b420fadaa7484318 (patch)
tree971c7ca3eb5324e1e073c36b6da213f510a81745 /drivers/gpu/drm/i915/intel_display.c
parent8bcc2795a68ad9c2010fd5a2548432fad930fcc1 (diff)
drm/i915: move i9xx dpll enabling into crtc enable function
Now that we have the proper pipe config to track this, we don't need to write any registers any more. Note that for platforms without DPLL_MD (pre-gen4) which store the pixel mutliplier in the DPLL register I've decided to keep the seemingly "redundant" write: The comment right below saying "do this trice for luck" doesn't instill confidence ... v2: Drop a few now unnecessary local variables and switch the enable function to take a struct intel_crtc * to simply arguments. v3: Rebase on top of the newly-colored BUG_ON. v4: Amend commit message to alliviate Imre's comment about the redudant DPLL write for the pixel mutliplier. Cc: Imre Deak <imre.deak@intel.com> Cc: Jani Nikula <jani.nikula@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@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.c100
1 files changed, 36 insertions, 64 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4e451faf96c6..1a8a01bc28a4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1331,32 +1331,48 @@ static void vlv_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
1331 udelay(150); /* wait for warmup */ 1331 udelay(150); /* wait for warmup */
1332} 1332}
1333 1333
1334static void i9xx_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) 1334static void i9xx_enable_pll(struct intel_crtc *crtc)
1335{ 1335{
1336 int reg; 1336 struct drm_device *dev = crtc->base.dev;
1337 u32 val; 1337 struct drm_i915_private *dev_priv = dev->dev_private;
1338 int reg = DPLL(crtc->pipe);
1339 u32 dpll = crtc->config.dpll_hw_state.dpll;
1338 1340
1339 assert_pipe_disabled(dev_priv, pipe); 1341 assert_pipe_disabled(dev_priv, crtc->pipe);
1340 1342
1341 /* No really, not for ILK+ */ 1343 /* No really, not for ILK+ */
1342 BUG_ON(dev_priv->info->gen >= 5); 1344 BUG_ON(dev_priv->info->gen >= 5);
1343 1345
1344 /* PLL is protected by panel, make sure we can write it */ 1346 /* PLL is protected by panel, make sure we can write it */
1345 if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev)) 1347 if (IS_MOBILE(dev) && !IS_I830(dev))
1346 assert_panel_unlocked(dev_priv, pipe); 1348 assert_panel_unlocked(dev_priv, crtc->pipe);
1347 1349
1348 reg = DPLL(pipe); 1350 I915_WRITE(reg, dpll);
1349 val = I915_READ(reg); 1351
1350 val |= DPLL_VCO_ENABLE; 1352 /* Wait for the clocks to stabilize. */
1353 POSTING_READ(reg);
1354 udelay(150);
1355
1356 if (INTEL_INFO(dev)->gen >= 4) {
1357 I915_WRITE(DPLL_MD(crtc->pipe),
1358 crtc->config.dpll_hw_state.dpll_md);
1359 } else {
1360 /* The pixel multiplier can only be updated once the
1361 * DPLL is enabled and the clocks are stable.
1362 *
1363 * So write it again.
1364 */
1365 I915_WRITE(reg, dpll);
1366 }
1351 1367
1352 /* We do this three times for luck */ 1368 /* We do this three times for luck */
1353 I915_WRITE(reg, val); 1369 I915_WRITE(reg, dpll);
1354 POSTING_READ(reg); 1370 POSTING_READ(reg);
1355 udelay(150); /* wait for warmup */ 1371 udelay(150); /* wait for warmup */
1356 I915_WRITE(reg, val); 1372 I915_WRITE(reg, dpll);
1357 POSTING_READ(reg); 1373 POSTING_READ(reg);
1358 udelay(150); /* wait for warmup */ 1374 udelay(150); /* wait for warmup */
1359 I915_WRITE(reg, val); 1375 I915_WRITE(reg, dpll);
1360 POSTING_READ(reg); 1376 POSTING_READ(reg);
1361 udelay(150); /* wait for warmup */ 1377 udelay(150); /* wait for warmup */
1362} 1378}
@@ -3646,7 +3662,11 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
3646 intel_crtc->active = true; 3662 intel_crtc->active = true;
3647 intel_update_watermarks(dev); 3663 intel_update_watermarks(dev);
3648 3664
3649 i9xx_enable_pll(dev_priv, pipe); 3665 for_each_encoder_on_crtc(dev, crtc, encoder)
3666 if (encoder->pre_pll_enable)
3667 encoder->pre_pll_enable(encoder);
3668
3669 i9xx_enable_pll(intel_crtc);
3650 3670
3651 for_each_encoder_on_crtc(dev, crtc, encoder) 3671 for_each_encoder_on_crtc(dev, crtc, encoder)
3652 if (encoder->pre_enable) 3672 if (encoder->pre_enable)
@@ -4488,8 +4508,6 @@ static void i9xx_update_pll(struct intel_crtc *crtc,
4488{ 4508{
4489 struct drm_device *dev = crtc->base.dev; 4509 struct drm_device *dev = crtc->base.dev;
4490 struct drm_i915_private *dev_priv = dev->dev_private; 4510 struct drm_i915_private *dev_priv = dev->dev_private;
4491 struct intel_encoder *encoder;
4492 int pipe = crtc->pipe;
4493 u32 dpll; 4511 u32 dpll;
4494 bool is_sdvo; 4512 bool is_sdvo;
4495 struct dpll *clock = &crtc->config.dpll; 4513 struct dpll *clock = &crtc->config.dpll;
@@ -4553,37 +4571,14 @@ static void i9xx_update_pll(struct intel_crtc *crtc,
4553 dpll |= DPLL_VCO_ENABLE; 4571 dpll |= DPLL_VCO_ENABLE;
4554 crtc->config.dpll_hw_state.dpll = dpll; 4572 crtc->config.dpll_hw_state.dpll = dpll;
4555 4573
4556 I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE);
4557 POSTING_READ(DPLL(pipe));
4558 udelay(150);
4559
4560 for_each_encoder_on_crtc(dev, &crtc->base, encoder)
4561 if (encoder->pre_pll_enable)
4562 encoder->pre_pll_enable(encoder);
4563
4564 if (crtc->config.has_dp_encoder)
4565 intel_dp_set_m_n(crtc);
4566
4567 I915_WRITE(DPLL(pipe), dpll);
4568
4569 /* Wait for the clocks to stabilize. */
4570 POSTING_READ(DPLL(pipe));
4571 udelay(150);
4572
4573 if (INTEL_INFO(dev)->gen >= 4) { 4574 if (INTEL_INFO(dev)->gen >= 4) {
4574 u32 dpll_md = (crtc->config.pixel_multiplier - 1) 4575 u32 dpll_md = (crtc->config.pixel_multiplier - 1)
4575 << DPLL_MD_UDI_MULTIPLIER_SHIFT; 4576 << DPLL_MD_UDI_MULTIPLIER_SHIFT;
4576 crtc->config.dpll_hw_state.dpll_md = dpll_md; 4577 crtc->config.dpll_hw_state.dpll_md = dpll_md;
4577
4578 I915_WRITE(DPLL_MD(pipe), dpll_md);
4579 } else {
4580 /* The pixel multiplier can only be updated once the
4581 * DPLL is enabled and the clocks are stable.
4582 *
4583 * So write it again.
4584 */
4585 I915_WRITE(DPLL(pipe), dpll);
4586 } 4578 }
4579
4580 if (crtc->config.has_dp_encoder)
4581 intel_dp_set_m_n(crtc);
4587} 4582}
4588 4583
4589static void i8xx_update_pll(struct intel_crtc *crtc, 4584static void i8xx_update_pll(struct intel_crtc *crtc,
@@ -4592,8 +4587,6 @@ static void i8xx_update_pll(struct intel_crtc *crtc,
4592{ 4587{
4593 struct drm_device *dev = crtc->base.dev; 4588 struct drm_device *dev = crtc->base.dev;
4594 struct drm_i915_private *dev_priv = dev->dev_private; 4589 struct drm_i915_private *dev_priv = dev->dev_private;
4595 struct intel_encoder *encoder;
4596 int pipe = crtc->pipe;
4597 u32 dpll; 4590 u32 dpll;
4598 struct dpll *clock = &crtc->config.dpll; 4591 struct dpll *clock = &crtc->config.dpll;
4599 4592
@@ -4620,27 +4613,6 @@ static void i8xx_update_pll(struct intel_crtc *crtc,
4620 4613
4621 dpll |= DPLL_VCO_ENABLE; 4614 dpll |= DPLL_VCO_ENABLE;
4622 crtc->config.dpll_hw_state.dpll = dpll; 4615 crtc->config.dpll_hw_state.dpll = dpll;
4623
4624 I915_WRITE(DPLL(pipe), dpll & ~DPLL_VCO_ENABLE);
4625 POSTING_READ(DPLL(pipe));
4626 udelay(150);
4627
4628 for_each_encoder_on_crtc(dev, &crtc->base, encoder)
4629 if (encoder->pre_pll_enable)
4630 encoder->pre_pll_enable(encoder);
4631
4632 I915_WRITE(DPLL(pipe), dpll);
4633
4634 /* Wait for the clocks to stabilize. */
4635 POSTING_READ(DPLL(pipe));
4636 udelay(150);
4637
4638 /* The pixel multiplier can only be updated once the
4639 * DPLL is enabled and the clocks are stable.
4640 *
4641 * So write it again.
4642 */
4643 I915_WRITE(DPLL(pipe), dpll);
4644} 4616}
4645 4617
4646static void intel_set_pipe_timings(struct intel_crtc *intel_crtc) 4618static void intel_set_pipe_timings(struct intel_crtc *intel_crtc)