diff options
Diffstat (limited to 'common/recipes-kernel/linux/files/0461-drm-amdgpu-change-parameter-passing-in-the-VM-code.patch')
-rw-r--r-- | common/recipes-kernel/linux/files/0461-drm-amdgpu-change-parameter-passing-in-the-VM-code.patch | 324 |
1 files changed, 324 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/files/0461-drm-amdgpu-change-parameter-passing-in-the-VM-code.patch b/common/recipes-kernel/linux/files/0461-drm-amdgpu-change-parameter-passing-in-the-VM-code.patch new file mode 100644 index 00000000..8d417e54 --- /dev/null +++ b/common/recipes-kernel/linux/files/0461-drm-amdgpu-change-parameter-passing-in-the-VM-code.patch @@ -0,0 +1,324 @@ +From 7d78c8e4a3fe6f5735c815db7d285a803c62d0df Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Christian=20K=C3=B6nig?= <christian.koenig@amd.com> +Date: Fri, 18 Mar 2016 21:00:35 +0100 +Subject: [PATCH 0461/1110] drm/amdgpu: change parameter passing in the VM code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Make it more flexible by passing src and page addresses +directly instead of the structures they contain. + +Signed-off-by: Christian König <christian.koenig@amd.com> +Reviewed-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Alex Deucher <alexander.deucher@amd.com> +Signed-off-by: Kalyan Alle <kalyan.alle@amd.com> +--- + drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 100 ++++++++++++++++++--------------- + 1 file changed, 54 insertions(+), 46 deletions(-) + +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +index ac4e092..4db8a2b 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c +@@ -356,8 +356,8 @@ 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 ++ * @src: address where to copy page table entries from ++ * @pages_addr: DMA addresses to use for mapping + * @ib: indirect buffer to fill with commands + * @pe: addr of the page entry + * @addr: dst addr to write into pe +@@ -369,8 +369,8 @@ struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm, + * 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, ++ uint64_t src, ++ dma_addr_t *pages_addr, + struct amdgpu_ib *ib, + uint64_t pe, uint64_t addr, + unsigned count, uint32_t incr, +@@ -378,12 +378,11 @@ static void amdgpu_vm_update_pages(struct amdgpu_device *adev, + { + trace_amdgpu_vm_set_page(pe, addr, count, incr, flags); + +- if ((gtt == &adev->gart) && (flags == gtt_flags)) { +- uint64_t src = gtt->table_addr + (addr >> 12) * 8; ++ if (src) { ++ src += (addr >> 12) * 8; + amdgpu_vm_copy_pte(adev, ib, pe, src, count); + +- } else if (gtt) { +- dma_addr_t *pages_addr = gtt->pages_addr; ++ } else if (pages_addr) { + amdgpu_vm_write_pte(adev, ib, pages_addr, pe, addr, + count, incr, flags); + +@@ -432,7 +431,7 @@ static int amdgpu_vm_clear_bo(struct amdgpu_device *adev, + r = amdgpu_job_alloc_with_ib(adev, 64, &job); + if (r) + goto error; +- amdgpu_vm_update_pages(adev, NULL, 0, &job->ibs[0], addr, 0, entries, ++ amdgpu_vm_update_pages(adev, 0, NULL, &job->ibs[0], addr, 0, entries, + 0, 0); + amdgpu_ring_pad_ib(ring, &job->ibs[0]); + +@@ -538,7 +537,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, + ((last_pt + incr * count) != pt)) { + + if (count) { +- amdgpu_vm_update_pages(adev, NULL, 0, ib, ++ amdgpu_vm_update_pages(adev, 0, NULL, ib, + last_pde, last_pt, + count, incr, + AMDGPU_PTE_VALID); +@@ -553,7 +552,7 @@ int amdgpu_vm_update_page_directory(struct amdgpu_device *adev, + } + + if (count) +- amdgpu_vm_update_pages(adev, NULL, 0, ib, last_pde, last_pt, ++ amdgpu_vm_update_pages(adev, 0, NULL, ib, last_pde, last_pt, + count, incr, AMDGPU_PTE_VALID); + + if (ib->length_dw != 0) { +@@ -584,8 +583,8 @@ 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 ++ * @src: address where to copy page table entries from ++ * @pages_addr: DMA addresses to use for mapping + * @ib: IB for the update + * @pe_start: first PTE to handle + * @pe_end: last PTE to handle +@@ -595,8 +594,8 @@ error_free: + * 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, ++ uint64_t src, ++ dma_addr_t *pages_addr, + struct amdgpu_ib *ib, + uint64_t pe_start, uint64_t pe_end, + uint64_t addr, uint32_t flags) +@@ -634,10 +633,11 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, + return; + + /* system pages are non continuously */ +- if (gtt || !(flags & AMDGPU_PTE_VALID) || (frag_start >= frag_end)) { ++ if (src || pages_addr || !(flags & AMDGPU_PTE_VALID) || ++ (frag_start >= frag_end)) { + + count = (pe_end - pe_start) / 8; +- amdgpu_vm_update_pages(adev, gtt, gtt_flags, ib, pe_start, ++ amdgpu_vm_update_pages(adev, src, pages_addr, ib, pe_start, + addr, count, AMDGPU_GPU_PAGE_SIZE, + flags); + return; +@@ -646,21 +646,21 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, + /* handle the 4K area at the beginning */ + if (pe_start != frag_start) { + count = (frag_start - pe_start) / 8; +- amdgpu_vm_update_pages(adev, NULL, 0, ib, pe_start, addr, ++ amdgpu_vm_update_pages(adev, 0, NULL, 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, NULL, 0, ib, frag_start, addr, count, ++ amdgpu_vm_update_pages(adev, 0, NULL, 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, NULL, 0, ib, frag_end, addr, ++ amdgpu_vm_update_pages(adev, 0, NULL, ib, frag_end, addr, + count, AMDGPU_GPU_PAGE_SIZE, flags); + } + } +@@ -669,8 +669,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 ++ * @src: address where to copy page table entries from ++ * @pages_addr: DMA addresses to use for mapping + * @vm: requested vm + * @start: start of GPU address range + * @end: end of GPU address range +@@ -680,8 +680,8 @@ static void amdgpu_vm_frag_ptes(struct amdgpu_device *adev, + * Update the page tables in the range @start - @end. + */ + static void amdgpu_vm_update_ptes(struct amdgpu_device *adev, +- struct amdgpu_gart *gtt, +- uint32_t gtt_flags, ++ uint64_t src, ++ dma_addr_t *pages_addr, + struct amdgpu_vm *vm, + struct amdgpu_ib *ib, + uint64_t start, uint64_t end, +@@ -712,7 +712,7 @@ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev, + + if (last_pe_end != pe_start) { + +- amdgpu_vm_frag_ptes(adev, gtt, gtt_flags, ib, ++ amdgpu_vm_frag_ptes(adev, src, pages_addr, ib, + last_pe_start, last_pe_end, + last_dst, flags); + +@@ -727,17 +727,16 @@ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev, + dst += nptes * AMDGPU_GPU_PAGE_SIZE; + } + +- amdgpu_vm_frag_ptes(adev, gtt, gtt_flags, ib, +- last_pe_start, last_pe_end, +- last_dst, flags); ++ amdgpu_vm_frag_ptes(adev, src, pages_addr, ib, last_pe_start, ++ last_pe_end, last_dst, flags); + } + + /** + * amdgpu_vm_bo_update_mapping - update a mapping in the vm page table + * + * @adev: amdgpu_device pointer +- * @gtt: GART instance to use for mapping +- * @gtt_flags: flags as they are used for GTT ++ * @src: address where to copy page table entries from ++ * @pages_addr: DMA addresses to use for mapping + * @vm: requested vm + * @start: start of mapped range + * @last: last mapped entry +@@ -749,8 +748,8 @@ static void amdgpu_vm_update_ptes(struct amdgpu_device *adev, + * Returns 0 for success, -EINVAL for failure. + */ + static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, +- struct amdgpu_gart *gtt, +- uint32_t gtt_flags, ++ uint64_t src, ++ dma_addr_t *pages_addr, + struct amdgpu_vm *vm, + uint64_t start, uint64_t last, + uint32_t flags, uint64_t addr, +@@ -781,11 +780,11 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, + /* padding, etc. */ + ndw = 64; + +- if ((gtt == &adev->gart) && (flags == gtt_flags)) { ++ if (src) { + /* only copy commands needed */ + ndw += ncmds * 7; + +- } else if (gtt) { ++ } else if (pages_addr) { + /* header for write data commands */ + ndw += ncmds * 4; + +@@ -815,8 +814,8 @@ static int amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, + if (r) + goto error_free; + +- amdgpu_vm_update_ptes(adev, gtt, gtt_flags, vm, ib, start, last + 1, +- addr, flags); ++ amdgpu_vm_update_ptes(adev, src, pages_addr, vm, ib, start, ++ last + 1, addr, flags); + + amdgpu_ring_pad_ib(ring, ib); + WARN_ON(ib->length_dw > ndw); +@@ -858,12 +857,13 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, + uint32_t gtt_flags, + struct amdgpu_vm *vm, + struct amdgpu_bo_va_mapping *mapping, +- uint64_t addr, struct fence **fence) ++ uint32_t flags, uint64_t addr, ++ struct fence **fence) + { + const uint64_t max_size = 64ULL * 1024ULL * 1024ULL / AMDGPU_GPU_PAGE_SIZE; + +- uint64_t start = mapping->it.start; +- uint32_t flags = gtt_flags; ++ uint64_t src = 0, start = mapping->it.start; ++ dma_addr_t *pages_addr = NULL; + int r; + + /* normally,bo_va->flags only contians READABLE and WIRTEABLE bit go here +@@ -876,10 +876,17 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, + + trace_amdgpu_vm_bo_update(mapping); + ++ if (gtt) { ++ if (flags == gtt_flags) ++ src = adev->gart.table_addr + (addr >> 12) * 8; ++ else ++ pages_addr = >t->pages_addr[addr >> 12]; ++ addr = 0; ++ } + addr += mapping->offset; + +- if (!gtt || ((gtt == &adev->gart) && (flags == gtt_flags))) +- return amdgpu_vm_bo_update_mapping(adev, gtt, gtt_flags, vm, ++ if (!gtt || src) ++ return amdgpu_vm_bo_update_mapping(adev, src, pages_addr, vm, + start, mapping->it.last, + flags, addr, fence); + +@@ -887,7 +894,7 @@ static int amdgpu_vm_bo_split_mapping(struct amdgpu_device *adev, + uint64_t last; + + last = min((uint64_t)mapping->it.last, start + max_size - 1); +- r = amdgpu_vm_bo_update_mapping(adev, gtt, gtt_flags, vm, ++ r = amdgpu_vm_bo_update_mapping(adev, src, pages_addr, vm, + start, last, flags, addr, + fence); + if (r) +@@ -919,7 +926,7 @@ 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; ++ uint32_t gtt_flags, flags; + uint64_t addr; + int r; + +@@ -942,6 +949,7 @@ int amdgpu_vm_bo_update(struct amdgpu_device *adev, + } + + flags = amdgpu_ttm_tt_pte_flags(adev, bo_va->bo->tbo.ttm, mem); ++ gtt_flags = (adev == bo_va->bo->adev) ? flags : 0; + + spin_lock(&vm->status_lock); + if (!list_empty(&bo_va->vm_status)) +@@ -949,8 +957,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_split_mapping(adev, gtt, flags, vm, mapping, addr, +- &bo_va->last_pt_update); ++ r = amdgpu_vm_bo_split_mapping(adev, gtt, gtt_flags, vm, mapping, ++ flags, addr, &bo_va->last_pt_update); + if (r) + return r; + } +@@ -996,7 +1004,7 @@ int amdgpu_vm_clear_freed(struct amdgpu_device *adev, + list_del(&mapping->list); + + r = amdgpu_vm_bo_split_mapping(adev, NULL, 0, vm, mapping, +- 0, NULL); ++ 0, 0, NULL); + kfree(mapping); + if (r) + return r; +-- +2.7.4 + |