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 <sgadagottu@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1514338
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
seshendra Gadagottu
2017-07-05 22:47:20 -07:00
committed by mobile promotions
parent 017a9f5775
commit a9ce91f910
6 changed files with 36 additions and 4 deletions

View File

@@ -25,6 +25,7 @@
#include <linux/reset.h> #include <linux/reset.h>
#include <linux/platform/tegra/common.h> #include <linux/platform/tegra/common.h>
#include <nvgpu/dma.h>
#include <nvgpu/kmem.h> #include <nvgpu/kmem.h>
#include <nvgpu/nvgpu_common.h> #include <nvgpu/nvgpu_common.h>
#include <nvgpu/soc.h> #include <nvgpu/soc.h>
@@ -1026,9 +1027,16 @@ int nvgpu_remove(struct device *dev, struct class *class)
struct gk20a *g = get_gk20a(dev); struct gk20a *g = get_gk20a(dev);
struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
struct gk20a_platform *platform = gk20a_get_platform(dev); struct gk20a_platform *platform = gk20a_get_platform(dev);
int err;
gk20a_dbg_fn(""); 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) if (platform->has_cde)
gk20a_cde_destroy(l); gk20a_cde_destroy(l);
@@ -1061,7 +1069,7 @@ int nvgpu_remove(struct device *dev, struct class *class)
gk20a_dbg_fn("removed"); gk20a_dbg_fn("removed");
return 0; return err;
} }
static int __exit gk20a_remove(struct platform_device *pdev) static int __exit gk20a_remove(struct platform_device *pdev)

View File

@@ -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_mutex_acquire(&vm->update_gmmu_lock);
nvgpu_rbtree_enum_start(0, &node, vm->mapped_buffers); nvgpu_rbtree_enum_start(0, &node, vm->mapped_buffers);

View File

@@ -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", 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, 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; 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); wait_id, sp->syncpt_buf.gpu_va);
c->g->ops.fifo.add_syncpt_wait_cmd(c->g, wait_cmd, c->g->ops.fifo.add_syncpt_wait_cmd(c->g, wait_cmd,
i * wait_cmd_size, wait_id, wait_value, i * wait_cmd_size, wait_id, wait_value,
sp->syncpt_buf.gpu_va); c->vm->syncpt_ro_map_gpu_va);
} }
} }

View File

@@ -154,6 +154,9 @@ int gk20a_finalize_poweron(struct gk20a *g)
{ {
struct gk20a_platform *platform = gk20a_get_platform(dev_from_gk20a(g)); struct gk20a_platform *platform = gk20a_get_platform(dev_from_gk20a(g));
int err; int err;
#if defined(CONFIG_TEGRA_GK20A_NVHOST) && defined(CONFIG_TEGRA_19x_GPU)
u32 nr_pages;
#endif
gk20a_dbg_fn(""); 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: done:
if (err) if (err)
g->power_on = false; g->power_on = false;

View File

@@ -1293,6 +1293,7 @@ struct gk20a {
size_t syncpt_unit_size; size_t syncpt_unit_size;
u32 syncpt_size; u32 syncpt_size;
#endif #endif
struct nvgpu_mem syncpt_mem;
}; };
static inline unsigned long gk20a_get_gr_idle_timeout(struct gk20a *g) static inline unsigned long gk20a_get_gr_idle_timeout(struct gk20a *g)

View File

@@ -175,6 +175,12 @@ struct vm_gk20a {
* Each address space needs to have a semaphore pool. * Each address space needs to have a semaphore pool.
*/ */
struct nvgpu_semaphore_pool *sema_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); void nvgpu_vm_get(struct vm_gk20a *vm);