summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/mm/gmmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/common/mm/gmmu.c')
-rw-r--r--drivers/gpu/nvgpu/common/mm/gmmu.c114
1 files changed, 21 insertions, 93 deletions
diff --git a/drivers/gpu/nvgpu/common/mm/gmmu.c b/drivers/gpu/nvgpu/common/mm/gmmu.c
index cad53fa1..b802cb53 100644
--- a/drivers/gpu/nvgpu/common/mm/gmmu.c
+++ b/drivers/gpu/nvgpu/common/mm/gmmu.c
@@ -466,79 +466,12 @@ static int __set_pd_level(struct vm_gk20a *vm,
466 return 0; 466 return 0;
467} 467}
468 468
469/* 469static int __nvgpu_gmmu_do_update_page_table(struct vm_gk20a *vm,
470 * VIDMEM version of the update_ptes logic. 470 struct nvgpu_sgt *sgt,
471 */ 471 u64 space_to_skip,
472static int __nvgpu_gmmu_update_page_table_vidmem(struct vm_gk20a *vm, 472 u64 virt_addr,
473 struct nvgpu_sgt *sgt, 473 u64 length,
474 u64 space_to_skip, 474 struct nvgpu_gmmu_attrs *attrs)
475 u64 virt_addr,
476 u64 length,
477 struct nvgpu_gmmu_attrs *attrs)
478{
479 u64 phys_addr, chunk_length;
480 int err = 0;
481 void *sgl;
482
483 if (!sgt) {
484 /*
485 * This is considered an unmap. Just pass in 0 as the physical
486 * address for the entire GPU range.
487 */
488 err = __set_pd_level(vm, &vm->pdb,
489 0,
490 0,
491 virt_addr, length,
492 attrs);
493 return err;
494 }
495
496 /*
497 * Otherwise iterate across all the chunks in this allocation and
498 * map them.
499 */
500 nvgpu_sgt_for_each_sgl(sgl, sgt) {
501 if (space_to_skip &&
502 space_to_skip >= nvgpu_sgt_get_length(sgt, sgl)) {
503 space_to_skip -= nvgpu_sgt_get_length(sgt, sgl);
504 sgl = nvgpu_sgt_get_next(sgt, sgl);
505 continue;
506 }
507
508 phys_addr = nvgpu_sgt_get_phys(sgt, sgl) + space_to_skip;
509 chunk_length = min(length, (nvgpu_sgt_get_length(sgt, sgl) -
510 space_to_skip));
511
512 err = __set_pd_level(vm, &vm->pdb,
513 0,
514 phys_addr,
515 virt_addr, chunk_length,
516 attrs);
517 if (err)
518 break;
519
520 /* Space has been skipped so zero this for future chunks. */
521 space_to_skip = 0;
522
523 /*
524 * Update the map pointer and the remaining length.
525 */
526 virt_addr += chunk_length;
527 length -= chunk_length;
528
529 if (length == 0)
530 break;
531 }
532
533 return err;
534}
535
536static int __nvgpu_gmmu_update_page_table_sysmem(struct vm_gk20a *vm,
537 struct nvgpu_sgt *sgt,
538 u64 space_to_skip,
539 u64 virt_addr,
540 u64 length,
541 struct nvgpu_gmmu_attrs *attrs)
542{ 475{
543 struct gk20a *g = gk20a_from_vm(vm); 476 struct gk20a *g = gk20a_from_vm(vm);
544 void *sgl; 477 void *sgl;
@@ -565,7 +498,7 @@ static int __nvgpu_gmmu_update_page_table_sysmem(struct vm_gk20a *vm,
565 * mapping is simple since the "physical" address is actually a virtual 498 * mapping is simple since the "physical" address is actually a virtual
566 * IO address and will be contiguous. 499 * IO address and will be contiguous.
567 */ 500 */
568 if (!g->mm.bypass_smmu) { 501 if (attrs->aperture == APERTURE_SYSMEM && !g->mm.bypass_smmu) {
569 u64 io_addr = nvgpu_sgt_get_gpu_addr(sgt, g, sgt->sgl, attrs); 502 u64 io_addr = nvgpu_sgt_get_gpu_addr(sgt, g, sgt->sgl, attrs);
570 503
571 io_addr += space_to_skip; 504 io_addr += space_to_skip;
@@ -608,8 +541,15 @@ static int __nvgpu_gmmu_update_page_table_sysmem(struct vm_gk20a *vm,
608 virt_addr, 541 virt_addr,
609 chunk_length, 542 chunk_length,
610 attrs); 543 attrs);
544 if (err)
545 break;
611 546
547 /* Space has been skipped so zero this for future chunks. */
612 space_to_skip = 0; 548 space_to_skip = 0;
549
550 /*
551 * Update the map pointer and the remaining length.
552 */
613 virt_addr += chunk_length; 553 virt_addr += chunk_length;
614 length -= chunk_length; 554 length -= chunk_length;
615 555
@@ -617,7 +557,7 @@ static int __nvgpu_gmmu_update_page_table_sysmem(struct vm_gk20a *vm,
617 break; 557 break;
618 } 558 }
619 559
620 return 0; 560 return err;
621} 561}
622 562
623/* 563/*
@@ -689,24 +629,12 @@ static int __nvgpu_gmmu_update_page_table(struct vm_gk20a *vm,
689 attrs->coherent ? 'c' : '-', 629 attrs->coherent ? 'c' : '-',
690 attrs->valid ? 'V' : '-'); 630 attrs->valid ? 'V' : '-');
691 631
692 /* 632 err = __nvgpu_gmmu_do_update_page_table(vm,
693 * For historical reasons these are separate, but soon these will be 633 sgt,
694 * unified. 634 space_to_skip,
695 */ 635 virt_addr,
696 if (attrs->aperture == APERTURE_VIDMEM) 636 length,
697 err = __nvgpu_gmmu_update_page_table_vidmem(vm, 637 attrs);
698 sgt,
699 space_to_skip,
700 virt_addr,
701 length,
702 attrs);
703 else
704 err = __nvgpu_gmmu_update_page_table_sysmem(vm,
705 sgt,
706 space_to_skip,
707 virt_addr,
708 length,
709 attrs);
710 638
711 unmap_gmmu_pages(g, &vm->pdb); 639 unmap_gmmu_pages(g, &vm->pdb);
712 nvgpu_smp_mb(); 640 nvgpu_smp_mb();