diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_test.c')
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_test.c | 186 |
1 files changed, 125 insertions, 61 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_test.c b/drivers/gpu/drm/radeon/radeon_test.c index fda09c9ea68..3a13e0d1055 100644 --- a/drivers/gpu/drm/radeon/radeon_test.c +++ b/drivers/gpu/drm/radeon/radeon_test.c @@ -35,10 +35,9 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag) { struct radeon_bo *vram_obj = NULL; struct radeon_bo **gtt_obj = NULL; - struct radeon_fence *fence = NULL; uint64_t gtt_addr, vram_addr; - unsigned i, n, size; - int r, ring; + unsigned n, size; + int i, r, ring; switch (flag) { case RADEON_TEST_COPY_DMA: @@ -81,37 +80,38 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag) } r = radeon_bo_reserve(vram_obj, false); if (unlikely(r != 0)) - goto out_cleanup; + goto out_unref; r = radeon_bo_pin(vram_obj, RADEON_GEM_DOMAIN_VRAM, &vram_addr); if (r) { DRM_ERROR("Failed to pin VRAM object\n"); - goto out_cleanup; + goto out_unres; } for (i = 0; i < n; i++) { void *gtt_map, *vram_map; void **gtt_start, **gtt_end; void **vram_start, **vram_end; + struct radeon_fence *fence = NULL; r = radeon_bo_create(rdev, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_GTT, NULL, gtt_obj + i); if (r) { DRM_ERROR("Failed to create GTT object %d\n", i); - goto out_cleanup; + goto out_lclean; } r = radeon_bo_reserve(gtt_obj[i], false); if (unlikely(r != 0)) - goto out_cleanup; + goto out_lclean_unref; r = radeon_bo_pin(gtt_obj[i], RADEON_GEM_DOMAIN_GTT, >t_addr); if (r) { DRM_ERROR("Failed to pin GTT object %d\n", i); - goto out_cleanup; + goto out_lclean_unres; } r = radeon_bo_kmap(gtt_obj[i], >t_map); if (r) { DRM_ERROR("Failed to map GTT object %d\n", i); - goto out_cleanup; + goto out_lclean_unpin; } for (gtt_start = gtt_map, gtt_end = gtt_map + size; @@ -127,13 +127,13 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag) r = radeon_copy_blit(rdev, gtt_addr, vram_addr, size / RADEON_GPU_PAGE_SIZE, &fence); if (r) { DRM_ERROR("Failed GTT->VRAM copy %d\n", i); - goto out_cleanup; + goto out_lclean_unpin; } r = radeon_fence_wait(fence, false); if (r) { DRM_ERROR("Failed to wait for GTT->VRAM fence %d\n", i); - goto out_cleanup; + goto out_lclean_unpin; } radeon_fence_unref(&fence); @@ -141,7 +141,7 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag) r = radeon_bo_kmap(vram_obj, &vram_map); if (r) { DRM_ERROR("Failed to map VRAM object after copy %d\n", i); - goto out_cleanup; + goto out_lclean_unpin; } for (gtt_start = gtt_map, gtt_end = gtt_map + size, @@ -160,7 +160,7 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag) (vram_addr - rdev->mc.vram_start + (void*)gtt_start - gtt_map)); radeon_bo_kunmap(vram_obj); - goto out_cleanup; + goto out_lclean_unpin; } *vram_start = vram_start; } @@ -173,13 +173,13 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag) r = radeon_copy_blit(rdev, vram_addr, gtt_addr, size / RADEON_GPU_PAGE_SIZE, &fence); if (r) { DRM_ERROR("Failed VRAM->GTT copy %d\n", i); - goto out_cleanup; + goto out_lclean_unpin; } r = radeon_fence_wait(fence, false); if (r) { DRM_ERROR("Failed to wait for VRAM->GTT fence %d\n", i); - goto out_cleanup; + goto out_lclean_unpin; } radeon_fence_unref(&fence); @@ -187,7 +187,7 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag) r = radeon_bo_kmap(gtt_obj[i], >t_map); if (r) { DRM_ERROR("Failed to map GTT object after copy %d\n", i); - goto out_cleanup; + goto out_lclean_unpin; } for (gtt_start = gtt_map, gtt_end = gtt_map + size, @@ -206,7 +206,7 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag) (gtt_addr - rdev->mc.gtt_start + (void*)vram_start - vram_map)); radeon_bo_kunmap(gtt_obj[i]); - goto out_cleanup; + goto out_lclean_unpin; } } @@ -214,31 +214,32 @@ static void radeon_do_test_moves(struct radeon_device *rdev, int flag) DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n", gtt_addr - rdev->mc.gtt_start); + continue; + +out_lclean_unpin: + radeon_bo_unpin(gtt_obj[i]); +out_lclean_unres: + radeon_bo_unreserve(gtt_obj[i]); +out_lclean_unref: + radeon_bo_unref(>t_obj[i]); +out_lclean: + for (--i; i >= 0; --i) { + radeon_bo_unpin(gtt_obj[i]); + radeon_bo_unreserve(gtt_obj[i]); + radeon_bo_unref(>t_obj[i]); + } + if (fence) + radeon_fence_unref(&fence); + break; } + radeon_bo_unpin(vram_obj); +out_unres: + radeon_bo_unreserve(vram_obj); +out_unref: + radeon_bo_unref(&vram_obj); out_cleanup: - if (vram_obj) { - if (radeon_bo_is_reserved(vram_obj)) { - radeon_bo_unpin(vram_obj); - radeon_bo_unreserve(vram_obj); - } - radeon_bo_unref(&vram_obj); - } - if (gtt_obj) { - for (i = 0; i < n; i++) { - if (gtt_obj[i]) { - if (radeon_bo_is_reserved(gtt_obj[i])) { - radeon_bo_unpin(gtt_obj[i]); - radeon_bo_unreserve(gtt_obj[i]); - } - radeon_bo_unref(>t_obj[i]); - } - } - kfree(gtt_obj); - } - if (fence) { - radeon_fence_unref(&fence); - } + kfree(gtt_obj); if (r) { printk(KERN_WARNING "Error while testing BO move.\n"); } @@ -252,6 +253,52 @@ void radeon_test_moves(struct radeon_device *rdev) radeon_do_test_moves(rdev, RADEON_TEST_COPY_BLIT); } +static int radeon_test_create_and_emit_fence(struct radeon_device *rdev, + struct radeon_ring *ring, + struct radeon_fence **fence) +{ + uint32_t handle = ring->idx ^ 0xdeafbeef; + int r; + + if (ring->idx == R600_RING_TYPE_UVD_INDEX) { + r = radeon_uvd_get_create_msg(rdev, ring->idx, handle, NULL); + if (r) { + DRM_ERROR("Failed to get dummy create msg\n"); + return r; + } + + r = radeon_uvd_get_destroy_msg(rdev, ring->idx, handle, fence); + if (r) { + DRM_ERROR("Failed to get dummy destroy msg\n"); + return r; + } + + } else if (ring->idx == TN_RING_TYPE_VCE1_INDEX || + ring->idx == TN_RING_TYPE_VCE2_INDEX) { + r = radeon_vce_get_create_msg(rdev, ring->idx, handle, NULL); + if (r) { + DRM_ERROR("Failed to get dummy create msg\n"); + return r; + } + + r = radeon_vce_get_destroy_msg(rdev, ring->idx, handle, fence); + if (r) { + DRM_ERROR("Failed to get dummy destroy msg\n"); + return r; + } + + } else { + r = radeon_ring_lock(rdev, ring, 64); + if (r) { + DRM_ERROR("Failed to lock ring A %d\n", ring->idx); + return r; + } + radeon_fence_emit(rdev, fence, ring->idx); + radeon_ring_unlock_commit(rdev, ring); + } + return 0; +} + void radeon_test_ring_sync(struct radeon_device *rdev, struct radeon_ring *ringA, struct radeon_ring *ringB) @@ -272,21 +319,24 @@ void radeon_test_ring_sync(struct radeon_device *rdev, goto out_cleanup; } radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore); - r = radeon_fence_emit(rdev, &fence1, ringA->idx); - if (r) { - DRM_ERROR("Failed to emit fence 1\n"); - radeon_ring_unlock_undo(rdev, ringA); + radeon_ring_unlock_commit(rdev, ringA); + + r = radeon_test_create_and_emit_fence(rdev, ringA, &fence1); + if (r) goto out_cleanup; - } - radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore); - r = radeon_fence_emit(rdev, &fence2, ringA->idx); + + r = radeon_ring_lock(rdev, ringA, 64); if (r) { - DRM_ERROR("Failed to emit fence 2\n"); - radeon_ring_unlock_undo(rdev, ringA); + DRM_ERROR("Failed to lock ring A %d\n", ringA->idx); goto out_cleanup; } + radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore); radeon_ring_unlock_commit(rdev, ringA); + r = radeon_test_create_and_emit_fence(rdev, ringA, &fence2); + if (r) + goto out_cleanup; + mdelay(1000); if (radeon_fence_signaled(fence1)) { @@ -364,27 +414,22 @@ static void radeon_test_ring_sync2(struct radeon_device *rdev, goto out_cleanup; } radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore); - r = radeon_fence_emit(rdev, &fenceA, ringA->idx); - if (r) { - DRM_ERROR("Failed to emit sync fence 1\n"); - radeon_ring_unlock_undo(rdev, ringA); - goto out_cleanup; - } radeon_ring_unlock_commit(rdev, ringA); + r = radeon_test_create_and_emit_fence(rdev, ringA, &fenceA); + if (r) + goto out_cleanup; + r = radeon_ring_lock(rdev, ringB, 64); if (r) { DRM_ERROR("Failed to lock ring B %d\n", ringB->idx); goto out_cleanup; } radeon_semaphore_emit_wait(rdev, ringB->idx, semaphore); - r = radeon_fence_emit(rdev, &fenceB, ringB->idx); - if (r) { - DRM_ERROR("Failed to create sync fence 2\n"); - radeon_ring_unlock_undo(rdev, ringB); - goto out_cleanup; - } radeon_ring_unlock_commit(rdev, ringB); + r = radeon_test_create_and_emit_fence(rdev, ringB, &fenceB); + if (r) + goto out_cleanup; mdelay(1000); @@ -393,7 +438,7 @@ static void radeon_test_ring_sync2(struct radeon_device *rdev, goto out_cleanup; } if (radeon_fence_signaled(fenceB)) { - DRM_ERROR("Fence A signaled without waiting for semaphore.\n"); + DRM_ERROR("Fence B signaled without waiting for semaphore.\n"); goto out_cleanup; } @@ -457,6 +502,16 @@ out_cleanup: printk(KERN_WARNING "Error while testing ring sync (%d).\n", r); } +static bool radeon_test_sync_possible(struct radeon_ring *ringA, + struct radeon_ring *ringB) +{ + if (ringA->idx == TN_RING_TYPE_VCE2_INDEX && + ringB->idx == TN_RING_TYPE_VCE1_INDEX) + return false; + + return true; +} + void radeon_test_syncing(struct radeon_device *rdev) { int i, j, k; @@ -471,6 +526,9 @@ void radeon_test_syncing(struct radeon_device *rdev) if (!ringB->ready) continue; + if (!radeon_test_sync_possible(ringA, ringB)) + continue; + DRM_INFO("Testing syncing between rings %d and %d...\n", i, j); radeon_test_ring_sync(rdev, ringA, ringB); @@ -482,6 +540,12 @@ void radeon_test_syncing(struct radeon_device *rdev) if (!ringC->ready) continue; + if (!radeon_test_sync_possible(ringA, ringC)) + continue; + + if (!radeon_test_sync_possible(ringB, ringC)) + continue; + DRM_INFO("Testing syncing between rings %d, %d and %d...\n", i, j, k); radeon_test_ring_sync2(rdev, ringA, ringB, ringC); |
