@@ -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);
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@chris-wilson.co.uk> --- drivers/gpu/drm/i915/intel_display.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-)