.. | .. |
---|
27 | 27 | |
---|
28 | 28 | #include <linux/firmware.h> |
---|
29 | 29 | #include <linux/module.h> |
---|
30 | | -#include <drm/drmP.h> |
---|
| 30 | + |
---|
31 | 31 | #include <drm/drm.h> |
---|
32 | 32 | |
---|
33 | 33 | #include "amdgpu.h" |
---|
.. | .. |
---|
80 | 80 | MODULE_FIRMWARE(FIRMWARE_VEGA20); |
---|
81 | 81 | |
---|
82 | 82 | static void amdgpu_vce_idle_work_handler(struct work_struct *work); |
---|
| 83 | +static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, |
---|
| 84 | + struct amdgpu_bo *bo, |
---|
| 85 | + struct dma_fence **fence); |
---|
| 86 | +static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, |
---|
| 87 | + bool direct, struct dma_fence **fence); |
---|
83 | 88 | |
---|
84 | 89 | /** |
---|
85 | 90 | * amdgpu_vce_init - allocate memory, load vce firmware |
---|
.. | .. |
---|
211 | 216 | if (adev->vce.vcpu_bo == NULL) |
---|
212 | 217 | return 0; |
---|
213 | 218 | |
---|
| 219 | + cancel_delayed_work_sync(&adev->vce.idle_work); |
---|
214 | 220 | drm_sched_entity_destroy(&adev->vce.entity); |
---|
215 | 221 | |
---|
216 | 222 | amdgpu_bo_free_kernel(&adev->vce.vcpu_bo, &adev->vce.gpu_addr, |
---|
.. | .. |
---|
234 | 240 | int amdgpu_vce_entity_init(struct amdgpu_device *adev) |
---|
235 | 241 | { |
---|
236 | 242 | struct amdgpu_ring *ring; |
---|
237 | | - struct drm_sched_rq *rq; |
---|
| 243 | + struct drm_gpu_scheduler *sched; |
---|
238 | 244 | int r; |
---|
239 | 245 | |
---|
240 | 246 | ring = &adev->vce.ring[0]; |
---|
241 | | - rq = &ring->sched.sched_rq[DRM_SCHED_PRIORITY_NORMAL]; |
---|
242 | | - r = drm_sched_entity_init(&adev->vce.entity, &rq, 1, NULL); |
---|
| 247 | + sched = &ring->sched; |
---|
| 248 | + r = drm_sched_entity_init(&adev->vce.entity, DRM_SCHED_PRIORITY_NORMAL, |
---|
| 249 | + &sched, 1, NULL); |
---|
243 | 250 | if (r != 0) { |
---|
244 | 251 | DRM_ERROR("Failed setting up VCE run queue.\n"); |
---|
245 | 252 | return r; |
---|
.. | .. |
---|
428 | 435 | * |
---|
429 | 436 | * Open up a stream for HW test |
---|
430 | 437 | */ |
---|
431 | | -int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, |
---|
432 | | - struct dma_fence **fence) |
---|
| 438 | +static int amdgpu_vce_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, |
---|
| 439 | + struct amdgpu_bo *bo, |
---|
| 440 | + struct dma_fence **fence) |
---|
433 | 441 | { |
---|
434 | 442 | const unsigned ib_size_dw = 1024; |
---|
435 | 443 | struct amdgpu_job *job; |
---|
436 | 444 | struct amdgpu_ib *ib; |
---|
437 | 445 | struct dma_fence *f = NULL; |
---|
438 | | - uint64_t dummy; |
---|
| 446 | + uint64_t addr; |
---|
439 | 447 | int i, r; |
---|
440 | 448 | |
---|
441 | | - r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); |
---|
| 449 | + r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, |
---|
| 450 | + AMDGPU_IB_POOL_DIRECT, &job); |
---|
442 | 451 | if (r) |
---|
443 | 452 | return r; |
---|
444 | 453 | |
---|
445 | 454 | ib = &job->ibs[0]; |
---|
446 | 455 | |
---|
447 | | - dummy = ib->gpu_addr + 1024; |
---|
| 456 | + addr = amdgpu_bo_gpu_offset(bo); |
---|
448 | 457 | |
---|
449 | 458 | /* stitch together an VCE create msg */ |
---|
450 | 459 | ib->length_dw = 0; |
---|
.. | .. |
---|
476 | 485 | |
---|
477 | 486 | ib->ptr[ib->length_dw++] = 0x00000014; /* len */ |
---|
478 | 487 | ib->ptr[ib->length_dw++] = 0x05000005; /* feedback buffer */ |
---|
479 | | - ib->ptr[ib->length_dw++] = upper_32_bits(dummy); |
---|
480 | | - ib->ptr[ib->length_dw++] = dummy; |
---|
| 488 | + ib->ptr[ib->length_dw++] = upper_32_bits(addr); |
---|
| 489 | + ib->ptr[ib->length_dw++] = addr; |
---|
481 | 490 | ib->ptr[ib->length_dw++] = 0x00000001; |
---|
482 | 491 | |
---|
483 | 492 | for (i = ib->length_dw; i < ib_size_dw; ++i) |
---|
.. | .. |
---|
507 | 516 | * |
---|
508 | 517 | * Close up a stream for HW test or if userspace failed to do so |
---|
509 | 518 | */ |
---|
510 | | -int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, |
---|
511 | | - bool direct, struct dma_fence **fence) |
---|
| 519 | +static int amdgpu_vce_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle, |
---|
| 520 | + bool direct, struct dma_fence **fence) |
---|
512 | 521 | { |
---|
513 | 522 | const unsigned ib_size_dw = 1024; |
---|
514 | 523 | struct amdgpu_job *job; |
---|
.. | .. |
---|
516 | 525 | struct dma_fence *f = NULL; |
---|
517 | 526 | int i, r; |
---|
518 | 527 | |
---|
519 | | - r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job); |
---|
| 528 | + r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, |
---|
| 529 | + direct ? AMDGPU_IB_POOL_DIRECT : |
---|
| 530 | + AMDGPU_IB_POOL_DELAYED, &job); |
---|
520 | 531 | if (r) |
---|
521 | 532 | return r; |
---|
522 | 533 | |
---|
.. | .. |
---|
644 | 655 | |
---|
645 | 656 | if ((addr + (uint64_t)size) > |
---|
646 | 657 | (mapping->last + 1) * AMDGPU_GPU_PAGE_SIZE) { |
---|
647 | | - DRM_ERROR("BO to small for addr 0x%010Lx %d %d\n", |
---|
| 658 | + DRM_ERROR("BO too small for addr 0x%010Lx %d %d\n", |
---|
648 | 659 | addr, lo, hi); |
---|
649 | 660 | return -EINVAL; |
---|
650 | 661 | } |
---|
.. | .. |
---|
1032 | 1043 | * @ib: the IB to execute |
---|
1033 | 1044 | * |
---|
1034 | 1045 | */ |
---|
1035 | | -void amdgpu_vce_ring_emit_ib(struct amdgpu_ring *ring, struct amdgpu_ib *ib, |
---|
1036 | | - unsigned vmid, bool ctx_switch) |
---|
| 1046 | +void amdgpu_vce_ring_emit_ib(struct amdgpu_ring *ring, |
---|
| 1047 | + struct amdgpu_job *job, |
---|
| 1048 | + struct amdgpu_ib *ib, |
---|
| 1049 | + uint32_t flags) |
---|
1037 | 1050 | { |
---|
1038 | 1051 | amdgpu_ring_write(ring, VCE_CMD_IB); |
---|
1039 | 1052 | amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr)); |
---|
.. | .. |
---|
1079 | 1092 | return 0; |
---|
1080 | 1093 | |
---|
1081 | 1094 | r = amdgpu_ring_alloc(ring, 16); |
---|
1082 | | - if (r) { |
---|
1083 | | - DRM_ERROR("amdgpu: vce failed to lock ring %d (%d).\n", |
---|
1084 | | - ring->idx, r); |
---|
| 1095 | + if (r) |
---|
1085 | 1096 | return r; |
---|
1086 | | - } |
---|
1087 | 1097 | |
---|
1088 | 1098 | rptr = amdgpu_ring_get_rptr(ring); |
---|
1089 | 1099 | |
---|
.. | .. |
---|
1093 | 1103 | for (i = 0; i < timeout; i++) { |
---|
1094 | 1104 | if (amdgpu_ring_get_rptr(ring) != rptr) |
---|
1095 | 1105 | break; |
---|
1096 | | - DRM_UDELAY(1); |
---|
| 1106 | + udelay(1); |
---|
1097 | 1107 | } |
---|
1098 | 1108 | |
---|
1099 | | - if (i < timeout) { |
---|
1100 | | - DRM_DEBUG("ring test on %d succeeded in %d usecs\n", |
---|
1101 | | - ring->idx, i); |
---|
1102 | | - } else { |
---|
1103 | | - DRM_ERROR("amdgpu: ring %d test failed\n", |
---|
1104 | | - ring->idx); |
---|
| 1109 | + if (i >= timeout) |
---|
1105 | 1110 | r = -ETIMEDOUT; |
---|
1106 | | - } |
---|
1107 | 1111 | |
---|
1108 | 1112 | return r; |
---|
1109 | 1113 | } |
---|
.. | .. |
---|
1117 | 1121 | int amdgpu_vce_ring_test_ib(struct amdgpu_ring *ring, long timeout) |
---|
1118 | 1122 | { |
---|
1119 | 1123 | struct dma_fence *fence = NULL; |
---|
| 1124 | + struct amdgpu_bo *bo = NULL; |
---|
1120 | 1125 | long r; |
---|
1121 | 1126 | |
---|
1122 | 1127 | /* skip vce ring1/2 ib test for now, since it's not reliable */ |
---|
1123 | 1128 | if (ring != &ring->adev->vce.ring[0]) |
---|
1124 | 1129 | return 0; |
---|
1125 | 1130 | |
---|
1126 | | - r = amdgpu_vce_get_create_msg(ring, 1, NULL); |
---|
1127 | | - if (r) { |
---|
1128 | | - DRM_ERROR("amdgpu: failed to get create msg (%ld).\n", r); |
---|
| 1131 | + r = amdgpu_bo_create_reserved(ring->adev, 512, PAGE_SIZE, |
---|
| 1132 | + AMDGPU_GEM_DOMAIN_VRAM, |
---|
| 1133 | + &bo, NULL, NULL); |
---|
| 1134 | + if (r) |
---|
| 1135 | + return r; |
---|
| 1136 | + |
---|
| 1137 | + r = amdgpu_vce_get_create_msg(ring, 1, bo, NULL); |
---|
| 1138 | + if (r) |
---|
1129 | 1139 | goto error; |
---|
1130 | | - } |
---|
1131 | 1140 | |
---|
1132 | 1141 | r = amdgpu_vce_get_destroy_msg(ring, 1, true, &fence); |
---|
1133 | | - if (r) { |
---|
1134 | | - DRM_ERROR("amdgpu: failed to get destroy ib (%ld).\n", r); |
---|
| 1142 | + if (r) |
---|
1135 | 1143 | goto error; |
---|
1136 | | - } |
---|
1137 | 1144 | |
---|
1138 | 1145 | r = dma_fence_wait_timeout(fence, false, timeout); |
---|
1139 | | - if (r == 0) { |
---|
1140 | | - DRM_ERROR("amdgpu: IB test timed out.\n"); |
---|
| 1146 | + if (r == 0) |
---|
1141 | 1147 | r = -ETIMEDOUT; |
---|
1142 | | - } else if (r < 0) { |
---|
1143 | | - DRM_ERROR("amdgpu: fence wait failed (%ld).\n", r); |
---|
1144 | | - } else { |
---|
1145 | | - DRM_DEBUG("ib test on ring %d succeeded\n", ring->idx); |
---|
| 1148 | + else if (r > 0) |
---|
1146 | 1149 | r = 0; |
---|
1147 | | - } |
---|
| 1150 | + |
---|
1148 | 1151 | error: |
---|
1149 | 1152 | dma_fence_put(fence); |
---|
| 1153 | + amdgpu_bo_unreserve(bo); |
---|
| 1154 | + amdgpu_bo_unref(&bo); |
---|
1150 | 1155 | return r; |
---|
1151 | 1156 | } |
---|