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

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

 



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@xxxxxxxxxxxxxxxxxx>
---
 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

_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
https://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