summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2018-01-16 06:07:37 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2018-02-07 18:35:47 -0500
commitf0cbe19b12524f5df6466eaf86acbfb349def6b1 (patch)
treebed8a312e29592d41d9de4afb331756c2d38fb96 /drivers/gpu
parent0c8deb74aff6d0781cdf3278f56d7bce42b16a67 (diff)
gpu: nvgpu: add user API to get read-only syncpoint address map
Add User space API NVGPU_AS_IOCTL_GET_SYNC_RO_MAP to get read-only syncpoint address map in user space We already map whole syncpoint shim to each address space with base address being vm->syncpt_ro_map_gpu_va This new API exposes this base GPU_VA address of syncpoint map, and unit size of each syncpoint to user space. User space can then calculate address of each syncpoint as syncpoint_address = base_gpu_va + (syncpoint_id * syncpoint_unit_size) Note that this syncpoint address is read_only, and should be only used for inserting semaphore acquires. Adding semaphore release with this address would result in MMU_FAULT Define new HAL g->ops.fifo.get_sync_ro_map and set this for all GPUs supported on Xavier SoC Bug 200327559 Change-Id: Ica0db48fc28fdd0ff2a5eb09574dac843dc5e4fd Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1649365 Reviewed-by: svc-mobile-coverity <svc-mobile-coverity@nvidia.com> GVS: Gerrit_Virtual_Submit Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/nvgpu/common/linux/ioctl_as.c33
-rw-r--r--drivers/gpu/nvgpu/common/linux/vgpu/gp10b/vgpu_hal_gp10b.c1
-rw-r--r--drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_fifo_gv11b.c93
-rw-r--r--drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_fifo_gv11b.h4
-rw-r--r--drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_hal_gv11b.c1
-rw-r--r--drivers/gpu/nvgpu/common/mm/vm.c2
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h2
-rw-r--r--drivers/gpu/nvgpu/gm20b/hal_gm20b.c1
-rw-r--r--drivers/gpu/nvgpu/gp106/hal_gp106.c1
-rw-r--r--drivers/gpu/nvgpu/gp10b/hal_gp10b.c1
-rw-r--r--drivers/gpu/nvgpu/gv100/hal_gv100.c1
-rw-r--r--drivers/gpu/nvgpu/gv11b/fifo_gv11b.c56
-rw-r--r--drivers/gpu/nvgpu/gv11b/fifo_gv11b.h4
-rw-r--r--drivers/gpu/nvgpu/gv11b/hal_gv11b.c1
-rw-r--r--drivers/gpu/nvgpu/include/nvgpu/vm.h2
15 files changed, 158 insertions, 45 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/ioctl_as.c b/drivers/gpu/nvgpu/common/linux/ioctl_as.c
index 8aea3d22..c5769476 100644
--- a/drivers/gpu/nvgpu/common/linux/ioctl_as.c
+++ b/drivers/gpu/nvgpu/common/linux/ioctl_as.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * GK20A Address Spaces 2 * GK20A Address Spaces
3 * 3 *
4 * Copyright (c) 2011-2017, NVIDIA CORPORATION. All rights reserved. 4 * Copyright (c) 2011-2018, NVIDIA CORPORATION. All rights reserved.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License, 7 * under the terms and conditions of the GNU General Public License,
@@ -256,6 +256,33 @@ static int gk20a_as_ioctl_get_va_regions(
256 return 0; 256 return 0;
257} 257}
258 258
259static int nvgpu_as_ioctl_get_sync_ro_map(
260 struct gk20a_as_share *as_share,
261 struct nvgpu_as_get_sync_ro_map_args *args)
262{
263#ifdef CONFIG_TEGRA_GK20A_NVHOST
264 struct vm_gk20a *vm = as_share->vm;
265 struct gk20a *g = gk20a_from_vm(vm);
266 u64 base_gpuva;
267 u32 sync_size;
268 int err = 0;
269
270 if (!g->ops.fifo.get_sync_ro_map)
271 return -EINVAL;
272
273 err = g->ops.fifo.get_sync_ro_map(vm, &base_gpuva, &sync_size);
274 if (err)
275 return err;
276
277 args->base_gpuva = base_gpuva;
278 args->sync_size = sync_size;
279
280 return err;
281#else
282 return -EINVAL;
283#endif
284}
285
259int gk20a_as_dev_open(struct inode *inode, struct file *filp) 286int gk20a_as_dev_open(struct inode *inode, struct file *filp)
260{ 287{
261 struct nvgpu_os_linux *l; 288 struct nvgpu_os_linux *l;
@@ -367,6 +394,10 @@ long gk20a_as_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
367 err = gk20a_as_ioctl_map_buffer_batch(as_share, 394 err = gk20a_as_ioctl_map_buffer_batch(as_share,
368 (struct nvgpu_as_map_buffer_batch_args *)buf); 395 (struct nvgpu_as_map_buffer_batch_args *)buf);
369 break; 396 break;
397 case NVGPU_AS_IOCTL_GET_SYNC_RO_MAP:
398 err = nvgpu_as_ioctl_get_sync_ro_map(as_share,
399 (struct nvgpu_as_get_sync_ro_map_args *)buf);
400 break;
370 default: 401 default:
371 err = -ENOTTY; 402 err = -ENOTTY;
372 break; 403 break;
diff --git a/drivers/gpu/nvgpu/common/linux/vgpu/gp10b/vgpu_hal_gp10b.c b/drivers/gpu/nvgpu/common/linux/vgpu/gp10b/vgpu_hal_gp10b.c
index 164ac3d2..39b92263 100644
--- a/drivers/gpu/nvgpu/common/linux/vgpu/gp10b/vgpu_hal_gp10b.c
+++ b/drivers/gpu/nvgpu/common/linux/vgpu/gp10b/vgpu_hal_gp10b.c
@@ -341,6 +341,7 @@ static const struct gpu_ops vgpu_gp10b_ops = {
341 .get_syncpt_wait_cmd_size = gk20a_fifo_get_syncpt_wait_cmd_size, 341 .get_syncpt_wait_cmd_size = gk20a_fifo_get_syncpt_wait_cmd_size,
342 .add_syncpt_incr_cmd = gk20a_fifo_add_syncpt_incr_cmd, 342 .add_syncpt_incr_cmd = gk20a_fifo_add_syncpt_incr_cmd,
343 .get_syncpt_incr_cmd_size = gk20a_fifo_get_syncpt_incr_cmd_size, 343 .get_syncpt_incr_cmd_size = gk20a_fifo_get_syncpt_incr_cmd_size,
344 .get_sync_ro_map = NULL,
344#endif 345#endif
345 .resetup_ramfc = NULL, 346 .resetup_ramfc = NULL,
346 .device_info_fault_id = top_device_info_data_fault_id_enum_v, 347 .device_info_fault_id = top_device_info_data_fault_id_enum_v,
diff --git a/drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_fifo_gv11b.c b/drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_fifo_gv11b.c
index 134ca67a..af25e486 100644
--- a/drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_fifo_gv11b.c
+++ b/drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_fifo_gv11b.c
@@ -23,12 +23,52 @@
23#include <linux/tegra_vgpu.h> 23#include <linux/tegra_vgpu.h>
24 24
25#ifdef CONFIG_TEGRA_GK20A_NVHOST 25#ifdef CONFIG_TEGRA_GK20A_NVHOST
26
27static int set_syncpt_ro_map_gpu_va_locked(struct vm_gk20a *vm)
28{
29 int err;
30 struct gk20a *g = gk20a_from_vm(vm);
31 struct tegra_vgpu_cmd_msg msg = {};
32 struct tegra_vgpu_map_syncpt_params *p = &msg.params.map_syncpt;
33
34 if (vm->syncpt_ro_map_gpu_va)
35 return 0;
36
37 vm->syncpt_ro_map_gpu_va = __nvgpu_vm_alloc_va(vm,
38 g->syncpt_unit_size,
39 gmmu_page_size_kernel);
40 if (!vm->syncpt_ro_map_gpu_va) {
41 nvgpu_err(g, "allocating read-only va space failed");
42 return -ENOMEM;
43 }
44
45 msg.cmd = TEGRA_VGPU_CMD_MAP_SYNCPT;
46 msg.handle = vgpu_get_handle(g);
47 p->as_handle = vm->handle;
48 p->gpu_va = vm->syncpt_ro_map_gpu_va;
49 p->len = g->syncpt_unit_size;
50 p->offset = 0;
51 p->prot = TEGRA_VGPU_MAP_PROT_READ_ONLY;
52 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
53 err = err ? err : msg.ret;
54 if (err) {
55 nvgpu_err(g,
56 "mapping read-only va space failed err %d",
57 err);
58 __nvgpu_vm_free_va(vm, vm->syncpt_ro_map_gpu_va,
59 gmmu_page_size_kernel);
60 vm->syncpt_ro_map_gpu_va = 0;
61 return err;
62 }
63
64 return 0;
65}
66
26int vgpu_gv11b_fifo_alloc_syncpt_buf(struct channel_gk20a *c, 67int vgpu_gv11b_fifo_alloc_syncpt_buf(struct channel_gk20a *c,
27 u32 syncpt_id, struct nvgpu_mem *syncpt_buf) 68 u32 syncpt_id, struct nvgpu_mem *syncpt_buf)
28{ 69{
29 int err; 70 int err;
30 struct gk20a *g = c->g; 71 struct gk20a *g = c->g;
31 struct vm_gk20a *vm = c->vm;
32 struct tegra_vgpu_cmd_msg msg = {}; 72 struct tegra_vgpu_cmd_msg msg = {};
33 struct tegra_vgpu_map_syncpt_params *p = &msg.params.map_syncpt; 73 struct tegra_vgpu_map_syncpt_params *p = &msg.params.map_syncpt;
34 74
@@ -37,34 +77,11 @@ int vgpu_gv11b_fifo_alloc_syncpt_buf(struct channel_gk20a *c,
37 * All channels sharing same vm will share same ro mapping. 77 * All channels sharing same vm will share same ro mapping.
38 * Create rw map for current channel sync point. 78 * Create rw map for current channel sync point.
39 */ 79 */
40 if (!vm->syncpt_ro_map_gpu_va) { 80 nvgpu_mutex_acquire(&c->vm->syncpt_ro_map_lock);
41 vm->syncpt_ro_map_gpu_va = __nvgpu_vm_alloc_va(vm, 81 err = set_syncpt_ro_map_gpu_va_locked(c->vm);
42 g->syncpt_unit_size, 82 nvgpu_mutex_release(&c->vm->syncpt_ro_map_lock);
43 gmmu_page_size_kernel); 83 if (err)
44 if (!vm->syncpt_ro_map_gpu_va) { 84 return err;
45 nvgpu_err(g, "allocating read-only va space failed");
46 return -ENOMEM;
47 }
48
49 msg.cmd = TEGRA_VGPU_CMD_MAP_SYNCPT;
50 msg.handle = vgpu_get_handle(g);
51 p->as_handle = c->vm->handle;
52 p->gpu_va = vm->syncpt_ro_map_gpu_va;
53 p->len = g->syncpt_unit_size;
54 p->offset = 0;
55 p->prot = TEGRA_VGPU_MAP_PROT_READ_ONLY;
56 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
57 err = err ? err : msg.ret;
58 if (err) {
59 nvgpu_err(g,
60 "mapping read-only va space failed err %d",
61 err);
62 __nvgpu_vm_free_va(c->vm, vm->syncpt_ro_map_gpu_va,
63 gmmu_page_size_kernel);
64 vm->syncpt_ro_map_gpu_va = 0;
65 return err;
66 }
67 }
68 85
69 syncpt_buf->gpu_va = __nvgpu_vm_alloc_va(c->vm, g->syncpt_size, 86 syncpt_buf->gpu_va = __nvgpu_vm_alloc_va(c->vm, g->syncpt_size,
70 gmmu_page_size_kernel); 87 gmmu_page_size_kernel);
@@ -92,6 +109,24 @@ int vgpu_gv11b_fifo_alloc_syncpt_buf(struct channel_gk20a *c,
92 109
93 return 0; 110 return 0;
94} 111}
112
113int vgpu_gv11b_fifo_get_sync_ro_map(struct vm_gk20a *vm,
114 u64 *base_gpuva, u32 *sync_size)
115{
116 struct gk20a *g = gk20a_from_vm(vm);
117 int err;
118
119 nvgpu_mutex_acquire(&vm->syncpt_ro_map_lock);
120 err = set_syncpt_ro_map_gpu_va_locked(vm);
121 nvgpu_mutex_release(&vm->syncpt_ro_map_lock);
122 if (err)
123 return err;
124
125 *base_gpuva = vm->syncpt_ro_map_gpu_va;
126 *sync_size = g->syncpt_size;
127
128 return 0;
129}
95#endif /* CONFIG_TEGRA_GK20A_NVHOST */ 130#endif /* CONFIG_TEGRA_GK20A_NVHOST */
96 131
97int vgpu_gv11b_init_fifo_setup_hw(struct gk20a *g) 132int vgpu_gv11b_init_fifo_setup_hw(struct gk20a *g)
diff --git a/drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_fifo_gv11b.h b/drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_fifo_gv11b.h
index c2e75680..66f482af 100644
--- a/drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_fifo_gv11b.h
+++ b/drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_fifo_gv11b.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. 2 * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 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, 5 * under the terms and conditions of the GNU General Public License,
@@ -22,4 +22,6 @@ struct gk20a;
22int vgpu_gv11b_init_fifo_setup_hw(struct gk20a *g); 22int vgpu_gv11b_init_fifo_setup_hw(struct gk20a *g);
23int vgpu_gv11b_fifo_alloc_syncpt_buf(struct channel_gk20a *c, 23int vgpu_gv11b_fifo_alloc_syncpt_buf(struct channel_gk20a *c,
24 u32 syncpt_id, struct nvgpu_mem *syncpt_buf); 24 u32 syncpt_id, struct nvgpu_mem *syncpt_buf);
25int vgpu_gv11b_fifo_get_sync_ro_map(struct vm_gk20a *vm,
26 u64 *base_gpuva, u32 *sync_size);
25#endif 27#endif
diff --git a/drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_hal_gv11b.c b/drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_hal_gv11b.c
index 8669bf0d..b9e44b03 100644
--- a/drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_hal_gv11b.c
+++ b/drivers/gpu/nvgpu/common/linux/vgpu/gv11b/vgpu_hal_gv11b.c
@@ -385,6 +385,7 @@ static const struct gpu_ops vgpu_gv11b_ops = {
385 .get_syncpt_wait_cmd_size = gv11b_fifo_get_syncpt_wait_cmd_size, 385 .get_syncpt_wait_cmd_size = gv11b_fifo_get_syncpt_wait_cmd_size,
386 .add_syncpt_incr_cmd = gv11b_fifo_add_syncpt_incr_cmd, 386 .add_syncpt_incr_cmd = gv11b_fifo_add_syncpt_incr_cmd,
387 .get_syncpt_incr_cmd_size = gv11b_fifo_get_syncpt_incr_cmd_size, 387 .get_syncpt_incr_cmd_size = gv11b_fifo_get_syncpt_incr_cmd_size,
388 .get_sync_ro_map = vgpu_gv11b_fifo_get_sync_ro_map,
388#endif 389#endif
389 .resetup_ramfc = NULL, 390 .resetup_ramfc = NULL,
390 .reschedule_runlist = NULL, 391 .reschedule_runlist = NULL,
diff --git a/drivers/gpu/nvgpu/common/mm/vm.c b/drivers/gpu/nvgpu/common/mm/vm.c
index f2d04dab..e5ad22f3 100644
--- a/drivers/gpu/nvgpu/common/mm/vm.c
+++ b/drivers/gpu/nvgpu/common/mm/vm.c
@@ -459,6 +459,7 @@ int __nvgpu_vm_init(struct mm_gk20a *mm,
459 459
460 vm->mapped_buffers = NULL; 460 vm->mapped_buffers = NULL;
461 461
462 nvgpu_mutex_init(&vm->syncpt_ro_map_lock);
462 nvgpu_mutex_init(&vm->update_gmmu_lock); 463 nvgpu_mutex_init(&vm->update_gmmu_lock);
463 nvgpu_ref_init(&vm->ref); 464 nvgpu_ref_init(&vm->ref);
464 nvgpu_init_list_node(&vm->vm_area_list); 465 nvgpu_init_list_node(&vm->vm_area_list);
@@ -614,6 +615,7 @@ static void __nvgpu_vm_remove(struct vm_gk20a *vm)
614 615
615 nvgpu_mutex_release(&vm->update_gmmu_lock); 616 nvgpu_mutex_release(&vm->update_gmmu_lock);
616 617
618 nvgpu_mutex_destroy(&vm->syncpt_ro_map_lock);
617 nvgpu_kfree(g, vm); 619 nvgpu_kfree(g, vm);
618} 620}
619 621
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 5e46344a..02c7d0d9 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -617,6 +617,8 @@ struct gpu_ops {
617 bool wfi_cmd, struct priv_cmd_entry *cmd, 617 bool wfi_cmd, struct priv_cmd_entry *cmd,
618 u32 id, u64 gpu_va); 618 u32 id, u64 gpu_va);
619 u32 (*get_syncpt_incr_cmd_size)(bool wfi_cmd); 619 u32 (*get_syncpt_incr_cmd_size)(bool wfi_cmd);
620 int (*get_sync_ro_map)(struct vm_gk20a *vm,
621 u64 *base_gpuva, u32 *sync_size);
620#endif 622#endif
621 } fifo; 623 } fifo;
622 struct pmu_v { 624 struct pmu_v {
diff --git a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c
index 58367bcb..b3efdc8a 100644
--- a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c
@@ -436,6 +436,7 @@ static const struct gpu_ops gm20b_ops = {
436 .get_syncpt_wait_cmd_size = gk20a_fifo_get_syncpt_wait_cmd_size, 436 .get_syncpt_wait_cmd_size = gk20a_fifo_get_syncpt_wait_cmd_size,
437 .add_syncpt_incr_cmd = gk20a_fifo_add_syncpt_incr_cmd, 437 .add_syncpt_incr_cmd = gk20a_fifo_add_syncpt_incr_cmd,
438 .get_syncpt_incr_cmd_size = gk20a_fifo_get_syncpt_incr_cmd_size, 438 .get_syncpt_incr_cmd_size = gk20a_fifo_get_syncpt_incr_cmd_size,
439 .get_sync_ro_map = NULL,
439#endif 440#endif
440 }, 441 },
441 .gr_ctx = { 442 .gr_ctx = {
diff --git a/drivers/gpu/nvgpu/gp106/hal_gp106.c b/drivers/gpu/nvgpu/gp106/hal_gp106.c
index 77a1b8f6..502a6778 100644
--- a/drivers/gpu/nvgpu/gp106/hal_gp106.c
+++ b/drivers/gpu/nvgpu/gp106/hal_gp106.c
@@ -496,6 +496,7 @@ static const struct gpu_ops gp106_ops = {
496 .get_syncpt_wait_cmd_size = gk20a_fifo_get_syncpt_wait_cmd_size, 496 .get_syncpt_wait_cmd_size = gk20a_fifo_get_syncpt_wait_cmd_size,
497 .add_syncpt_incr_cmd = gk20a_fifo_add_syncpt_incr_cmd, 497 .add_syncpt_incr_cmd = gk20a_fifo_add_syncpt_incr_cmd,
498 .get_syncpt_incr_cmd_size = gk20a_fifo_get_syncpt_incr_cmd_size, 498 .get_syncpt_incr_cmd_size = gk20a_fifo_get_syncpt_incr_cmd_size,
499 .get_sync_ro_map = NULL,
499#endif 500#endif
500 .resetup_ramfc = gp10b_fifo_resetup_ramfc, 501 .resetup_ramfc = gp10b_fifo_resetup_ramfc,
501 .device_info_fault_id = top_device_info_data_fault_id_enum_v, 502 .device_info_fault_id = top_device_info_data_fault_id_enum_v,
diff --git a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c
index 462943a0..91ebab55 100644
--- a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c
@@ -469,6 +469,7 @@ static const struct gpu_ops gp10b_ops = {
469 .get_syncpt_wait_cmd_size = gk20a_fifo_get_syncpt_wait_cmd_size, 469 .get_syncpt_wait_cmd_size = gk20a_fifo_get_syncpt_wait_cmd_size,
470 .add_syncpt_incr_cmd = gk20a_fifo_add_syncpt_incr_cmd, 470 .add_syncpt_incr_cmd = gk20a_fifo_add_syncpt_incr_cmd,
471 .get_syncpt_incr_cmd_size = gk20a_fifo_get_syncpt_incr_cmd_size, 471 .get_syncpt_incr_cmd_size = gk20a_fifo_get_syncpt_incr_cmd_size,
472 .get_sync_ro_map = NULL,
472#endif 473#endif
473 .resetup_ramfc = gp10b_fifo_resetup_ramfc, 474 .resetup_ramfc = gp10b_fifo_resetup_ramfc,
474 .device_info_fault_id = top_device_info_data_fault_id_enum_v, 475 .device_info_fault_id = top_device_info_data_fault_id_enum_v,
diff --git a/drivers/gpu/nvgpu/gv100/hal_gv100.c b/drivers/gpu/nvgpu/gv100/hal_gv100.c
index f75e6ff9..c39b3444 100644
--- a/drivers/gpu/nvgpu/gv100/hal_gv100.c
+++ b/drivers/gpu/nvgpu/gv100/hal_gv100.c
@@ -511,6 +511,7 @@ static const struct gpu_ops gv100_ops = {
511 .get_syncpt_wait_cmd_size = gv11b_fifo_get_syncpt_wait_cmd_size, 511 .get_syncpt_wait_cmd_size = gv11b_fifo_get_syncpt_wait_cmd_size,
512 .add_syncpt_incr_cmd = gv11b_fifo_add_syncpt_incr_cmd, 512 .add_syncpt_incr_cmd = gv11b_fifo_add_syncpt_incr_cmd,
513 .get_syncpt_incr_cmd_size = gv11b_fifo_get_syncpt_incr_cmd_size, 513 .get_syncpt_incr_cmd_size = gv11b_fifo_get_syncpt_incr_cmd_size,
514 .get_sync_ro_map = gv11b_fifo_get_sync_ro_map,
514#endif 515#endif
515 .resetup_ramfc = NULL, 516 .resetup_ramfc = NULL,
516 .device_info_fault_id = top_device_info_data_fault_id_enum_v, 517 .device_info_fault_id = top_device_info_data_fault_id_enum_v,
diff --git a/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c b/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c
index 271dcc41..41d14a82 100644
--- a/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c
+++ b/drivers/gpu/nvgpu/gv11b/fifo_gv11b.c
@@ -1657,31 +1657,43 @@ void gv11b_fifo_deinit_eng_method_buffers(struct gk20a *g,
1657} 1657}
1658 1658
1659#ifdef CONFIG_TEGRA_GK20A_NVHOST 1659#ifdef CONFIG_TEGRA_GK20A_NVHOST
1660static int set_syncpt_ro_map_gpu_va_locked(struct vm_gk20a *vm)
1661{
1662 struct gk20a *g = gk20a_from_vm(vm);
1663
1664 if (vm->syncpt_ro_map_gpu_va)
1665 return 0;
1666
1667 vm->syncpt_ro_map_gpu_va = nvgpu_gmmu_map(vm,
1668 &g->syncpt_mem, g->syncpt_unit_size,
1669 0, gk20a_mem_flag_read_only,
1670 false, APERTURE_SYSMEM);
1671
1672 if (!vm->syncpt_ro_map_gpu_va) {
1673 nvgpu_err(g, "failed to ro map syncpt buffer");
1674 return -ENOMEM;
1675 }
1676
1677 return 0;
1678}
1679
1660int gv11b_fifo_alloc_syncpt_buf(struct channel_gk20a *c, 1680int gv11b_fifo_alloc_syncpt_buf(struct channel_gk20a *c,
1661 u32 syncpt_id, struct nvgpu_mem *syncpt_buf) 1681 u32 syncpt_id, struct nvgpu_mem *syncpt_buf)
1662{ 1682{
1663 u32 nr_pages; 1683 u32 nr_pages;
1664 int err = 0; 1684 int err = 0;
1665 struct gk20a *g = c->g; 1685 struct gk20a *g = c->g;
1666 struct vm_gk20a *vm = c->vm;
1667 1686
1668 /* 1687 /*
1669 * Add ro map for complete sync point shim range in vm 1688 * Add ro map for complete sync point shim range in vm
1670 * All channels sharing same vm will share same ro mapping. 1689 * All channels sharing same vm will share same ro mapping.
1671 * Create rw map for current channel sync point 1690 * Create rw map for current channel sync point
1672 */ 1691 */
1673 if (!vm->syncpt_ro_map_gpu_va) { 1692 nvgpu_mutex_acquire(&c->vm->syncpt_ro_map_lock);
1674 vm->syncpt_ro_map_gpu_va = nvgpu_gmmu_map(c->vm, 1693 err = set_syncpt_ro_map_gpu_va_locked(c->vm);
1675 &g->syncpt_mem, g->syncpt_unit_size, 1694 nvgpu_mutex_release(&c->vm->syncpt_ro_map_lock);
1676 0, gk20a_mem_flag_read_only, 1695 if (err)
1677 false, APERTURE_SYSMEM); 1696 return err;
1678
1679 if (!vm->syncpt_ro_map_gpu_va) {
1680 nvgpu_err(g, "failed to ro map syncpt buffer");
1681 nvgpu_dma_free(g, &g->syncpt_mem);
1682 err = -ENOMEM;
1683 }
1684 }
1685 1697
1686 nr_pages = DIV_ROUND_UP(g->syncpt_size, PAGE_SIZE); 1698 nr_pages = DIV_ROUND_UP(g->syncpt_size, PAGE_SIZE);
1687 __nvgpu_mem_create_from_phys(g, syncpt_buf, 1699 __nvgpu_mem_create_from_phys(g, syncpt_buf,
@@ -1707,6 +1719,24 @@ void gv11b_fifo_free_syncpt_buf(struct channel_gk20a *c,
1707 nvgpu_dma_free(c->g, syncpt_buf); 1719 nvgpu_dma_free(c->g, syncpt_buf);
1708} 1720}
1709 1721
1722int gv11b_fifo_get_sync_ro_map(struct vm_gk20a *vm,
1723 u64 *base_gpuva, u32 *sync_size)
1724{
1725 struct gk20a *g = gk20a_from_vm(vm);
1726 int err;
1727
1728 nvgpu_mutex_acquire(&vm->syncpt_ro_map_lock);
1729 err = set_syncpt_ro_map_gpu_va_locked(vm);
1730 nvgpu_mutex_release(&vm->syncpt_ro_map_lock);
1731 if (err)
1732 return err;
1733
1734 *base_gpuva = vm->syncpt_ro_map_gpu_va;
1735 *sync_size = g->syncpt_size;
1736
1737 return 0;
1738}
1739
1710void gv11b_fifo_add_syncpt_wait_cmd(struct gk20a *g, 1740void gv11b_fifo_add_syncpt_wait_cmd(struct gk20a *g,
1711 struct priv_cmd_entry *cmd, u32 off, 1741 struct priv_cmd_entry *cmd, u32 off,
1712 u32 id, u32 thresh, u64 gpu_va_base) 1742 u32 id, u32 thresh, u64 gpu_va_base)
diff --git a/drivers/gpu/nvgpu/gv11b/fifo_gv11b.h b/drivers/gpu/nvgpu/gv11b/fifo_gv11b.h
index fc1ddf83..c0e6e5cd 100644
--- a/drivers/gpu/nvgpu/gv11b/fifo_gv11b.h
+++ b/drivers/gpu/nvgpu/gv11b/fifo_gv11b.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * GV11B Fifo 2 * GV11B Fifo
3 * 3 *
4 * Copyright (c) 2016-2017, NVIDIA CORPORATION. All rights reserved. 4 * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved.
5 * 5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a 6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"), 7 * copy of this software and associated documentation files (the "Software"),
@@ -102,6 +102,8 @@ int gv11b_fifo_alloc_syncpt_buf(struct channel_gk20a *c,
102 u32 syncpt_id, struct nvgpu_mem *syncpt_buf); 102 u32 syncpt_id, struct nvgpu_mem *syncpt_buf);
103void gv11b_fifo_free_syncpt_buf(struct channel_gk20a *c, 103void gv11b_fifo_free_syncpt_buf(struct channel_gk20a *c,
104 struct nvgpu_mem *syncpt_buf); 104 struct nvgpu_mem *syncpt_buf);
105int gv11b_fifo_get_sync_ro_map(struct vm_gk20a *vm,
106 u64 *base_gpuva, u32 *sync_size);
105void gv11b_fifo_add_syncpt_wait_cmd(struct gk20a *g, 107void gv11b_fifo_add_syncpt_wait_cmd(struct gk20a *g,
106 struct priv_cmd_entry *cmd, u32 off, 108 struct priv_cmd_entry *cmd, u32 off,
107 u32 id, u32 thresh, u64 gpu_va_base); 109 u32 id, u32 thresh, u64 gpu_va_base);
diff --git a/drivers/gpu/nvgpu/gv11b/hal_gv11b.c b/drivers/gpu/nvgpu/gv11b/hal_gv11b.c
index 91d80080..72537b44 100644
--- a/drivers/gpu/nvgpu/gv11b/hal_gv11b.c
+++ b/drivers/gpu/nvgpu/gv11b/hal_gv11b.c
@@ -534,6 +534,7 @@ static const struct gpu_ops gv11b_ops = {
534 .get_syncpt_wait_cmd_size = gv11b_fifo_get_syncpt_wait_cmd_size, 534 .get_syncpt_wait_cmd_size = gv11b_fifo_get_syncpt_wait_cmd_size,
535 .add_syncpt_incr_cmd = gv11b_fifo_add_syncpt_incr_cmd, 535 .add_syncpt_incr_cmd = gv11b_fifo_add_syncpt_incr_cmd,
536 .get_syncpt_incr_cmd_size = gv11b_fifo_get_syncpt_incr_cmd_size, 536 .get_syncpt_incr_cmd_size = gv11b_fifo_get_syncpt_incr_cmd_size,
537 .get_sync_ro_map = gv11b_fifo_get_sync_ro_map,
537#endif 538#endif
538 .resetup_ramfc = NULL, 539 .resetup_ramfc = NULL,
539 .device_info_fault_id = top_device_info_data_fault_id_enum_v, 540 .device_info_fault_id = top_device_info_data_fault_id_enum_v,
diff --git a/drivers/gpu/nvgpu/include/nvgpu/vm.h b/drivers/gpu/nvgpu/include/nvgpu/vm.h
index e5d0e197..a5a358ea 100644
--- a/drivers/gpu/nvgpu/include/nvgpu/vm.h
+++ b/drivers/gpu/nvgpu/include/nvgpu/vm.h
@@ -198,6 +198,8 @@ struct vm_gk20a {
198 * Channels sharing same vm will also share same sync point ro map 198 * Channels sharing same vm will also share same sync point ro map
199 */ 199 */
200 u64 syncpt_ro_map_gpu_va; 200 u64 syncpt_ro_map_gpu_va;
201 /* Protect allocation of sync point map */
202 struct nvgpu_mutex syncpt_ro_map_lock;
201}; 203};
202 204
203/* 205/*