xref: /openbmc/linux/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c (revision 4f727ecefefbd180de10e25b3e74c03dce3f1e75)
1 /*
2  * Copyright 2016 Advanced Micro Devices, Inc.
3  * All Rights Reserved.
4  *
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:
12  *
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.
20  *
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.
24  *
25  */
26 
27 #include <linux/firmware.h>
28 #include <linux/module.h>
29 #include <linux/pci.h>
30 
31 #include <drm/drm.h>
32 
33 #include "amdgpu.h"
34 #include "amdgpu_pm.h"
35 #include "amdgpu_vcn.h"
36 #include "soc15d.h"
37 #include "soc15_common.h"
38 
39 #include "vcn/vcn_1_0_offset.h"
40 #include "vcn/vcn_1_0_sh_mask.h"
41 
42 /* 1 second timeout */
43 #define VCN_IDLE_TIMEOUT	msecs_to_jiffies(1000)
44 
45 /* Firmware Names */
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_NAVI10 	"amdgpu/navi10_vcn.bin"
50 #define FIRMWARE_NAVI14 	"amdgpu/navi14_vcn.bin"
51 
52 MODULE_FIRMWARE(FIRMWARE_RAVEN);
53 MODULE_FIRMWARE(FIRMWARE_PICASSO);
54 MODULE_FIRMWARE(FIRMWARE_RAVEN2);
55 MODULE_FIRMWARE(FIRMWARE_NAVI10);
56 MODULE_FIRMWARE(FIRMWARE_NAVI14);
57 
58 static void amdgpu_vcn_idle_work_handler(struct work_struct *work);
59 
60 int amdgpu_vcn_sw_init(struct amdgpu_device *adev)
61 {
62 	unsigned long bo_size;
63 	const char *fw_name;
64 	const struct common_firmware_header *hdr;
65 	unsigned char fw_check;
66 	int r;
67 
68 	INIT_DELAYED_WORK(&adev->vcn.idle_work, amdgpu_vcn_idle_work_handler);
69 
70 	switch (adev->asic_type) {
71 	case CHIP_RAVEN:
72 		if (adev->rev_id >= 8)
73 			fw_name = FIRMWARE_RAVEN2;
74 		else if (adev->pdev->device == 0x15d8)
75 			fw_name = FIRMWARE_PICASSO;
76 		else
77 			fw_name = FIRMWARE_RAVEN;
78 		break;
79 	case CHIP_NAVI10:
80 		fw_name = FIRMWARE_NAVI10;
81 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
82 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
83 			adev->vcn.indirect_sram = true;
84 		break;
85     case CHIP_NAVI14:
86 		fw_name = FIRMWARE_NAVI14;
87 		if ((adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) &&
88 		    (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG))
89 			adev->vcn.indirect_sram = true;
90 		break;
91 	default:
92 		return -EINVAL;
93 	}
94 
95 	r = request_firmware(&adev->vcn.fw, fw_name, adev->dev);
96 	if (r) {
97 		dev_err(adev->dev, "amdgpu_vcn: Can't load firmware \"%s\"\n",
98 			fw_name);
99 		return r;
100 	}
101 
102 	r = amdgpu_ucode_validate(adev->vcn.fw);
103 	if (r) {
104 		dev_err(adev->dev, "amdgpu_vcn: Can't validate firmware \"%s\"\n",
105 			fw_name);
106 		release_firmware(adev->vcn.fw);
107 		adev->vcn.fw = NULL;
108 		return r;
109 	}
110 
111 	hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
112 	adev->vcn.fw_version = le32_to_cpu(hdr->ucode_version);
113 
114 	/* Bit 20-23, it is encode major and non-zero for new naming convention.
115 	 * This field is part of version minor and DRM_DISABLED_FLAG in old naming
116 	 * convention. Since the l:wq!atest version minor is 0x5B and DRM_DISABLED_FLAG
117 	 * is zero in old naming convention, this field is always zero so far.
118 	 * These four bits are used to tell which naming convention is present.
119 	 */
120 	fw_check = (le32_to_cpu(hdr->ucode_version) >> 20) & 0xf;
121 	if (fw_check) {
122 		unsigned int dec_ver, enc_major, enc_minor, vep, fw_rev;
123 
124 		fw_rev = le32_to_cpu(hdr->ucode_version) & 0xfff;
125 		enc_minor = (le32_to_cpu(hdr->ucode_version) >> 12) & 0xff;
126 		enc_major = fw_check;
127 		dec_ver = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xf;
128 		vep = (le32_to_cpu(hdr->ucode_version) >> 28) & 0xf;
129 		DRM_INFO("Found VCN firmware Version ENC: %hu.%hu DEC: %hu VEP: %hu Revision: %hu\n",
130 			enc_major, enc_minor, dec_ver, vep, fw_rev);
131 	} else {
132 		unsigned int version_major, version_minor, family_id;
133 
134 		family_id = le32_to_cpu(hdr->ucode_version) & 0xff;
135 		version_major = (le32_to_cpu(hdr->ucode_version) >> 24) & 0xff;
136 		version_minor = (le32_to_cpu(hdr->ucode_version) >> 8) & 0xff;
137 		DRM_INFO("Found VCN firmware Version: %hu.%hu Family ID: %hu\n",
138 			version_major, version_minor, family_id);
139 	}
140 
141 	bo_size = AMDGPU_VCN_STACK_SIZE + AMDGPU_VCN_CONTEXT_SIZE;
142 	if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP)
143 		bo_size += AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
144 	r = amdgpu_bo_create_kernel(adev, bo_size, PAGE_SIZE,
145 				    AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.vcpu_bo,
146 				    &adev->vcn.gpu_addr, &adev->vcn.cpu_addr);
147 	if (r) {
148 		dev_err(adev->dev, "(%d) failed to allocate vcn bo\n", r);
149 		return r;
150 	}
151 
152 	if (adev->vcn.indirect_sram) {
153 		r = amdgpu_bo_create_kernel(adev, 64 * 2 * 4, PAGE_SIZE,
154 			    AMDGPU_GEM_DOMAIN_VRAM, &adev->vcn.dpg_sram_bo,
155 			    &adev->vcn.dpg_sram_gpu_addr, &adev->vcn.dpg_sram_cpu_addr);
156 		if (r) {
157 			dev_err(adev->dev, "(%d) failed to allocate DPG bo\n", r);
158 			return r;
159 		}
160 	}
161 
162 	return 0;
163 }
164 
165 int amdgpu_vcn_sw_fini(struct amdgpu_device *adev)
166 {
167 	int i;
168 
169 	kvfree(adev->vcn.saved_bo);
170 
171 	if (adev->vcn.indirect_sram) {
172 		amdgpu_bo_free_kernel(&adev->vcn.dpg_sram_bo,
173 			      &adev->vcn.dpg_sram_gpu_addr,
174 			      (void **)&adev->vcn.dpg_sram_cpu_addr);
175 	}
176 
177 	amdgpu_bo_free_kernel(&adev->vcn.vcpu_bo,
178 			      &adev->vcn.gpu_addr,
179 			      (void **)&adev->vcn.cpu_addr);
180 
181 	amdgpu_ring_fini(&adev->vcn.ring_dec);
182 
183 	for (i = 0; i < adev->vcn.num_enc_rings; ++i)
184 		amdgpu_ring_fini(&adev->vcn.ring_enc[i]);
185 
186 	amdgpu_ring_fini(&adev->vcn.ring_jpeg);
187 
188 	release_firmware(adev->vcn.fw);
189 
190 	return 0;
191 }
192 
193 int amdgpu_vcn_suspend(struct amdgpu_device *adev)
194 {
195 	unsigned size;
196 	void *ptr;
197 
198 	cancel_delayed_work_sync(&adev->vcn.idle_work);
199 
200 	if (adev->vcn.vcpu_bo == NULL)
201 		return 0;
202 
203 	size = amdgpu_bo_size(adev->vcn.vcpu_bo);
204 	ptr = adev->vcn.cpu_addr;
205 
206 	adev->vcn.saved_bo = kvmalloc(size, GFP_KERNEL);
207 	if (!adev->vcn.saved_bo)
208 		return -ENOMEM;
209 
210 	memcpy_fromio(adev->vcn.saved_bo, ptr, size);
211 
212 	return 0;
213 }
214 
215 int amdgpu_vcn_resume(struct amdgpu_device *adev)
216 {
217 	unsigned size;
218 	void *ptr;
219 
220 	if (adev->vcn.vcpu_bo == NULL)
221 		return -EINVAL;
222 
223 	size = amdgpu_bo_size(adev->vcn.vcpu_bo);
224 	ptr = adev->vcn.cpu_addr;
225 
226 	if (adev->vcn.saved_bo != NULL) {
227 		memcpy_toio(ptr, adev->vcn.saved_bo, size);
228 		kvfree(adev->vcn.saved_bo);
229 		adev->vcn.saved_bo = NULL;
230 	} else {
231 		const struct common_firmware_header *hdr;
232 		unsigned offset;
233 
234 		hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
235 		if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) {
236 			offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
237 			memcpy_toio(adev->vcn.cpu_addr, adev->vcn.fw->data + offset,
238 				    le32_to_cpu(hdr->ucode_size_bytes));
239 			size -= le32_to_cpu(hdr->ucode_size_bytes);
240 			ptr += le32_to_cpu(hdr->ucode_size_bytes);
241 		}
242 		memset_io(ptr, 0, size);
243 	}
244 
245 	return 0;
246 }
247 
248 static void amdgpu_vcn_idle_work_handler(struct work_struct *work)
249 {
250 	struct amdgpu_device *adev =
251 		container_of(work, struct amdgpu_device, vcn.idle_work.work);
252 	unsigned int fences = 0;
253 	unsigned int i;
254 
255 	for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
256 		fences += amdgpu_fence_count_emitted(&adev->vcn.ring_enc[i]);
257 	}
258 
259 	if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)	{
260 		struct dpg_pause_state new_state;
261 
262 		if (fences)
263 			new_state.fw_based = VCN_DPG_STATE__PAUSE;
264 		else
265 			new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
266 
267 		if (amdgpu_fence_count_emitted(&adev->vcn.ring_jpeg))
268 			new_state.jpeg = VCN_DPG_STATE__PAUSE;
269 		else
270 			new_state.jpeg = VCN_DPG_STATE__UNPAUSE;
271 
272 		adev->vcn.pause_dpg_mode(adev, &new_state);
273 	}
274 
275 	fences += amdgpu_fence_count_emitted(&adev->vcn.ring_jpeg);
276 	fences += amdgpu_fence_count_emitted(&adev->vcn.ring_dec);
277 
278 	if (fences == 0) {
279 		amdgpu_gfx_off_ctrl(adev, true);
280 		if (adev->asic_type < CHIP_NAVI10 && adev->pm.dpm_enabled)
281 			amdgpu_dpm_enable_uvd(adev, false);
282 		else
283 			amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
284 							       AMD_PG_STATE_GATE);
285 	} else {
286 		schedule_delayed_work(&adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
287 	}
288 }
289 
290 void amdgpu_vcn_ring_begin_use(struct amdgpu_ring *ring)
291 {
292 	struct amdgpu_device *adev = ring->adev;
293 	bool set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
294 
295 	if (set_clocks) {
296 		amdgpu_gfx_off_ctrl(adev, false);
297 		if (adev->asic_type < CHIP_NAVI10 && adev->pm.dpm_enabled)
298 			amdgpu_dpm_enable_uvd(adev, true);
299 		else
300 			amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCN,
301 							       AMD_PG_STATE_UNGATE);
302 	}
303 
304 	if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)	{
305 		struct dpg_pause_state new_state;
306 		unsigned int fences = 0;
307 		unsigned int i;
308 
309 		for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
310 			fences += amdgpu_fence_count_emitted(&adev->vcn.ring_enc[i]);
311 		}
312 		if (fences)
313 			new_state.fw_based = VCN_DPG_STATE__PAUSE;
314 		else
315 			new_state.fw_based = VCN_DPG_STATE__UNPAUSE;
316 
317 		if (amdgpu_fence_count_emitted(&adev->vcn.ring_jpeg))
318 			new_state.jpeg = VCN_DPG_STATE__PAUSE;
319 		else
320 			new_state.jpeg = VCN_DPG_STATE__UNPAUSE;
321 
322 		if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_ENC)
323 			new_state.fw_based = VCN_DPG_STATE__PAUSE;
324 		else if (ring->funcs->type == AMDGPU_RING_TYPE_VCN_JPEG)
325 			new_state.jpeg = VCN_DPG_STATE__PAUSE;
326 
327 		adev->vcn.pause_dpg_mode(adev, &new_state);
328 	}
329 }
330 
331 void amdgpu_vcn_ring_end_use(struct amdgpu_ring *ring)
332 {
333 	schedule_delayed_work(&ring->adev->vcn.idle_work, VCN_IDLE_TIMEOUT);
334 }
335 
336 int amdgpu_vcn_dec_ring_test_ring(struct amdgpu_ring *ring)
337 {
338 	struct amdgpu_device *adev = ring->adev;
339 	uint32_t tmp = 0;
340 	unsigned i;
341 	int r;
342 
343 	WREG32(adev->vcn.external.scratch9, 0xCAFEDEAD);
344 	r = amdgpu_ring_alloc(ring, 3);
345 	if (r)
346 		return r;
347 	amdgpu_ring_write(ring, PACKET0(adev->vcn.internal.scratch9, 0));
348 	amdgpu_ring_write(ring, 0xDEADBEEF);
349 	amdgpu_ring_commit(ring);
350 	for (i = 0; i < adev->usec_timeout; i++) {
351 		tmp = RREG32(adev->vcn.external.scratch9);
352 		if (tmp == 0xDEADBEEF)
353 			break;
354 		udelay(1);
355 	}
356 
357 	if (i >= adev->usec_timeout)
358 		r = -ETIMEDOUT;
359 
360 	return r;
361 }
362 
363 static int amdgpu_vcn_dec_send_msg(struct amdgpu_ring *ring,
364 				   struct amdgpu_bo *bo,
365 				   struct dma_fence **fence)
366 {
367 	struct amdgpu_device *adev = ring->adev;
368 	struct dma_fence *f = NULL;
369 	struct amdgpu_job *job;
370 	struct amdgpu_ib *ib;
371 	uint64_t addr;
372 	int i, r;
373 
374 	r = amdgpu_job_alloc_with_ib(adev, 64, &job);
375 	if (r)
376 		goto err;
377 
378 	ib = &job->ibs[0];
379 	addr = amdgpu_bo_gpu_offset(bo);
380 	ib->ptr[0] = PACKET0(adev->vcn.internal.data0, 0);
381 	ib->ptr[1] = addr;
382 	ib->ptr[2] = PACKET0(adev->vcn.internal.data1, 0);
383 	ib->ptr[3] = addr >> 32;
384 	ib->ptr[4] = PACKET0(adev->vcn.internal.cmd, 0);
385 	ib->ptr[5] = 0;
386 	for (i = 6; i < 16; i += 2) {
387 		ib->ptr[i] = PACKET0(adev->vcn.internal.nop, 0);
388 		ib->ptr[i+1] = 0;
389 	}
390 	ib->length_dw = 16;
391 
392 	r = amdgpu_job_submit_direct(job, ring, &f);
393 	if (r)
394 		goto err_free;
395 
396 	amdgpu_bo_fence(bo, f, false);
397 	amdgpu_bo_unreserve(bo);
398 	amdgpu_bo_unref(&bo);
399 
400 	if (fence)
401 		*fence = dma_fence_get(f);
402 	dma_fence_put(f);
403 
404 	return 0;
405 
406 err_free:
407 	amdgpu_job_free(job);
408 
409 err:
410 	amdgpu_bo_unreserve(bo);
411 	amdgpu_bo_unref(&bo);
412 	return r;
413 }
414 
415 static int amdgpu_vcn_dec_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
416 			      struct dma_fence **fence)
417 {
418 	struct amdgpu_device *adev = ring->adev;
419 	struct amdgpu_bo *bo = NULL;
420 	uint32_t *msg;
421 	int r, i;
422 
423 	r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
424 				      AMDGPU_GEM_DOMAIN_VRAM,
425 				      &bo, NULL, (void **)&msg);
426 	if (r)
427 		return r;
428 
429 	msg[0] = cpu_to_le32(0x00000028);
430 	msg[1] = cpu_to_le32(0x00000038);
431 	msg[2] = cpu_to_le32(0x00000001);
432 	msg[3] = cpu_to_le32(0x00000000);
433 	msg[4] = cpu_to_le32(handle);
434 	msg[5] = cpu_to_le32(0x00000000);
435 	msg[6] = cpu_to_le32(0x00000001);
436 	msg[7] = cpu_to_le32(0x00000028);
437 	msg[8] = cpu_to_le32(0x00000010);
438 	msg[9] = cpu_to_le32(0x00000000);
439 	msg[10] = cpu_to_le32(0x00000007);
440 	msg[11] = cpu_to_le32(0x00000000);
441 	msg[12] = cpu_to_le32(0x00000780);
442 	msg[13] = cpu_to_le32(0x00000440);
443 	for (i = 14; i < 1024; ++i)
444 		msg[i] = cpu_to_le32(0x0);
445 
446 	return amdgpu_vcn_dec_send_msg(ring, bo, fence);
447 }
448 
449 static int amdgpu_vcn_dec_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
450 			       struct dma_fence **fence)
451 {
452 	struct amdgpu_device *adev = ring->adev;
453 	struct amdgpu_bo *bo = NULL;
454 	uint32_t *msg;
455 	int r, i;
456 
457 	r = amdgpu_bo_create_reserved(adev, 1024, PAGE_SIZE,
458 				      AMDGPU_GEM_DOMAIN_VRAM,
459 				      &bo, NULL, (void **)&msg);
460 	if (r)
461 		return r;
462 
463 	msg[0] = cpu_to_le32(0x00000028);
464 	msg[1] = cpu_to_le32(0x00000018);
465 	msg[2] = cpu_to_le32(0x00000000);
466 	msg[3] = cpu_to_le32(0x00000002);
467 	msg[4] = cpu_to_le32(handle);
468 	msg[5] = cpu_to_le32(0x00000000);
469 	for (i = 6; i < 1024; ++i)
470 		msg[i] = cpu_to_le32(0x0);
471 
472 	return amdgpu_vcn_dec_send_msg(ring, bo, fence);
473 }
474 
475 int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)
476 {
477 	struct dma_fence *fence;
478 	long r;
479 
480 	r = amdgpu_vcn_dec_get_create_msg(ring, 1, NULL);
481 	if (r)
482 		goto error;
483 
484 	r = amdgpu_vcn_dec_get_destroy_msg(ring, 1, &fence);
485 	if (r)
486 		goto error;
487 
488 	r = dma_fence_wait_timeout(fence, false, timeout);
489 	if (r == 0)
490 		r = -ETIMEDOUT;
491 	else if (r > 0)
492 		r = 0;
493 
494 	dma_fence_put(fence);
495 error:
496 	return r;
497 }
498 
499 int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring)
500 {
501 	struct amdgpu_device *adev = ring->adev;
502 	uint32_t rptr;
503 	unsigned i;
504 	int r;
505 
506 	r = amdgpu_ring_alloc(ring, 16);
507 	if (r)
508 		return r;
509 
510 	rptr = amdgpu_ring_get_rptr(ring);
511 
512 	amdgpu_ring_write(ring, VCN_ENC_CMD_END);
513 	amdgpu_ring_commit(ring);
514 
515 	for (i = 0; i < adev->usec_timeout; i++) {
516 		if (amdgpu_ring_get_rptr(ring) != rptr)
517 			break;
518 		udelay(1);
519 	}
520 
521 	if (i >= adev->usec_timeout)
522 		r = -ETIMEDOUT;
523 
524 	return r;
525 }
526 
527 static int amdgpu_vcn_enc_get_create_msg(struct amdgpu_ring *ring, uint32_t handle,
528 			      struct dma_fence **fence)
529 {
530 	const unsigned ib_size_dw = 16;
531 	struct amdgpu_job *job;
532 	struct amdgpu_ib *ib;
533 	struct dma_fence *f = NULL;
534 	uint64_t dummy;
535 	int i, r;
536 
537 	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
538 	if (r)
539 		return r;
540 
541 	ib = &job->ibs[0];
542 	dummy = ib->gpu_addr + 1024;
543 
544 	ib->length_dw = 0;
545 	ib->ptr[ib->length_dw++] = 0x00000018;
546 	ib->ptr[ib->length_dw++] = 0x00000001; /* session info */
547 	ib->ptr[ib->length_dw++] = handle;
548 	ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
549 	ib->ptr[ib->length_dw++] = dummy;
550 	ib->ptr[ib->length_dw++] = 0x0000000b;
551 
552 	ib->ptr[ib->length_dw++] = 0x00000014;
553 	ib->ptr[ib->length_dw++] = 0x00000002; /* task info */
554 	ib->ptr[ib->length_dw++] = 0x0000001c;
555 	ib->ptr[ib->length_dw++] = 0x00000000;
556 	ib->ptr[ib->length_dw++] = 0x00000000;
557 
558 	ib->ptr[ib->length_dw++] = 0x00000008;
559 	ib->ptr[ib->length_dw++] = 0x08000001; /* op initialize */
560 
561 	for (i = ib->length_dw; i < ib_size_dw; ++i)
562 		ib->ptr[i] = 0x0;
563 
564 	r = amdgpu_job_submit_direct(job, ring, &f);
565 	if (r)
566 		goto err;
567 
568 	if (fence)
569 		*fence = dma_fence_get(f);
570 	dma_fence_put(f);
571 
572 	return 0;
573 
574 err:
575 	amdgpu_job_free(job);
576 	return r;
577 }
578 
579 static int amdgpu_vcn_enc_get_destroy_msg(struct amdgpu_ring *ring, uint32_t handle,
580 				struct dma_fence **fence)
581 {
582 	const unsigned ib_size_dw = 16;
583 	struct amdgpu_job *job;
584 	struct amdgpu_ib *ib;
585 	struct dma_fence *f = NULL;
586 	uint64_t dummy;
587 	int i, r;
588 
589 	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
590 	if (r)
591 		return r;
592 
593 	ib = &job->ibs[0];
594 	dummy = ib->gpu_addr + 1024;
595 
596 	ib->length_dw = 0;
597 	ib->ptr[ib->length_dw++] = 0x00000018;
598 	ib->ptr[ib->length_dw++] = 0x00000001;
599 	ib->ptr[ib->length_dw++] = handle;
600 	ib->ptr[ib->length_dw++] = upper_32_bits(dummy);
601 	ib->ptr[ib->length_dw++] = dummy;
602 	ib->ptr[ib->length_dw++] = 0x0000000b;
603 
604 	ib->ptr[ib->length_dw++] = 0x00000014;
605 	ib->ptr[ib->length_dw++] = 0x00000002;
606 	ib->ptr[ib->length_dw++] = 0x0000001c;
607 	ib->ptr[ib->length_dw++] = 0x00000000;
608 	ib->ptr[ib->length_dw++] = 0x00000000;
609 
610 	ib->ptr[ib->length_dw++] = 0x00000008;
611 	ib->ptr[ib->length_dw++] = 0x08000002; /* op close session */
612 
613 	for (i = ib->length_dw; i < ib_size_dw; ++i)
614 		ib->ptr[i] = 0x0;
615 
616 	r = amdgpu_job_submit_direct(job, ring, &f);
617 	if (r)
618 		goto err;
619 
620 	if (fence)
621 		*fence = dma_fence_get(f);
622 	dma_fence_put(f);
623 
624 	return 0;
625 
626 err:
627 	amdgpu_job_free(job);
628 	return r;
629 }
630 
631 int amdgpu_vcn_enc_ring_test_ib(struct amdgpu_ring *ring, long timeout)
632 {
633 	struct dma_fence *fence = NULL;
634 	long r;
635 
636 	r = amdgpu_vcn_enc_get_create_msg(ring, 1, NULL);
637 	if (r)
638 		goto error;
639 
640 	r = amdgpu_vcn_enc_get_destroy_msg(ring, 1, &fence);
641 	if (r)
642 		goto error;
643 
644 	r = dma_fence_wait_timeout(fence, false, timeout);
645 	if (r == 0)
646 		r = -ETIMEDOUT;
647 	else if (r > 0)
648 		r = 0;
649 
650 error:
651 	dma_fence_put(fence);
652 	return r;
653 }
654 
655 int amdgpu_vcn_jpeg_ring_test_ring(struct amdgpu_ring *ring)
656 {
657 	struct amdgpu_device *adev = ring->adev;
658 	uint32_t tmp = 0;
659 	unsigned i;
660 	int r;
661 
662 	WREG32(adev->vcn.external.jpeg_pitch, 0xCAFEDEAD);
663 	r = amdgpu_ring_alloc(ring, 3);
664 	if (r)
665 		return r;
666 
667 	amdgpu_ring_write(ring, PACKET0(adev->vcn.internal.jpeg_pitch, 0));
668 	amdgpu_ring_write(ring, 0xDEADBEEF);
669 	amdgpu_ring_commit(ring);
670 
671 	for (i = 0; i < adev->usec_timeout; i++) {
672 		tmp = RREG32(adev->vcn.external.jpeg_pitch);
673 		if (tmp == 0xDEADBEEF)
674 			break;
675 		udelay(1);
676 	}
677 
678 	if (i >= adev->usec_timeout)
679 		r = -ETIMEDOUT;
680 
681 	return r;
682 }
683 
684 static int amdgpu_vcn_jpeg_set_reg(struct amdgpu_ring *ring, uint32_t handle,
685 		struct dma_fence **fence)
686 {
687 	struct amdgpu_device *adev = ring->adev;
688 	struct amdgpu_job *job;
689 	struct amdgpu_ib *ib;
690 	struct dma_fence *f = NULL;
691 	const unsigned ib_size_dw = 16;
692 	int i, r;
693 
694 	r = amdgpu_job_alloc_with_ib(ring->adev, ib_size_dw * 4, &job);
695 	if (r)
696 		return r;
697 
698 	ib = &job->ibs[0];
699 
700 	ib->ptr[0] = PACKETJ(adev->vcn.internal.jpeg_pitch, 0, 0, PACKETJ_TYPE0);
701 	ib->ptr[1] = 0xDEADBEEF;
702 	for (i = 2; i < 16; i += 2) {
703 		ib->ptr[i] = PACKETJ(0, 0, 0, PACKETJ_TYPE6);
704 		ib->ptr[i+1] = 0;
705 	}
706 	ib->length_dw = 16;
707 
708 	r = amdgpu_job_submit_direct(job, ring, &f);
709 	if (r)
710 		goto err;
711 
712 	if (fence)
713 		*fence = dma_fence_get(f);
714 	dma_fence_put(f);
715 
716 	return 0;
717 
718 err:
719 	amdgpu_job_free(job);
720 	return r;
721 }
722 
723 int amdgpu_vcn_jpeg_ring_test_ib(struct amdgpu_ring *ring, long timeout)
724 {
725 	struct amdgpu_device *adev = ring->adev;
726 	uint32_t tmp = 0;
727 	unsigned i;
728 	struct dma_fence *fence = NULL;
729 	long r = 0;
730 
731 	r = amdgpu_vcn_jpeg_set_reg(ring, 1, &fence);
732 	if (r)
733 		goto error;
734 
735 	r = dma_fence_wait_timeout(fence, false, timeout);
736 	if (r == 0) {
737 		r = -ETIMEDOUT;
738 		goto error;
739 	} else if (r < 0) {
740 		goto error;
741 	} else {
742 		r = 0;
743 	}
744 
745 	for (i = 0; i < adev->usec_timeout; i++) {
746 		tmp = RREG32(adev->vcn.external.jpeg_pitch);
747 		if (tmp == 0xDEADBEEF)
748 			break;
749 		udelay(1);
750 	}
751 
752 	if (i >= adev->usec_timeout)
753 		r = -ETIMEDOUT;
754 
755 	dma_fence_put(fence);
756 error:
757 	return r;
758 }
759