/* * drivers/video/tegra/host/nvhost_memmgr.c * * Tegra Graphics Host Memory Management Abstraction * * Copyright (c) 2012-2014, 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 #include #include "nvhost_memmgr.h" #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP #include "nvmap.h" #include #endif #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF #include "dmabuf.h" #endif #include "chip_support.h" struct mem_mgr *nvhost_memmgr_alloc_mgr(void) { struct mem_mgr *mgr = NULL; #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP mgr = nvhost_nvmap_alloc_mgr(); #else #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF mgr = (struct mem_mgr *)1; #endif #endif return mgr; } void nvhost_memmgr_put_mgr(struct mem_mgr *mgr) { #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP nvhost_nvmap_put_mgr(mgr); #else #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF mgr = (struct mem_mgr *)1; #endif #endif } struct mem_mgr *nvhost_memmgr_get_mgr(struct mem_mgr *_mgr) { struct mem_mgr *mgr = NULL; #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP mgr = nvhost_nvmap_get_mgr(_mgr); #else #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF mgr = (struct mem_mgr *)1; #endif #endif return mgr; } struct mem_mgr *nvhost_memmgr_get_mgr_file(int fd) { struct mem_mgr *mgr = NULL; #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP mgr = nvhost_nvmap_get_mgr_file(fd); #else #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF mgr = (struct mem_mgr *)1; #endif #endif return mgr; } struct mem_handle *nvhost_memmgr_alloc(struct mem_mgr *mgr, size_t size, size_t align, int flags, unsigned int heap_mask) { struct mem_handle *h = NULL; #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP h = nvhost_nvmap_alloc(mgr, size, align, flags, heap_mask); #else #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF h = nvhost_dmabuf_alloc(mgr, size, align, flags); #endif #endif return h; } struct mem_handle *nvhost_memmgr_get(struct mem_mgr *mgr, ulong id, struct platform_device *dev) { struct mem_handle *h = ERR_PTR(-EINVAL); switch (nvhost_memmgr_type(id)) { #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP case mem_mgr_type_nvmap: h = (struct mem_handle *) nvhost_nvmap_get(mgr, id, dev); break; #endif #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF case mem_mgr_type_dmabuf: h = (struct mem_handle *) nvhost_dmabuf_get(id, dev); break; #endif case mem_mgr_type_invalid: /* Fall through */ default: WARN_ON(1); break; } return h; } void nvhost_memmgr_put(struct mem_mgr *mgr, struct mem_handle *handle) { switch (nvhost_memmgr_type((u32)((uintptr_t)handle))) { #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP case mem_mgr_type_nvmap: nvhost_nvmap_put(mgr, handle); break; #endif #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF case mem_mgr_type_dmabuf: nvhost_dmabuf_put(handle); break; #endif case mem_mgr_type_invalid: /* Fall through */ default: WARN_ON(1); break; } } struct sg_table *nvhost_memmgr_pin(struct mem_mgr *mgr, struct mem_handle *handle, struct device *dev, int rw_flag) { switch (nvhost_memmgr_type((u32)((uintptr_t)handle))) { #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP case mem_mgr_type_nvmap: return nvhost_nvmap_pin(mgr, handle, dev, rw_flag); break; #endif #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF case mem_mgr_type_dmabuf: return nvhost_dmabuf_pin(handle, dev); break; #endif case mem_mgr_type_invalid: /* Fall through */ default: WARN_ON(1); return 0; break; } } void nvhost_memmgr_unpin(struct mem_mgr *mgr, struct mem_handle *handle, struct device *dev, struct sg_table *sgt) { switch (nvhost_memmgr_type((u32)((uintptr_t)handle))) { #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP case mem_mgr_type_nvmap: nvhost_nvmap_unpin(mgr, handle, dev, sgt); break; #endif #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF case mem_mgr_type_dmabuf: nvhost_dmabuf_unpin(handle, sgt); break; #endif case mem_mgr_type_invalid: /* Fall through */ default: WARN_ON(1); break; } } void *nvhost_memmgr_mmap(struct mem_handle *handle) { switch (nvhost_memmgr_type((u32)((uintptr_t)handle))) { #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP case mem_mgr_type_nvmap: return nvhost_nvmap_mmap(handle); break; #endif #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF case mem_mgr_type_dmabuf: return nvhost_dmabuf_mmap(handle); break; #endif case mem_mgr_type_invalid: /* Fall through */ default: WARN_ON(1); return 0; break; } } void nvhost_memmgr_munmap(struct mem_handle *handle, void *addr) { switch (nvhost_memmgr_type((u32)((uintptr_t)handle))) { #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP case mem_mgr_type_nvmap: nvhost_nvmap_munmap(handle, addr); break; #endif #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF case mem_mgr_type_dmabuf: nvhost_dmabuf_munmap(handle, addr); break; #endif case mem_mgr_type_invalid: /* Fall through */ default: WARN_ON(1); break; } } int nvhost_memmgr_get_param(struct mem_mgr *mem_mgr, struct mem_handle *mem_handle, u32 param, u64 *result) { #ifndef CONFIG_ARM64 switch (nvhost_memmgr_type((u32)mem_handle)) { #else switch (nvhost_memmgr_type((u32)((uintptr_t)mem_handle))) { #endif #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP case mem_mgr_type_nvmap: return nvhost_nvmap_get_param(mem_mgr, mem_handle, param, result); break; #endif #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF case mem_mgr_type_dmabuf: return nvhost_dmabuf_get_param(mem_mgr, mem_handle, param, result); break; #endif case mem_mgr_type_invalid: /* Fall through */ default: WARN_ON(1); break; } return -EINVAL; } void *nvhost_memmgr_kmap(struct mem_handle *handle, unsigned int pagenum) { switch (nvhost_memmgr_type((u32)((uintptr_t)handle))) { #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP case mem_mgr_type_nvmap: return nvhost_nvmap_kmap(handle, pagenum); break; #endif #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF case mem_mgr_type_dmabuf: return nvhost_dmabuf_kmap(handle, pagenum); break; #endif case mem_mgr_type_invalid: /* Fall through */ default: return 0; WARN_ON(1); break; } } void nvhost_memmgr_kunmap(struct mem_handle *handle, unsigned int pagenum, void *addr) { switch (nvhost_memmgr_type((u32)((uintptr_t)handle))) { #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP case mem_mgr_type_nvmap: nvhost_nvmap_kunmap(handle, pagenum, addr); break; #endif #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF case mem_mgr_type_dmabuf: nvhost_dmabuf_kunmap(handle, pagenum, addr); break; #endif case mem_mgr_type_invalid: /* Fall through */ default: WARN_ON(1); break; } } u32 nvhost_memmgr_handle_to_id(struct mem_handle *handle) { switch (nvhost_memmgr_type((u32)handle)) { #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP case mem_mgr_type_nvmap: return (u32)nvmap_dmabuf_to_user_id( (struct dma_buf *)handle); break; #endif #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF case mem_mgr_type_dmabuf: WARN_ON(1); break; #endif case mem_mgr_type_invalid: /* Fall through */ default: WARN_ON(1); break; } return 0; } struct sg_table *nvhost_memmgr_sg_table(struct mem_mgr *mgr, struct mem_handle *handle) { switch (nvhost_memmgr_type((ulong)handle)) { #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP case mem_mgr_type_nvmap: return nvmap_dmabuf_sg_table((struct dma_buf *)handle); break; #endif #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF case mem_mgr_type_dmabuf: WARN_ON(1); break; #endif case mem_mgr_type_invalid: /* Fall through */ default: break; } return NULL; } void nvhost_memmgr_free_sg_table(struct mem_mgr *mgr, struct mem_handle *handle, struct sg_table *sgt) { switch (nvhost_memmgr_type((ulong)handle)) { #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP case mem_mgr_type_nvmap: return nvmap_dmabuf_free_sg_table( (struct dma_buf *)handle, sgt); break; #endif #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF case mem_mgr_type_dmabuf: WARN_ON(1); break; #endif case mem_mgr_type_invalid: /* Fall through */ default: WARN_ON(1); break; } return; } void nvhost_memmgr_get_comptags(struct mem_handle *mem, struct nvhost_comptags *comptags) { #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP switch (nvhost_memmgr_type((ulong)mem)) { case mem_mgr_type_nvmap: nvhost_nvmap_get_comptags(mem, comptags); return; #endif #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF case mem_mgr_type_dmabuf: nvhost_dmabuf_get_comptags(mem, comptags); return; #endif case mem_mgr_type_invalid: /* Fall through */ default: WARN_ON(1); return; } } int nvhost_memmgr_alloc_comptags(struct mem_handle *mem, struct nvhost_allocator *allocator, int lines) { #ifdef CONFIG_TEGRA_GRHOST_USE_NVMAP switch (nvhost_memmgr_type((ulong)mem)) { case mem_mgr_type_nvmap: return nvhost_nvmap_alloc_comptags(mem, allocator, lines); #endif #ifdef CONFIG_TEGRA_GRHOST_USE_DMABUF case mem_mgr_type_dmabuf: return nvhost_dmabuf_alloc_comptags(mem, allocator, lines); #endif case mem_mgr_type_invalid: /* Fall through */ default: WARN_ON(1); return 0; } } int nvhost_memmgr_init(struct nvhost_chip_support *chip) { return 0; }