diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1e2a17d66ebb..a54b701f867c 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1956,6 +1956,10 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) int plane = intel_crtc->plane; u32 reg, temp; + if (intel_crtc->active) + return; + + intel_crtc->active = true; intel_update_watermarks(dev); if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { @@ -2116,6 +2120,9 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) int plane = intel_crtc->plane; u32 reg, temp; + if (!intel_crtc->active) + return; + drm_vblank_off(dev, pipe); intel_crtc_update_cursor(crtc, false); @@ -2245,6 +2252,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc) POSTING_READ(reg); udelay(100); + intel_crtc->active = false; intel_update_watermarks(dev); intel_update_fbc(dev); intel_clear_scanline_wait(dev); @@ -2298,6 +2306,10 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc) int plane = intel_crtc->plane; u32 reg, temp; + if (intel_crtc->active) + return; + + intel_crtc->active = true; intel_update_watermarks(dev); /* Enable the DPLL */ @@ -2354,6 +2366,9 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) int plane = intel_crtc->plane; u32 reg, temp; + if (!intel_crtc->active) + return; + /* Give the overlay scaler a chance to disable if it's on this pipe */ intel_crtc_dpms_overlay(intel_crtc, false); intel_crtc_update_cursor(crtc, false); @@ -2402,6 +2417,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc) } done: + intel_crtc->active = false; intel_update_fbc(dev); intel_update_watermarks(dev); intel_clear_scanline_wait(dev); @@ -3463,7 +3479,7 @@ static void intel_update_watermarks(struct drm_device *dev) /* Get the clock config from both planes */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - if (intel_crtc->dpms_mode == DRM_MODE_DPMS_ON) { + if (intel_crtc->active) { enabled++; if (intel_crtc->plane == 0) { DRM_DEBUG_KMS("plane A (pipe %d) clock: %d\n", diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index c0891b1ec7b5..5171b0523178 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -169,6 +169,7 @@ struct intel_crtc { enum plane plane; u8 lut_r[256], lut_g[256], lut_b[256]; int dpms_mode; + bool active; /* is the crtc on? independent of the dpms mode */ bool busy; /* is scanout buffer being updated frequently? */ struct timer_list idle_timer; bool lowfreq_avail; diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 3dff16118ee5..c4699c916698 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -875,15 +875,13 @@ static int check_overlay_possible_on_crtc(struct intel_overlay *overlay, struct intel_crtc *crtc) { drm_i915_private_t *dev_priv = overlay->dev->dev_private; - u32 pipeconf; - if (!crtc->base.enabled || crtc->dpms_mode != DRM_MODE_DPMS_ON) + if (!crtc->active) return -EINVAL; - pipeconf = I915_READ(PIPECONF(crtc->pipe)); - /* can't use the overlay with double wide pipe */ - if (!IS_I965G(overlay->dev) && pipeconf & PIPECONF_DOUBLE_WIDE) + if (!IS_I965G(overlay->dev) && + (I915_READ(PIPECONF(crtc->pipe)) & (PIPECONF_DOUBLE_WIDE | PIPECONF_ENABLE)) != PIPECONF_ENABLE) return -EINVAL; return 0;