summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/Makefile.nvgpu1
-rw-r--r--drivers/gpu/nvgpu/common/linux/dma.c10
-rw-r--r--drivers/gpu/nvgpu/common/linux/ioctl_as.c2
-rw-r--r--drivers/gpu/nvgpu/common/mm/gmmu.c109
-rw-r--r--drivers/gpu/nvgpu/common/semaphore.c20
-rw-r--r--drivers/gpu/nvgpu/gk20a/cde_gk20a.c9
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c55
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c68
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.h21
-rw-r--r--drivers/gpu/nvgpu/gm20b/acr_gm20b.c13
-rw-r--r--drivers/gpu/nvgpu/gp10b/gr_gp10b.c5
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/dma.h5
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/gmmu.h69
13 files changed, 237 insertions, 150 deletions
diff --git a/drivers/gpu/nvgpu/Makefile.nvgpu b/drivers/gpu/nvgpu/Makefile.nvgpu
index 08d939f0..59c81826 100644
--- a/drivers/gpu/nvgpu/Makefile.nvgpu
+++ b/drivers/gpu/nvgpu/Makefile.nvgpu
@@ -43,6 +43,7 @@ nvgpu-y := \
43 common/mm/buddy_allocator.o \ 43 common/mm/buddy_allocator.o \
44 common/mm/page_allocator.o \ 44 common/mm/page_allocator.o \
45 common/mm/lockless_allocator.o \ 45 common/mm/lockless_allocator.o \
46 common/mm/gmmu.o \
46 common/pramin.o \ 47 common/pramin.o \
47 common/semaphore.o \ 48 common/semaphore.o \
48 common/as.o \ 49 common/as.o \
diff --git a/drivers/gpu/nvgpu/common/linux/dma.c b/drivers/gpu/nvgpu/common/linux/dma.c
index eb2d0ac4..d3d51f18 100644
--- a/drivers/gpu/nvgpu/common/linux/dma.c
+++ b/drivers/gpu/nvgpu/common/linux/dma.c
@@ -20,6 +20,7 @@
20#include <nvgpu/dma.h> 20#include <nvgpu/dma.h>
21#include <nvgpu/lock.h> 21#include <nvgpu/lock.h>
22#include <nvgpu/bug.h> 22#include <nvgpu/bug.h>
23#include <nvgpu/gmmu.h>
23 24
24#include <nvgpu/linux/dma.h> 25#include <nvgpu/linux/dma.h>
25 26
@@ -71,7 +72,7 @@ int nvgpu_dma_alloc_flags(struct gk20a *g, unsigned long flags, size_t size,
71 /* 72 /*
72 * Force the no-kernel-mapping flag on because we don't support 73 * Force the no-kernel-mapping flag on because we don't support
73 * the lack of it for vidmem - the user should not care when 74 * the lack of it for vidmem - the user should not care when
74 * using gk20a_gmmu_alloc_map and it's vidmem, or if there's a 75 * using nvgpu_gmmu_alloc_map and it's vidmem, or if there's a
75 * difference, the user should use the flag explicitly anyway. 76 * difference, the user should use the flag explicitly anyway.
76 */ 77 */
77 int err = nvgpu_dma_alloc_flags_vid(g, 78 int err = nvgpu_dma_alloc_flags_vid(g,
@@ -285,7 +286,7 @@ int nvgpu_dma_alloc_map_flags_sys(struct vm_gk20a *vm, unsigned long flags,
285 if (err) 286 if (err)
286 return err; 287 return err;
287 288
288 mem->gpu_va = gk20a_gmmu_map(vm, &mem->priv.sgt, size, 0, 289 mem->gpu_va = nvgpu_gmmu_map(vm, mem, size, 0,
289 gk20a_mem_flag_none, false, 290 gk20a_mem_flag_none, false,
290 mem->aperture); 291 mem->aperture);
291 if (!mem->gpu_va) { 292 if (!mem->gpu_va) {
@@ -315,7 +316,7 @@ int nvgpu_dma_alloc_map_flags_vid(struct vm_gk20a *vm, unsigned long flags,
315 if (err) 316 if (err)
316 return err; 317 return err;
317 318
318 mem->gpu_va = gk20a_gmmu_map(vm, &mem->priv.sgt, size, 0, 319 mem->gpu_va = nvgpu_gmmu_map(vm, mem, size, 0,
319 gk20a_mem_flag_none, false, 320 gk20a_mem_flag_none, false,
320 mem->aperture); 321 mem->aperture);
321 if (!mem->gpu_va) { 322 if (!mem->gpu_va) {
@@ -420,8 +421,7 @@ void nvgpu_dma_free(struct gk20a *g, struct nvgpu_mem *mem)
420void nvgpu_dma_unmap_free(struct vm_gk20a *vm, struct nvgpu_mem *mem) 421void nvgpu_dma_unmap_free(struct vm_gk20a *vm, struct nvgpu_mem *mem)
421{ 422{
422 if (mem->gpu_va) 423 if (mem->gpu_va)
423 gk20a_gmmu_unmap(vm, mem->gpu_va, 424 nvgpu_gmmu_unmap(vm, mem, mem->gpu_va);
424 mem->size, gk20a_mem_flag_none);
425 mem->gpu_va = 0; 425 mem->gpu_va = 0;
426 426
427 nvgpu_dma_free(vm->mm->g, mem); 427 nvgpu_dma_free(vm->mm->g, mem);
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_as.c b/drivers/gpu/nvgpu/common/linux/ioctl_as.c
index 6a9d3811..31d99d26 100644
--- a/drivers/gpu/nvgpu/common/linux/ioctl_as.c
+++ b/drivers/gpu/nvgpu/common/linux/ioctl_as.c
@@ -23,6 +23,8 @@
23 23
24#include <uapi/linux/nvgpu.h> 24#include <uapi/linux/nvgpu.h>
25 25
26#include <nvgpu/gmmu.h>
27
26#include "gk20a/gk20a.h" 28#include "gk20a/gk20a.h"
27#include "ioctl_as.h" 29#include "ioctl_as.h"
28 30
diff --git a/drivers/gpu/nvgpu/common/mm/gmmu.c b/drivers/gpu/nvgpu/common/mm/gmmu.c
new file mode 100644
index 00000000..a2ed3f3a
--- /dev/null
+++ b/drivers/gpu/nvgpu/common/mm/gmmu.c
@@ -0,0 +1,109 @@
1/*
2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#include <nvgpu/log.h>
18#include <nvgpu/gmmu.h>
19#include <nvgpu/nvgpu_mem.h>
20
21#include "gk20a/gk20a.h"
22#include "gk20a/mm_gk20a.h"
23
24/*
25 * Core GMMU map function for the kernel to use. If @addr is 0 then the GPU
26 * VA will be allocated for you. If addr is non-zero then the buffer will be
27 * mapped at @addr.
28 */
29static u64 __nvgpu_gmmu_map(struct vm_gk20a *vm,
30 struct nvgpu_mem *mem,
31 u64 addr,
32 u64 size,
33 u32 flags,
34 int rw_flag,
35 bool priv,
36 enum nvgpu_aperture aperture)
37{
38 struct gk20a *g = gk20a_from_vm(vm);
39 u64 vaddr;
40
41 struct sg_table *sgt = mem->priv.sgt;
42
43 nvgpu_mutex_acquire(&vm->update_gmmu_lock);
44 vaddr = g->ops.mm.gmmu_map(vm, addr,
45 sgt, /* sg table */
46 0, /* sg offset */
47 size,
48 gmmu_page_size_kernel,
49 0, /* kind */
50 0, /* ctag_offset */
51 flags, rw_flag,
52 false, /* clear_ctags */
53 false, /* sparse */
54 priv, /* priv */
55 NULL, /* mapping_batch handle */
56 aperture);
57 nvgpu_mutex_release(&vm->update_gmmu_lock);
58 if (!vaddr) {
59 nvgpu_err(g, "failed to allocate va space");
60 return 0;
61 }
62
63 return vaddr;
64}
65
66u64 nvgpu_gmmu_map(struct vm_gk20a *vm,
67 struct nvgpu_mem *mem,
68 u64 size,
69 u32 flags,
70 int rw_flag,
71 bool priv,
72 enum nvgpu_aperture aperture)
73{
74 return __nvgpu_gmmu_map(vm, mem, 0, size, flags, rw_flag, priv,
75 aperture);
76}
77
78/*
79 * Like nvgpu_gmmu_map() except it can work on a fixed address instead.
80 */
81u64 nvgpu_gmmu_map_fixed(struct vm_gk20a *vm,
82 struct nvgpu_mem *mem,
83 u64 addr,
84 u64 size,
85 u32 flags,
86 int rw_flag,
87 bool priv,
88 enum nvgpu_aperture aperture)
89{
90 return __nvgpu_gmmu_map(vm, mem, addr, size, flags, rw_flag, priv,
91 aperture);
92}
93
94void nvgpu_gmmu_unmap(struct vm_gk20a *vm, struct nvgpu_mem *mem, u64 gpu_va)
95{
96 struct gk20a *g = gk20a_from_vm(vm);
97
98 nvgpu_mutex_acquire(&vm->update_gmmu_lock);
99 g->ops.mm.gmmu_unmap(vm,
100 gpu_va,
101 mem->size,
102 gmmu_page_size_kernel,
103 true, /*va_allocated */
104 gk20a_mem_flag_none,
105 false,
106 NULL);
107
108 nvgpu_mutex_release(&vm->update_gmmu_lock);
109}
diff --git a/drivers/gpu/nvgpu/common/semaphore.c b/drivers/gpu/nvgpu/common/semaphore.c
index fa86985b..a54ce831 100644
--- a/drivers/gpu/nvgpu/common/semaphore.c
+++ b/drivers/gpu/nvgpu/common/semaphore.c
@@ -14,6 +14,7 @@
14 */ 14 */
15 15
16#include <nvgpu/dma.h> 16#include <nvgpu/dma.h>
17#include <nvgpu/gmmu.h>
17#include <nvgpu/semaphore.h> 18#include <nvgpu/semaphore.h>
18#include <nvgpu/kmem.h> 19#include <nvgpu/kmem.h>
19#include <nvgpu/bug.h> 20#include <nvgpu/bug.h>
@@ -197,7 +198,7 @@ int nvgpu_semaphore_pool_map(struct nvgpu_semaphore_pool *p,
197 */ 198 */
198 __lock_sema_sea(p->sema_sea); 199 __lock_sema_sea(p->sema_sea);
199 200
200 addr = gk20a_gmmu_fixed_map(vm, &p->sema_sea->sea_mem.priv.sgt, 201 addr = nvgpu_gmmu_map_fixed(vm, &p->sema_sea->sea_mem,
201 p->sema_sea->gpu_va, 202 p->sema_sea->gpu_va,
202 p->sema_sea->map_size, 203 p->sema_sea->map_size,
203 0, gk20a_mem_flag_read_only, 0, 204 0, gk20a_mem_flag_read_only, 0,
@@ -225,7 +226,7 @@ int nvgpu_semaphore_pool_map(struct nvgpu_semaphore_pool *p,
225 if (err) 226 if (err)
226 goto fail_unmap; 227 goto fail_unmap;
227 228
228 addr = gk20a_gmmu_map(vm, &p->rw_mem.priv.sgt, SZ_4K, 0, 229 addr = nvgpu_gmmu_map(vm, &p->rw_mem, SZ_4K, 0,
229 gk20a_mem_flag_none, 0, 230 gk20a_mem_flag_none, 0,
230 p->rw_mem.aperture); 231 p->rw_mem.aperture);
231 232
@@ -250,10 +251,7 @@ int nvgpu_semaphore_pool_map(struct nvgpu_semaphore_pool *p,
250fail_free_submem: 251fail_free_submem:
251 nvgpu_dma_free(pool_to_gk20a(p), &p->rw_mem); 252 nvgpu_dma_free(pool_to_gk20a(p), &p->rw_mem);
252fail_unmap: 253fail_unmap:
253 gk20a_gmmu_unmap(vm, 254 nvgpu_gmmu_unmap(vm, &p->sema_sea->sea_mem, p->gpu_va_ro);
254 p->sema_sea->sea_mem.gpu_va,
255 p->sema_sea->map_size,
256 gk20a_mem_flag_none);
257 gpu_sema_dbg(pool_to_gk20a(p), 255 gpu_sema_dbg(pool_to_gk20a(p),
258 " %d: Failed to map semaphore pool!", p->page_idx); 256 " %d: Failed to map semaphore pool!", p->page_idx);
259fail_unlock: 257fail_unlock:
@@ -269,14 +267,8 @@ void nvgpu_semaphore_pool_unmap(struct nvgpu_semaphore_pool *p,
269{ 267{
270 __lock_sema_sea(p->sema_sea); 268 __lock_sema_sea(p->sema_sea);
271 269
272 gk20a_gmmu_unmap(vm, 270 nvgpu_gmmu_unmap(vm, &p->sema_sea->sea_mem, p->gpu_va_ro);
273 p->sema_sea->sea_mem.gpu_va, 271 nvgpu_gmmu_unmap(vm, &p->rw_mem, p->gpu_va);
274 p->sema_sea->sea_mem.size,
275 gk20a_mem_flag_none);
276 gk20a_gmmu_unmap(vm,
277 p->rw_mem.gpu_va,
278 p->rw_mem.size,
279 gk20a_mem_flag_none);
280 nvgpu_dma_free(pool_to_gk20a(p), &p->rw_mem); 272 nvgpu_dma_free(pool_to_gk20a(p), &p->rw_mem);
281 273
282 p->gpu_va = 0; 274 p->gpu_va = 0;
diff --git a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c
index f0927692..74de7e8e 100644
--- a/drivers/gpu/nvgpu/gk20a/cde_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/cde_gk20a.c
@@ -26,6 +26,7 @@
26#include <trace/events/gk20a.h> 26#include <trace/events/gk20a.h>
27 27
28#include <nvgpu/dma.h> 28#include <nvgpu/dma.h>
29#include <nvgpu/gmmu.h>
29#include <nvgpu/timers.h> 30#include <nvgpu/timers.h>
30#include <nvgpu/nvgpu_common.h> 31#include <nvgpu/nvgpu_common.h>
31#include <nvgpu/kmem.h> 32#include <nvgpu/kmem.h>
@@ -83,8 +84,8 @@ __must_hold(&cde_app->mutex)
83 84
84 /* release mapped memory */ 85 /* release mapped memory */
85 gk20a_deinit_cde_img(cde_ctx); 86 gk20a_deinit_cde_img(cde_ctx);
86 gk20a_gmmu_unmap(vm, cde_ctx->backing_store_vaddr, 87 nvgpu_gmmu_unmap(vm, &g->gr.compbit_store.mem,
87 g->gr.compbit_store.mem.size, 1); 88 cde_ctx->backing_store_vaddr);
88 89
89 /* free the channel */ 90 /* free the channel */
90 gk20a_channel_close(ch); 91 gk20a_channel_close(ch);
@@ -1241,7 +1242,7 @@ static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx)
1241 } 1242 }
1242 1243
1243 /* map backing store to gpu virtual space */ 1244 /* map backing store to gpu virtual space */
1244 vaddr = gk20a_gmmu_map(ch->vm, &gr->compbit_store.mem.priv.sgt, 1245 vaddr = nvgpu_gmmu_map(ch->vm, &gr->compbit_store.mem,
1245 g->gr.compbit_store.mem.size, 1246 g->gr.compbit_store.mem.size,
1246 NVGPU_MAP_BUFFER_FLAGS_CACHEABLE_TRUE, 1247 NVGPU_MAP_BUFFER_FLAGS_CACHEABLE_TRUE,
1247 gk20a_mem_flag_read_only, 1248 gk20a_mem_flag_read_only,
@@ -1272,7 +1273,7 @@ static int gk20a_cde_load(struct gk20a_cde_ctx *cde_ctx)
1272 return 0; 1273 return 0;
1273 1274
1274err_init_cde_img: 1275err_init_cde_img:
1275 gk20a_gmmu_unmap(ch->vm, vaddr, g->gr.compbit_store.mem.size, 1); 1276 nvgpu_gmmu_unmap(ch->vm, &g->gr.compbit_store.mem, vaddr);
1276err_map_backingstore: 1277err_map_backingstore:
1277err_alloc_gpfifo: 1278err_alloc_gpfifo:
1278 gk20a_vm_put(ch->vm); 1279 gk20a_vm_put(ch->vm);
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index 77a947de..2f52fdcf 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -21,6 +21,7 @@
21 21
22#include <nvgpu/dma.h> 22#include <nvgpu/dma.h>
23#include <nvgpu/kmem.h> 23#include <nvgpu/kmem.h>
24#include <nvgpu/gmmu.h>
24#include <nvgpu/timers.h> 25#include <nvgpu/timers.h>
25#include <nvgpu/nvgpu_common.h> 26#include <nvgpu/nvgpu_common.h>
26#include <nvgpu/log.h> 27#include <nvgpu/log.h>
@@ -1946,8 +1947,8 @@ int gr_gk20a_update_hwpm_ctxsw_mode(struct gk20a *g,
1946 return ret; 1947 return ret;
1947 } 1948 }
1948 1949
1949 pm_ctx->mem.gpu_va = gk20a_gmmu_map(c->vm, 1950 pm_ctx->mem.gpu_va = nvgpu_gmmu_map(c->vm,
1950 &pm_ctx->mem.priv.sgt, 1951 &pm_ctx->mem,
1951 pm_ctx->mem.size, 1952 pm_ctx->mem.size,
1952 NVGPU_MAP_BUFFER_FLAGS_CACHEABLE_TRUE, 1953 NVGPU_MAP_BUFFER_FLAGS_CACHEABLE_TRUE,
1953 gk20a_mem_flag_none, true, 1954 gk20a_mem_flag_none, true,
@@ -2013,8 +2014,7 @@ int gr_gk20a_update_hwpm_ctxsw_mode(struct gk20a *g,
2013clean_up_mem: 2014clean_up_mem:
2014 nvgpu_mem_end(g, gr_mem); 2015 nvgpu_mem_end(g, gr_mem);
2015cleanup_pm_buf: 2016cleanup_pm_buf:
2016 gk20a_gmmu_unmap(c->vm, pm_ctx->mem.gpu_va, pm_ctx->mem.size, 2017 nvgpu_gmmu_unmap(c->vm, &pm_ctx->mem, pm_ctx->mem.gpu_va);
2017 gk20a_mem_flag_none);
2018 nvgpu_dma_free(g, &pm_ctx->mem); 2018 nvgpu_dma_free(g, &pm_ctx->mem);
2019 memset(&pm_ctx->mem, 0, sizeof(struct nvgpu_mem)); 2019 memset(&pm_ctx->mem, 0, sizeof(struct nvgpu_mem));
2020 2020
@@ -2198,8 +2198,8 @@ static int gr_gk20a_init_ctxsw_ucode_vaspace(struct gk20a *g)
2198 g->ops.mm.init_inst_block(&ucode_info->inst_blk_desc, vm, 0); 2198 g->ops.mm.init_inst_block(&ucode_info->inst_blk_desc, vm, 0);
2199 2199
2200 /* Map ucode surface to GMMU */ 2200 /* Map ucode surface to GMMU */
2201 ucode_info->surface_desc.gpu_va = gk20a_gmmu_map(vm, 2201 ucode_info->surface_desc.gpu_va = nvgpu_gmmu_map(vm,
2202 &ucode_info->surface_desc.priv.sgt, 2202 &ucode_info->surface_desc,
2203 ucode_info->surface_desc.size, 2203 ucode_info->surface_desc.size,
2204 0, /* flags */ 2204 0, /* flags */
2205 gk20a_mem_flag_read_only, 2205 gk20a_mem_flag_read_only,
@@ -2331,10 +2331,10 @@ int gr_gk20a_init_ctxsw_ucode(struct gk20a *g)
2331 2331
2332 return 0; 2332 return 0;
2333 2333
2334 clean_up: 2334clean_up:
2335 if (ucode_info->surface_desc.gpu_va) 2335 if (ucode_info->surface_desc.gpu_va)
2336 gk20a_gmmu_unmap(vm, ucode_info->surface_desc.gpu_va, 2336 nvgpu_gmmu_unmap(vm, &ucode_info->surface_desc,
2337 ucode_info->surface_desc.size, gk20a_mem_flag_none); 2337 ucode_info->surface_desc.gpu_va);
2338 nvgpu_dma_free(g, &ucode_info->surface_desc); 2338 nvgpu_dma_free(g, &ucode_info->surface_desc);
2339 2339
2340 nvgpu_release_firmware(g, gpccs_fw); 2340 nvgpu_release_firmware(g, gpccs_fw);
@@ -2824,7 +2824,7 @@ static int gr_gk20a_map_global_ctx_buffers(struct gk20a *g,
2824 mem = &gr->global_ctx_buffer[CIRCULAR_VPR].mem; 2824 mem = &gr->global_ctx_buffer[CIRCULAR_VPR].mem;
2825 } 2825 }
2826 2826
2827 gpu_va = gk20a_gmmu_map(ch_vm, &mem->priv.sgt, mem->size, 2827 gpu_va = nvgpu_gmmu_map(ch_vm, mem, mem->size,
2828 NVGPU_MAP_BUFFER_FLAGS_CACHEABLE_TRUE, 2828 NVGPU_MAP_BUFFER_FLAGS_CACHEABLE_TRUE,
2829 gk20a_mem_flag_none, true, mem->aperture); 2829 gk20a_mem_flag_none, true, mem->aperture);
2830 if (!gpu_va) 2830 if (!gpu_va)
@@ -2840,7 +2840,7 @@ static int gr_gk20a_map_global_ctx_buffers(struct gk20a *g,
2840 mem = &gr->global_ctx_buffer[ATTRIBUTE_VPR].mem; 2840 mem = &gr->global_ctx_buffer[ATTRIBUTE_VPR].mem;
2841 } 2841 }
2842 2842
2843 gpu_va = gk20a_gmmu_map(ch_vm, &mem->priv.sgt, mem->size, 2843 gpu_va = nvgpu_gmmu_map(ch_vm, mem, mem->size,
2844 NVGPU_MAP_BUFFER_FLAGS_CACHEABLE_TRUE, 2844 NVGPU_MAP_BUFFER_FLAGS_CACHEABLE_TRUE,
2845 gk20a_mem_flag_none, false, mem->aperture); 2845 gk20a_mem_flag_none, false, mem->aperture);
2846 if (!gpu_va) 2846 if (!gpu_va)
@@ -2856,7 +2856,7 @@ static int gr_gk20a_map_global_ctx_buffers(struct gk20a *g,
2856 mem = &gr->global_ctx_buffer[PAGEPOOL_VPR].mem; 2856 mem = &gr->global_ctx_buffer[PAGEPOOL_VPR].mem;
2857 } 2857 }
2858 2858
2859 gpu_va = gk20a_gmmu_map(ch_vm, &mem->priv.sgt, mem->size, 2859 gpu_va = nvgpu_gmmu_map(ch_vm, mem, mem->size,
2860 NVGPU_MAP_BUFFER_FLAGS_CACHEABLE_TRUE, 2860 NVGPU_MAP_BUFFER_FLAGS_CACHEABLE_TRUE,
2861 gk20a_mem_flag_none, true, mem->aperture); 2861 gk20a_mem_flag_none, true, mem->aperture);
2862 if (!gpu_va) 2862 if (!gpu_va)
@@ -2866,7 +2866,7 @@ static int gr_gk20a_map_global_ctx_buffers(struct gk20a *g,
2866 2866
2867 /* Golden Image */ 2867 /* Golden Image */
2868 mem = &gr->global_ctx_buffer[GOLDEN_CTX].mem; 2868 mem = &gr->global_ctx_buffer[GOLDEN_CTX].mem;
2869 gpu_va = gk20a_gmmu_map(ch_vm, &mem->priv.sgt, mem->size, 0, 2869 gpu_va = nvgpu_gmmu_map(ch_vm, mem, mem->size, 0,
2870 gk20a_mem_flag_none, true, mem->aperture); 2870 gk20a_mem_flag_none, true, mem->aperture);
2871 if (!gpu_va) 2871 if (!gpu_va)
2872 goto clean_up; 2872 goto clean_up;
@@ -2875,7 +2875,7 @@ static int gr_gk20a_map_global_ctx_buffers(struct gk20a *g,
2875 2875
2876 /* Priv register Access Map */ 2876 /* Priv register Access Map */
2877 mem = &gr->global_ctx_buffer[PRIV_ACCESS_MAP].mem; 2877 mem = &gr->global_ctx_buffer[PRIV_ACCESS_MAP].mem;
2878 gpu_va = gk20a_gmmu_map(ch_vm, &mem->priv.sgt, mem->size, 0, 2878 gpu_va = nvgpu_gmmu_map(ch_vm, mem, mem->size, 0,
2879 gk20a_mem_flag_none, true, mem->aperture); 2879 gk20a_mem_flag_none, true, mem->aperture);
2880 if (!gpu_va) 2880 if (!gpu_va)
2881 goto clean_up; 2881 goto clean_up;
@@ -2885,12 +2885,11 @@ static int gr_gk20a_map_global_ctx_buffers(struct gk20a *g,
2885 c->ch_ctx.global_ctx_buffer_mapped = true; 2885 c->ch_ctx.global_ctx_buffer_mapped = true;
2886 return 0; 2886 return 0;
2887 2887
2888 clean_up: 2888clean_up:
2889 for (i = 0; i < NR_GLOBAL_CTX_BUF_VA; i++) { 2889 for (i = 0; i < NR_GLOBAL_CTX_BUF_VA; i++) {
2890 if (g_bfr_va[i]) { 2890 if (g_bfr_va[i]) {
2891 gk20a_gmmu_unmap(ch_vm, g_bfr_va[i], 2891 nvgpu_gmmu_unmap(ch_vm, &gr->global_ctx_buffer[i].mem,
2892 gr->global_ctx_buffer[i].mem.size, 2892 g_bfr_va[i]);
2893 gk20a_mem_flag_none);
2894 g_bfr_va[i] = 0; 2893 g_bfr_va[i] = 0;
2895 } 2894 }
2896 } 2895 }
@@ -2900,6 +2899,7 @@ static int gr_gk20a_map_global_ctx_buffers(struct gk20a *g,
2900static void gr_gk20a_unmap_global_ctx_buffers(struct channel_gk20a *c) 2899static void gr_gk20a_unmap_global_ctx_buffers(struct channel_gk20a *c)
2901{ 2900{
2902 struct vm_gk20a *ch_vm = c->vm; 2901 struct vm_gk20a *ch_vm = c->vm;
2902 struct gr_gk20a *gr = &c->g->gr;
2903 u64 *g_bfr_va = c->ch_ctx.global_ctx_buffer_va; 2903 u64 *g_bfr_va = c->ch_ctx.global_ctx_buffer_va;
2904 u64 *g_bfr_size = c->ch_ctx.global_ctx_buffer_size; 2904 u64 *g_bfr_size = c->ch_ctx.global_ctx_buffer_size;
2905 u32 i; 2905 u32 i;
@@ -2908,9 +2908,8 @@ static void gr_gk20a_unmap_global_ctx_buffers(struct channel_gk20a *c)
2908 2908
2909 for (i = 0; i < NR_GLOBAL_CTX_BUF_VA; i++) { 2909 for (i = 0; i < NR_GLOBAL_CTX_BUF_VA; i++) {
2910 if (g_bfr_va[i]) { 2910 if (g_bfr_va[i]) {
2911 gk20a_gmmu_unmap(ch_vm, g_bfr_va[i], 2911 nvgpu_gmmu_unmap(ch_vm, &gr->global_ctx_buffer[i].mem,
2912 g_bfr_size[i], 2912 g_bfr_va[i]);
2913 gk20a_mem_flag_none);
2914 g_bfr_va[i] = 0; 2913 g_bfr_va[i] = 0;
2915 g_bfr_size[i] = 0; 2914 g_bfr_size[i] = 0;
2916 } 2915 }
@@ -2946,8 +2945,8 @@ int gr_gk20a_alloc_gr_ctx(struct gk20a *g,
2946 if (err) 2945 if (err)
2947 goto err_free_ctx; 2946 goto err_free_ctx;
2948 2947
2949 gr_ctx->mem.gpu_va = gk20a_gmmu_map(vm, 2948 gr_ctx->mem.gpu_va = nvgpu_gmmu_map(vm,
2950 &gr_ctx->mem.priv.sgt, 2949 &gr_ctx->mem,
2951 gr_ctx->mem.size, 2950 gr_ctx->mem.size,
2952 NVGPU_MAP_BUFFER_FLAGS_CACHEABLE_FALSE, 2951 NVGPU_MAP_BUFFER_FLAGS_CACHEABLE_FALSE,
2953 gk20a_mem_flag_none, true, 2952 gk20a_mem_flag_none, true,
@@ -3007,8 +3006,7 @@ void gr_gk20a_free_gr_ctx(struct gk20a *g,
3007 if (!gr_ctx || !gr_ctx->mem.gpu_va) 3006 if (!gr_ctx || !gr_ctx->mem.gpu_va)
3008 return; 3007 return;
3009 3008
3010 gk20a_gmmu_unmap(vm, gr_ctx->mem.gpu_va, 3009 nvgpu_gmmu_unmap(vm, &gr_ctx->mem, gr_ctx->mem.gpu_va);
3011 gr_ctx->mem.size, gk20a_mem_flag_none);
3012 nvgpu_dma_free(g, &gr_ctx->mem); 3010 nvgpu_dma_free(g, &gr_ctx->mem);
3013 nvgpu_kfree(g, gr_ctx); 3011 nvgpu_kfree(g, gr_ctx);
3014} 3012}
@@ -3055,8 +3053,8 @@ static void gr_gk20a_free_channel_patch_ctx(struct channel_gk20a *c)
3055 gk20a_dbg_fn(""); 3053 gk20a_dbg_fn("");
3056 3054
3057 if (patch_ctx->mem.gpu_va) 3055 if (patch_ctx->mem.gpu_va)
3058 gk20a_gmmu_unmap(c->vm, patch_ctx->mem.gpu_va, 3056 nvgpu_gmmu_unmap(c->vm, &patch_ctx->mem,
3059 patch_ctx->mem.size, gk20a_mem_flag_none); 3057 patch_ctx->mem.gpu_va);
3060 3058
3061 nvgpu_dma_free(g, &patch_ctx->mem); 3059 nvgpu_dma_free(g, &patch_ctx->mem);
3062 patch_ctx->data_count = 0; 3060 patch_ctx->data_count = 0;
@@ -3070,8 +3068,7 @@ static void gr_gk20a_free_channel_pm_ctx(struct channel_gk20a *c)
3070 gk20a_dbg_fn(""); 3068 gk20a_dbg_fn("");
3071 3069
3072 if (pm_ctx->mem.gpu_va) { 3070 if (pm_ctx->mem.gpu_va) {
3073 gk20a_gmmu_unmap(c->vm, pm_ctx->mem.gpu_va, 3071 nvgpu_gmmu_unmap(c->vm, &pm_ctx->mem, pm_ctx->mem.gpu_va);
3074 pm_ctx->mem.size, gk20a_mem_flag_none);
3075 3072
3076 nvgpu_dma_free(g, &pm_ctx->mem); 3073 nvgpu_dma_free(g, &pm_ctx->mem);
3077 } 3074 }
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index d95a2cde..08c99895 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -2441,74 +2441,6 @@ int gk20a_vm_map_compbits(struct vm_gk20a *vm,
2441 return 0; 2441 return 0;
2442} 2442}
2443 2443
2444/*
2445 * Core GMMU map function for the kernel to use. If @addr is 0 then the GPU
2446 * VA will be allocated for you. If addr is non-zero then the buffer will be
2447 * mapped at @addr.
2448 */
2449static u64 __gk20a_gmmu_map(struct vm_gk20a *vm,
2450 struct sg_table **sgt,
2451 u64 addr,
2452 u64 size,
2453 u32 flags,
2454 int rw_flag,
2455 bool priv,
2456 enum nvgpu_aperture aperture)
2457{
2458 struct gk20a *g = gk20a_from_vm(vm);
2459 u64 vaddr;
2460
2461 nvgpu_mutex_acquire(&vm->update_gmmu_lock);
2462 vaddr = g->ops.mm.gmmu_map(vm, addr,
2463 *sgt, /* sg table */
2464 0, /* sg offset */
2465 size,
2466 gmmu_page_size_kernel,
2467 0, /* kind */
2468 0, /* ctag_offset */
2469 flags, rw_flag,
2470 false, /* clear_ctags */
2471 false, /* sparse */
2472 priv, /* priv */
2473 NULL, /* mapping_batch handle */
2474 aperture);
2475 nvgpu_mutex_release(&vm->update_gmmu_lock);
2476 if (!vaddr) {
2477 nvgpu_err(g, "failed to allocate va space");
2478 return 0;
2479 }
2480
2481 return vaddr;
2482}
2483
2484u64 gk20a_gmmu_map(struct vm_gk20a *vm,
2485 struct sg_table **sgt,
2486 u64 size,
2487 u32 flags,
2488 int rw_flag,
2489 bool priv,
2490 enum nvgpu_aperture aperture)
2491{
2492 return __gk20a_gmmu_map(vm, sgt, 0, size, flags, rw_flag, priv,
2493 aperture);
2494}
2495
2496/*
2497 * Like gk20a_gmmu_map() except it works on a fixed address instead.
2498 */
2499u64 gk20a_gmmu_fixed_map(struct vm_gk20a *vm,
2500 struct sg_table **sgt,
2501 u64 addr,
2502 u64 size,
2503 u32 flags,
2504 int rw_flag,
2505 bool priv,
2506 enum nvgpu_aperture aperture)
2507{
2508 return __gk20a_gmmu_map(vm, sgt, addr, size, flags, rw_flag, priv,
2509 aperture);
2510}
2511
2512#if defined(CONFIG_GK20A_VIDMEM) 2444#if defined(CONFIG_GK20A_VIDMEM)
2513static int gk20a_gmmu_clear_vidmem_mem(struct gk20a *g, struct nvgpu_mem *mem) 2445static int gk20a_gmmu_clear_vidmem_mem(struct gk20a *g, struct nvgpu_mem *mem)
2514{ 2446{
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
index 9717efff..0a102cb2 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h
@@ -509,22 +509,6 @@ bool gk20a_mm_mmu_debug_mode_enabled(struct gk20a *g);
509 509
510int gk20a_mm_mmu_vpr_info_fetch(struct gk20a *g); 510int gk20a_mm_mmu_vpr_info_fetch(struct gk20a *g);
511 511
512u64 gk20a_gmmu_map(struct vm_gk20a *vm,
513 struct sg_table **sgt,
514 u64 size,
515 u32 flags,
516 int rw_flag,
517 bool priv,
518 enum nvgpu_aperture aperture);
519u64 gk20a_gmmu_fixed_map(struct vm_gk20a *vm,
520 struct sg_table **sgt,
521 u64 addr,
522 u64 size,
523 u32 flags,
524 int rw_flag,
525 bool priv,
526 enum nvgpu_aperture aperture);
527
528static inline phys_addr_t gk20a_mem_phys(struct nvgpu_mem *mem) 512static inline phys_addr_t gk20a_mem_phys(struct nvgpu_mem *mem)
529{ 513{
530 /* FIXME: the sgt/sgl may get null if this is accessed e.g. in an isr 514 /* FIXME: the sgt/sgl may get null if this is accessed e.g. in an isr
@@ -565,11 +549,6 @@ u64 gk20a_locked_gmmu_map(struct vm_gk20a *vm,
565 struct vm_gk20a_mapping_batch *batch, 549 struct vm_gk20a_mapping_batch *batch,
566 enum nvgpu_aperture aperture); 550 enum nvgpu_aperture aperture);
567 551
568void gk20a_gmmu_unmap(struct vm_gk20a *vm,
569 u64 vaddr,
570 u64 size,
571 int rw_flag);
572
573void gk20a_locked_gmmu_unmap(struct vm_gk20a *vm, 552void gk20a_locked_gmmu_unmap(struct vm_gk20a *vm,
574 u64 vaddr, 553 u64 vaddr,
575 u64 size, 554 u64 size,
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
index 6679d905..7c56c4cc 100644
--- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
@@ -19,6 +19,7 @@
19#include <linux/platform/tegra/mc.h> 19#include <linux/platform/tegra/mc.h>
20 20
21#include <nvgpu/dma.h> 21#include <nvgpu/dma.h>
22#include <nvgpu/gmmu.h>
22#include <nvgpu/timers.h> 23#include <nvgpu/timers.h>
23#include <nvgpu/nvgpu_common.h> 24#include <nvgpu/nvgpu_common.h>
24#include <nvgpu/kmem.h> 25#include <nvgpu/kmem.h>
@@ -413,7 +414,7 @@ int prepare_ucode_blob(struct gk20a *g)
413 414
414 page = phys_to_page(wpr_addr); 415 page = phys_to_page(wpr_addr);
415 __nvgpu_mem_create_from_pages(g, &g->pmu.wpr_buf, &page, 1); 416 __nvgpu_mem_create_from_pages(g, &g->pmu.wpr_buf, &page, 1);
416 g->pmu.wpr_buf.gpu_va = gk20a_gmmu_map(vm, &g->pmu.wpr_buf.priv.sgt, 417 g->pmu.wpr_buf.gpu_va = nvgpu_gmmu_map(vm, &g->pmu.wpr_buf,
417 wprsize, 0, gk20a_mem_flag_none, 418 wprsize, 0, gk20a_mem_flag_none,
418 false, APERTURE_SYSMEM); 419 false, APERTURE_SYSMEM);
419 gm20b_dbg_pmu("wpr mapped gpu va :%llx\n", g->pmu.wpr_buf.gpu_va); 420 gm20b_dbg_pmu("wpr mapped gpu va :%llx\n", g->pmu.wpr_buf.gpu_va);
@@ -445,8 +446,7 @@ int prepare_ucode_blob(struct gk20a *g)
445 gm20b_dbg_pmu("prepare ucode blob return 0\n"); 446 gm20b_dbg_pmu("prepare ucode blob return 0\n");
446 free_acr_resources(g, plsfm); 447 free_acr_resources(g, plsfm);
447free_sgt: 448free_sgt:
448 gk20a_gmmu_unmap(vm, g->pmu.wpr_buf.gpu_va, 449 nvgpu_gmmu_unmap(vm, &g->pmu.wpr_buf, g->pmu.wpr_buf.gpu_va);
449 g->pmu.wpr_buf.size, gk20a_mem_flag_none);
450 return err; 450 return err;
451} 451}
452 452
@@ -1412,8 +1412,8 @@ int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt)
1412 goto err_done; 1412 goto err_done;
1413 } 1413 }
1414 1414
1415 acr->hsbl_ucode.gpu_va = gk20a_gmmu_map(vm, 1415 acr->hsbl_ucode.gpu_va = nvgpu_gmmu_map(vm,
1416 &acr->hsbl_ucode.priv.sgt, 1416 &acr->hsbl_ucode,
1417 bl_sz, 1417 bl_sz,
1418 0, /* flags */ 1418 0, /* flags */
1419 gk20a_mem_flag_read_only, false, 1419 gk20a_mem_flag_read_only, false,
@@ -1461,8 +1461,7 @@ int pmu_exec_gen_bl(struct gk20a *g, void *desc, u8 b_wait_for_halt)
1461 start_gm20b_pmu(g); 1461 start_gm20b_pmu(g);
1462 return 0; 1462 return 0;
1463err_unmap_bl: 1463err_unmap_bl:
1464 gk20a_gmmu_unmap(vm, acr->hsbl_ucode.gpu_va, 1464 nvgpu_gmmu_unmap(vm, &acr->hsbl_ucode, acr->hsbl_ucode.gpu_va);
1465 acr->hsbl_ucode.size, gk20a_mem_flag_none);
1466err_free_ucode: 1465err_free_ucode:
1467 nvgpu_dma_free(g, &acr->hsbl_ucode); 1466 nvgpu_dma_free(g, &acr->hsbl_ucode);
1468err_done: 1467err_done:
diff --git a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
index 855c2b14..a43252de 100644
--- a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
@@ -20,6 +20,7 @@
20 20
21#include <nvgpu/timers.h> 21#include <nvgpu/timers.h>
22#include <nvgpu/kmem.h> 22#include <nvgpu/kmem.h>
23#include <nvgpu/gmmu.h>
23#include <nvgpu/dma.h> 24#include <nvgpu/dma.h>
24#include <nvgpu/bug.h> 25#include <nvgpu/bug.h>
25 26
@@ -858,8 +859,8 @@ int gr_gp10b_alloc_buffer(struct vm_gk20a *vm, size_t size,
858 if (err) 859 if (err)
859 return err; 860 return err;
860 861
861 mem->gpu_va = gk20a_gmmu_map(vm, 862 mem->gpu_va = nvgpu_gmmu_map(vm,
862 &mem->priv.sgt, 863 mem,
863 size, 864 size,
864 NVGPU_MAP_BUFFER_FLAGS_CACHEABLE_TRUE, 865 NVGPU_MAP_BUFFER_FLAGS_CACHEABLE_TRUE,
865 gk20a_mem_flag_none, 866 gk20a_mem_flag_none,
diff --git a/drivers/gpu/nvgpu/include/nvgpu/dma.h b/drivers/gpu/nvgpu/include/nvgpu/dma.h
index 43cff215..1c6474e7 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/dma.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/dma.h
@@ -197,6 +197,11 @@ void nvgpu_dma_free(struct gk20a *g, struct nvgpu_mem *mem);
197 * Note this is different than mapping it into the CPU. This memory can be 197 * Note this is different than mapping it into the CPU. This memory can be
198 * either placed in VIDMEM or SYSMEM, which ever is more convenient for the 198 * either placed in VIDMEM or SYSMEM, which ever is more convenient for the
199 * driver. 199 * driver.
200 *
201 * Note: currently a bug exists in the nvgpu_dma_alloc_map*() routines: you
202 * cannot use nvgpu_gmmu_map() on said buffer - it will overwrite the necessary
203 * information for the DMA unmap routines to actually unmap the buffer. You
204 * will either leak mappings or see GMMU faults.
200 */ 205 */
201int nvgpu_dma_alloc_map(struct vm_gk20a *vm, size_t size, 206int nvgpu_dma_alloc_map(struct vm_gk20a *vm, size_t size,
202 struct nvgpu_mem *mem); 207 struct nvgpu_mem *mem);
diff --git a/drivers/gpu/nvgpu/include/nvgpu/gmmu.h b/drivers/gpu/nvgpu/include/nvgpu/gmmu.h
new file mode 100644
index 00000000..7fb0147e
--- /dev/null
+++ b/drivers/gpu/nvgpu/include/nvgpu/gmmu.h
@@ -0,0 +1,69 @@
1/*
2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16
17#ifndef __NVGPU_GMMU_H__
18#define __NVGPU_GMMU_H__
19
20#include <nvgpu/types.h>
21
22/*
23 * This is the GMMU API visible to blocks outside of the GMMU. Basically this
24 * API supports all the different types of mappings that might be done in the
25 * GMMU.
26 */
27
28struct vm_gk20a;
29struct nvgpu_mem;
30
31enum nvgpu_aperture;
32
33/**
34 * nvgpu_gmmu_map - Map memory into the GMMU.
35 *
36 * Kernel space.
37 */
38u64 nvgpu_gmmu_map(struct vm_gk20a *vm,
39 struct nvgpu_mem *mem,
40 u64 size,
41 u32 flags,
42 int rw_flag,
43 bool priv,
44 enum nvgpu_aperture aperture);
45
46/**
47 * nvgpu_gmmu_map_fixed - Map memory into the GMMU.
48 *
49 * Kernel space.
50 */
51u64 nvgpu_gmmu_map_fixed(struct vm_gk20a *vm,
52 struct nvgpu_mem *mem,
53 u64 addr,
54 u64 size,
55 u32 flags,
56 int rw_flag,
57 bool priv,
58 enum nvgpu_aperture aperture);
59
60/**
61 * nvgpu_gmmu_unmap - Unmap a buffer.
62 *
63 * Kernel space.
64 */
65void nvgpu_gmmu_unmap(struct vm_gk20a *vm,
66 struct nvgpu_mem *mem,
67 u64 gpu_va);
68
69#endif