Merge tag 'drm-intel-fixes-2014-07-03' of git://anongit.freedesktop.org/drm-intel
[cascardo/linux.git] / drivers / gpu / drm / i915 / intel_pm.c
index 54242e4..ee72807 100644 (file)
@@ -3209,6 +3209,14 @@ void gen6_set_rps(struct drm_device *dev, u8 val)
 */
 static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
 {
+       struct drm_device *dev = dev_priv->dev;
+
+       /* Latest VLV doesn't need to force the gfx clock */
+       if (dev->pdev->revision >= 0xd) {
+               valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_freq_softlimit);
+               return;
+       }
+
        /*
         * When we are idle.  Drop to min voltage state.
         */
@@ -5603,8 +5611,8 @@ static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv,
                     (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED);
 }
 
-bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv,
-                                   enum intel_display_power_domain domain)
+bool intel_display_power_enabled_unlocked(struct drm_i915_private *dev_priv,
+                                         enum intel_display_power_domain domain)
 {
        struct i915_power_domains *power_domains;
        struct i915_power_well *power_well;
@@ -5615,16 +5623,19 @@ bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv,
                return false;
 
        power_domains = &dev_priv->power_domains;
+
        is_enabled = true;
+
        for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
                if (power_well->always_on)
                        continue;
 
-               if (!power_well->count) {
+               if (!power_well->hw_enabled) {
                        is_enabled = false;
                        break;
                }
        }
+
        return is_enabled;
 }
 
@@ -5632,30 +5643,15 @@ bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
                                 enum intel_display_power_domain domain)
 {
        struct i915_power_domains *power_domains;
-       struct i915_power_well *power_well;
-       bool is_enabled;
-       int i;
-
-       if (dev_priv->pm.suspended)
-               return false;
+       bool ret;
 
        power_domains = &dev_priv->power_domains;
 
-       is_enabled = true;
-
        mutex_lock(&power_domains->lock);
-       for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
-               if (power_well->always_on)
-                       continue;
-
-               if (!power_well->ops->is_enabled(dev_priv, power_well)) {
-                       is_enabled = false;
-                       break;
-               }
-       }
+       ret = intel_display_power_enabled_unlocked(dev_priv, domain);
        mutex_unlock(&power_domains->lock);
 
-       return is_enabled;
+       return ret;
 }
 
 /*
@@ -5976,6 +5972,7 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
                if (!power_well->count++) {
                        DRM_DEBUG_KMS("enabling %s\n", power_well->name);
                        power_well->ops->enable(dev_priv, power_well);
+                       power_well->hw_enabled = true;
                }
 
                check_power_well_state(dev_priv, power_well);
@@ -6005,6 +6002,7 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
 
                if (!--power_well->count && i915.disable_power_well) {
                        DRM_DEBUG_KMS("disabling %s\n", power_well->name);
+                       power_well->hw_enabled = false;
                        power_well->ops->disable(dev_priv, power_well);
                }
 
@@ -6048,6 +6046,27 @@ int i915_release_power_well(void)
 }
 EXPORT_SYMBOL_GPL(i915_release_power_well);
 
+/*
+ * Private interface for the audio driver to get CDCLK in kHz.
+ *
+ * Caller must request power well using i915_request_power_well() prior to
+ * making the call.
+ */
+int i915_get_cdclk_freq(void)
+{
+       struct drm_i915_private *dev_priv;
+
+       if (!hsw_pwr)
+               return -ENODEV;
+
+       dev_priv = container_of(hsw_pwr, struct drm_i915_private,
+                               power_domains);
+
+       return intel_ddi_get_cdclk_freq(dev_priv);
+}
+EXPORT_SYMBOL_GPL(i915_get_cdclk_freq);
+
+
 #define POWER_DOMAIN_MASK (BIT(POWER_DOMAIN_NUM) - 1)
 
 #define HSW_ALWAYS_ON_POWER_DOMAINS (                  \
@@ -6267,8 +6286,11 @@ static void intel_power_domains_resume(struct drm_i915_private *dev_priv)
        int i;
 
        mutex_lock(&power_domains->lock);
-       for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains)
+       for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) {
                power_well->ops->sync_hw(dev_priv, power_well);
+               power_well->hw_enabled = power_well->ops->is_enabled(dev_priv,
+                                                                    power_well);
+       }
        mutex_unlock(&power_domains->lock);
 }