From a9ce91f910ca730a3abadb9e7491e3504af30d86 Mon Sep 17 00:00:00 2001 From: seshendra Gadagottu Date: Wed, 5 Jul 2017 22:47:20 -0700 Subject: [PATCH] gpu: nvgpu: add syncpoint read map For sync-point read map: 1. Added nvgpu_mem memory allocator in gk20a struct and allocated memory for this in gk20a_finalize_poweron() and freed this memory in gk20a_remove(). 2. Added "u64 syncpt_ro_map_gpu_va" in vm_gk20a struct for read map in vm. Added nvgpu_quiesce() in nvgpu_remove() before freeing syncpoint read map to ensure that nvgpu is idle. JIRA GPUT19X-2 Change-Id: I7cbfec57f0992682dd833a1b0d92d694bcaf1eb3 Signed-off-by: seshendra Gadagottu Reviewed-on: https://git-master.nvidia.com/r/1514338 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/linux/module.c | 10 +++++++++- drivers/gpu/nvgpu/common/mm/vm.c | 6 ++++++ drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c | 6 +++--- drivers/gpu/nvgpu/gk20a/gk20a.c | 11 +++++++++++ drivers/gpu/nvgpu/gk20a/gk20a.h | 1 + drivers/gpu/nvgpu/include/nvgpu/vm.h | 6 ++++++ 6 files changed, 36 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/nvgpu/common/linux/module.c b/drivers/gpu/nvgpu/common/linux/module.c index ac64041e5..52f987b26 100644 --- a/drivers/gpu/nvgpu/common/linux/module.c +++ b/drivers/gpu/nvgpu/common/linux/module.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -1026,9 +1027,16 @@ int nvgpu_remove(struct device *dev, struct class *class) struct gk20a *g = get_gk20a(dev); struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); struct gk20a_platform *platform = gk20a_get_platform(dev); + int err; gk20a_dbg_fn(""); + err = nvgpu_quiesce(g); + WARN(err, "gpu failed to idle during driver removal"); + + if (nvgpu_mem_is_valid(&g->syncpt_mem)) + nvgpu_dma_free(g, &g->syncpt_mem); + if (platform->has_cde) gk20a_cde_destroy(l); @@ -1061,7 +1069,7 @@ int nvgpu_remove(struct device *dev, struct class *class) gk20a_dbg_fn("removed"); - return 0; + return err; } static int __exit gk20a_remove(struct platform_device *pdev) diff --git a/drivers/gpu/nvgpu/common/mm/vm.c b/drivers/gpu/nvgpu/common/mm/vm.c index 354d6ce46..f8d583494 100644 --- a/drivers/gpu/nvgpu/common/mm/vm.c +++ b/drivers/gpu/nvgpu/common/mm/vm.c @@ -527,6 +527,12 @@ static void __nvgpu_vm_remove(struct vm_gk20a *vm) } } +#if defined(CONFIG_TEGRA_GK20A_NVHOST) && defined(CONFIG_TEGRA_19x_GPU) + if (nvgpu_mem_is_valid(&g->syncpt_mem) && vm->syncpt_ro_map_gpu_va) + nvgpu_gmmu_unmap(vm, &g->syncpt_mem, + vm->syncpt_ro_map_gpu_va); +#endif + nvgpu_mutex_acquire(&vm->update_gmmu_lock); nvgpu_rbtree_enum_start(0, &node, vm->mapped_buffers); diff --git a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c index 380ea0488..d83684e47 100644 --- a/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/channel_sync_gk20a.c @@ -76,9 +76,9 @@ static int gk20a_channel_syncpt_wait_syncpt(struct gk20a_channel_sync *s, } nvgpu_log(c->g, gpu_dbg_info, "sp->id %d gpu va %llx", - id, sp->syncpt_buf.gpu_va); + id, sp->c->vm->syncpt_ro_map_gpu_va); c->g->ops.fifo.add_syncpt_wait_cmd(c->g, wait_cmd, 0, id, - thresh, sp->syncpt_buf.gpu_va); + thresh, c->vm->syncpt_ro_map_gpu_va); return 0; } @@ -147,7 +147,7 @@ static int gk20a_channel_syncpt_wait_fd(struct gk20a_channel_sync *s, int fd, wait_id, sp->syncpt_buf.gpu_va); c->g->ops.fifo.add_syncpt_wait_cmd(c->g, wait_cmd, i * wait_cmd_size, wait_id, wait_value, - sp->syncpt_buf.gpu_va); + c->vm->syncpt_ro_map_gpu_va); } } diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index d1ad5992a..cac62db7d 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c @@ -154,6 +154,9 @@ int gk20a_finalize_poweron(struct gk20a *g) { struct gk20a_platform *platform = gk20a_get_platform(dev_from_gk20a(g)); int err; +#if defined(CONFIG_TEGRA_GK20A_NVHOST) && defined(CONFIG_TEGRA_19x_GPU) + u32 nr_pages; +#endif gk20a_dbg_fn(""); @@ -346,6 +349,14 @@ int gk20a_finalize_poweron(struct gk20a *g) } } +#if defined(CONFIG_TEGRA_GK20A_NVHOST) && defined(CONFIG_TEGRA_19x_GPU) + if (gk20a_platform_has_syncpoints(g) && g->syncpt_unit_size) { + nr_pages = DIV_ROUND_UP(g->syncpt_unit_size, PAGE_SIZE); + __nvgpu_mem_create_from_phys(g, &g->syncpt_mem, + g->syncpt_unit_base, nr_pages); + } +#endif + done: if (err) g->power_on = false; diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h index 72e47ec64..a45a7b4e6 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/gk20a.h @@ -1293,6 +1293,7 @@ struct gk20a { size_t syncpt_unit_size; u32 syncpt_size; #endif + struct nvgpu_mem syncpt_mem; }; static inline unsigned long gk20a_get_gr_idle_timeout(struct gk20a *g) diff --git a/drivers/gpu/nvgpu/include/nvgpu/vm.h b/drivers/gpu/nvgpu/include/nvgpu/vm.h index 4c5d3232d..f88680651 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/vm.h +++ b/drivers/gpu/nvgpu/include/nvgpu/vm.h @@ -175,6 +175,12 @@ struct vm_gk20a { * Each address space needs to have a semaphore pool. */ struct nvgpu_semaphore_pool *sema_pool; + + /* + * Create sync point read only map for sync point range. + * Channels sharing same vm will also share same sync point ro map + */ + u64 syncpt_ro_map_gpu_va; }; void nvgpu_vm_get(struct vm_gk20a *vm);