Merge commit drm-intel-fixes into topic/ppgtt
[linux-2.6-block.git] / drivers / gpu / drm / i915 / i915_gem_gtt.c
index 0218e34f178a9de7e35702d8414f51856a792131..88e49b19baba2ba90c7994f6263f50d53d873fcc 100644 (file)
@@ -57,7 +57,9 @@ typedef gen8_gtt_pte_t gen8_ppgtt_pde_t;
 #define HSW_WB_LLC_AGE3                        HSW_CACHEABILITY_CONTROL(0x2)
 #define HSW_WB_LLC_AGE0                        HSW_CACHEABILITY_CONTROL(0x3)
 #define HSW_WB_ELLC_LLC_AGE0           HSW_CACHEABILITY_CONTROL(0xb)
+#define HSW_WB_ELLC_LLC_AGE3           HSW_CACHEABILITY_CONTROL(0x8)
 #define HSW_WT_ELLC_LLC_AGE0           HSW_CACHEABILITY_CONTROL(0x6)
+#define HSW_WT_ELLC_LLC_AGE3           HSW_CACHEABILITY_CONTROL(0x7)
 
 #define GEN8_PTES_PER_PAGE             (PAGE_SIZE / sizeof(gen8_gtt_pte_t))
 #define GEN8_PDES_PER_PAGE             (PAGE_SIZE / sizeof(gen8_ppgtt_pde_t))
@@ -191,10 +193,10 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
        case I915_CACHE_NONE:
                break;
        case I915_CACHE_WT:
-               pte |= HSW_WT_ELLC_LLC_AGE0;
+               pte |= HSW_WT_ELLC_LLC_AGE3;
                break;
        default:
-               pte |= HSW_WB_ELLC_LLC_AGE0;
+               pte |= HSW_WB_ELLC_LLC_AGE3;
                break;
        }
 
@@ -631,8 +633,6 @@ static int gen7_ppgtt_enable(struct i915_hw_ppgtt *ppgtt)
        uint32_t ecochk, ecobits;
        int i;
 
-       gen6_write_pdes(ppgtt);
-
        ecobits = I915_READ(GAC_ECO_BITS);
        I915_WRITE(GAC_ECO_BITS, ecobits | ECOBITS_PPGTT_CACHE64B);
 
@@ -666,8 +666,6 @@ static int gen6_ppgtt_enable(struct i915_hw_ppgtt *ppgtt)
        uint32_t ecochk, gab_ctl, ecobits;
        int i;
 
-       gen6_write_pdes(ppgtt);
-
        ecobits = I915_READ(GAC_ECO_BITS);
        I915_WRITE(GAC_ECO_BITS, ecobits | ECOBITS_SNB_BIT |
                   ECOBITS_PPGTT_CACHE64B);
@@ -888,15 +886,10 @@ err_pt_alloc:
        return ret;
 }
 
-static int i915_gem_init_aliasing_ppgtt(struct drm_device *dev)
+int i915_gem_init_ppgtt(struct drm_device *dev, struct i915_hw_ppgtt *ppgtt)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct i915_hw_ppgtt *ppgtt;
-       int ret;
-
-       ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL);
-       if (!ppgtt)
-               return -ENOMEM;
+       int ret = 0;
 
        ppgtt->base.dev = dev;
 
@@ -907,29 +900,17 @@ static int i915_gem_init_aliasing_ppgtt(struct drm_device *dev)
        else
                BUG();
 
-       if (ret)
-               kfree(ppgtt);
-       else {
-               dev_priv->mm.aliasing_ppgtt = ppgtt;
+       if (!ret) {
+               kref_init(&ppgtt->ref);
                drm_mm_init(&ppgtt->base.mm, ppgtt->base.start,
                            ppgtt->base.total);
+               if (INTEL_INFO(dev)->gen < 8)
+                       gen6_write_pdes(ppgtt);
        }
 
        return ret;
 }
 
-void i915_gem_cleanup_aliasing_ppgtt(struct drm_device *dev)
-{
-       struct drm_i915_private *dev_priv = dev->dev_private;
-       struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
-
-       if (!ppgtt)
-               return;
-
-       ppgtt->base.cleanup(&ppgtt->base);
-       dev_priv->mm.aliasing_ppgtt = NULL;
-}
-
 static void __always_unused
 ppgtt_bind_vma(struct i915_vma *vma,
               enum i915_cache_level cache_level,
@@ -1041,6 +1022,7 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct drm_i915_gem_object *obj;
+       struct i915_address_space *vm;
 
        i915_check_and_clear_faults(dev);
 
@@ -1065,6 +1047,21 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev)
                vma->bind_vma(vma, obj->cache_level, GLOBAL_BIND);
        }
 
+
+       if (INTEL_INFO(dev)->gen >= 8)
+               return;
+
+       list_for_each_entry(vm, &dev_priv->vm_list, global_link) {
+               /* TODO: Perhaps it shouldn't be gen6 specific */
+               if (i915_is_ggtt(vm)) {
+                       if (dev_priv->mm.aliasing_ppgtt)
+                               gen6_write_pdes(dev_priv->mm.aliasing_ppgtt);
+                       continue;
+               }
+
+               gen6_write_pdes(container_of(vm, struct i915_hw_ppgtt, base));
+       }
+
        i915_gem_chipset_flush(dev);
 }
 
@@ -1405,21 +1402,6 @@ void i915_gem_setup_global_gtt(struct drm_device *dev,
        ggtt_vm->clear_range(ggtt_vm, end / PAGE_SIZE - 1, 1, true);
 }
 
-static bool
-intel_enable_ppgtt(struct drm_device *dev)
-{
-       if (i915_enable_ppgtt >= 0)
-               return i915_enable_ppgtt;
-
-#ifdef CONFIG_INTEL_IOMMU
-       /* Disable ppgtt on SNB if VT-d is on. */
-       if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped)
-               return false;
-#endif
-
-       return true;
-}
-
 void i915_gem_init_global_gtt(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
@@ -1429,13 +1411,6 @@ void i915_gem_init_global_gtt(struct drm_device *dev)
        mappable_size = dev_priv->gtt.mappable_end;
 
        i915_gem_setup_global_gtt(dev, 0, mappable_size, gtt_size);
-       if (intel_enable_ppgtt(dev) && HAS_ALIASING_PPGTT(dev)) {
-               int ret;
-
-               ret = i915_gem_init_aliasing_ppgtt(dev);
-               if (ret)
-                       DRM_ERROR("Aliased PPGTT setup failed %d\n", ret);
-       }
 }
 
 static int setup_scratch_page(struct drm_device *dev)