summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
diff options
context:
space:
mode:
authorLakshmanan M <lm@nvidia.com>2016-06-29 06:36:39 -0400
committerVijayakumar Subbu <vsubbu@nvidia.com>2016-07-20 06:09:28 -0400
commit89aecd1202b49727e940069f2a6feb5c3cf4c927 (patch)
tree8a0d3a493b389167ce1d93e55f23e114ec2cbd38 /drivers/gpu/nvgpu/gk20a/mm_gk20a.c
parentf6ebdc5f2916706f7a61983567420e0985faeeb1 (diff)
gpu: nvgpu: Add nvgpu infra to allow kernel to create privileged CE channels
Added interface to allow kernel to create privileged CE channels for page migration and clearing support between sysmem and videmem. JIRA DNVGPU-53 Change-Id: I3e18d18403809c9e64fa45d40b6c4e3844992506 Signed-off-by: Lakshmanan M <lm@nvidia.com> Reviewed-on: http://git-master/r/1173085 GVS: Gerrit_Virtual_Submit Reviewed-by: Vijayakumar Subbu <vsubbu@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/mm_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c86
1 files changed, 84 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
index 750ce10c..7b2174bc 100644
--- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
@@ -393,7 +393,7 @@ static int __must_check gk20a_init_system_vm(struct mm_gk20a *mm);
393static int __must_check gk20a_init_bar1_vm(struct mm_gk20a *mm); 393static int __must_check gk20a_init_bar1_vm(struct mm_gk20a *mm);
394static int __must_check gk20a_init_hwpm(struct mm_gk20a *mm); 394static int __must_check gk20a_init_hwpm(struct mm_gk20a *mm);
395static int __must_check gk20a_init_cde_vm(struct mm_gk20a *mm); 395static int __must_check gk20a_init_cde_vm(struct mm_gk20a *mm);
396 396static int __must_check gk20a_init_ce_vm(struct mm_gk20a *mm);
397 397
398struct gk20a_dmabuf_priv { 398struct gk20a_dmabuf_priv {
399 struct mutex lock; 399 struct mutex lock;
@@ -702,6 +702,7 @@ void gk20a_remove_vm(struct vm_gk20a *vm, struct mem_desc *inst_block)
702static void gk20a_remove_mm_support(struct mm_gk20a *mm) 702static void gk20a_remove_mm_support(struct mm_gk20a *mm)
703{ 703{
704 struct gk20a *g = gk20a_from_mm(mm); 704 struct gk20a *g = gk20a_from_mm(mm);
705 struct gk20a_platform *platform = gk20a_get_platform(g->dev);
705 706
706 if (g->ops.mm.remove_bar2_vm) 707 if (g->ops.mm.remove_bar2_vm)
707 g->ops.mm.remove_bar2_vm(g); 708 g->ops.mm.remove_bar2_vm(g);
@@ -709,6 +710,14 @@ static void gk20a_remove_mm_support(struct mm_gk20a *mm)
709 gk20a_remove_vm(&mm->pmu.vm, &mm->pmu.inst_block); 710 gk20a_remove_vm(&mm->pmu.vm, &mm->pmu.inst_block);
710 gk20a_free_inst_block(gk20a_from_mm(mm), &mm->hwpm.inst_block); 711 gk20a_free_inst_block(gk20a_from_mm(mm), &mm->hwpm.inst_block);
711 gk20a_vm_remove_support_nofree(&mm->cde.vm); 712 gk20a_vm_remove_support_nofree(&mm->cde.vm);
713
714 if (mm->ce_vidmem_ctx_id != ~0)
715 gk20a_ce_delete_context(g->dev, mm->ce_vidmem_ctx_id );
716
717 mm->ce_vidmem_ctx_id = ~0;
718
719 if (platform->has_ce)
720 gk20a_vm_remove_support_nofree(&mm->ce.vm);
712} 721}
713 722
714static int gk20a_alloc_sysmem_flush(struct gk20a *g) 723static int gk20a_alloc_sysmem_flush(struct gk20a *g)
@@ -754,6 +763,7 @@ int gk20a_init_mm_setup_sw(struct gk20a *g)
754{ 763{
755 struct mm_gk20a *mm = &g->mm; 764 struct mm_gk20a *mm = &g->mm;
756 int err; 765 int err;
766 struct gk20a_platform *platform = gk20a_get_platform(g->dev);
757 767
758 gk20a_dbg_fn(""); 768 gk20a_dbg_fn("");
759 769
@@ -775,6 +785,8 @@ int gk20a_init_mm_setup_sw(struct gk20a *g)
775 785
776 gk20a_init_pramin(mm); 786 gk20a_init_pramin(mm);
777 787
788 mm->ce_vidmem_ctx_id = ~0;
789
778 err = gk20a_init_vidmem(mm); 790 err = gk20a_init_vidmem(mm);
779 if (err) 791 if (err)
780 return err; 792 return err;
@@ -804,6 +816,12 @@ int gk20a_init_mm_setup_sw(struct gk20a *g)
804 if (err) 816 if (err)
805 return err; 817 return err;
806 818
819 if (platform->has_ce) {
820 err = gk20a_init_ce_vm(mm);
821 if (err)
822 return err;
823 }
824
807 /* set vm_alloc_share op here as gk20a_as_alloc_share needs it */ 825 /* set vm_alloc_share op here as gk20a_as_alloc_share needs it */
808 g->ops.mm.vm_alloc_share = gk20a_vm_alloc_share; 826 g->ops.mm.vm_alloc_share = gk20a_vm_alloc_share;
809 mm->remove_support = gk20a_remove_mm_support; 827 mm->remove_support = gk20a_remove_mm_support;
@@ -881,6 +899,25 @@ int gk20a_init_mm_support(struct gk20a *g)
881 return err; 899 return err;
882} 900}
883 901
902void gk20a_init_mm_ce_context(struct gk20a *g)
903{
904#if defined(CONFIG_GK20A_VIDMEM)
905 if (g->mm.vidmem_size && (g->mm.ce_vidmem_ctx_id == ~0)) {
906 g->mm.ce_vidmem_ctx_id =
907 gk20a_ce_create_context_with_cb(g->dev,
908 gk20a_fifo_get_fast_ce_runlist_id(g),
909 -1,
910 -1,
911 -1,
912 NULL);
913
914 if (g->mm.ce_vidmem_ctx_id == ~0)
915 gk20a_err(g->dev,
916 "Failed to allocate CE context for vidmem page clearing support");
917 }
918#endif
919}
920
884static int alloc_gmmu_phys_pages(struct vm_gk20a *vm, u32 order, 921static int alloc_gmmu_phys_pages(struct vm_gk20a *vm, u32 order,
885 struct gk20a_mm_entry *entry) 922 struct gk20a_mm_entry *entry)
886{ 923{
@@ -2484,6 +2521,7 @@ int gk20a_gmmu_alloc_attr_vid_at(struct gk20a *g, enum dma_attr attr,
2484 struct device *d = &g->mm.vidmem_dev; 2521 struct device *d = &g->mm.vidmem_dev;
2485 int err; 2522 int err;
2486 dma_addr_t iova; 2523 dma_addr_t iova;
2524 bool need_pramin_access = true;
2487 DEFINE_DMA_ATTRS(attrs); 2525 DEFINE_DMA_ATTRS(attrs);
2488 2526
2489 gk20a_dbg_fn(""); 2527 gk20a_dbg_fn("");
@@ -2519,7 +2557,38 @@ int gk20a_gmmu_alloc_attr_vid_at(struct gk20a *g, enum dma_attr attr,
2519 mem->size = size; 2557 mem->size = size;
2520 mem->aperture = APERTURE_VIDMEM; 2558 mem->aperture = APERTURE_VIDMEM;
2521 2559
2522 gk20a_memset(g, mem, 0, 0, size); 2560 if (g->mm.ce_vidmem_ctx_id != ~0) {
2561 struct gk20a_fence *gk20a_fence_out = NULL;
2562 u64 dst_bufbase = g->ops.mm.get_iova_addr(g, mem->sgt->sgl, 0);
2563
2564 err = gk20a_ce_execute_ops(g->dev,
2565 g->mm.ce_vidmem_ctx_id,
2566 0,
2567 dst_bufbase,
2568 (u64)size,
2569 0x00000000,
2570 NVGPU_CE_DST_LOCATION_LOCAL_FB,
2571 NVGPU_CE_MEMSET,
2572 NULL,
2573 0,
2574 &gk20a_fence_out);
2575
2576 if (!err) {
2577 if (gk20a_fence_out) {
2578 err = gk20a_fence_wait(gk20a_fence_out, gk20a_get_gr_idle_timeout(g));
2579 gk20a_fence_put(gk20a_fence_out);
2580 if (err)
2581 gk20a_err(g->dev,
2582 "Failed to get the fence_out from CE execute ops");
2583 else
2584 need_pramin_access = false;
2585 }
2586 } else
2587 gk20a_err(g->dev, "Failed gk20a_ce_execute_ops[%d]",err);
2588 }
2589
2590 if (need_pramin_access)
2591 gk20a_memset(g, mem, 0, 0, size);
2523 2592
2524 gk20a_dbg_fn("done"); 2593 gk20a_dbg_fn("done");
2525 2594
@@ -4125,6 +4194,19 @@ static int gk20a_init_cde_vm(struct mm_gk20a *mm)
4125 false, false, "cde"); 4194 false, false, "cde");
4126} 4195}
4127 4196
4197static int gk20a_init_ce_vm(struct mm_gk20a *mm)
4198{
4199 struct vm_gk20a *vm = &mm->ce.vm;
4200 struct gk20a *g = gk20a_from_mm(mm);
4201 u32 big_page_size = gk20a_get_platform(g->dev)->default_big_page_size;
4202
4203 return gk20a_init_vm(mm, vm, big_page_size,
4204 SZ_4K * 16,
4205 NV_MM_DEFAULT_KERNEL_SIZE,
4206 NV_MM_DEFAULT_KERNEL_SIZE + NV_MM_DEFAULT_USER_SIZE,
4207 false, false, "ce");
4208}
4209
4128void gk20a_mm_init_pdb(struct gk20a *g, struct mem_desc *inst_block, 4210void gk20a_mm_init_pdb(struct gk20a *g, struct mem_desc *inst_block,
4129 struct vm_gk20a *vm) 4211 struct vm_gk20a *vm)
4130{ 4212{