diff options
author | Christian König <deathsimple@vodafone.de> | 2011-09-27 12:31:00 +0200 |
---|---|---|
committer | Jerome Glisse <jglisse@redhat.com> | 2011-12-05 18:25:05 -0500 |
commit | ba4da430f82fc79ee990901c62bf32b6f8b9c90e (patch) | |
tree | 2cc86fe39815722fe7ae09b2e294d5e3cee3955b | |
parent | 09a3f1153d2648ab6f636b3ccc998100ee6b2cc5 (diff) |
drm/radeon: Add radeon_test_syncing function v2
Tests syncing between all rings by using
semaphores and fences.
v2: use radeon_testing as a bit flag rather than on/off switch
this allow to test for one thing at a time (bo_move or semaphore
test). It kind of break the usage if user wheren't using 1
for bo move test but as it's a test feature i believe it's ok.
Signed-off-by: Christian König <deathsimple@vodafone.de>
Reviewed-by: Jerome Glisse <jglisse@redhat.com>
-rw-r--r-- | drivers/gpu/drm/radeon/radeon.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_test.c | 88 |
3 files changed, 96 insertions, 1 deletions
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 3abcdc7a117e..d6af618605d3 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -914,6 +914,10 @@ void radeon_benchmark(struct radeon_device *rdev, int test_number); * Testing */ void radeon_test_moves(struct radeon_device *rdev); +void radeon_test_ring_sync(struct radeon_device *rdev, + struct radeon_cp *cpA, + struct radeon_cp *cpB); +void radeon_test_syncing(struct radeon_device *rdev); /* diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index c6e2cac2479e..d96300da3c5a 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -817,9 +817,12 @@ int radeon_device_init(struct radeon_device *rdev, if (r) return r; } - if (radeon_testing) { + if ((radeon_testing & 1)) { radeon_test_moves(rdev); } + if ((radeon_testing & 2)) { + radeon_test_syncing(rdev); + } if (radeon_benchmarking) { radeon_benchmark(rdev, radeon_benchmarking); } diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index 160e7df77551..5f4d31ef3933 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c @@ -234,3 +234,91 @@ out_cleanup: printk(KERN_WARNING "Error while testing BO move.\n"); } } + +void radeon_test_ring_sync(struct radeon_device *rdev, + struct radeon_cp *cpA, + struct radeon_cp *cpB) +{ + struct radeon_fence *fence = NULL; + struct radeon_semaphore *semaphore = NULL; + int ringA = radeon_ring_index(rdev, cpA); + int ringB = radeon_ring_index(rdev, cpB); + int r; + + r = radeon_fence_create(rdev, &fence, ringA); + if (r) { + DRM_ERROR("Failed to create sync fence\n"); + goto out_cleanup; + } + + r = radeon_semaphore_create(rdev, &semaphore); + if (r) { + DRM_ERROR("Failed to create semaphore\n"); + goto out_cleanup; + } + + r = radeon_ring_lock(rdev, cpA, 64); + if (r) { + DRM_ERROR("Failed to lock ring %d\n", ringA); + goto out_cleanup; + } + radeon_semaphore_emit_wait(rdev, ringA, semaphore); + radeon_fence_emit(rdev, fence); + radeon_ring_unlock_commit(rdev, cpA); + + mdelay(1000); + + if (radeon_fence_signaled(fence)) { + DRM_ERROR("Fence signaled without waiting for semaphore.\n"); + goto out_cleanup; + } + + r = radeon_ring_lock(rdev, cpB, 64); + if (r) { + DRM_ERROR("Failed to lock ring %d\n", ringB); + goto out_cleanup; + } + radeon_semaphore_emit_signal(rdev, ringB, semaphore); + radeon_ring_unlock_commit(rdev, cpB); + + r = radeon_fence_wait(fence, false); + if (r) { + DRM_ERROR("Failed to wait for sync fence\n"); + goto out_cleanup; + } + + DRM_INFO("Syncing between rings %d and %d seems to work.\n", ringA, ringB); + +out_cleanup: + if (semaphore) + radeon_semaphore_free(rdev, semaphore); + + if (fence) + radeon_fence_unref(&fence); + + if (r) + printk(KERN_WARNING "Error while testing ring sync (%d).\n", r); +} + +void radeon_test_syncing(struct radeon_device *rdev) +{ + int i, j; + + for (i = 1; i < RADEON_NUM_RINGS; ++i) { + struct radeon_cp *cpA = &rdev->cp[i]; + if (!cpA->ready) + continue; + + for (j = 0; j < i; ++j) { + struct radeon_cp *cpB = &rdev->cp[j]; + if (!cpB->ready) + continue; + + DRM_INFO("Testing syncing between rings %d and %d\n", i, j); + radeon_test_ring_sync(rdev, cpA, cpB); + + DRM_INFO("Testing syncing between rings %d and %d\n", j, i); + radeon_test_ring_sync(rdev, cpB, cpA); + } + } +} |