From 6765625e0b677a86dbd533f045ab4e52e2761d79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Mon, 16 Sep 2013 17:38:28 +0300 Subject: [PATCH] drm/i915: Add intel_display_power_{get, put} to request power for specific domains MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add APIs to get/put power well references for specific purposes. v2: Split the i915_request change to another patch Signed-off-by: Ville Syrjälä Reviewed-by: Paulo Zanoni Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/intel_drv.h | 4 ++ drivers/gpu/drm/i915/intel_pm.c | 63 ++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f1f11d10e485..1f0526780356 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -762,6 +762,10 @@ extern void i915_remove_power_well(struct drm_device *dev); extern bool intel_display_power_enabled(struct drm_device *dev, enum intel_display_power_domain domain); +extern void intel_display_power_get(struct drm_device *dev, + enum intel_display_power_domain domain); +extern void intel_display_power_put(struct drm_device *dev, + enum intel_display_power_domain domain); extern void intel_init_power_well(struct drm_device *dev); extern void intel_set_power_well(struct drm_device *dev, bool enable); extern void intel_resume_power_well(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 609c936d1dfe..a0e198c8e141 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c @@ -5345,6 +5345,69 @@ static void __intel_set_power_well(struct drm_device *dev, bool enable) } } +void intel_display_power_get(struct drm_device *dev, + enum intel_display_power_domain domain) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct i915_power_well *power_well = &dev_priv->power_well; + + if (!HAS_POWER_WELL(dev)) + return; + + switch (domain) { + case POWER_DOMAIN_PIPE_A: + case POWER_DOMAIN_TRANSCODER_EDP: + return; + case POWER_DOMAIN_PIPE_B: + case POWER_DOMAIN_PIPE_C: + case POWER_DOMAIN_PIPE_A_PANEL_FITTER: + case POWER_DOMAIN_PIPE_B_PANEL_FITTER: + case POWER_DOMAIN_PIPE_C_PANEL_FITTER: + case POWER_DOMAIN_TRANSCODER_A: + case POWER_DOMAIN_TRANSCODER_B: + case POWER_DOMAIN_TRANSCODER_C: + spin_lock_irq(&power_well->lock); + if (!power_well->count++) + __intel_set_power_well(power_well->device, true); + spin_unlock_irq(&power_well->lock); + return; + default: + BUG(); + } +} + +void intel_display_power_put(struct drm_device *dev, + enum intel_display_power_domain domain) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct i915_power_well *power_well = &dev_priv->power_well; + + if (!HAS_POWER_WELL(dev)) + return; + + switch (domain) { + case POWER_DOMAIN_PIPE_A: + case POWER_DOMAIN_TRANSCODER_EDP: + return; + case POWER_DOMAIN_PIPE_B: + case POWER_DOMAIN_PIPE_C: + case POWER_DOMAIN_PIPE_A_PANEL_FITTER: + case POWER_DOMAIN_PIPE_B_PANEL_FITTER: + case POWER_DOMAIN_PIPE_C_PANEL_FITTER: + case POWER_DOMAIN_TRANSCODER_A: + case POWER_DOMAIN_TRANSCODER_B: + case POWER_DOMAIN_TRANSCODER_C: + spin_lock_irq(&power_well->lock); + WARN_ON(!power_well->count); + if (!--power_well->count) + __intel_set_power_well(power_well->device, false); + spin_unlock_irq(&power_well->lock); + return; + default: + BUG(); + } +} + static struct i915_power_well *hsw_pwr; /* Display audio driver power well request */