diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_gart.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_gart.c | 60 |
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 | */ |
930 | static int radeon_vm_update_pdes(struct radeon_device *rdev, | 930 | static 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 | */ |
1010 | static void radeon_vm_update_ptes(struct radeon_device *rdev, | 1011 | static 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; |