summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
diff options
context:
space:
mode:
authorKonsta Holtta <kholtta@nvidia.com>2016-05-02 09:11:17 -0400
committerTerje Bergstrom <tbergstrom@nvidia.com>2016-05-03 16:27:58 -0400
commitb9cb2481adb24e079757b18ace8e214b6617b7ce (patch)
treef70cac665f05b6bb37e3a34232b44584d65a9464 /drivers/gpu/nvgpu/gk20a/mm_gk20a.c
parent98679b0ba4fc1b1f378f1802108d0b04f790965d (diff)
gpu: nvgpu: don't alloc gmmu bufs manually
Use gk20a_gmmu_{alloc,free}() instead of duplicating their code for page tables. The linsim-specific special case is kept as-is. JIRA DNVGPU-23 JIRA DNVGPU-20 Change-Id: I66d772337bad5d081256b13877c4e713ea8b634a Signed-off-by: Konsta Holtta <kholtta@nvidia.com> Reviewed-on: http://git-master/r/1139695 Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Tested-by: Terje Bergstrom <tbergstrom@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/mm_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c95
1 files changed, 27 insertions, 68 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index 3bb5ddb4..79fba6ce 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -563,9 +563,11 @@ static int alloc_gmmu_phys_pages(struct vm_gk20a *vm, u32 order,
563 563
564 gk20a_dbg_fn(""); 564 gk20a_dbg_fn("");
565 565
566 /* note: mem_desc slightly abused (wrt. alloc_gmmu_pages) */
567
566 pages = alloc_pages(GFP_KERNEL, order); 568 pages = alloc_pages(GFP_KERNEL, order);
567 if (!pages) { 569 if (!pages) {
568 gk20a_dbg(gpu_dbg_pte, "alloc_pages failed\n"); 570 gk20a_dbg(gpu_dbg_pte, "alloc_pages failed");
569 goto err_out; 571 goto err_out;
570 } 572 }
571 entry->mem.sgt = kzalloc(sizeof(*entry->mem.sgt), GFP_KERNEL); 573 entry->mem.sgt = kzalloc(sizeof(*entry->mem.sgt), GFP_KERNEL);
@@ -575,7 +577,7 @@ static int alloc_gmmu_phys_pages(struct vm_gk20a *vm, u32 order,
575 } 577 }
576 err = sg_alloc_table(entry->mem.sgt, 1, GFP_KERNEL); 578 err = sg_alloc_table(entry->mem.sgt, 1, GFP_KERNEL);
577 if (err) { 579 if (err) {
578 gk20a_dbg(gpu_dbg_pte, "sg_alloc_table failed\n"); 580 gk20a_dbg(gpu_dbg_pte, "sg_alloc_table failed");
579 goto err_sg_table; 581 goto err_sg_table;
580 } 582 }
581 sg_set_page(entry->mem.sgt->sgl, pages, len, 0); 583 sg_set_page(entry->mem.sgt->sgl, pages, len, 0);
@@ -598,12 +600,16 @@ static void free_gmmu_phys_pages(struct vm_gk20a *vm,
598 struct gk20a_mm_entry *entry) 600 struct gk20a_mm_entry *entry)
599{ 601{
600 gk20a_dbg_fn(""); 602 gk20a_dbg_fn("");
603
604 /* note: mem_desc slightly abused (wrt. free_gmmu_pages) */
605
601 free_pages((unsigned long)entry->mem.cpu_va, get_order(entry->mem.size)); 606 free_pages((unsigned long)entry->mem.cpu_va, get_order(entry->mem.size));
602 entry->mem.cpu_va = NULL; 607 entry->mem.cpu_va = NULL;
603 608
604 sg_free_table(entry->mem.sgt); 609 sg_free_table(entry->mem.sgt);
605 kfree(entry->mem.sgt); 610 kfree(entry->mem.sgt);
606 entry->mem.sgt = NULL; 611 entry->mem.sgt = NULL;
612 entry->mem.size = 0;
607} 613}
608 614
609static int map_gmmu_phys_pages(struct gk20a_mm_entry *entry) 615static int map_gmmu_phys_pages(struct gk20a_mm_entry *entry)
@@ -625,83 +631,43 @@ static int alloc_gmmu_pages(struct vm_gk20a *vm, u32 order,
625 struct gk20a_mm_entry *entry) 631 struct gk20a_mm_entry *entry)
626{ 632{
627 struct device *d = dev_from_vm(vm); 633 struct device *d = dev_from_vm(vm);
634 struct gk20a *g = gk20a_from_vm(vm);
628 u32 num_pages = 1 << order; 635 u32 num_pages = 1 << order;
629 u32 len = num_pages * PAGE_SIZE; 636 u32 len = num_pages * PAGE_SIZE;
630 dma_addr_t iova; 637 int err;
631 DEFINE_DMA_ATTRS(attrs);
632 void *cpuva;
633 int err = 0;
634 638
635 gk20a_dbg_fn(""); 639 gk20a_dbg_fn("");
636 640
637 if (tegra_platform_is_linsim()) 641 if (tegra_platform_is_linsim())
638 return alloc_gmmu_phys_pages(vm, order, entry); 642 return alloc_gmmu_phys_pages(vm, order, entry);
639 643
640 entry->mem.size = len;
641
642 /* 644 /*
643 * On arm32 we're limited by vmalloc space, so we do not map pages by 645 * On arm32 we're limited by vmalloc space, so we do not map pages by
644 * default. 646 * default.
645 */ 647 */
646 if (IS_ENABLED(CONFIG_ARM64)) { 648 if (IS_ENABLED(CONFIG_ARM64))
647 cpuva = dma_zalloc_coherent(d, len, &iova, GFP_KERNEL); 649 err = gk20a_gmmu_alloc(g, len, &entry->mem);
648 if (!cpuva) { 650 else
649 gk20a_err(d, "memory allocation failed\n"); 651 err = gk20a_gmmu_alloc_attr(g, DMA_ATTR_NO_KERNEL_MAPPING,
650 goto err_out; 652 len, &entry->mem);
651 }
652
653 err = gk20a_get_sgtable(d, &entry->mem.sgt, cpuva, iova, len);
654 if (err) {
655 gk20a_err(d, "sgt allocation failed\n");
656 goto err_free;
657 }
658
659 entry->mem.cpu_va = cpuva;
660 } else {
661 struct page **pages;
662
663 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
664 pages = dma_alloc_attrs(d, len, &iova, GFP_KERNEL, &attrs);
665 if (!pages) {
666 gk20a_err(d, "memory allocation failed\n");
667 goto err_out;
668 }
669 653
670 err = gk20a_get_sgtable_from_pages(d, &entry->mem.sgt, pages,
671 iova, len);
672 if (err) {
673 gk20a_err(d, "sgt allocation failed\n");
674 goto err_free;
675 }
676 654
677 entry->mem.pages = pages; 655 if (err) {
656 gk20a_err(d, "memory allocation failed");
657 return -ENOMEM;
678 } 658 }
679 659
680 return 0; 660 return 0;
681
682err_free:
683 if (IS_ENABLED(CONFIG_ARM64)) {
684 dma_free_coherent(d, len, entry->mem.cpu_va, iova);
685 cpuva = NULL;
686 } else {
687 dma_free_attrs(d, len, entry->mem.pages, iova, &attrs);
688 entry->mem.pages = NULL;
689 }
690 iova = 0;
691err_out:
692 return -ENOMEM;
693} 661}
694 662
695void free_gmmu_pages(struct vm_gk20a *vm, 663void free_gmmu_pages(struct vm_gk20a *vm,
696 struct gk20a_mm_entry *entry) 664 struct gk20a_mm_entry *entry)
697{ 665{
698 struct device *d = dev_from_vm(vm); 666 struct gk20a *g = gk20a_from_vm(vm);
699 u64 iova;
700 DEFINE_DMA_ATTRS(attrs);
701 667
702 gk20a_dbg_fn(""); 668 gk20a_dbg_fn("");
703 669
704 if (!entry->mem.sgt) 670 if (!entry->mem.size)
705 return; 671 return;
706 672
707 if (tegra_platform_is_linsim()) { 673 if (tegra_platform_is_linsim()) {
@@ -709,24 +675,15 @@ void free_gmmu_pages(struct vm_gk20a *vm,
709 return; 675 return;
710 } 676 }
711 677
712 iova = sg_dma_address(entry->mem.sgt->sgl);
713
714 gk20a_free_sgtable(&entry->mem.sgt);
715
716 /* 678 /*
717 * On arm32 we're limited by vmalloc space, so we do not map pages by 679 * On arm32 we're limited by vmalloc space, so we do not map pages by
718 * default. 680 * default.
719 */ 681 */
720 if (IS_ENABLED(CONFIG_ARM64)) { 682 if (IS_ENABLED(CONFIG_ARM64))
721 dma_free_coherent(d, entry->mem.size, entry->mem.cpu_va, iova); 683 gk20a_gmmu_free(g, &entry->mem);
722 entry->mem.cpu_va = NULL; 684 else
723 } else { 685 gk20a_gmmu_free_attr(g, DMA_ATTR_NO_KERNEL_MAPPING,
724 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs); 686 &entry->mem);
725 dma_free_attrs(d, entry->mem.size, entry->mem.pages, iova, &attrs);
726 entry->mem.pages = NULL;
727 }
728 entry->mem.size = 0;
729 entry->mem.sgt = NULL;
730} 687}
731 688
732int map_gmmu_pages(struct gk20a_mm_entry *entry) 689int map_gmmu_pages(struct gk20a_mm_entry *entry)
@@ -2140,6 +2097,8 @@ void gk20a_gmmu_free_attr(struct gk20a *g, enum dma_attr attr,
2140 2097
2141 if (mem->sgt) 2098 if (mem->sgt)
2142 gk20a_free_sgtable(&mem->sgt); 2099 gk20a_free_sgtable(&mem->sgt);
2100
2101 mem->size = 0;
2143} 2102}
2144 2103
2145void gk20a_gmmu_free(struct gk20a *g, struct mem_desc *mem) 2104void gk20a_gmmu_free(struct gk20a *g, struct mem_desc *mem)