diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/dma.c')
-rw-r--r-- | drivers/gpu/nvgpu/common/linux/dma.c | 79 |
1 files changed, 73 insertions, 6 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 | } | ||