Commit debcaddc authored by Chris Wilson's avatar Chris Wilson Committed by Eric Anholt

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=28969Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent 862daefc
...@@ -2369,8 +2369,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -2369,8 +2369,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
case DRM_MODE_DPMS_ON: case DRM_MODE_DPMS_ON:
case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_SUSPEND:
intel_update_watermarks(dev);
/* Enable the DPLL */ /* Enable the DPLL */
temp = I915_READ(dpll_reg); temp = I915_READ(dpll_reg);
if ((temp & DPLL_VCO_ENABLE) == 0) { if ((temp & DPLL_VCO_ENABLE) == 0) {
...@@ -2410,8 +2408,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -2410,8 +2408,6 @@ static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
intel_crtc_dpms_overlay(intel_crtc, true); intel_crtc_dpms_overlay(intel_crtc, true);
break; break;
case DRM_MODE_DPMS_OFF: case DRM_MODE_DPMS_OFF:
intel_update_watermarks(dev);
/* Give the overlay scaler a chance to disable if it's on this pipe */ /* Give the overlay scaler a chance to disable if it's on this pipe */
intel_crtc_dpms_overlay(intel_crtc, false); intel_crtc_dpms_overlay(intel_crtc, false);
drm_vblank_off(dev, pipe); drm_vblank_off(dev, pipe);
...@@ -2476,12 +2472,26 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) ...@@ -2476,12 +2472,26 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
int pipe = intel_crtc->pipe; int pipe = intel_crtc->pipe;
bool enabled; bool enabled;
dev_priv->display.dpms(crtc, mode);
intel_crtc->dpms_mode = mode; intel_crtc->dpms_mode = mode;
intel_crtc->cursor_on = mode == DRM_MODE_DPMS_ON; intel_crtc->cursor_on = mode == DRM_MODE_DPMS_ON;
intel_crtc_update_cursor(crtc);
/* When switching on the display, ensure that SR is disabled
* with multiple pipes prior to enabling to new pipe.
*
* When switching off the display, make sure the cursor is
* properly hidden prior to disabling the pipe.
*/
if (mode == DRM_MODE_DPMS_ON)
intel_update_watermarks(dev);
else
intel_crtc_update_cursor(crtc);
dev_priv->display.dpms(crtc, mode);
if (mode == DRM_MODE_DPMS_ON)
intel_crtc_update_cursor(crtc);
else
intel_update_watermarks(dev);
if (!dev->primary->master) if (!dev->primary->master)
return; return;
...@@ -3362,12 +3372,11 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock, ...@@ -3362,12 +3372,11 @@ static void ironlake_update_wm(struct drm_device *dev, int planea_clock,
int line_count; int line_count;
int planea_htotal = 0, planeb_htotal = 0; int planea_htotal = 0, planeb_htotal = 0;
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct intel_crtc *intel_crtc;
/* Need htotal for all active display plane */ /* Need htotal for all active display plane */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
if (crtc->enabled) { if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) {
if (intel_crtc->plane == 0) if (intel_crtc->plane == 0)
planea_htotal = crtc->mode.htotal; planea_htotal = crtc->mode.htotal;
else else
...@@ -3527,7 +3536,6 @@ static void intel_update_watermarks(struct drm_device *dev) ...@@ -3527,7 +3536,6 @@ static void intel_update_watermarks(struct drm_device *dev)
{ {
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct intel_crtc *intel_crtc;
int sr_hdisplay = 0; int sr_hdisplay = 0;
unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0; unsigned long planea_clock = 0, planeb_clock = 0, sr_clock = 0;
int enabled = 0, pixel_size = 0; int enabled = 0, pixel_size = 0;
...@@ -3538,8 +3546,8 @@ static void intel_update_watermarks(struct drm_device *dev) ...@@ -3538,8 +3546,8 @@ static void intel_update_watermarks(struct drm_device *dev)
/* Get the clock config from both planes */ /* Get the clock config from both planes */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
if (crtc->enabled) { if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) {
enabled++; enabled++;
if (intel_crtc->plane == 0) { if (intel_crtc->plane == 0) {
DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment