/* * 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); }