]> Pileus Git - ~andy/linux/blobdiff - drivers/gpu/drm/i915/intel_pm.c
Merge tag 'v3.13-rc3' into drm-intel-next-queued
[~andy/linux] / drivers / gpu / drm / i915 / intel_pm.c
index 9230781824e5c8b8b10a94ef925126fe192ed47d..41b6e080e3622a0636a67d95b4d21f027a767ab7 100644 (file)
@@ -191,7 +191,11 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev)
        u32 blt_ecoskpd;
 
        /* Make sure blitter notifies FBC of writes */
-       gen6_gt_force_wake_get(dev_priv);
+
+       /* Blitter is part of Media powerwell on VLV. No impact of
+        * his param in other platforms for now */
+       gen6_gt_force_wake_get(dev_priv, FORCEWAKE_MEDIA);
+
        blt_ecoskpd = I915_READ(GEN6_BLITTER_ECOSKPD);
        blt_ecoskpd |= GEN6_BLITTER_FBC_NOTIFY <<
                GEN6_BLITTER_LOCK_SHIFT;
@@ -202,7 +206,8 @@ static void sandybridge_blit_fbc_update(struct drm_device *dev)
                         GEN6_BLITTER_LOCK_SHIFT);
        I915_WRITE(GEN6_BLITTER_ECOSKPD, blt_ecoskpd);
        POSTING_READ(GEN6_BLITTER_ECOSKPD);
-       gen6_gt_force_wake_put(dev_priv);
+
+       gen6_gt_force_wake_put(dev_priv, FORCEWAKE_MEDIA);
 }
 
 static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
@@ -532,10 +537,10 @@ void intel_update_fbc(struct drm_device *dev)
                        DRM_DEBUG_KMS("mode too large for compression, disabling\n");
                goto out_disable;
        }
-       if ((IS_I915GM(dev) || IS_I945GM(dev) || IS_HASWELL(dev)) &&
-           intel_crtc->plane != 0) {
+       if ((INTEL_INFO(dev)->gen < 4 || IS_HASWELL(dev)) &&
+           intel_crtc->plane != PLANE_A) {
                if (set_no_fbc_reason(dev_priv, FBC_BAD_PLANE))
-                       DRM_DEBUG_KMS("plane not 0, disabling compression\n");
+                       DRM_DEBUG_KMS("plane not A, disabling compression\n");
                goto out_disable;
        }
 
@@ -1627,7 +1632,7 @@ static void i9xx_update_wm(struct drm_crtc *unused_crtc)
                        &to_intel_crtc(enabled)->config.adjusted_mode;
                int clock = adjusted_mode->crtc_clock;
                int htotal = adjusted_mode->htotal;
-               int hdisplay = to_intel_crtc(crtc)->config.pipe_src_w;
+               int hdisplay = to_intel_crtc(enabled)->config.pipe_src_w;
                int pixel_size = enabled->fb->bits_per_pixel / 8;
                unsigned long line_time_us;
                int entries;
@@ -3739,7 +3744,7 @@ static void gen8_enable_rps(struct drm_device *dev)
 
        /* 1c & 1d: Get forcewake during program sequence. Although the driver
         * hasn't enabled a state yet where we need forcewake, BIOS may have.*/
-       gen6_gt_force_wake_get(dev_priv);
+       gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
 
        /* 2a: Disable RC states. */
        I915_WRITE(GEN6_RC_CONTROL, 0);
@@ -3796,7 +3801,7 @@ static void gen8_enable_rps(struct drm_device *dev)
 
        gen6_enable_rps_interrupts(dev);
 
-       gen6_gt_force_wake_put(dev_priv);
+       gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
 }
 
 static void gen6_enable_rps(struct drm_device *dev)
@@ -3826,7 +3831,7 @@ static void gen6_enable_rps(struct drm_device *dev)
                I915_WRITE(GTFIFODBG, gtfifodbg);
        }
 
-       gen6_gt_force_wake_get(dev_priv);
+       gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
 
        rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
        gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
@@ -3853,7 +3858,7 @@ static void gen6_enable_rps(struct drm_device *dev)
 
        I915_WRITE(GEN6_RC_SLEEP, 0);
        I915_WRITE(GEN6_RC1e_THRESHOLD, 1000);
-       if (INTEL_INFO(dev)->gen <= 6 || IS_IVYBRIDGE(dev))
+       if (IS_IVYBRIDGE(dev))
                I915_WRITE(GEN6_RC6_THRESHOLD, 125000);
        else
                I915_WRITE(GEN6_RC6_THRESHOLD, 50000);
@@ -3918,7 +3923,7 @@ static void gen6_enable_rps(struct drm_device *dev)
                        DRM_ERROR("Couldn't fix incorrect rc6 voltage\n");
        }
 
-       gen6_gt_force_wake_put(dev_priv);
+       gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
 }
 
 void gen6_update_ring_freq(struct drm_device *dev)
@@ -4080,7 +4085,8 @@ static void valleyview_enable_rps(struct drm_device *dev)
 
        valleyview_setup_pctx(dev);
 
-       gen6_gt_force_wake_get(dev_priv);
+       /* If VLV, Forcewake all wells, else re-direct to regular path */
+       gen6_gt_force_wake_get(dev_priv, FORCEWAKE_ALL);
 
        I915_WRITE(GEN6_RP_UP_THRESHOLD, 59400);
        I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 245000);
@@ -4104,7 +4110,7 @@ static void valleyview_enable_rps(struct drm_device *dev)
        for_each_ring(ring, dev_priv, i)
                I915_WRITE(RING_MAX_IDLE(ring->mmio_base), 10);
 
-       I915_WRITE(GEN6_RC6_THRESHOLD, 0xc350);
+       I915_WRITE(GEN6_RC6_THRESHOLD, 0x557);
 
        /* allows RC6 residency counter to work */
        I915_WRITE(VLV_COUNTER_CONTROL,
@@ -4112,7 +4118,7 @@ static void valleyview_enable_rps(struct drm_device *dev)
                                      VLV_MEDIA_RC6_COUNT_EN |
                                      VLV_RENDER_RC6_COUNT_EN));
        if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
-               rc6_mode = GEN7_RC_CTL_TO_MODE;
+               rc6_mode = GEN7_RC_CTL_TO_MODE | VLV_RC_CTL_CTX_RST_PARALLEL;
 
        intel_print_rc6_info(dev, rc6_mode);
 
@@ -4152,7 +4158,7 @@ static void valleyview_enable_rps(struct drm_device *dev)
 
        gen6_enable_rps_interrupts(dev);
 
-       gen6_gt_force_wake_put(dev_priv);
+       gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
 }
 
 void ironlake_teardown_rc6(struct drm_device *dev)
@@ -5635,6 +5641,17 @@ static bool hsw_power_well_enabled(struct drm_device *dev,
                     (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED);
 }
 
+bool intel_display_power_enabled_sw(struct drm_device *dev,
+                                   enum intel_display_power_domain domain)
+{
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       struct i915_power_domains *power_domains;
+
+       power_domains = &dev_priv->power_domains;
+
+       return power_domains->domain_use_count[domain];
+}
+
 bool intel_display_power_enabled(struct drm_device *dev,
                                 enum intel_display_power_domain domain)
 {
@@ -5644,9 +5661,6 @@ bool intel_display_power_enabled(struct drm_device *dev,
        bool is_enabled;
        int i;
 
-       if (!HAS_POWER_WELL(dev))
-               return true;
-
        power_domains = &dev_priv->power_domains;
 
        is_enabled = true;
@@ -5754,14 +5768,15 @@ void intel_display_power_get(struct drm_device *dev,
        struct i915_power_well *power_well;
        int i;
 
-       if (!HAS_POWER_WELL(dev))
-               return;
-
        power_domains = &dev_priv->power_domains;
 
        mutex_lock(&power_domains->lock);
+
        for_each_power_well(i, power_well, BIT(domain), power_domains)
                __intel_power_well_get(dev, power_well);
+
+       power_domains->domain_use_count[domain]++;
+
        mutex_unlock(&power_domains->lock);
 }
 
@@ -5773,14 +5788,16 @@ void intel_display_power_put(struct drm_device *dev,
        struct i915_power_well *power_well;
        int i;
 
-       if (!HAS_POWER_WELL(dev))
-               return;
-
        power_domains = &dev_priv->power_domains;
 
        mutex_lock(&power_domains->lock);
+
+       WARN_ON(!power_domains->domain_use_count[domain]);
+       power_domains->domain_use_count[domain]--;
+
        for_each_power_well_rev(i, power_well, BIT(domain), power_domains)
                __intel_power_well_put(dev, power_well);
+
        mutex_unlock(&power_domains->lock);
 }
 
@@ -5814,6 +5831,14 @@ void i915_release_power_well(void)
 }
 EXPORT_SYMBOL_GPL(i915_release_power_well);
 
+static struct i915_power_well i9xx_always_on_power_well[] = {
+       {
+               .name = "always-on",
+               .always_on = 1,
+               .domains = POWER_DOMAIN_MASK,
+       },
+};
+
 static struct i915_power_well hsw_power_wells[] = {
        {
                .name = "always-on",
@@ -5852,9 +5877,6 @@ int intel_power_domains_init(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct i915_power_domains *power_domains = &dev_priv->power_domains;
 
-       if (!HAS_POWER_WELL(dev))
-               return 0;
-
        mutex_init(&power_domains->lock);
 
        /*
@@ -5868,7 +5890,7 @@ int intel_power_domains_init(struct drm_device *dev)
                set_power_wells(power_domains, bdw_power_wells);
                hsw_pwr = power_domains;
        } else {
-               WARN_ON(1);
+               set_power_wells(power_domains, i9xx_always_on_power_well);
        }
 
        return 0;
@@ -5886,9 +5908,6 @@ static void intel_power_domains_resume(struct drm_device *dev)
        struct i915_power_well *power_well;
        int i;
 
-       if (!HAS_POWER_WELL(dev))
-               return;
-
        mutex_lock(&power_domains->lock);
        for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) {
                if (power_well->set)
@@ -5907,13 +5926,13 @@ void intel_power_domains_init_hw(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
 
-       if (!HAS_POWER_WELL(dev))
-               return;
-
        /* For now, we need the power well to be always enabled. */
        intel_display_set_init_power(dev, true);
        intel_power_domains_resume(dev);
 
+       if (!(IS_HASWELL(dev) || IS_BROADWELL(dev)))
+               return;
+
        /* We're taking over the BIOS, so clear any requests made by it since
         * the driver is in charge now. */
        if (I915_READ(HSW_PWR_WELL_BIOS) & HSW_PWR_WELL_ENABLE_REQUEST)
@@ -5937,25 +5956,23 @@ void intel_init_pm(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
 
        if (I915_HAS_FBC(dev)) {
-               if (HAS_PCH_SPLIT(dev)) {
+               if (INTEL_INFO(dev)->gen >= 7) {
                        dev_priv->display.fbc_enabled = ironlake_fbc_enabled;
-                       if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev))
-                               dev_priv->display.enable_fbc =
-                                       gen7_enable_fbc;
-                       else
-                               dev_priv->display.enable_fbc =
-                                       ironlake_enable_fbc;
+                       dev_priv->display.enable_fbc = gen7_enable_fbc;
+                       dev_priv->display.disable_fbc = ironlake_disable_fbc;
+               } else if (INTEL_INFO(dev)->gen >= 5) {
+                       dev_priv->display.fbc_enabled = ironlake_fbc_enabled;
+                       dev_priv->display.enable_fbc = ironlake_enable_fbc;
                        dev_priv->display.disable_fbc = ironlake_disable_fbc;
                } else if (IS_GM45(dev)) {
                        dev_priv->display.fbc_enabled = g4x_fbc_enabled;
                        dev_priv->display.enable_fbc = g4x_enable_fbc;
                        dev_priv->display.disable_fbc = g4x_disable_fbc;
-               } else if (IS_CRESTLINE(dev)) {
+               } else {
                        dev_priv->display.fbc_enabled = i8xx_fbc_enabled;
                        dev_priv->display.enable_fbc = i8xx_enable_fbc;
                        dev_priv->display.disable_fbc = i8xx_disable_fbc;
                }
-               /* 855GM needs testing */
        }
 
        /* For cxsr */