drm/i915/chv: PPAT setup for Cherryview
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Wed, 9 Apr 2014 10:28:01 +0000 (13:28 +0300)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 6 May 2014 16:29:34 +0000 (18:29 +0200)
Ignore the cache bits in PPAT and just set the snoop bit where
appropriate. BDW WB is mapped to snooped access, while all other
modes are mapped to non-snooped access.

The hardware supposedly ignores everything except the snoop bit
in the PPAT entries.

Additionally the hardware actually enforces snooping for all
page table accesses, and thus the snoop bit is ignored for PDEs.

v2: Rebased on top of the bdw resume fix to reload the ppat entries.

v3: Rebase on top of the i915_gem_gtt.h header extraction.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> (v1)
Acked-by: Ben Widawsky <ben@bwidawsk.net>
Reviewed-by: Rafael Barbalho <rafael.barbalho@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_gem_gtt.c
drivers/gpu/drm/i915/i915_gem_gtt.h

index 496916298e8a59ef89323e53a97a1beae44d909b..836c8b6391c2cea799e85ac45de157ff771915d4 100644 (file)
@@ -30,7 +30,8 @@
 #include "i915_trace.h"
 #include "intel_drv.h"
 
-static void gen8_setup_private_ppat(struct drm_i915_private *dev_priv);
+static void bdw_setup_private_ppat(struct drm_i915_private *dev_priv);
+static void chv_setup_private_ppat(struct drm_i915_private *dev_priv);
 
 bool intel_enable_ppgtt(struct drm_device *dev, bool full)
 {
@@ -1325,7 +1326,11 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
 
 
        if (INTEL_INFO(dev)->gen >= 8) {
-               gen8_setup_private_ppat(dev_priv);
+               if (IS_CHERRYVIEW(dev))
+                       chv_setup_private_ppat(dev_priv);
+               else
+                       bdw_setup_private_ppat(dev_priv);
+
                return;
        }
 
@@ -1797,7 +1802,7 @@ static int ggtt_probe_common(struct drm_device *dev,
 /* The GGTT and PPGTT need a private PPAT setup in order to handle cacheability
  * bits. When using advanced contexts each context stores its own PAT, but
  * writing this data shouldn't be harmful even in those cases. */
-static void gen8_setup_private_ppat(struct drm_i915_private *dev_priv)
+static void bdw_setup_private_ppat(struct drm_i915_private *dev_priv)
 {
        uint64_t pat;
 
@@ -1816,6 +1821,33 @@ static void gen8_setup_private_ppat(struct drm_i915_private *dev_priv)
        I915_WRITE(GEN8_PRIVATE_PAT + 4, pat >> 32);
 }
 
+static void chv_setup_private_ppat(struct drm_i915_private *dev_priv)
+{
+       uint64_t pat;
+
+       /*
+        * Map WB on BDW to snooped on CHV.
+        *
+        * Only the snoop bit has meaning for CHV, the rest is
+        * ignored.
+        *
+        * Note that the harware enforces snooping for all page
+        * table accesses. The snoop bit is actually ignored for
+        * PDEs.
+        */
+       pat = GEN8_PPAT(0, CHV_PPAT_SNOOP) |
+             GEN8_PPAT(1, 0) |
+             GEN8_PPAT(2, 0) |
+             GEN8_PPAT(3, 0) |
+             GEN8_PPAT(4, CHV_PPAT_SNOOP) |
+             GEN8_PPAT(5, CHV_PPAT_SNOOP) |
+             GEN8_PPAT(6, CHV_PPAT_SNOOP) |
+             GEN8_PPAT(7, CHV_PPAT_SNOOP);
+
+       I915_WRITE(GEN8_PRIVATE_PAT, pat);
+       I915_WRITE(GEN8_PRIVATE_PAT + 4, pat >> 32);
+}
+
 static int gen8_gmch_probe(struct drm_device *dev,
                           size_t *gtt_total,
                           size_t *stolen,
@@ -1841,7 +1873,10 @@ static int gen8_gmch_probe(struct drm_device *dev,
        gtt_size = gen8_get_total_gtt_size(snb_gmch_ctl);
        *gtt_total = (gtt_size / sizeof(gen8_gtt_pte_t)) << PAGE_SHIFT;
 
-       gen8_setup_private_ppat(dev_priv);
+       if (IS_CHERRYVIEW(dev))
+               chv_setup_private_ppat(dev_priv);
+       else
+               bdw_setup_private_ppat(dev_priv);
 
        ret = ggtt_probe_common(dev, gtt_size);
 
index b5e8ac0f5ce4ddb291ccbc7dd384715b2e5b6498..cfca023c4076c8890e765cdaeb2e7cc669d48525 100644 (file)
@@ -95,6 +95,7 @@ typedef gen8_gtt_pte_t gen8_ppgtt_pde_t;
 #define PPAT_CACHED_INDEX              _PAGE_PAT /* WB LLCeLLC */
 #define PPAT_DISPLAY_ELLC_INDEX                _PAGE_PCD /* WT eLLC */
 
+#define CHV_PPAT_SNOOP                 (1<<6)
 #define GEN8_PPAT_AGE(x)               (x<<4)
 #define GEN8_PPAT_LLCeLLC              (3<<2)
 #define GEN8_PPAT_LLCELLC              (2<<2)