drm/i915: Power gating display wells during i915_pm_suspend
authorBorun Fu <borun.fu@intel.com>
Sat, 12 Jul 2014 04:32:27 +0000 (10:02 +0530)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Wed, 23 Jul 2014 05:04:54 +0000 (07:04 +0200)
On VLV, after i915_pm_suspend display power wells are staying
power ungated. So, after initiating mem sleep "echo mem > /sys/power/state"
Display is staing D0 State. There might be better way/place to power gate
these wells. Also, we need to make sure that if wells are power gated due to
DPMS OFF sequence, they need not be turned off by i915_pm_suspend again.

v2: Extracted helper for intel_crtc_disable and power gating CRTC power wells.
[Daniel]

Cc: Imre Deak <imre.deak@intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Change-Id: I34c80da66aa24c423a5576c68aa1f3a8d0f43848
Signed-off-by: Borun Fu <borun.fu@intel.com>
Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_drv.h

index 23139aaa9431ca10d3c88fad5851ee09df2c23de..de7d9a73eb2bcc20b3388a7fc763663a6f0e0369 100644 (file)
@@ -525,12 +525,11 @@ static int i915_drm_freeze(struct drm_device *dev)
 
                /*
                 * Disable CRTCs directly since we want to preserve sw state
-                * for _thaw.
+                * for _thaw. Also, power gate the CRTC power wells.
                 */
                drm_modeset_lock_all(dev);
-               for_each_crtc(dev, crtc) {
-                       dev_priv->display.crtc_disable(crtc);
-               }
+               for_each_crtc(dev, crtc)
+                       intel_crtc_control(crtc, false);
                drm_modeset_unlock_all(dev);
 
                intel_modeset_suspend_hw(dev);
index 8620ea91e10825299b6ee6ffcd3a5f3aa65c5d56..1c6640118a7084b61733156d4ee8d3bc6e0017b3 100644 (file)
@@ -179,6 +179,10 @@ enum hpd_pin {
        list_for_each_entry((intel_connector), &(dev)->mode_config.connector_list, base.head) \
                if ((intel_connector)->base.encoder == (__encoder))
 
+#define for_each_power_domain(domain, mask)                            \
+       for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++)     \
+               if ((1 << (domain)) & (mask))
+
 struct drm_i915_private;
 struct i915_mmu_object;
 
index d2b752dd0aafa3768a4c52dd2c2f8d8ca6032a44..7e0dc46ec505d7819cff69a09f5a7d7c6961cbf4 100644 (file)
@@ -4300,10 +4300,6 @@ static void i9xx_pfit_enable(struct intel_crtc *crtc)
        I915_WRITE(BCLRPAT(crtc->pipe), 0);
 }
 
-#define for_each_power_domain(domain, mask)                            \
-       for ((domain) = 0; (domain) < POWER_DOMAIN_NUM; (domain)++)     \
-               if ((1 << (domain)) & (mask))
-
 enum intel_display_power_domain
 intel_display_port_power_domain(struct intel_encoder *intel_encoder)
 {
@@ -4872,21 +4868,14 @@ static void intel_crtc_update_sarea(struct drm_crtc *crtc,
        }
 }
 
-/**
- * Sets the power management mode of the pipe and plane.
- */
-void intel_crtc_update_dpms(struct drm_crtc *crtc)
+/* Master function to enable/disable CRTC and corresponding power wells */
+void intel_crtc_control(struct drm_crtc *crtc, bool enable)
 {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
-       struct intel_encoder *intel_encoder;
        enum intel_display_power_domain domain;
        unsigned long domains;
-       bool enable = false;
-
-       for_each_encoder_on_crtc(dev, crtc, intel_encoder)
-               enable |= intel_encoder->connectors_active;
 
        if (enable) {
                if (!intel_crtc->active) {
@@ -4907,6 +4896,21 @@ void intel_crtc_update_dpms(struct drm_crtc *crtc)
                        intel_crtc->enabled_power_domains = 0;
                }
        }
+}
+
+/**
+ * Sets the power management mode of the pipe and plane.
+ */
+void intel_crtc_update_dpms(struct drm_crtc *crtc)
+{
+       struct drm_device *dev = crtc->dev;
+       struct intel_encoder *intel_encoder;
+       bool enable = false;
+
+       for_each_encoder_on_crtc(dev, crtc, intel_encoder)
+               enable |= intel_encoder->connectors_active;
+
+       intel_crtc_control(crtc, enable);
 
        intel_crtc_update_sarea(crtc, enable);
 }
index fa19744ed6c0ed97b1429a8685a3bf404d6de090..b9540c01bab3c71b29d8aa11f2f4e778870c3092 100644 (file)
@@ -753,6 +753,7 @@ void intel_frontbuffer_flip(struct drm_device *dev,
 void intel_fb_obj_flush(struct drm_i915_gem_object *obj, bool retire);
 void intel_mark_idle(struct drm_device *dev);
 void intel_crtc_restore_mode(struct drm_crtc *crtc);
+void intel_crtc_control(struct drm_crtc *crtc, bool enable);
 void intel_crtc_update_dpms(struct drm_crtc *crtc);
 void intel_encoder_destroy(struct drm_encoder *encoder);
 void intel_connector_dpms(struct drm_connector *, int mode);