aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_gart.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_gart.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c60
1 files changed, 24 insertions, 36 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index 6e24f84755b5..2c1341f63dc5 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -929,6 +929,7 @@ uint64_t radeon_vm_map_gart(struct radeon_device *rdev, uint64_t addr)
929 */ 929 */
930static int radeon_vm_update_pdes(struct radeon_device *rdev, 930static int radeon_vm_update_pdes(struct radeon_device *rdev,
931 struct radeon_vm *vm, 931 struct radeon_vm *vm,
932 struct radeon_ib *ib,
932 uint64_t start, uint64_t end) 933 uint64_t start, uint64_t end)
933{ 934{
934 static const uint32_t incr = RADEON_VM_PTE_COUNT * 8; 935 static const uint32_t incr = RADEON_VM_PTE_COUNT * 8;
@@ -971,7 +972,7 @@ retry:
971 ((last_pt + incr * count) != pt)) { 972 ((last_pt + incr * count) != pt)) {
972 973
973 if (count) { 974 if (count) {
974 radeon_asic_vm_set_page(rdev, last_pde, 975 radeon_asic_vm_set_page(rdev, ib, last_pde,
975 last_pt, count, incr, 976 last_pt, count, incr,
976 RADEON_VM_PAGE_VALID); 977 RADEON_VM_PAGE_VALID);
977 } 978 }
@@ -985,7 +986,7 @@ retry:
985 } 986 }
986 987
987 if (count) { 988 if (count) {
988 radeon_asic_vm_set_page(rdev, last_pde, last_pt, count, 989 radeon_asic_vm_set_page(rdev, ib, last_pde, last_pt, count,
989 incr, RADEON_VM_PAGE_VALID); 990 incr, RADEON_VM_PAGE_VALID);
990 991
991 } 992 }
@@ -1009,6 +1010,7 @@ retry:
1009 */ 1010 */
1010static void radeon_vm_update_ptes(struct radeon_device *rdev, 1011static void radeon_vm_update_ptes(struct radeon_device *rdev,
1011 struct radeon_vm *vm, 1012 struct radeon_vm *vm,
1013 struct radeon_ib *ib,
1012 uint64_t start, uint64_t end, 1014 uint64_t start, uint64_t end,
1013 uint64_t dst, uint32_t flags) 1015 uint64_t dst, uint32_t flags)
1014{ 1016{
@@ -1038,7 +1040,7 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev,
1038 if ((last_pte + 8 * count) != pte) { 1040 if ((last_pte + 8 * count) != pte) {
1039 1041
1040 if (count) { 1042 if (count) {
1041 radeon_asic_vm_set_page(rdev, last_pte, 1043 radeon_asic_vm_set_page(rdev, ib, last_pte,
1042 last_dst, count, 1044 last_dst, count,
1043 RADEON_GPU_PAGE_SIZE, 1045 RADEON_GPU_PAGE_SIZE,
1044 flags); 1046 flags);
@@ -1056,7 +1058,8 @@ static void radeon_vm_update_ptes(struct radeon_device *rdev,
1056 } 1058 }
1057 1059
1058 if (count) { 1060 if (count) {
1059 radeon_asic_vm_set_page(rdev, last_pte, last_dst, count, 1061 radeon_asic_vm_set_page(rdev, ib, last_pte,
1062 last_dst, count,
1060 RADEON_GPU_PAGE_SIZE, flags); 1063 RADEON_GPU_PAGE_SIZE, flags);
1061 } 1064 }
1062} 1065}
@@ -1080,8 +1083,7 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev,
1080 struct ttm_mem_reg *mem) 1083 struct ttm_mem_reg *mem)
1081{ 1084{
1082 unsigned ridx = rdev->asic->vm.pt_ring_index; 1085 unsigned ridx = rdev->asic->vm.pt_ring_index;
1083 struct radeon_ring *ring = &rdev->ring[ridx]; 1086 struct radeon_ib ib;
1084 struct radeon_semaphore *sem = NULL;
1085 struct radeon_bo_va *bo_va; 1087 struct radeon_bo_va *bo_va;
1086 unsigned nptes, npdes, ndw; 1088 unsigned nptes, npdes, ndw;
1087 uint64_t addr; 1089 uint64_t addr;
@@ -1124,25 +1126,13 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev,
1124 bo_va->valid = false; 1126 bo_va->valid = false;
1125 } 1127 }
1126 1128
1127 if (vm->fence && radeon_fence_signaled(vm->fence)) {
1128 radeon_fence_unref(&vm->fence);
1129 }
1130
1131 if (vm->fence && vm->fence->ring != ridx) {
1132 r = radeon_semaphore_create(rdev, &sem);
1133 if (r) {
1134 return r;
1135 }
1136 }
1137
1138 nptes = radeon_bo_ngpu_pages(bo); 1129 nptes = radeon_bo_ngpu_pages(bo);
1139 1130
1140 /* assume two extra pdes in case the mapping overlaps the borders */ 1131 /* assume two extra pdes in case the mapping overlaps the borders */
1141 npdes = (nptes >> RADEON_VM_BLOCK_SIZE) + 2; 1132 npdes = (nptes >> RADEON_VM_BLOCK_SIZE) + 2;
1142 1133
1143 /* estimate number of dw needed */ 1134 /* padding, etc. */
1144 /* semaphore, fence and padding */ 1135 ndw = 64;
1145 ndw = 32;
1146 1136
1147 if (RADEON_VM_BLOCK_SIZE > 11) 1137 if (RADEON_VM_BLOCK_SIZE > 11)
1148 /* reserve space for one header for every 2k dwords */ 1138 /* reserve space for one header for every 2k dwords */
@@ -1161,33 +1151,31 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev,
1161 /* reserve space for pde addresses */ 1151 /* reserve space for pde addresses */
1162 ndw += npdes * 2; 1152 ndw += npdes * 2;
1163 1153
1164 r = radeon_ring_lock(rdev, ring, ndw); 1154 /* update too big for an IB */
1165 if (r) { 1155 if (ndw > 0xfffff)
1166 return r; 1156 return -ENOMEM;
1167 }
1168 1157
1169 if (sem && radeon_fence_need_sync(vm->fence, ridx)) { 1158 r = radeon_ib_get(rdev, ridx, &ib, NULL, ndw * 4);
1170 radeon_semaphore_sync_rings(rdev, sem, vm->fence->ring, ridx); 1159 ib.length_dw = 0;
1171 radeon_fence_note_sync(vm->fence, ridx);
1172 }
1173 1160
1174 r = radeon_vm_update_pdes(rdev, vm, bo_va->soffset, bo_va->eoffset); 1161 r = radeon_vm_update_pdes(rdev, vm, &ib, bo_va->soffset, bo_va->eoffset);
1175 if (r) { 1162 if (r) {
1176 radeon_ring_unlock_undo(rdev, ring); 1163 radeon_ib_free(rdev, &ib);
1177 return r; 1164 return r;
1178 } 1165 }
1179 1166
1180 radeon_vm_update_ptes(rdev, vm, bo_va->soffset, bo_va->eoffset, 1167 radeon_vm_update_ptes(rdev, vm, &ib, bo_va->soffset, bo_va->eoffset,
1181 addr, bo_va->flags); 1168 addr, bo_va->flags);
1182 1169
1183 radeon_fence_unref(&vm->fence); 1170 radeon_ib_sync_to(&ib, vm->fence);
1184 r = radeon_fence_emit(rdev, &vm->fence, ridx); 1171 r = radeon_ib_schedule(rdev, &ib, NULL);
1185 if (r) { 1172 if (r) {
1186 radeon_ring_unlock_undo(rdev, ring); 1173 radeon_ib_free(rdev, &ib);
1187 return r; 1174 return r;
1188 } 1175 }
1189 radeon_ring_unlock_commit(rdev, ring); 1176 radeon_fence_unref(&vm->fence);
1190 radeon_semaphore_free(rdev, &sem, vm->fence); 1177 vm->fence = radeon_fence_ref(ib.fence);
1178 radeon_ib_free(rdev, &ib);
1191 radeon_fence_unref(&vm->last_flush); 1179 radeon_fence_unref(&vm->last_flush);
1192 1180
1193 return 0; 1181 return 0;