#include "i915_gem_object.h"
 #include "i915_vma.h"
 
+#define VTD_GUARD (168u * I915_GTT_PAGE_SIZE) /* 168 or tile-row PTE padding */
+
 static bool gpu_write_needs_clflush(struct drm_i915_gem_object *obj)
 {
        struct drm_i915_private *i915 = to_i915(obj->base.dev);
        if (ret)
                return ERR_PTR(ret);
 
+       /* VT-d may overfetch before/after the vma, so pad with scratch */
+       if (intel_scanout_needs_vtd_wa(i915)) {
+               unsigned int guard = VTD_GUARD;
+
+               if (i915_gem_object_is_tiled(obj))
+                       guard = max(guard,
+                                   i915_gem_object_get_tile_row_size(obj));
+
+               flags |= PIN_OFFSET_GUARD | guard;
+       }
+
        /*
         * As the user may map the buffer once pinned in the display plane
         * (e.g. libkms for the bootup splash), we have to ensure that we
 
 {
 }
 
-static void gen8_ggtt_clear_range(struct i915_address_space *vm,
-                                 u64 start, u64 length)
-{
-       struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
-       unsigned int first_entry = start / I915_GTT_PAGE_SIZE;
-       unsigned int num_entries = length / I915_GTT_PAGE_SIZE;
-       const gen8_pte_t scratch_pte = vm->scratch[0]->encode;
-       gen8_pte_t __iomem *gtt_base =
-               (gen8_pte_t __iomem *)ggtt->gsm + first_entry;
-       const int max_entries = ggtt_total_entries(ggtt) - first_entry;
-       int i;
-
-       if (WARN(num_entries > max_entries,
-                "First entry = %d; Num entries = %d (max=%d)\n",
-                first_entry, num_entries, max_entries))
-               num_entries = max_entries;
-
-       for (i = 0; i < num_entries; i++)
-               gen8_set_pte(>t_base[i], scratch_pte);
-}
-
 static void bxt_vtd_ggtt_wa(struct i915_address_space *vm)
 {
        /*
        ggtt->vm.cleanup = gen6_gmch_remove;
        ggtt->vm.insert_page = gen8_ggtt_insert_page;
        ggtt->vm.clear_range = nop_clear_range;
-       if (intel_scanout_needs_vtd_wa(i915))
-               ggtt->vm.clear_range = gen8_ggtt_clear_range;
 
        ggtt->vm.insert_entries = gen8_ggtt_insert_entries;
 
        ggtt->vm.alloc_scratch_dma = alloc_pt_dma;
 
        ggtt->vm.clear_range = nop_clear_range;
-       if (!HAS_FULL_PPGTT(i915) || intel_scanout_needs_vtd_wa(i915))
+       if (!HAS_FULL_PPGTT(i915))
                ggtt->vm.clear_range = gen6_ggtt_clear_range;
        ggtt->vm.insert_page = gen6_ggtt_insert_page;
        ggtt->vm.insert_entries = gen6_ggtt_insert_entries;