diff options
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/dma.c | 79 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/nvgpu_mem.c | 6 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 73 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.h | 10 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/acr_gm20b.c | 4 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/linux/dma.h | 34 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c | 4 |
7 files changed, 120 insertions, 90 deletions
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 @@ | |||
21 | #include <nvgpu/lock.h> | 21 | #include <nvgpu/lock.h> |
22 | #include <nvgpu/bug.h> | 22 | #include <nvgpu/bug.h> |
23 | 23 | ||
24 | #include <nvgpu/linux/dma.h> | ||
25 | |||
24 | #include "gk20a/gk20a.h" | 26 | #include "gk20a/gk20a.h" |
25 | 27 | ||
26 | #if defined(CONFIG_GK20A_VIDMEM) | 28 | #if defined(CONFIG_GK20A_VIDMEM) |
@@ -126,11 +128,11 @@ int nvgpu_dma_alloc_flags_sys(struct gk20a *g, unsigned long flags, | |||
126 | } | 128 | } |
127 | 129 | ||
128 | if (flags & NVGPU_DMA_NO_KERNEL_MAPPING) | 130 | if (flags & NVGPU_DMA_NO_KERNEL_MAPPING) |
129 | err = gk20a_get_sgtable_from_pages(d, &mem->priv.sgt, | 131 | err = nvgpu_get_sgtable_from_pages(g, &mem->priv.sgt, |
130 | mem->priv.pages, | 132 | mem->priv.pages, |
131 | iova, size); | 133 | iova, size); |
132 | else { | 134 | else { |
133 | err = gk20a_get_sgtable(d, &mem->priv.sgt, mem->cpu_va, | 135 | err = nvgpu_get_sgtable(g, &mem->priv.sgt, mem->cpu_va, |
134 | iova, size); | 136 | iova, size); |
135 | memset(mem->cpu_va, 0, size); | 137 | memset(mem->cpu_va, 0, size); |
136 | } | 138 | } |
@@ -359,7 +361,7 @@ static void nvgpu_dma_free_sys(struct gk20a *g, struct nvgpu_mem *mem) | |||
359 | } | 361 | } |
360 | 362 | ||
361 | if (mem->priv.sgt) | 363 | if (mem->priv.sgt) |
362 | gk20a_free_sgtable(g, &mem->priv.sgt); | 364 | nvgpu_free_sgtable(g, &mem->priv.sgt); |
363 | 365 | ||
364 | mem->size = 0; | 366 | mem->size = 0; |
365 | mem->aperture = APERTURE_INVALID; | 367 | mem->aperture = APERTURE_INVALID; |
@@ -389,7 +391,7 @@ static void nvgpu_dma_free_vid(struct gk20a *g, struct nvgpu_mem *mem) | |||
389 | nvgpu_memset(g, mem, 0, 0, mem->size); | 391 | nvgpu_memset(g, mem, 0, 0, mem->size); |
390 | nvgpu_free(mem->allocator, | 392 | nvgpu_free(mem->allocator, |
391 | (u64)get_vidmem_page_alloc(mem->priv.sgt->sgl)); | 393 | (u64)get_vidmem_page_alloc(mem->priv.sgt->sgl)); |
392 | gk20a_free_sgtable(g, &mem->priv.sgt); | 394 | nvgpu_free_sgtable(g, &mem->priv.sgt); |
393 | 395 | ||
394 | mem->size = 0; | 396 | mem->size = 0; |
395 | mem->aperture = APERTURE_INVALID; | 397 | mem->aperture = APERTURE_INVALID; |
@@ -412,9 +414,74 @@ void nvgpu_dma_free(struct gk20a *g, struct nvgpu_mem *mem) | |||
412 | void nvgpu_dma_unmap_free(struct vm_gk20a *vm, struct nvgpu_mem *mem) | 414 | void nvgpu_dma_unmap_free(struct vm_gk20a *vm, struct nvgpu_mem *mem) |
413 | { | 415 | { |
414 | if (mem->gpu_va) | 416 | if (mem->gpu_va) |
415 | gk20a_gmmu_unmap(vm, mem->gpu_va, mem->size, | 417 | gk20a_gmmu_unmap(vm, mem->gpu_va, |
416 | gk20a_mem_flag_none); | 418 | mem->size, gk20a_mem_flag_none); |
417 | mem->gpu_va = 0; | 419 | mem->gpu_va = 0; |
418 | 420 | ||
419 | nvgpu_dma_free(vm->mm->g, mem); | 421 | nvgpu_dma_free(vm->mm->g, mem); |
420 | } | 422 | } |
423 | |||
424 | int nvgpu_get_sgtable(struct gk20a *g, struct sg_table **sgt, | ||
425 | void *cpuva, u64 iova, size_t size) | ||
426 | { | ||
427 | int err = 0; | ||
428 | struct sg_table *tbl; | ||
429 | |||
430 | tbl = nvgpu_kzalloc(g, sizeof(struct sg_table)); | ||
431 | if (!tbl) { | ||
432 | err = -ENOMEM; | ||
433 | goto fail; | ||
434 | } | ||
435 | |||
436 | err = dma_get_sgtable(dev_from_gk20a(g), tbl, cpuva, iova, size); | ||
437 | if (err) | ||
438 | goto fail; | ||
439 | |||
440 | sg_dma_address(tbl->sgl) = iova; | ||
441 | *sgt = tbl; | ||
442 | |||
443 | return 0; | ||
444 | |||
445 | fail: | ||
446 | if (tbl) | ||
447 | nvgpu_kfree(g, tbl); | ||
448 | |||
449 | return err; | ||
450 | } | ||
451 | |||
452 | int nvgpu_get_sgtable_from_pages(struct gk20a *g, struct sg_table **sgt, | ||
453 | struct page **pages, u64 iova, size_t size) | ||
454 | { | ||
455 | int err = 0; | ||
456 | struct sg_table *tbl; | ||
457 | |||
458 | tbl = nvgpu_kzalloc(g, sizeof(struct sg_table)); | ||
459 | if (!tbl) { | ||
460 | err = -ENOMEM; | ||
461 | goto fail; | ||
462 | } | ||
463 | |||
464 | err = sg_alloc_table_from_pages(tbl, pages, | ||
465 | DIV_ROUND_UP(size, PAGE_SIZE), | ||
466 | 0, size, GFP_KERNEL); | ||
467 | if (err) | ||
468 | goto fail; | ||
469 | |||
470 | sg_dma_address(tbl->sgl) = iova; | ||
471 | *sgt = tbl; | ||
472 | |||
473 | return 0; | ||
474 | |||
475 | fail: | ||
476 | if (tbl) | ||
477 | nvgpu_kfree(g, tbl); | ||
478 | |||
479 | return err; | ||
480 | } | ||
481 | |||
482 | void nvgpu_free_sgtable(struct gk20a *g, struct sg_table **sgt) | ||
483 | { | ||
484 | sg_free_table(*sgt); | ||
485 | nvgpu_kfree(g, *sgt); | ||
486 | *sgt = NULL; | ||
487 | } | ||
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 @@ | |||
20 | #include <nvgpu/log.h> | 20 | #include <nvgpu/log.h> |
21 | #include <nvgpu/bug.h> | 21 | #include <nvgpu/bug.h> |
22 | 22 | ||
23 | #include <nvgpu/linux/dma.h> | ||
24 | |||
23 | #include "gk20a/gk20a.h" | 25 | #include "gk20a/gk20a.h" |
24 | #include "gk20a/mm_gk20a.h" | 26 | #include "gk20a/mm_gk20a.h" |
25 | 27 | ||
@@ -286,11 +288,11 @@ int nvgpu_mem_create_from_mem(struct gk20a *g, | |||
286 | * is passed to us. This table gets freed by the dma free routines. | 288 | * is passed to us. This table gets freed by the dma free routines. |
287 | */ | 289 | */ |
288 | if (src->priv.flags & NVGPU_DMA_NO_KERNEL_MAPPING) | 290 | if (src->priv.flags & NVGPU_DMA_NO_KERNEL_MAPPING) |
289 | ret = gk20a_get_sgtable_from_pages(g->dev, &dest->priv.sgt, | 291 | ret = nvgpu_get_sgtable_from_pages(g, &dest->priv.sgt, |
290 | src->priv.pages + start_page, | 292 | src->priv.pages + start_page, |
291 | new_iova, size); | 293 | new_iova, size); |
292 | else | 294 | else |
293 | ret = gk20a_get_sgtable(g->dev, &dest->priv.sgt, dest->cpu_va, | 295 | ret = nvgpu_get_sgtable(g, &dest->priv.sgt, dest->cpu_va, |
294 | new_iova, size); | 296 | new_iova, size); |
295 | 297 | ||
296 | return ret; | 298 | 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 @@ | |||
38 | #include <nvgpu/bug.h> | 38 | #include <nvgpu/bug.h> |
39 | #include <nvgpu/log2.h> | 39 | #include <nvgpu/log2.h> |
40 | 40 | ||
41 | #include <nvgpu/linux/dma.h> | ||
42 | |||
41 | #include "gk20a.h" | 43 | #include "gk20a.h" |
42 | #include "mm_gk20a.h" | 44 | #include "mm_gk20a.h" |
43 | #include "fence_gk20a.h" | 45 | #include "fence_gk20a.h" |
@@ -2621,7 +2623,7 @@ static void gk20a_vidmem_clear_mem_worker(struct work_struct *work) | |||
2621 | gk20a_gmmu_clear_vidmem_mem(g, mem); | 2623 | gk20a_gmmu_clear_vidmem_mem(g, mem); |
2622 | nvgpu_free(mem->allocator, | 2624 | nvgpu_free(mem->allocator, |
2623 | (u64)get_vidmem_page_alloc(mem->priv.sgt->sgl)); | 2625 | (u64)get_vidmem_page_alloc(mem->priv.sgt->sgl)); |
2624 | gk20a_free_sgtable(g, &mem->priv.sgt); | 2626 | nvgpu_free_sgtable(g, &mem->priv.sgt); |
2625 | 2627 | ||
2626 | WARN_ON(atomic64_sub_return(mem->size, | 2628 | WARN_ON(atomic64_sub_return(mem->size, |
2627 | &g->mm.vidmem.bytes_pending) < 0); | 2629 | &g->mm.vidmem.bytes_pending) < 0); |
@@ -2668,75 +2670,6 @@ void gk20a_gmmu_unmap(struct vm_gk20a *vm, | |||
2668 | nvgpu_mutex_release(&vm->update_gmmu_lock); | 2670 | nvgpu_mutex_release(&vm->update_gmmu_lock); |
2669 | } | 2671 | } |
2670 | 2672 | ||
2671 | /* get sg_table from already allocated buffer */ | ||
2672 | int gk20a_get_sgtable(struct device *d, struct sg_table **sgt, | ||
2673 | void *cpuva, u64 iova, | ||
2674 | size_t size) | ||
2675 | { | ||
2676 | struct gk20a *g = get_gk20a(d); | ||
2677 | |||
2678 | int err = 0; | ||
2679 | *sgt = nvgpu_kzalloc(g, sizeof(struct sg_table)); | ||
2680 | if (!(*sgt)) { | ||
2681 | nvgpu_err(g, "failed to allocate memory\n"); | ||
2682 | err = -ENOMEM; | ||
2683 | goto fail; | ||
2684 | } | ||
2685 | err = dma_get_sgtable(d, *sgt, | ||
2686 | cpuva, iova, | ||
2687 | size); | ||
2688 | if (err) { | ||
2689 | nvgpu_err(g, "failed to create sg table\n"); | ||
2690 | goto fail; | ||
2691 | } | ||
2692 | sg_dma_address((*sgt)->sgl) = iova; | ||
2693 | |||
2694 | return 0; | ||
2695 | fail: | ||
2696 | if (*sgt) { | ||
2697 | nvgpu_kfree(g, *sgt); | ||
2698 | *sgt = NULL; | ||
2699 | } | ||
2700 | return err; | ||
2701 | } | ||
2702 | |||
2703 | int gk20a_get_sgtable_from_pages(struct device *d, struct sg_table **sgt, | ||
2704 | struct page **pages, u64 iova, | ||
2705 | size_t size) | ||
2706 | { | ||
2707 | int err = 0; | ||
2708 | struct gk20a *g = get_gk20a(d); | ||
2709 | |||
2710 | *sgt = nvgpu_kzalloc(g, sizeof(struct sg_table)); | ||
2711 | if (!(*sgt)) { | ||
2712 | nvgpu_err(g, "failed to allocate memory\n"); | ||
2713 | err = -ENOMEM; | ||
2714 | goto fail; | ||
2715 | } | ||
2716 | err = sg_alloc_table_from_pages(*sgt, pages, | ||
2717 | DIV_ROUND_UP(size, PAGE_SIZE), 0, size, GFP_KERNEL); | ||
2718 | if (err) { | ||
2719 | nvgpu_err(g, "failed to allocate sg_table\n"); | ||
2720 | goto fail; | ||
2721 | } | ||
2722 | sg_dma_address((*sgt)->sgl) = iova; | ||
2723 | |||
2724 | return 0; | ||
2725 | fail: | ||
2726 | if (*sgt) { | ||
2727 | nvgpu_kfree(get_gk20a(d), *sgt); | ||
2728 | *sgt = NULL; | ||
2729 | } | ||
2730 | return err; | ||
2731 | } | ||
2732 | |||
2733 | void gk20a_free_sgtable(struct gk20a *g, struct sg_table **sgt) | ||
2734 | { | ||
2735 | sg_free_table(*sgt); | ||
2736 | nvgpu_kfree(g, *sgt); | ||
2737 | *sgt = NULL; | ||
2738 | } | ||
2739 | |||
2740 | u64 gk20a_mm_smmu_vaddr_translate(struct gk20a *g, dma_addr_t iova) | 2673 | u64 gk20a_mm_smmu_vaddr_translate(struct gk20a *g, dma_addr_t iova) |
2741 | { | 2674 | { |
2742 | /* ensure it is not vidmem allocation */ | 2675 | /* 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, | |||
497 | 497 | ||
498 | int gk20a_mm_suspend(struct gk20a *g); | 498 | int gk20a_mm_suspend(struct gk20a *g); |
499 | 499 | ||
500 | int gk20a_get_sgtable(struct device *d, struct sg_table **sgt, | ||
501 | void *cpuva, u64 iova, | ||
502 | size_t size); | ||
503 | |||
504 | int gk20a_get_sgtable_from_pages(struct device *d, struct sg_table **sgt, | ||
505 | struct page **pages, u64 iova, | ||
506 | size_t size); | ||
507 | |||
508 | void gk20a_free_sgtable(struct gk20a *g, struct sg_table **sgt); | ||
509 | |||
510 | u64 gk20a_mm_iova_addr(struct gk20a *g, struct scatterlist *sgl, | 500 | u64 gk20a_mm_iova_addr(struct gk20a *g, struct scatterlist *sgl, |
511 | u32 flags); | 501 | u32 flags); |
512 | u64 gk20a_mm_smmu_vaddr_translate(struct gk20a *g, dma_addr_t iova); | 502 | 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 @@ | |||
25 | #include <nvgpu/acr/nvgpu_acr.h> | 25 | #include <nvgpu/acr/nvgpu_acr.h> |
26 | #include <nvgpu/firmware.h> | 26 | #include <nvgpu/firmware.h> |
27 | 27 | ||
28 | #include <nvgpu/linux/dma.h> | ||
29 | |||
28 | #include "gk20a/gk20a.h" | 30 | #include "gk20a/gk20a.h" |
29 | #include "gk20a/pmu_gk20a.h" | 31 | #include "gk20a/pmu_gk20a.h" |
30 | #include "mm_gm20b.h" | 32 | #include "mm_gm20b.h" |
@@ -456,7 +458,7 @@ int prepare_ucode_blob(struct gk20a *g) | |||
456 | gm20b_dbg_pmu("prepare ucode blob return 0\n"); | 458 | gm20b_dbg_pmu("prepare ucode blob return 0\n"); |
457 | free_acr_resources(g, plsfm); | 459 | free_acr_resources(g, plsfm); |
458 | free_sgt: | 460 | free_sgt: |
459 | gk20a_free_sgtable(g, &sgt); | 461 | nvgpu_free_sgtable(g, &sgt); |
460 | return err; | 462 | return err; |
461 | } | 463 | } |
462 | 464 | ||
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 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #ifndef __NVGPU_LINUX_DMA_H__ | ||
18 | #define __NVGPU_LINUX_DMA_H__ | ||
19 | |||
20 | /** | ||
21 | * Functions used internally for building the backing SGTs for nvgpu_mems. | ||
22 | */ | ||
23 | |||
24 | int nvgpu_get_sgtable(struct gk20a *g, struct sg_table **sgt, | ||
25 | void *cpuva, u64 iova, | ||
26 | size_t size); | ||
27 | |||
28 | int nvgpu_get_sgtable_from_pages(struct gk20a *g, struct sg_table **sgt, | ||
29 | struct page **pages, u64 iova, | ||
30 | size_t size); | ||
31 | |||
32 | void nvgpu_free_sgtable(struct gk20a *g, struct sg_table **sgt); | ||
33 | |||
34 | #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 @@ | |||
51 | #include <nvgpu/kmem.h> | 51 | #include <nvgpu/kmem.h> |
52 | #include <nvgpu/bug.h> | 52 | #include <nvgpu/bug.h> |
53 | 53 | ||
54 | #include <nvgpu/linux/dma.h> | ||
55 | |||
54 | #include "gk20a/gk20a.h" | 56 | #include "gk20a/gk20a.h" |
55 | #include "gk20a/hal_gk20a.h" | 57 | #include "gk20a/hal_gk20a.h" |
56 | #include "gk20a/platform_gk20a.h" | 58 | #include "gk20a/platform_gk20a.h" |
@@ -143,7 +145,7 @@ static void gk20a_tegra_secure_destroy(struct gk20a *g, | |||
143 | dma_free_attrs(&tegra_vpr_dev, desc->mem.size, | 145 | dma_free_attrs(&tegra_vpr_dev, desc->mem.size, |
144 | (void *)(uintptr_t)pa, | 146 | (void *)(uintptr_t)pa, |
145 | pa, __DMA_ATTR(attrs)); | 147 | pa, __DMA_ATTR(attrs)); |
146 | gk20a_free_sgtable(g, &desc->mem.priv.sgt); | 148 | nvgpu_free_sgtable(g, &desc->mem.priv.sgt); |
147 | desc->mem.priv.sgt = NULL; | 149 | desc->mem.priv.sgt = NULL; |
148 | } | 150 | } |
149 | } | 151 | } |