[PATCH 21/24] power well

José Roberto de Souza jose.souza at intel.com
Tue Sep 11 01:09:54 UTC 2018


---
 drivers/gpu/drm/i915/intel_runtime_pm.c | 83 +++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
index 331a4a06a9f4..11d6fd3fd0b9 100644
--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
+++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
@@ -1518,6 +1518,9 @@ __intel_display_power_get_domain(struct drm_i915_private *dev_priv,
 	struct i915_power_domains *power_domains = &dev_priv->power_domains;
 	struct i915_power_well *power_well;
 
+	if (!INTEL_INFO(dev_priv)->num_pipes)
+		DRM_ERROR("Enabling a power well with display disabled");
+
 	for_each_power_domain_well(dev_priv, power_well, BIT_ULL(domain))
 		intel_power_well_get(dev_priv, power_well);
 
@@ -1543,6 +1546,13 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
 
 	intel_runtime_pm_get(dev_priv);
 
+	/* With display disabled this should be the only 2 power domains
+	 * requested
+	 */
+	if ((domain == POWER_DOMAIN_INIT || domain == POWER_DOMAIN_GT_IRQ) &&
+	    !INTEL_INFO(dev_priv)->num_pipes)
+		return;
+
 	mutex_lock(&power_domains->lock);
 
 	__intel_display_power_get_domain(dev_priv, domain);
@@ -1603,6 +1613,10 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 	struct i915_power_domains *power_domains;
 	struct i915_power_well *power_well;
 
+	if ((domain == POWER_DOMAIN_INIT || domain == POWER_DOMAIN_GT_IRQ) &&
+	    !INTEL_INFO(dev_priv)->num_pipes)
+		goto end;
+
 	power_domains = &dev_priv->power_domains;
 
 	mutex_lock(&power_domains->lock);
@@ -1617,6 +1631,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 
 	mutex_unlock(&power_domains->lock);
 
+end:
 	intel_runtime_pm_put(dev_priv);
 }
 
@@ -3749,6 +3764,70 @@ static void vlv_cmnlane_wa(struct drm_i915_private *dev_priv)
 
 static void intel_power_domains_verify_state(struct drm_i915_private *dev_priv);
 
+static void intel_power_domains_disable_all(struct drm_i915_private *dev_priv)
+{
+	struct i915_power_domains *power_domains = &dev_priv->power_domains;
+	struct i915_power_well *power_well;
+	int i;
+
+	DRM_DEBUG_KMS("intel_power_domains_disable_all\n");
+
+	mutex_lock(&power_domains->lock);
+
+	/* Disable everything that is enabled and is not a HW power_well */
+	for_each_power_well(dev_priv, power_well) {
+		bool enabled;
+
+		WARN_ON(power_well->count);
+
+		/*
+		 * Power wells not belonging to any domain (like the MISC_IO
+		 * and PW1 power wells) are under FW control, so ignore them,
+		 * since their state can change asynchronously.
+		 */
+		if (!power_well->desc->domains || power_well->desc->always_on)
+			continue;
+
+		if (power_well->desc->id != DISP_PW_ID_NONE)
+			continue;
+
+		enabled = power_well->desc->ops->is_enabled(dev_priv,
+							    power_well);
+		if (!enabled)
+			continue;
+
+		intel_power_well_disable(dev_priv, power_well);
+	}
+
+	/* Disabled HW power_well in reverse order, so pw2 is disabled before
+	 * pw1 and so on as required by spec.
+	 */
+	for (i = power_domains->power_well_count - 1; i >= 0; i--) {
+		bool enabled;
+
+		power_well = &power_domains->power_wells[i];
+
+		WARN_ON(power_well->count);
+
+		if (!power_well->desc->domains || power_well->desc->always_on)
+			continue;
+
+		if (power_well->desc->id == DISP_PW_ID_NONE)
+			continue;
+
+		enabled = power_well->desc->ops->is_enabled(dev_priv,
+							    power_well);
+		if (!enabled)
+			continue;
+
+		intel_power_well_disable(dev_priv, power_well);
+	}
+
+	mutex_unlock(&power_domains->lock);
+
+	intel_power_domains_verify_state(dev_priv);
+}
+
 /**
  * intel_power_domains_init_hw - initialize hardware power domain state
  * @dev_priv: i915 device instance
@@ -3810,6 +3889,10 @@ void intel_power_domains_init_hw(struct drm_i915_private *dev_priv, bool resume)
 		intel_display_power_get(dev_priv, POWER_DOMAIN_INIT);
 	intel_power_domains_sync_hw(dev_priv);
 
+	/* disable everything left enabled by BIOS/firmware */
+	if (!INTEL_INFO(dev_priv)->num_pipes)
+		intel_power_domains_disable_all(dev_priv);
+
 	power_domains->initializing = false;
 }
 
-- 
2.18.0



More information about the Intel-gfx-trybot mailing list