diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2011-01-04 18:09:34 -0500 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2011-01-19 07:36:41 -0500 |
commit | 92f2584a083986c05fc811bbdf380c3fa7c12296 (patch) | |
tree | b6e4f8b2e02475e455b800da05d5501d7d234e85 /drivers/gpu/drm/i915/intel_display.c | |
parent | 63d7bbe9ded4146e3f78e5742b119fa1fdb52665 (diff) |
drm/i915: add PCH DPLL enable/disable functions
With assertions to check transcoder and reference clock state.
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 | 85 |
1 files changed, 74 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 607bd2fd21b9..515e0b99f32e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -1159,6 +1159,30 @@ static void assert_planes_disabled(struct drm_i915_private *dev_priv, | |||
1159 | } | 1159 | } |
1160 | } | 1160 | } |
1161 | 1161 | ||
1162 | static void assert_pch_refclk_enabled(struct drm_i915_private *dev_priv) | ||
1163 | { | ||
1164 | u32 val; | ||
1165 | bool enabled; | ||
1166 | |||
1167 | val = I915_READ(PCH_DREF_CONTROL); | ||
1168 | enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK | | ||
1169 | DREF_SUPERSPREAD_SOURCE_MASK)); | ||
1170 | WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n"); | ||
1171 | } | ||
1172 | |||
1173 | static void assert_transcoder_disabled(struct drm_i915_private *dev_priv, | ||
1174 | enum pipe pipe) | ||
1175 | { | ||
1176 | int reg; | ||
1177 | u32 val; | ||
1178 | bool enabled; | ||
1179 | |||
1180 | reg = TRANSCONF(pipe); | ||
1181 | val = I915_READ(reg); | ||
1182 | enabled = !!(val & TRANS_ENABLE); | ||
1183 | WARN(enabled, "transcoder assertion failed, should be off on pipe %c but is still active\n", pipe ? 'B' :'A'); | ||
1184 | } | ||
1185 | |||
1162 | /** | 1186 | /** |
1163 | * intel_enable_pll - enable a PLL | 1187 | * intel_enable_pll - enable a PLL |
1164 | * @dev_priv: i915 private structure | 1188 | * @dev_priv: i915 private structure |
@@ -1227,6 +1251,54 @@ static void intel_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) | |||
1227 | } | 1251 | } |
1228 | 1252 | ||
1229 | /** | 1253 | /** |
1254 | * intel_enable_pch_pll - enable PCH PLL | ||
1255 | * @dev_priv: i915 private structure | ||
1256 | * @pipe: pipe PLL to enable | ||
1257 | * | ||
1258 | * The PCH PLL needs to be enabled before the PCH transcoder, since it | ||
1259 | * drives the transcoder clock. | ||
1260 | */ | ||
1261 | static void intel_enable_pch_pll(struct drm_i915_private *dev_priv, | ||
1262 | enum pipe pipe) | ||
1263 | { | ||
1264 | int reg; | ||
1265 | u32 val; | ||
1266 | |||
1267 | /* PCH only available on ILK+ */ | ||
1268 | BUG_ON(dev_priv->info->gen < 5); | ||
1269 | |||
1270 | /* PCH refclock must be enabled first */ | ||
1271 | assert_pch_refclk_enabled(dev_priv); | ||
1272 | |||
1273 | reg = PCH_DPLL(pipe); | ||
1274 | val = I915_READ(reg); | ||
1275 | val |= DPLL_VCO_ENABLE; | ||
1276 | I915_WRITE(reg, val); | ||
1277 | POSTING_READ(reg); | ||
1278 | udelay(200); | ||
1279 | } | ||
1280 | |||
1281 | static void intel_disable_pch_pll(struct drm_i915_private *dev_priv, | ||
1282 | enum pipe pipe) | ||
1283 | { | ||
1284 | int reg; | ||
1285 | u32 val; | ||
1286 | |||
1287 | /* PCH only available on ILK+ */ | ||
1288 | BUG_ON(dev_priv->info->gen < 5); | ||
1289 | |||
1290 | /* Make sure transcoder isn't still depending on us */ | ||
1291 | assert_transcoder_disabled(dev_priv, pipe); | ||
1292 | |||
1293 | reg = PCH_DPLL(pipe); | ||
1294 | val = I915_READ(reg); | ||
1295 | val &= ~DPLL_VCO_ENABLE; | ||
1296 | I915_WRITE(reg, val); | ||
1297 | POSTING_READ(reg); | ||
1298 | udelay(200); | ||
1299 | } | ||
1300 | |||
1301 | /** | ||
1230 | * intel_enable_pipe - enable a pipe, assertiing requirements | 1302 | * intel_enable_pipe - enable a pipe, assertiing requirements |
1231 | * @dev_priv: i915 private structure | 1303 | * @dev_priv: i915 private structure |
1232 | * @pipe: pipe to enable | 1304 | * @pipe: pipe to enable |
@@ -2360,14 +2432,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) | |||
2360 | else | 2432 | else |
2361 | ironlake_fdi_link_train(crtc); | 2433 | ironlake_fdi_link_train(crtc); |
2362 | 2434 | ||
2363 | /* enable PCH DPLL */ | 2435 | intel_enable_pch_pll(dev_priv, pipe); |
2364 | reg = PCH_DPLL(pipe); | ||
2365 | temp = I915_READ(reg); | ||
2366 | if ((temp & DPLL_VCO_ENABLE) == 0) { | ||
2367 | I915_WRITE(reg, temp | DPLL_VCO_ENABLE); | ||
2368 | POSTING_READ(reg); | ||
2369 | udelay(200); | ||
2370 | } | ||
2371 | 2436 | ||
2372 | if (HAS_PCH_CPT(dev)) { | 2437 | if (HAS_PCH_CPT(dev)) { |
2373 | /* Be sure PCH DPLL SEL is set */ | 2438 | /* Be sure PCH DPLL SEL is set */ |
@@ -2553,9 +2618,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) | |||
2553 | } | 2618 | } |
2554 | 2619 | ||
2555 | /* disable PCH DPLL */ | 2620 | /* disable PCH DPLL */ |
2556 | reg = PCH_DPLL(pipe); | 2621 | intel_disable_pch_pll(dev_priv, pipe); |
2557 | temp = I915_READ(reg); | ||
2558 | I915_WRITE(reg, temp & ~DPLL_VCO_ENABLE); | ||
2559 | 2622 | ||
2560 | /* Switch from PCDclk to Rawclk */ | 2623 | /* Switch from PCDclk to Rawclk */ |
2561 | reg = FDI_RX_CTL(pipe); | 2624 | reg = FDI_RX_CTL(pipe); |