summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2015-02-26 17:37:43 -0500
committerDan Willemsen <dwillemsen@nvidia.com>2015-04-04 21:59:26 -0400
commit7290a6cbd5d03145d6f1ca4c3eacba40f6d4f93c (patch)
treede452c09f5eef76af273041dc64997fdc351dbd6 /drivers/gpu/nvgpu/gk20a/mm_gk20a.c
parentbb51cf9ec6482b50f3020179965ef82f58d91a0a (diff)
gpu: nvgpu: Implement common allocator and mem_desc
Introduce mem_desc, which holds all information needed for a buffer. Implement helper functions for allocation and freeing that use this data type. Change-Id: I82c88595d058d4fb8c5c5fbf19d13269e48e422f Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/712699
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/mm_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c135
1 files changed, 79 insertions, 56 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index c3895a53..954249c6 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -268,7 +268,7 @@ static int gk20a_init_mm_reset_enable_hw(struct gk20a *g)
268 return 0; 268 return 0;
269} 269}
270 270
271static void gk20a_remove_vm(struct vm_gk20a *vm, struct inst_desc *inst_block) 271static void gk20a_remove_vm(struct vm_gk20a *vm, struct mem_desc *inst_block)
272{ 272{
273 struct gk20a *g = vm->mm->g; 273 struct gk20a *g = vm->mm->g;
274 274
@@ -335,8 +335,8 @@ int gk20a_init_mm_setup_sw(struct gk20a *g)
335int gk20a_init_mm_setup_hw(struct gk20a *g) 335int gk20a_init_mm_setup_hw(struct gk20a *g)
336{ 336{
337 struct mm_gk20a *mm = &g->mm; 337 struct mm_gk20a *mm = &g->mm;
338 struct inst_desc *inst_block = &mm->bar1.inst_block; 338 struct mem_desc *inst_block = &mm->bar1.inst_block;
339 phys_addr_t inst_pa = inst_block->cpu_pa; 339 phys_addr_t inst_pa = gk20a_mem_phys(inst_block);
340 int err; 340 int err;
341 341
342 gk20a_dbg_fn(""); 342 gk20a_dbg_fn("");
@@ -1516,54 +1516,95 @@ u64 gk20a_gmmu_map(struct vm_gk20a *vm,
1516 return vaddr; 1516 return vaddr;
1517} 1517}
1518 1518
1519int gk20a_gmmu_alloc_map(struct vm_gk20a *vm, 1519int gk20a_gmmu_alloc(struct gk20a *g, size_t size, struct mem_desc *mem)
1520 size_t size, struct mem_desc *mem) 1520{
1521 return gk20a_gmmu_alloc_attr(g, 0, size, mem);
1522}
1523
1524int gk20a_gmmu_alloc_attr(struct gk20a *g, enum dma_attr attr, size_t size, struct mem_desc *mem)
1521{ 1525{
1522 struct gk20a *g = vm->mm->g;
1523 struct device *d = dev_from_gk20a(g); 1526 struct device *d = dev_from_gk20a(g);
1524 int err; 1527 int err;
1525 struct sg_table *sgt; 1528 dma_addr_t iova;
1529
1530 gk20a_dbg_fn("");
1531
1532 if (attr) {
1533 DEFINE_DMA_ATTRS(attrs);
1534 dma_set_attr(attr, &attrs);
1535 mem->cpu_va =
1536 dma_alloc_attrs(d, size, &iova, GFP_KERNEL, &attrs);
1537 } else {
1538 mem->cpu_va = dma_alloc_coherent(d, size, &iova, GFP_KERNEL);
1539 }
1526 1540
1527 mem->cpu_va = dma_alloc_coherent(d, size, &mem->iova, GFP_KERNEL);
1528 if (!mem->cpu_va) 1541 if (!mem->cpu_va)
1529 return -ENOMEM; 1542 return -ENOMEM;
1530 1543
1531 err = gk20a_get_sgtable(d, &sgt, mem->cpu_va, mem->iova, size); 1544 err = gk20a_get_sgtable(d, &mem->sgt, mem->cpu_va, iova, size);
1532 if (err) 1545 if (err)
1533 goto fail_free; 1546 goto fail_free;
1534 1547
1535 mem->gpu_va = gk20a_gmmu_map(vm, &sgt, size, 0, gk20a_mem_flag_none); 1548 mem->size = size;
1536 gk20a_free_sgtable(&sgt); 1549 memset(mem->cpu_va, 0, size);
1550
1551 gk20a_dbg_fn("done");
1552
1553 return 0;
1554
1555fail_free:
1556 dma_free_coherent(d, size, mem->cpu_va, iova);
1557 mem->cpu_va = NULL;
1558 mem->sgt = NULL;
1559 return err;
1560}
1561
1562void gk20a_gmmu_free(struct gk20a *g, struct mem_desc *mem)
1563{
1564 struct device *d = dev_from_gk20a(g);
1565
1566 if (mem->cpu_va)
1567 dma_free_coherent(d, mem->size, mem->cpu_va,
1568 sg_dma_address(mem->sgt->sgl));
1569 mem->cpu_va = NULL;
1570
1571 if (mem->sgt)
1572 gk20a_free_sgtable(&mem->sgt);
1573}
1574
1575int gk20a_gmmu_alloc_map(struct vm_gk20a *vm, size_t size, struct mem_desc *mem)
1576{
1577 return gk20a_gmmu_alloc_map_attr(vm, 0, size, mem);
1578}
1579
1580int gk20a_gmmu_alloc_map_attr(struct vm_gk20a *vm,
1581 enum dma_attr attr, size_t size, struct mem_desc *mem)
1582{
1583 int err = gk20a_gmmu_alloc_attr(vm->mm->g, attr, size, mem);
1584
1585 if (err)
1586 return err;
1587
1588 mem->gpu_va = gk20a_gmmu_map(vm, &mem->sgt, size, 0, gk20a_mem_flag_none);
1537 if (!mem->gpu_va) { 1589 if (!mem->gpu_va) {
1538 err = -ENOMEM; 1590 err = -ENOMEM;
1539 goto fail_free; 1591 goto fail_free;
1540 } 1592 }
1541 1593
1542 mem->size = size;
1543
1544 return 0; 1594 return 0;
1545 1595
1546fail_free: 1596fail_free:
1547 dma_free_coherent(d, size, mem->cpu_va, mem->iova); 1597 gk20a_gmmu_free(vm->mm->g, mem);
1548 mem->cpu_va = NULL;
1549 mem->iova = 0;
1550
1551 return err; 1598 return err;
1552} 1599}
1553 1600
1554void gk20a_gmmu_unmap_free(struct vm_gk20a *vm, struct mem_desc *mem) 1601void gk20a_gmmu_unmap_free(struct vm_gk20a *vm, struct mem_desc *mem)
1555{ 1602{
1556 struct gk20a *g = vm->mm->g;
1557 struct device *d = dev_from_gk20a(g);
1558
1559 if (mem->gpu_va) 1603 if (mem->gpu_va)
1560 gk20a_gmmu_unmap(vm, mem->gpu_va, mem->size, gk20a_mem_flag_none); 1604 gk20a_gmmu_unmap(vm, mem->gpu_va, mem->size, gk20a_mem_flag_none);
1561 mem->gpu_va = 0; 1605 mem->gpu_va = 0;
1562 1606
1563 if (mem->cpu_va) 1607 gk20a_gmmu_free(vm->mm->g, mem);
1564 dma_free_coherent(d, mem->size, mem->cpu_va, mem->iova);
1565 mem->cpu_va = NULL;
1566 mem->iova = 0;
1567} 1608}
1568 1609
1569dma_addr_t gk20a_mm_gpuva_to_iova_base(struct vm_gk20a *vm, u64 gpu_vaddr) 1610dma_addr_t gk20a_mm_gpuva_to_iova_base(struct vm_gk20a *vm, u64 gpu_vaddr)
@@ -2644,42 +2685,24 @@ void gk20a_deinit_vm(struct vm_gk20a *vm)
2644 kfree(vm->pdb.entries); 2685 kfree(vm->pdb.entries);
2645} 2686}
2646 2687
2647int gk20a_alloc_inst_block(struct gk20a *g, struct inst_desc *inst_block) 2688int gk20a_alloc_inst_block(struct gk20a *g, struct mem_desc *inst_block)
2648{ 2689{
2649 struct device *dev = dev_from_gk20a(g); 2690 struct device *dev = dev_from_gk20a(g);
2650 dma_addr_t iova; 2691 int err;
2651 2692
2652 inst_block->size = ram_in_alloc_size_v(); 2693 err = gk20a_gmmu_alloc(g, ram_in_alloc_size_v(), inst_block);
2653 inst_block->cpuva = dma_alloc_coherent(dev, inst_block->size, 2694 if (err) {
2654 &iova, GFP_KERNEL);
2655 if (!inst_block->cpuva) {
2656 gk20a_err(dev, "%s: memory allocation failed\n", __func__); 2695 gk20a_err(dev, "%s: memory allocation failed\n", __func__);
2657 return -ENOMEM; 2696 return err;
2658 }
2659
2660 inst_block->iova = iova;
2661 inst_block->cpu_pa = gk20a_get_phys_from_iova(dev, inst_block->iova);
2662 if (!inst_block->cpu_pa) {
2663 gk20a_err(dev, "%s: failed to get phys address\n", __func__);
2664 gk20a_free_inst_block(g, inst_block);
2665 return -ENOMEM;
2666 } 2697 }
2667 2698
2668 memset(inst_block->cpuva, 0, inst_block->size);
2669
2670 return 0; 2699 return 0;
2671} 2700}
2672 2701
2673void gk20a_free_inst_block(struct gk20a *g, struct inst_desc *inst_block) 2702void gk20a_free_inst_block(struct gk20a *g, struct mem_desc *inst_block)
2674{ 2703{
2675 struct device *dev = dev_from_gk20a(g); 2704 if (inst_block->cpu_va)
2676 2705 gk20a_gmmu_free(g, inst_block);
2677 if (inst_block->cpuva) {
2678 dma_free_coherent(dev, inst_block->size,
2679 inst_block->cpuva, inst_block->iova);
2680 }
2681
2682 memset(inst_block, 0, sizeof(*inst_block));
2683} 2706}
2684 2707
2685static int gk20a_init_bar1_vm(struct mm_gk20a *mm) 2708static int gk20a_init_bar1_vm(struct mm_gk20a *mm)
@@ -2687,7 +2710,7 @@ static int gk20a_init_bar1_vm(struct mm_gk20a *mm)
2687 int err; 2710 int err;
2688 struct vm_gk20a *vm = &mm->bar1.vm; 2711 struct vm_gk20a *vm = &mm->bar1.vm;
2689 struct gk20a *g = gk20a_from_mm(mm); 2712 struct gk20a *g = gk20a_from_mm(mm);
2690 struct inst_desc *inst_block = &mm->bar1.inst_block; 2713 struct mem_desc *inst_block = &mm->bar1.inst_block;
2691 u32 big_page_size = gk20a_get_platform(g->dev)->default_big_page_size; 2714 u32 big_page_size = gk20a_get_platform(g->dev)->default_big_page_size;
2692 2715
2693 mm->bar1.aperture_size = bar1_aperture_size_mb_gk20a() << 20; 2716 mm->bar1.aperture_size = bar1_aperture_size_mb_gk20a() << 20;
@@ -2713,7 +2736,7 @@ static int gk20a_init_system_vm(struct mm_gk20a *mm)
2713 int err; 2736 int err;
2714 struct vm_gk20a *vm = &mm->pmu.vm; 2737 struct vm_gk20a *vm = &mm->pmu.vm;
2715 struct gk20a *g = gk20a_from_mm(mm); 2738 struct gk20a *g = gk20a_from_mm(mm);
2716 struct inst_desc *inst_block = &mm->pmu.inst_block; 2739 struct mem_desc *inst_block = &mm->pmu.inst_block;
2717 u32 big_page_size = gk20a_get_platform(g->dev)->default_big_page_size; 2740 u32 big_page_size = gk20a_get_platform(g->dev)->default_big_page_size;
2718 2741
2719 mm->pmu.aperture_size = GK20A_PMU_VA_SIZE; 2742 mm->pmu.aperture_size = GK20A_PMU_VA_SIZE;
@@ -2739,7 +2762,7 @@ static int gk20a_init_hwpm(struct mm_gk20a *mm)
2739 int err; 2762 int err;
2740 struct vm_gk20a *vm = &mm->pmu.vm; 2763 struct vm_gk20a *vm = &mm->pmu.vm;
2741 struct gk20a *g = gk20a_from_mm(mm); 2764 struct gk20a *g = gk20a_from_mm(mm);
2742 struct inst_desc *inst_block = &mm->hwpm.inst_block; 2765 struct mem_desc *inst_block = &mm->hwpm.inst_block;
2743 2766
2744 err = gk20a_alloc_inst_block(g, inst_block); 2767 err = gk20a_alloc_inst_block(g, inst_block);
2745 if (err) 2768 if (err)
@@ -2763,13 +2786,13 @@ void gk20a_mm_init_pdb(struct gk20a *g, void *inst_ptr, u64 pdb_addr)
2763 ram_in_page_dir_base_hi_f(pdb_addr_hi)); 2786 ram_in_page_dir_base_hi_f(pdb_addr_hi));
2764} 2787}
2765 2788
2766void gk20a_init_inst_block(struct inst_desc *inst_block, struct vm_gk20a *vm, 2789void gk20a_init_inst_block(struct mem_desc *inst_block, struct vm_gk20a *vm,
2767 u32 big_page_size) 2790 u32 big_page_size)
2768{ 2791{
2769 struct gk20a *g = gk20a_from_vm(vm); 2792 struct gk20a *g = gk20a_from_vm(vm);
2770 u64 pde_addr = gk20a_mm_iova_addr(g, vm->pdb.sgt->sgl); 2793 u64 pde_addr = gk20a_mm_iova_addr(g, vm->pdb.sgt->sgl);
2771 phys_addr_t inst_pa = inst_block->cpu_pa; 2794 phys_addr_t inst_pa = gk20a_mem_phys(inst_block);
2772 void *inst_ptr = inst_block->cpuva; 2795 void *inst_ptr = inst_block->cpu_va;
2773 2796
2774 gk20a_dbg_info("inst block phys = 0x%llx, kv = 0x%p", 2797 gk20a_dbg_info("inst block phys = 0x%llx, kv = 0x%p",
2775 (u64)inst_pa, inst_ptr); 2798 (u64)inst_pa, inst_ptr);