aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2010-09-10 13:31:34 -0400
committerChris Wilson <chris@chris-wilson.co.uk>2010-09-10 17:23:45 -0400
commit0b8765c6e7fb6e0aaa9b9081454fb0f202852523 (patch)
treee668955f8bf8ab79bda4b589c559742a902193e2 /drivers/gpu/drm/i915/intel_display.c
parent6be4a6078e41a8ec511dad35d1377bc5338f97be (diff)
drm/i915: split i9xx CRTC enable/disable code
So we can use it for CRTC prepare/commit. 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.c185
1 files changed, 103 insertions, 82 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 56ca589a83f..fecb98c2d8a 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2262,7 +2262,7 @@ static void intel_crtc_dpms_overlay(struct intel_crtc *intel_crtc, bool enable)
2262 */ 2262 */
2263} 2263}
2264 2264
2265static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) 2265static void i9xx_crtc_enable(struct drm_crtc *crtc)
2266{ 2266{
2267 struct drm_device *dev = crtc->dev; 2267 struct drm_device *dev = crtc->dev;
2268 struct drm_i915_private *dev_priv = dev->dev_private; 2268 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2275,97 +2275,118 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
2275 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF; 2275 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
2276 u32 temp; 2276 u32 temp;
2277 2277
2278 /* XXX: When our outputs are all unaware of DPMS modes other than off 2278 /* Enable the DPLL */
2279 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC. 2279 temp = I915_READ(dpll_reg);
2280 */ 2280 if ((temp & DPLL_VCO_ENABLE) == 0) {
2281 switch (mode) { 2281 I915_WRITE(dpll_reg, temp);
2282 case DRM_MODE_DPMS_ON: 2282 I915_READ(dpll_reg);
2283 case DRM_MODE_DPMS_STANDBY: 2283 /* Wait for the clocks to stabilize. */
2284 case DRM_MODE_DPMS_SUSPEND: 2284 udelay(150);
2285 /* Enable the DPLL */ 2285 I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
2286 temp = I915_READ(dpll_reg); 2286 I915_READ(dpll_reg);
2287 if ((temp & DPLL_VCO_ENABLE) == 0) { 2287 /* Wait for the clocks to stabilize. */
2288 I915_WRITE(dpll_reg, temp); 2288 udelay(150);
2289 I915_READ(dpll_reg); 2289 I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
2290 /* Wait for the clocks to stabilize. */ 2290 I915_READ(dpll_reg);
2291 udelay(150); 2291 /* Wait for the clocks to stabilize. */
2292 I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE); 2292 udelay(150);
2293 I915_READ(dpll_reg); 2293 }
2294 /* Wait for the clocks to stabilize. */
2295 udelay(150);
2296 I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
2297 I915_READ(dpll_reg);
2298 /* Wait for the clocks to stabilize. */
2299 udelay(150);
2300 }
2301 2294
2302 /* Enable the pipe */ 2295 /* Enable the pipe */
2303 temp = I915_READ(pipeconf_reg); 2296 temp = I915_READ(pipeconf_reg);
2304 if ((temp & PIPEACONF_ENABLE) == 0) 2297 if ((temp & PIPEACONF_ENABLE) == 0)
2305 I915_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE); 2298 I915_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
2306
2307 /* Enable the plane */
2308 temp = I915_READ(dspcntr_reg);
2309 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
2310 I915_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
2311 /* Flush the plane changes */
2312 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
2313 }
2314 2299
2315 intel_crtc_load_lut(crtc); 2300 /* Enable the plane */
2301 temp = I915_READ(dspcntr_reg);
2302 if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
2303 I915_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
2304 /* Flush the plane changes */
2305 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
2306 }
2316 2307
2317 if ((IS_I965G(dev) || plane == 0)) 2308 intel_crtc_load_lut(crtc);
2318 intel_update_fbc(crtc, &crtc->mode);
2319 2309
2320 /* Give the overlay scaler a chance to enable if it's on this pipe */ 2310 if ((IS_I965G(dev) || plane == 0))
2321 intel_crtc_dpms_overlay(intel_crtc, true); 2311 intel_update_fbc(crtc, &crtc->mode);
2322 break;
2323 case DRM_MODE_DPMS_OFF:
2324 /* Give the overlay scaler a chance to disable if it's on this pipe */
2325 intel_crtc_dpms_overlay(intel_crtc, false);
2326 drm_vblank_off(dev, pipe);
2327
2328 if (dev_priv->cfb_plane == plane &&
2329 dev_priv->display.disable_fbc)
2330 dev_priv->display.disable_fbc(dev);
2331
2332 /* Disable display plane */
2333 temp = I915_READ(dspcntr_reg);
2334 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
2335 I915_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
2336 /* Flush the plane changes */
2337 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
2338 I915_READ(dspbase_reg);
2339 }
2340 2312
2341 if (!IS_I9XX(dev)) { 2313 /* Give the overlay scaler a chance to enable if it's on this pipe */
2342 /* Wait for vblank for the disable to take effect */ 2314 intel_crtc_dpms_overlay(intel_crtc, true);
2343 intel_wait_for_vblank_off(dev, pipe); 2315}
2344 }
2345 2316
2346 /* Don't disable pipe A or pipe A PLLs if needed */ 2317static void i9xx_crtc_disable(struct drm_crtc *crtc)
2347 if (pipeconf_reg == PIPEACONF && 2318{
2348 (dev_priv->quirks & QUIRK_PIPEA_FORCE)) 2319 struct drm_device *dev = crtc->dev;
2349 goto skip_pipe_off; 2320 struct drm_i915_private *dev_priv = dev->dev_private;
2321 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
2322 int pipe = intel_crtc->pipe;
2323 int plane = intel_crtc->plane;
2324 int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
2325 int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
2326 int dspbase_reg = (plane == 0) ? DSPAADDR : DSPBADDR;
2327 int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
2328 u32 temp;
2350 2329
2351 /* Next, disable display pipes */ 2330 /* Give the overlay scaler a chance to disable if it's on this pipe */
2352 temp = I915_READ(pipeconf_reg); 2331 intel_crtc_dpms_overlay(intel_crtc, false);
2353 if ((temp & PIPEACONF_ENABLE) != 0) { 2332 drm_vblank_off(dev, pipe);
2354 I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE); 2333
2355 I915_READ(pipeconf_reg); 2334 if (dev_priv->cfb_plane == plane &&
2356 } 2335 dev_priv->display.disable_fbc)
2336 dev_priv->display.disable_fbc(dev);
2357 2337
2358 /* Wait for vblank for the disable to take effect. */ 2338 /* Disable display plane */
2339 temp = I915_READ(dspcntr_reg);
2340 if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
2341 I915_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
2342 /* Flush the plane changes */
2343 I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
2344 I915_READ(dspbase_reg);
2345 }
2346
2347 if (!IS_I9XX(dev)) {
2348 /* Wait for vblank for the disable to take effect */
2359 intel_wait_for_vblank_off(dev, pipe); 2349 intel_wait_for_vblank_off(dev, pipe);
2350 }
2360 2351
2361 temp = I915_READ(dpll_reg); 2352 /* Don't disable pipe A or pipe A PLLs if needed */
2362 if ((temp & DPLL_VCO_ENABLE) != 0) { 2353 if (pipeconf_reg == PIPEACONF &&
2363 I915_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE); 2354 (dev_priv->quirks & QUIRK_PIPEA_FORCE))
2364 I915_READ(dpll_reg); 2355 goto skip_pipe_off;
2365 } 2356
2366 skip_pipe_off: 2357 /* Next, disable display pipes */
2367 /* Wait for the clocks to turn off. */ 2358 temp = I915_READ(pipeconf_reg);
2368 udelay(150); 2359 if ((temp & PIPEACONF_ENABLE) != 0) {
2360 I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
2361 I915_READ(pipeconf_reg);
2362 }
2363
2364 /* Wait for vblank for the disable to take effect. */
2365 intel_wait_for_vblank_off(dev, pipe);
2366
2367 temp = I915_READ(dpll_reg);
2368 if ((temp & DPLL_VCO_ENABLE) != 0) {
2369 I915_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
2370 I915_READ(dpll_reg);
2371 }
2372skip_pipe_off:
2373 /* Wait for the clocks to turn off. */
2374 udelay(150);
2375}
2376
2377static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
2378{
2379 /* XXX: When our outputs are all unaware of DPMS modes other than off
2380 * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
2381 */
2382 switch (mode) {
2383 case DRM_MODE_DPMS_ON:
2384 case DRM_MODE_DPMS_STANDBY:
2385 case DRM_MODE_DPMS_SUSPEND:
2386 i9xx_crtc_enable(crtc);
2387 break;
2388 case DRM_MODE_DPMS_OFF:
2389 i9xx_crtc_disable(crtc);
2369 break; 2390 break;
2370 } 2391 }
2371} 2392}