From 26783b85bfee4c2ef4f2ccc2d16ebc783dd0aa7d Mon Sep 17 00:00:00 2001 From: Terje Bergstrom Date: Mon, 2 Jul 2018 10:44:05 -0700 Subject: gpu: nvpgu: Rename Linux specific vidmem code Rename os/linux/vidmem.c to os/linux/dmabuf_vidmem.c. The code is mainly dealing with interfacing with Linux dmabuf framework and its responsibilities got confused with common/mm/vidmem.c. Also move the header include/nvgpu/linux/vidmem.h to os/linux/dmabuf_vidmem.h. It does not expose any interface to outside Linux code. Change-Id: I2cb1057a8934d5cb5c5860023aa12f8f048a6684 Signed-off-by: Terje Bergstrom Reviewed-on: https://git-master.nvidia.com/r/1768261 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/Makefile | 2 +- drivers/gpu/nvgpu/include/nvgpu/linux/vidmem.h | 77 ------- drivers/gpu/nvgpu/os/linux/dma.c | 2 +- drivers/gpu/nvgpu/os/linux/dmabuf.c | 2 +- drivers/gpu/nvgpu/os/linux/dmabuf_vidmem.c | 268 +++++++++++++++++++++++++ drivers/gpu/nvgpu/os/linux/dmabuf_vidmem.h | 78 +++++++ drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c | 3 +- drivers/gpu/nvgpu/os/linux/ioctl_dbg.c | 2 +- drivers/gpu/nvgpu/os/linux/nvgpu_mem.c | 2 +- drivers/gpu/nvgpu/os/linux/vidmem.c | 268 ------------------------- drivers/gpu/nvgpu/os/linux/vm.c | 2 +- 11 files changed, 353 insertions(+), 353 deletions(-) delete mode 100644 drivers/gpu/nvgpu/include/nvgpu/linux/vidmem.h create mode 100644 drivers/gpu/nvgpu/os/linux/dmabuf_vidmem.c create mode 100644 drivers/gpu/nvgpu/os/linux/dmabuf_vidmem.h delete mode 100644 drivers/gpu/nvgpu/os/linux/vidmem.c (limited to 'drivers') diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index 61636ff5..b21d3279 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile @@ -66,7 +66,7 @@ nvgpu-y += \ os/linux/dt.o nvgpu-$(CONFIG_GK20A_VIDMEM) += \ - os/linux/vidmem.o + os/linux/dmabuf_vidmem.o nvgpu-$(CONFIG_DEBUG_FS) += \ os/linux/debug.o \ diff --git a/drivers/gpu/nvgpu/include/nvgpu/linux/vidmem.h b/drivers/gpu/nvgpu/include/nvgpu/linux/vidmem.h deleted file mode 100644 index ec02faec..00000000 --- a/drivers/gpu/nvgpu/include/nvgpu/linux/vidmem.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * 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 . - */ - -#ifndef __NVGPU_LINUX_VIDMEM_H__ -#define __NVGPU_LINUX_VIDMEM_H__ - -#include - -struct dma_buf; - -struct gk20a; - -#ifdef CONFIG_GK20A_VIDMEM - -struct gk20a *nvgpu_vidmem_buf_owner(struct dma_buf *dmabuf); -int nvgpu_vidmem_export_linux(struct gk20a *g, size_t bytes); - -void nvgpu_vidmem_set_page_alloc(struct scatterlist *sgl, u64 addr); -struct nvgpu_page_alloc *nvgpu_vidmem_get_page_alloc(struct scatterlist *sgl); - -int nvgpu_vidmem_buf_access_memory(struct gk20a *g, struct dma_buf *dmabuf, - void *buffer, u64 offset, u64 size, u32 cmd); - -#else /* !CONFIG_GK20A_VIDMEM */ - -static inline struct gk20a *nvgpu_vidmem_buf_owner(struct dma_buf *dmabuf) -{ - return NULL; -} - -static inline int nvgpu_vidmem_export_linux(struct gk20a *g, size_t bytes) -{ - return -ENOSYS; -} - -static inline void nvgpu_vidmem_set_page_alloc(struct scatterlist *sgl, - u64 addr) -{ -} - -static inline struct nvgpu_page_alloc *nvgpu_vidmem_get_page_alloc( - struct scatterlist *sgl) -{ - return NULL; -} - -static inline int nvgpu_vidmem_buf_access_memory(struct gk20a *g, - struct dma_buf *dmabuf, - void *buffer, u64 offset, - u64 size, u32 cmd) -{ - return -ENOSYS; -} - -#endif - - -struct nvgpu_vidmem_linux { - struct dma_buf *dmabuf; - void *dmabuf_priv; - void (*dmabuf_priv_delete)(void *); -}; - -#endif diff --git a/drivers/gpu/nvgpu/os/linux/dma.c b/drivers/gpu/nvgpu/os/linux/dma.c index 6f17e284..86a17a7e 100644 --- a/drivers/gpu/nvgpu/os/linux/dma.c +++ b/drivers/gpu/nvgpu/os/linux/dma.c @@ -27,12 +27,12 @@ #include #include -#include #include "gk20a/gk20a.h" #include "platform_gk20a.h" #include "os_linux.h" +#include "dmabuf_vidmem.h" #ifdef __DMA_ATTRS_LONGS #define NVGPU_DEFINE_DMA_ATTRS(x) \ diff --git a/drivers/gpu/nvgpu/os/linux/dmabuf.c b/drivers/gpu/nvgpu/os/linux/dmabuf.c index 129739f0..6f07e88a 100644 --- a/drivers/gpu/nvgpu/os/linux/dmabuf.c +++ b/drivers/gpu/nvgpu/os/linux/dmabuf.c @@ -22,13 +22,13 @@ #include #include -#include #include "gk20a/gk20a.h" #include "platform_gk20a.h" #include "dmabuf.h" #include "os_linux.h" +#include "dmabuf_vidmem.h" static void gk20a_mm_delete_priv(void *_priv) { diff --git a/drivers/gpu/nvgpu/os/linux/dmabuf_vidmem.c b/drivers/gpu/nvgpu/os/linux/dmabuf_vidmem.c new file mode 100644 index 00000000..572c2b0f --- /dev/null +++ b/drivers/gpu/nvgpu/os/linux/dmabuf_vidmem.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2017-2018, 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 + +#ifdef CONFIG_NVGPU_USE_TEGRA_ALLOC_FD +#include +#endif + +#include +#include +#include +#include +#include + +#include +#include + +#include "gk20a/gk20a.h" +#include "gk20a/mm_gk20a.h" +#include "dmabuf_vidmem.h" + +bool nvgpu_addr_is_vidmem_page_alloc(u64 addr) +{ + return !!(addr & 1ULL); +} + +void nvgpu_vidmem_set_page_alloc(struct scatterlist *sgl, u64 addr) +{ + /* set bit 0 to indicate vidmem allocation */ + sg_dma_address(sgl) = (addr | 1ULL); +} + +struct nvgpu_page_alloc *nvgpu_vidmem_get_page_alloc(struct scatterlist *sgl) +{ + u64 addr; + + addr = sg_dma_address(sgl); + + if (nvgpu_addr_is_vidmem_page_alloc(addr)) + addr = addr & ~1ULL; + else + WARN_ON(1); + + return (struct nvgpu_page_alloc *)(uintptr_t)addr; +} + +static struct sg_table *gk20a_vidbuf_map_dma_buf( + struct dma_buf_attachment *attach, enum dma_data_direction dir) +{ + struct nvgpu_vidmem_buf *buf = attach->dmabuf->priv; + + return buf->mem->priv.sgt; +} + +static void gk20a_vidbuf_unmap_dma_buf(struct dma_buf_attachment *attach, + struct sg_table *sgt, + enum dma_data_direction dir) +{ +} + +static void gk20a_vidbuf_release(struct dma_buf *dmabuf) +{ + struct nvgpu_vidmem_buf *buf = dmabuf->priv; + struct nvgpu_vidmem_linux *linux_buf = buf->priv; + struct gk20a *g = buf->g; + + vidmem_dbg(g, "Releasing Linux VIDMEM buf: dmabuf=0x%p size=%zuKB", + dmabuf, buf->mem->size >> 10); + + if (linux_buf && linux_buf->dmabuf_priv_delete) + linux_buf->dmabuf_priv_delete(linux_buf->dmabuf_priv); + + nvgpu_kfree(g, linux_buf); + nvgpu_vidmem_buf_free(g, buf); + + gk20a_put(g); +} + +static void *gk20a_vidbuf_kmap(struct dma_buf *dmabuf, unsigned long page_num) +{ + WARN_ON("Not supported"); + return NULL; +} + +static void *gk20a_vidbuf_kmap_atomic(struct dma_buf *dmabuf, + unsigned long page_num) +{ + WARN_ON("Not supported"); + return NULL; +} + +static int gk20a_vidbuf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) +{ + return -EINVAL; +} + +static int gk20a_vidbuf_set_private(struct dma_buf *dmabuf, + struct device *dev, void *priv, void (*delete)(void *priv)) +{ + struct nvgpu_vidmem_buf *buf = dmabuf->priv; + struct nvgpu_vidmem_linux *linux_buf = buf->priv; + + linux_buf->dmabuf_priv = priv; + linux_buf->dmabuf_priv_delete = delete; + + return 0; +} + +static void *gk20a_vidbuf_get_private(struct dma_buf *dmabuf, + struct device *dev) +{ + struct nvgpu_vidmem_buf *buf = dmabuf->priv; + struct nvgpu_vidmem_linux *linux_buf = buf->priv; + + return linux_buf->dmabuf_priv; +} + +static const struct dma_buf_ops gk20a_vidbuf_ops = { + .map_dma_buf = gk20a_vidbuf_map_dma_buf, + .unmap_dma_buf = gk20a_vidbuf_unmap_dma_buf, + .release = gk20a_vidbuf_release, +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) + .map_atomic = gk20a_vidbuf_kmap_atomic, + .map = gk20a_vidbuf_kmap, +#else + .kmap_atomic = gk20a_vidbuf_kmap_atomic, + .kmap = gk20a_vidbuf_kmap, +#endif + .mmap = gk20a_vidbuf_mmap, + .set_drvdata = gk20a_vidbuf_set_private, + .get_drvdata = gk20a_vidbuf_get_private, +}; + +static struct dma_buf *gk20a_vidbuf_export(struct nvgpu_vidmem_buf *buf) +{ + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + + exp_info.priv = buf; + exp_info.ops = &gk20a_vidbuf_ops; + exp_info.size = buf->mem->size; + exp_info.flags = O_RDWR; + + return dma_buf_export(&exp_info); +} + +struct gk20a *nvgpu_vidmem_buf_owner(struct dma_buf *dmabuf) +{ + struct nvgpu_vidmem_buf *buf = dmabuf->priv; + + if (dmabuf->ops != &gk20a_vidbuf_ops) + return NULL; + + return buf->g; +} + +int nvgpu_vidmem_export_linux(struct gk20a *g, size_t bytes) +{ + struct nvgpu_vidmem_buf *buf = NULL; + struct nvgpu_vidmem_linux *priv; + int err, fd; + + /* + * This ref is released when the dma_buf is closed. + */ + if (!gk20a_get(g)) + return -ENODEV; + + vidmem_dbg(g, "Allocating vidmem buf: %zu bytes", bytes); + + priv = nvgpu_kzalloc(g, sizeof(*priv)); + if (!priv) { + err = -ENOMEM; + goto fail; + } + + buf = nvgpu_vidmem_user_alloc(g, bytes); + if (IS_ERR(buf)) { + err = PTR_ERR(buf); + goto fail; + } + + priv->dmabuf = gk20a_vidbuf_export(buf); + if (IS_ERR(priv->dmabuf)) { + err = PTR_ERR(priv->dmabuf); + goto fail; + } + + buf->priv = priv; + +#ifdef CONFIG_NVGPU_USE_TEGRA_ALLOC_FD + fd = tegra_alloc_fd(current->files, 1024, O_RDWR); +#else + fd = get_unused_fd_flags(O_RDWR); +#endif + if (fd < 0) { + /* ->release frees what we have done */ + dma_buf_put(priv->dmabuf); + return fd; + } + + /* fclose() on this drops one ref, freeing the dma buf */ + fd_install(fd, priv->dmabuf->file); + + vidmem_dbg(g, "Alloced Linux VIDMEM buf: dmabuf=0x%p size=%zuKB", + priv->dmabuf, buf->mem->size >> 10); + + return fd; + +fail: + nvgpu_vidmem_buf_free(g, buf); + nvgpu_kfree(g, priv); + gk20a_put(g); + + vidmem_dbg(g, "Failed to alloc Linux VIDMEM buf: %d", err); + return err; +} + +int nvgpu_vidmem_buf_access_memory(struct gk20a *g, struct dma_buf *dmabuf, + void *buffer, u64 offset, u64 size, u32 cmd) +{ + struct nvgpu_vidmem_buf *vidmem_buf; + struct nvgpu_mem *mem; + int err = 0; + + if (gk20a_dmabuf_aperture(g, dmabuf) != APERTURE_VIDMEM) + return -EINVAL; + + vidmem_buf = dmabuf->priv; + mem = vidmem_buf->mem; + + switch (cmd) { + case NVGPU_DBG_GPU_IOCTL_ACCESS_FB_MEMORY_CMD_READ: + nvgpu_mem_rd_n(g, mem, offset, buffer, size); + break; + + case NVGPU_DBG_GPU_IOCTL_ACCESS_FB_MEMORY_CMD_WRITE: + nvgpu_mem_wr_n(g, mem, offset, buffer, size); + break; + + default: + err = -EINVAL; + } + + return err; +} + +void __nvgpu_mem_free_vidmem_alloc(struct gk20a *g, struct nvgpu_mem *vidmem) +{ + nvgpu_free(vidmem->allocator, + (u64)nvgpu_vidmem_get_page_alloc(vidmem->priv.sgt->sgl)); + nvgpu_free_sgtable(g, &vidmem->priv.sgt); +} diff --git a/drivers/gpu/nvgpu/os/linux/dmabuf_vidmem.h b/drivers/gpu/nvgpu/os/linux/dmabuf_vidmem.h new file mode 100644 index 00000000..977fd78b --- /dev/null +++ b/drivers/gpu/nvgpu/os/linux/dmabuf_vidmem.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2017-2018, 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 . + */ + +#ifndef __NVGPU_LINUX_DMABUF_VIDMEM_H__ +#define __NVGPU_LINUX_DMABUF_VIDMEM_H__ + +#include + +struct dma_buf; + +struct gk20a; +struct scatterlist; + +#ifdef CONFIG_GK20A_VIDMEM + +struct gk20a *nvgpu_vidmem_buf_owner(struct dma_buf *dmabuf); +int nvgpu_vidmem_export_linux(struct gk20a *g, size_t bytes); + +void nvgpu_vidmem_set_page_alloc(struct scatterlist *sgl, u64 addr); +struct nvgpu_page_alloc *nvgpu_vidmem_get_page_alloc(struct scatterlist *sgl); + +int nvgpu_vidmem_buf_access_memory(struct gk20a *g, struct dma_buf *dmabuf, + void *buffer, u64 offset, u64 size, u32 cmd); + +#else /* !CONFIG_GK20A_VIDMEM */ + +static inline struct gk20a *nvgpu_vidmem_buf_owner(struct dma_buf *dmabuf) +{ + return NULL; +} + +static inline int nvgpu_vidmem_export_linux(struct gk20a *g, size_t bytes) +{ + return -ENOSYS; +} + +static inline void nvgpu_vidmem_set_page_alloc(struct scatterlist *sgl, + u64 addr) +{ +} + +static inline struct nvgpu_page_alloc *nvgpu_vidmem_get_page_alloc( + struct scatterlist *sgl) +{ + return NULL; +} + +static inline int nvgpu_vidmem_buf_access_memory(struct gk20a *g, + struct dma_buf *dmabuf, + void *buffer, u64 offset, + u64 size, u32 cmd) +{ + return -ENOSYS; +} + +#endif + + +struct nvgpu_vidmem_linux { + struct dma_buf *dmabuf; + void *dmabuf_priv; + void (*dmabuf_priv_delete)(void *); +}; + +#endif diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c index f9ad8082..17f1e923 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_ctrl.c @@ -30,8 +30,6 @@ #include #include -#include - #include "ioctl_ctrl.h" #include "ioctl_dbg.h" #include "ioctl_as.h" @@ -44,6 +42,7 @@ #include "os_linux.h" #include "dmabuf.h" #include "channel.h" +#include "dmabuf_vidmem.h" #define HZ_TO_MHZ(a) ((a > 0xF414F9CD7ULL) ? 0xffff : (a >> 32) ? \ (u32) ((a * 0x10C8ULL) >> 32) : (u16) ((u32) a/MHZ)) diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c index 3156837b..9c7608e9 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_dbg.c @@ -30,7 +30,6 @@ #include #include -#include #include #include "gk20a/gk20a.h" @@ -40,6 +39,7 @@ #include "os_linux.h" #include "platform_gk20a.h" #include "ioctl_dbg.h" +#include "dmabuf_vidmem.h" struct dbg_session_gk20a_linux { struct device *dev; diff --git a/drivers/gpu/nvgpu/os/linux/nvgpu_mem.c b/drivers/gpu/nvgpu/os/linux/nvgpu_mem.c index aa8fcd84..4fc95db9 100644 --- a/drivers/gpu/nvgpu/os/linux/nvgpu_mem.c +++ b/drivers/gpu/nvgpu/os/linux/nvgpu_mem.c @@ -25,12 +25,12 @@ #include #include -#include #include #include #include "os_linux.h" +#include "dmabuf_vidmem.h" #include "gk20a/gk20a.h" #include "gk20a/mm_gk20a.h" diff --git a/drivers/gpu/nvgpu/os/linux/vidmem.c b/drivers/gpu/nvgpu/os/linux/vidmem.c deleted file mode 100644 index df1a905d..00000000 --- a/drivers/gpu/nvgpu/os/linux/vidmem.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright (c) 2017-2018, 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 - -#ifdef CONFIG_NVGPU_USE_TEGRA_ALLOC_FD -#include -#endif - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "gk20a/gk20a.h" -#include "gk20a/mm_gk20a.h" - -bool nvgpu_addr_is_vidmem_page_alloc(u64 addr) -{ - return !!(addr & 1ULL); -} - -void nvgpu_vidmem_set_page_alloc(struct scatterlist *sgl, u64 addr) -{ - /* set bit 0 to indicate vidmem allocation */ - sg_dma_address(sgl) = (addr | 1ULL); -} - -struct nvgpu_page_alloc *nvgpu_vidmem_get_page_alloc(struct scatterlist *sgl) -{ - u64 addr; - - addr = sg_dma_address(sgl); - - if (nvgpu_addr_is_vidmem_page_alloc(addr)) - addr = addr & ~1ULL; - else - WARN_ON(1); - - return (struct nvgpu_page_alloc *)(uintptr_t)addr; -} - -static struct sg_table *gk20a_vidbuf_map_dma_buf( - struct dma_buf_attachment *attach, enum dma_data_direction dir) -{ - struct nvgpu_vidmem_buf *buf = attach->dmabuf->priv; - - return buf->mem->priv.sgt; -} - -static void gk20a_vidbuf_unmap_dma_buf(struct dma_buf_attachment *attach, - struct sg_table *sgt, - enum dma_data_direction dir) -{ -} - -static void gk20a_vidbuf_release(struct dma_buf *dmabuf) -{ - struct nvgpu_vidmem_buf *buf = dmabuf->priv; - struct nvgpu_vidmem_linux *linux_buf = buf->priv; - struct gk20a *g = buf->g; - - vidmem_dbg(g, "Releasing Linux VIDMEM buf: dmabuf=0x%p size=%zuKB", - dmabuf, buf->mem->size >> 10); - - if (linux_buf && linux_buf->dmabuf_priv_delete) - linux_buf->dmabuf_priv_delete(linux_buf->dmabuf_priv); - - nvgpu_kfree(g, linux_buf); - nvgpu_vidmem_buf_free(g, buf); - - gk20a_put(g); -} - -static void *gk20a_vidbuf_kmap(struct dma_buf *dmabuf, unsigned long page_num) -{ - WARN_ON("Not supported"); - return NULL; -} - -static void *gk20a_vidbuf_kmap_atomic(struct dma_buf *dmabuf, - unsigned long page_num) -{ - WARN_ON("Not supported"); - return NULL; -} - -static int gk20a_vidbuf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) -{ - return -EINVAL; -} - -static int gk20a_vidbuf_set_private(struct dma_buf *dmabuf, - struct device *dev, void *priv, void (*delete)(void *priv)) -{ - struct nvgpu_vidmem_buf *buf = dmabuf->priv; - struct nvgpu_vidmem_linux *linux_buf = buf->priv; - - linux_buf->dmabuf_priv = priv; - linux_buf->dmabuf_priv_delete = delete; - - return 0; -} - -static void *gk20a_vidbuf_get_private(struct dma_buf *dmabuf, - struct device *dev) -{ - struct nvgpu_vidmem_buf *buf = dmabuf->priv; - struct nvgpu_vidmem_linux *linux_buf = buf->priv; - - return linux_buf->dmabuf_priv; -} - -static const struct dma_buf_ops gk20a_vidbuf_ops = { - .map_dma_buf = gk20a_vidbuf_map_dma_buf, - .unmap_dma_buf = gk20a_vidbuf_unmap_dma_buf, - .release = gk20a_vidbuf_release, -#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0) - .map_atomic = gk20a_vidbuf_kmap_atomic, - .map = gk20a_vidbuf_kmap, -#else - .kmap_atomic = gk20a_vidbuf_kmap_atomic, - .kmap = gk20a_vidbuf_kmap, -#endif - .mmap = gk20a_vidbuf_mmap, - .set_drvdata = gk20a_vidbuf_set_private, - .get_drvdata = gk20a_vidbuf_get_private, -}; - -static struct dma_buf *gk20a_vidbuf_export(struct nvgpu_vidmem_buf *buf) -{ - DEFINE_DMA_BUF_EXPORT_INFO(exp_info); - - exp_info.priv = buf; - exp_info.ops = &gk20a_vidbuf_ops; - exp_info.size = buf->mem->size; - exp_info.flags = O_RDWR; - - return dma_buf_export(&exp_info); -} - -struct gk20a *nvgpu_vidmem_buf_owner(struct dma_buf *dmabuf) -{ - struct nvgpu_vidmem_buf *buf = dmabuf->priv; - - if (dmabuf->ops != &gk20a_vidbuf_ops) - return NULL; - - return buf->g; -} - -int nvgpu_vidmem_export_linux(struct gk20a *g, size_t bytes) -{ - struct nvgpu_vidmem_buf *buf = NULL; - struct nvgpu_vidmem_linux *priv; - int err, fd; - - /* - * This ref is released when the dma_buf is closed. - */ - if (!gk20a_get(g)) - return -ENODEV; - - vidmem_dbg(g, "Allocating vidmem buf: %zu bytes", bytes); - - priv = nvgpu_kzalloc(g, sizeof(*priv)); - if (!priv) { - err = -ENOMEM; - goto fail; - } - - buf = nvgpu_vidmem_user_alloc(g, bytes); - if (IS_ERR(buf)) { - err = PTR_ERR(buf); - goto fail; - } - - priv->dmabuf = gk20a_vidbuf_export(buf); - if (IS_ERR(priv->dmabuf)) { - err = PTR_ERR(priv->dmabuf); - goto fail; - } - - buf->priv = priv; - -#ifdef CONFIG_NVGPU_USE_TEGRA_ALLOC_FD - fd = tegra_alloc_fd(current->files, 1024, O_RDWR); -#else - fd = get_unused_fd_flags(O_RDWR); -#endif - if (fd < 0) { - /* ->release frees what we have done */ - dma_buf_put(priv->dmabuf); - return fd; - } - - /* fclose() on this drops one ref, freeing the dma buf */ - fd_install(fd, priv->dmabuf->file); - - vidmem_dbg(g, "Alloced Linux VIDMEM buf: dmabuf=0x%p size=%zuKB", - priv->dmabuf, buf->mem->size >> 10); - - return fd; - -fail: - nvgpu_vidmem_buf_free(g, buf); - nvgpu_kfree(g, priv); - gk20a_put(g); - - vidmem_dbg(g, "Failed to alloc Linux VIDMEM buf: %d", err); - return err; -} - -int nvgpu_vidmem_buf_access_memory(struct gk20a *g, struct dma_buf *dmabuf, - void *buffer, u64 offset, u64 size, u32 cmd) -{ - struct nvgpu_vidmem_buf *vidmem_buf; - struct nvgpu_mem *mem; - int err = 0; - - if (gk20a_dmabuf_aperture(g, dmabuf) != APERTURE_VIDMEM) - return -EINVAL; - - vidmem_buf = dmabuf->priv; - mem = vidmem_buf->mem; - - switch (cmd) { - case NVGPU_DBG_GPU_IOCTL_ACCESS_FB_MEMORY_CMD_READ: - nvgpu_mem_rd_n(g, mem, offset, buffer, size); - break; - - case NVGPU_DBG_GPU_IOCTL_ACCESS_FB_MEMORY_CMD_WRITE: - nvgpu_mem_wr_n(g, mem, offset, buffer, size); - break; - - default: - err = -EINVAL; - } - - return err; -} - -void __nvgpu_mem_free_vidmem_alloc(struct gk20a *g, struct nvgpu_mem *vidmem) -{ - nvgpu_free(vidmem->allocator, - (u64)nvgpu_vidmem_get_page_alloc(vidmem->priv.sgt->sgl)); - nvgpu_free_sgtable(g, &vidmem->priv.sgt); -} diff --git a/drivers/gpu/nvgpu/os/linux/vm.c b/drivers/gpu/nvgpu/os/linux/vm.c index eb9ca8fd..2b5ed103 100644 --- a/drivers/gpu/nvgpu/os/linux/vm.c +++ b/drivers/gpu/nvgpu/os/linux/vm.c @@ -27,7 +27,6 @@ #include #include -#include #include #include "gk20a/gk20a.h" @@ -36,6 +35,7 @@ #include "platform_gk20a.h" #include "os_linux.h" #include "dmabuf.h" +#include "dmabuf_vidmem.h" static u32 nvgpu_vm_translate_linux_flags(struct gk20a *g, u32 flags) { -- cgit v1.2.2