Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 60a7e396 authored by Christian König's avatar Christian König Committed by Dave Airlie
Browse files

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: default avatarChristian König <deathsimple@vodafone.de>
Reviewed-by: default avatarJerome Glisse <jglisse@redhat.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent bf852799
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -913,6 +913,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);


/*
+4 −1
Original line number Diff line number Diff line
@@ -823,9 +823,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);
	}
+88 −0
Original line number Diff line number Diff line
@@ -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);
		}
	}
}