|
@@ -929,6 +929,7 @@ uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr)
|
|
|
*/
|
|
|
static int radeon_vm_update_pdes(struct radeon_device *rdev,
|
|
|
struct radeon_vm *vm,
|
|
|
+ struct radeon_ib *ib,
|
|
|
uint64_t start, uint64_t end)
|
|
|
{
|
|
|
static const uint32_t incr = RADEON_VM_PTE_COUNT * 8;
|
|
@@ -971,7 +972,7 @@ retry:
|
|
|
((last_pt + incr * count) != pt)) {
|
|
|
|
|
|
if (count) {
|
|
|
- radeon_asic_vm_set_page(rdev, last_pde,
|
|
|
+ radeon_asic_vm_set_page(rdev, ib, last_pde,
|
|
|
last_pt, count, incr,
|
|
|
RADEON_VM_PAGE_VALID);
|
|
|
}
|
|
@@ -985,7 +986,7 @@ retry:
|
|
|
}
|
|
|
|
|
|
if (count) {
|
|
|
- radeon_asic_vm_set_page(rdev, last_pde, last_pt, count,
|
|
|
+ radeon_asic_vm_set_page(rdev, ib, last_pde, last_pt, count,
|
|
|
incr, RADEON_VM_PAGE_VALID);
|
|
|
|
|
|
}
|
|
@@ -1009,6 +1010,7 @@ retry:
|
|
|
*/
|
|
|
static void radeon_vm_update_ptes(struct radeon_device *rdev,
|
|
|
struct radeon_vm *vm,
|
|
|
+ struct radeon_ib *ib,
|
|
|
uint64_t start, uint64_t end,
|
|
|
uint64_t dst, uint32_t flags)
|
|
|
{
|
|
@@ -1038,7 +1040,7 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev,
|
|
|
if ((last_pte + 8 * count) != pte) {
|
|
|
|
|
|
if (count) {
|
|
|
- radeon_asic_vm_set_page(rdev, last_pte,
|
|
|
+ radeon_asic_vm_set_page(rdev, ib, last_pte,
|
|
|
last_dst, count,
|
|
|
RADEON_GPU_PAGE_SIZE,
|
|
|
flags);
|
|
@@ -1056,7 +1058,8 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev,
|
|
|
}
|
|
|
|
|
|
if (count) {
|
|
|
- radeon_asic_vm_set_page(rdev, last_pte, last_dst, count,
|
|
|
+ radeon_asic_vm_set_page(rdev, ib, last_pte,
|
|
|
+ last_dst, count,
|
|
|
RADEON_GPU_PAGE_SIZE, flags);
|
|
|
}
|
|
|
}
|
|
@@ -1080,8 +1083,7 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev,
|
|
|
struct ttm_mem_reg *mem)
|
|
|
{
|
|
|
unsigned ridx = rdev->asic->vm.pt_ring_index;
|
|
|
- struct radeon_ring *ring = &rdev->ring[ridx];
|
|
|
- struct radeon_semaphore *sem = NULL;
|
|
|
+ struct radeon_ib ib;
|
|
|
struct radeon_bo_va *bo_va;
|
|
|
unsigned nptes, npdes, ndw;
|
|
|
uint64_t addr;
|
|
@@ -1124,25 +1126,13 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev,
|
|
|
bo_va->valid = false;
|
|
|
}
|
|
|
|
|
|
- if (vm->fence && radeon_fence_signaled(vm->fence)) {
|
|
|
- radeon_fence_unref(&vm->fence);
|
|
|
- }
|
|
|
-
|
|
|
- if (vm->fence && vm->fence->ring != ridx) {
|
|
|
- r = radeon_semaphore_create(rdev, &sem);
|
|
|
- if (r) {
|
|
|
- return r;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
nptes = radeon_bo_ngpu_pages(bo);
|
|
|
|
|
|
/* assume two extra pdes in case the mapping overlaps the borders */
|
|
|
npdes = (nptes >> RADEON_VM_BLOCK_SIZE) + 2;
|
|
|
|
|
|
- /* estimate number of dw needed */
|
|
|
- /* semaphore, fence and padding */
|
|
|
- ndw = 32;
|
|
|
+ /* padding, etc. */
|
|
|
+ ndw = 64;
|
|
|
|
|
|
if (RADEON_VM_BLOCK_SIZE > 11)
|
|
|
/* reserve space for one header for every 2k dwords */
|
|
@@ -1161,33 +1151,31 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev,
|
|
|
/* reserve space for pde addresses */
|
|
|
ndw += npdes * 2;
|
|
|
|
|
|
- r = radeon_ring_lock(rdev, ring, ndw);
|
|
|
- if (r) {
|
|
|
- return r;
|
|
|
- }
|
|
|
+ /* update too big for an IB */
|
|
|
+ if (ndw > 0xfffff)
|
|
|
+ return -ENOMEM;
|
|
|
|
|
|
- if (sem && radeon_fence_need_sync(vm->fence, ridx)) {
|
|
|
- radeon_semaphore_sync_rings(rdev, sem, vm->fence->ring, ridx);
|
|
|
- radeon_fence_note_sync(vm->fence, ridx);
|
|
|
- }
|
|
|
+ r = radeon_ib_get(rdev, ridx, &ib, NULL, ndw * 4);
|
|
|
+ ib.length_dw = 0;
|
|
|
|
|
|
- r = radeon_vm_update_pdes(rdev, vm, bo_va->soffset, bo_va->eoffset);
|
|
|
+ r = radeon_vm_update_pdes(rdev, vm, &ib, bo_va->soffset, bo_va->eoffset);
|
|
|
if (r) {
|
|
|
- radeon_ring_unlock_undo(rdev, ring);
|
|
|
+ radeon_ib_free(rdev, &ib);
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
- radeon_vm_update_ptes(rdev, vm, bo_va->soffset, bo_va->eoffset,
|
|
|
+ radeon_vm_update_ptes(rdev, vm, &ib, bo_va->soffset, bo_va->eoffset,
|
|
|
addr, bo_va->flags);
|
|
|
|
|
|
- radeon_fence_unref(&vm->fence);
|
|
|
- r = radeon_fence_emit(rdev, &vm->fence, ridx);
|
|
|
+ radeon_ib_sync_to(&ib, vm->fence);
|
|
|
+ r = radeon_ib_schedule(rdev, &ib, NULL);
|
|
|
if (r) {
|
|
|
- radeon_ring_unlock_undo(rdev, ring);
|
|
|
+ radeon_ib_free(rdev, &ib);
|
|
|
return r;
|
|
|
}
|
|
|
- radeon_ring_unlock_commit(rdev, ring);
|
|
|
- radeon_semaphore_free(rdev, &sem, vm->fence);
|
|
|
+ radeon_fence_unref(&vm->fence);
|
|
|
+ vm->fence = radeon_fence_ref(ib.fence);
|
|
|
+ radeon_ib_free(rdev, &ib);
|
|
|
radeon_fence_unref(&vm->last_flush);
|
|
|
|
|
|
return 0;
|