drm/i915: Add intel_display_power_{get, put} to request power for specific domains
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Mon, 16 Sep 2013 14:38:28 +0000 (17:38 +0300)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 20 Sep 2013 21:48:44 +0000 (23:48 +0200)
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ä <ville.syrjala@linux.intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_pm.c

index f1f11d1..1f05267 100644 (file)
@@ -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);
index 609c936..a0e198c 100644 (file)
@@ -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 */