drm/i915: use drm_i915_private everywhere in the power domain api
[deliverable/linux.git] / drivers / gpu / drm / i915 / intel_pm.c
index fa256fb83a8b20e98ebe1e7a2ec3b17ee3549a69..87ab6544dc48f46fa9fb8e5cee142256b6375cda 100644 (file)
@@ -469,7 +469,7 @@ void intel_update_fbc(struct drm_device *dev)
                return;
        }
 
-       if (!i915_powersave) {
+       if (!i915.powersave) {
                if (set_no_fbc_reason(dev_priv, FBC_MODULE_PARAM))
                        DRM_DEBUG_KMS("fbc disabled per module param\n");
                return;
@@ -508,13 +508,13 @@ void intel_update_fbc(struct drm_device *dev)
        obj = intel_fb->obj;
        adjusted_mode = &intel_crtc->config.adjusted_mode;
 
-       if (i915_enable_fbc < 0 &&
+       if (i915.enable_fbc < 0 &&
            INTEL_INFO(dev)->gen <= 7 && !IS_HASWELL(dev)) {
                if (set_no_fbc_reason(dev_priv, FBC_CHIP_DEFAULT))
                        DRM_DEBUG_KMS("disabled per chip default\n");
                goto out_disable;
        }
-       if (!i915_enable_fbc) {
+       if (!i915.enable_fbc) {
                if (set_no_fbc_reason(dev_priv, FBC_MODULE_PARAM))
                        DRM_DEBUG_KMS("fbc disabled per module param\n");
                goto out_disable;
@@ -1889,7 +1889,7 @@ static unsigned int ilk_cursor_wm_max(const struct drm_device *dev,
 }
 
 /* Calculate the maximum FBC watermark */
-static unsigned int ilk_fbc_wm_max(struct drm_device *dev)
+static unsigned int ilk_fbc_wm_max(const struct drm_device *dev)
 {
        /* max that registers can hold */
        if (INTEL_INFO(dev)->gen >= 8)
@@ -1898,7 +1898,7 @@ static unsigned int ilk_fbc_wm_max(struct drm_device *dev)
                return 15;
 }
 
-static void ilk_compute_wm_maximums(struct drm_device *dev,
+static void ilk_compute_wm_maximums(const struct drm_device *dev,
                                    int level,
                                    const struct intel_wm_config *config,
                                    enum intel_ddb_partitioning ddb_partitioning,
@@ -1951,7 +1951,7 @@ static bool ilk_validate_wm_level(int level,
        return ret;
 }
 
-static void ilk_compute_wm_level(struct drm_i915_private *dev_priv,
+static void ilk_compute_wm_level(const struct drm_i915_private *dev_priv,
                                 int level,
                                 const struct ilk_pipe_wm_parameters *p,
                                 struct intel_wm_level *result)
@@ -2143,7 +2143,7 @@ static bool intel_compute_pipe_wm(struct drm_crtc *crtc,
                                  struct intel_pipe_wm *pipe_wm)
 {
        struct drm_device *dev = crtc->dev;
-       struct drm_i915_private *dev_priv = dev->dev_private;
+       const struct drm_i915_private *dev_priv = dev->dev_private;
        int level, max_level = ilk_wm_max_level(dev);
        /* LP0 watermark maximums depend on this pipe alone */
        struct intel_wm_config config = {
@@ -2741,7 +2741,7 @@ intel_alloc_context_page(struct drm_device *dev)
                return NULL;
        }
 
-       ret = i915_gem_obj_ggtt_pin(ctx, 4096, true, false);
+       ret = i915_gem_obj_ggtt_pin(ctx, 4096, 0);
        if (ret) {
                DRM_ERROR("failed to pin power context: %d\n", ret);
                goto err_unref;
@@ -3003,6 +3003,9 @@ static void gen6_set_rps_thresholds(struct drm_i915_private *dev_priv, u8 val)
        dev_priv->rps.last_adj = 0;
 }
 
+/* gen6_set_rps is called to update the frequency request, but should also be
+ * called when the range (min_delay and max_delay) is modified so that we can
+ * update the GEN6_RP_INTERRUPT_LIMITS register accordingly. */
 void gen6_set_rps(struct drm_device *dev, u8 val)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -3011,8 +3014,14 @@ void gen6_set_rps(struct drm_device *dev, u8 val)
        WARN_ON(val > dev_priv->rps.max_delay);
        WARN_ON(val < dev_priv->rps.min_delay);
 
-       if (val == dev_priv->rps.cur_delay)
+       if (val == dev_priv->rps.cur_delay) {
+               /* min/max delay may still have been modified so be sure to
+                * write the limits value */
+               I915_WRITE(GEN6_RP_INTERRUPT_LIMITS,
+                          gen6_rps_limits(dev_priv, val));
+
                return;
+       }
 
        gen6_set_rps_thresholds(dev_priv, val);
 
@@ -3038,6 +3047,58 @@ void gen6_set_rps(struct drm_device *dev, u8 val)
        trace_intel_gpu_freq_change(val * 50);
 }
 
+/* vlv_set_rps_idle: Set the frequency to Rpn if Gfx clocks are down
+ *
+ * * If Gfx is Idle, then
+ * 1. Mask Turbo interrupts
+ * 2. Bring up Gfx clock
+ * 3. Change the freq to Rpn and wait till P-Unit updates freq
+ * 4. Clear the Force GFX CLK ON bit so that Gfx can down
+ * 5. Unmask Turbo interrupts
+*/
+static void vlv_set_rps_idle(struct drm_i915_private *dev_priv)
+{
+       /*
+        * When we are idle.  Drop to min voltage state.
+        */
+
+       if (dev_priv->rps.cur_delay <= dev_priv->rps.min_delay)
+               return;
+
+       /* Mask turbo interrupt so that they will not come in between */
+       I915_WRITE(GEN6_PMINTRMSK, 0xffffffff);
+
+       /* Bring up the Gfx clock */
+       I915_WRITE(VLV_GTLC_SURVIVABILITY_REG,
+               I915_READ(VLV_GTLC_SURVIVABILITY_REG) |
+                               VLV_GFX_CLK_FORCE_ON_BIT);
+
+       if (wait_for(((VLV_GFX_CLK_STATUS_BIT &
+               I915_READ(VLV_GTLC_SURVIVABILITY_REG)) != 0), 5)) {
+                       DRM_ERROR("GFX_CLK_ON request timed out\n");
+               return;
+       }
+
+       dev_priv->rps.cur_delay = dev_priv->rps.min_delay;
+
+       vlv_punit_write(dev_priv, PUNIT_REG_GPU_FREQ_REQ,
+                                       dev_priv->rps.min_delay);
+
+       if (wait_for(((vlv_punit_read(dev_priv, PUNIT_REG_GPU_FREQ_STS))
+                               & GENFREQSTATUS) == 0, 5))
+               DRM_ERROR("timed out waiting for Punit\n");
+
+       /* Release the Gfx clock */
+       I915_WRITE(VLV_GTLC_SURVIVABILITY_REG,
+               I915_READ(VLV_GTLC_SURVIVABILITY_REG) &
+                               ~VLV_GFX_CLK_FORCE_ON_BIT);
+
+       /* Unmask Up interrupts */
+       dev_priv->rps.rp_up_masked = true;
+       gen6_set_pm_mask(dev_priv, GEN6_PM_RP_DOWN_THRESHOLD,
+                                               dev_priv->rps.min_delay);
+}
+
 void gen6_rps_idle(struct drm_i915_private *dev_priv)
 {
        struct drm_device *dev = dev_priv->dev;
@@ -3045,7 +3106,7 @@ void gen6_rps_idle(struct drm_i915_private *dev_priv)
        mutex_lock(&dev_priv->rps.hw_lock);
        if (dev_priv->rps.enabled) {
                if (IS_VALLEYVIEW(dev))
-                       valleyview_set_rps(dev_priv->dev, dev_priv->rps.min_delay);
+                       vlv_set_rps_idle(dev_priv);
                else
                        gen6_set_rps(dev_priv->dev, dev_priv->rps.min_delay);
                dev_priv->rps.last_adj = 0;
@@ -3135,16 +3196,10 @@ static void valleyview_disable_rps(struct drm_device *dev)
 
 static void intel_print_rc6_info(struct drm_device *dev, u32 mode)
 {
-       if (IS_GEN6(dev))
-               DRM_DEBUG_DRIVER("Sandybridge: deep RC6 disabled\n");
-
-       if (IS_HASWELL(dev))
-               DRM_DEBUG_DRIVER("Haswell: only RC6 available\n");
-
        DRM_INFO("Enabling RC6 states: RC6 %s, RC6p %s, RC6pp %s\n",
-                       (mode & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off",
-                       (mode & GEN6_RC_CTL_RC6p_ENABLE) ? "on" : "off",
-                       (mode & GEN6_RC_CTL_RC6pp_ENABLE) ? "on" : "off");
+                (mode & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off",
+                (mode & GEN6_RC_CTL_RC6p_ENABLE) ? "on" : "off",
+                (mode & GEN6_RC_CTL_RC6pp_ENABLE) ? "on" : "off");
 }
 
 int intel_enable_rc6(const struct drm_device *dev)
@@ -3154,21 +3209,17 @@ int intel_enable_rc6(const struct drm_device *dev)
                return 0;
 
        /* Respect the kernel parameter if it is set */
-       if (i915_enable_rc6 >= 0)
-               return i915_enable_rc6;
+       if (i915.enable_rc6 >= 0)
+               return i915.enable_rc6;
 
        /* Disable RC6 on Ironlake */
        if (INTEL_INFO(dev)->gen == 5)
                return 0;
 
-       if (IS_HASWELL(dev))
-               return INTEL_RC6_ENABLE;
-
-       /* snb/ivb have more than one rc6 state. */
-       if (INTEL_INFO(dev)->gen == 6)
-               return INTEL_RC6_ENABLE;
+       if (IS_IVYBRIDGE(dev))
+               return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE);
 
-       return (INTEL_RC6_ENABLE | INTEL_RC6p_ENABLE);
+       return INTEL_RC6_ENABLE;
 }
 
 static void gen6_enable_rps_interrupts(struct drm_device *dev)
@@ -3225,10 +3276,10 @@ static void gen8_enable_rps(struct drm_device *dev)
        /* 3: Enable RC6 */
        if (intel_enable_rc6(dev) & INTEL_RC6_ENABLE)
                rc6_mask = GEN6_RC_CTL_RC6_ENABLE;
-       DRM_INFO("RC6 %s\n", (rc6_mask & GEN6_RC_CTL_RC6_ENABLE) ? "on" : "off");
+       intel_print_rc6_info(dev, rc6_mask);
        I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_HW_ENABLE |
-                       GEN6_RC_CTL_EI_MODE(1) |
-                       rc6_mask);
+                                   GEN6_RC_CTL_EI_MODE(1) |
+                                   rc6_mask);
 
        /* 4 Program defaults and thresholds for RPS*/
        I915_WRITE(GEN6_RPNSWREQ, HSW_FREQUENCY(10)); /* Request 500 MHz */
@@ -3270,7 +3321,7 @@ static void gen6_enable_rps(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_ring_buffer *ring;
-       u32 rp_state_cap;
+       u32 rp_state_cap, hw_max, hw_min;
        u32 gt_perf_status;
        u32 rc6vids, pcu_mbox, rc6_mask = 0;
        u32 gtfifodbg;
@@ -3299,13 +3350,20 @@ static void gen6_enable_rps(struct drm_device *dev)
        gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS);
 
        /* In units of 50MHz */
-       dev_priv->rps.hw_max = dev_priv->rps.max_delay = rp_state_cap & 0xff;
-       dev_priv->rps.min_delay = (rp_state_cap >> 16) & 0xff;
+       dev_priv->rps.hw_max = hw_max = rp_state_cap & 0xff;
+       hw_min = (rp_state_cap >> 16) & 0xff;
        dev_priv->rps.rp1_delay = (rp_state_cap >>  8) & 0xff;
        dev_priv->rps.rp0_delay = (rp_state_cap >>  0) & 0xff;
        dev_priv->rps.rpe_delay = dev_priv->rps.rp1_delay;
        dev_priv->rps.cur_delay = 0;
 
+       /* Preserve min/max settings in case of re-init */
+       if (dev_priv->rps.max_delay == 0)
+               dev_priv->rps.max_delay = hw_max;
+
+       if (dev_priv->rps.min_delay == 0)
+               dev_priv->rps.min_delay = hw_min;
+
        /* disable the counters and set deterministic thresholds */
        I915_WRITE(GEN6_RC_CONTROL, 0);
 
@@ -3534,7 +3592,7 @@ static void valleyview_enable_rps(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_ring_buffer *ring;
-       u32 gtfifodbg, val, rc6_mode = 0;
+       u32 gtfifodbg, val, hw_max, hw_min, rc6_mode = 0;
        int i;
 
        WARN_ON(!mutex_is_locked(&dev_priv->rps.hw_lock));
@@ -3596,21 +3654,27 @@ static void valleyview_enable_rps(struct drm_device *dev)
                         vlv_gpu_freq(dev_priv, dev_priv->rps.cur_delay),
                         dev_priv->rps.cur_delay);
 
-       dev_priv->rps.max_delay = valleyview_rps_max_freq(dev_priv);
-       dev_priv->rps.hw_max = dev_priv->rps.max_delay;
+       dev_priv->rps.hw_max = hw_max = valleyview_rps_max_freq(dev_priv);
        DRM_DEBUG_DRIVER("max GPU freq: %d MHz (%u)\n",
-                        vlv_gpu_freq(dev_priv, dev_priv->rps.max_delay),
-                        dev_priv->rps.max_delay);
+                        vlv_gpu_freq(dev_priv, hw_max),
+                        hw_max);
 
        dev_priv->rps.rpe_delay = valleyview_rps_rpe_freq(dev_priv);
        DRM_DEBUG_DRIVER("RPe GPU freq: %d MHz (%u)\n",
                         vlv_gpu_freq(dev_priv, dev_priv->rps.rpe_delay),
                         dev_priv->rps.rpe_delay);
 
-       dev_priv->rps.min_delay = valleyview_rps_min_freq(dev_priv);
+       hw_min = valleyview_rps_min_freq(dev_priv);
        DRM_DEBUG_DRIVER("min GPU freq: %d MHz (%u)\n",
-                        vlv_gpu_freq(dev_priv, dev_priv->rps.min_delay),
-                        dev_priv->rps.min_delay);
+                        vlv_gpu_freq(dev_priv, hw_min),
+                        hw_min);
+
+       /* Preserve min/max settings in case of re-init */
+       if (dev_priv->rps.max_delay == 0)
+               dev_priv->rps.max_delay = hw_max;
+
+       if (dev_priv->rps.min_delay == 0)
+               dev_priv->rps.min_delay = hw_min;
 
        DRM_DEBUG_DRIVER("setting GPU freq to %d MHz (%u)\n",
                         vlv_gpu_freq(dev_priv, dev_priv->rps.rpe_delay),
@@ -3618,6 +3682,9 @@ static void valleyview_enable_rps(struct drm_device *dev)
 
        valleyview_set_rps(dev_priv->dev, dev_priv->rps.rpe_delay);
 
+       dev_priv->rps.rp_up_masked = false;
+       dev_priv->rps.rp_down_masked = false;
+
        gen6_enable_rps_interrupts(dev);
 
        gen6_gt_force_wake_put(dev_priv, FORCEWAKE_ALL);
@@ -3826,9 +3893,10 @@ static unsigned long __i915_chipset_val(struct drm_i915_private *dev_priv)
 
 unsigned long i915_chipset_val(struct drm_i915_private *dev_priv)
 {
+       struct drm_device *dev = dev_priv->dev;
        unsigned long val;
 
-       if (dev_priv->info->gen != 5)
+       if (INTEL_INFO(dev)->gen != 5)
                return 0;
 
        spin_lock_irq(&mchdev_lock);
@@ -3857,6 +3925,7 @@ unsigned long i915_mch_val(struct drm_i915_private *dev_priv)
 
 static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid)
 {
+       struct drm_device *dev = dev_priv->dev;
        static const struct v_table {
                u16 vd; /* in .1 mil */
                u16 vm; /* in .1 mil */
@@ -3990,7 +4059,7 @@ static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid)
                { 16000, 14875, },
                { 16125, 15000, },
        };
-       if (dev_priv->info->is_mobile)
+       if (INTEL_INFO(dev)->is_mobile)
                return v_table[pxvid].vm;
        else
                return v_table[pxvid].vd;
@@ -4033,7 +4102,9 @@ static void __i915_update_gfx_val(struct drm_i915_private *dev_priv)
 
 void i915_update_gfx_val(struct drm_i915_private *dev_priv)
 {
-       if (dev_priv->info->gen != 5)
+       struct drm_device *dev = dev_priv->dev;
+
+       if (INTEL_INFO(dev)->gen != 5)
                return;
 
        spin_lock_irq(&mchdev_lock);
@@ -4082,9 +4153,10 @@ static unsigned long __i915_gfx_val(struct drm_i915_private *dev_priv)
 
 unsigned long i915_gfx_val(struct drm_i915_private *dev_priv)
 {
+       struct drm_device *dev = dev_priv->dev;
        unsigned long val;
 
-       if (dev_priv->info->gen != 5)
+       if (INTEL_INFO(dev)->gen != 5)
                return 0;
 
        spin_lock_irq(&mchdev_lock);
@@ -4273,6 +4345,7 @@ void intel_gpu_ips_teardown(void)
        i915_mch_dev = NULL;
        spin_unlock_irq(&mchdev_lock);
 }
+
 static void intel_init_emon(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -4588,6 +4661,17 @@ static void gen6_init_clock_gating(struct drm_device *dev)
                I915_WRITE(GEN6_GT_MODE,
                           _MASKED_BIT_ENABLE(GEN6_TD_FOUR_ROW_DISPATCH_DISABLE));
 
+       /*
+        * BSpec recoomends 8x4 when MSAA is used,
+        * however in practice 16x4 seems fastest.
+        *
+        * Note that PS/WM thread counts depend on the WIZ hashing
+        * disable bit, which we don't touch here, but it's good
+        * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
+        */
+       I915_WRITE(GEN6_GT_MODE,
+                  GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4);
+
        ilk_init_lp_watermarks(dev);
 
        I915_WRITE(CACHE_MODE_0,
@@ -4608,17 +4692,24 @@ static void gen6_init_clock_gating(struct drm_device *dev)
         * According to the spec, bit 11 (RCCUNIT) must also be set,
         * but we didn't debug actual testcases to find it out.
         *
-        * Also apply WaDisableVDSUnitClockGating:snb and
-        * WaDisableRCPBUnitClockGating:snb.
+        * WaDisableRCCUnitClockGating:snb
+        * WaDisableRCPBUnitClockGating:snb
         */
        I915_WRITE(GEN6_UCGCTL2,
-                  GEN7_VDSUNIT_CLOCK_GATE_DISABLE |
                   GEN6_RCPBUNIT_CLOCK_GATE_DISABLE |
                   GEN6_RCCUNIT_CLOCK_GATE_DISABLE);
 
-       /* Bspec says we need to always set all mask bits. */
-       I915_WRITE(_3D_CHICKEN3, (0xFFFF << 16) |
-                  _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL);
+       /* WaStripsFansDisableFastClipPerformanceFix:snb */
+       I915_WRITE(_3D_CHICKEN3,
+                  _MASKED_BIT_ENABLE(_3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL));
+
+       /*
+        * Bspec says:
+        * "This bit must be set if 3DSTATE_CLIP clip mode is set to normal and
+        * 3DSTATE_SF number of SF output attributes is more than 16."
+        */
+       I915_WRITE(_3D_CHICKEN3,
+                  _MASKED_BIT_ENABLE(_3D_CHICKEN3_SF_DISABLE_PIPELINED_ATTR_FETCH));
 
        /*
         * According to the spec the following bits should be
@@ -4644,11 +4735,6 @@ static void gen6_init_clock_gating(struct drm_device *dev)
 
        g4x_disable_trickle_feed(dev);
 
-       /* The default value should be 0x200 according to docs, but the two
-        * platforms I checked have a 0 for this. (Maybe BIOS overrides?) */
-       I915_WRITE(GEN6_GT_MODE, _MASKED_BIT_DISABLE(0xffff));
-       I915_WRITE(GEN6_GT_MODE, _MASKED_BIT_ENABLE(GEN6_GT_MODE_HI));
-
        cpt_init_clock_gating(dev);
 
        gen6_check_mch_setup(dev);
@@ -4658,14 +4744,17 @@ static void gen7_setup_fixed_func_scheduler(struct drm_i915_private *dev_priv)
 {
        uint32_t reg = I915_READ(GEN7_FF_THREAD_MODE);
 
+       /*
+        * WaVSThreadDispatchOverride:ivb,vlv
+        *
+        * This actually overrides the dispatch
+        * mode for all thread types.
+        */
        reg &= ~GEN7_FF_SCHED_MASK;
        reg |= GEN7_FF_TS_SCHED_HW;
        reg |= GEN7_FF_VS_SCHED_HW;
        reg |= GEN7_FF_DS_SCHED_HW;
 
-       if (IS_HASWELL(dev_priv->dev))
-               reg &= ~GEN7_FF_VS_REF_CNT_FFME;
-
        I915_WRITE(GEN7_FF_THREAD_MODE, reg);
 }
 
@@ -4758,6 +4847,17 @@ static void gen8_init_clock_gating(struct drm_device *dev)
        I915_WRITE(GEN7_FF_THREAD_MODE,
                   I915_READ(GEN7_FF_THREAD_MODE) &
                   ~(GEN8_FF_DS_REF_CNT_FFME | GEN7_FF_VS_REF_CNT_FFME));
+
+       /*
+        * BSpec recommends 8x4 when MSAA is used,
+        * however in practice 16x4 seems fastest.
+        *
+        * Note that PS/WM thread counts depend on the WIZ hashing
+        * disable bit, which we don't touch here, but it's good
+        * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
+        */
+       I915_WRITE(GEN7_GT_MODE,
+                  GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4);
 }
 
 static void haswell_init_clock_gating(struct drm_device *dev)
@@ -4766,21 +4866,6 @@ static void haswell_init_clock_gating(struct drm_device *dev)
 
        ilk_init_lp_watermarks(dev);
 
-       /* According to the spec, bit 13 (RCZUNIT) must be set on IVB.
-        * This implements the WaDisableRCZUnitClockGating:hsw workaround.
-        */
-       I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
-
-       /* Apply the WaDisableRHWOOptimizationForRenderHang:hsw workaround. */
-       I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1,
-                  GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
-
-       /* WaApplyL3ControlAndL3ChickenMode:hsw */
-       I915_WRITE(GEN7_L3CNTLREG1,
-                       GEN7_WA_FOR_GEN7_L3_CONTROL);
-       I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER,
-                       GEN7_WA_L3_CHICKEN_MODE);
-
        /* L3 caching of data atomics doesn't work -- disable it. */
        I915_WRITE(HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE);
        I915_WRITE(HSW_ROW_CHICKEN3,
@@ -4792,12 +4877,28 @@ static void haswell_init_clock_gating(struct drm_device *dev)
                        GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
 
        /* WaVSRefCountFullforceMissDisable:hsw */
-       gen7_setup_fixed_func_scheduler(dev_priv);
+       I915_WRITE(GEN7_FF_THREAD_MODE,
+                  I915_READ(GEN7_FF_THREAD_MODE) & ~GEN7_FF_VS_REF_CNT_FFME);
+
+       /* enable HiZ Raw Stall Optimization */
+       I915_WRITE(CACHE_MODE_0_GEN7,
+                  _MASKED_BIT_DISABLE(HIZ_RAW_STALL_OPT_DISABLE));
 
        /* WaDisable4x2SubspanOptimization:hsw */
        I915_WRITE(CACHE_MODE_1,
                   _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE));
 
+       /*
+        * BSpec recommends 8x4 when MSAA is used,
+        * however in practice 16x4 seems fastest.
+        *
+        * Note that PS/WM thread counts depend on the WIZ hashing
+        * disable bit, which we don't touch here, but it's good
+        * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
+        */
+       I915_WRITE(GEN7_GT_MODE,
+                  GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4);
+
        /* WaSwitchSolVfFArbitrationPriority:hsw */
        I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) | HSW_ECOCHK_ARB_PRIO_SOL);
 
@@ -4830,9 +4931,6 @@ static void ivybridge_init_clock_gating(struct drm_device *dev)
        if (IS_IVB_GT1(dev))
                I915_WRITE(GEN7_HALF_SLICE_CHICKEN1,
                           _MASKED_BIT_ENABLE(GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE));
-       else
-               I915_WRITE(GEN7_HALF_SLICE_CHICKEN1_GT2,
-                          _MASKED_BIT_ENABLE(GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE));
 
        /* Apply the WaDisableRHWOOptimizationForRenderHang:ivb workaround. */
        I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1,
@@ -4846,31 +4944,24 @@ static void ivybridge_init_clock_gating(struct drm_device *dev)
        if (IS_IVB_GT1(dev))
                I915_WRITE(GEN7_ROW_CHICKEN2,
                           _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
-       else
+       else {
+               /* must write both registers */
+               I915_WRITE(GEN7_ROW_CHICKEN2,
+                          _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
                I915_WRITE(GEN7_ROW_CHICKEN2_GT2,
                           _MASKED_BIT_ENABLE(DOP_CLOCK_GATING_DISABLE));
-
+       }
 
        /* WaForceL3Serialization:ivb */
        I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) &
                   ~L3SQ_URB_READ_CAM_MATCH_DISABLE);
 
-       /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock
-        * gating disable must be set.  Failure to set it results in
-        * flickering pixels due to Z write ordering failures after
-        * some amount of runtime in the Mesa "fire" demo, and Unigine
-        * Sanctuary and Tropics, and apparently anything else with
-        * alpha test or pixel discard.
-        *
-        * According to the spec, bit 11 (RCCUNIT) must also be set,
-        * but we didn't debug actual testcases to find it out.
-        *
+       /*
         * According to the spec, bit 13 (RCZUNIT) must be set on IVB.
         * This implements the WaDisableRCZUnitClockGating:ivb workaround.
         */
        I915_WRITE(GEN6_UCGCTL2,
-                  GEN6_RCZUNIT_CLOCK_GATE_DISABLE |
-                  GEN6_RCCUNIT_CLOCK_GATE_DISABLE);
+                  GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
 
        /* This is required by WaCatErrorRejectionIssue:ivb */
        I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
@@ -4879,13 +4970,29 @@ static void ivybridge_init_clock_gating(struct drm_device *dev)
 
        g4x_disable_trickle_feed(dev);
 
-       /* WaVSRefCountFullforceMissDisable:ivb */
        gen7_setup_fixed_func_scheduler(dev_priv);
 
+       if (0) { /* causes HiZ corruption on ivb:gt1 */
+               /* enable HiZ Raw Stall Optimization */
+               I915_WRITE(CACHE_MODE_0_GEN7,
+                          _MASKED_BIT_DISABLE(HIZ_RAW_STALL_OPT_DISABLE));
+       }
+
        /* WaDisable4x2SubspanOptimization:ivb */
        I915_WRITE(CACHE_MODE_1,
                   _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE));
 
+       /*
+        * BSpec recommends 8x4 when MSAA is used,
+        * however in practice 16x4 seems fastest.
+        *
+        * Note that PS/WM thread counts depend on the WIZ hashing
+        * disable bit, which we don't touch here, but it's good
+        * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
+        */
+       I915_WRITE(GEN7_GT_MODE,
+                  GEN6_WIZ_HASHING_MASK | GEN6_WIZ_HASHING_16x4);
+
        snpcr = I915_READ(GEN6_MBCUNIT_SNPCR);
        snpcr &= ~GEN6_MBC_SNPCR_MASK;
        snpcr |= GEN6_MBC_SNPCR_MED;
@@ -4938,15 +5045,6 @@ static void valleyview_init_clock_gating(struct drm_device *dev)
                   _MASKED_BIT_ENABLE(GEN7_MAX_PS_THREAD_DEP |
                                      GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE));
 
-       /* Apply the WaDisableRHWOOptimizationForRenderHang:vlv workaround. */
-       I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1,
-                  GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
-
-       /* WaDisableL3CacheAging:vlv */
-       I915_WRITE(GEN7_L3CNTLREG1, I915_READ(GEN7_L3CNTLREG1) | GEN7_L3AGDIS);
-       /* WaApplyL3ControlAndL3ChickenMode:vlv */
-       I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, GEN7_WA_L3_CHICKEN_MODE);
-
        /* WaForceL3Serialization:vlv */
        I915_WRITE(GEN7_L3SQCREG4, I915_READ(GEN7_L3SQCREG4) &
                   ~L3SQ_URB_READ_CAM_MATCH_DISABLE);
@@ -4960,52 +5058,39 @@ static void valleyview_init_clock_gating(struct drm_device *dev)
                   I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
                   GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
 
-       /* According to the BSpec vol1g, bit 12 (RCPBUNIT) clock
-        * gating disable must be set.  Failure to set it results in
-        * flickering pixels due to Z write ordering failures after
-        * some amount of runtime in the Mesa "fire" demo, and Unigine
-        * Sanctuary and Tropics, and apparently anything else with
-        * alpha test or pixel discard.
-        *
-        * According to the spec, bit 11 (RCCUNIT) must also be set,
-        * but we didn't debug actual testcases to find it out.
-        *
+       gen7_setup_fixed_func_scheduler(dev_priv);
+
+       /*
         * According to the spec, bit 13 (RCZUNIT) must be set on IVB.
         * This implements the WaDisableRCZUnitClockGating:vlv workaround.
-        *
-        * Also apply WaDisableVDSUnitClockGating:vlv and
-        * WaDisableRCPBUnitClockGating:vlv.
         */
        I915_WRITE(GEN6_UCGCTL2,
-                  GEN7_VDSUNIT_CLOCK_GATE_DISABLE |
-                  GEN7_TDLUNIT_CLOCK_GATE_DISABLE |
-                  GEN6_RCZUNIT_CLOCK_GATE_DISABLE |
-                  GEN6_RCPBUNIT_CLOCK_GATE_DISABLE |
-                  GEN6_RCCUNIT_CLOCK_GATE_DISABLE);
+                  GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
 
        /* WaDisableL3Bank2xClockGate:vlv */
        I915_WRITE(GEN7_UCGCTL4, GEN7_L3BANK2X_CLOCK_GATE_DISABLE);
 
        I915_WRITE(MI_ARB_VLV, MI_ARB_DISPLAY_TRICKLE_FEED_DISABLE);
 
+       /*
+        * BSpec says this must be set, even though
+        * WaDisable4x2SubspanOptimization isn't listed for VLV.
+        */
        I915_WRITE(CACHE_MODE_1,
                   _MASKED_BIT_ENABLE(PIXEL_SUBSPAN_COLLECT_OPT_DISABLE));
 
+       /*
+        * WaIncreaseL3CreditsForVLVB0:vlv
+        * This is the hardware default actually.
+        */
+       I915_WRITE(GEN7_L3SQCREG1, VLV_B0_WA_L3SQCREG1_VALUE);
+
        /*
         * WaDisableVLVClockGating_VBIIssue:vlv
         * Disable clock gating on th GCFG unit to prevent a delay
         * in the reporting of vblank events.
         */
-       I915_WRITE(VLV_GUNIT_CLOCK_GATE, 0xffffffff);
-
-       /* Conservative clock gating settings for now */
-       I915_WRITE(0x9400, 0xffffffff);
-       I915_WRITE(0x9404, 0xffffffff);
-       I915_WRITE(0x9408, 0xffffffff);
-       I915_WRITE(0x940c, 0xffffffff);
-       I915_WRITE(0x9410, 0xffffffff);
-       I915_WRITE(0x9414, 0xffffffff);
-       I915_WRITE(0x9418, 0xffffffff);
+       I915_WRITE(VLV_GUNIT_CLOCK_GATE, GCFG_DIS);
 }
 
 static void g4x_init_clock_gating(struct drm_device *dev)
@@ -5120,19 +5205,16 @@ void intel_suspend_hw(struct drm_device *dev)
  * enable it, so check if it's enabled and also check if we've requested it to
  * be enabled.
  */
-static bool hsw_power_well_enabled(struct drm_device *dev,
+static bool hsw_power_well_enabled(struct drm_i915_private *dev_priv,
                                   struct i915_power_well *power_well)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-
        return I915_READ(HSW_PWR_WELL_DRIVER) ==
                     (HSW_PWR_WELL_ENABLE_REQUEST | HSW_PWR_WELL_STATE_ENABLED);
 }
 
-bool intel_display_power_enabled_sw(struct drm_device *dev,
+bool intel_display_power_enabled_sw(struct drm_i915_private *dev_priv,
                                    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;
@@ -5140,10 +5222,9 @@ bool intel_display_power_enabled_sw(struct drm_device *dev,
        return power_domains->domain_use_count[domain];
 }
 
-bool intel_display_power_enabled(struct drm_device *dev,
+bool intel_display_power_enabled(struct drm_i915_private *dev_priv,
                                 enum intel_display_power_domain domain)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
        struct i915_power_domains *power_domains;
        struct i915_power_well *power_well;
        bool is_enabled;
@@ -5158,7 +5239,7 @@ bool intel_display_power_enabled(struct drm_device *dev,
                if (power_well->always_on)
                        continue;
 
-               if (!power_well->is_enabled(dev, power_well)) {
+               if (!power_well->is_enabled(dev_priv, power_well)) {
                        is_enabled = false;
                        break;
                }
@@ -5224,10 +5305,9 @@ static void hsw_power_well_post_disable(struct drm_i915_private *dev_priv)
        spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
 }
 
-static void hsw_set_power_well(struct drm_device *dev,
+static void hsw_set_power_well(struct drm_i915_private *dev_priv,
                               struct i915_power_well *power_well, bool enable)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
        bool is_enabled, enable_requested;
        uint32_t tmp;
 
@@ -5261,35 +5341,30 @@ static void hsw_set_power_well(struct drm_device *dev,
        }
 }
 
-static void __intel_power_well_get(struct drm_device *dev,
+static void __intel_power_well_get(struct drm_i915_private *dev_priv,
                                   struct i915_power_well *power_well)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-
        if (!power_well->count++ && power_well->set) {
                hsw_disable_package_c8(dev_priv);
-               power_well->set(dev, power_well, true);
+               power_well->set(dev_priv, power_well, true);
        }
 }
 
-static void __intel_power_well_put(struct drm_device *dev,
+static void __intel_power_well_put(struct drm_i915_private *dev_priv,
                                   struct i915_power_well *power_well)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-
        WARN_ON(!power_well->count);
 
        if (!--power_well->count && power_well->set &&
-           i915_disable_power_well) {
-               power_well->set(dev, power_well, false);
+           i915.disable_power_well) {
+               power_well->set(dev_priv, power_well, false);
                hsw_enable_package_c8(dev_priv);
        }
 }
 
-void intel_display_power_get(struct drm_device *dev,
+void intel_display_power_get(struct drm_i915_private *dev_priv,
                             enum intel_display_power_domain domain)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
        struct i915_power_domains *power_domains;
        struct i915_power_well *power_well;
        int i;
@@ -5299,17 +5374,16 @@ void intel_display_power_get(struct drm_device *dev,
        mutex_lock(&power_domains->lock);
 
        for_each_power_well(i, power_well, BIT(domain), power_domains)
-               __intel_power_well_get(dev, power_well);
+               __intel_power_well_get(dev_priv, power_well);
 
        power_domains->domain_use_count[domain]++;
 
        mutex_unlock(&power_domains->lock);
 }
 
-void intel_display_power_put(struct drm_device *dev,
+void intel_display_power_put(struct drm_i915_private *dev_priv,
                             enum intel_display_power_domain domain)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
        struct i915_power_domains *power_domains;
        struct i915_power_well *power_well;
        int i;
@@ -5322,7 +5396,7 @@ void intel_display_power_put(struct drm_device *dev,
        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);
+               __intel_power_well_put(dev_priv, power_well);
 
        mutex_unlock(&power_domains->lock);
 }
@@ -5339,7 +5413,7 @@ void i915_request_power_well(void)
 
        dev_priv = container_of(hsw_pwr, struct drm_i915_private,
                                power_domains);
-       intel_display_power_get(dev_priv->dev, POWER_DOMAIN_AUDIO);
+       intel_display_power_get(dev_priv, POWER_DOMAIN_AUDIO);
 }
 EXPORT_SYMBOL_GPL(i915_request_power_well);
 
@@ -5353,7 +5427,7 @@ void i915_release_power_well(void)
 
        dev_priv = container_of(hsw_pwr, struct drm_i915_private,
                                power_domains);
-       intel_display_power_put(dev_priv->dev, POWER_DOMAIN_AUDIO);
+       intel_display_power_put(dev_priv, POWER_DOMAIN_AUDIO);
 }
 EXPORT_SYMBOL_GPL(i915_release_power_well);
 
@@ -5398,9 +5472,8 @@ static struct i915_power_well bdw_power_wells[] = {
        (power_domains)->power_well_count = ARRAY_SIZE(__power_wells);  \
 })
 
-int intel_power_domains_init(struct drm_device *dev)
+int intel_power_domains_init(struct drm_i915_private *dev_priv)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
        struct i915_power_domains *power_domains = &dev_priv->power_domains;
 
        mutex_init(&power_domains->lock);
@@ -5409,10 +5482,10 @@ int intel_power_domains_init(struct drm_device *dev)
         * The enabling order will be from lower to higher indexed wells,
         * the disabling order is reversed.
         */
-       if (IS_HASWELL(dev)) {
+       if (IS_HASWELL(dev_priv->dev)) {
                set_power_wells(power_domains, hsw_power_wells);
                hsw_pwr = power_domains;
-       } else if (IS_BROADWELL(dev)) {
+       } else if (IS_BROADWELL(dev_priv->dev)) {
                set_power_wells(power_domains, bdw_power_wells);
                hsw_pwr = power_domains;
        } else {
@@ -5422,14 +5495,13 @@ int intel_power_domains_init(struct drm_device *dev)
        return 0;
 }
 
-void intel_power_domains_remove(struct drm_device *dev)
+void intel_power_domains_remove(struct drm_i915_private *dev_priv)
 {
        hsw_pwr = NULL;
 }
 
-static void intel_power_domains_resume(struct drm_device *dev)
+static void intel_power_domains_resume(struct drm_i915_private *dev_priv)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
        struct i915_power_domains *power_domains = &dev_priv->power_domains;
        struct i915_power_well *power_well;
        int i;
@@ -5437,7 +5509,7 @@ static void intel_power_domains_resume(struct drm_device *dev)
        mutex_lock(&power_domains->lock);
        for_each_power_well(i, power_well, POWER_DOMAIN_MASK, power_domains) {
                if (power_well->set)
-                       power_well->set(dev, power_well, power_well->count > 0);
+                       power_well->set(dev_priv, power_well, power_well->count > 0);
        }
        mutex_unlock(&power_domains->lock);
 }
@@ -5448,15 +5520,13 @@ static void intel_power_domains_resume(struct drm_device *dev)
  * to be enabled, and it will only be disabled if none of the registers is
  * requesting it to be enabled.
  */
-void intel_power_domains_init_hw(struct drm_device *dev)
+void intel_power_domains_init_hw(struct drm_i915_private *dev_priv)
 {
-       struct drm_i915_private *dev_priv = dev->dev_private;
-
        /* For now, we need the power well to be always enabled. */
-       intel_display_set_init_power(dev, true);
-       intel_power_domains_resume(dev);
+       intel_display_set_init_power(dev_priv, true);
+       intel_power_domains_resume(dev_priv);
 
-       if (!(IS_HASWELL(dev) || IS_BROADWELL(dev)))
+       if (!(IS_HASWELL(dev_priv->dev) || IS_BROADWELL(dev_priv->dev)))
                return;
 
        /* We're taking over the BIOS, so clear any requests made by it since
This page took 0.03834 seconds and 5 git commands to generate.