diff options
author | Christian König <deathsimple@vodafone.de> | 2011-11-17 09:22:44 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-12-20 14:51:37 -0500 |
commit | ce9548843756d2fc64bf11c7208de52be5774863 (patch) | |
tree | 1ebef207d1b381fbdc385d4acf542b61d7d07032 /drivers/gpu/drm | |
parent | 30eb77f4e6ba20f797af4ff79807fae7cb67429e (diff) |
drm/radeon: improve radeon_test_syncing function
Also test multiple waits on the same semaphore.
Signed-off-by: Christian König <deathsimple@vodafone.de>
Reviewed-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_test.c | 199 |
1 files changed, 185 insertions, 14 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index 3ab4be9e63d4..210d99f91932 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c | |||
@@ -239,15 +239,20 @@ void radeon_test_ring_sync(struct radeon_device *rdev, | |||
239 | struct radeon_ring *ringA, | 239 | struct radeon_ring *ringA, |
240 | struct radeon_ring *ringB) | 240 | struct radeon_ring *ringB) |
241 | { | 241 | { |
242 | struct radeon_fence *fence = NULL; | 242 | struct radeon_fence *fence1 = NULL, *fence2 = NULL; |
243 | struct radeon_semaphore *semaphore = NULL; | 243 | struct radeon_semaphore *semaphore = NULL; |
244 | int ridxA = radeon_ring_index(rdev, ringA); | 244 | int ridxA = radeon_ring_index(rdev, ringA); |
245 | int ridxB = radeon_ring_index(rdev, ringB); | 245 | int ridxB = radeon_ring_index(rdev, ringB); |
246 | int r; | 246 | int r; |
247 | 247 | ||
248 | r = radeon_fence_create(rdev, &fence, ridxA); | 248 | r = radeon_fence_create(rdev, &fence1, ridxA); |
249 | if (r) { | ||
250 | DRM_ERROR("Failed to create sync fence 1\n"); | ||
251 | goto out_cleanup; | ||
252 | } | ||
253 | r = radeon_fence_create(rdev, &fence2, ridxA); | ||
249 | if (r) { | 254 | if (r) { |
250 | DRM_ERROR("Failed to create sync fence\n"); | 255 | DRM_ERROR("Failed to create sync fence 2\n"); |
251 | goto out_cleanup; | 256 | goto out_cleanup; |
252 | } | 257 | } |
253 | 258 | ||
@@ -263,13 +268,15 @@ void radeon_test_ring_sync(struct radeon_device *rdev, | |||
263 | goto out_cleanup; | 268 | goto out_cleanup; |
264 | } | 269 | } |
265 | radeon_semaphore_emit_wait(rdev, ridxA, semaphore); | 270 | radeon_semaphore_emit_wait(rdev, ridxA, semaphore); |
266 | radeon_fence_emit(rdev, fence); | 271 | radeon_fence_emit(rdev, fence1); |
272 | radeon_semaphore_emit_wait(rdev, ridxA, semaphore); | ||
273 | radeon_fence_emit(rdev, fence2); | ||
267 | radeon_ring_unlock_commit(rdev, ringA); | 274 | radeon_ring_unlock_commit(rdev, ringA); |
268 | 275 | ||
269 | mdelay(1000); | 276 | mdelay(1000); |
270 | 277 | ||
271 | if (radeon_fence_signaled(fence)) { | 278 | if (radeon_fence_signaled(fence1)) { |
272 | DRM_ERROR("Fence signaled without waiting for semaphore.\n"); | 279 | DRM_ERROR("Fence 1 signaled without waiting for semaphore.\n"); |
273 | goto out_cleanup; | 280 | goto out_cleanup; |
274 | } | 281 | } |
275 | 282 | ||
@@ -281,20 +288,162 @@ void radeon_test_ring_sync(struct radeon_device *rdev, | |||
281 | radeon_semaphore_emit_signal(rdev, ridxB, semaphore); | 288 | radeon_semaphore_emit_signal(rdev, ridxB, semaphore); |
282 | radeon_ring_unlock_commit(rdev, ringB); | 289 | radeon_ring_unlock_commit(rdev, ringB); |
283 | 290 | ||
284 | r = radeon_fence_wait(fence, false); | 291 | r = radeon_fence_wait(fence1, false); |
292 | if (r) { | ||
293 | DRM_ERROR("Failed to wait for sync fence 1\n"); | ||
294 | goto out_cleanup; | ||
295 | } | ||
296 | |||
297 | mdelay(1000); | ||
298 | |||
299 | if (radeon_fence_signaled(fence2)) { | ||
300 | DRM_ERROR("Fence 2 signaled without waiting for semaphore.\n"); | ||
301 | goto out_cleanup; | ||
302 | } | ||
303 | |||
304 | r = radeon_ring_lock(rdev, ringB, 64); | ||
285 | if (r) { | 305 | if (r) { |
286 | DRM_ERROR("Failed to wait for sync fence\n"); | 306 | DRM_ERROR("Failed to lock ring B %p\n", ringB); |
287 | goto out_cleanup; | 307 | goto out_cleanup; |
288 | } | 308 | } |
309 | radeon_semaphore_emit_signal(rdev, ridxB, semaphore); | ||
310 | radeon_ring_unlock_commit(rdev, ringB); | ||
289 | 311 | ||
290 | DRM_INFO("Syncing between rings %d and %d seems to work.\n", ridxA, ridxB); | 312 | r = radeon_fence_wait(fence2, false); |
313 | if (r) { | ||
314 | DRM_ERROR("Failed to wait for sync fence 1\n"); | ||
315 | goto out_cleanup; | ||
316 | } | ||
291 | 317 | ||
292 | out_cleanup: | 318 | out_cleanup: |
293 | if (semaphore) | 319 | if (semaphore) |
294 | radeon_semaphore_free(rdev, semaphore); | 320 | radeon_semaphore_free(rdev, semaphore); |
295 | 321 | ||
296 | if (fence) | 322 | if (fence1) |
297 | radeon_fence_unref(&fence); | 323 | radeon_fence_unref(&fence1); |
324 | |||
325 | if (fence2) | ||
326 | radeon_fence_unref(&fence2); | ||
327 | |||
328 | if (r) | ||
329 | printk(KERN_WARNING "Error while testing ring sync (%d).\n", r); | ||
330 | } | ||
331 | |||
332 | void radeon_test_ring_sync2(struct radeon_device *rdev, | ||
333 | struct radeon_ring *ringA, | ||
334 | struct radeon_ring *ringB, | ||
335 | struct radeon_ring *ringC) | ||
336 | { | ||
337 | struct radeon_fence *fenceA = NULL, *fenceB = NULL; | ||
338 | struct radeon_semaphore *semaphore = NULL; | ||
339 | int ridxA = radeon_ring_index(rdev, ringA); | ||
340 | int ridxB = radeon_ring_index(rdev, ringB); | ||
341 | int ridxC = radeon_ring_index(rdev, ringC); | ||
342 | bool sigA, sigB; | ||
343 | int i, r; | ||
344 | |||
345 | r = radeon_fence_create(rdev, &fenceA, ridxA); | ||
346 | if (r) { | ||
347 | DRM_ERROR("Failed to create sync fence 1\n"); | ||
348 | goto out_cleanup; | ||
349 | } | ||
350 | r = radeon_fence_create(rdev, &fenceB, ridxB); | ||
351 | if (r) { | ||
352 | DRM_ERROR("Failed to create sync fence 2\n"); | ||
353 | goto out_cleanup; | ||
354 | } | ||
355 | |||
356 | r = radeon_semaphore_create(rdev, &semaphore); | ||
357 | if (r) { | ||
358 | DRM_ERROR("Failed to create semaphore\n"); | ||
359 | goto out_cleanup; | ||
360 | } | ||
361 | |||
362 | r = radeon_ring_lock(rdev, ringA, 64); | ||
363 | if (r) { | ||
364 | DRM_ERROR("Failed to lock ring A %d\n", ridxA); | ||
365 | goto out_cleanup; | ||
366 | } | ||
367 | radeon_semaphore_emit_wait(rdev, ridxA, semaphore); | ||
368 | radeon_fence_emit(rdev, fenceA); | ||
369 | radeon_ring_unlock_commit(rdev, ringA); | ||
370 | |||
371 | r = radeon_ring_lock(rdev, ringB, 64); | ||
372 | if (r) { | ||
373 | DRM_ERROR("Failed to lock ring B %d\n", ridxB); | ||
374 | goto out_cleanup; | ||
375 | } | ||
376 | radeon_semaphore_emit_wait(rdev, ridxB, semaphore); | ||
377 | radeon_fence_emit(rdev, fenceB); | ||
378 | radeon_ring_unlock_commit(rdev, ringB); | ||
379 | |||
380 | mdelay(1000); | ||
381 | |||
382 | if (radeon_fence_signaled(fenceA)) { | ||
383 | DRM_ERROR("Fence A signaled without waiting for semaphore.\n"); | ||
384 | goto out_cleanup; | ||
385 | } | ||
386 | if (radeon_fence_signaled(fenceB)) { | ||
387 | DRM_ERROR("Fence A signaled without waiting for semaphore.\n"); | ||
388 | goto out_cleanup; | ||
389 | } | ||
390 | |||
391 | r = radeon_ring_lock(rdev, ringC, 64); | ||
392 | if (r) { | ||
393 | DRM_ERROR("Failed to lock ring B %p\n", ringC); | ||
394 | goto out_cleanup; | ||
395 | } | ||
396 | radeon_semaphore_emit_signal(rdev, ridxC, semaphore); | ||
397 | radeon_ring_unlock_commit(rdev, ringC); | ||
398 | |||
399 | for (i = 0; i < 30; ++i) { | ||
400 | mdelay(100); | ||
401 | sigA = radeon_fence_signaled(fenceA); | ||
402 | sigB = radeon_fence_signaled(fenceB); | ||
403 | if (sigA || sigB) | ||
404 | break; | ||
405 | } | ||
406 | |||
407 | if (!sigA && !sigB) { | ||
408 | DRM_ERROR("Neither fence A nor B has been signaled\n"); | ||
409 | goto out_cleanup; | ||
410 | } else if (sigA && sigB) { | ||
411 | DRM_ERROR("Both fence A and B has been signaled\n"); | ||
412 | goto out_cleanup; | ||
413 | } | ||
414 | |||
415 | DRM_INFO("Fence %c was first signaled\n", sigA ? 'A' : 'B'); | ||
416 | |||
417 | r = radeon_ring_lock(rdev, ringC, 64); | ||
418 | if (r) { | ||
419 | DRM_ERROR("Failed to lock ring B %p\n", ringC); | ||
420 | goto out_cleanup; | ||
421 | } | ||
422 | radeon_semaphore_emit_signal(rdev, ridxC, semaphore); | ||
423 | radeon_ring_unlock_commit(rdev, ringC); | ||
424 | |||
425 | mdelay(1000); | ||
426 | |||
427 | r = radeon_fence_wait(fenceA, false); | ||
428 | if (r) { | ||
429 | DRM_ERROR("Failed to wait for sync fence A\n"); | ||
430 | goto out_cleanup; | ||
431 | } | ||
432 | r = radeon_fence_wait(fenceB, false); | ||
433 | if (r) { | ||
434 | DRM_ERROR("Failed to wait for sync fence B\n"); | ||
435 | goto out_cleanup; | ||
436 | } | ||
437 | |||
438 | out_cleanup: | ||
439 | if (semaphore) | ||
440 | radeon_semaphore_free(rdev, semaphore); | ||
441 | |||
442 | if (fenceA) | ||
443 | radeon_fence_unref(&fenceA); | ||
444 | |||
445 | if (fenceB) | ||
446 | radeon_fence_unref(&fenceB); | ||
298 | 447 | ||
299 | if (r) | 448 | if (r) |
300 | printk(KERN_WARNING "Error while testing ring sync (%d).\n", r); | 449 | printk(KERN_WARNING "Error while testing ring sync (%d).\n", r); |
@@ -302,7 +451,7 @@ out_cleanup: | |||
302 | 451 | ||
303 | void radeon_test_syncing(struct radeon_device *rdev) | 452 | void radeon_test_syncing(struct radeon_device *rdev) |
304 | { | 453 | { |
305 | int i, j; | 454 | int i, j, k; |
306 | 455 | ||
307 | for (i = 1; i < RADEON_NUM_RINGS; ++i) { | 456 | for (i = 1; i < RADEON_NUM_RINGS; ++i) { |
308 | struct radeon_ring *ringA = &rdev->ring[i]; | 457 | struct radeon_ring *ringA = &rdev->ring[i]; |
@@ -314,11 +463,33 @@ void radeon_test_syncing(struct radeon_device *rdev) | |||
314 | if (!ringB->ready) | 463 | if (!ringB->ready) |
315 | continue; | 464 | continue; |
316 | 465 | ||
317 | DRM_INFO("Testing syncing between rings %d and %d\n", i, j); | 466 | DRM_INFO("Testing syncing between rings %d and %d...\n", i, j); |
318 | radeon_test_ring_sync(rdev, ringA, ringB); | 467 | radeon_test_ring_sync(rdev, ringA, ringB); |
319 | 468 | ||
320 | DRM_INFO("Testing syncing between rings %d and %d\n", j, i); | 469 | DRM_INFO("Testing syncing between rings %d and %d...\n", j, i); |
321 | radeon_test_ring_sync(rdev, ringB, ringA); | 470 | radeon_test_ring_sync(rdev, ringB, ringA); |
471 | |||
472 | for (k = 0; k < j; ++k) { | ||
473 | struct radeon_ring *ringC = &rdev->ring[k]; | ||
474 | |||
475 | DRM_INFO("Testing syncing between rings %d, %d and %d...\n", i, j, k); | ||
476 | radeon_test_ring_sync2(rdev, ringA, ringB, ringC); | ||
477 | |||
478 | DRM_INFO("Testing syncing between rings %d, %d and %d...\n", i, k, j); | ||
479 | radeon_test_ring_sync2(rdev, ringA, ringC, ringB); | ||
480 | |||
481 | DRM_INFO("Testing syncing between rings %d, %d and %d...\n", j, i, k); | ||
482 | radeon_test_ring_sync2(rdev, ringB, ringA, ringC); | ||
483 | |||
484 | DRM_INFO("Testing syncing between rings %d, %d and %d...\n", j, k, i); | ||
485 | radeon_test_ring_sync2(rdev, ringB, ringC, ringA); | ||
486 | |||
487 | DRM_INFO("Testing syncing between rings %d, %d and %d...\n", k, i, j); | ||
488 | radeon_test_ring_sync2(rdev, ringC, ringA, ringB); | ||
489 | |||
490 | DRM_INFO("Testing syncing between rings %d, %d and %d...\n", k, j, i); | ||
491 | radeon_test_ring_sync2(rdev, ringC, ringB, ringA); | ||
492 | } | ||
322 | } | 493 | } |
323 | } | 494 | } |
324 | } | 495 | } |