[PATCH 20/22] drm/i915/skl+: Power down all powers wells turn on by BIOS/firmware when display is disabled

José Roberto de Souza jose.souza at intel.com
Mon Aug 6 21:52:57 UTC 2018


Now that no display block is touched when display is disable we can
save more power by powering down all power wells that BIOS/firmware
or even a previous load of i915.
Here disabling higher power wells that depends in lower ones than
disabling everything else that was left(aux and ddi).

Signed-off-by: José Roberto de Souza <jose.souza at intel.com>
---
 drivers/gpu/drm/i915/intel_runtime_pm.c | 98 ++++++++++++++++++++++++-
 1 file changed, 94 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 8f4a8a5f69da..68d573bf3f97 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -3074,6 +3074,23 @@ static void skl_pch_reset_handshake(struct drm_i915_private *dev_priv)
 	I915_WRITE(HSW_NDE_RSTWRN_OPT, val);
 }
 
+static void power_well_disable_all(struct drm_i915_private *dev_priv)
+{
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+	unsigned i;
+
+	for (i = 0; i < power_domains->power_well_count; i++) {
+		struct i915_power_well *power_well;
+
+		power_well = &power_domains->power_wells[i];
+
+		if (!power_well->hw_enabled || power_well->always_on)
+			continue;
+
+		intel_power_well_disable(dev_priv, power_well);
+	}
+}
+
 static void skl_display_core_init(struct drm_i915_private *dev_priv,
 				   bool resume)
 {
@@ -3085,8 +3102,27 @@ static void skl_display_core_init(struct drm_i915_private *dev_priv,
 	/* enable PCH reset handshake */
 	skl_pch_reset_handshake(dev_priv);
 
-	if (!INTEL_INFO(dev_priv)->num_pipes)
+	if (!INTEL_INFO(dev_priv)->num_pipes) {
+		/* sync so it can take control of PW that BIOS enabled */
+		intel_power_domains_sync_hw(dev_priv);
+
+		mutex_lock(&power_domains->lock);
+
+		well = lookup_power_well(dev_priv, SKL_DISP_PW_MISC_IO);
+		intel_power_well_disable(dev_priv, well);
+
+		well = lookup_power_well(dev_priv, SKL_DISP_PW_2);
+		intel_power_well_disable(dev_priv, well);
+
+		well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
+		intel_power_well_disable(dev_priv, well);
+
+		power_well_disable_all(dev_priv);
+
+		mutex_unlock(&power_domains->lock);
+
 		return;
+	}
 
 	/* enable PG1 and Misc I/O */
 	mutex_lock(&power_domains->lock);
@@ -3156,8 +3192,27 @@ void bxt_display_core_init(struct drm_i915_private *dev_priv,
 	 */
 	skl_pch_reset_handshake(dev_priv);
 
-	if (!INTEL_INFO(dev_priv)->num_pipes)
+	if (!INTEL_INFO(dev_priv)->num_pipes) {
+		/* sync so it can take control of PW that BIOS enabled */
+		intel_power_domains_sync_hw(dev_priv);
+
+		mutex_lock(&power_domains->lock);
+
+		well = lookup_power_well(dev_priv, SKL_DISP_PW_MISC_IO);
+		intel_power_well_disable(dev_priv, well);
+
+		well = lookup_power_well(dev_priv, SKL_DISP_PW_2);
+		intel_power_well_disable(dev_priv, well);
+
+		well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
+		intel_power_well_disable(dev_priv, well);
+
+		power_well_disable_all(dev_priv);
+
+		mutex_unlock(&power_domains->lock);
+
 		return;
+	}
 
 	/* Enable PG1 */
 	mutex_lock(&power_domains->lock);
@@ -3283,8 +3338,24 @@ static void cnl_display_core_init(struct drm_i915_private *dev_priv, bool resume
 	/* 1. Enable PCH Reset Handshake */
 	skl_pch_reset_handshake(dev_priv);
 
-	if (!INTEL_INFO(dev_priv)->num_pipes)
+	if (!INTEL_INFO(dev_priv)->num_pipes) {
+		/* sync so it can take control of PW that BIOS enabled */
+		intel_power_domains_sync_hw(dev_priv);
+
+		mutex_lock(&power_domains->lock);
+
+		well = lookup_power_well(dev_priv, SKL_DISP_PW_2);
+		intel_power_well_disable(dev_priv, well);
+
+		well = lookup_power_well(dev_priv, SKL_DISP_PW_1);
+		intel_power_well_disable(dev_priv, well);
+
+		power_well_disable_all(dev_priv);
+
+		mutex_unlock(&power_domains->lock);
+
 		return;
+	}
 
 	/* 2. Enable Comp */
 	val = I915_READ(CHICKEN_MISC_2);
@@ -3372,8 +3443,27 @@ static void icl_display_core_init(struct drm_i915_private *dev_priv,
 	/* 1. Enable PCH reset handshake. */
 	skl_pch_reset_handshake(dev_priv);
 
-	if (!INTEL_INFO(dev_priv)->num_pipes)
+	if (!INTEL_INFO(dev_priv)->num_pipes) {
+		enum i915_power_well_id pw_id;
+
+		/* sync so it can take control of PW that BIOS enabled */
+		intel_power_domains_sync_hw(dev_priv);
+
+		mutex_lock(&power_domains->lock);
+
+		pw_id = ICL_DISP_PW_4 + 1;
+		do {
+			pw_id--;
+			well = lookup_power_well(dev_priv, pw_id);
+			intel_power_well_disable(dev_priv, well);
+		} while (pw_id > ICL_DISP_PW_1);
+
+		power_well_disable_all(dev_priv);
+
+		mutex_unlock(&power_domains->lock);
+
 		return;
+	}
 
 	for (port = PORT_A; port <= PORT_B; port++) {
 		/* 2. Enable DDI combo PHY comp. */
-- 
2.18.0



More information about the Intel-gfx-trybot mailing list