drm/i915/lmem: support optional CPU clearing for special internal use
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / gem / i915_gem_region.c
index 3e3dad2..ce8fcfc 100644 (file)
@@ -95,6 +95,28 @@ i915_gem_object_get_pages_buddy(struct drm_i915_gem_object *obj)
        sg_mark_end(sg);
        i915_sg_trim(st);
 
+       /* Intended for kernel internal use only */
+       if (obj->flags & I915_BO_ALLOC_CPU_CLEAR) {
+               struct scatterlist *sg;
+               unsigned long i;
+
+               for_each_sg(st->sgl, sg, st->nents, i) {
+                       unsigned int length;
+                       void __iomem *vaddr;
+                       dma_addr_t daddr;
+
+                       daddr = sg_dma_address(sg);
+                       daddr -= mem->region.start;
+                       length = sg_dma_len(sg);
+
+                       vaddr = io_mapping_map_wc(&mem->iomap, daddr, length);
+                       memset64((void __force *)vaddr, 0, length / sizeof(u64));
+                       io_mapping_unmap(vaddr);
+               }
+
+               wmb();
+       }
+
        __i915_gem_object_set_pages(obj, st, sg_page_sizes);
 
        return 0;
@@ -106,13 +128,11 @@ err_free_sg:
 }
 
 void i915_gem_object_init_memory_region(struct drm_i915_gem_object *obj,
-                                       struct intel_memory_region *mem,
-                                       unsigned long flags)
+                                       struct intel_memory_region *mem)
 {
        INIT_LIST_HEAD(&obj->mm.blocks);
        obj->mm.region = intel_memory_region_get(mem);
 
-       obj->flags |= flags;
        if (obj->base.size <= mem->min_page_size)
                obj->flags |= I915_BO_ALLOC_CONTIGUOUS;
 
@@ -161,17 +181,7 @@ i915_gem_object_create_region(struct intel_memory_region *mem,
        GEM_BUG_ON(!size);
        GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_MIN_ALIGNMENT));
 
-       /*
-        * XXX: There is a prevalence of the assumption that we fit the
-        * object's page count inside a 32bit _signed_ variable. Let's document
-        * this and catch if we ever need to fix it. In the meantime, if you do
-        * spot such a local variable, please consider fixing!
-        */
-
-       if (size >> PAGE_SHIFT > INT_MAX)
-               return ERR_PTR(-E2BIG);
-
-       if (overflows_type(size, obj->base.size))
+       if (i915_gem_object_size_2big(size))
                return ERR_PTR(-E2BIG);
 
        obj = i915_gem_object_alloc();