0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <drm/radeon_drm.h>
0027 #include "radeon_reg.h"
0028 #include "radeon.h"
0029
0030 #define RADEON_TEST_COPY_BLIT 1
0031 #define RADEON_TEST_COPY_DMA 0
0032
0033
0034
0035 static void radeon_do_test_moves(struct radeon_device *rdev, int flag)
0036 {
0037 struct radeon_bo *vram_obj = NULL;
0038 struct radeon_bo **gtt_obj = NULL;
0039 uint64_t gtt_addr, vram_addr;
0040 unsigned n, size;
0041 int i, r, ring;
0042
0043 switch (flag) {
0044 case RADEON_TEST_COPY_DMA:
0045 ring = radeon_copy_dma_ring_index(rdev);
0046 break;
0047 case RADEON_TEST_COPY_BLIT:
0048 ring = radeon_copy_blit_ring_index(rdev);
0049 break;
0050 default:
0051 DRM_ERROR("Unknown copy method\n");
0052 return;
0053 }
0054
0055 size = 1024 * 1024;
0056
0057
0058
0059
0060 n = rdev->mc.gtt_size - rdev->gart_pin_size;
0061 n /= size;
0062
0063 gtt_obj = kcalloc(n, sizeof(*gtt_obj), GFP_KERNEL);
0064 if (!gtt_obj) {
0065 DRM_ERROR("Failed to allocate %d pointers\n", n);
0066 r = 1;
0067 goto out_cleanup;
0068 }
0069
0070 r = radeon_bo_create(rdev, size, PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
0071 0, NULL, NULL, &vram_obj);
0072 if (r) {
0073 DRM_ERROR("Failed to create VRAM object\n");
0074 goto out_cleanup;
0075 }
0076 r = radeon_bo_reserve(vram_obj, false);
0077 if (unlikely(r != 0))
0078 goto out_unref;
0079 r = radeon_bo_pin(vram_obj, RADEON_GEM_DOMAIN_VRAM, &vram_addr);
0080 if (r) {
0081 DRM_ERROR("Failed to pin VRAM object\n");
0082 goto out_unres;
0083 }
0084 for (i = 0; i < n; i++) {
0085 void *gtt_map, *vram_map;
0086 void **gtt_start, **gtt_end;
0087 void **vram_start, **vram_end;
0088 struct radeon_fence *fence = NULL;
0089
0090 r = radeon_bo_create(rdev, size, PAGE_SIZE, true,
0091 RADEON_GEM_DOMAIN_GTT, 0, NULL, NULL,
0092 gtt_obj + i);
0093 if (r) {
0094 DRM_ERROR("Failed to create GTT object %d\n", i);
0095 goto out_lclean;
0096 }
0097
0098 r = radeon_bo_reserve(gtt_obj[i], false);
0099 if (unlikely(r != 0))
0100 goto out_lclean_unref;
0101 r = radeon_bo_pin(gtt_obj[i], RADEON_GEM_DOMAIN_GTT, >t_addr);
0102 if (r) {
0103 DRM_ERROR("Failed to pin GTT object %d\n", i);
0104 goto out_lclean_unres;
0105 }
0106
0107 r = radeon_bo_kmap(gtt_obj[i], >t_map);
0108 if (r) {
0109 DRM_ERROR("Failed to map GTT object %d\n", i);
0110 goto out_lclean_unpin;
0111 }
0112
0113 for (gtt_start = gtt_map, gtt_end = gtt_map + size;
0114 gtt_start < gtt_end;
0115 gtt_start++)
0116 *gtt_start = gtt_start;
0117
0118 radeon_bo_kunmap(gtt_obj[i]);
0119
0120 if (ring == R600_RING_TYPE_DMA_INDEX)
0121 fence = radeon_copy_dma(rdev, gtt_addr, vram_addr,
0122 size / RADEON_GPU_PAGE_SIZE,
0123 vram_obj->tbo.base.resv);
0124 else
0125 fence = radeon_copy_blit(rdev, gtt_addr, vram_addr,
0126 size / RADEON_GPU_PAGE_SIZE,
0127 vram_obj->tbo.base.resv);
0128 if (IS_ERR(fence)) {
0129 DRM_ERROR("Failed GTT->VRAM copy %d\n", i);
0130 r = PTR_ERR(fence);
0131 goto out_lclean_unpin;
0132 }
0133
0134 r = radeon_fence_wait(fence, false);
0135 if (r) {
0136 DRM_ERROR("Failed to wait for GTT->VRAM fence %d\n", i);
0137 goto out_lclean_unpin;
0138 }
0139
0140 radeon_fence_unref(&fence);
0141
0142 r = radeon_bo_kmap(vram_obj, &vram_map);
0143 if (r) {
0144 DRM_ERROR("Failed to map VRAM object after copy %d\n", i);
0145 goto out_lclean_unpin;
0146 }
0147
0148 for (gtt_start = gtt_map, gtt_end = gtt_map + size,
0149 vram_start = vram_map, vram_end = vram_map + size;
0150 vram_start < vram_end;
0151 gtt_start++, vram_start++) {
0152 if (*vram_start != gtt_start) {
0153 DRM_ERROR("Incorrect GTT->VRAM copy %d: Got 0x%p, "
0154 "expected 0x%p (GTT/VRAM offset "
0155 "0x%16llx/0x%16llx)\n",
0156 i, *vram_start, gtt_start,
0157 (unsigned long long)
0158 (gtt_addr - rdev->mc.gtt_start +
0159 (void*)gtt_start - gtt_map),
0160 (unsigned long long)
0161 (vram_addr - rdev->mc.vram_start +
0162 (void*)gtt_start - gtt_map));
0163 radeon_bo_kunmap(vram_obj);
0164 goto out_lclean_unpin;
0165 }
0166 *vram_start = vram_start;
0167 }
0168
0169 radeon_bo_kunmap(vram_obj);
0170
0171 if (ring == R600_RING_TYPE_DMA_INDEX)
0172 fence = radeon_copy_dma(rdev, vram_addr, gtt_addr,
0173 size / RADEON_GPU_PAGE_SIZE,
0174 vram_obj->tbo.base.resv);
0175 else
0176 fence = radeon_copy_blit(rdev, vram_addr, gtt_addr,
0177 size / RADEON_GPU_PAGE_SIZE,
0178 vram_obj->tbo.base.resv);
0179 if (IS_ERR(fence)) {
0180 DRM_ERROR("Failed VRAM->GTT copy %d\n", i);
0181 r = PTR_ERR(fence);
0182 goto out_lclean_unpin;
0183 }
0184
0185 r = radeon_fence_wait(fence, false);
0186 if (r) {
0187 DRM_ERROR("Failed to wait for VRAM->GTT fence %d\n", i);
0188 goto out_lclean_unpin;
0189 }
0190
0191 radeon_fence_unref(&fence);
0192
0193 r = radeon_bo_kmap(gtt_obj[i], >t_map);
0194 if (r) {
0195 DRM_ERROR("Failed to map GTT object after copy %d\n", i);
0196 goto out_lclean_unpin;
0197 }
0198
0199 for (gtt_start = gtt_map, gtt_end = gtt_map + size,
0200 vram_start = vram_map, vram_end = vram_map + size;
0201 gtt_start < gtt_end;
0202 gtt_start++, vram_start++) {
0203 if (*gtt_start != vram_start) {
0204 DRM_ERROR("Incorrect VRAM->GTT copy %d: Got 0x%p, "
0205 "expected 0x%p (VRAM/GTT offset "
0206 "0x%16llx/0x%16llx)\n",
0207 i, *gtt_start, vram_start,
0208 (unsigned long long)
0209 (vram_addr - rdev->mc.vram_start +
0210 (void*)vram_start - vram_map),
0211 (unsigned long long)
0212 (gtt_addr - rdev->mc.gtt_start +
0213 (void*)vram_start - vram_map));
0214 radeon_bo_kunmap(gtt_obj[i]);
0215 goto out_lclean_unpin;
0216 }
0217 }
0218
0219 radeon_bo_kunmap(gtt_obj[i]);
0220
0221 DRM_INFO("Tested GTT->VRAM and VRAM->GTT copy for GTT offset 0x%llx\n",
0222 gtt_addr - rdev->mc.gtt_start);
0223 continue;
0224
0225 out_lclean_unpin:
0226 radeon_bo_unpin(gtt_obj[i]);
0227 out_lclean_unres:
0228 radeon_bo_unreserve(gtt_obj[i]);
0229 out_lclean_unref:
0230 radeon_bo_unref(>t_obj[i]);
0231 out_lclean:
0232 for (--i; i >= 0; --i) {
0233 radeon_bo_unpin(gtt_obj[i]);
0234 radeon_bo_unreserve(gtt_obj[i]);
0235 radeon_bo_unref(>t_obj[i]);
0236 }
0237 if (fence && !IS_ERR(fence))
0238 radeon_fence_unref(&fence);
0239 break;
0240 }
0241
0242 radeon_bo_unpin(vram_obj);
0243 out_unres:
0244 radeon_bo_unreserve(vram_obj);
0245 out_unref:
0246 radeon_bo_unref(&vram_obj);
0247 out_cleanup:
0248 kfree(gtt_obj);
0249 if (r) {
0250 pr_warn("Error while testing BO move\n");
0251 }
0252 }
0253
0254 void radeon_test_moves(struct radeon_device *rdev)
0255 {
0256 if (rdev->asic->copy.dma)
0257 radeon_do_test_moves(rdev, RADEON_TEST_COPY_DMA);
0258 if (rdev->asic->copy.blit)
0259 radeon_do_test_moves(rdev, RADEON_TEST_COPY_BLIT);
0260 }
0261
0262 static int radeon_test_create_and_emit_fence(struct radeon_device *rdev,
0263 struct radeon_ring *ring,
0264 struct radeon_fence **fence)
0265 {
0266 uint32_t handle = ring->idx ^ 0xdeafbeef;
0267 int r;
0268
0269 if (ring->idx == R600_RING_TYPE_UVD_INDEX) {
0270 r = radeon_uvd_get_create_msg(rdev, ring->idx, handle, NULL);
0271 if (r) {
0272 DRM_ERROR("Failed to get dummy create msg\n");
0273 return r;
0274 }
0275
0276 r = radeon_uvd_get_destroy_msg(rdev, ring->idx, handle, fence);
0277 if (r) {
0278 DRM_ERROR("Failed to get dummy destroy msg\n");
0279 return r;
0280 }
0281
0282 } else if (ring->idx == TN_RING_TYPE_VCE1_INDEX ||
0283 ring->idx == TN_RING_TYPE_VCE2_INDEX) {
0284 r = radeon_vce_get_create_msg(rdev, ring->idx, handle, NULL);
0285 if (r) {
0286 DRM_ERROR("Failed to get dummy create msg\n");
0287 return r;
0288 }
0289
0290 r = radeon_vce_get_destroy_msg(rdev, ring->idx, handle, fence);
0291 if (r) {
0292 DRM_ERROR("Failed to get dummy destroy msg\n");
0293 return r;
0294 }
0295
0296 } else {
0297 r = radeon_ring_lock(rdev, ring, 64);
0298 if (r) {
0299 DRM_ERROR("Failed to lock ring A %d\n", ring->idx);
0300 return r;
0301 }
0302 r = radeon_fence_emit(rdev, fence, ring->idx);
0303 if (r) {
0304 DRM_ERROR("Failed to emit fence\n");
0305 radeon_ring_unlock_undo(rdev, ring);
0306 return r;
0307 }
0308 radeon_ring_unlock_commit(rdev, ring, false);
0309 }
0310 return 0;
0311 }
0312
0313 void radeon_test_ring_sync(struct radeon_device *rdev,
0314 struct radeon_ring *ringA,
0315 struct radeon_ring *ringB)
0316 {
0317 struct radeon_fence *fence1 = NULL, *fence2 = NULL;
0318 struct radeon_semaphore *semaphore = NULL;
0319 int r;
0320
0321 r = radeon_semaphore_create(rdev, &semaphore);
0322 if (r) {
0323 DRM_ERROR("Failed to create semaphore\n");
0324 goto out_cleanup;
0325 }
0326
0327 r = radeon_ring_lock(rdev, ringA, 64);
0328 if (r) {
0329 DRM_ERROR("Failed to lock ring A %d\n", ringA->idx);
0330 goto out_cleanup;
0331 }
0332 radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore);
0333 radeon_ring_unlock_commit(rdev, ringA, false);
0334
0335 r = radeon_test_create_and_emit_fence(rdev, ringA, &fence1);
0336 if (r)
0337 goto out_cleanup;
0338
0339 r = radeon_ring_lock(rdev, ringA, 64);
0340 if (r) {
0341 DRM_ERROR("Failed to lock ring A %d\n", ringA->idx);
0342 goto out_cleanup;
0343 }
0344 radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore);
0345 radeon_ring_unlock_commit(rdev, ringA, false);
0346
0347 r = radeon_test_create_and_emit_fence(rdev, ringA, &fence2);
0348 if (r)
0349 goto out_cleanup;
0350
0351 msleep(1000);
0352
0353 if (radeon_fence_signaled(fence1)) {
0354 DRM_ERROR("Fence 1 signaled without waiting for semaphore.\n");
0355 goto out_cleanup;
0356 }
0357
0358 r = radeon_ring_lock(rdev, ringB, 64);
0359 if (r) {
0360 DRM_ERROR("Failed to lock ring B %p\n", ringB);
0361 goto out_cleanup;
0362 }
0363 radeon_semaphore_emit_signal(rdev, ringB->idx, semaphore);
0364 radeon_ring_unlock_commit(rdev, ringB, false);
0365
0366 r = radeon_fence_wait(fence1, false);
0367 if (r) {
0368 DRM_ERROR("Failed to wait for sync fence 1\n");
0369 goto out_cleanup;
0370 }
0371
0372 msleep(1000);
0373
0374 if (radeon_fence_signaled(fence2)) {
0375 DRM_ERROR("Fence 2 signaled without waiting for semaphore.\n");
0376 goto out_cleanup;
0377 }
0378
0379 r = radeon_ring_lock(rdev, ringB, 64);
0380 if (r) {
0381 DRM_ERROR("Failed to lock ring B %p\n", ringB);
0382 goto out_cleanup;
0383 }
0384 radeon_semaphore_emit_signal(rdev, ringB->idx, semaphore);
0385 radeon_ring_unlock_commit(rdev, ringB, false);
0386
0387 r = radeon_fence_wait(fence2, false);
0388 if (r) {
0389 DRM_ERROR("Failed to wait for sync fence 1\n");
0390 goto out_cleanup;
0391 }
0392
0393 out_cleanup:
0394 radeon_semaphore_free(rdev, &semaphore, NULL);
0395
0396 if (fence1)
0397 radeon_fence_unref(&fence1);
0398
0399 if (fence2)
0400 radeon_fence_unref(&fence2);
0401
0402 if (r)
0403 pr_warn("Error while testing ring sync (%d)\n", r);
0404 }
0405
0406 static void radeon_test_ring_sync2(struct radeon_device *rdev,
0407 struct radeon_ring *ringA,
0408 struct radeon_ring *ringB,
0409 struct radeon_ring *ringC)
0410 {
0411 struct radeon_fence *fenceA = NULL, *fenceB = NULL;
0412 struct radeon_semaphore *semaphore = NULL;
0413 bool sigA, sigB;
0414 int i, r;
0415
0416 r = radeon_semaphore_create(rdev, &semaphore);
0417 if (r) {
0418 DRM_ERROR("Failed to create semaphore\n");
0419 goto out_cleanup;
0420 }
0421
0422 r = radeon_ring_lock(rdev, ringA, 64);
0423 if (r) {
0424 DRM_ERROR("Failed to lock ring A %d\n", ringA->idx);
0425 goto out_cleanup;
0426 }
0427 radeon_semaphore_emit_wait(rdev, ringA->idx, semaphore);
0428 radeon_ring_unlock_commit(rdev, ringA, false);
0429
0430 r = radeon_test_create_and_emit_fence(rdev, ringA, &fenceA);
0431 if (r)
0432 goto out_cleanup;
0433
0434 r = radeon_ring_lock(rdev, ringB, 64);
0435 if (r) {
0436 DRM_ERROR("Failed to lock ring B %d\n", ringB->idx);
0437 goto out_cleanup;
0438 }
0439 radeon_semaphore_emit_wait(rdev, ringB->idx, semaphore);
0440 radeon_ring_unlock_commit(rdev, ringB, false);
0441 r = radeon_test_create_and_emit_fence(rdev, ringB, &fenceB);
0442 if (r)
0443 goto out_cleanup;
0444
0445 msleep(1000);
0446
0447 if (radeon_fence_signaled(fenceA)) {
0448 DRM_ERROR("Fence A signaled without waiting for semaphore.\n");
0449 goto out_cleanup;
0450 }
0451 if (radeon_fence_signaled(fenceB)) {
0452 DRM_ERROR("Fence B signaled without waiting for semaphore.\n");
0453 goto out_cleanup;
0454 }
0455
0456 r = radeon_ring_lock(rdev, ringC, 64);
0457 if (r) {
0458 DRM_ERROR("Failed to lock ring B %p\n", ringC);
0459 goto out_cleanup;
0460 }
0461 radeon_semaphore_emit_signal(rdev, ringC->idx, semaphore);
0462 radeon_ring_unlock_commit(rdev, ringC, false);
0463
0464 for (i = 0; i < 30; ++i) {
0465 msleep(100);
0466 sigA = radeon_fence_signaled(fenceA);
0467 sigB = radeon_fence_signaled(fenceB);
0468 if (sigA || sigB)
0469 break;
0470 }
0471
0472 if (!sigA && !sigB) {
0473 DRM_ERROR("Neither fence A nor B has been signaled\n");
0474 goto out_cleanup;
0475 } else if (sigA && sigB) {
0476 DRM_ERROR("Both fence A and B has been signaled\n");
0477 goto out_cleanup;
0478 }
0479
0480 DRM_INFO("Fence %c was first signaled\n", sigA ? 'A' : 'B');
0481
0482 r = radeon_ring_lock(rdev, ringC, 64);
0483 if (r) {
0484 DRM_ERROR("Failed to lock ring B %p\n", ringC);
0485 goto out_cleanup;
0486 }
0487 radeon_semaphore_emit_signal(rdev, ringC->idx, semaphore);
0488 radeon_ring_unlock_commit(rdev, ringC, false);
0489
0490 msleep(1000);
0491
0492 r = radeon_fence_wait(fenceA, false);
0493 if (r) {
0494 DRM_ERROR("Failed to wait for sync fence A\n");
0495 goto out_cleanup;
0496 }
0497 r = radeon_fence_wait(fenceB, false);
0498 if (r) {
0499 DRM_ERROR("Failed to wait for sync fence B\n");
0500 goto out_cleanup;
0501 }
0502
0503 out_cleanup:
0504 radeon_semaphore_free(rdev, &semaphore, NULL);
0505
0506 if (fenceA)
0507 radeon_fence_unref(&fenceA);
0508
0509 if (fenceB)
0510 radeon_fence_unref(&fenceB);
0511
0512 if (r)
0513 pr_warn("Error while testing ring sync (%d)\n", r);
0514 }
0515
0516 static bool radeon_test_sync_possible(struct radeon_ring *ringA,
0517 struct radeon_ring *ringB)
0518 {
0519 if (ringA->idx == TN_RING_TYPE_VCE2_INDEX &&
0520 ringB->idx == TN_RING_TYPE_VCE1_INDEX)
0521 return false;
0522
0523 return true;
0524 }
0525
0526 void radeon_test_syncing(struct radeon_device *rdev)
0527 {
0528 int i, j, k;
0529
0530 for (i = 1; i < RADEON_NUM_RINGS; ++i) {
0531 struct radeon_ring *ringA = &rdev->ring[i];
0532 if (!ringA->ready)
0533 continue;
0534
0535 for (j = 0; j < i; ++j) {
0536 struct radeon_ring *ringB = &rdev->ring[j];
0537 if (!ringB->ready)
0538 continue;
0539
0540 if (!radeon_test_sync_possible(ringA, ringB))
0541 continue;
0542
0543 DRM_INFO("Testing syncing between rings %d and %d...\n", i, j);
0544 radeon_test_ring_sync(rdev, ringA, ringB);
0545
0546 DRM_INFO("Testing syncing between rings %d and %d...\n", j, i);
0547 radeon_test_ring_sync(rdev, ringB, ringA);
0548
0549 for (k = 0; k < j; ++k) {
0550 struct radeon_ring *ringC = &rdev->ring[k];
0551 if (!ringC->ready)
0552 continue;
0553
0554 if (!radeon_test_sync_possible(ringA, ringC))
0555 continue;
0556
0557 if (!radeon_test_sync_possible(ringB, ringC))
0558 continue;
0559
0560 DRM_INFO("Testing syncing between rings %d, %d and %d...\n", i, j, k);
0561 radeon_test_ring_sync2(rdev, ringA, ringB, ringC);
0562
0563 DRM_INFO("Testing syncing between rings %d, %d and %d...\n", i, k, j);
0564 radeon_test_ring_sync2(rdev, ringA, ringC, ringB);
0565
0566 DRM_INFO("Testing syncing between rings %d, %d and %d...\n", j, i, k);
0567 radeon_test_ring_sync2(rdev, ringB, ringA, ringC);
0568
0569 DRM_INFO("Testing syncing between rings %d, %d and %d...\n", j, k, i);
0570 radeon_test_ring_sync2(rdev, ringB, ringC, ringA);
0571
0572 DRM_INFO("Testing syncing between rings %d, %d and %d...\n", k, i, j);
0573 radeon_test_ring_sync2(rdev, ringC, ringA, ringB);
0574
0575 DRM_INFO("Testing syncing between rings %d, %d and %d...\n", k, j, i);
0576 radeon_test_ring_sync2(rdev, ringC, ringB, ringA);
0577 }
0578 }
0579 }
0580 }