diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_vm.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_vm.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_vm.c b/drivers/gpu/drm/radeon/radeon_vm.c index a128a4fd64b3..a72e9c81805d 100644 --- a/drivers/gpu/drm/radeon/radeon_vm.c +++ b/drivers/gpu/drm/radeon/radeon_vm.c | |||
@@ -130,10 +130,10 @@ struct radeon_cs_reloc *radeon_vm_get_bos(struct radeon_device *rdev, | |||
130 | struct list_head *head) | 130 | struct list_head *head) |
131 | { | 131 | { |
132 | struct radeon_cs_reloc *list; | 132 | struct radeon_cs_reloc *list; |
133 | unsigned i, idx, size; | 133 | unsigned i, idx; |
134 | 134 | ||
135 | size = (radeon_vm_num_pdes(rdev) + 1) * sizeof(struct radeon_cs_reloc); | 135 | list = kmalloc_array(vm->max_pde_used + 2, |
136 | list = kmalloc(size, GFP_KERNEL); | 136 | sizeof(struct radeon_cs_reloc), GFP_KERNEL); |
137 | if (!list) | 137 | if (!list) |
138 | return NULL; | 138 | return NULL; |
139 | 139 | ||
@@ -585,7 +585,8 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, | |||
585 | { | 585 | { |
586 | static const uint32_t incr = RADEON_VM_PTE_COUNT * 8; | 586 | static const uint32_t incr = RADEON_VM_PTE_COUNT * 8; |
587 | 587 | ||
588 | uint64_t pd_addr = radeon_bo_gpu_offset(vm->page_directory); | 588 | struct radeon_bo *pd = vm->page_directory; |
589 | uint64_t pd_addr = radeon_bo_gpu_offset(pd); | ||
589 | uint64_t last_pde = ~0, last_pt = ~0; | 590 | uint64_t last_pde = ~0, last_pt = ~0; |
590 | unsigned count = 0, pt_idx, ndw; | 591 | unsigned count = 0, pt_idx, ndw; |
591 | struct radeon_ib ib; | 592 | struct radeon_ib ib; |
@@ -595,7 +596,7 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, | |||
595 | ndw = 64; | 596 | ndw = 64; |
596 | 597 | ||
597 | /* assume the worst case */ | 598 | /* assume the worst case */ |
598 | ndw += vm->max_pde_used * 12; | 599 | ndw += vm->max_pde_used * 16; |
599 | 600 | ||
600 | /* update too big for an IB */ | 601 | /* update too big for an IB */ |
601 | if (ndw > 0xfffff) | 602 | if (ndw > 0xfffff) |
@@ -642,6 +643,7 @@ int radeon_vm_update_page_directory(struct radeon_device *rdev, | |||
642 | incr, R600_PTE_VALID); | 643 | incr, R600_PTE_VALID); |
643 | 644 | ||
644 | if (ib.length_dw != 0) { | 645 | if (ib.length_dw != 0) { |
646 | radeon_semaphore_sync_to(ib.semaphore, pd->tbo.sync_obj); | ||
645 | radeon_semaphore_sync_to(ib.semaphore, vm->last_id_use); | 647 | radeon_semaphore_sync_to(ib.semaphore, vm->last_id_use); |
646 | r = radeon_ib_schedule(rdev, &ib, NULL); | 648 | r = radeon_ib_schedule(rdev, &ib, NULL); |
647 | if (r) { | 649 | if (r) { |
@@ -767,15 +769,18 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev, | |||
767 | /* walk over the address space and update the page tables */ | 769 | /* walk over the address space and update the page tables */ |
768 | for (addr = start; addr < end; ) { | 770 | for (addr = start; addr < end; ) { |
769 | uint64_t pt_idx = addr >> RADEON_VM_BLOCK_SIZE; | 771 | uint64_t pt_idx = addr >> RADEON_VM_BLOCK_SIZE; |
772 | struct radeon_bo *pt = vm->page_tables[pt_idx].bo; | ||
770 | unsigned nptes; | 773 | unsigned nptes; |
771 | uint64_t pte; | 774 | uint64_t pte; |
772 | 775 | ||
776 | radeon_semaphore_sync_to(ib->semaphore, pt->tbo.sync_obj); | ||
777 | |||
773 | if ((addr & ~mask) == (end & ~mask)) | 778 | if ((addr & ~mask) == (end & ~mask)) |
774 | nptes = end - addr; | 779 | nptes = end - addr; |
775 | else | 780 | else |
776 | nptes = RADEON_VM_PTE_COUNT - (addr & mask); | 781 | nptes = RADEON_VM_PTE_COUNT - (addr & mask); |
777 | 782 | ||
778 | pte = radeon_bo_gpu_offset(vm->page_tables[pt_idx].bo); | 783 | pte = radeon_bo_gpu_offset(pt); |
779 | pte += (addr & mask) * 8; | 784 | pte += (addr & mask) * 8; |
780 | 785 | ||
781 | if ((last_pte + 8 * count) != pte) { | 786 | if ((last_pte + 8 * count) != pte) { |