aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2010-08-07 06:01:33 -0400
committerEric Anholt <eric@anholt.net>2010-08-09 14:24:35 -0400
commitdebcaddcbd92387137b87f2c1c640571753915e0 (patch)
treec03c02892abe03129d09ea91b1c3e63493a80a3c
parent862daefcc9a1eb9ff3e4c3d8076c31535f710cf9 (diff)
drm/i915: Update watermarks for Ironlake after dpms changes
Previously, we only remembered to update the watermarks for i9xx, and incorrectly assumed that the crtc->enabled flag was valid at that point in the dpms cycle. Note that on my x201s this makes a SR bug on pipe 1 much easier to hit. (Since before this patch when disabling pipe 0, we either didn't update the watermarks at all, or when we did we still thought we had two pipes enabled and so disabled SR.) References: Bug 28969 - [Arrandale] Screen flickers, suspect Self-Refresh https://bugs.freedesktop.org/show_bug.cgi?id=28969 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r--drivers/gpu/drm/i915/intel_display.c36
1 files changed, 22 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 07f19967687b..1eae234ff485 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2369,8 +2369,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
2369 case DRM_MODE_DPMS_ON: 2369 case DRM_MODE_DPMS_ON:
2370 case DRM_MODE_DPMS_STANDBY: 2370 case DRM_MODE_DPMS_STANDBY:
2371 case DRM_MODE_DPMS_SUSPEND: 2371 case DRM_MODE_DPMS_SUSPEND:
2372 intel_update_watermarks(dev);
2373
2374 /* Enable the DPLL */ 2372 /* Enable the DPLL */
2375 temp = I915_READ(dpll_reg); 2373 temp = I915_READ(dpll_reg);
2376 if ((temp & DPLL_VCO_ENABLE) == 0) { 2374 if ((temp & DPLL_VCO_ENABLE) == 0) {
@@ -2410,8 +2408,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
2410 intel_crtc_dpms_overlay(intel_crtc, true); 2408 intel_crtc_dpms_overlay(intel_crtc, true);
2411 break; 2409 break;
2412 case DRM_MODE_DPMS_OFF: 2410 case DRM_MODE_DPMS_OFF:
2413 intel_update_watermarks(dev);
2414
2415 /* Give the overlay scaler a chance to disable if it's on this pipe */ 2411 /* Give the overlay scaler a chance to disable if it's on this pipe */
2416 intel_crtc_dpms_overlay(intel_crtc, false); 2412 intel_crtc_dpms_overlay(intel_crtc, false);
2417 drm_vblank_off(dev, pipe); 2413 drm_vblank_off(dev, pipe);
@@ -2476,12 +2472,26 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
2476 int pipe = intel_crtc->pipe; 2472 int pipe = intel_crtc->pipe;
2477 bool enabled; 2473 bool enabled;
2478 2474
2479 dev_priv->display.dpms(crtc, mode);
2480
2481 intel_crtc->dpms_mode = mode; 2475 intel_crtc->dpms_mode = mode;
2482
2483 intel_crtc->cursor_on = mode == DRM_MODE_DPMS_ON; 2476 intel_crtc->cursor_on = mode == DRM_MODE_DPMS_ON;
2484 intel_crtc_update_cursor(crtc); 2477
2478 /* When switching on the display, ensure that SR is disabled
2479 * with multiple pipes prior to enabling to new pipe.
2480 *
2481 * When switching off the display, make sure the cursor is
2482 * properly hidden prior to disabling the pipe.
2483 */
2484 if (mode == DRM_MODE_DPMS_ON)
2485 intel_update_watermarks(dev);
2486 else
2487 intel_crtc_update_cursor(crtc);
2488
2489 dev_priv->display.dpms(crtc, mode);
2490
2491 if (mode == DRM_MODE_DPMS_ON)
2492 intel_crtc_update_cursor(crtc);
2493 else
2494 intel_update_watermarks(dev);
2485 2495
2486 if (!dev->primary->master) 2496 if (!dev->primary->master)
2487 return; 2497 return;
@@ -3362,12 +3372,11 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock,
3362 int line_count; 3372 int line_count;
3363 int planea_htotal = 0, planeb_htotal = 0; 3373 int planea_htotal = 0, planeb_htotal = 0;
3364 struct drm_crtc *crtc; 3374 struct drm_crtc *crtc;
3365 struct intel_crtc *intel_crtc;
3366 3375
3367 /* Need htotal for all active display plane */ 3376 /* Need htotal for all active display plane */
3368 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 3377 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
3369 intel_crtc = to_intel_crtc(crtc); 3378 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
3370 if (crtc->enabled) { 3379 if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) {
3371 if (intel_crtc->plane == 0) 3380 if (intel_crtc->plane == 0)
3372 planea_htotal = crtc->mode.htotal; 3381 planea_htotal = crtc->mode.htotal;
3373 else 3382 else
@@ -3527,7 +3536,6 @@ static void intel_update_watermarks(struct drm_device *dev)
3527{ 3536{
3528 struct drm_i915_private *dev_priv = dev->dev_private; 3537 struct drm_i915_private *dev_priv = dev->dev_private;
3529 struct drm_crtc *crtc; 3538 struct drm_crtc *crtc;
3530 struct intel_crtc *intel_crtc;
3531 int sr_hdisplay = 0; 3539 int sr_hdisplay = 0;
3532 unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; 3540 unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0;
3533 int enabled = 0, pixel_size = 0; 3541 int enabled = 0, pixel_size = 0;
@@ -3538,8 +3546,8 @@ static void intel_update_watermarks(struct drm_device *dev)
3538 3546
3539 /* Get the clock config from both planes */ 3547 /* Get the clock config from both planes */
3540 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 3548 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
3541 intel_crtc = to_intel_crtc(crtc); 3549 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
3542 if (crtc->enabled) { 3550 if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) {
3543 enabled++; 3551 enabled++;
3544 if (intel_crtc->plane == 0) { 3552 if (intel_crtc->plane == 0) {
3545 DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", 3553 DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n",