drm/i915: Fix an overlay regression from 7e7d76c
authorChris Wilson <chris@chris-wilson.co.uk>
Mon, 13 Sep 2010 13:19:16 +0000 (14:19 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Mon, 13 Sep 2010 13:32:18 +0000 (14:32 +0100)
When separating out the prepare/commit into its own separate functions
we overlooked that the intel_crtc->dpms_mode was being used elsewhere to
check on the actual status of the pipe.

Track that bit of logic separately from the actual dpms mode, so there
is no confusion should we be able to handle multiple dpms modes, nor
any semantic conflict between prepare/commit and dpms.

Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_overlay.c

index 1e2a17d66ebbe2b5b25705029127788fb0781f4d..a54b701f867c6732232a25fc2e0352db57a73dde 100644 (file)
@@ -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",
index c0891b1ec7b5f4eab70acd94494959522f3f3271..5171b05231785eeb881e7acc4fba5b60d6939f2b 100644 (file)
@@ -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;
index 3dff16118ee592cda9791e07afdd2389615e479a..c4699c916698234375d18c5d415b352d7288f752 100644 (file)
@@ -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;