From 126c735d3015f515bde9f26d10b4e34d6e194e36 Mon Sep 17 00:00:00 2001 From: Alex Waterman Date: Mon, 10 Apr 2017 13:51:43 -0700 Subject: gpu: nvgpu: Move and rename gk20a_sgtable* Move and rename the functions that build sgtables for nvgpu_mems into the Linux specific DMA code. One place outside of the Linux code do include the Linux DMA header. That will be fixed in a subsequent patch. JIRA NVGPU-12 JIRA NVGPU-30 Change-Id: Ie43c752b8f998f122af70f7c7eb727af0b0d98df Signed-off-by: Alex Waterman Reviewed-on: http://git-master/r/1464078 Reviewed-by: mobile promotions Tested-by: mobile promotions --- drivers/gpu/nvgpu/common/linux/dma.c | 79 ++++++++++++++++++++-- drivers/gpu/nvgpu/common/linux/nvgpu_mem.c | 6 +- drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 73 +------------------- drivers/gpu/nvgpu/gk20a/mm_gk20a.h | 10 --- drivers/gpu/nvgpu/gm20b/acr_gm20b.c | 4 +- drivers/gpu/nvgpu/include/nvgpu/linux/dma.h | 34 ++++++++++ .../gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c | 4 +- 7 files changed, 120 insertions(+), 90 deletions(-) create mode 100644 drivers/gpu/nvgpu/include/nvgpu/linux/dma.h (limited to 'drivers/gpu') diff --git a/drivers/gpu/nvgpu/common/linux/dma.c b/drivers/gpu/nvgpu/common/linux/dma.c index 7453fdef..b943aabf 100644 --- a/drivers/gpu/nvgpu/common/linux/dma.c +++ b/drivers/gpu/nvgpu/common/linux/dma.c @@ -21,6 +21,8 @@ #include #include +#include + #include "gk20a/gk20a.h" #if defined(CONFIG_GK20A_VIDMEM) @@ -126,11 +128,11 @@ int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags, } if (flags & NVGPU_DMA_NO_KERNEL_MAPPING) - err = gk20a_get_sgtable_from_pages(d, &mem->priv.sgt, + err = nvgpu_get_sgtable_from_pages(g, &mem->priv.sgt, mem->priv.pages, iova, size); else { - err = gk20a_get_sgtable(d, &mem->priv.sgt, mem->cpu_va, + err = nvgpu_get_sgtable(g, &mem->priv.sgt, mem->cpu_va, iova, size); memset(mem->cpu_va, 0, size); } @@ -359,7 +361,7 @@ static void nvgpu_dma_free_sys(struct gk20a *g, struct nvgpu_mem *mem) } if (mem->priv.sgt) - gk20a_free_sgtable(g, &mem->priv.sgt); + nvgpu_free_sgtable(g, &mem->priv.sgt); mem->size = 0; mem->aperture = APERTURE_INVALID; @@ -389,7 +391,7 @@ static void nvgpu_dma_free_vid(struct gk20a *g, struct nvgpu_mem *mem) nvgpu_memset(g, mem, 0, 0, mem->size); nvgpu_free(mem->allocator, (u64)get_vidmem_page_alloc(mem->priv.sgt->sgl)); - gk20a_free_sgtable(g, &mem->priv.sgt); + nvgpu_free_sgtable(g, &mem->priv.sgt); mem->size = 0; mem->aperture = APERTURE_INVALID; @@ -412,9 +414,74 @@ 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); + gk20a_gmmu_unmap(vm, mem->gpu_va, + mem->size, gk20a_mem_flag_none); mem->gpu_va = 0; nvgpu_dma_free(vm->mm->g, mem); } + +int nvgpu_get_sgtable(struct gk20a *g, struct sg_table **sgt, + void *cpuva, u64 iova, size_t size) +{ + int err = 0; + struct sg_table *tbl; + + tbl = nvgpu_kzalloc(g, sizeof(struct sg_table)); + if (!tbl) { + err = -ENOMEM; + goto fail; + } + + err = dma_get_sgtable(dev_from_gk20a(g), tbl, cpuva, iova, size); + if (err) + goto fail; + + sg_dma_address(tbl->sgl) = iova; + *sgt = tbl; + + return 0; + +fail: + if (tbl) + nvgpu_kfree(g, tbl); + + return err; +} + +int nvgpu_get_sgtable_from_pages(struct gk20a *g, struct sg_table **sgt, + struct page **pages, u64 iova, size_t size) +{ + int err = 0; + struct sg_table *tbl; + + tbl = nvgpu_kzalloc(g, sizeof(struct sg_table)); + if (!tbl) { + err = -ENOMEM; + goto fail; + } + + err = sg_alloc_table_from_pages(tbl, pages, + DIV_ROUND_UP(size, PAGE_SIZE), + 0, size, GFP_KERNEL); + if (err) + goto fail; + + sg_dma_address(tbl->sgl) = iova; + *sgt = tbl; + + return 0; + +fail: + if (tbl) + nvgpu_kfree(g, tbl); + + return err; +} + +void nvgpu_free_sgtable(struct gk20a *g, struct sg_table **sgt) +{ + sg_free_table(*sgt); + nvgpu_kfree(g, *sgt); + *sgt = NULL; +} diff --git a/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c b/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c index fb7ee7fe..b46dbb6b 100644 --- a/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c +++ b/drivers/gpu/nvgpu/common/linux/nvgpu_mem.c @@ -20,6 +20,8 @@ #include #include +#include + #include "gk20a/gk20a.h" #include "gk20a/mm_gk20a.h" @@ -286,11 +288,11 @@ int nvgpu_mem_create_from_mem(struct gk20a *g, * is passed to us. This table gets freed by the dma free routines. */ if (src->priv.flags & NVGPU_DMA_NO_KERNEL_MAPPING) - ret = gk20a_get_sgtable_from_pages(g->dev, &dest->priv.sgt, + ret = nvgpu_get_sgtable_from_pages(g, &dest->priv.sgt, src->priv.pages + start_page, new_iova, size); else - ret = gk20a_get_sgtable(g->dev, &dest->priv.sgt, dest->cpu_va, + ret = nvgpu_get_sgtable(g, &dest->priv.sgt, dest->cpu_va, new_iova, size); return ret; diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index 69e00c5e..79aa44a5 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c @@ -38,6 +38,8 @@ #include #include +#include + #include "gk20a.h" #include "mm_gk20a.h" #include "fence_gk20a.h" @@ -2621,7 +2623,7 @@ static void gk20a_vidmem_clear_mem_worker(struct work_struct *work) gk20a_gmmu_clear_vidmem_mem(g, mem); nvgpu_free(mem->allocator, (u64)get_vidmem_page_alloc(mem->priv.sgt->sgl)); - gk20a_free_sgtable(g, &mem->priv.sgt); + nvgpu_free_sgtable(g, &mem->priv.sgt); WARN_ON(atomic64_sub_return(mem->size, &g->mm.vidmem.bytes_pending) < 0); @@ -2668,75 +2670,6 @@ void gk20a_gmmu_unmap(struct vm_gk20a *vm, nvgpu_mutex_release(&vm->update_gmmu_lock); } -/* get sg_table from already allocated buffer */ -int gk20a_get_sgtable(struct device *d, struct sg_table **sgt, - void *cpuva, u64 iova, - size_t size) -{ - struct gk20a *g = get_gk20a(d); - - int err = 0; - *sgt = nvgpu_kzalloc(g, sizeof(struct sg_table)); - if (!(*sgt)) { - nvgpu_err(g, "failed to allocate memory\n"); - err = -ENOMEM; - goto fail; - } - err = dma_get_sgtable(d, *sgt, - cpuva, iova, - size); - if (err) { - nvgpu_err(g, "failed to create sg table\n"); - goto fail; - } - sg_dma_address((*sgt)->sgl) = iova; - - return 0; - fail: - if (*sgt) { - nvgpu_kfree(g, *sgt); - *sgt = NULL; - } - return err; -} - -int gk20a_get_sgtable_from_pages(struct device *d, struct sg_table **sgt, - struct page **pages, u64 iova, - size_t size) -{ - int err = 0; - struct gk20a *g = get_gk20a(d); - - *sgt = nvgpu_kzalloc(g, sizeof(struct sg_table)); - if (!(*sgt)) { - nvgpu_err(g, "failed to allocate memory\n"); - err = -ENOMEM; - goto fail; - } - err = sg_alloc_table_from_pages(*sgt, pages, - DIV_ROUND_UP(size, PAGE_SIZE), 0, size, GFP_KERNEL); - if (err) { - nvgpu_err(g, "failed to allocate sg_table\n"); - goto fail; - } - sg_dma_address((*sgt)->sgl) = iova; - - return 0; - fail: - if (*sgt) { - nvgpu_kfree(get_gk20a(d), *sgt); - *sgt = NULL; - } - return err; -} - -void gk20a_free_sgtable(struct gk20a *g, struct sg_table **sgt) -{ - sg_free_table(*sgt); - nvgpu_kfree(g, *sgt); - *sgt = NULL; -} - u64 gk20a_mm_smmu_vaddr_translate(struct gk20a *g, dma_addr_t iova) { /* ensure it is not vidmem allocation */ diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h index 94dc0b6f..9717efff 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.h @@ -497,16 +497,6 @@ void gk20a_mm_dump_vm(struct vm_gk20a *vm, int gk20a_mm_suspend(struct gk20a *g); -int gk20a_get_sgtable(struct device *d, struct sg_table **sgt, - void *cpuva, u64 iova, - size_t size); - -int gk20a_get_sgtable_from_pages(struct device *d, struct sg_table **sgt, - struct page **pages, u64 iova, - size_t size); - -void gk20a_free_sgtable(struct gk20a *g, struct sg_table **sgt); - u64 gk20a_mm_iova_addr(struct gk20a *g, struct scatterlist *sgl, u32 flags); u64 gk20a_mm_smmu_vaddr_translate(struct gk20a *g, dma_addr_t iova); diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c index fafe8734..8622f7b4 100644 --- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c +++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c @@ -25,6 +25,8 @@ #include #include +#include + #include "gk20a/gk20a.h" #include "gk20a/pmu_gk20a.h" #include "mm_gm20b.h" @@ -456,7 +458,7 @@ int prepare_ucode_blob(struct gk20a *g) gm20b_dbg_pmu("prepare ucode blob return 0\n"); free_acr_resources(g, plsfm); free_sgt: - gk20a_free_sgtable(g, &sgt); + nvgpu_free_sgtable(g, &sgt); return err; } diff --git a/drivers/gpu/nvgpu/include/nvgpu/linux/dma.h b/drivers/gpu/nvgpu/include/nvgpu/linux/dma.h new file mode 100644 index 00000000..3960e654 --- /dev/null +++ b/drivers/gpu/nvgpu/include/nvgpu/linux/dma.h @@ -0,0 +1,34 @@ +/* + * 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_DMA_H__ +#define __NVGPU_LINUX_DMA_H__ + +/** + * Functions used internally for building the backing SGTs for nvgpu_mems. + */ + +int nvgpu_get_sgtable(struct gk20a *g, struct sg_table **sgt, + void *cpuva, u64 iova, + size_t size); + +int nvgpu_get_sgtable_from_pages(struct gk20a *g, struct sg_table **sgt, + struct page **pages, u64 iova, + size_t size); + +void nvgpu_free_sgtable(struct gk20a *g, struct sg_table **sgt); + +#endif diff --git a/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c index 852dcdf2..c2f0321a 100644 --- a/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c +++ b/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c @@ -51,6 +51,8 @@ #include #include +#include + #include "gk20a/gk20a.h" #include "gk20a/hal_gk20a.h" #include "gk20a/platform_gk20a.h" @@ -143,7 +145,7 @@ static void gk20a_tegra_secure_destroy(struct gk20a *g, dma_free_attrs(&tegra_vpr_dev, desc->mem.size, (void *)(uintptr_t)pa, pa, __DMA_ATTR(attrs)); - gk20a_free_sgtable(g, &desc->mem.priv.sgt); + nvgpu_free_sgtable(g, &desc->mem.priv.sgt); desc->mem.priv.sgt = NULL; } } -- cgit v1.2.2