[Intel-gfx] [RFC 8/8] drm/i915: Track crtc wakerefs during modesetting

Chris Wilson chris at chris-wilson.co.uk
Fri Aug 10 07:11:38 UTC 2018


Modesetting is one of the more complex interactions with power wells as
it acquires multiple wells to do its business. Fortunately, we do not
have to track every one individually as they are all called from the
same location and thus will have matching wakerefs (being a hash of its
stacktrace).

Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
---
 drivers/gpu/drm/i915/intel_display.c | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 6606e57f9265..9efbb930da9c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -5953,7 +5953,8 @@ static u64 get_crtc_power_domains(struct drm_crtc *crtc,
 
 static u64
 modeset_get_crtc_power_domains(struct drm_crtc *crtc,
-			       struct intel_crtc_state *crtc_state)
+			       struct intel_crtc_state *crtc_state,
+			       intel_wakeref_t *wakeref)
 {
 	struct drm_i915_private *dev_priv = to_i915(crtc->dev);
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -5967,18 +5968,18 @@ modeset_get_crtc_power_domains(struct drm_crtc *crtc,
 	domains = new_domains & ~old_domains;
 
 	for_each_power_domain(domain, domains)
-		intel_display_power_get(dev_priv, domain);
+		*wakeref = intel_display_power_get(dev_priv, domain);
 
 	return old_domains & ~new_domains;
 }
 
 static void modeset_put_power_domains(struct drm_i915_private *dev_priv,
-				      u64 domains)
+				      u64 domains, intel_wakeref_t wakeref)
 {
 	enum intel_display_power_domain domain;
 
 	for_each_power_domain(domain, domains)
-		intel_display_power_put_unchecked(dev_priv, domain);
+		intel_display_power_put(dev_priv, domain, wakeref);
 }
 
 static void valleyview_crtc_enable(struct intel_crtc_state *pipe_config,
@@ -12598,6 +12599,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
 	struct intel_crtc_state *intel_cstate;
 	u64 put_domains[I915_MAX_PIPES] = {};
 	intel_wakeref_t wakeref = 0;
+	intel_wakeref_t crtc_wakeref = 0;
 	int i;
 
 	intel_atomic_commit_fence_wait(intel_state);
@@ -12615,7 +12617,8 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
 
 			put_domains[to_intel_crtc(crtc)->pipe] =
 				modeset_get_crtc_power_domains(crtc,
-					to_intel_crtc_state(new_crtc_state));
+					to_intel_crtc_state(new_crtc_state),
+					&crtc_wakeref);
 		}
 
 		if (!needs_modeset(new_crtc_state))
@@ -12725,7 +12728,9 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
 		intel_post_plane_update(to_intel_crtc_state(old_crtc_state));
 
 		if (put_domains[i])
-			modeset_put_power_domains(dev_priv, put_domains[i]);
+			modeset_put_power_domains(dev_priv,
+						  put_domains[i],
+						  crtc_wakeref);
 
 		intel_modeset_verify_crtc(crtc, state, old_crtc_state, new_crtc_state);
 	}
@@ -15920,11 +15925,16 @@ intel_modeset_setup_hw_state(struct drm_device *dev,
 	}
 
 	for_each_intel_crtc(dev, crtc) {
+		intel_wakeref_t wakeref;
 		u64 put_domains;
 
-		put_domains = modeset_get_crtc_power_domains(&crtc->base, crtc->config);
+		put_domains = modeset_get_crtc_power_domains(&crtc->base,
+							     crtc->config,
+							     &wakeref);
 		if (WARN_ON(put_domains))
-			modeset_put_power_domains(dev_priv, put_domains);
+			modeset_put_power_domains(dev_priv,
+						  put_domains,
+						  wakeref);
 	}
 	intel_display_set_init_power(dev_priv, false);
 
-- 
2.18.0



More information about the Intel-gfx mailing list