2 * Copyright 2016 Advanced Micro Devices, Inc.
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 * The above copyright notice and this permission notice (including the
22 * next paragraph) shall be included in all copies or substantial portions
27 #include <linux/firmware.h>
28 #include <linux/module.h>
29 #include <linux/pci.h>
32 #include "amdgpu_pm.h"
33 #include "amdgpu_vcn.h"
37 #define FIRMWARE_RAVEN "amdgpu/raven_vcn.bin"
38 #define FIRMWARE_PICASSO "amdgpu/picasso_vcn.bin"
39 #define FIRMWARE_RAVEN2 "amdgpu/raven2_vcn.bin"
40 #define FIRMWARE_ARCTURUS "amdgpu/arcturus_vcn.bin"
41 #define FIRMWARE_RENOIR "amdgpu/renoir_vcn.bin"
42 #define FIRMWARE_NAVI10 "amdgpu/navi10_vcn.bin"
43 #define FIRMWARE_NAVI14 "amdgpu/navi14_vcn.bin"
44 #define FIRMWARE_NAVI12 "amdgpu/navi12_vcn.bin"
46 MODULE_FIRMWARE(FIRMWARE_RAVEN);
47 MODULE_FIRMWARE(FIRMWARE_PICASSO);
48 MODULE_FIRMWARE(FIRMWARE_RAVEN2);
49 MODULE_FIRMWARE(FIRMWARE_ARCTURUS);
50 MODULE_FIRMWARE(FIRMWARE_RENOIR);
51 MODULE_FIRMWARE(FIRMWARE_NAVI10);
52 MODULE_FIRMWARE(FIRMWARE_NAVI14);
53 MODULE_FIRMWARE(FIRMWARE_NAVI12);
55 static void amdgpu_vcn_idle_work_handler(struct work_struct *work);
57 int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
59 unsigned long bo_size, fw_shared_bo_size;
61 const struct common_firmware_header *hdr;
62 unsigned char fw_check;
65 INIT_DELAYED_WORK(&adev->vcn.idle_work, amdgpu_vcn_idle_work_handler);
66 mutex_init(&adev->vcn.vcn_pg_lock);
67 atomic_set(&adev->vcn.total_submission_cnt, 0);
68 for (i = 0; i < adev->vcn.num_vcn_inst; i++)
69 atomic_set(&adev->vcn.inst[i].dpg_enc_submission_cnt, 0);
71 switch (adev->asic_type) {
73 if (adev->apu_flags & AMD_APU_IS_RAVEN2)
74 fw_name = FIRMWARE_RAVEN2;
75 else if (adev->apu_flags & AMD_APU_IS_PICASSO)
76 fw_name = FIRMWARE_PICASSO;
78 fw_name = FIRMWARE_RAVEN;
81 fw_name = FIRMWARE_ARCTURUS;
82 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
83 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
84 adev->vcn.indirect_sram = true;
87 fw_name = FIRMWARE_RENOIR;
88 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
89 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
90 adev->vcn.indirect_sram = true;
93 fw_name = FIRMWARE_NAVI10;
94 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
95 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
96 adev->vcn.indirect_sram = true;
99 fw_name = FIRMWARE_NAVI14;
100 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
101 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
102 adev->vcn.indirect_sram = true;
105 fw_name = FIRMWARE_NAVI12;
106 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
107 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
108 adev->vcn.indirect_sram = true;
114 r = request_firmware(&adev->vcn.fw, fw_name, adev->dev);
116 dev_err(adev->dev, "amdgpu_vcn: Can't load firmware \"%s\"\n",
121 r = amdgpu_ucode_validate(adev->vcn.fw);
123 dev_err(adev->dev, "amdgpu_vcn: Can't validate firmware \"%s\"\n",
125 release_firmware(adev->vcn.fw);
130 hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
131 adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version);
133 /* Bit 20-23, it is encode major and non-zero for new naming convention.
134 * This field is part of version minor and DRM_DISABLED_FLAG in old naming
135 * convention. Since the l:wq!atest version minor is 0x5B and DRM_DISABLED_FLAG
136 * is zero in old naming convention, this field is always zero so far.
137 * These four bits are used to tell which naming convention is present.
139 fw_check = (le32_to_cpu(hdr->ucode_version) >> 20) & 0xf;
141 unsigned int dec_ver, enc_major, enc_minor, vep, fw_rev;
143 fw_rev = le32_to_cpu(hdr->ucode_version) & 0xfff;
144 enc_minor = (le32_to_cpu(hdr->ucode_version) >> 12) & 0xff;
145 enc_major = fw_check;
146 dec_ver = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xf;
147 vep = (le32_to_cpu(hdr->ucode_version) >> 28) & 0xf;
148 DRM_INFO("Found VCN firmware Version ENC: %hu.%hu DEC: %hu VEP: %hu Revision: %hu\n",
149 enc_major, enc_minor, dec_ver, vep, fw_rev);
151 unsigned int version_major, version_minor, family_id;
153 family_id = le32_to_cpu(hdr->ucode_version) & 0xff;
154 version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff;
155 version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff;
156 DRM_INFO("Found VCN firmware Version: %hu.%hu Family ID: %hu\n",
157 version_major, version_minor, family_id);
160 bo_size = AMDGPU_VCN_STACK_SIZE + AMDGPU_VCN_CONTEXT_SIZE;
161 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
162 bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
164 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
165 if (adev->vcn.harvest_config & (1 << i))
168 r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE,
169 AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].vcpu_bo,
170 &adev->vcn.inst[i].gpu_addr, &adev->vcn.inst[i].cpu_addr);
172 dev_err(adev->dev, "(%d) failed to allocate vcn bo\n", r);
176 if (adev->vcn.indirect_sram) {
177 r = amdgpu_bo_create_kernel(adev, 64 * 2 * 4, PAGE_SIZE,
178 AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].dpg_sram_bo,
179 &adev->vcn.inst[i].dpg_sram_gpu_addr, &adev->vcn.inst[i].dpg_sram_cpu_addr);
181 dev_err(adev->dev, "VCN %d (%d) failed to allocate DPG bo\n", i, r);
186 r = amdgpu_bo_create_kernel(adev, AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)),
187 PAGE_SIZE, AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].fw_shared_bo,
188 &adev->vcn.inst[i].fw_shared_gpu_addr, &adev->vcn.inst[i].fw_shared_cpu_addr);
190 dev_err(adev->dev, "VCN %d (%d) failed to allocate firmware shared bo\n", i, r);
194 fw_shared_bo_size = amdgpu_bo_size(adev->vcn.inst[i].fw_shared_bo);
195 adev->vcn.inst[i].saved_shm_bo = kvmalloc(fw_shared_bo_size, GFP_KERNEL);
201 int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
205 cancel_delayed_work_sync(&adev->vcn.idle_work);
207 for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
208 if (adev->vcn.harvest_config & (1 << j))
211 kvfree(adev->vcn.inst[j].saved_shm_bo);
212 amdgpu_bo_free_kernel(&adev->vcn.inst[j].fw_shared_bo,
213 &adev->vcn.inst[j].fw_shared_gpu_addr,
214 (void **)&adev->vcn.inst[j].fw_shared_cpu_addr);
216 if (adev->vcn.indirect_sram) {
217 amdgpu_bo_free_kernel(&adev->vcn.inst[j].dpg_sram_bo,
218 &adev->vcn.inst[j].dpg_sram_gpu_addr,
219 (void **)&adev->vcn.inst[j].dpg_sram_cpu_addr);
221 kvfree(adev->vcn.inst[j].saved_bo);
223 amdgpu_bo_free_kernel(&adev->vcn.inst[j].vcpu_bo,
224 &adev->vcn.inst[j].gpu_addr,
225 (void **)&adev->vcn.inst[j].cpu_addr);
227 amdgpu_ring_fini(&adev->vcn.inst[j].ring_dec);
229 for (i = 0; i < adev->vcn.num_enc_rings; ++i)
230 amdgpu_ring_fini(&adev->vcn.inst[j].ring_enc[i]);
233 release_firmware(adev->vcn.fw);
234 mutex_destroy(&adev->vcn.vcn_pg_lock);
239 int amdgpu_vcn_suspend(struct amdgpu_device *adev)
245 cancel_delayed_work_sync(&adev->vcn.idle_work);
247 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
248 if (adev->vcn.harvest_config & (1 << i))
250 if (adev->vcn.inst[i].vcpu_bo == NULL)
253 size = amdgpu_bo_size(adev->vcn.inst[i].vcpu_bo);
254 ptr = adev->vcn.inst[i].cpu_addr;
256 adev->vcn.inst[i].saved_bo = kvmalloc(size, GFP_KERNEL);
257 if (!adev->vcn.inst[i].saved_bo)
260 memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size);
262 if (adev->vcn.inst[i].fw_shared_bo == NULL)
265 if (!adev->vcn.inst[i].saved_shm_bo)
268 size = amdgpu_bo_size(adev->vcn.inst[i].fw_shared_bo);
269 ptr = adev->vcn.inst[i].fw_shared_cpu_addr;
271 memcpy_fromio(adev->vcn.inst[i].saved_shm_bo, ptr, size);
276 int amdgpu_vcn_resume(struct amdgpu_device *adev)
282 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
283 if (adev->vcn.harvest_config & (1 << i))
285 if (adev->vcn.inst[i].vcpu_bo == NULL)
288 size = amdgpu_bo_size(adev->vcn.inst[i].vcpu_bo);
289 ptr = adev->vcn.inst[i].cpu_addr;
291 if (adev->vcn.inst[i].saved_bo != NULL) {
292 memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size);
293 kvfree(adev->vcn.inst[i].saved_bo);
294 adev->vcn.inst[i].saved_bo = NULL;
296 const struct common_firmware_header *hdr;
299 hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
300 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
301 offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
302 memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset,
303 le32_to_cpu(hdr->ucode_size_bytes));
304 size -= le32_to_cpu(hdr->ucode_size_bytes);
305 ptr += le32_to_cpu(hdr->ucode_size_bytes);
307 memset_io(ptr, 0, size);
310 if (adev->vcn.inst[i].fw_shared_bo == NULL)
313 size = amdgpu_bo_size(adev->vcn.inst[i].fw_shared_bo);
314 ptr = adev->vcn.inst[i].fw_shared_cpu_addr;
316 if (adev->vcn.inst[i].saved_shm_bo != NULL)
317 memcpy_toio(ptr, adev->vcn.inst[i].saved_shm_bo, size);
319 memset_io(ptr, 0, size);
324 static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
326 struct amdgpu_device *adev =
327 container_of(work, struct amdgpu_device, vcn.idle_work.work);
328 unsigned int fences = 0, fence[AMDGPU_MAX_VCN_INSTANCES] = {0};
331 for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
332 if (adev->vcn.harvest_config & (1 << j))
335 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
336 fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_enc[i]);
339 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
340 struct dpg_pause_state new_state;
343 unlikely(atomic_read(&adev->vcn.inst[j].dpg_enc_submission_cnt)))
344 new_state.fw_based = VCN_DPG_STATE__PAUSE;
346 new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
348 adev->vcn.pause_dpg_mode(adev, j, &new_state);
351 fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_dec);
355 if (!fences && !atomic_read(&adev->vcn.total_submission_cnt)) {
356 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
359 schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
363 void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
365 struct amdgpu_device *adev = ring->adev;
367 atomic_inc(&adev->vcn.total_submission_cnt);
368 cancel_delayed_work_sync(&adev->vcn.idle_work);
370 mutex_lock(&adev->vcn.vcn_pg_lock);
371 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
372 AMD_PG_STATE_UNGATE);
374 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
375 struct dpg_pause_state new_state;
377 if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC) {
378 atomic_inc(&adev->vcn.inst[ring->me].dpg_enc_submission_cnt);
379 new_state.fw_based = VCN_DPG_STATE__PAUSE;
381 unsigned int fences = 0;
384 for (i = 0; i < adev->vcn.num_enc_rings; ++i)
385 fences += amdgpu_fence_count_emitted(&adev->vcn.inst[ring->me].ring_enc[i]);
387 if (fences || atomic_read(&adev->vcn.inst[ring->me].dpg_enc_submission_cnt))
388 new_state.fw_based = VCN_DPG_STATE__PAUSE;
390 new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
393 adev->vcn.pause_dpg_mode(adev, ring->me, &new_state);
395 mutex_unlock(&adev->vcn.vcn_pg_lock);
398 void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring)
400 if (ring->adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG &&
401 ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
402 atomic_dec(&ring->adev->vcn.inst[ring->me].dpg_enc_submission_cnt);
404 atomic_dec(&ring->adev->vcn.total_submission_cnt);
406 schedule_delayed_work(&ring->adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
409 int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring)
411 struct amdgpu_device *adev = ring->adev;
416 WREG32(adev->vcn.inst[ring->me].external.scratch9, 0xCAFEDEAD);
417 r = amdgpu_ring_alloc(ring, 3);
420 amdgpu_ring_write(ring, PACKET0(adev->vcn.internal.scratch9, 0));
421 amdgpu_ring_write(ring, 0xDEADBEEF);
422 amdgpu_ring_commit(ring);
423 for (i = 0; i < adev->usec_timeout; i++) {
424 tmp = RREG32(adev->vcn.inst[ring->me].external.scratch9);
425 if (tmp == 0xDEADBEEF)
430 if (i >= adev->usec_timeout)
436 static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,
437 struct amdgpu_bo *bo,
438 struct dma_fence **fence)
440 struct amdgpu_device *adev = ring->adev;
441 struct dma_fence *f = NULL;
442 struct amdgpu_job *job;
443 struct amdgpu_ib *ib;
447 r = amdgpu_job_alloc_with_ib(adev, 64,
448 AMDGPU_IB_POOL_DIRECT, &job);
453 addr = amdgpu_bo_gpu_offset(bo);
454 ib->ptr[0] = PACKET0(adev->vcn.internal.data0, 0);
456 ib->ptr[2] = PACKET0(adev->vcn.internal.data1, 0);
457 ib->ptr[3] = addr >> 32;
458 ib->ptr[4] = PACKET0(adev->vcn.internal.cmd, 0);
460 for (i = 6; i < 16; i += 2) {
461 ib->ptr[i] = PACKET0(adev->vcn.internal.nop, 0);
466 r = amdgpu_job_submit_direct(job, ring, &f);
470 amdgpu_bo_fence(bo, f, false);
471 amdgpu_bo_unreserve(bo);
472 amdgpu_bo_unref(&bo);
475 *fence = dma_fence_get(f);
481 amdgpu_job_free(job);
484 amdgpu_bo_unreserve(bo);
485 amdgpu_bo_unref(&bo);
489 static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
490 struct dma_fence **fence)
492 struct amdgpu_device *adev = ring->adev;
493 struct amdgpu_bo *bo = NULL;
497 r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
498 AMDGPU_GEM_DOMAIN_VRAM,
499 &bo, NULL, (void **)&msg);
503 msg[0] = cpu_to_le32(0x00000028);
504 msg[1] = cpu_to_le32(0x00000038);
505 msg[2] = cpu_to_le32(0x00000001);
506 msg[3] = cpu_to_le32(0x00000000);
507 msg[4] = cpu_to_le32(handle);
508 msg[5] = cpu_to_le32(0x00000000);
509 msg[6] = cpu_to_le32(0x00000001);
510 msg[7] = cpu_to_le32(0x00000028);
511 msg[8] = cpu_to_le32(0x00000010);
512 msg[9] = cpu_to_le32(0x00000000);
513 msg[10] = cpu_to_le32(0x00000007);
514 msg[11] = cpu_to_le32(0x00000000);
515 msg[12] = cpu_to_le32(0x00000780);
516 msg[13] = cpu_to_le32(0x00000440);
517 for (i = 14; i < 1024; ++i)
518 msg[i] = cpu_to_le32(0x0);
520 return amdgpu_vcn_dec_send_msg(ring, bo, fence);
523 static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
524 struct dma_fence **fence)
526 struct amdgpu_device *adev = ring->adev;
527 struct amdgpu_bo *bo = NULL;
531 r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
532 AMDGPU_GEM_DOMAIN_VRAM,
533 &bo, NULL, (void **)&msg);
537 msg[0] = cpu_to_le32(0x00000028);
538 msg[1] = cpu_to_le32(0x00000018);
539 msg[2] = cpu_to_le32(0x00000000);
540 msg[3] = cpu_to_le32(0x00000002);
541 msg[4] = cpu_to_le32(handle);
542 msg[5] = cpu_to_le32(0x00000000);
543 for (i = 6; i < 1024; ++i)
544 msg[i] = cpu_to_le32(0x0);
546 return amdgpu_vcn_dec_send_msg(ring, bo, fence);
549 int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)
551 struct dma_fence *fence;
554 r = amdgpu_vcn_dec_get_create_msg(ring, 1, NULL);
558 r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &fence);
562 r = dma_fence_wait_timeout(fence, false, timeout);
568 dma_fence_put(fence);
573 int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring)
575 struct amdgpu_device *adev = ring->adev;
580 if (amdgpu_sriov_vf(adev))
583 r = amdgpu_ring_alloc(ring, 16);
587 rptr = amdgpu_ring_get_rptr(ring);
589 amdgpu_ring_write(ring, VCN_ENC_CMD_END);
590 amdgpu_ring_commit(ring);
592 for (i = 0; i < adev->usec_timeout; i++) {
593 if (amdgpu_ring_get_rptr(ring) != rptr)
598 if (i >= adev->usec_timeout)
604 static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
605 struct amdgpu_bo *bo,
606 struct dma_fence **fence)
608 const unsigned ib_size_dw = 16;
609 struct amdgpu_job *job;
610 struct amdgpu_ib *ib;
611 struct dma_fence *f = NULL;
615 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
616 AMDGPU_IB_POOL_DIRECT, &job);
621 addr = amdgpu_bo_gpu_offset(bo);
624 ib->ptr[ib->length_dw++] = 0x00000018;
625 ib->ptr[ib->length_dw++] = 0x00000001; /* session info */
626 ib->ptr[ib->length_dw++] = handle;
627 ib->ptr[ib->length_dw++] = upper_32_bits(addr);
628 ib->ptr[ib->length_dw++] = addr;
629 ib->ptr[ib->length_dw++] = 0x0000000b;
631 ib->ptr[ib->length_dw++] = 0x00000014;
632 ib->ptr[ib->length_dw++] = 0x00000002; /* task info */
633 ib->ptr[ib->length_dw++] = 0x0000001c;
634 ib->ptr[ib->length_dw++] = 0x00000000;
635 ib->ptr[ib->length_dw++] = 0x00000000;
637 ib->ptr[ib->length_dw++] = 0x00000008;
638 ib->ptr[ib->length_dw++] = 0x08000001; /* op initialize */
640 for (i = ib->length_dw; i < ib_size_dw; ++i)
643 r = amdgpu_job_submit_direct(job, ring, &f);
648 *fence = dma_fence_get(f);
654 amdgpu_job_free(job);
658 static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
659 struct amdgpu_bo *bo,
660 struct dma_fence **fence)
662 const unsigned ib_size_dw = 16;
663 struct amdgpu_job *job;
664 struct amdgpu_ib *ib;
665 struct dma_fence *f = NULL;
669 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4,
670 AMDGPU_IB_POOL_DIRECT, &job);
675 addr = amdgpu_bo_gpu_offset(bo);
678 ib->ptr[ib->length_dw++] = 0x00000018;
679 ib->ptr[ib->length_dw++] = 0x00000001;
680 ib->ptr[ib->length_dw++] = handle;
681 ib->ptr[ib->length_dw++] = upper_32_bits(addr);
682 ib->ptr[ib->length_dw++] = addr;
683 ib->ptr[ib->length_dw++] = 0x0000000b;
685 ib->ptr[ib->length_dw++] = 0x00000014;
686 ib->ptr[ib->length_dw++] = 0x00000002;
687 ib->ptr[ib->length_dw++] = 0x0000001c;
688 ib->ptr[ib->length_dw++] = 0x00000000;
689 ib->ptr[ib->length_dw++] = 0x00000000;
691 ib->ptr[ib->length_dw++] = 0x00000008;
692 ib->ptr[ib->length_dw++] = 0x08000002; /* op close session */
694 for (i = ib->length_dw; i < ib_size_dw; ++i)
697 r = amdgpu_job_submit_direct(job, ring, &f);
702 *fence = dma_fence_get(f);
708 amdgpu_job_free(job);
712 int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
714 struct dma_fence *fence = NULL;
715 struct amdgpu_bo *bo = NULL;
718 r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE,
719 AMDGPU_GEM_DOMAIN_VRAM,
724 r = amdgpu_vcn_enc_get_create_msg(ring, 1, bo, NULL);
728 r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, bo, &fence);
732 r = dma_fence_wait_timeout(fence, false, timeout);
739 dma_fence_put(fence);
740 amdgpu_bo_unreserve(bo);
741 amdgpu_bo_unref(&bo);