From c3fa78b1d9cba28547ca59154207d434931ae746 Mon Sep 17 00:00:00 2001 From: Alex Waterman Date: Mon, 10 Apr 2017 14:04:15 -0700 Subject: gpu: nvgpu: Separate GMMU out of mm_gk20a.c Begin moving (and renaming) the GMMU code into common/mm/gmmu.c. This block of code will be responsible for handling the platform/OS independent GMMU operations. JIRA NVGPU-12 JIRA NVGPU-30 Change-Id: Ide761bab75e5d84be3dcb977c4842ae4b3a7c1b3 Signed-off-by: Alex Waterman Reviewed-on: http://git-master/r/1464083 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/linux/dma.c | 10 +-- drivers/gpu/nvgpu/common/linux/ioctl_as.c | 2 + drivers/gpu/nvgpu/common/mm/gmmu.c | 109 ++++++++++++++++++++++++++++++ drivers/gpu/nvgpu/common/semaphore.c | 20 ++---- 4 files changed, 122 insertions(+), 19 deletions(-) create mode 100644 drivers/gpu/nvgpu/common/mm/gmmu.c (limited to 'drivers/gpu/nvgpu/common') 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 @@ #include #include #include +#include #include @@ -71,7 +72,7 @@ int nvgpu_dma_alloc_flags(struct gk20a *g, unsigned long flags, size_t size, /* * 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 + * using nvgpu_gmmu_alloc_map and it's vidmem, or if there's a * difference, the user should use the flag explicitly anyway. */ 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, if (err) return err; - mem->gpu_va = gk20a_gmmu_map(vm, &mem->priv.sgt, size, 0, + mem->gpu_va = nvgpu_gmmu_map(vm, mem, size, 0, gk20a_mem_flag_none, false, mem->aperture); if (!mem->gpu_va) { @@ -315,7 +316,7 @@ int nvgpu_dma_alloc_map_flags_vid(struct vm_gk20a *vm, unsigned long flags, if (err) return err; - mem->gpu_va = gk20a_gmmu_map(vm, &mem->priv.sgt, size, 0, + mem->gpu_va = nvgpu_gmmu_map(vm, mem, size, 0, gk20a_mem_flag_none, false, mem->aperture); if (!mem->gpu_va) { @@ -420,8 +421,7 @@ void nvgpu_dma_free(struct gk20a *g, struct nvgpu_mem *mem) void nvgpu_dma_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); + nvgpu_gmmu_unmap(vm, mem, mem->gpu_va); mem->gpu_va = 0; 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 @@ #include +#include + #include "gk20a/gk20a.h" #include "ioctl_as.h" 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 @@ +/* + * 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 "gk20a/gk20a.h" +#include "gk20a/mm_gk20a.h" + +/* + * Core GMMU map function for the kernel to use. If @addr is 0 then the GPU + * VA will be allocated for you. If addr is non-zero then the buffer will be + * mapped at @addr. + */ +static u64 __nvgpu_gmmu_map(struct vm_gk20a *vm, + struct nvgpu_mem *mem, + u64 addr, + u64 size, + u32 flags, + int rw_flag, + bool priv, + enum nvgpu_aperture aperture) +{ + struct gk20a *g = gk20a_from_vm(vm); + u64 vaddr; + + struct sg_table *sgt = mem->priv.sgt; + + nvgpu_mutex_acquire(&vm->update_gmmu_lock); + vaddr = g->ops.mm.gmmu_map(vm, addr, + sgt, /* sg table */ + 0, /* sg offset */ + size, + gmmu_page_size_kernel, + 0, /* kind */ + 0, /* ctag_offset */ + flags, rw_flag, + false, /* clear_ctags */ + false, /* sparse */ + priv, /* priv */ + NULL, /* mapping_batch handle */ + aperture); + nvgpu_mutex_release(&vm->update_gmmu_lock); + if (!vaddr) { + nvgpu_err(g, "failed to allocate va space"); + return 0; + } + + return vaddr; +} + +u64 nvgpu_gmmu_map(struct vm_gk20a *vm, + struct nvgpu_mem *mem, + u64 size, + u32 flags, + int rw_flag, + bool priv, + enum nvgpu_aperture aperture) +{ + return __nvgpu_gmmu_map(vm, mem, 0, size, flags, rw_flag, priv, + aperture); +} + +/* + * Like nvgpu_gmmu_map() except it can work on a fixed address instead. + */ +u64 nvgpu_gmmu_map_fixed(struct vm_gk20a *vm, + struct nvgpu_mem *mem, + u64 addr, + u64 size, + u32 flags, + int rw_flag, + bool priv, + enum nvgpu_aperture aperture) +{ + return __nvgpu_gmmu_map(vm, mem, addr, size, flags, rw_flag, priv, + aperture); +} + +void nvgpu_gmmu_unmap(struct vm_gk20a *vm, struct nvgpu_mem *mem, u64 gpu_va) +{ + struct gk20a *g = gk20a_from_vm(vm); + + nvgpu_mutex_acquire(&vm->update_gmmu_lock); + g->ops.mm.gmmu_unmap(vm, + gpu_va, + mem->size, + gmmu_page_size_kernel, + true, /*va_allocated */ + gk20a_mem_flag_none, + false, + NULL); + + nvgpu_mutex_release(&vm->update_gmmu_lock); +} 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 @@ */ #include +#include #include #include #include @@ -197,7 +198,7 @@ int nvgpu_semaphore_pool_map(struct nvgpu_semaphore_pool *p, */ __lock_sema_sea(p->sema_sea); - addr = gk20a_gmmu_fixed_map(vm, &p->sema_sea->sea_mem.priv.sgt, + addr = nvgpu_gmmu_map_fixed(vm, &p->sema_sea->sea_mem, p->sema_sea->gpu_va, p->sema_sea->map_size, 0, gk20a_mem_flag_read_only, 0, @@ -225,7 +226,7 @@ int nvgpu_semaphore_pool_map(struct nvgpu_semaphore_pool *p, if (err) goto fail_unmap; - addr = gk20a_gmmu_map(vm, &p->rw_mem.priv.sgt, SZ_4K, 0, + addr = nvgpu_gmmu_map(vm, &p->rw_mem, SZ_4K, 0, gk20a_mem_flag_none, 0, p->rw_mem.aperture); @@ -250,10 +251,7 @@ int nvgpu_semaphore_pool_map(struct nvgpu_semaphore_pool *p, fail_free_submem: nvgpu_dma_free(pool_to_gk20a(p), &p->rw_mem); fail_unmap: - gk20a_gmmu_unmap(vm, - p->sema_sea->sea_mem.gpu_va, - p->sema_sea->map_size, - gk20a_mem_flag_none); + nvgpu_gmmu_unmap(vm, &p->sema_sea->sea_mem, p->gpu_va_ro); gpu_sema_dbg(pool_to_gk20a(p), " %d: Failed to map semaphore pool!", p->page_idx); fail_unlock: @@ -269,14 +267,8 @@ void nvgpu_semaphore_pool_unmap(struct nvgpu_semaphore_pool *p, { __lock_sema_sea(p->sema_sea); - gk20a_gmmu_unmap(vm, - p->sema_sea->sea_mem.gpu_va, - p->sema_sea->sea_mem.size, - gk20a_mem_flag_none); - gk20a_gmmu_unmap(vm, - p->rw_mem.gpu_va, - p->rw_mem.size, - gk20a_mem_flag_none); + nvgpu_gmmu_unmap(vm, &p->sema_sea->sea_mem, p->gpu_va_ro); + nvgpu_gmmu_unmap(vm, &p->rw_mem, p->gpu_va); nvgpu_dma_free(pool_to_gk20a(p), &p->rw_mem); p->gpu_va = 0; -- cgit v1.2.2