Rev 1430 | Rev 2004 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1430 | Rev 1963 | ||
---|---|---|---|
Line 24... | Line 24... | ||
24 | * Authors: Dave Airlie |
24 | * Authors: Dave Airlie |
25 | * Alex Deucher |
25 | * Alex Deucher |
26 | * Jerome Glisse |
26 | * Jerome Glisse |
27 | */ |
27 | */ |
28 | #include |
28 | #include |
- | 29 | #include |
|
29 | #include "drmP.h" |
30 | #include "drmP.h" |
30 | #include "radeon_drm.h" |
31 | #include "radeon_drm.h" |
31 | #include "radeon_reg.h" |
32 | #include "radeon_reg.h" |
32 | #include "radeon.h" |
33 | #include "radeon.h" |
33 | #include "atom.h" |
34 | #include "atom.h" |
Line 121... | Line 122... | ||
121 | } |
122 | } |
Line 122... | Line 123... | ||
122 | 123 | ||
123 | /* 64 dwords should be enough for fence too */ |
124 | /* 64 dwords should be enough for fence too */ |
124 | r = radeon_ring_lock(rdev, 64); |
125 | r = radeon_ring_lock(rdev, 64); |
125 | if (r) { |
126 | if (r) { |
126 | DRM_ERROR("radeon: scheduling IB failled (%d).\n", r); |
127 | DRM_ERROR("radeon: scheduling IB failed (%d).\n", r); |
127 | return r; |
128 | return r; |
128 | } |
129 | } |
129 | radeon_ring_ib_execute(rdev, ib); |
130 | radeon_ring_ib_execute(rdev, ib); |
130 | radeon_fence_emit(rdev, ib->fence); |
131 | radeon_fence_emit(rdev, ib->fence); |
Line 146... | Line 147... | ||
146 | 147 | ||
147 | if (rdev->ib_pool.robj) |
148 | if (rdev->ib_pool.robj) |
148 | return 0; |
149 | return 0; |
149 | INIT_LIST_HEAD(&rdev->ib_pool.bogus_ib); |
150 | INIT_LIST_HEAD(&rdev->ib_pool.bogus_ib); |
150 | /* Allocate 1M object buffer */ |
151 | /* Allocate 1M object buffer */ |
151 | r = radeon_bo_create(rdev, NULL, RADEON_IB_POOL_SIZE*64*1024, |
152 | r = radeon_bo_create(rdev, RADEON_IB_POOL_SIZE*64*1024, |
152 | true, RADEON_GEM_DOMAIN_GTT, |
153 | PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT, |
153 | &rdev->ib_pool.robj); |
154 | &rdev->ib_pool.robj); |
154 | if (r) { |
155 | if (r) { |
155 | DRM_ERROR("radeon: failed to ib pool (%d).\n", r); |
156 | DRM_ERROR("radeon: failed to ib pool (%d).\n", r); |
156 | return r; |
157 | return r; |
Line 165... | Line 166... | ||
165 | return r; |
166 | return r; |
166 | } |
167 | } |
167 | r = radeon_bo_kmap(rdev->ib_pool.robj, &ptr); |
168 | r = radeon_bo_kmap(rdev->ib_pool.robj, &ptr); |
168 | radeon_bo_unreserve(rdev->ib_pool.robj); |
169 | radeon_bo_unreserve(rdev->ib_pool.robj); |
169 | if (r) { |
170 | if (r) { |
170 | DRM_ERROR("radeon: failed to map ib poll (%d).\n", r); |
171 | DRM_ERROR("radeon: failed to map ib pool (%d).\n", r); |
171 | return r; |
172 | return r; |
172 | } |
173 | } |
173 | for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { |
174 | for (i = 0; i < RADEON_IB_POOL_SIZE; i++) { |
174 | unsigned offset; |
175 | unsigned offset; |
Line 190... | Line 191... | ||
190 | } |
191 | } |
Line 191... | Line 192... | ||
191 | 192 | ||
192 | void radeon_ib_pool_fini(struct radeon_device *rdev) |
193 | void radeon_ib_pool_fini(struct radeon_device *rdev) |
193 | { |
194 | { |
- | 195 | int r; |
|
Line 194... | Line 196... | ||
194 | int r; |
196 | struct radeon_bo *robj; |
195 | 197 | ||
196 | if (!rdev->ib_pool.ready) { |
198 | if (!rdev->ib_pool.ready) { |
197 | return; |
199 | return; |
- | 200 | } |
|
198 | } |
201 | mutex_lock(&rdev->ib_pool.mutex); |
- | 202 | // radeon_ib_bogus_cleanup(rdev); |
|
- | 203 | robj = rdev->ib_pool.robj; |
|
- | 204 | rdev->ib_pool.robj = NULL; |
|
- | 205 | mutex_unlock(&rdev->ib_pool.mutex); |
|
199 | mutex_lock(&rdev->ib_pool.mutex); |
206 | |
200 | if (rdev->ib_pool.robj) { |
207 | if (robj) { |
201 | r = radeon_bo_reserve(rdev->ib_pool.robj, false); |
208 | r = radeon_bo_reserve(robj, false); |
202 | if (likely(r == 0)) { |
209 | if (likely(r == 0)) { |
203 | radeon_bo_kunmap(rdev->ib_pool.robj); |
210 | radeon_bo_kunmap(robj); |
204 | radeon_bo_unpin(rdev->ib_pool.robj); |
211 | radeon_bo_unpin(robj); |
205 | radeon_bo_unreserve(rdev->ib_pool.robj); |
212 | radeon_bo_unreserve(robj); |
206 | } |
- | |
207 | radeon_bo_unref(&rdev->ib_pool.robj); |
213 | } |
208 | rdev->ib_pool.robj = NULL; |
- | |
209 | } |
214 | radeon_bo_unref(&robj); |
Line 210... | Line 215... | ||
210 | mutex_unlock(&rdev->ib_pool.mutex); |
215 | } |
211 | } |
216 | } |
212 | 217 | ||
213 | 218 | ||
214 | /* |
219 | /* |
- | 220 | * Ring. |
|
- | 221 | */ |
|
- | 222 | void radeon_ring_free_size(struct radeon_device *rdev) |
|
215 | * Ring. |
223 | { |
216 | */ |
224 | if (rdev->wb.enabled) |
217 | void radeon_ring_free_size(struct radeon_device *rdev) |
225 | rdev->cp.rptr = le32_to_cpu(rdev->wb.wb[RADEON_WB_CP_RPTR_OFFSET/4]); |
218 | { |
226 | else { |
- | 227 | if (rdev->family >= CHIP_R600) |
|
219 | if (rdev->family >= CHIP_R600) |
228 | rdev->cp.rptr = RREG32(R600_CP_RB_RPTR); |
220 | rdev->cp.rptr = RREG32(R600_CP_RB_RPTR); |
229 | else |
221 | else |
230 | rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); |
222 | rdev->cp.rptr = RREG32(RADEON_CP_RB_RPTR); |
231 | } |
223 | /* This works because ring_size is a power of 2 */ |
232 | /* This works because ring_size is a power of 2 */ |
224 | rdev->cp.ring_free_dw = (rdev->cp.rptr + (rdev->cp.ring_size / 4)); |
233 | rdev->cp.ring_free_dw = (rdev->cp.rptr + (rdev->cp.ring_size / 4)); |
225 | rdev->cp.ring_free_dw -= rdev->cp.wptr; |
234 | rdev->cp.ring_free_dw -= rdev->cp.wptr; |
226 | rdev->cp.ring_free_dw &= rdev->cp.ptr_mask; |
235 | rdev->cp.ring_free_dw &= rdev->cp.ptr_mask; |
Line 227... | Line 236... | ||
227 | if (!rdev->cp.ring_free_dw) { |
236 | if (!rdev->cp.ring_free_dw) { |
228 | rdev->cp.ring_free_dw = rdev->cp.ring_size / 4; |
237 | rdev->cp.ring_free_dw = rdev->cp.ring_size / 4; |
229 | } |
238 | } |
Line 230... | Line 239... | ||
230 | } |
239 | } |
231 | 240 | ||
232 | int radeon_ring_lock(struct radeon_device *rdev, unsigned ndw) |
241 | int radeon_ring_alloc(struct radeon_device *rdev, unsigned ndw) |
233 | { |
- | |
234 | int r; |
242 | { |
235 | 243 | int r; |
|
236 | /* Align requested size with padding so unlock_commit can |
244 | |
237 | * pad safely */ |
245 | /* Align requested size with padding so unlock_commit can |
238 | ndw = (ndw + rdev->cp.align_mask) & ~rdev->cp.align_mask; |
246 | * pad safely */ |
Line 251... | Line 259... | ||
251 | rdev->cp.count_dw = ndw; |
259 | rdev->cp.count_dw = ndw; |
252 | rdev->cp.wptr_old = rdev->cp.wptr; |
260 | rdev->cp.wptr_old = rdev->cp.wptr; |
253 | return 0; |
261 | return 0; |
254 | } |
262 | } |
Line -... | Line 263... | ||
- | 263 | ||
- | 264 | int radeon_ring_lock(struct radeon_device *rdev, unsigned ndw) |
|
- | 265 | { |
|
- | 266 | int r; |
|
- | 267 | ||
- | 268 | mutex_lock(&rdev->cp.mutex); |
|
- | 269 | r = radeon_ring_alloc(rdev, ndw); |
|
- | 270 | if (r) { |
|
- | 271 | mutex_unlock(&rdev->cp.mutex); |
|
- | 272 | return r; |
|
- | 273 | } |
|
- | 274 | return 0; |
|
- | 275 | } |
|
255 | 276 | ||
256 | void radeon_ring_unlock_commit(struct radeon_device *rdev) |
277 | void radeon_ring_commit(struct radeon_device *rdev) |
257 | { |
278 | { |
258 | unsigned count_dw_pad; |
279 | unsigned count_dw_pad; |
Line 259... | Line 280... | ||
259 | unsigned i; |
280 | unsigned i; |
Line 264... | Line 285... | ||
264 | for (i = 0; i < count_dw_pad; i++) { |
285 | for (i = 0; i < count_dw_pad; i++) { |
265 | radeon_ring_write(rdev, 2 << 30); |
286 | radeon_ring_write(rdev, 2 << 30); |
266 | } |
287 | } |
267 | DRM_MEMORYBARRIER(); |
288 | DRM_MEMORYBARRIER(); |
268 | radeon_cp_commit(rdev); |
289 | radeon_cp_commit(rdev); |
- | 290 | } |
|
- | 291 | ||
- | 292 | void radeon_ring_unlock_commit(struct radeon_device *rdev) |
|
- | 293 | { |
|
- | 294 | radeon_ring_commit(rdev); |
|
269 | mutex_unlock(&rdev->cp.mutex); |
295 | mutex_unlock(&rdev->cp.mutex); |
270 | } |
296 | } |
Line 271... | Line 297... | ||
271 | 297 | ||
272 | void radeon_ring_unlock_undo(struct radeon_device *rdev) |
298 | void radeon_ring_unlock_undo(struct radeon_device *rdev) |
Line 280... | Line 306... | ||
280 | int r; |
306 | int r; |
Line 281... | Line 307... | ||
281 | 307 | ||
282 | rdev->cp.ring_size = ring_size; |
308 | rdev->cp.ring_size = ring_size; |
283 | /* Allocate ring buffer */ |
309 | /* Allocate ring buffer */ |
284 | if (rdev->cp.ring_obj == NULL) { |
310 | if (rdev->cp.ring_obj == NULL) { |
285 | r = radeon_bo_create(rdev, NULL, rdev->cp.ring_size, true, |
311 | r = radeon_bo_create(rdev, rdev->cp.ring_size, PAGE_SIZE, true, |
286 | RADEON_GEM_DOMAIN_GTT, |
312 | RADEON_GEM_DOMAIN_GTT, |
287 | &rdev->cp.ring_obj); |
313 | &rdev->cp.ring_obj); |
288 | if (r) { |
314 | if (r) { |
289 | dev_err(rdev->dev, "(%d) ring create failed\n", r); |
315 | dev_err(rdev->dev, "(%d) ring create failed\n", r); |
Line 313... | Line 339... | ||
313 | } |
339 | } |
Line 314... | Line 340... | ||
314 | 340 | ||
315 | void radeon_ring_fini(struct radeon_device *rdev) |
341 | void radeon_ring_fini(struct radeon_device *rdev) |
316 | { |
342 | { |
- | 343 | int r; |
|
Line 317... | Line 344... | ||
317 | int r; |
344 | struct radeon_bo *ring_obj; |
318 | - | ||
319 | mutex_lock(&rdev->cp.mutex); |
- | |
320 | if (rdev->cp.ring_obj) { |
- | |
321 | r = radeon_bo_reserve(rdev->cp.ring_obj, false); |
- | |
322 | if (likely(r == 0)) { |
345 | |
323 | radeon_bo_kunmap(rdev->cp.ring_obj); |
- | |
324 | radeon_bo_unpin(rdev->cp.ring_obj); |
- | |
325 | radeon_bo_unreserve(rdev->cp.ring_obj); |
- | |
326 | } |
346 | mutex_lock(&rdev->cp.mutex); |
327 | radeon_bo_unref(&rdev->cp.ring_obj); |
347 | ring_obj = rdev->cp.ring_obj; |
328 | rdev->cp.ring = NULL; |
- | |
329 | rdev->cp.ring_obj = NULL; |
348 | rdev->cp.ring = NULL; |
- | 349 | rdev->cp.ring_obj = NULL; |
|
- | 350 | mutex_unlock(&rdev->cp.mutex); |
|
- | 351 | ||
- | 352 | if (ring_obj) { |
|
- | 353 | r = radeon_bo_reserve(ring_obj, false); |
|
- | 354 | if (likely(r == 0)) { |
|
- | 355 | radeon_bo_kunmap(ring_obj); |
|
- | 356 | radeon_bo_unpin(ring_obj); |
|
- | 357 | radeon_bo_unreserve(ring_obj); |
|
- | 358 | } |
|
330 | } |
359 | radeon_bo_unref(&ring_obj); |
Line 331... | Line 360... | ||
331 | mutex_unlock(&rdev->cp.mutex); |
360 | } |
332 | } |
361 | } |
Line 352... | Line 381... | ||
352 | seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]); |
381 | seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]); |
353 | } |
382 | } |
354 | return 0; |
383 | return 0; |
355 | } |
384 | } |
Line -... | Line 385... | ||
- | 385 | ||
- | 386 | static int radeon_debugfs_ib_bogus_info(struct seq_file *m, void *data) |
|
- | 387 | { |
|
- | 388 | struct drm_info_node *node = (struct drm_info_node *) m->private; |
|
- | 389 | struct radeon_device *rdev = node->info_ent->data; |
|
- | 390 | struct radeon_ib *ib; |
|
- | 391 | unsigned i; |
|
- | 392 | ||
- | 393 | mutex_lock(&rdev->ib_pool.mutex); |
|
- | 394 | if (list_empty(&rdev->ib_pool.bogus_ib)) { |
|
- | 395 | mutex_unlock(&rdev->ib_pool.mutex); |
|
- | 396 | seq_printf(m, "no bogus IB recorded\n"); |
|
- | 397 | return 0; |
|
- | 398 | } |
|
- | 399 | ib = list_first_entry(&rdev->ib_pool.bogus_ib, struct radeon_ib, list); |
|
- | 400 | list_del_init(&ib->list); |
|
- | 401 | mutex_unlock(&rdev->ib_pool.mutex); |
|
- | 402 | seq_printf(m, "IB size %05u dwords\n", ib->length_dw); |
|
- | 403 | for (i = 0; i < ib->length_dw; i++) { |
|
- | 404 | seq_printf(m, "[%05u]=0x%08X\n", i, ib->ptr[i]); |
|
- | 405 | } |
|
- | 406 | vfree(ib->ptr); |
|
- | 407 | kfree(ib); |
|
- | 408 | return 0; |
|
- | 409 | } |
|
356 | 410 | ||
357 | static struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE]; |
411 | static struct drm_info_list radeon_debugfs_ib_list[RADEON_IB_POOL_SIZE]; |
- | 412 | static char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32]; |
|
- | 413 | ||
- | 414 | static struct drm_info_list radeon_debugfs_ib_bogus_info_list[] = { |
|
- | 415 | {"radeon_ib_bogus", radeon_debugfs_ib_bogus_info, 0, NULL}, |
|
358 | static char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32]; |
416 | }; |
Line 359... | Line 417... | ||
359 | #endif |
417 | #endif |
360 | 418 | ||
361 | int radeon_debugfs_ib_init(struct radeon_device *rdev) |
419 | int radeon_debugfs_ib_init(struct radeon_device *rdev) |