From: Ville Syrj?l? <ville.syrj...@linux.intel.com>

When setting a display mode, disable all planes on the CRTC beforehand,
and re-enable them after the new mode has been set.

Signed-off-by: Ville Syrj?l? <ville.syrjala at linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |   48 ++++++++++++++++++++++++++++++++++
 1 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 72ac2f9..aec6cac 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3012,6 +3012,49 @@ void intel_cpt_verify_modeset(struct drm_device *dev, 
int pipe)
        }
 }

+static int intel_crtc_disable_planes(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_plane *plane;
+
+       list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+               int ret;
+
+               if (plane->crtc != crtc || !plane->fb)
+                       continue;
+
+               ret = plane->funcs->disable_plane(plane);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int intel_crtc_enable_planes(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct drm_plane *plane;
+
+       list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+               int ret;
+
+               if (plane->crtc != crtc || !plane->fb)
+                       continue;
+
+               ret = plane->funcs->update_plane(plane,
+                                                plane->crtc, plane->fb,
+                                                plane->crtc_x, plane->crtc_y,
+                                                plane->crtc_w, plane->crtc_h,
+                                                plane->src_x, plane->src_y,
+                                                plane->src_w, plane->src_h);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+
 static void ironlake_crtc_enable(struct drm_crtc *crtc)
 {
        struct drm_device *dev = crtc->dev;
@@ -3060,6 +3103,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
        intel_crtc_load_lut(crtc);

        intel_enable_pipe(dev_priv, pipe, is_pch_port);
+       intel_crtc_enable_planes(crtc);
        intel_enable_plane(dev_priv, plane, pipe);

        if (is_pch_port)
@@ -3088,6 +3132,7 @@ static void ironlake_crtc_disable(struct drm_crtc *crtc)
        drm_vblank_off(dev, pipe);
        intel_crtc_update_cursor(crtc, false);

+       intel_crtc_disable_planes(crtc);
        intel_disable_plane(dev_priv, plane, pipe);

        if (dev_priv->cfb_plane == plane)
@@ -3233,6 +3278,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)

        intel_enable_pll(dev_priv, pipe);
        intel_enable_pipe(dev_priv, pipe, false);
+
        intel_enable_plane(dev_priv, plane, pipe);

        intel_crtc_load_lut(crtc);
@@ -3241,6 +3287,7 @@ static void i9xx_crtc_enable(struct drm_crtc *crtc)
        /* Give the overlay scaler a chance to enable if it's on this pipe */
        intel_crtc_dpms_overlay(intel_crtc, true);
        intel_crtc_update_cursor(crtc, true);
+       intel_crtc_enable_planes(crtc);
 }

 static void i9xx_crtc_disable(struct drm_crtc *crtc)
@@ -3259,6 +3306,7 @@ static void i9xx_crtc_disable(struct drm_crtc *crtc)
        drm_vblank_off(dev, pipe);
        intel_crtc_dpms_overlay(intel_crtc, false);
        intel_crtc_update_cursor(crtc, false);
+       intel_crtc_disable_planes(crtc);

        if (dev_priv->cfb_plane == plane)
                intel_disable_fbc(dev);
-- 
1.7.3.4

Reply via email to