drm/i915: set IDICOS to medium uncore resources
[deliverable/linux.git] / drivers / gpu / drm / i915 / intel_pm.c
index 8e79ff67ec98931e6a7680d8b9e28375d8db1978..404b474eaea32237c2d45586e0bc39f8f17ae619 100644 (file)
@@ -405,7 +405,9 @@ void intel_update_fbc(struct drm_device *dev)
         *   - going to an unsupported config (interlace, pixel multiply, etc.)
         */
        list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) {
-               if (tmp_crtc->enabled && tmp_crtc->fb) {
+               if (tmp_crtc->enabled &&
+                   !to_intel_crtc(tmp_crtc)->primary_disabled &&
+                   tmp_crtc->fb) {
                        if (crtc) {
                                DRM_DEBUG_KMS("more than one pipe active, disabling compression\n");
                                dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES;
@@ -2270,10 +2272,33 @@ void ironlake_disable_drps(struct drm_device *dev)
 void gen6_set_rps(struct drm_device *dev, u8 val)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 swreq;
+       u32 limits;
 
-       swreq = (val & 0x3ff) << 25;
-       I915_WRITE(GEN6_RPNSWREQ, swreq);
+       limits = 0;
+       if (val >= dev_priv->max_delay)
+               val = dev_priv->max_delay;
+       else
+               limits |= dev_priv->max_delay << 24;
+
+       if (val <= dev_priv->min_delay)
+               val = dev_priv->min_delay;
+       else
+               limits |= dev_priv->min_delay << 16;
+
+       if (val == dev_priv->cur_delay)
+               return;
+
+       I915_WRITE(GEN6_RPNSWREQ,
+                  GEN6_FREQUENCY(val) |
+                  GEN6_OFFSET(0) |
+                  GEN6_AGGRESSIVE_TURBO);
+
+       /* Make sure we continue to get interrupts
+        * until we hit the minimum or maximum frequencies.
+        */
+       I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits);
+
+       dev_priv->cur_delay = val;
 }
 
 void gen6_disable_rps(struct drm_device *dev)
@@ -2327,11 +2352,10 @@ int intel_enable_rc6(const struct drm_device *dev)
 void gen6_enable_rps(struct drm_i915_private *dev_priv)
 {
        struct intel_ring_buffer *ring;
-       u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
-       u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
+       u32 rp_state_cap;
+       u32 gt_perf_status;
        u32 pcu_mbox, rc6_mask = 0;
        u32 gtfifodbg;
-       int cur_freq, min_freq, max_freq;
        int rc6_mode;
        int i;
 
@@ -2352,6 +2376,14 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
 
        gen6_gt_force_wake_get(dev_priv);
 
+       rp_state_cap = I915_READ(GEN6_RP_STATE_CAP);
+       gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
+
+       /* In units of 100MHz */
+       dev_priv->max_delay = rp_state_cap & 0xff;
+       dev_priv->min_delay = (rp_state_cap & 0xff0000) >> 16;
+       dev_priv->cur_delay = 0;
+
        /* disable the counters and set deterministic thresholds */
        I915_WRITE(GEN6_RC_CONTROL, 0);
 
@@ -2399,8 +2431,8 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
 
        I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000);
        I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
-                  18 << 24 |
-                  6 << 16);
+                  dev_priv->max_delay << 24 |
+                  dev_priv->min_delay << 16);
        I915_WRITE(GEN6_RP_UP_THRESHOLD, 10000);
        I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 1000000);
        I915_WRITE(GEN6_RP_UP_EI, 100000);
@@ -2408,7 +2440,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
        I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10);
        I915_WRITE(GEN6_RP_CONTROL,
                   GEN6_RP_MEDIA_TURBO |
-                  GEN6_RP_MEDIA_HW_MODE |
+                  GEN6_RP_MEDIA_HW_NORMAL_MODE |
                   GEN6_RP_MEDIA_IS_GFX |
                   GEN6_RP_ENABLE |
                   GEN6_RP_UP_BUSY_AVG |
@@ -2426,10 +2458,6 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
                     500))
                DRM_ERROR("timeout waiting for pcode mailbox to finish\n");
 
-       min_freq = (rp_state_cap & 0xff0000) >> 16;
-       max_freq = rp_state_cap & 0xff;
-       cur_freq = (gt_perf_status & 0xff00) >> 8;
-
        /* Check for overclock support */
        if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0,
                     500))
@@ -2440,14 +2468,11 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
                     500))
                DRM_ERROR("timeout waiting for pcode mailbox to finish\n");
        if (pcu_mbox & (1<<31)) { /* OC supported */
-               max_freq = pcu_mbox & 0xff;
+               dev_priv->max_delay = pcu_mbox & 0xff;
                DRM_DEBUG_DRIVER("overclocking supported, adjusting frequency max to %dMHz\n", pcu_mbox * 50);
        }
 
-       /* In units of 100MHz */
-       dev_priv->max_delay = max_freq;
-       dev_priv->min_delay = min_freq;
-       dev_priv->cur_delay = cur_freq;
+       gen6_set_rps(dev_priv->dev, (gt_perf_status & 0xff00) >> 8);
 
        /* requires MSI enabled */
        I915_WRITE(GEN6_PMIER,
@@ -3359,6 +3384,7 @@ static void ivybridge_init_clock_gating(struct drm_device *dev)
        struct drm_i915_private *dev_priv = dev->dev_private;
        int pipe;
        uint32_t dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE;
+       uint32_t snpcr;
 
        I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate);
 
@@ -3404,6 +3430,11 @@ static void ivybridge_init_clock_gating(struct drm_device *dev)
        /* WaDisable4x2SubspanOptimization */
        I915_WRITE(CACHE_MODE_1,
                   _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE));
+
+       snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
+       snpcr &= ~GEN6_MBC_SNPCR_MASK;
+       snpcr |= GEN6_MBC_SNPCR_MED;
+       I915_WRITE(GEN6_MBCUNIT_SNPCR, snpcr);
 }
 
 static void valleyview_init_clock_gating(struct drm_device *dev)
@@ -3580,8 +3611,9 @@ static void gen6_sanitize_pm(struct drm_device *dev)
                limits |= (dev_priv->min_delay & 0x3f) << 16;
 
        if (old != limits) {
-               DRM_ERROR("Power management discrepancy: GEN6_RP_INTERRUPT_LIMITS expected %08x, was %08x\n",
-                         limits, old);
+               /* Note that the known failure case is to read back 0. */
+               DRM_DEBUG_DRIVER("Power management discrepancy: GEN6_RP_INTERRUPT_LIMITS "
+                                "expected %08x, was %08x\n", limits, old);
                I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, limits);
        }
 
This page took 0.030272 seconds and 5 git commands to generate.