diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2011-01-04 18:09:33 -0500 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-01-19 07:36:26 -0500 |
commit | 63d7bbe9ded4146e3f78e5742b119fa1fdb52665 (patch) | |
tree | 0ea80f9e2c5d8573e32738c91fd9df0f0779dda5 /drivers/gpu/drm/i915/intel_display.c | |
parent | ea0760cfc00b9e534423fdaf630d1c8ce7a5ede0 (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/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 124 |
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 | ||
1113 | static void assert_pipe_enabled(struct drm_i915_private *dev_priv, | 1113 | static 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 | ||
1126 | static void assert_plane_enabled(struct drm_i915_private *dev_priv, | 1130 | static 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 | */ | ||
1173 | static 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 | */ | ||
1210 | static 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 | |||
2644 | done: | ||
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); |