aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2012-04-20 12:11:53 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-05-03 05:18:08 -0400
commitee7b9f93fd96a72e5d09e2b44024c11880873c6b (patch)
tree81686c6a104dccef07ca2ddd9fa9bc95d7f8676b /drivers/gpu/drm/i915/intel_display.c
parentc2798b19bac2538393fc932bfbe59807a4734b3e (diff)
drm/i915: manage PCH PLLs separately from pipes
PCH PLLs aren't required for outputs on the CPU, so we shouldn't just treat them as part of the pipe. So split the code out and manage PCH PLLs separately, allocating them when needed or trying to re-use existing PCH PLL setups when the timings match. v2: add num_pch_pll field to dev_priv (Daniel) don't NULL the pch_pll pointer in disable or DPMS will fail (Jesse) put register offsets in pll struct (Chris) v3: Decouple enable/disable of PLLs from get/put. v4: Track temporary PLL disabling during modeset v5: Tidy PLL initialisation by only checking for num_pch_pll == 0 (Eugeni) v6: Avoid mishandling allocation failure by embedding the small array of PLLs into the device struct Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=44309 Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> (up to v2) Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> (v3+) Reviewed-by: Eugeni Dodonov <eugeni.dodonov@intel.com> Tested-by: Jesse Barnes <jbarnes@virtuousgeek.org> Reviewed-by: Jesse Barnes <jbarnes@virtuousgeek.org> 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.c271
1 files changed, 196 insertions, 75 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 4c844c68ec80..c5f071daa851 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -911,26 +911,28 @@ static void assert_pll(struct drm_i915_private *dev_priv,
911 911
912/* For ILK+ */ 912/* For ILK+ */
913static void assert_pch_pll(struct drm_i915_private *dev_priv, 913static void assert_pch_pll(struct drm_i915_private *dev_priv,
914 enum pipe pipe, bool state) 914 struct intel_crtc *intel_crtc, bool state)
915{ 915{
916 int reg; 916 int reg;
917 u32 val; 917 u32 val;
918 bool cur_state; 918 bool cur_state;
919 919
920 if (!intel_crtc->pch_pll) {
921 WARN(1, "asserting PCH PLL enabled with no PLL\n");
922 return;
923 }
924
920 if (HAS_PCH_CPT(dev_priv->dev)) { 925 if (HAS_PCH_CPT(dev_priv->dev)) {
921 u32 pch_dpll; 926 u32 pch_dpll;
922 927
923 pch_dpll = I915_READ(PCH_DPLL_SEL); 928 pch_dpll = I915_READ(PCH_DPLL_SEL);
924 929
925 /* Make sure the selected PLL is enabled to the transcoder */ 930 /* Make sure the selected PLL is enabled to the transcoder */
926 WARN(!((pch_dpll >> (4 * pipe)) & 8), 931 WARN(!((pch_dpll >> (4 * intel_crtc->pipe)) & 8),
927 "transcoder %d PLL not enabled\n", pipe); 932 "transcoder %d PLL not enabled\n", intel_crtc->pipe);
928
929 /* Convert the transcoder pipe number to a pll pipe number */
930 pipe = (pch_dpll >> (4 * pipe)) & 1;
931 } 933 }
932 934
933 reg = PCH_DPLL(pipe); 935 reg = intel_crtc->pch_pll->pll_reg;
934 val = I915_READ(reg); 936 val = I915_READ(reg);
935 cur_state = !!(val & DPLL_VCO_ENABLE); 937 cur_state = !!(val & DPLL_VCO_ENABLE);
936 WARN(cur_state != state, 938 WARN(cur_state != state,
@@ -1306,60 +1308,79 @@ static void intel_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
1306 * The PCH PLL needs to be enabled before the PCH transcoder, since it 1308 * The PCH PLL needs to be enabled before the PCH transcoder, since it
1307 * drives the transcoder clock. 1309 * drives the transcoder clock.
1308 */ 1310 */
1309static void intel_enable_pch_pll(struct drm_i915_private *dev_priv, 1311static void intel_enable_pch_pll(struct intel_crtc *intel_crtc)
1310 enum pipe pipe)
1311{ 1312{
1313 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
1314 struct intel_pch_pll *pll = intel_crtc->pch_pll;
1312 int reg; 1315 int reg;
1313 u32 val; 1316 u32 val;
1314 1317
1315 if (pipe > 1)
1316 return;
1317
1318 /* PCH only available on ILK+ */ 1318 /* PCH only available on ILK+ */
1319 BUG_ON(dev_priv->info->gen < 5); 1319 BUG_ON(dev_priv->info->gen < 5);
1320 BUG_ON(pll == NULL);
1321 BUG_ON(pll->refcount == 0);
1322
1323 DRM_DEBUG_KMS("enable PCH PLL %x (active %d, on? %d)for crtc %d\n",
1324 pll->pll_reg, pll->active, pll->on,
1325 intel_crtc->base.base.id);
1320 1326
1321 /* PCH refclock must be enabled first */ 1327 /* PCH refclock must be enabled first */
1322 assert_pch_refclk_enabled(dev_priv); 1328 assert_pch_refclk_enabled(dev_priv);
1323 1329
1324 reg = PCH_DPLL(pipe); 1330 if (pll->active++ && pll->on) {
1331 assert_pch_pll_enabled(dev_priv, intel_crtc);
1332 return;
1333 }
1334
1335 DRM_DEBUG_KMS("enabling PCH PLL %x\n", pll->pll_reg);
1336
1337 reg = pll->pll_reg;
1325 val = I915_READ(reg); 1338 val = I915_READ(reg);
1326 val |= DPLL_VCO_ENABLE; 1339 val |= DPLL_VCO_ENABLE;
1327 I915_WRITE(reg, val); 1340 I915_WRITE(reg, val);
1328 POSTING_READ(reg); 1341 POSTING_READ(reg);
1329 udelay(200); 1342 udelay(200);
1343
1344 pll->on = true;
1330} 1345}
1331 1346
1332static void intel_disable_pch_pll(struct drm_i915_private *dev_priv, 1347static void intel_disable_pch_pll(struct intel_crtc *intel_crtc)
1333 enum pipe pipe)
1334{ 1348{
1349 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
1350 struct intel_pch_pll *pll = intel_crtc->pch_pll;
1335 int reg; 1351 int reg;
1336 u32 val, pll_mask = TRANSC_DPLL_ENABLE | TRANSC_DPLLB_SEL, 1352 u32 val;
1337 pll_sel = TRANSC_DPLL_ENABLE;
1338
1339 if (pipe > 1)
1340 return;
1341 1353
1342 /* PCH only available on ILK+ */ 1354 /* PCH only available on ILK+ */
1343 BUG_ON(dev_priv->info->gen < 5); 1355 BUG_ON(dev_priv->info->gen < 5);
1356 if (pll == NULL)
1357 return;
1344 1358
1345 /* Make sure transcoder isn't still depending on us */ 1359 BUG_ON(pll->refcount == 0);
1346 assert_transcoder_disabled(dev_priv, pipe);
1347
1348 if (pipe == 0)
1349 pll_sel |= TRANSC_DPLLA_SEL;
1350 else if (pipe == 1)
1351 pll_sel |= TRANSC_DPLLB_SEL;
1352 1360
1361 DRM_DEBUG_KMS("disable PCH PLL %x (active %d, on? %d) for crtc %d\n",
1362 pll->pll_reg, pll->active, pll->on,
1363 intel_crtc->base.base.id);
1353 1364
1354 if ((I915_READ(PCH_DPLL_SEL) & pll_mask) == pll_sel) 1365 BUG_ON(pll->active == 0);
1366 if (--pll->active) {
1367 assert_pch_pll_enabled(dev_priv, intel_crtc);
1355 return; 1368 return;
1369 }
1370
1371 DRM_DEBUG_KMS("disabling PCH PLL %x\n", pll->pll_reg);
1372
1373 /* Make sure transcoder isn't still depending on us */
1374 assert_transcoder_disabled(dev_priv, intel_crtc->pipe);
1356 1375
1357 reg = PCH_DPLL(pipe); 1376 reg = pll->pll_reg;
1358 val = I915_READ(reg); 1377 val = I915_READ(reg);
1359 val &= ~DPLL_VCO_ENABLE; 1378 val &= ~DPLL_VCO_ENABLE;
1360 I915_WRITE(reg, val); 1379 I915_WRITE(reg, val);
1361 POSTING_READ(reg); 1380 POSTING_READ(reg);
1362 udelay(200); 1381 udelay(200);
1382
1383 pll->on = false;
1363} 1384}
1364 1385
1365static void intel_enable_transcoder(struct drm_i915_private *dev_priv, 1386static void intel_enable_transcoder(struct drm_i915_private *dev_priv,
@@ -1373,7 +1394,7 @@ static void intel_enable_transcoder(struct drm_i915_private *dev_priv,
1373 BUG_ON(dev_priv->info->gen < 5); 1394 BUG_ON(dev_priv->info->gen < 5);
1374 1395
1375 /* Make sure PCH DPLL is enabled */ 1396 /* Make sure PCH DPLL is enabled */
1376 assert_pch_pll_enabled(dev_priv, pipe); 1397 assert_pch_pll_enabled(dev_priv, to_intel_crtc(crtc));
1377 1398
1378 /* FDI must be feeding us bits for PCH ports */ 1399 /* FDI must be feeding us bits for PCH ports */
1379 assert_fdi_tx_enabled(dev_priv, pipe); 1400 assert_fdi_tx_enabled(dev_priv, pipe);
@@ -2578,29 +2599,36 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
2578 struct drm_i915_private *dev_priv = dev->dev_private; 2599 struct drm_i915_private *dev_priv = dev->dev_private;
2579 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 2600 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
2580 int pipe = intel_crtc->pipe; 2601 int pipe = intel_crtc->pipe;
2581 u32 reg, temp, transc_sel; 2602 u32 reg, temp;
2582 2603
2583 /* For PCH output, training FDI link */ 2604 /* For PCH output, training FDI link */
2584 dev_priv->display.fdi_link_train(crtc); 2605 dev_priv->display.fdi_link_train(crtc);
2585 2606
2586 intel_enable_pch_pll(dev_priv, pipe); 2607 intel_enable_pch_pll(intel_crtc);
2587 2608
2588 if (HAS_PCH_CPT(dev)) { 2609 if (HAS_PCH_CPT(dev)) {
2589 transc_sel = intel_crtc->use_pll_a ? TRANSC_DPLLA_SEL : 2610 u32 sel;
2590 TRANSC_DPLLB_SEL;
2591 2611
2592 /* Be sure PCH DPLL SEL is set */
2593 temp = I915_READ(PCH_DPLL_SEL); 2612 temp = I915_READ(PCH_DPLL_SEL);
2594 if (pipe == 0) { 2613 switch (pipe) {
2595 temp &= ~(TRANSA_DPLLB_SEL); 2614 default:
2596 temp |= (TRANSA_DPLL_ENABLE | TRANSA_DPLLA_SEL); 2615 case 0:
2597 } else if (pipe == 1) { 2616 temp |= TRANSA_DPLL_ENABLE;
2598 temp &= ~(TRANSB_DPLLB_SEL); 2617 sel = TRANSA_DPLLB_SEL;
2599 temp |= (TRANSB_DPLL_ENABLE | TRANSB_DPLLB_SEL); 2618 break;
2600 } else if (pipe == 2) { 2619 case 1:
2601 temp &= ~(TRANSC_DPLLB_SEL); 2620 temp |= TRANSB_DPLL_ENABLE;
2602 temp |= (TRANSC_DPLL_ENABLE | transc_sel); 2621 sel = TRANSB_DPLLB_SEL;
2622 break;
2623 case 2:
2624 temp |= TRANSC_DPLL_ENABLE;
2625 sel = TRANSC_DPLLB_SEL;
2626 break;
2603 } 2627 }
2628 if (intel_crtc->pch_pll->pll_reg == _PCH_DPLL_B)
2629 temp |= sel;
2630 else
2631 temp &= ~sel;
2604 I915_WRITE(PCH_DPLL_SEL, temp); 2632 I915_WRITE(PCH_DPLL_SEL, temp);
2605 } 2633 }
2606 2634
@@ -2658,6 +2686,79 @@ static void ironlake_pch_enable(struct drm_crtc *crtc)
2658 intel_enable_transcoder(dev_priv, pipe); 2686 intel_enable_transcoder(dev_priv, pipe);
2659} 2687}
2660 2688
2689static void intel_put_pch_pll(struct intel_crtc *intel_crtc)
2690{
2691 struct intel_pch_pll *pll = intel_crtc->pch_pll;
2692
2693 if (pll == NULL)
2694 return;
2695
2696 if (pll->refcount == 0) {
2697 WARN(1, "bad PCH PLL refcount\n");
2698 return;
2699 }
2700
2701 --pll->refcount;
2702 intel_crtc->pch_pll = NULL;
2703}
2704
2705static struct intel_pch_pll *intel_get_pch_pll(struct intel_crtc *intel_crtc, u32 dpll, u32 fp)
2706{
2707 struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private;
2708 struct intel_pch_pll *pll;
2709 int i;
2710
2711 pll = intel_crtc->pch_pll;
2712 if (pll) {
2713 DRM_DEBUG_KMS("CRTC:%d reusing existing PCH PLL %x\n",
2714 intel_crtc->base.base.id, pll->pll_reg);
2715 goto prepare;
2716 }
2717
2718 for (i = 0; i < dev_priv->num_pch_pll; i++) {
2719 pll = &dev_priv->pch_plls[i];
2720
2721 /* Only want to check enabled timings first */
2722 if (pll->refcount == 0)
2723 continue;
2724
2725 if (dpll == (I915_READ(pll->pll_reg) & 0x7fffffff) &&
2726 fp == I915_READ(pll->fp0_reg)) {
2727 DRM_DEBUG_KMS("CRTC:%d sharing existing PCH PLL %x (refcount %d, ative %d)\n",
2728 intel_crtc->base.base.id,
2729 pll->pll_reg, pll->refcount, pll->active);
2730
2731 goto found;
2732 }
2733 }
2734
2735 /* Ok no matching timings, maybe there's a free one? */
2736 for (i = 0; i < dev_priv->num_pch_pll; i++) {
2737 pll = &dev_priv->pch_plls[i];
2738 if (pll->refcount == 0) {
2739 DRM_DEBUG_KMS("CRTC:%d allocated PCH PLL %x\n",
2740 intel_crtc->base.base.id, pll->pll_reg);
2741 goto found;
2742 }
2743 }
2744
2745 return NULL;
2746
2747found:
2748 intel_crtc->pch_pll = pll;
2749 pll->refcount++;
2750 DRM_DEBUG_DRIVER("using pll %d for pipe %d\n", i, intel_crtc->pipe);
2751prepare: /* separate function? */
2752 DRM_DEBUG_DRIVER("switching PLL %x off\n", pll->pll_reg);
2753 I915_WRITE(pll->fp0_reg, fp);
2754 I915_WRITE(pll->pll_reg, dpll & ~DPLL_VCO_ENABLE);
2755
2756 POSTING_READ(pll->pll_reg);
2757 udelay(150);
2758 pll->on = false;
2759 return pll;
2760}
2761
2661void intel_cpt_verify_modeset(struct drm_device *dev, int pipe) 2762void intel_cpt_verify_modeset(struct drm_device *dev, int pipe)
2662{ 2763{
2663 struct drm_i915_private *dev_priv = dev->dev_private; 2764 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2802,8 +2903,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
2802 } 2903 }
2803 2904
2804 /* disable PCH DPLL */ 2905 /* disable PCH DPLL */
2805 if (!intel_crtc->no_pll) 2906 intel_disable_pch_pll(intel_crtc);
2806 intel_disable_pch_pll(dev_priv, pipe);
2807 2907
2808 /* Switch from PCDclk to Rawclk */ 2908 /* Switch from PCDclk to Rawclk */
2809 reg = FDI_RX_CTL(pipe); 2909 reg = FDI_RX_CTL(pipe);
@@ -2859,6 +2959,12 @@ static void ironlake_crtc_dpms(struct drm_crtc *crtc, int mode)
2859 } 2959 }
2860} 2960}
2861 2961
2962static void ironlake_crtc_off(struct drm_crtc *crtc)
2963{
2964 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
2965 intel_put_pch_pll(intel_crtc);
2966}
2967
2862static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable) 2968static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
2863{ 2969{
2864 if (!enable && intel_crtc->overlay) { 2970 if (!enable && intel_crtc->overlay) {
@@ -2950,6 +3056,10 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
2950 } 3056 }
2951} 3057}
2952 3058
3059static void i9xx_crtc_off(struct drm_crtc *crtc)
3060{
3061}
3062
2953/** 3063/**
2954 * Sets the power management mode of the pipe and plane. 3064 * Sets the power management mode of the pipe and plane.
2955 */ 3065 */
@@ -2997,8 +3107,11 @@ static void intel_crtc_disable(struct drm_crtc *crtc)
2997{ 3107{
2998 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; 3108 struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
2999 struct drm_device *dev = crtc->dev; 3109 struct drm_device *dev = crtc->dev;
3110 struct drm_i915_private *dev_priv = dev->dev_private;
3000 3111
3001 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); 3112 crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
3113 dev_priv->display.off(crtc);
3114
3002 assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane); 3115 assert_plane_disabled(dev->dev_private, to_intel_crtc(crtc)->plane);
3003 assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe); 3116 assert_pipe_disabled(dev->dev_private, to_intel_crtc(crtc)->pipe);
3004 3117
@@ -4238,29 +4351,18 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
4238 DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe); 4351 DRM_DEBUG_KMS("Mode for pipe %d:\n", pipe);
4239 drm_mode_debug_printmodeline(mode); 4352 drm_mode_debug_printmodeline(mode);
4240 4353
4241 /* PCH eDP needs FDI, but CPU eDP does not */ 4354 /* CPU eDP is the only output that doesn't need a PCH PLL of its own */
4242 if (!intel_crtc->no_pll) { 4355 if (!is_cpu_edp) {
4243 if (!is_cpu_edp) { 4356 struct intel_pch_pll *pll;
4244 I915_WRITE(PCH_FP0(pipe), fp);
4245 I915_WRITE(PCH_DPLL(pipe), dpll & ~DPLL_VCO_ENABLE);
4246 4357
4247 POSTING_READ(PCH_DPLL(pipe)); 4358 pll = intel_get_pch_pll(intel_crtc, dpll, fp);
4248 udelay(150); 4359 if (pll == NULL) {
4249 } 4360 DRM_DEBUG_DRIVER("failed to find PLL for pipe %d\n",
4250 } else { 4361 pipe);
4251 if (dpll == (I915_READ(PCH_DPLL(0)) & 0x7fffffff) &&
4252 fp == I915_READ(PCH_FP0(0))) {
4253 intel_crtc->use_pll_a = true;
4254 DRM_DEBUG_KMS("using pipe a dpll\n");
4255 } else if (dpll == (I915_READ(PCH_DPLL(1)) & 0x7fffffff) &&
4256 fp == I915_READ(PCH_FP0(1))) {
4257 intel_crtc->use_pll_a = false;
4258 DRM_DEBUG_KMS("using pipe b dpll\n");
4259 } else {
4260 DRM_DEBUG_KMS("no matching PLL configuration for pipe 2\n");
4261 return -EINVAL; 4362 return -EINVAL;
4262 } 4363 }
4263 } 4364 } else
4365 intel_put_pch_pll(intel_crtc);
4264 4366
4265 /* The LVDS pin pair needs to be on before the DPLLs are enabled. 4367 /* The LVDS pin pair needs to be on before the DPLLs are enabled.
4266 * This is an exception to the general rule that mode_set doesn't turn 4368 * This is an exception to the general rule that mode_set doesn't turn
@@ -4317,11 +4419,11 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
4317 I915_WRITE(TRANSDPLINK_N1(pipe), 0); 4419 I915_WRITE(TRANSDPLINK_N1(pipe), 0);
4318 } 4420 }
4319 4421
4320 if (!intel_crtc->no_pll && (!edp_encoder || is_pch_edp)) { 4422 if (intel_crtc->pch_pll) {
4321 I915_WRITE(PCH_DPLL(pipe), dpll); 4423 I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
4322 4424
4323 /* Wait for the clocks to stabilize. */ 4425 /* Wait for the clocks to stabilize. */
4324 POSTING_READ(PCH_DPLL(pipe)); 4426 POSTING_READ(intel_crtc->pch_pll->pll_reg);
4325 udelay(150); 4427 udelay(150);
4326 4428
4327 /* The pixel multiplier can only be updated once the 4429 /* The pixel multiplier can only be updated once the
@@ -4329,20 +4431,20 @@ static int ironlake_crtc_mode_set(struct drm_crtc *crtc,
4329 * 4431 *
4330 * So write it again. 4432 * So write it again.
4331 */ 4433 */
4332 I915_WRITE(PCH_DPLL(pipe), dpll); 4434 I915_WRITE(intel_crtc->pch_pll->pll_reg, dpll);
4333 } 4435 }
4334 4436
4335 intel_crtc->lowfreq_avail = false; 4437 intel_crtc->lowfreq_avail = false;
4336 if (!intel_crtc->no_pll) { 4438 if (intel_crtc->pch_pll) {
4337 if (is_lvds && has_reduced_clock && i915_powersave) { 4439 if (is_lvds && has_reduced_clock && i915_powersave) {
4338 I915_WRITE(PCH_FP1(pipe), fp2); 4440 I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp2);
4339 intel_crtc->lowfreq_avail = true; 4441 intel_crtc->lowfreq_avail = true;
4340 if (HAS_PIPE_CXSR(dev)) { 4442 if (HAS_PIPE_CXSR(dev)) {
4341 DRM_DEBUG_KMS("enabling CxSR downclocking\n"); 4443 DRM_DEBUG_KMS("enabling CxSR downclocking\n");
4342 pipeconf |= PIPECONF_CXSR_DOWNCLOCK; 4444 pipeconf |= PIPECONF_CXSR_DOWNCLOCK;
4343 } 4445 }
4344 } else { 4446 } else {
4345 I915_WRITE(PCH_FP1(pipe), fp); 4447 I915_WRITE(intel_crtc->pch_pll->fp1_reg, fp);
4346 if (HAS_PIPE_CXSR(dev)) { 4448 if (HAS_PIPE_CXSR(dev)) {
4347 DRM_DEBUG_KMS("disabling CxSR downclocking\n"); 4449 DRM_DEBUG_KMS("disabling CxSR downclocking\n");
4348 pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK; 4450 pipeconf &= ~PIPECONF_CXSR_DOWNCLOCK;
@@ -6016,6 +6118,23 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
6016 .page_flip = intel_crtc_page_flip, 6118 .page_flip = intel_crtc_page_flip,
6017}; 6119};
6018 6120
6121static void intel_pch_pll_init(struct drm_device *dev)
6122{
6123 drm_i915_private_t *dev_priv = dev->dev_private;
6124 int i;
6125
6126 if (dev_priv->num_pch_pll == 0) {
6127 DRM_DEBUG_KMS("No PCH PLLs on this hardware, skipping initialisation\n");
6128 return;
6129 }
6130
6131 for (i = 0; i < dev_priv->num_pch_pll; i++) {
6132 dev_priv->pch_plls[i].pll_reg = _PCH_DPLL(i);
6133 dev_priv->pch_plls[i].fp0_reg = _PCH_FP0(i);
6134 dev_priv->pch_plls[i].fp1_reg = _PCH_FP1(i);
6135 }
6136}
6137
6019static void intel_crtc_init(struct drm_device *dev, int pipe) 6138static void intel_crtc_init(struct drm_device *dev, int pipe)
6020{ 6139{
6021 drm_i915_private_t *dev_priv = dev->dev_private; 6140 drm_i915_private_t *dev_priv = dev->dev_private;
@@ -6053,8 +6172,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
6053 intel_crtc->bpp = 24; /* default for pre-Ironlake */ 6172 intel_crtc->bpp = 24; /* default for pre-Ironlake */
6054 6173
6055 if (HAS_PCH_SPLIT(dev)) { 6174 if (HAS_PCH_SPLIT(dev)) {
6056 if (pipe == 2 && IS_IVYBRIDGE(dev))
6057 intel_crtc->no_pll = true;
6058 intel_helper_funcs.prepare = ironlake_crtc_prepare; 6175 intel_helper_funcs.prepare = ironlake_crtc_prepare;
6059 intel_helper_funcs.commit = ironlake_crtc_commit; 6176 intel_helper_funcs.commit = ironlake_crtc_commit;
6060 } else { 6177 } else {
@@ -6337,10 +6454,12 @@ static void intel_init_display(struct drm_device *dev)
6337 if (HAS_PCH_SPLIT(dev)) { 6454 if (HAS_PCH_SPLIT(dev)) {
6338 dev_priv->display.dpms = ironlake_crtc_dpms; 6455 dev_priv->display.dpms = ironlake_crtc_dpms;
6339 dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set; 6456 dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set;
6457 dev_priv->display.off = ironlake_crtc_off;
6340 dev_priv->display.update_plane = ironlake_update_plane; 6458 dev_priv->display.update_plane = ironlake_update_plane;
6341 } else { 6459 } else {
6342 dev_priv->display.dpms = i9xx_crtc_dpms; 6460 dev_priv->display.dpms = i9xx_crtc_dpms;
6343 dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; 6461 dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set;
6462 dev_priv->display.off = i9xx_crtc_off;
6344 dev_priv->display.update_plane = i9xx_update_plane; 6463 dev_priv->display.update_plane = i9xx_update_plane;
6345 } 6464 }
6346 6465
@@ -6603,6 +6722,8 @@ void intel_modeset_init(struct drm_device *dev)
6603 DRM_DEBUG_KMS("plane %d init failed: %d\n", i, ret); 6722 DRM_DEBUG_KMS("plane %d init failed: %d\n", i, ret);
6604 } 6723 }
6605 6724
6725 intel_pch_pll_init(dev);
6726
6606 /* Just disable it once at startup */ 6727 /* Just disable it once at startup */
6607 i915_disable_vga(dev); 6728 i915_disable_vga(dev);
6608 intel_setup_outputs(dev); 6729 intel_setup_outputs(dev);