diff --git a/drivers/gpu/nvgpu/Makefile.nvgpu b/drivers/gpu/nvgpu/Makefile.nvgpu
index 34d8d19f2..d994ac1dd 100644
--- a/drivers/gpu/nvgpu/Makefile.nvgpu
+++ b/drivers/gpu/nvgpu/Makefile.nvgpu
@@ -32,6 +32,7 @@ nvgpu-y := \
common/linux/ioctl_tsg.o \
common/linux/log.o \
common/linux/nvgpu_mem.o \
+ common/linux/dma.o \
common/mm/nvgpu_allocator.o \
common/mm/bitmap_allocator.o \
common/mm/buddy_allocator.o \
diff --git a/drivers/gpu/nvgpu/common/linux/dma.c b/drivers/gpu/nvgpu/common/linux/dma.c
new file mode 100644
index 000000000..755848eae
--- /dev/null
+++ b/drivers/gpu/nvgpu/common/linux/dma.c
@@ -0,0 +1,415 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#include
+#include
+
+#include
+#include
+
+#include "gk20a/gk20a.h"
+
+#if defined(CONFIG_GK20A_VIDMEM)
+static u64 __gk20a_gmmu_alloc(struct nvgpu_allocator *allocator, dma_addr_t at,
+ size_t size)
+{
+ u64 addr = 0;
+
+ if (at)
+ addr = nvgpu_alloc_fixed(allocator, at, size, 0);
+ else
+ addr = nvgpu_alloc(allocator, size);
+
+ return addr;
+}
+#endif
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
+static void gk20a_dma_flags_to_attrs(unsigned long *attrs,
+ unsigned long flags)
+#define ATTR_ARG(x) *x
+#else
+static void gk20a_dma_flags_to_attrs(struct dma_attrs *attrs,
+ unsigned long flags)
+#define ATTR_ARG(x) x
+#endif
+{
+ if (flags & NVGPU_DMA_NO_KERNEL_MAPPING)
+ dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, ATTR_ARG(attrs));
+ if (flags & NVGPU_DMA_FORCE_CONTIGUOUS)
+ dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, ATTR_ARG(attrs));
+ if (flags & NVGPU_DMA_READ_ONLY)
+ dma_set_attr(DMA_ATTR_READ_ONLY, ATTR_ARG(attrs));
+#undef ATTR_ARG
+}
+
+int gk20a_gmmu_alloc(struct gk20a *g, size_t size, struct nvgpu_mem *mem)
+{
+ return gk20a_gmmu_alloc_flags(g, 0, size, mem);
+}
+
+int gk20a_gmmu_alloc_flags(struct gk20a *g, unsigned long flags, size_t size,
+ struct nvgpu_mem *mem)
+{
+ if (g->mm.vidmem_is_vidmem) {
+ /*
+ * Force the no-kernel-mapping flag on because we don't support
+ * the lack of it for vidmem - the user should not care when
+ * using gk20a_gmmu_alloc_map and it's vidmem, or if there's a
+ * difference, the user should use the flag explicitly anyway.
+ */
+ int err = gk20a_gmmu_alloc_flags_vid(g,
+ flags | NVGPU_DMA_NO_KERNEL_MAPPING,
+ size, mem);
+
+ if (!err)
+ return 0;
+ /*
+ * Fall back to sysmem (which may then also fail) in case
+ * vidmem is exhausted.
+ */
+ }
+
+ return gk20a_gmmu_alloc_flags_sys(g, flags, size, mem);
+}
+
+int gk20a_gmmu_alloc_sys(struct gk20a *g, size_t size, struct nvgpu_mem *mem)
+{
+ return gk20a_gmmu_alloc_flags_sys(g, 0, size, mem);
+}
+
+int gk20a_gmmu_alloc_flags_sys(struct gk20a *g, unsigned long flags,
+ size_t size, struct nvgpu_mem *mem)
+{
+ struct device *d = dev_from_gk20a(g);
+ int err;
+ dma_addr_t iova;
+
+ gk20a_dbg_fn("");
+
+ if (flags) {
+ DEFINE_DMA_ATTRS(dma_attrs);
+
+ gk20a_dma_flags_to_attrs(&dma_attrs, flags);
+
+ if (flags & NVGPU_DMA_NO_KERNEL_MAPPING) {
+ mem->pages = dma_alloc_attrs(d,
+ size, &iova, GFP_KERNEL,
+ __DMA_ATTR(dma_attrs));
+ if (!mem->pages)
+ return -ENOMEM;
+ } else {
+ mem->cpu_va = dma_alloc_attrs(d,
+ size, &iova, GFP_KERNEL,
+ __DMA_ATTR(dma_attrs));
+ if (!mem->cpu_va)
+ return -ENOMEM;
+ }
+ } else {
+ mem->cpu_va = dma_alloc_coherent(d, size, &iova, GFP_KERNEL);
+ if (!mem->cpu_va)
+ return -ENOMEM;
+ }
+
+ if (flags & NVGPU_DMA_NO_KERNEL_MAPPING)
+ err = gk20a_get_sgtable_from_pages(d, &mem->sgt, mem->pages,
+ iova, size);
+ else {
+ err = gk20a_get_sgtable(d, &mem->sgt, mem->cpu_va, iova, size);
+ memset(mem->cpu_va, 0, size);
+ }
+ if (err)
+ goto fail_free;
+
+ mem->size = size;
+ mem->aperture = APERTURE_SYSMEM;
+ mem->flags = flags;
+
+ gk20a_dbg_fn("done");
+
+ return 0;
+
+fail_free:
+ dma_free_coherent(d, size, mem->cpu_va, iova);
+ mem->cpu_va = NULL;
+ mem->sgt = NULL;
+ return err;
+}
+
+int gk20a_gmmu_alloc_vid(struct gk20a *g, size_t size, struct nvgpu_mem *mem)
+{
+ return gk20a_gmmu_alloc_flags_vid(g,
+ NVGPU_DMA_NO_KERNEL_MAPPING, size, mem);
+}
+
+int gk20a_gmmu_alloc_flags_vid(struct gk20a *g, unsigned long flags,
+ size_t size, struct nvgpu_mem *mem)
+{
+ return gk20a_gmmu_alloc_flags_vid_at(g, flags, size, mem, 0);
+}
+
+int gk20a_gmmu_alloc_flags_vid_at(struct gk20a *g, unsigned long flags,
+ size_t size, struct nvgpu_mem *mem, dma_addr_t at)
+{
+#if defined(CONFIG_GK20A_VIDMEM)
+ u64 addr;
+ int err;
+ struct nvgpu_allocator *vidmem_alloc = g->mm.vidmem.cleared ?
+ &g->mm.vidmem.allocator :
+ &g->mm.vidmem.bootstrap_allocator;
+ int before_pending;
+
+ gk20a_dbg_fn("");
+
+ if (!nvgpu_alloc_initialized(&g->mm.vidmem.allocator))
+ return -ENOSYS;
+
+ /*
+ * Our own allocator doesn't have any flags yet, and we can't
+ * kernel-map these, so require explicit flags.
+ */
+ WARN_ON(flags != NVGPU_DMA_NO_KERNEL_MAPPING);
+
+ nvgpu_mutex_acquire(&g->mm.vidmem.clear_list_mutex);
+ before_pending = atomic64_read(&g->mm.vidmem.bytes_pending);
+ addr = __gk20a_gmmu_alloc(vidmem_alloc, at, size);
+ nvgpu_mutex_release(&g->mm.vidmem.clear_list_mutex);
+ if (!addr) {
+ /*
+ * If memory is known to be freed soon, let the user know that
+ * it may be available after a while.
+ */
+ if (before_pending)
+ return -EAGAIN;
+ else
+ return -ENOMEM;
+ }
+
+ if (at)
+ mem->fixed = true;
+ else
+ mem->fixed = false;
+
+ mem->sgt = nvgpu_kzalloc(g, sizeof(struct sg_table));
+ if (!mem->sgt) {
+ err = -ENOMEM;
+ goto fail_physfree;
+ }
+
+ err = sg_alloc_table(mem->sgt, 1, GFP_KERNEL);
+ if (err)
+ goto fail_kfree;
+
+ set_vidmem_page_alloc(mem->sgt->sgl, addr);
+ sg_set_page(mem->sgt->sgl, NULL, size, 0);
+
+ mem->size = size;
+ mem->aperture = APERTURE_VIDMEM;
+ mem->allocator = vidmem_alloc;
+ mem->flags = flags;
+
+ nvgpu_init_list_node(&mem->clear_list_entry);
+
+ gk20a_dbg_fn("done at 0x%llx size %zu", addr, size);
+
+ return 0;
+
+fail_kfree:
+ nvgpu_kfree(g, mem->sgt);
+fail_physfree:
+ nvgpu_free(&g->mm.vidmem.allocator, addr);
+ return err;
+#else
+ return -ENOSYS;
+#endif
+}
+
+int gk20a_gmmu_alloc_map(struct vm_gk20a *vm, size_t size,
+ struct nvgpu_mem *mem)
+{
+ return gk20a_gmmu_alloc_map_flags(vm, 0, size, mem);
+}
+
+int gk20a_gmmu_alloc_map_flags(struct vm_gk20a *vm, unsigned long flags,
+ size_t size, struct nvgpu_mem *mem)
+{
+ if (vm->mm->vidmem_is_vidmem) {
+ /*
+ * Force the no-kernel-mapping flag on because we don't support
+ * the lack of it for vidmem - the user should not care when
+ * using gk20a_gmmu_alloc_map and it's vidmem, or if there's a
+ * difference, the user should use the flag explicitly anyway.
+ */
+ int err = gk20a_gmmu_alloc_map_flags_vid(vm,
+ flags | NVGPU_DMA_NO_KERNEL_MAPPING,
+ size, mem);
+
+ if (!err)
+ return 0;
+ /*
+ * Fall back to sysmem (which may then also fail) in case
+ * vidmem is exhausted.
+ */
+ }
+
+ return gk20a_gmmu_alloc_map_flags_sys(vm, flags, size, mem);
+}
+
+int gk20a_gmmu_alloc_map_sys(struct vm_gk20a *vm, size_t size,
+ struct nvgpu_mem *mem)
+{
+ return gk20a_gmmu_alloc_map_flags_sys(vm, 0, size, mem);
+}
+
+int gk20a_gmmu_alloc_map_flags_sys(struct vm_gk20a *vm, unsigned long flags,
+ size_t size, struct nvgpu_mem *mem)
+{
+ int err = gk20a_gmmu_alloc_flags_sys(vm->mm->g, flags, size, mem);
+
+ if (err)
+ return err;
+
+ mem->gpu_va = gk20a_gmmu_map(vm, &mem->sgt, size, 0,
+ gk20a_mem_flag_none, false,
+ mem->aperture);
+ if (!mem->gpu_va) {
+ err = -ENOMEM;
+ goto fail_free;
+ }
+
+ return 0;
+
+fail_free:
+ gk20a_gmmu_free(vm->mm->g, mem);
+ return err;
+}
+
+int gk20a_gmmu_alloc_map_vid(struct vm_gk20a *vm, size_t size,
+ struct nvgpu_mem *mem)
+{
+ return gk20a_gmmu_alloc_map_flags_vid(vm,
+ NVGPU_DMA_NO_KERNEL_MAPPING, size, mem);
+}
+
+int gk20a_gmmu_alloc_map_flags_vid(struct vm_gk20a *vm, unsigned long flags,
+ size_t size, struct nvgpu_mem *mem)
+{
+ int err = gk20a_gmmu_alloc_flags_vid(vm->mm->g, flags, size, mem);
+
+ if (err)
+ return err;
+
+ mem->gpu_va = gk20a_gmmu_map(vm, &mem->sgt, size, 0,
+ gk20a_mem_flag_none, false,
+ mem->aperture);
+ if (!mem->gpu_va) {
+ err = -ENOMEM;
+ goto fail_free;
+ }
+
+ return 0;
+
+fail_free:
+ gk20a_gmmu_free(vm->mm->g, mem);
+ return err;
+}
+
+static void gk20a_gmmu_free_sys(struct gk20a *g, struct nvgpu_mem *mem)
+{
+ struct device *d = dev_from_gk20a(g);
+
+ if (mem->cpu_va || mem->pages) {
+ if (mem->flags) {
+ DEFINE_DMA_ATTRS(dma_attrs);
+
+ gk20a_dma_flags_to_attrs(&dma_attrs, mem->flags);
+
+ if (mem->flags & NVGPU_DMA_NO_KERNEL_MAPPING) {
+ dma_free_attrs(d, mem->size, mem->pages,
+ sg_dma_address(mem->sgt->sgl),
+ __DMA_ATTR(dma_attrs));
+ } else {
+ dma_free_attrs(d, mem->size, mem->cpu_va,
+ sg_dma_address(mem->sgt->sgl),
+ __DMA_ATTR(dma_attrs));
+ }
+ } else {
+ dma_free_coherent(d, mem->size, mem->cpu_va,
+ sg_dma_address(mem->sgt->sgl));
+ }
+ mem->cpu_va = NULL;
+ mem->pages = NULL;
+ }
+
+ if (mem->sgt)
+ gk20a_free_sgtable(g, &mem->sgt);
+
+ mem->size = 0;
+ mem->aperture = APERTURE_INVALID;
+}
+
+static void gk20a_gmmu_free_vid(struct gk20a *g, struct nvgpu_mem *mem)
+{
+#if defined(CONFIG_GK20A_VIDMEM)
+ bool was_empty;
+
+ /* Sanity check - only this supported when allocating. */
+ WARN_ON(mem->flags != NVGPU_DMA_NO_KERNEL_MAPPING);
+
+ if (mem->user_mem) {
+ nvgpu_mutex_acquire(&g->mm.vidmem.clear_list_mutex);
+ was_empty = nvgpu_list_empty(&g->mm.vidmem.clear_list_head);
+ nvgpu_list_add_tail(&mem->clear_list_entry,
+ &g->mm.vidmem.clear_list_head);
+ atomic64_add(mem->size, &g->mm.vidmem.bytes_pending);
+ nvgpu_mutex_release(&g->mm.vidmem.clear_list_mutex);
+
+ if (was_empty) {
+ cancel_work_sync(&g->mm.vidmem.clear_mem_worker);
+ schedule_work(&g->mm.vidmem.clear_mem_worker);
+ }
+ } else {
+ nvgpu_memset(g, mem, 0, 0, mem->size);
+ nvgpu_free(mem->allocator,
+ (u64)get_vidmem_page_alloc(mem->sgt->sgl));
+ gk20a_free_sgtable(g, &mem->sgt);
+
+ mem->size = 0;
+ mem->aperture = APERTURE_INVALID;
+ }
+#endif
+}
+
+void gk20a_gmmu_free(struct gk20a *g, struct nvgpu_mem *mem)
+{
+ switch (mem->aperture) {
+ case APERTURE_SYSMEM:
+ return gk20a_gmmu_free_sys(g, mem);
+ case APERTURE_VIDMEM:
+ return gk20a_gmmu_free_vid(g, mem);
+ default:
+ break; /* like free() on "null" memory */
+ }
+}
+
+void gk20a_gmmu_unmap_free(struct vm_gk20a *vm, struct nvgpu_mem *mem)
+{
+ if (mem->gpu_va)
+ gk20a_gmmu_unmap(vm, mem->gpu_va, mem->size, gk20a_mem_flag_none);
+ mem->gpu_va = 0;
+
+ gk20a_gmmu_free(vm->mm->g, mem);
+}
diff --git a/drivers/gpu/nvgpu/common/semaphore.c b/drivers/gpu/nvgpu/common/semaphore.c
index 6fb6c27e2..cfe1149f7 100644
--- a/drivers/gpu/nvgpu/common/semaphore.c
+++ b/drivers/gpu/nvgpu/common/semaphore.c
@@ -18,6 +18,7 @@
#include
#include
+#include
#include
#include
diff --git a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c
index 0db6c21ae..e70ee4a67 100644
--- a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c
@@ -24,6 +24,7 @@
#include
+#include
#include
#include
#include
diff --git a/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c b/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c
index ce76bfc32..9cc4b6783 100644
--- a/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/ce2_gk20a.c
@@ -26,6 +26,7 @@
#include
#include
+#include
#include "gk20a.h"
#include "debug_gk20a.h"
diff --git a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
index d0e2be79e..6be616b37 100644
--- a/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/channel_gk20a.c
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
#include "gk20a.h"
#include "debug_gk20a.h"
diff --git a/drivers/gpu/nvgpu/gk20a/css_gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/css_gr_gk20a.c
index 98fa53ab9..738e8c1cd 100644
--- a/drivers/gpu/nvgpu/gk20a/css_gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/css_gr_gk20a.c
@@ -22,6 +22,7 @@
#include
#include
+#include
#include "gk20a.h"
#include "css_gr_gk20a.h"
diff --git a/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c b/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c
index 3ed28718e..d8fa75057 100644
--- a/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fecs_trace_gk20a.c
@@ -24,6 +24,7 @@
#include
#include
+#include
#include "ctxsw_trace_gk20a.h"
#include "fecs_trace_gk20a.h"
diff --git a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
index 1e9a8e15c..c1f94eb38 100644
--- a/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/fifo_gk20a.c
@@ -26,6 +26,7 @@
#endif
#include
+#include
#include
#include
#include
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index 971e23209..a9b6a5460 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -29,6 +29,7 @@
#include
#include
+#include
#include
#include
#include
diff --git a/drivers/gpu/nvgpu/gk20a/ltc_common.c b/drivers/gpu/nvgpu/gk20a/ltc_common.c
index 7c4db84ec..7c73be777 100644
--- a/drivers/gpu/nvgpu/gk20a/ltc_common.c
+++ b/drivers/gpu/nvgpu/gk20a/ltc_common.c
@@ -21,6 +21,8 @@
#include
#include
+#include
+
#include "gk20a.h"
#include "gr_gk20a.h"
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index cdd0e541f..79654af30 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -30,6 +30,7 @@
#include
#include
+#include
#include
#include
#include
@@ -2519,152 +2520,6 @@ u64 gk20a_gmmu_fixed_map(struct vm_gk20a *vm,
aperture);
}
-int gk20a_gmmu_alloc(struct gk20a *g, size_t size, struct nvgpu_mem *mem)
-{
- return gk20a_gmmu_alloc_flags(g, 0, size, mem);
-}
-
-int gk20a_gmmu_alloc_flags(struct gk20a *g, unsigned long flags, size_t size,
- struct nvgpu_mem *mem)
-{
- if (g->mm.vidmem_is_vidmem) {
- /*
- * Force the no-kernel-mapping flag on because we don't support
- * the lack of it for vidmem - the user should not care when
- * using gk20a_gmmu_alloc_map and it's vidmem, or if there's a
- * difference, the user should use the flag explicitly anyway.
- */
- int err = gk20a_gmmu_alloc_flags_vid(g,
- flags | NVGPU_DMA_NO_KERNEL_MAPPING,
- size, mem);
-
- if (!err)
- return 0;
- /*
- * Fall back to sysmem (which may then also fail) in case
- * vidmem is exhausted.
- */
- }
-
- return gk20a_gmmu_alloc_flags_sys(g, flags, size, mem);
-}
-
-int gk20a_gmmu_alloc_sys(struct gk20a *g, size_t size, struct nvgpu_mem *mem)
-{
- return gk20a_gmmu_alloc_flags_sys(g, 0, size, mem);
-}
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
-static void gk20a_dma_flags_to_attrs(unsigned long *attrs,
- unsigned long flags)
-#define ATTR_ARG(x) *x
-#else
-static void gk20a_dma_flags_to_attrs(struct dma_attrs *attrs,
- unsigned long flags)
-#define ATTR_ARG(x) x
-#endif
-{
- if (flags & NVGPU_DMA_NO_KERNEL_MAPPING)
- dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, ATTR_ARG(attrs));
- if (flags & NVGPU_DMA_FORCE_CONTIGUOUS)
- dma_set_attr(DMA_ATTR_FORCE_CONTIGUOUS, ATTR_ARG(attrs));
- if (flags & NVGPU_DMA_READ_ONLY)
- dma_set_attr(DMA_ATTR_READ_ONLY, ATTR_ARG(attrs));
-#undef ATTR_ARG
-}
-
-int gk20a_gmmu_alloc_flags_sys(struct gk20a *g, unsigned long flags,
- size_t size, struct nvgpu_mem *mem)
-{
- struct device *d = dev_from_gk20a(g);
- int err;
- dma_addr_t iova;
-
- gk20a_dbg_fn("");
-
- if (flags) {
- DEFINE_DMA_ATTRS(dma_attrs);
-
- gk20a_dma_flags_to_attrs(&dma_attrs, flags);
-
- if (flags & NVGPU_DMA_NO_KERNEL_MAPPING) {
- mem->pages = dma_alloc_attrs(d,
- size, &iova, GFP_KERNEL,
- __DMA_ATTR(dma_attrs));
- if (!mem->pages)
- return -ENOMEM;
- } else {
- mem->cpu_va = dma_alloc_attrs(d,
- size, &iova, GFP_KERNEL,
- __DMA_ATTR(dma_attrs));
- if (!mem->cpu_va)
- return -ENOMEM;
- }
- } else {
- mem->cpu_va = dma_alloc_coherent(d, size, &iova, GFP_KERNEL);
- if (!mem->cpu_va)
- return -ENOMEM;
- }
-
- if (flags & NVGPU_DMA_NO_KERNEL_MAPPING)
- err = gk20a_get_sgtable_from_pages(d, &mem->sgt, mem->pages,
- iova, size);
- else {
- err = gk20a_get_sgtable(d, &mem->sgt, mem->cpu_va, iova, size);
- memset(mem->cpu_va, 0, size);
- }
- if (err)
- goto fail_free;
-
- mem->size = size;
- mem->aperture = APERTURE_SYSMEM;
- mem->flags = flags;
-
- gk20a_dbg_fn("done");
-
- return 0;
-
-fail_free:
- dma_free_coherent(d, size, mem->cpu_va, iova);
- mem->cpu_va = NULL;
- mem->sgt = NULL;
- return err;
-}
-
-static void gk20a_gmmu_free_sys(struct gk20a *g, struct nvgpu_mem *mem)
-{
- struct device *d = dev_from_gk20a(g);
-
- if (mem->cpu_va || mem->pages) {
- if (mem->flags) {
- DEFINE_DMA_ATTRS(dma_attrs);
-
- gk20a_dma_flags_to_attrs(&dma_attrs, mem->flags);
-
- if (mem->flags & NVGPU_DMA_NO_KERNEL_MAPPING) {
- dma_free_attrs(d, mem->size, mem->pages,
- sg_dma_address(mem->sgt->sgl),
- __DMA_ATTR(dma_attrs));
- } else {
- dma_free_attrs(d, mem->size, mem->cpu_va,
- sg_dma_address(mem->sgt->sgl),
- __DMA_ATTR(dma_attrs));
- }
- } else {
- dma_free_coherent(d, mem->size, mem->cpu_va,
- sg_dma_address(mem->sgt->sgl));
- }
- mem->cpu_va = NULL;
- mem->pages = NULL;
- }
-
- if (mem->sgt)
- gk20a_free_sgtable(g, &mem->sgt);
-
- mem->size = 0;
- mem->aperture = APERTURE_INVALID;
-}
-
#if defined(CONFIG_GK20A_VIDMEM)
static int gk20a_gmmu_clear_vidmem_mem(struct gk20a *g, struct nvgpu_mem *mem)
{
@@ -2728,153 +2583,6 @@ static int gk20a_gmmu_clear_vidmem_mem(struct gk20a *g, struct nvgpu_mem *mem)
}
#endif
-int gk20a_gmmu_alloc_vid(struct gk20a *g, size_t size, struct nvgpu_mem *mem)
-{
- return gk20a_gmmu_alloc_flags_vid(g,
- NVGPU_DMA_NO_KERNEL_MAPPING, size, mem);
-}
-
-int gk20a_gmmu_alloc_flags_vid(struct gk20a *g, unsigned long flags,
- size_t size, struct nvgpu_mem *mem)
-{
- return gk20a_gmmu_alloc_flags_vid_at(g, flags, size, mem, 0);
-}
-
-#if defined(CONFIG_GK20A_VIDMEM)
-static u64 __gk20a_gmmu_alloc(struct nvgpu_allocator *allocator, dma_addr_t at,
- size_t size)
-{
- u64 addr = 0;
-
- if (at)
- addr = nvgpu_alloc_fixed(allocator, at, size, 0);
- else
- addr = nvgpu_alloc(allocator, size);
-
- return addr;
-}
-#endif
-
-int gk20a_gmmu_alloc_flags_vid_at(struct gk20a *g, unsigned long flags,
- size_t size, struct nvgpu_mem *mem, dma_addr_t at)
-{
-#if defined(CONFIG_GK20A_VIDMEM)
- u64 addr;
- int err;
- struct nvgpu_allocator *vidmem_alloc = g->mm.vidmem.cleared ?
- &g->mm.vidmem.allocator :
- &g->mm.vidmem.bootstrap_allocator;
- int before_pending;
-
- gk20a_dbg_fn("");
-
- if (!nvgpu_alloc_initialized(&g->mm.vidmem.allocator))
- return -ENOSYS;
-
- /*
- * Our own allocator doesn't have any flags yet, and we can't
- * kernel-map these, so require explicit flags.
- */
- WARN_ON(flags != NVGPU_DMA_NO_KERNEL_MAPPING);
-
- nvgpu_mutex_acquire(&g->mm.vidmem.clear_list_mutex);
- before_pending = atomic64_read(&g->mm.vidmem.bytes_pending);
- addr = __gk20a_gmmu_alloc(vidmem_alloc, at, size);
- nvgpu_mutex_release(&g->mm.vidmem.clear_list_mutex);
- if (!addr) {
- /*
- * If memory is known to be freed soon, let the user know that
- * it may be available after a while.
- */
- if (before_pending)
- return -EAGAIN;
- else
- return -ENOMEM;
- }
-
- if (at)
- mem->fixed = true;
- else
- mem->fixed = false;
-
- mem->sgt = nvgpu_kzalloc(g, sizeof(struct sg_table));
- if (!mem->sgt) {
- err = -ENOMEM;
- goto fail_physfree;
- }
-
- err = sg_alloc_table(mem->sgt, 1, GFP_KERNEL);
- if (err)
- goto fail_kfree;
-
- set_vidmem_page_alloc(mem->sgt->sgl, addr);
- sg_set_page(mem->sgt->sgl, NULL, size, 0);
-
- mem->size = size;
- mem->aperture = APERTURE_VIDMEM;
- mem->allocator = vidmem_alloc;
- mem->flags = flags;
-
- nvgpu_init_list_node(&mem->clear_list_entry);
-
- gk20a_dbg_fn("done at 0x%llx size %zu", addr, size);
-
- return 0;
-
-fail_kfree:
- nvgpu_kfree(g, mem->sgt);
-fail_physfree:
- nvgpu_free(&g->mm.vidmem.allocator, addr);
- return err;
-#else
- return -ENOSYS;
-#endif
-}
-
-static void gk20a_gmmu_free_vid(struct gk20a *g, struct nvgpu_mem *mem)
-{
-#if defined(CONFIG_GK20A_VIDMEM)
- bool was_empty;
-
- /* Sanity check - only this supported when allocating. */
- WARN_ON(mem->flags != NVGPU_DMA_NO_KERNEL_MAPPING);
-
- if (mem->user_mem) {
- nvgpu_mutex_acquire(&g->mm.vidmem.clear_list_mutex);
- was_empty = nvgpu_list_empty(&g->mm.vidmem.clear_list_head);
- nvgpu_list_add_tail(&mem->clear_list_entry,
- &g->mm.vidmem.clear_list_head);
- atomic64_add(mem->size, &g->mm.vidmem.bytes_pending);
- nvgpu_mutex_release(&g->mm.vidmem.clear_list_mutex);
-
- if (was_empty) {
- cancel_work_sync(&g->mm.vidmem.clear_mem_worker);
- schedule_work(&g->mm.vidmem.clear_mem_worker);
- }
- } else {
- nvgpu_memset(g, mem, 0, 0, mem->size);
- nvgpu_free(mem->allocator,
- (u64)get_vidmem_page_alloc(mem->sgt->sgl));
- gk20a_free_sgtable(g, &mem->sgt);
-
- mem->size = 0;
- mem->aperture = APERTURE_INVALID;
- }
-#endif
-}
-
-void gk20a_gmmu_free(struct gk20a *g, struct nvgpu_mem *mem)
-{
- switch (mem->aperture) {
- case APERTURE_SYSMEM:
- return gk20a_gmmu_free_sys(g, mem);
- case APERTURE_VIDMEM:
- return gk20a_gmmu_free_vid(g, mem);
- default:
- break; /* like free() on "null" memory */
- }
-}
-
/*
* If mem is in VIDMEM, return base address in vidmem
* else return IOVA address for SYSMEM
@@ -2938,105 +2646,6 @@ static void gk20a_vidmem_clear_mem_worker(struct work_struct *work)
}
#endif
-int gk20a_gmmu_alloc_map(struct vm_gk20a *vm, size_t size,
- struct nvgpu_mem *mem)
-{
- return gk20a_gmmu_alloc_map_flags(vm, 0, size, mem);
-}
-
-int gk20a_gmmu_alloc_map_flags(struct vm_gk20a *vm, unsigned long flags,
- size_t size, struct nvgpu_mem *mem)
-{
- if (vm->mm->vidmem_is_vidmem) {
- /*
- * Force the no-kernel-mapping flag on because we don't support
- * the lack of it for vidmem - the user should not care when
- * using gk20a_gmmu_alloc_map and it's vidmem, or if there's a
- * difference, the user should use the flag explicitly anyway.
- */
- int err = gk20a_gmmu_alloc_map_flags_vid(vm,
- flags | NVGPU_DMA_NO_KERNEL_MAPPING,
- size, mem);
-
- if (!err)
- return 0;
- /*
- * Fall back to sysmem (which may then also fail) in case
- * vidmem is exhausted.
- */
- }
-
- return gk20a_gmmu_alloc_map_flags_sys(vm, flags, size, mem);
-}
-
-int gk20a_gmmu_alloc_map_sys(struct vm_gk20a *vm, size_t size,
- struct nvgpu_mem *mem)
-{
- return gk20a_gmmu_alloc_map_flags_sys(vm, 0, size, mem);
-}
-
-int gk20a_gmmu_alloc_map_flags_sys(struct vm_gk20a *vm, unsigned long flags,
- size_t size, struct nvgpu_mem *mem)
-{
- int err = gk20a_gmmu_alloc_flags_sys(vm->mm->g, flags, size, mem);
-
- if (err)
- return err;
-
- mem->gpu_va = gk20a_gmmu_map(vm, &mem->sgt, size, 0,
- gk20a_mem_flag_none, false,
- mem->aperture);
- if (!mem->gpu_va) {
- err = -ENOMEM;
- goto fail_free;
- }
-
- return 0;
-
-fail_free:
- gk20a_gmmu_free(vm->mm->g, mem);
- return err;
-}
-
-int gk20a_gmmu_alloc_map_vid(struct vm_gk20a *vm, size_t size,
- struct nvgpu_mem *mem)
-{
- return gk20a_gmmu_alloc_map_flags_vid(vm,
- NVGPU_DMA_NO_KERNEL_MAPPING, size, mem);
-}
-
-int gk20a_gmmu_alloc_map_flags_vid(struct vm_gk20a *vm, unsigned long flags,
- size_t size, struct nvgpu_mem *mem)
-{
- int err = gk20a_gmmu_alloc_flags_vid(vm->mm->g, flags, size, mem);
-
- if (err)
- return err;
-
- mem->gpu_va = gk20a_gmmu_map(vm, &mem->sgt, size, 0,
- gk20a_mem_flag_none, false,
- mem->aperture);
- if (!mem->gpu_va) {
- err = -ENOMEM;
- goto fail_free;
- }
-
- return 0;
-
-fail_free:
- gk20a_gmmu_free(vm->mm->g, mem);
- return err;
-}
-
-void gk20a_gmmu_unmap_free(struct vm_gk20a *vm, struct nvgpu_mem *mem)
-{
- if (mem->gpu_va)
- gk20a_gmmu_unmap(vm, mem->gpu_va, mem->size, gk20a_mem_flag_none);
- mem->gpu_va = 0;
-
- gk20a_gmmu_free(vm->mm->g, mem);
-}
-
dma_addr_t gk20a_mm_gpuva_to_iova_base(struct vm_gk20a *vm, u64 gpu_vaddr)
{
struct mapped_buffer_node *buffer;
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
index db72ca79f..53366caf0 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
@@ -524,56 +524,6 @@ u64 gk20a_gmmu_fixed_map(struct vm_gk20a *vm,
bool priv,
enum nvgpu_aperture aperture);
-/* Flags for the below gk20a_gmmu_{alloc,alloc_map}_flags* */
-
-/*
- * Don't create a virtual kernel mapping for the buffer but only allocate it;
- * this may save some resources. The buffer can be mapped later explicitly.
- */
-#define NVGPU_DMA_NO_KERNEL_MAPPING (1 << 0)
-/*
- * Don't allow building the buffer from individual pages but require a
- * physically contiguous block.
- */
-#define NVGPU_DMA_FORCE_CONTIGUOUS (1 << 1)
-/*
- * Make the mapping read-only.
- */
-#define NVGPU_DMA_READ_ONLY (1 << 2)
-
-int gk20a_gmmu_alloc_map(struct vm_gk20a *vm, size_t size,
- struct nvgpu_mem *mem);
-int gk20a_gmmu_alloc_map_flags(struct vm_gk20a *vm, unsigned long flags,
- size_t size, struct nvgpu_mem *mem);
-
-int gk20a_gmmu_alloc_map_sys(struct vm_gk20a *vm, size_t size,
- struct nvgpu_mem *mem);
-int gk20a_gmmu_alloc_map_flags_sys(struct vm_gk20a *vm, unsigned long flags,
- size_t size, struct nvgpu_mem *mem);
-
-int gk20a_gmmu_alloc_map_vid(struct vm_gk20a *vm, size_t size,
- struct nvgpu_mem *mem);
-int gk20a_gmmu_alloc_map_flags_vid(struct vm_gk20a *vm, unsigned long flags,
- size_t size, struct nvgpu_mem *mem);
-
-void gk20a_gmmu_unmap_free(struct vm_gk20a *vm, struct nvgpu_mem *mem);
-
-int gk20a_gmmu_alloc(struct gk20a *g, size_t size, struct nvgpu_mem *mem);
-int gk20a_gmmu_alloc_flags(struct gk20a *g, unsigned long flags, size_t size,
- struct nvgpu_mem *mem);
-
-int gk20a_gmmu_alloc_sys(struct gk20a *g, size_t size, struct nvgpu_mem *mem);
-int gk20a_gmmu_alloc_flags_sys(struct gk20a *g, unsigned long flags,
- size_t size, struct nvgpu_mem *mem);
-
-int gk20a_gmmu_alloc_vid(struct gk20a *g, size_t size, struct nvgpu_mem *mem);
-int gk20a_gmmu_alloc_flags_vid(struct gk20a *g, unsigned long flags,
- size_t size, struct nvgpu_mem *mem);
-int gk20a_gmmu_alloc_flags_vid_at(struct gk20a *g, unsigned long flags,
- size_t size, struct nvgpu_mem *mem, dma_addr_t at);
-
-void gk20a_gmmu_free(struct gk20a *g, struct nvgpu_mem *mem);
-
static inline phys_addr_t gk20a_mem_phys(struct nvgpu_mem *mem)
{
/* FIXME: the sgt/sgl may get null if this is accessed e.g. in an isr
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
index 591b71636..7a6bfe227 100644
--- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
#include "gk20a.h"
#include "gr_gk20a.h"
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
index 013ce43af..3cfcbb193 100644
--- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
@@ -20,6 +20,7 @@
#include
+#include
#include
#include
#include
diff --git a/drivers/gpu/nvgpu/gp106/acr_gp106.c b/drivers/gpu/nvgpu/gp106/acr_gp106.c
index 41c4981d7..9acc8edad 100644
--- a/drivers/gpu/nvgpu/gp106/acr_gp106.c
+++ b/drivers/gpu/nvgpu/gp106/acr_gp106.c
@@ -20,6 +20,7 @@
#include
#include
+#include
#include
#include "gk20a/gk20a.h"
diff --git a/drivers/gpu/nvgpu/gp106/gr_gp106.c b/drivers/gpu/nvgpu/gp106/gr_gp106.c
index dae23374e..78859f881 100644
--- a/drivers/gpu/nvgpu/gp106/gr_gp106.c
+++ b/drivers/gpu/nvgpu/gp106/gr_gp106.c
@@ -13,6 +13,8 @@
* more details.
*/
+#include
+
#include "gk20a/gk20a.h"
#include "gk20a/gr_gk20a.h"
#include "gm20b/gr_gm20b.h"
diff --git a/drivers/gpu/nvgpu/gp10b/fifo_gp10b.c b/drivers/gpu/nvgpu/gp10b/fifo_gp10b.c
index a7e77232a..b305b8959 100644
--- a/drivers/gpu/nvgpu/gp10b/fifo_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/fifo_gp10b.c
@@ -15,6 +15,8 @@
#include
+#include
+
#include "fifo_gp10b.h"
#include "gk20a/gk20a.h"
diff --git a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
index 8e1517f63..b93671201 100644
--- a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
@@ -22,6 +22,7 @@
#include
#include
+#include
#include "gk20a/gk20a.h"
#include "gk20a/gr_gk20a.h"
diff --git a/drivers/gpu/nvgpu/gp10b/mm_gp10b.c b/drivers/gpu/nvgpu/gp10b/mm_gp10b.c
index a0dc8c55f..2f894435e 100644
--- a/drivers/gpu/nvgpu/gp10b/mm_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/mm_gp10b.c
@@ -16,6 +16,8 @@
#include
#include
+#include
+
#include "gk20a/gk20a.h"
#include "gm20b/mm_gm20b.h"
#include "mm_gp10b.h"
diff --git a/drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c b/drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c
index e73bcd8f1..bf52b5c97 100644
--- a/drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/rpfb_gp10b.c
@@ -16,6 +16,8 @@
#include
#include
+#include
+
#include "gk20a/gk20a.h"
#include "rpfb_gp10b.h"
diff --git a/drivers/gpu/nvgpu/include/nvgpu/dma.h b/drivers/gpu/nvgpu/include/nvgpu/dma.h
new file mode 100644
index 000000000..d4fad584e
--- /dev/null
+++ b/drivers/gpu/nvgpu/include/nvgpu/dma.h
@@ -0,0 +1,312 @@
+/*
+ * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+#ifndef __NVGPU_DMA_H__
+#define __NVGPU_DMA_H__
+
+#include
+
+struct gk20a;
+struct vm_gk20a;
+struct nvgpu_mem;
+
+/*
+ * Flags for the below gk20a_gmmu_{alloc,alloc_map}_flags*
+ */
+
+/*
+ * Don't create a virtual kernel mapping for the buffer but only allocate it;
+ * this may save some resources. The buffer can be mapped later explicitly.
+ */
+#define NVGPU_DMA_NO_KERNEL_MAPPING (1 << 0)
+
+/*
+ * Don't allow building the buffer from individual pages but require a
+ * physically contiguous block.
+ */
+#define NVGPU_DMA_FORCE_CONTIGUOUS (1 << 1)
+
+/*
+ * Make the mapping read-only.
+ */
+#define NVGPU_DMA_READ_ONLY (1 << 2)
+
+/**
+ * gk20a_gmmu_alloc - Allocate DMA memory
+ *
+ * @g - The GPU.
+ * @size - Size of the allocation in bytes.
+ * @mem - Struct for storing the allocation information.
+ *
+ * Allocate memory suitable for doing DMA. Store the allocation info in @mem.
+ * Returns 0 on success and a suitable error code when there's an error. This
+ * memory can be either placed in VIDMEM or SYSMEM, which ever is more
+ * convenient for the driver.
+ */
+int gk20a_gmmu_alloc(struct gk20a *g, size_t size, struct nvgpu_mem *mem);
+
+/**
+ * gk20a_gmmu_alloc_flags - Allocate DMA memory
+ *
+ * @g - The GPU.
+ * @flags - Flags modifying the operation of the DMA allocation.
+ * @size - Size of the allocation in bytes.
+ * @mem - Struct for storing the allocation information.
+ *
+ * Allocate memory suitable for doing DMA. Store the allocation info in @mem.
+ * Returns 0 on success and a suitable error code when there's an error. This
+ * memory can be either placed in VIDMEM or SYSMEM, which ever is more
+ * convenient for the driver.
+ *
+ * The following flags are accepted:
+ *
+ * %NVGPU_DMA_NO_KERNEL_MAPPING
+ * %NVGPU_DMA_FORCE_CONTIGUOUS
+ * %NVGPU_DMA_READ_ONLY
+ */
+int gk20a_gmmu_alloc_flags(struct gk20a *g, unsigned long flags, size_t size,
+ struct nvgpu_mem *mem);
+
+/**
+ * gk20a_gmmu_alloc_sys - Allocate DMA memory
+ *
+ * @g - The GPU.
+ * @size - Size of the allocation in bytes.
+ * @mem - Struct for storing the allocation information.
+ *
+ * Allocate memory suitable for doing DMA. Store the allocation info in @mem.
+ * Returns 0 on success and a suitable error code when there's an error. This
+ * allocates memory specifically in SYSMEM.
+ */
+int gk20a_gmmu_alloc_sys(struct gk20a *g, size_t size, struct nvgpu_mem *mem);
+
+/**
+ * gk20a_gmmu_alloc_flags_sys - Allocate DMA memory
+ *
+ * @g - The GPU.
+ * @flags - Flags modifying the operation of the DMA allocation.
+ * @size - Size of the allocation in bytes.
+ * @mem - Struct for storing the allocation information.
+ *
+ * Allocate memory suitable for doing DMA. Store the allocation info in @mem.
+ * Returns 0 on success and a suitable error code when there's an error. This
+ * allocates memory specifically in SYSMEM.
+ *
+ * The following flags are accepted:
+ *
+ * %NVGPU_DMA_NO_KERNEL_MAPPING
+ * %NVGPU_DMA_FORCE_CONTIGUOUS
+ * %NVGPU_DMA_READ_ONLY
+ */
+int gk20a_gmmu_alloc_flags_sys(struct gk20a *g, unsigned long flags,
+ size_t size, struct nvgpu_mem *mem);
+
+/**
+ * gk20a_gmmu_alloc_vid - Allocate DMA memory
+ *
+ * @g - The GPU.
+ * @size - Size of the allocation in bytes.
+ * @mem - Struct for storing the allocation information.
+ *
+ * Allocate memory suitable for doing DMA. Store the allocation info in @mem.
+ * Returns 0 on success and a suitable error code when there's an error. This
+ * allocates memory specifically in VIDMEM.
+ */
+int gk20a_gmmu_alloc_vid(struct gk20a *g, size_t size, struct nvgpu_mem *mem);
+
+/**
+ * gk20a_gmmu_alloc_flags_vid - Allocate DMA memory
+ *
+ * @g - The GPU.
+ * @flags - Flags modifying the operation of the DMA allocation.
+ * @size - Size of the allocation in bytes.
+ * @mem - Struct for storing the allocation information.
+ *
+ * Allocate memory suitable for doing DMA. Store the allocation info in @mem.
+ * Returns 0 on success and a suitable error code when there's an error. This
+ * allocates memory specifically in VIDMEM.
+ *
+ * Only the following flags are accepted:
+ *
+ * %NVGPU_DMA_NO_KERNEL_MAPPING
+ *
+ */
+int gk20a_gmmu_alloc_flags_vid(struct gk20a *g, unsigned long flags,
+ size_t size, struct nvgpu_mem *mem);
+
+/**
+ * gk20a_gmmu_alloc_flags_vid_at - Allocate DMA memory
+ *
+ * @g - The GPU.
+ * @flags - Flags modifying the operation of the DMA allocation.
+ * @size - Size of the allocation in bytes.
+ * @mem - Struct for storing the allocation information.
+ * @at - A specific location to attempt to allocate memory from or 0 if the
+ * caller does not care what the address is.
+ *
+ * Allocate memory suitable for doing DMA. Store the allocation info in @mem.
+ * Returns 0 on success and a suitable error code when there's an error. This
+ * allocates memory specifically in VIDMEM.
+ *
+ * Only the following flags are accepted:
+ *
+ * %NVGPU_DMA_NO_KERNEL_MAPPING
+ */
+int gk20a_gmmu_alloc_flags_vid_at(struct gk20a *g, unsigned long flags,
+ size_t size, struct nvgpu_mem *mem, dma_addr_t at);
+
+/**
+ * gk20a_gmmu_free - Free a DMA allocation
+ *
+ * @g - The GPU.
+ * @mem - An allocation to free.
+ *
+ * Free memory created with any of:
+ *
+ * gk20a_gmmu_alloc()
+ * gk20a_gmmu_alloc_flags()
+ * gk20a_gmmu_alloc_sys()
+ * gk20a_gmmu_alloc_flags_sys()
+ * gk20a_gmmu_alloc_vid()
+ * gk20a_gmmu_alloc_flags_vid()
+ * gk20a_gmmu_alloc_flags_vid_at()
+ */
+void gk20a_gmmu_free(struct gk20a *g, struct nvgpu_mem *mem);
+
+/**
+ * gk20a_gmmu_alloc_map - Allocate DMA memory and map into GMMU.
+ *
+ * @vm - VM context for GMMU mapping.
+ * @size - Size of the allocation in bytes.
+ * @mem - Struct for storing the allocation information.
+ *
+ * Allocate memory suitable for doing DMA and map that memory into the GMMU.
+ * Note this is different than mapping it into the CPU. This memory can be
+ * either placed in VIDMEM or SYSMEM, which ever is more convenient for the
+ * driver.
+ */
+int gk20a_gmmu_alloc_map(struct vm_gk20a *vm, size_t size,
+ struct nvgpu_mem *mem);
+
+/**
+ * gk20a_gmmu_alloc_map_flags - Allocate DMA memory and map into GMMU.
+ *
+ * @vm - VM context for GMMU mapping.
+ * @flags - Flags modifying the operation of the DMA allocation.
+ * @size - Size of the allocation in bytes.
+ * @mem - Struct for storing the allocation information.
+ *
+ * Allocate memory suitable for doing DMA and map that memory into the GMMU.
+ * Note this is different than mapping it into the CPU. This memory can be
+ * either placed in VIDMEM or SYSMEM, which ever is more convenient for the
+ * driver.
+ *
+ * This version passes @flags on to the underlying DMA allocation. The accepted
+ * flags are:
+ *
+ * %NVGPU_DMA_NO_KERNEL_MAPPING
+ * %NVGPU_DMA_FORCE_CONTIGUOUS
+ * %NVGPU_DMA_READ_ONLY
+ */
+int gk20a_gmmu_alloc_map_flags(struct vm_gk20a *vm, unsigned long flags,
+ size_t size, struct nvgpu_mem *mem);
+
+/**
+ * gk20a_gmmu_alloc_map_sys - Allocate DMA memory and map into GMMU.
+ *
+ * @vm - VM context for GMMU mapping.
+ * @size - Size of the allocation in bytes.
+ * @mem - Struct for storing the allocation information.
+ *
+ * Allocate memory suitable for doing DMA and map that memory into the GMMU.
+ * This memory will be placed in SYSMEM.
+ */
+int gk20a_gmmu_alloc_map_sys(struct vm_gk20a *vm, size_t size,
+ struct nvgpu_mem *mem);
+
+/**
+ * gk20a_gmmu_alloc_map_flags_sys - Allocate DMA memory and map into GMMU.
+ *
+ * @vm - VM context for GMMU mapping.
+ * @flags - Flags modifying the operation of the DMA allocation.
+ * @size - Size of the allocation in bytes.
+ * @mem - Struct for storing the allocation information.
+ *
+ * Allocate memory suitable for doing DMA and map that memory into the GMMU.
+ * This memory will be placed in SYSMEM.
+ *
+ * This version passes @flags on to the underlying DMA allocation. The accepted
+ * flags are:
+ *
+ * %NVGPU_DMA_NO_KERNEL_MAPPING
+ * %NVGPU_DMA_FORCE_CONTIGUOUS
+ * %NVGPU_DMA_READ_ONLY
+ */
+int gk20a_gmmu_alloc_map_flags_sys(struct vm_gk20a *vm, unsigned long flags,
+ size_t size, struct nvgpu_mem *mem);
+
+/**
+ * gk20a_gmmu_alloc_map_vid - Allocate DMA memory and map into GMMU.
+ *
+ * @vm - VM context for GMMU mapping.
+ * @size - Size of the allocation in bytes.
+ * @mem - Struct for storing the allocation information.
+ *
+ * Allocate memory suitable for doing DMA and map that memory into the GMMU.
+ * This memory will be placed in VIDMEM.
+ */
+int gk20a_gmmu_alloc_map_vid(struct vm_gk20a *vm, size_t size,
+ struct nvgpu_mem *mem);
+
+/**
+ * gk20a_gmmu_alloc_map_flags_vid - Allocate DMA memory and map into GMMU.
+ *
+ * @vm - VM context for GMMU mapping.
+ * @flags - Flags modifying the operation of the DMA allocation.
+ * @size - Size of the allocation in bytes.
+ * @mem - Struct for storing the allocation information.
+ *
+ * Allocate memory suitable for doing DMA and map that memory into the GMMU.
+ * This memory will be placed in VIDMEM.
+ *
+ * This version passes @flags on to the underlying DMA allocation. The accepted
+ * flags are:
+ *
+ * %NVGPU_DMA_NO_KERNEL_MAPPING
+ * %NVGPU_DMA_FORCE_CONTIGUOUS
+ * %NVGPU_DMA_READ_ONLY
+ */
+int gk20a_gmmu_alloc_map_flags_vid(struct vm_gk20a *vm, unsigned long flags,
+ size_t size, struct nvgpu_mem *mem);
+
+/**
+ * gk20a_gmmu_unmap_free - Free a DMA allocation
+ *
+ * @g - The GPU.
+ * @mem - An allocation to free.
+ *
+ * Free memory created with any of:
+ *
+ * gk20a_gmmu_alloc_map()
+ * gk20a_gmmu_alloc_map_flags()
+ * gk20a_gmmu_alloc_map_sys()
+ * gk20a_gmmu_alloc_map_flags_sys()
+ * gk20a_gmmu_alloc_map_vid()
+ * gk20a_gmmu_alloc_map_flags_vid()
+ */
+void gk20a_gmmu_unmap_free(struct vm_gk20a *vm, struct nvgpu_mem *mem);
+
+#endif
diff --git a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c
index cfe9322e1..59fb0c4af 100644
--- a/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/fifo_vgpu.c
@@ -17,6 +17,7 @@
#include
#include
+#include
#include "vgpu/vgpu.h"
#include "gk20a/ctxsw_trace_gk20a.h"
diff --git a/drivers/gpu/nvgpu/vgpu/gp10b/vgpu_gr_gp10b.c b/drivers/gpu/nvgpu/vgpu/gp10b/vgpu_gr_gp10b.c
index 8cb5b0299..527e12e4a 100644
--- a/drivers/gpu/nvgpu/vgpu/gp10b/vgpu_gr_gp10b.c
+++ b/drivers/gpu/nvgpu/vgpu/gp10b/vgpu_gr_gp10b.c
@@ -12,6 +12,7 @@
*/
#include
+#include
#include "vgpu/vgpu.h"
#include "vgpu/gm20b/vgpu_gr_gm20b.h"
diff --git a/drivers/gpu/nvgpu/vgpu/mm_vgpu.c b/drivers/gpu/nvgpu/vgpu/mm_vgpu.c
index ea81cefe3..b12f8a53d 100644
--- a/drivers/gpu/nvgpu/vgpu/mm_vgpu.c
+++ b/drivers/gpu/nvgpu/vgpu/mm_vgpu.c
@@ -16,6 +16,7 @@
#include
#include
+#include
#include "vgpu/vgpu.h"
#include "gk20a/mm_gk20a.h"