treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / gpu / drm / amd / amdgpu / amdgpu_vcn.c
blobf96464e2c157fa6fe575a6ee175790caa87815dc
1 /*
2 * Copyright 2016 Advanced Micro Devices, Inc.
3 * All Rights Reserved.
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
23 * of the Software.
27 #include <linux/firmware.h>
28 #include <linux/module.h>
29 #include <linux/pci.h>
31 #include "amdgpu.h"
32 #include "amdgpu_pm.h"
33 #include "amdgpu_vcn.h"
34 #include "soc15d.h"
36 /* Firmware Names */
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;
60 const char *fw_name;
61 const struct common_firmware_header *hdr;
62 unsigned char fw_check;
63 int i, r;
65 INIT_DELAYED_WORK(&adev->vcn.idle_work, amdgpu_vcn_idle_work_handler);
67 switch (adev->asic_type) {
68 case CHIP_RAVEN:
69 if (adev->rev_id >= 8)
70 fw_name = FIRMWARE_RAVEN2;
71 else if (adev->pdev->device == 0x15d8)
72 fw_name = FIRMWARE_PICASSO;
73 else
74 fw_name = FIRMWARE_RAVEN;
75 break;
76 case CHIP_ARCTURUS:
77 fw_name = FIRMWARE_ARCTURUS;
78 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
79 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
80 adev->vcn.indirect_sram = true;
81 break;
82 case CHIP_RENOIR:
83 fw_name = FIRMWARE_RENOIR;
84 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
85 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
86 adev->vcn.indirect_sram = true;
87 break;
88 case CHIP_NAVI10:
89 fw_name = FIRMWARE_NAVI10;
90 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
91 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
92 adev->vcn.indirect_sram = true;
93 break;
94 case CHIP_NAVI14:
95 fw_name = FIRMWARE_NAVI14;
96 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
97 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
98 adev->vcn.indirect_sram = true;
99 break;
100 case CHIP_NAVI12:
101 fw_name = FIRMWARE_NAVI12;
102 if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
103 (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
104 adev->vcn.indirect_sram = true;
105 break;
106 default:
107 return -EINVAL;
110 r = request_firmware(&adev->vcn.fw, fw_name, adev->dev);
111 if (r) {
112 dev_err(adev->dev, "amdgpu_vcn: Can't load firmware \"%s\"\n",
113 fw_name);
114 return r;
117 r = amdgpu_ucode_validate(adev->vcn.fw);
118 if (r) {
119 dev_err(adev->dev, "amdgpu_vcn: Can't validate firmware \"%s\"\n",
120 fw_name);
121 release_firmware(adev->vcn.fw);
122 adev->vcn.fw = NULL;
123 return r;
126 hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
127 adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version);
129 /* Bit 20-23, it is encode major and non-zero for new naming convention.
130 * This field is part of version minor and DRM_DISABLED_FLAG in old naming
131 * convention. Since the l:wq!atest version minor is 0x5B and DRM_DISABLED_FLAG
132 * is zero in old naming convention, this field is always zero so far.
133 * These four bits are used to tell which naming convention is present.
135 fw_check = (le32_to_cpu(hdr->ucode_version) >> 20) & 0xf;
136 if (fw_check) {
137 unsigned int dec_ver, enc_major, enc_minor, vep, fw_rev;
139 fw_rev = le32_to_cpu(hdr->ucode_version) & 0xfff;
140 enc_minor = (le32_to_cpu(hdr->ucode_version) >> 12) & 0xff;
141 enc_major = fw_check;
142 dec_ver = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xf;
143 vep = (le32_to_cpu(hdr->ucode_version) >> 28) & 0xf;
144 DRM_INFO("Found VCN firmware Version ENC: %hu.%hu DEC: %hu VEP: %hu Revision: %hu\n",
145 enc_major, enc_minor, dec_ver, vep, fw_rev);
146 } else {
147 unsigned int version_major, version_minor, family_id;
149 family_id = le32_to_cpu(hdr->ucode_version) & 0xff;
150 version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff;
151 version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff;
152 DRM_INFO("Found VCN firmware Version: %hu.%hu Family ID: %hu\n",
153 version_major, version_minor, family_id);
156 bo_size = AMDGPU_VCN_STACK_SIZE + AMDGPU_VCN_CONTEXT_SIZE;
157 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
158 bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
160 for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
161 if (adev->vcn.harvest_config & (1 << i))
162 continue;
164 r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE,
165 AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].vcpu_bo,
166 &adev->vcn.inst[i].gpu_addr, &adev->vcn.inst[i].cpu_addr);
167 if (r) {
168 dev_err(adev->dev, "(%d) failed to allocate vcn bo\n", r);
169 return r;
172 if (adev->vcn.indirect_sram) {
173 r = amdgpu_bo_create_kernel(adev, 64 * 2 * 4, PAGE_SIZE,
174 AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.inst[i].dpg_sram_bo,
175 &adev->vcn.inst[i].dpg_sram_gpu_addr, &adev->vcn.inst[i].dpg_sram_cpu_addr);
176 if (r) {
177 dev_err(adev->dev, "VCN %d (%d) failed to allocate DPG bo\n", i, r);
178 return r;
183 return 0;
186 int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
188 int i, j;
190 cancel_delayed_work_sync(&adev->vcn.idle_work);
192 for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
193 if (adev->vcn.harvest_config & (1 << j))
194 continue;
195 if (adev->vcn.indirect_sram) {
196 amdgpu_bo_free_kernel(&adev->vcn.inst[j].dpg_sram_bo,
197 &adev->vcn.inst[j].dpg_sram_gpu_addr,
198 (void **)&adev->vcn.inst[j].dpg_sram_cpu_addr);
200 kvfree(adev->vcn.inst[j].saved_bo);
202 amdgpu_bo_free_kernel(&adev->vcn.inst[j].vcpu_bo,
203 &adev->vcn.inst[j].gpu_addr,
204 (void **)&adev->vcn.inst[j].cpu_addr);
206 amdgpu_ring_fini(&adev->vcn.inst[j].ring_dec);
208 for (i = 0; i < adev->vcn.num_enc_rings; ++i)
209 amdgpu_ring_fini(&adev->vcn.inst[j].ring_enc[i]);
212 release_firmware(adev->vcn.fw);
214 return 0;
217 int amdgpu_vcn_suspend(struct amdgpu_device *adev)
219 unsigned size;
220 void *ptr;
221 int i;
223 cancel_delayed_work_sync(&adev->vcn.idle_work);
225 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
226 if (adev->vcn.harvest_config & (1 << i))
227 continue;
228 if (adev->vcn.inst[i].vcpu_bo == NULL)
229 return 0;
231 size = amdgpu_bo_size(adev->vcn.inst[i].vcpu_bo);
232 ptr = adev->vcn.inst[i].cpu_addr;
234 adev->vcn.inst[i].saved_bo = kvmalloc(size, GFP_KERNEL);
235 if (!adev->vcn.inst[i].saved_bo)
236 return -ENOMEM;
238 memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size);
240 return 0;
243 int amdgpu_vcn_resume(struct amdgpu_device *adev)
245 unsigned size;
246 void *ptr;
247 int i;
249 for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
250 if (adev->vcn.harvest_config & (1 << i))
251 continue;
252 if (adev->vcn.inst[i].vcpu_bo == NULL)
253 return -EINVAL;
255 size = amdgpu_bo_size(adev->vcn.inst[i].vcpu_bo);
256 ptr = adev->vcn.inst[i].cpu_addr;
258 if (adev->vcn.inst[i].saved_bo != NULL) {
259 memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size);
260 kvfree(adev->vcn.inst[i].saved_bo);
261 adev->vcn.inst[i].saved_bo = NULL;
262 } else {
263 const struct common_firmware_header *hdr;
264 unsigned offset;
266 hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
267 if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
268 offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
269 memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset,
270 le32_to_cpu(hdr->ucode_size_bytes));
271 size -= le32_to_cpu(hdr->ucode_size_bytes);
272 ptr += le32_to_cpu(hdr->ucode_size_bytes);
274 memset_io(ptr, 0, size);
277 return 0;
280 static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
282 struct amdgpu_device *adev =
283 container_of(work, struct amdgpu_device, vcn.idle_work.work);
284 unsigned int fences = 0, fence[AMDGPU_MAX_VCN_INSTANCES] = {0};
285 unsigned int i, j;
287 for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
288 if (adev->vcn.harvest_config & (1 << j))
289 continue;
291 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
292 fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_enc[i]);
295 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
296 struct dpg_pause_state new_state;
298 if (fence[j])
299 new_state.fw_based = VCN_DPG_STATE__PAUSE;
300 else
301 new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
303 adev->vcn.pause_dpg_mode(adev, j, &new_state);
306 fence[j] += amdgpu_fence_count_emitted(&adev->vcn.inst[j].ring_dec);
307 fences += fence[j];
310 if (fences == 0) {
311 amdgpu_gfx_off_ctrl(adev, true);
312 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
313 AMD_PG_STATE_GATE);
314 } else {
315 schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
319 void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
321 struct amdgpu_device *adev = ring->adev;
322 bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
324 if (set_clocks) {
325 amdgpu_gfx_off_ctrl(adev, false);
326 amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
327 AMD_PG_STATE_UNGATE);
330 if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
331 struct dpg_pause_state new_state;
332 unsigned int fences = 0;
333 unsigned int i;
335 for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
336 fences += amdgpu_fence_count_emitted(&adev->vcn.inst[ring->me].ring_enc[i]);
338 if (fences)
339 new_state.fw_based = VCN_DPG_STATE__PAUSE;
340 else
341 new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
343 if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
344 new_state.fw_based = VCN_DPG_STATE__PAUSE;
346 adev->vcn.pause_dpg_mode(adev, ring->me, &new_state);
350 void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring)
352 schedule_delayed_work(&ring->adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
355 int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring)
357 struct amdgpu_device *adev = ring->adev;
358 uint32_t tmp = 0;
359 unsigned i;
360 int r;
362 WREG32(adev->vcn.inst[ring->me].external.scratch9, 0xCAFEDEAD);
363 r = amdgpu_ring_alloc(ring, 3);
364 if (r)
365 return r;
366 amdgpu_ring_write(ring, PACKET0(adev->vcn.internal.scratch9, 0));
367 amdgpu_ring_write(ring, 0xDEADBEEF);
368 amdgpu_ring_commit(ring);
369 for (i = 0; i < adev->usec_timeout; i++) {
370 tmp = RREG32(adev->vcn.inst[ring->me].external.scratch9);
371 if (tmp == 0xDEADBEEF)
372 break;
373 udelay(1);
376 if (i >= adev->usec_timeout)
377 r = -ETIMEDOUT;
379 return r;
382 static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,
383 struct amdgpu_bo *bo,
384 struct dma_fence **fence)
386 struct amdgpu_device *adev = ring->adev;
387 struct dma_fence *f = NULL;
388 struct amdgpu_job *job;
389 struct amdgpu_ib *ib;
390 uint64_t addr;
391 int i, r;
393 r = amdgpu_job_alloc_with_ib(adev, 64, &job);
394 if (r)
395 goto err;
397 ib = &job->ibs[0];
398 addr = amdgpu_bo_gpu_offset(bo);
399 ib->ptr[0] = PACKET0(adev->vcn.internal.data0, 0);
400 ib->ptr[1] = addr;
401 ib->ptr[2] = PACKET0(adev->vcn.internal.data1, 0);
402 ib->ptr[3] = addr >> 32;
403 ib->ptr[4] = PACKET0(adev->vcn.internal.cmd, 0);
404 ib->ptr[5] = 0;
405 for (i = 6; i < 16; i += 2) {
406 ib->ptr[i] = PACKET0(adev->vcn.internal.nop, 0);
407 ib->ptr[i+1] = 0;
409 ib->length_dw = 16;
411 r = amdgpu_job_submit_direct(job, ring, &f);
412 if (r)
413 goto err_free;
415 amdgpu_bo_fence(bo, f, false);
416 amdgpu_bo_unreserve(bo);
417 amdgpu_bo_unref(&bo);
419 if (fence)
420 *fence = dma_fence_get(f);
421 dma_fence_put(f);
423 return 0;
425 err_free:
426 amdgpu_job_free(job);
428 err:
429 amdgpu_bo_unreserve(bo);
430 amdgpu_bo_unref(&bo);
431 return r;
434 static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
435 struct dma_fence **fence)
437 struct amdgpu_device *adev = ring->adev;
438 struct amdgpu_bo *bo = NULL;
439 uint32_t *msg;
440 int r, i;
442 r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
443 AMDGPU_GEM_DOMAIN_VRAM,
444 &bo, NULL, (void **)&msg);
445 if (r)
446 return r;
448 msg[0] = cpu_to_le32(0x00000028);
449 msg[1] = cpu_to_le32(0x00000038);
450 msg[2] = cpu_to_le32(0x00000001);
451 msg[3] = cpu_to_le32(0x00000000);
452 msg[4] = cpu_to_le32(handle);
453 msg[5] = cpu_to_le32(0x00000000);
454 msg[6] = cpu_to_le32(0x00000001);
455 msg[7] = cpu_to_le32(0x00000028);
456 msg[8] = cpu_to_le32(0x00000010);
457 msg[9] = cpu_to_le32(0x00000000);
458 msg[10] = cpu_to_le32(0x00000007);
459 msg[11] = cpu_to_le32(0x00000000);
460 msg[12] = cpu_to_le32(0x00000780);
461 msg[13] = cpu_to_le32(0x00000440);
462 for (i = 14; i < 1024; ++i)
463 msg[i] = cpu_to_le32(0x0);
465 return amdgpu_vcn_dec_send_msg(ring, bo, fence);
468 static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
469 struct dma_fence **fence)
471 struct amdgpu_device *adev = ring->adev;
472 struct amdgpu_bo *bo = NULL;
473 uint32_t *msg;
474 int r, i;
476 r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
477 AMDGPU_GEM_DOMAIN_VRAM,
478 &bo, NULL, (void **)&msg);
479 if (r)
480 return r;
482 msg[0] = cpu_to_le32(0x00000028);
483 msg[1] = cpu_to_le32(0x00000018);
484 msg[2] = cpu_to_le32(0x00000000);
485 msg[3] = cpu_to_le32(0x00000002);
486 msg[4] = cpu_to_le32(handle);
487 msg[5] = cpu_to_le32(0x00000000);
488 for (i = 6; i < 1024; ++i)
489 msg[i] = cpu_to_le32(0x0);
491 return amdgpu_vcn_dec_send_msg(ring, bo, fence);
494 int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)
496 struct amdgpu_device *adev = ring->adev;
497 struct dma_fence *fence;
498 long r;
500 /* temporarily disable ib test for sriov */
501 if (amdgpu_sriov_vf(adev))
502 return 0;
504 r = amdgpu_vcn_dec_get_create_msg(ring, 1, NULL);
505 if (r)
506 goto error;
508 r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &fence);
509 if (r)
510 goto error;
512 r = dma_fence_wait_timeout(fence, false, timeout);
513 if (r == 0)
514 r = -ETIMEDOUT;
515 else if (r > 0)
516 r = 0;
518 dma_fence_put(fence);
519 error:
520 return r;
523 int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring)
525 struct amdgpu_device *adev = ring->adev;
526 uint32_t rptr;
527 unsigned i;
528 int r;
530 r = amdgpu_ring_alloc(ring, 16);
531 if (r)
532 return r;
534 rptr = amdgpu_ring_get_rptr(ring);
536 amdgpu_ring_write(ring, VCN_ENC_CMD_END);
537 amdgpu_ring_commit(ring);
539 for (i = 0; i < adev->usec_timeout; i++) {
540 if (amdgpu_ring_get_rptr(ring) != rptr)
541 break;
542 udelay(1);
545 if (i >= adev->usec_timeout)
546 r = -ETIMEDOUT;
548 return r;
551 static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
552 struct amdgpu_bo *bo,
553 struct dma_fence **fence)
555 const unsigned ib_size_dw = 16;
556 struct amdgpu_job *job;
557 struct amdgpu_ib *ib;
558 struct dma_fence *f = NULL;
559 uint64_t addr;
560 int i, r;
562 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
563 if (r)
564 return r;
566 ib = &job->ibs[0];
567 addr = amdgpu_bo_gpu_offset(bo);
569 ib->length_dw = 0;
570 ib->ptr[ib->length_dw++] = 0x00000018;
571 ib->ptr[ib->length_dw++] = 0x00000001; /* session info */
572 ib->ptr[ib->length_dw++] = handle;
573 ib->ptr[ib->length_dw++] = upper_32_bits(addr);
574 ib->ptr[ib->length_dw++] = addr;
575 ib->ptr[ib->length_dw++] = 0x0000000b;
577 ib->ptr[ib->length_dw++] = 0x00000014;
578 ib->ptr[ib->length_dw++] = 0x00000002; /* task info */
579 ib->ptr[ib->length_dw++] = 0x0000001c;
580 ib->ptr[ib->length_dw++] = 0x00000000;
581 ib->ptr[ib->length_dw++] = 0x00000000;
583 ib->ptr[ib->length_dw++] = 0x00000008;
584 ib->ptr[ib->length_dw++] = 0x08000001; /* op initialize */
586 for (i = ib->length_dw; i < ib_size_dw; ++i)
587 ib->ptr[i] = 0x0;
589 r = amdgpu_job_submit_direct(job, ring, &f);
590 if (r)
591 goto err;
593 if (fence)
594 *fence = dma_fence_get(f);
595 dma_fence_put(f);
597 return 0;
599 err:
600 amdgpu_job_free(job);
601 return r;
604 static int amdgpu_vcn_enc_get_destroy_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;
612 uint64_t addr;
613 int i, r;
615 r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
616 if (r)
617 return r;
619 ib = &job->ibs[0];
620 addr = amdgpu_bo_gpu_offset(bo);
622 ib->length_dw = 0;
623 ib->ptr[ib->length_dw++] = 0x00000018;
624 ib->ptr[ib->length_dw++] = 0x00000001;
625 ib->ptr[ib->length_dw++] = handle;
626 ib->ptr[ib->length_dw++] = upper_32_bits(addr);
627 ib->ptr[ib->length_dw++] = addr;
628 ib->ptr[ib->length_dw++] = 0x0000000b;
630 ib->ptr[ib->length_dw++] = 0x00000014;
631 ib->ptr[ib->length_dw++] = 0x00000002;
632 ib->ptr[ib->length_dw++] = 0x0000001c;
633 ib->ptr[ib->length_dw++] = 0x00000000;
634 ib->ptr[ib->length_dw++] = 0x00000000;
636 ib->ptr[ib->length_dw++] = 0x00000008;
637 ib->ptr[ib->length_dw++] = 0x08000002; /* op close session */
639 for (i = ib->length_dw; i < ib_size_dw; ++i)
640 ib->ptr[i] = 0x0;
642 r = amdgpu_job_submit_direct(job, ring, &f);
643 if (r)
644 goto err;
646 if (fence)
647 *fence = dma_fence_get(f);
648 dma_fence_put(f);
650 return 0;
652 err:
653 amdgpu_job_free(job);
654 return r;
657 int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
659 struct amdgpu_device *adev = ring->adev;
660 struct dma_fence *fence = NULL;
661 struct amdgpu_bo *bo = NULL;
662 long r;
664 /* temporarily disable ib test for sriov */
665 if (amdgpu_sriov_vf(adev))
666 return 0;
668 r = amdgpu_bo_create_reserved(ring->adev, 128 * 1024, PAGE_SIZE,
669 AMDGPU_GEM_DOMAIN_VRAM,
670 &bo, NULL, NULL);
671 if (r)
672 return r;
674 r = amdgpu_vcn_enc_get_create_msg(ring, 1, bo, NULL);
675 if (r)
676 goto error;
678 r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, bo, &fence);
679 if (r)
680 goto error;
682 r = dma_fence_wait_timeout(fence, false, timeout);
683 if (r == 0)
684 r = -ETIMEDOUT;
685 else if (r > 0)
686 r = 0;
688 error:
689 dma_fence_put(fence);
690 amdgpu_bo_unreserve(bo);
691 amdgpu_bo_unref(&bo);
692 return r;