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