diff options
author | Lakshmanan M <lm@nvidia.com> | 2016-06-29 06:36:39 -0400 |
---|---|---|
committer | Vijayakumar Subbu <vsubbu@nvidia.com> | 2016-07-20 06:09:28 -0400 |
commit | 89aecd1202b49727e940069f2a6feb5c3cf4c927 (patch) | |
tree | 8a0d3a493b389167ce1d93e55f23e114ec2cbd38 /drivers/gpu/nvgpu/gk20a/mm_gk20a.c | |
parent | f6ebdc5f2916706f7a61983567420e0985faeeb1 (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.c | 86 |
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); | |||
393 | static int __must_check gk20a_init_bar1_vm(struct mm_gk20a *mm); | 393 | static int __must_check gk20a_init_bar1_vm(struct mm_gk20a *mm); |
394 | static int __must_check gk20a_init_hwpm(struct mm_gk20a *mm); | 394 | static int __must_check gk20a_init_hwpm(struct mm_gk20a *mm); |
395 | static int __must_check gk20a_init_cde_vm(struct mm_gk20a *mm); | 395 | static int __must_check gk20a_init_cde_vm(struct mm_gk20a *mm); |
396 | 396 | static int __must_check gk20a_init_ce_vm(struct mm_gk20a *mm); | |
397 | 397 | ||
398 | struct gk20a_dmabuf_priv { | 398 | struct 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) | |||
702 | static void gk20a_remove_mm_support(struct mm_gk20a *mm) | 702 | static 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 | ||
714 | static int gk20a_alloc_sysmem_flush(struct gk20a *g) | 723 | static 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 | ||
902 | void 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 | |||
884 | static int alloc_gmmu_phys_pages(struct vm_gk20a *vm, u32 order, | 921 | static 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 | ||
4197 | static 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 | |||
4128 | void gk20a_mm_init_pdb(struct gk20a *g, struct mem_desc *inst_block, | 4210 | void gk20a_mm_init_pdb(struct gk20a *g, struct mem_desc *inst_block, |
4129 | struct vm_gk20a *vm) | 4211 | struct vm_gk20a *vm) |
4130 | { | 4212 | { |