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>
34 #include "amdgpu_pm.h"
35 #include "amdgpu_vcn.h"
37 #include "soc15_common.h"
39 #include "vcn/vcn_1_0_offset.h"
40 #include "vcn/vcn_1_0_sh_mask.h"
42 /* 1 second timeout */
43 #define VCN_IDLE_TIMEOUT msecs_to_jiffies(1000)
46 #define FIRMWARE_RAVEN "amdgpu/raven_vcn.bin"
47 #define FIRMWARE_PICASSO "amdgpu/picasso_vcn.bin"
48 #define FIRMWARE_RAVEN2 "amdgpu/raven2_vcn.bin"
49 #define FIRMWARE_ARCTURUS "amdgpu/arcturus_vcn.bin"
50 #define FIRMWARE_RENOIR "amdgpu/renoir_vcn.bin"
51 #define FIRMWARE_NAVI10 "amdgpu/navi10_vcn.bin"
52 #define FIRMWARE_NAVI14 "amdgpu/navi14_vcn.bin"
53 #define FIRMWARE_NAVI12 "amdgpu/navi12_vcn.bin"
55 MODULE_FIRMWARE(FIRMWARE_RAVEN
);
56 MODULE_FIRMWARE(FIRMWARE_PICASSO
);
57 MODULE_FIRMWARE(FIRMWARE_RAVEN2
);
58 MODULE_FIRMWARE(FIRMWARE_ARCTURUS
);
59 MODULE_FIRMWARE(FIRMWARE_RENOIR
);
60 MODULE_FIRMWARE(FIRMWARE_NAVI10
);
61 MODULE_FIRMWARE(FIRMWARE_NAVI14
);
62 MODULE_FIRMWARE(FIRMWARE_NAVI12
);
64 static void amdgpu_vcn_idle_work_handler(struct work_struct
*work
);
66 int amdgpu_vcn_sw_init(struct amdgpu_device
*adev
)
68 unsigned long bo_size
;
70 const struct common_firmware_header
*hdr
;
71 unsigned char fw_check
;
74 INIT_DELAYED_WORK(&adev
->vcn
.idle_work
, amdgpu_vcn_idle_work_handler
);
76 switch (adev
->asic_type
) {
78 if (adev
->rev_id
>= 8)
79 fw_name
= FIRMWARE_RAVEN2
;
80 else if (adev
->pdev
->device
== 0x15d8)
81 fw_name
= FIRMWARE_PICASSO
;
83 fw_name
= FIRMWARE_RAVEN
;
86 fw_name
= FIRMWARE_ARCTURUS
;
89 fw_name
= FIRMWARE_RENOIR
;
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;
95 fw_name
= FIRMWARE_NAVI10
;
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;
101 fw_name
= FIRMWARE_NAVI14
;
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;
107 fw_name
= FIRMWARE_NAVI12
;
108 if ((adev
->firmware
.load_type
== AMDGPU_FW_LOAD_PSP
) &&
109 (adev
->pg_flags
& AMD_PG_SUPPORT_VCN_DPG
))
110 adev
->vcn
.indirect_sram
= true;
116 r
= request_firmware(&adev
->vcn
.fw
, fw_name
, adev
->dev
);
118 dev_err(adev
->dev
, "amdgpu_vcn: Can't load firmware \"%s\"\n",
123 r
= amdgpu_ucode_validate(adev
->vcn
.fw
);
125 dev_err(adev
->dev
, "amdgpu_vcn: Can't validate firmware \"%s\"\n",
127 release_firmware(adev
->vcn
.fw
);
132 hdr
= (const struct common_firmware_header
*)adev
->vcn
.fw
->data
;
133 adev
->vcn
.fw_version
= le32_to_cpu(hdr
->ucode_version
);
135 /* Bit 20-23, it is encode major and non-zero for new naming convention.
136 * This field is part of version minor and DRM_DISABLED_FLAG in old naming
137 * convention. Since the l:wq!atest version minor is 0x5B and DRM_DISABLED_FLAG
138 * is zero in old naming convention, this field is always zero so far.
139 * These four bits are used to tell which naming convention is present.
141 fw_check
= (le32_to_cpu(hdr
->ucode_version
) >> 20) & 0xf;
143 unsigned int dec_ver
, enc_major
, enc_minor
, vep
, fw_rev
;
145 fw_rev
= le32_to_cpu(hdr
->ucode_version
) & 0xfff;
146 enc_minor
= (le32_to_cpu(hdr
->ucode_version
) >> 12) & 0xff;
147 enc_major
= fw_check
;
148 dec_ver
= (le32_to_cpu(hdr
->ucode_version
) >> 24) & 0xf;
149 vep
= (le32_to_cpu(hdr
->ucode_version
) >> 28) & 0xf;
150 DRM_INFO("Found VCN firmware Version ENC: %hu.%hu DEC: %hu VEP: %hu Revision: %hu\n",
151 enc_major
, enc_minor
, dec_ver
, vep
, fw_rev
);
153 unsigned int version_major
, version_minor
, family_id
;
155 family_id
= le32_to_cpu(hdr
->ucode_version
) & 0xff;
156 version_major
= (le32_to_cpu(hdr
->ucode_version
) >> 24) & 0xff;
157 version_minor
= (le32_to_cpu(hdr
->ucode_version
) >> 8) & 0xff;
158 DRM_INFO("Found VCN firmware Version: %hu.%hu Family ID: %hu\n",
159 version_major
, version_minor
, family_id
);
162 bo_size
= AMDGPU_VCN_STACK_SIZE
+ AMDGPU_VCN_CONTEXT_SIZE
;
163 if (adev
->firmware
.load_type
!= AMDGPU_FW_LOAD_PSP
)
164 bo_size
+= AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr
->ucode_size_bytes
) + 8);
166 for (i
= 0; i
< adev
->vcn
.num_vcn_inst
; i
++) {
167 if (adev
->vcn
.harvest_config
& (1 << i
))
170 r
= amdgpu_bo_create_kernel(adev
, bo_size
, PAGE_SIZE
,
171 AMDGPU_GEM_DOMAIN_VRAM
, &adev
->vcn
.inst
[i
].vcpu_bo
,
172 &adev
->vcn
.inst
[i
].gpu_addr
, &adev
->vcn
.inst
[i
].cpu_addr
);
174 dev_err(adev
->dev
, "(%d) failed to allocate vcn bo\n", r
);
179 if (adev
->vcn
.indirect_sram
) {
180 r
= amdgpu_bo_create_kernel(adev
, 64 * 2 * 4, PAGE_SIZE
,
181 AMDGPU_GEM_DOMAIN_VRAM
, &adev
->vcn
.dpg_sram_bo
,
182 &adev
->vcn
.dpg_sram_gpu_addr
, &adev
->vcn
.dpg_sram_cpu_addr
);
184 dev_err(adev
->dev
, "(%d) failed to allocate DPG bo\n", r
);
192 int amdgpu_vcn_sw_fini(struct amdgpu_device
*adev
)
196 if (adev
->vcn
.indirect_sram
) {
197 amdgpu_bo_free_kernel(&adev
->vcn
.dpg_sram_bo
,
198 &adev
->vcn
.dpg_sram_gpu_addr
,
199 (void **)&adev
->vcn
.dpg_sram_cpu_addr
);
202 for (j
= 0; j
< adev
->vcn
.num_vcn_inst
; ++j
) {
203 if (adev
->vcn
.harvest_config
& (1 << j
))
205 kvfree(adev
->vcn
.inst
[j
].saved_bo
);
207 amdgpu_bo_free_kernel(&adev
->vcn
.inst
[j
].vcpu_bo
,
208 &adev
->vcn
.inst
[j
].gpu_addr
,
209 (void **)&adev
->vcn
.inst
[j
].cpu_addr
);
211 amdgpu_ring_fini(&adev
->vcn
.inst
[j
].ring_dec
);
213 for (i
= 0; i
< adev
->vcn
.num_enc_rings
; ++i
)
214 amdgpu_ring_fini(&adev
->vcn
.inst
[j
].ring_enc
[i
]);
216 amdgpu_ring_fini(&adev
->vcn
.inst
[j
].ring_jpeg
);
219 release_firmware(adev
->vcn
.fw
);
224 int amdgpu_vcn_suspend(struct amdgpu_device
*adev
)
230 cancel_delayed_work_sync(&adev
->vcn
.idle_work
);
232 for (i
= 0; i
< adev
->vcn
.num_vcn_inst
; ++i
) {
233 if (adev
->vcn
.harvest_config
& (1 << i
))
235 if (adev
->vcn
.inst
[i
].vcpu_bo
== NULL
)
238 size
= amdgpu_bo_size(adev
->vcn
.inst
[i
].vcpu_bo
);
239 ptr
= adev
->vcn
.inst
[i
].cpu_addr
;
241 adev
->vcn
.inst
[i
].saved_bo
= kvmalloc(size
, GFP_KERNEL
);
242 if (!adev
->vcn
.inst
[i
].saved_bo
)
245 memcpy_fromio(adev
->vcn
.inst
[i
].saved_bo
, ptr
, size
);
250 int amdgpu_vcn_resume(struct amdgpu_device
*adev
)
256 for (i
= 0; i
< adev
->vcn
.num_vcn_inst
; ++i
) {
257 if (adev
->vcn
.harvest_config
& (1 << i
))
259 if (adev
->vcn
.inst
[i
].vcpu_bo
== NULL
)
262 size
= amdgpu_bo_size(adev
->vcn
.inst
[i
].vcpu_bo
);
263 ptr
= adev
->vcn
.inst
[i
].cpu_addr
;
265 if (adev
->vcn
.inst
[i
].saved_bo
!= NULL
) {
266 memcpy_toio(ptr
, adev
->vcn
.inst
[i
].saved_bo
, size
);
267 kvfree(adev
->vcn
.inst
[i
].saved_bo
);
268 adev
->vcn
.inst
[i
].saved_bo
= NULL
;
270 const struct common_firmware_header
*hdr
;
273 hdr
= (const struct common_firmware_header
*)adev
->vcn
.fw
->data
;
274 if (adev
->firmware
.load_type
!= AMDGPU_FW_LOAD_PSP
) {
275 offset
= le32_to_cpu(hdr
->ucode_array_offset_bytes
);
276 memcpy_toio(adev
->vcn
.inst
[i
].cpu_addr
, adev
->vcn
.fw
->data
+ offset
,
277 le32_to_cpu(hdr
->ucode_size_bytes
));
278 size
-= le32_to_cpu(hdr
->ucode_size_bytes
);
279 ptr
+= le32_to_cpu(hdr
->ucode_size_bytes
);
281 memset_io(ptr
, 0, size
);
287 static void amdgpu_vcn_idle_work_handler(struct work_struct
*work
)
289 struct amdgpu_device
*adev
=
290 container_of(work
, struct amdgpu_device
, vcn
.idle_work
.work
);
291 unsigned int fences
= 0, fence
[AMDGPU_MAX_VCN_INSTANCES
] = {0};
294 for (j
= 0; j
< adev
->vcn
.num_vcn_inst
; ++j
) {
295 if (adev
->vcn
.harvest_config
& (1 << j
))
297 for (i
= 0; i
< adev
->vcn
.num_enc_rings
; ++i
) {
298 fence
[j
] += amdgpu_fence_count_emitted(&adev
->vcn
.inst
[j
].ring_enc
[i
]);
301 if (adev
->pg_flags
& AMD_PG_SUPPORT_VCN_DPG
) {
302 struct dpg_pause_state new_state
;
305 new_state
.fw_based
= VCN_DPG_STATE__PAUSE
;
307 new_state
.fw_based
= VCN_DPG_STATE__UNPAUSE
;
309 if (amdgpu_fence_count_emitted(&adev
->vcn
.inst
[j
].ring_jpeg
))
310 new_state
.jpeg
= VCN_DPG_STATE__PAUSE
;
312 new_state
.jpeg
= VCN_DPG_STATE__UNPAUSE
;
314 adev
->vcn
.pause_dpg_mode(adev
, &new_state
);
317 fence
[j
] += amdgpu_fence_count_emitted(&adev
->vcn
.inst
[j
].ring_jpeg
);
318 fence
[j
] += amdgpu_fence_count_emitted(&adev
->vcn
.inst
[j
].ring_dec
);
323 amdgpu_gfx_off_ctrl(adev
, true);
324 if (adev
->asic_type
< CHIP_ARCTURUS
&& adev
->pm
.dpm_enabled
)
325 amdgpu_dpm_enable_uvd(adev
, false);
327 amdgpu_device_ip_set_powergating_state(adev
, AMD_IP_BLOCK_TYPE_VCN
,
330 schedule_delayed_work(&adev
->vcn
.idle_work
, VCN_IDLE_TIMEOUT
);
334 void amdgpu_vcn_ring_begin_use(struct amdgpu_ring
*ring
)
336 struct amdgpu_device
*adev
= ring
->adev
;
337 bool set_clocks
= !cancel_delayed_work_sync(&adev
->vcn
.idle_work
);
340 amdgpu_gfx_off_ctrl(adev
, false);
341 if (adev
->asic_type
< CHIP_ARCTURUS
&& adev
->pm
.dpm_enabled
)
342 amdgpu_dpm_enable_uvd(adev
, true);
344 amdgpu_device_ip_set_powergating_state(adev
, AMD_IP_BLOCK_TYPE_VCN
,
345 AMD_PG_STATE_UNGATE
);
348 if (adev
->pg_flags
& AMD_PG_SUPPORT_VCN_DPG
) {
349 struct dpg_pause_state new_state
;
350 unsigned int fences
= 0;
353 for (i
= 0; i
< adev
->vcn
.num_enc_rings
; ++i
) {
354 fences
+= amdgpu_fence_count_emitted(&adev
->vcn
.inst
[ring
->me
].ring_enc
[i
]);
357 new_state
.fw_based
= VCN_DPG_STATE__PAUSE
;
359 new_state
.fw_based
= VCN_DPG_STATE__UNPAUSE
;
361 if (amdgpu_fence_count_emitted(&adev
->vcn
.inst
[ring
->me
].ring_jpeg
))
362 new_state
.jpeg
= VCN_DPG_STATE__PAUSE
;
364 new_state
.jpeg
= VCN_DPG_STATE__UNPAUSE
;
366 if (ring
->funcs
->type
== AMDGPU_RING_TYPE_VCN_ENC
)
367 new_state
.fw_based
= VCN_DPG_STATE__PAUSE
;
368 else if (ring
->funcs
->type
== AMDGPU_RING_TYPE_VCN_JPEG
)
369 new_state
.jpeg
= VCN_DPG_STATE__PAUSE
;
371 adev
->vcn
.pause_dpg_mode(adev
, &new_state
);
375 void amdgpu_vcn_ring_end_use(struct amdgpu_ring
*ring
)
377 schedule_delayed_work(&ring
->adev
->vcn
.idle_work
, VCN_IDLE_TIMEOUT
);
380 int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring
*ring
)
382 struct amdgpu_device
*adev
= ring
->adev
;
387 WREG32(adev
->vcn
.inst
[ring
->me
].external
.scratch9
, 0xCAFEDEAD);
388 r
= amdgpu_ring_alloc(ring
, 3);
391 amdgpu_ring_write(ring
, PACKET0(adev
->vcn
.internal
.scratch9
, 0));
392 amdgpu_ring_write(ring
, 0xDEADBEEF);
393 amdgpu_ring_commit(ring
);
394 for (i
= 0; i
< adev
->usec_timeout
; i
++) {
395 tmp
= RREG32(adev
->vcn
.inst
[ring
->me
].external
.scratch9
);
396 if (tmp
== 0xDEADBEEF)
401 if (i
>= adev
->usec_timeout
)
407 static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring
*ring
,
408 struct amdgpu_bo
*bo
,
409 struct dma_fence
**fence
)
411 struct amdgpu_device
*adev
= ring
->adev
;
412 struct dma_fence
*f
= NULL
;
413 struct amdgpu_job
*job
;
414 struct amdgpu_ib
*ib
;
418 r
= amdgpu_job_alloc_with_ib(adev
, 64, &job
);
423 addr
= amdgpu_bo_gpu_offset(bo
);
424 ib
->ptr
[0] = PACKET0(adev
->vcn
.internal
.data0
, 0);
426 ib
->ptr
[2] = PACKET0(adev
->vcn
.internal
.data1
, 0);
427 ib
->ptr
[3] = addr
>> 32;
428 ib
->ptr
[4] = PACKET0(adev
->vcn
.internal
.cmd
, 0);
430 for (i
= 6; i
< 16; i
+= 2) {
431 ib
->ptr
[i
] = PACKET0(adev
->vcn
.internal
.nop
, 0);
436 r
= amdgpu_job_submit_direct(job
, ring
, &f
);
440 amdgpu_bo_fence(bo
, f
, false);
441 amdgpu_bo_unreserve(bo
);
442 amdgpu_bo_unref(&bo
);
445 *fence
= dma_fence_get(f
);
451 amdgpu_job_free(job
);
454 amdgpu_bo_unreserve(bo
);
455 amdgpu_bo_unref(&bo
);
459 static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring
*ring
, uint32_t handle
,
460 struct dma_fence
**fence
)
462 struct amdgpu_device
*adev
= ring
->adev
;
463 struct amdgpu_bo
*bo
= NULL
;
467 r
= amdgpu_bo_create_reserved(adev
, 1024, PAGE_SIZE
,
468 AMDGPU_GEM_DOMAIN_VRAM
,
469 &bo
, NULL
, (void **)&msg
);
473 msg
[0] = cpu_to_le32(0x00000028);
474 msg
[1] = cpu_to_le32(0x00000038);
475 msg
[2] = cpu_to_le32(0x00000001);
476 msg
[3] = cpu_to_le32(0x00000000);
477 msg
[4] = cpu_to_le32(handle
);
478 msg
[5] = cpu_to_le32(0x00000000);
479 msg
[6] = cpu_to_le32(0x00000001);
480 msg
[7] = cpu_to_le32(0x00000028);
481 msg
[8] = cpu_to_le32(0x00000010);
482 msg
[9] = cpu_to_le32(0x00000000);
483 msg
[10] = cpu_to_le32(0x00000007);
484 msg
[11] = cpu_to_le32(0x00000000);
485 msg
[12] = cpu_to_le32(0x00000780);
486 msg
[13] = cpu_to_le32(0x00000440);
487 for (i
= 14; i
< 1024; ++i
)
488 msg
[i
] = cpu_to_le32(0x0);
490 return amdgpu_vcn_dec_send_msg(ring
, bo
, fence
);
493 static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring
*ring
, uint32_t handle
,
494 struct dma_fence
**fence
)
496 struct amdgpu_device
*adev
= ring
->adev
;
497 struct amdgpu_bo
*bo
= NULL
;
501 r
= amdgpu_bo_create_reserved(adev
, 1024, PAGE_SIZE
,
502 AMDGPU_GEM_DOMAIN_VRAM
,
503 &bo
, NULL
, (void **)&msg
);
507 msg
[0] = cpu_to_le32(0x00000028);
508 msg
[1] = cpu_to_le32(0x00000018);
509 msg
[2] = cpu_to_le32(0x00000000);
510 msg
[3] = cpu_to_le32(0x00000002);
511 msg
[4] = cpu_to_le32(handle
);
512 msg
[5] = cpu_to_le32(0x00000000);
513 for (i
= 6; i
< 1024; ++i
)
514 msg
[i
] = cpu_to_le32(0x0);
516 return amdgpu_vcn_dec_send_msg(ring
, bo
, fence
);
519 int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring
*ring
, long timeout
)
521 struct dma_fence
*fence
;
524 r
= amdgpu_vcn_dec_get_create_msg(ring
, 1, NULL
);
528 r
= amdgpu_vcn_dec_get_destroy_msg(ring
, 1, &fence
);
532 r
= dma_fence_wait_timeout(fence
, false, timeout
);
538 dma_fence_put(fence
);
543 int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring
*ring
)
545 struct amdgpu_device
*adev
= ring
->adev
;
550 r
= amdgpu_ring_alloc(ring
, 16);
554 rptr
= amdgpu_ring_get_rptr(ring
);
556 amdgpu_ring_write(ring
, VCN_ENC_CMD_END
);
557 amdgpu_ring_commit(ring
);
559 for (i
= 0; i
< adev
->usec_timeout
; i
++) {
560 if (amdgpu_ring_get_rptr(ring
) != rptr
)
565 if (i
>= adev
->usec_timeout
)
571 static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring
*ring
, uint32_t handle
,
572 struct dma_fence
**fence
)
574 const unsigned ib_size_dw
= 16;
575 struct amdgpu_job
*job
;
576 struct amdgpu_ib
*ib
;
577 struct dma_fence
*f
= NULL
;
581 r
= amdgpu_job_alloc_with_ib(ring
->adev
, ib_size_dw
* 4, &job
);
586 dummy
= ib
->gpu_addr
+ 1024;
589 ib
->ptr
[ib
->length_dw
++] = 0x00000018;
590 ib
->ptr
[ib
->length_dw
++] = 0x00000001; /* session info */
591 ib
->ptr
[ib
->length_dw
++] = handle
;
592 ib
->ptr
[ib
->length_dw
++] = upper_32_bits(dummy
);
593 ib
->ptr
[ib
->length_dw
++] = dummy
;
594 ib
->ptr
[ib
->length_dw
++] = 0x0000000b;
596 ib
->ptr
[ib
->length_dw
++] = 0x00000014;
597 ib
->ptr
[ib
->length_dw
++] = 0x00000002; /* task info */
598 ib
->ptr
[ib
->length_dw
++] = 0x0000001c;
599 ib
->ptr
[ib
->length_dw
++] = 0x00000000;
600 ib
->ptr
[ib
->length_dw
++] = 0x00000000;
602 ib
->ptr
[ib
->length_dw
++] = 0x00000008;
603 ib
->ptr
[ib
->length_dw
++] = 0x08000001; /* op initialize */
605 for (i
= ib
->length_dw
; i
< ib_size_dw
; ++i
)
608 r
= amdgpu_job_submit_direct(job
, ring
, &f
);
613 *fence
= dma_fence_get(f
);
619 amdgpu_job_free(job
);
623 static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring
*ring
, uint32_t handle
,
624 struct dma_fence
**fence
)
626 const unsigned ib_size_dw
= 16;
627 struct amdgpu_job
*job
;
628 struct amdgpu_ib
*ib
;
629 struct dma_fence
*f
= NULL
;
633 r
= amdgpu_job_alloc_with_ib(ring
->adev
, ib_size_dw
* 4, &job
);
638 dummy
= ib
->gpu_addr
+ 1024;
641 ib
->ptr
[ib
->length_dw
++] = 0x00000018;
642 ib
->ptr
[ib
->length_dw
++] = 0x00000001;
643 ib
->ptr
[ib
->length_dw
++] = handle
;
644 ib
->ptr
[ib
->length_dw
++] = upper_32_bits(dummy
);
645 ib
->ptr
[ib
->length_dw
++] = dummy
;
646 ib
->ptr
[ib
->length_dw
++] = 0x0000000b;
648 ib
->ptr
[ib
->length_dw
++] = 0x00000014;
649 ib
->ptr
[ib
->length_dw
++] = 0x00000002;
650 ib
->ptr
[ib
->length_dw
++] = 0x0000001c;
651 ib
->ptr
[ib
->length_dw
++] = 0x00000000;
652 ib
->ptr
[ib
->length_dw
++] = 0x00000000;
654 ib
->ptr
[ib
->length_dw
++] = 0x00000008;
655 ib
->ptr
[ib
->length_dw
++] = 0x08000002; /* op close session */
657 for (i
= ib
->length_dw
; i
< ib_size_dw
; ++i
)
660 r
= amdgpu_job_submit_direct(job
, ring
, &f
);
665 *fence
= dma_fence_get(f
);
671 amdgpu_job_free(job
);
675 int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring
*ring
, long timeout
)
677 struct dma_fence
*fence
= NULL
;
680 r
= amdgpu_vcn_enc_get_create_msg(ring
, 1, NULL
);
684 r
= amdgpu_vcn_enc_get_destroy_msg(ring
, 1, &fence
);
688 r
= dma_fence_wait_timeout(fence
, false, timeout
);
695 dma_fence_put(fence
);
699 int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring
*ring
)
701 struct amdgpu_device
*adev
= ring
->adev
;
706 WREG32(adev
->vcn
.inst
[ring
->me
].external
.jpeg_pitch
, 0xCAFEDEAD);
707 r
= amdgpu_ring_alloc(ring
, 3);
711 amdgpu_ring_write(ring
, PACKET0(adev
->vcn
.internal
.jpeg_pitch
, 0));
712 amdgpu_ring_write(ring
, 0xDEADBEEF);
713 amdgpu_ring_commit(ring
);
715 for (i
= 0; i
< adev
->usec_timeout
; i
++) {
716 tmp
= RREG32(adev
->vcn
.inst
[ring
->me
].external
.jpeg_pitch
);
717 if (tmp
== 0xDEADBEEF)
722 if (i
>= adev
->usec_timeout
)
728 static int amdgpu_vcn_jpeg_set_reg(struct amdgpu_ring
*ring
, uint32_t handle
,
729 struct dma_fence
**fence
)
731 struct amdgpu_device
*adev
= ring
->adev
;
732 struct amdgpu_job
*job
;
733 struct amdgpu_ib
*ib
;
734 struct dma_fence
*f
= NULL
;
735 const unsigned ib_size_dw
= 16;
738 r
= amdgpu_job_alloc_with_ib(ring
->adev
, ib_size_dw
* 4, &job
);
744 ib
->ptr
[0] = PACKETJ(adev
->vcn
.internal
.jpeg_pitch
, 0, 0, PACKETJ_TYPE0
);
745 ib
->ptr
[1] = 0xDEADBEEF;
746 for (i
= 2; i
< 16; i
+= 2) {
747 ib
->ptr
[i
] = PACKETJ(0, 0, 0, PACKETJ_TYPE6
);
752 r
= amdgpu_job_submit_direct(job
, ring
, &f
);
757 *fence
= dma_fence_get(f
);
763 amdgpu_job_free(job
);
767 int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring
*ring
, long timeout
)
769 struct amdgpu_device
*adev
= ring
->adev
;
772 struct dma_fence
*fence
= NULL
;
775 r
= amdgpu_vcn_jpeg_set_reg(ring
, 1, &fence
);
779 r
= dma_fence_wait_timeout(fence
, false, timeout
);
789 for (i
= 0; i
< adev
->usec_timeout
; i
++) {
790 tmp
= RREG32(adev
->vcn
.inst
[ring
->me
].external
.jpeg_pitch
);
791 if (tmp
== 0xDEADBEEF)
796 if (i
>= adev
->usec_timeout
)
799 dma_fence_put(fence
);