From 7d9951feab64741e37a4324e260edf08561c861c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Mon, 30 Nov 2015 14:19:26 +0100 Subject: [PATCH 0251/1110] drm/amdgpu: use BOs GART instance for mapping addresses v4 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit That allows the VM code to use GART BOs from other driver instances. v2: don't use copy optimization for foreign GARTs, that won't work. v3: some more comment cleanups v4: agd: rebase on upstream Signed-off-by: Christian König Reviewed-by: Alex Deucher Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 114 ++++++++++++++++++++------------- 1 file changed, 68 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c index 47e1186..3469d11 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c @@ -283,31 +283,34 @@ struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm, * amdgpu_vm_update_pages - helper to call the right asic function * * @adev: amdgpu_device pointer + * @gtt: GART instance to use for mapping + * @gtt_flags: GTT hw access flags * @ib: indirect buffer to fill with commands * @pe: addr of the page entry * @addr: dst addr to write into pe * @count: number of page entries to update * @incr: increase next addr by incr bytes * @flags: hw access flags - * @gtt_flags: GTT hw access flags * * Traces the parameters and calls the right asic functions * to setup the page table using the DMA. */ static void amdgpu_vm_update_pages(struct amdgpu_device *adev, + struct amdgpu_gart *gtt, + uint32_t gtt_flags, struct amdgpu_ib *ib, uint64_t pe, uint64_t addr, unsigned count, uint32_t incr, - uint32_t flags, uint32_t gtt_flags) + uint32_t flags) { trace_amdgpu_vm_set_page(pe, addr, count, incr, flags); - if ((flags & AMDGPU_PTE_SYSTEM) && (flags == gtt_flags)) { - uint64_t src = adev->gart.table_addr + (addr >> 12) * 8; + if ((gtt == &adev->gart) && (flags == gtt_flags)) { + uint64_t src = gtt->table_addr + (addr >> 12) * 8; amdgpu_vm_copy_pte(adev, ib, pe, src, count); - } else if (flags & AMDGPU_PTE_SYSTEM) { - dma_addr_t *pages_addr = adev->gart.pages_addr; + } else if (gtt) { + dma_addr_t *pages_addr = gtt->pages_addr; amdgpu_vm_write_pte(adev, ib, pages_addr, pe, addr, count, incr, flags); @@ -369,7 +372,8 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, ib->length_dw = 0; - amdgpu_vm_update_pages(adev, ib, addr, 0, entries, 0, 0, 0); + amdgpu_vm_update_pages(adev, NULL, 0, ib, addr, 0, entries, 0, 0); + amdgpu_vm_pad_ib(adev, ib); WARN_ON(ib->length_dw > 64); r = amdgpu_sched_ib_submit_kernel_helper(adev, ring, ib, 1, @@ -482,9 +486,10 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, ((last_pt + incr * count) != pt)) { if (count) { - amdgpu_vm_update_pages(adev, ib, last_pde, - last_pt, count, incr, - AMDGPU_PTE_VALID, 0); + amdgpu_vm_update_pages(adev, NULL, 0, ib, + last_pde, last_pt, + count, incr, + AMDGPU_PTE_VALID); } count = 1; @@ -496,8 +501,8 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, } if (count) - amdgpu_vm_update_pages(adev, ib, last_pde, last_pt, count, - incr, AMDGPU_PTE_VALID, 0); + amdgpu_vm_update_pages(adev, NULL, 0, ib, last_pde, last_pt, + count, incr, AMDGPU_PTE_VALID); if (ib->length_dw != 0) { amdgpu_vm_pad_ib(adev, ib); @@ -533,20 +538,22 @@ error_free: * amdgpu_vm_frag_ptes - add fragment information to PTEs * * @adev: amdgpu_device pointer + * @gtt: GART instance to use for mapping + * @gtt_flags: GTT hw mapping flags * @ib: IB for the update * @pe_start: first PTE to handle * @pe_end: last PTE to handle * @addr: addr those PTEs should point to * @flags: hw mapping flags - * @gtt_flags: GTT hw mapping flags * * Global and local mutex must be locked! */ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, + struct amdgpu_gart *gtt, + uint32_t gtt_flags, struct amdgpu_ib *ib, uint64_t pe_start, uint64_t pe_end, - uint64_t addr, uint32_t flags, - uint32_t gtt_flags) + uint64_t addr, uint32_t flags) { /** * The MC L1 TLB supports variable sized pages, based on a fragment @@ -577,35 +584,34 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, unsigned count; /* system pages are non continuously */ - if ((flags & AMDGPU_PTE_SYSTEM) || !(flags & AMDGPU_PTE_VALID) || - (frag_start >= frag_end)) { + if (gtt || !(flags & AMDGPU_PTE_VALID) || (frag_start >= frag_end)) { count = (pe_end - pe_start) / 8; - amdgpu_vm_update_pages(adev, ib, pe_start, addr, count, - AMDGPU_GPU_PAGE_SIZE, flags, gtt_flags); + amdgpu_vm_update_pages(adev, gtt, gtt_flags, ib, pe_start, + addr, count, AMDGPU_GPU_PAGE_SIZE, + flags); return; } /* handle the 4K area at the beginning */ if (pe_start != frag_start) { count = (frag_start - pe_start) / 8; - amdgpu_vm_update_pages(adev, ib, pe_start, addr, count, - AMDGPU_GPU_PAGE_SIZE, flags, gtt_flags); + amdgpu_vm_update_pages(adev, NULL, 0, ib, pe_start, addr, + count, AMDGPU_GPU_PAGE_SIZE, flags); addr += AMDGPU_GPU_PAGE_SIZE * count; } /* handle the area in the middle */ count = (frag_end - frag_start) / 8; - amdgpu_vm_update_pages(adev, ib, frag_start, addr, count, - AMDGPU_GPU_PAGE_SIZE, flags | frag_flags, - gtt_flags); + amdgpu_vm_update_pages(adev, NULL, 0, ib, frag_start, addr, count, + AMDGPU_GPU_PAGE_SIZE, flags | frag_flags); /* handle the 4K area at the end */ if (frag_end != pe_end) { addr += AMDGPU_GPU_PAGE_SIZE * count; count = (pe_end - frag_end) / 8; - amdgpu_vm_update_pages(adev, ib, frag_end, addr, count, - AMDGPU_GPU_PAGE_SIZE, flags, gtt_flags); + amdgpu_vm_update_pages(adev, NULL, 0, ib, frag_end, addr, + count, AMDGPU_GPU_PAGE_SIZE, flags); } } @@ -613,6 +619,8 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, * amdgpu_vm_update_ptes - make sure that page tables are valid * * @adev: amdgpu_device pointer + * @gtt: GART instance to use for mapping + * @gtt_flags: GTT hw mapping flags * @vm: requested vm * @start: start of GPU address range * @end: end of GPU address range @@ -624,11 +632,12 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, * Global and local mutex must be locked! */ static int amdgpu_vm_update_ptes(struct amdgpu_device *adev, + struct amdgpu_gart *gtt, + uint32_t gtt_flags, struct amdgpu_vm *vm, struct amdgpu_ib *ib, uint64_t start, uint64_t end, - uint64_t dst, uint32_t flags, - uint32_t gtt_flags) + uint64_t dst, uint32_t flags) { uint64_t mask = AMDGPU_VM_PTE_COUNT - 1; uint64_t last_pte = ~0, last_dst = ~0; @@ -664,10 +673,9 @@ static int amdgpu_vm_update_ptes(struct amdgpu_device *adev, if ((last_pte + 8 * count) != pte) { if (count) { - amdgpu_vm_frag_ptes(adev, ib, last_pte, - last_pte + 8 * count, - last_dst, flags, - gtt_flags); + amdgpu_vm_frag_ptes(adev, gtt, gtt_flags, ib, + last_pte, last_pte + 8 * count, + last_dst, flags); } count = nptes; @@ -682,9 +690,9 @@ static int amdgpu_vm_update_ptes(struct amdgpu_device *adev, } if (count) { - amdgpu_vm_frag_ptes(adev, ib, last_pte, - last_pte + 8 * count, - last_dst, flags, gtt_flags); + amdgpu_vm_frag_ptes(adev, gtt, gtt_flags, ib, + last_pte, last_pte + 8 * count, + last_dst, flags); } return 0; @@ -694,6 +702,7 @@ static int amdgpu_vm_update_ptes(struct amdgpu_device *adev, * amdgpu_vm_bo_update_mapping - update a mapping in the vm page table * * @adev: amdgpu_device pointer + * @gtt: GART instance to use for mapping * @vm: requested vm * @mapping: mapped range and flags to use for the update * @addr: addr to set the area to @@ -706,10 +715,11 @@ static int amdgpu_vm_update_ptes(struct amdgpu_device *adev, * Object have to be reserved and mutex must be locked! */ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, + struct amdgpu_gart *gtt, + uint32_t gtt_flags, struct amdgpu_vm *vm, struct amdgpu_bo_va_mapping *mapping, - uint64_t addr, uint32_t gtt_flags, - struct fence **fence) + uint64_t addr, struct fence **fence) { struct amdgpu_ring *ring = adev->vm_manager.vm_pte_funcs_ring; unsigned nptes, ncmds, ndw; @@ -739,11 +749,11 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, /* padding, etc. */ ndw = 64; - if ((flags & AMDGPU_PTE_SYSTEM) && (flags == gtt_flags)) { + if ((gtt == &adev->gart) && (flags == gtt_flags)) { /* only copy commands needed */ ndw += ncmds * 7; - } else if (flags & AMDGPU_PTE_SYSTEM) { + } else if (gtt) { /* header for write data commands */ ndw += ncmds * 4; @@ -770,9 +780,9 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, ib->length_dw = 0; - r = amdgpu_vm_update_ptes(adev, vm, ib, mapping->it.start, - mapping->it.last + 1, addr + mapping->offset, - flags, gtt_flags); + r = amdgpu_vm_update_ptes(adev, gtt, gtt_flags, vm, ib, + mapping->it.start, mapping->it.last + 1, + addr + mapping->offset, flags); if (r) { amdgpu_ib_free(adev, ib); @@ -821,14 +831,25 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, { struct amdgpu_vm *vm = bo_va->vm; struct amdgpu_bo_va_mapping *mapping; + struct amdgpu_gart *gtt = NULL; uint32_t flags; uint64_t addr; int r; if (mem) { addr = (u64)mem->start << PAGE_SHIFT; - if (mem->mem_type != TTM_PL_TT) + switch (mem->mem_type) { + case TTM_PL_TT: + gtt = &bo_va->bo->adev->gart; + break; + + case TTM_PL_VRAM: addr += adev->vm_manager.vram_base_offset; + break; + + default: + break; + } } else { addr = 0; } @@ -841,8 +862,8 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, spin_unlock(&vm->status_lock); list_for_each_entry(mapping, &bo_va->invalids, list) { - r = amdgpu_vm_bo_update_mapping(adev, vm, mapping, addr, - flags, &bo_va->last_pt_update); + r = amdgpu_vm_bo_update_mapping(adev, gtt, flags, vm, mapping, addr, + &bo_va->last_pt_update); if (r) return r; } @@ -888,7 +909,8 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, struct amdgpu_bo_va_mapping, list); list_del(&mapping->list); spin_unlock(&vm->freed_lock); - r = amdgpu_vm_bo_update_mapping(adev, vm, mapping, 0, 0, NULL); + r = amdgpu_vm_bo_update_mapping(adev, NULL, 0, vm, mapping, + 0, NULL); kfree(mapping); if (r) return r; -- 2.7.4