aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2011-01-04 18:09:33 -0500
committerChris Wilson <chris@chris-wilson.co.uk>2011-01-19 07:36:26 -0500
commit63d7bbe9ded4146e3f78e5742b119fa1fdb52665 (patch)
tree0ea80f9e2c5d8573e32738c91fd9df0f0779dda5 /drivers/gpu
parentea0760cfc00b9e534423fdaf630d1c8ce7a5ede0 (diff)
drm/i915: add PLL enable/disable functions
For pre-ILK only. Saves some code in the CRTC enable/disable functions and allows us to check for pipe and panel status at enable/disable time. Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c124
1 files changed, 78 insertions, 46 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 491ac56199d1..607bd2fd21b9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -1110,18 +1110,22 @@ static void assert_panel_unlocked(struct drm_i915_private *dev_priv,
1110 pipe ? 'B' : 'A'); 1110 pipe ? 'B' : 'A');
1111} 1111}
1112 1112
1113static void assert_pipe_enabled(struct drm_i915_private *dev_priv, 1113static void assert_pipe(struct drm_i915_private *dev_priv,
1114 enum pipe pipe) 1114 enum pipe pipe, bool state)
1115{ 1115{
1116 int reg; 1116 int reg;
1117 u32 val; 1117 u32 val;
1118 bool cur_state;
1118 1119
1119 reg = PIPECONF(pipe); 1120 reg = PIPECONF(pipe);
1120 val = I915_READ(reg); 1121 val = I915_READ(reg);
1121 WARN(!(val & PIPECONF_ENABLE), 1122 cur_state = !!(val & PIPECONF_ENABLE);
1122 "pipe %c assertion failure, should be active but is disabled\n", 1123 WARN(cur_state != state,
1123 pipe ? 'B' : 'A'); 1124 "pipe %c assertion failure (expected %s, current %s)\n",
1125 pipe ? 'B' : 'A', state_string(state), state_string(cur_state));
1124} 1126}
1127#define assert_pipe_enabled(d, p) assert_pipe(d, p, true)
1128#define assert_pipe_disabled(d, p) assert_pipe(d, p, false)
1125 1129
1126static void assert_plane_enabled(struct drm_i915_private *dev_priv, 1130static void assert_plane_enabled(struct drm_i915_private *dev_priv,
1127 enum plane plane) 1131 enum plane plane)
@@ -1156,6 +1160,73 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv,
1156} 1160}
1157 1161
1158/** 1162/**
1163 * intel_enable_pll - enable a PLL
1164 * @dev_priv: i915 private structure
1165 * @pipe: pipe PLL to enable
1166 *
1167 * Enable @pipe's PLL so we can start pumping pixels from a plane. Check to
1168 * make sure the PLL reg is writable first though, since the panel write
1169 * protect mechanism may be enabled.
1170 *
1171 * Note! This is for pre-ILK only.
1172 */
1173static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
1174{
1175 int reg;
1176 u32 val;
1177
1178 /* No really, not for ILK+ */
1179 BUG_ON(dev_priv->info->gen >= 5);
1180
1181 /* PLL is protected by panel, make sure we can write it */
1182 if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev))
1183 assert_panel_unlocked(dev_priv, pipe);
1184
1185 reg = DPLL(pipe);
1186 val = I915_READ(reg);
1187 val |= DPLL_VCO_ENABLE;
1188
1189 /* We do this three times for luck */
1190 I915_WRITE(reg, val);
1191 POSTING_READ(reg);
1192 udelay(150); /* wait for warmup */
1193 I915_WRITE(reg, val);
1194 POSTING_READ(reg);
1195 udelay(150); /* wait for warmup */
1196 I915_WRITE(reg, val);
1197 POSTING_READ(reg);
1198 udelay(150); /* wait for warmup */
1199}
1200
1201/**
1202 * intel_disable_pll - disable a PLL
1203 * @dev_priv: i915 private structure
1204 * @pipe: pipe PLL to disable
1205 *
1206 * Disable the PLL for @pipe, making sure the pipe is off first.
1207 *
1208 * Note! This is for pre-ILK only.
1209 */
1210static void intel_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe)
1211{
1212 int reg;
1213 u32 val;
1214
1215 /* Don't disable pipe A or pipe A PLLs if needed */
1216 if (pipe == PIPE_A && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
1217 return;
1218
1219 /* Make sure the pipe isn't still relying on us */
1220 assert_pipe_disabled(dev_priv, pipe);
1221
1222 reg = DPLL(pipe);
1223 val = I915_READ(reg);
1224 val &= ~DPLL_VCO_ENABLE;
1225 I915_WRITE(reg, val);
1226 POSTING_READ(reg);
1227}
1228
1229/**
1159 * intel_enable_pipe - enable a pipe, assertiing requirements 1230 * intel_enable_pipe - enable a pipe, assertiing requirements
1160 * @dev_priv: i915 private structure 1231 * @dev_priv: i915 private structure
1161 * @pipe: pipe to enable 1232 * @pipe: pipe to enable
@@ -2559,7 +2630,6 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
2559 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 2630 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
2560 int pipe = intel_crtc->pipe; 2631 int pipe = intel_crtc->pipe;
2561 int plane = intel_crtc->plane; 2632 int plane = intel_crtc->plane;
2562 u32 reg, temp;
2563 2633
2564 if (intel_crtc->active) 2634 if (intel_crtc->active)
2565 return; 2635 return;
@@ -2567,29 +2637,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
2567 intel_crtc->active = true; 2637 intel_crtc->active = true;
2568 intel_update_watermarks(dev); 2638 intel_update_watermarks(dev);
2569 2639
2570 /* Enable the DPLL */ 2640 intel_enable_pll(dev_priv, pipe);
2571 reg = DPLL(pipe);
2572 temp = I915_READ(reg);
2573 if ((temp & DPLL_VCO_ENABLE) == 0) {
2574 I915_WRITE(reg, temp);
2575
2576 /* Wait for the clocks to stabilize. */
2577 POSTING_READ(reg);
2578 udelay(150);
2579
2580 I915_WRITE(reg, temp | DPLL_VCO_ENABLE);
2581
2582 /* Wait for the clocks to stabilize. */
2583 POSTING_READ(reg);
2584 udelay(150);
2585
2586 I915_WRITE(reg, temp | DPLL_VCO_ENABLE);
2587
2588 /* Wait for the clocks to stabilize. */
2589 POSTING_READ(reg);
2590 udelay(150);
2591 }
2592
2593 intel_enable_pipe(dev_priv, pipe); 2641 intel_enable_pipe(dev_priv, pipe);
2594 intel_enable_plane(dev_priv, plane, pipe); 2642 intel_enable_plane(dev_priv, plane, pipe);
2595 2643
@@ -2608,7 +2656,6 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
2608 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 2656 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
2609 int pipe = intel_crtc->pipe; 2657 int pipe = intel_crtc->pipe;
2610 int plane = intel_crtc->plane; 2658 int plane = intel_crtc->plane;
2611 u32 reg, temp;
2612 2659
2613 if (!intel_crtc->active) 2660 if (!intel_crtc->active)
2614 return; 2661 return;
@@ -2624,24 +2671,9 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
2624 dev_priv->display.disable_fbc(dev); 2671 dev_priv->display.disable_fbc(dev);
2625 2672
2626 intel_disable_plane(dev_priv, plane, pipe); 2673 intel_disable_plane(dev_priv, plane, pipe);
2627
2628 /* Don't disable pipe A or pipe A PLLs if needed */
2629 if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
2630 goto done;
2631
2632 intel_disable_pipe(dev_priv, pipe); 2674 intel_disable_pipe(dev_priv, pipe);
2675 intel_disable_pll(dev_priv, pipe);
2633 2676
2634 reg = DPLL(pipe);
2635 temp = I915_READ(reg);
2636 if (temp & DPLL_VCO_ENABLE) {
2637 I915_WRITE(reg, temp & ~DPLL_VCO_ENABLE);
2638
2639 /* Wait for the clocks to turn off. */
2640 POSTING_READ(reg);
2641 udelay(150);
2642 }
2643
2644done:
2645 intel_crtc->active = false; 2677 intel_crtc->active = false;
2646 intel_update_fbc(dev); 2678 intel_update_fbc(dev);
2647 intel_update_watermarks(dev); 2679 intel_update_watermarks(dev);