]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - drivers/gpu/drm/i915/intel_runtime_pm.c
Merge branch 'linux-4.3' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into...
[karo-tx-linux.git] / drivers / gpu / drm / i915 / intel_runtime_pm.c
index 1a45385f4d66947087c8ae072e2e2b2328ad6651..af7fdb3bd663aef062a5cd41a2cdacbb4492515d 100644 (file)
 bool intel_display_power_well_is_enabled(struct drm_i915_private *dev_priv,
                                    int power_well_id);
 
+static void intel_power_well_enable(struct drm_i915_private *dev_priv,
+                                   struct i915_power_well *power_well)
+{
+       DRM_DEBUG_KMS("enabling %s\n", power_well->name);
+       power_well->ops->enable(dev_priv, power_well);
+       power_well->hw_enabled = true;
+}
+
+static void intel_power_well_disable(struct drm_i915_private *dev_priv,
+                                    struct i915_power_well *power_well)
+{
+       DRM_DEBUG_KMS("disabling %s\n", power_well->name);
+       power_well->hw_enabled = false;
+       power_well->ops->disable(dev_priv, power_well);
+}
+
 /*
  * We should only use the power well if we explicitly asked the hardware to
  * enable it, so check if it's enabled and also check if we've requested it to
@@ -281,6 +297,7 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
        BIT(POWER_DOMAIN_PORT_DDI_C_4_LANES) |          \
        BIT(POWER_DOMAIN_PORT_DDI_D_2_LANES) |          \
        BIT(POWER_DOMAIN_PORT_DDI_D_4_LANES) |          \
+       BIT(POWER_DOMAIN_PORT_DDI_E_2_LANES) |          \
        BIT(POWER_DOMAIN_AUX_B) |                       \
        BIT(POWER_DOMAIN_AUX_C) |                       \
        BIT(POWER_DOMAIN_AUX_D) |                       \
@@ -300,6 +317,7 @@ static void hsw_set_power_well(struct drm_i915_private *dev_priv,
 #define SKL_DISPLAY_DDI_A_E_POWER_DOMAINS (            \
        BIT(POWER_DOMAIN_PORT_DDI_A_2_LANES) |          \
        BIT(POWER_DOMAIN_PORT_DDI_A_4_LANES) |          \
+       BIT(POWER_DOMAIN_PORT_DDI_E_2_LANES) |          \
        BIT(POWER_DOMAIN_INIT))
 #define SKL_DISPLAY_DDI_B_POWER_DOMAINS (              \
        BIT(POWER_DOMAIN_PORT_DDI_B_2_LANES) |          \
@@ -835,12 +853,8 @@ static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
        return enabled;
 }
 
-static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv,
-                                         struct i915_power_well *power_well)
+static void vlv_display_power_well_init(struct drm_i915_private *dev_priv)
 {
-       WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);
-
-       vlv_set_power_well(dev_priv, power_well, true);
 
        spin_lock_irq(&dev_priv->irq_lock);
        valleyview_enable_display_irqs(dev_priv);
@@ -858,18 +872,33 @@ static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv,
        i915_redisable_vga_power_on(dev_priv->dev);
 }
 
+static void vlv_display_power_well_deinit(struct drm_i915_private *dev_priv)
+{
+       spin_lock_irq(&dev_priv->irq_lock);
+       valleyview_disable_display_irqs(dev_priv);
+       spin_unlock_irq(&dev_priv->irq_lock);
+
+       vlv_power_sequencer_reset(dev_priv);
+}
+
+static void vlv_display_power_well_enable(struct drm_i915_private *dev_priv,
+                                         struct i915_power_well *power_well)
+{
+       WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);
+
+       vlv_set_power_well(dev_priv, power_well, true);
+
+       vlv_display_power_well_init(dev_priv);
+}
+
 static void vlv_display_power_well_disable(struct drm_i915_private *dev_priv,
                                           struct i915_power_well *power_well)
 {
        WARN_ON_ONCE(power_well->data != PUNIT_POWER_WELL_DISP2D);
 
-       spin_lock_irq(&dev_priv->irq_lock);
-       valleyview_disable_display_irqs(dev_priv);
-       spin_unlock_irq(&dev_priv->irq_lock);
+       vlv_display_power_well_deinit(dev_priv);
 
        vlv_set_power_well(dev_priv, power_well, false);
-
-       vlv_power_sequencer_reset(dev_priv);
 }
 
 static void vlv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
@@ -882,8 +911,8 @@ static void vlv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
         * display and the reference clock for VGA
         * hotplug / manual detection.
         */
-       I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) |
-                  DPLL_REFA_CLK_ENABLE_VLV | DPLL_INTEGRATED_CRI_CLK_VLV);
+       I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) | DPLL_VGA_MODE_DIS |
+                  DPLL_REF_CLK_ENABLE_VLV | DPLL_INTEGRATED_CRI_CLK_VLV);
        udelay(1); /* >10ns for cmnreset, >0ns for sidereset */
 
        vlv_set_power_well(dev_priv, power_well, true);
@@ -933,14 +962,14 @@ static void chv_dpio_cmn_power_well_enable(struct drm_i915_private *dev_priv,
         */
        if (power_well->data == PUNIT_POWER_WELL_DPIO_CMN_BC) {
                phy = DPIO_PHY0;
-               I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) |
-                          DPLL_REFA_CLK_ENABLE_VLV);
-               I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) |
-                          DPLL_REFA_CLK_ENABLE_VLV | DPLL_INTEGRATED_CRI_CLK_VLV);
+               I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) | DPLL_VGA_MODE_DIS |
+                          DPLL_REF_CLK_ENABLE_VLV);
+               I915_WRITE(DPLL(PIPE_B), I915_READ(DPLL(PIPE_B)) | DPLL_VGA_MODE_DIS |
+                          DPLL_REF_CLK_ENABLE_VLV | DPLL_INTEGRATED_CRI_CLK_VLV);
        } else {
                phy = DPIO_PHY1;
-               I915_WRITE(DPLL(PIPE_C), I915_READ(DPLL(PIPE_C)) |
-                          DPLL_REFA_CLK_ENABLE_VLV | DPLL_INTEGRATED_CRI_CLK_VLV);
+               I915_WRITE(DPLL(PIPE_C), I915_READ(DPLL(PIPE_C)) | DPLL_VGA_MODE_DIS |
+                          DPLL_REF_CLK_ENABLE_VLV | DPLL_INTEGRATED_CRI_CLK_VLV);
        }
        udelay(1); /* >10ns for cmnreset, >0ns for sidereset */
        vlv_set_power_well(dev_priv, power_well, true);
@@ -1042,53 +1071,29 @@ out:
 static void chv_pipe_power_well_sync_hw(struct drm_i915_private *dev_priv,
                                        struct i915_power_well *power_well)
 {
+       WARN_ON_ONCE(power_well->data != PIPE_A);
+
        chv_set_pipe_power_well(dev_priv, power_well, power_well->count > 0);
 }
 
 static void chv_pipe_power_well_enable(struct drm_i915_private *dev_priv,
                                       struct i915_power_well *power_well)
 {
-       WARN_ON_ONCE(power_well->data != PIPE_A &&
-                    power_well->data != PIPE_B &&
-                    power_well->data != PIPE_C);
+       WARN_ON_ONCE(power_well->data != PIPE_A);
 
        chv_set_pipe_power_well(dev_priv, power_well, true);
 
-       if (power_well->data == PIPE_A) {
-               spin_lock_irq(&dev_priv->irq_lock);
-               valleyview_enable_display_irqs(dev_priv);
-               spin_unlock_irq(&dev_priv->irq_lock);
-
-               /*
-                * During driver initialization/resume we can avoid restoring the
-                * part of the HW/SW state that will be inited anyway explicitly.
-                */
-               if (dev_priv->power_domains.initializing)
-                       return;
-
-               intel_hpd_init(dev_priv);
-
-               i915_redisable_vga_power_on(dev_priv->dev);
-       }
+       vlv_display_power_well_init(dev_priv);
 }
 
 static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv,
                                        struct i915_power_well *power_well)
 {
-       WARN_ON_ONCE(power_well->data != PIPE_A &&
-                    power_well->data != PIPE_B &&
-                    power_well->data != PIPE_C);
+       WARN_ON_ONCE(power_well->data != PIPE_A);
 
-       if (power_well->data == PIPE_A) {
-               spin_lock_irq(&dev_priv->irq_lock);
-               valleyview_disable_display_irqs(dev_priv);
-               spin_unlock_irq(&dev_priv->irq_lock);
-       }
+       vlv_display_power_well_deinit(dev_priv);
 
        chv_set_pipe_power_well(dev_priv, power_well, false);
-
-       if (power_well->data == PIPE_A)
-               vlv_power_sequencer_reset(dev_priv);
 }
 
 /**
@@ -1117,11 +1122,8 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
        mutex_lock(&power_domains->lock);
 
        for_each_power_well(i, power_well, BIT(domain), power_domains) {
-               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;
-               }
+               if (!power_well->count++)
+                       intel_power_well_enable(dev_priv, power_well);
        }
 
        power_domains->domain_use_count[domain]++;
@@ -1155,11 +1157,8 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
        for_each_power_well_rev(i, power_well, BIT(domain), power_domains) {
                WARN_ON(!power_well->count);
 
-               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);
-               }
+               if (!--power_well->count && i915.disable_power_well)
+                       intel_power_well_disable(dev_priv, power_well);
        }
 
        mutex_unlock(&power_domains->lock);