[PATCH 06/31] drm/i915: Fix IPS disable sequence.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We cannot let IPS enabled in the pipe if there is
no plane enabled so whenever disabling the primary
plane we check the state of other planes and disable
IPS if needed.

Signed-off-by: Rodrigo Vivi <rodrigo.vivi@xxxxxxxxx>
---
 drivers/gpu/drm/i915/intel_display.c | 18 +++---------------
 drivers/gpu/drm/i915/intel_drv.h     |  1 +
 drivers/gpu/drm/i915/intel_ips.c     | 35 ++++++++++++++++++++++++++++++++++-
 3 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index b2c5c55..a0e053e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4662,14 +4662,6 @@ intel_pre_disable_primary(struct drm_crtc *crtc)
 		dev_priv->wm.vlv.cxsr = false;
 		intel_wait_for_vblank(dev, pipe);
 	}
-
-	/*
-	 * FIXME IPS should be fine as long as one plane is
-	 * enabled, but in practice it seems to have problems
-	 * when going from primary only to sprite only and vice
-	 * versa.
-	 */
-	intel_ips_disable(intel_crtc);
 }
 
 static void intel_post_plane_update(struct intel_crtc *crtc)
@@ -4711,7 +4703,7 @@ static void intel_pre_plane_update(struct intel_crtc *crtc)
 		intel_fbc_disable_crtc(crtc);
 
 	if (crtc->atomic.disable_ips)
-		intel_ips_disable(crtc);
+		intel_ips_disable_if_alone(crtc);
 
 	if (atomic->pre_disable_primary)
 		intel_pre_disable_primary(&crtc->base);
@@ -11562,12 +11554,8 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
 
 		if (turn_off) {
 			/*
-			 * FIXME: Actually if we will still have any other
-			 * plane enabled on the pipe we could let IPS enabled
-			 * still, but for now lets consider that when we make
-			 * primary invisible by setting DSPCNTR to 0 on
-			 * update_primary_plane function IPS needs to be
-			 * disable.
+			 * IPS disable_if_alone function will be called
+			 * in order to decide if IPS disable is really needed.
 			 */
 			intel_crtc->atomic.disable_ips = true;
 
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 92010f7..04c1fc4 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1211,6 +1211,7 @@ bool intel_ips_ready(struct intel_crtc *crtc,
 		     struct intel_crtc_state *crtc_state);
 void intel_ips_enable(struct intel_crtc *crtc);
 void intel_ips_disable(struct intel_crtc *crtc);
+void intel_ips_disable_if_alone(struct intel_crtc *crtc);
 void intel_ips_init(struct drm_i915_private *dev_priv);
 
 /* intel_csr.c */
diff --git a/drivers/gpu/drm/i915/intel_ips.c b/drivers/gpu/drm/i915/intel_ips.c
index 1d0d8ff..b867aba 100644
--- a/drivers/gpu/drm/i915/intel_ips.c
+++ b/drivers/gpu/drm/i915/intel_ips.c
@@ -199,13 +199,46 @@ out:
 }
 
 /**
+ * intel_ips_disable_if_alone - Disable IPS if alone in the pipe.
+ * @crtc: intel crtc
+ *
+ * This function should be called when primary plane is being disabled.
+ * It checks if there is any other plane enabled on the pipe when primary is
+ * going to be disabled. In this case IPS can continue enabled, but it needs
+ * to be disabled otherwise.
+ */
+void intel_ips_disable_if_alone(struct intel_crtc *crtc)
+{
+	struct drm_device *dev = crtc->base.dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	bool ips_enabled;
+	struct intel_plane *intel_plane;
+
+	mutex_lock(&dev_priv->display_ips.lock);
+	ips_enabled = dev_priv->display_ips.enabled;
+	mutex_unlock(&dev_priv->display_ips.lock);
+
+	if (!ips_enabled)
+		return;
+
+	for_each_intel_plane_on_crtc(dev, crtc, intel_plane) {
+		enum plane plane = intel_plane->plane;
+
+		if (plane != PLANE_A &&
+		    !!(I915_READ(DSPCNTR(plane)) & DISPLAY_PLANE_ENABLE))
+			return;
+		intel_ips_disable(crtc);
+	}
+}
+
+/**
  * intel_ips_init - Init IPS
  * @dev_priv: drm i915 private.
  *
  * This function should be called only once to initialize what ever needed
  * for IPS.
  */
-void intel_ips_init(struct drm_i915_private dev_priv)
+void intel_ips_init(struct drm_i915_private *dev_priv)
 {
 	mutex_init(&dev_priv->display_ips.lock);
 }
-- 
2.4.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/intel-gfx




[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux