xref: /linux/drivers/gpu/drm/amd/amdgpu/vce_v1_0.c (revision d4a640d4b9f34aa9472c71986ef4b5a42dbe4f0f)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright 2013 Advanced Micro Devices, Inc.
4  * Copyright 2025 Valve Corporation
5  * Copyright 2025 Alexandre Demers
6  * All Rights Reserved.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the
10  * "Software"), to deal in the Software without restriction, including
11  * without limitation the rights to use, copy, modify, merge, publish,
12  * distribute, sub license, and/or sell copies of the Software, and to
13  * permit persons to whom the Software is furnished to do so, subject to
14  * the following conditions:
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22  * USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * The above copyright notice and this permission notice (including the
25  * next paragraph) shall be included in all copies or substantial portions
26  * of the Software.
27  *
28  * Authors: Christian König <christian.koenig@amd.com>
29  *          Timur Kristóf <timur.kristof@gmail.com>
30  *          Alexandre Demers <alexandre.f.demers@gmail.com>
31  */
32 
33 #include <linux/firmware.h>
34 
35 #include "amdgpu.h"
36 #include "amdgpu_vce.h"
37 #include "sid.h"
38 #include "vce_v1_0.h"
39 #include "vce/vce_1_0_d.h"
40 #include "vce/vce_1_0_sh_mask.h"
41 #include "oss/oss_1_0_d.h"
42 #include "oss/oss_1_0_sh_mask.h"
43 
44 #define VCE_V1_0_FW_SIZE	(256 * 1024)
45 #define VCE_V1_0_STACK_SIZE	(64 * 1024)
46 #define VCE_V1_0_DATA_SIZE	(7808 * (AMDGPU_MAX_VCE_HANDLES + 1))
47 #define VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK	0x02
48 
49 static void vce_v1_0_set_ring_funcs(struct amdgpu_device *adev);
50 static void vce_v1_0_set_irq_funcs(struct amdgpu_device *adev);
51 
52 struct vce_v1_0_fw_signature {
53 	int32_t offset;
54 	uint32_t length;
55 	int32_t number;
56 	struct {
57 		uint32_t chip_id;
58 		uint32_t keyselect;
59 		uint32_t nonce[4];
60 		uint32_t sigval[4];
61 	} val[8];
62 };
63 
64 /**
65  * vce_v1_0_ring_get_rptr - get read pointer
66  *
67  * @ring: amdgpu_ring pointer
68  *
69  * Returns the current hardware read pointer
70  */
71 static uint64_t vce_v1_0_ring_get_rptr(struct amdgpu_ring *ring)
72 {
73 	struct amdgpu_device *adev = ring->adev;
74 
75 	if (ring->me == 0)
76 		return RREG32(mmVCE_RB_RPTR);
77 	else
78 		return RREG32(mmVCE_RB_RPTR2);
79 }
80 
81 /**
82  * vce_v1_0_ring_get_wptr - get write pointer
83  *
84  * @ring: amdgpu_ring pointer
85  *
86  * Returns the current hardware write pointer
87  */
88 static uint64_t vce_v1_0_ring_get_wptr(struct amdgpu_ring *ring)
89 {
90 	struct amdgpu_device *adev = ring->adev;
91 
92 	if (ring->me == 0)
93 		return RREG32(mmVCE_RB_WPTR);
94 	else
95 		return RREG32(mmVCE_RB_WPTR2);
96 }
97 
98 /**
99  * vce_v1_0_ring_set_wptr - set write pointer
100  *
101  * @ring: amdgpu_ring pointer
102  *
103  * Commits the write pointer to the hardware
104  */
105 static void vce_v1_0_ring_set_wptr(struct amdgpu_ring *ring)
106 {
107 	struct amdgpu_device *adev = ring->adev;
108 
109 	if (ring->me == 0)
110 		WREG32(mmVCE_RB_WPTR, lower_32_bits(ring->wptr));
111 	else
112 		WREG32(mmVCE_RB_WPTR2, lower_32_bits(ring->wptr));
113 }
114 
115 static int vce_v1_0_lmi_clean(struct amdgpu_device *adev)
116 {
117 	int i, j;
118 
119 	for (i = 0; i < 10; ++i) {
120 		for (j = 0; j < 100; ++j) {
121 			if (RREG32(mmVCE_LMI_STATUS) & 0x337f)
122 				return 0;
123 
124 			mdelay(10);
125 		}
126 	}
127 
128 	return -ETIMEDOUT;
129 }
130 
131 static int vce_v1_0_firmware_loaded(struct amdgpu_device *adev)
132 {
133 	int i, j;
134 
135 	for (i = 0; i < 10; ++i) {
136 		for (j = 0; j < 100; ++j) {
137 			if (RREG32(mmVCE_STATUS) & VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK)
138 				return 0;
139 			mdelay(10);
140 		}
141 
142 		dev_err(adev->dev, "VCE not responding, trying to reset the ECPU\n");
143 
144 		WREG32_P(mmVCE_SOFT_RESET,
145 			VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
146 			~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
147 		mdelay(10);
148 		WREG32_P(mmVCE_SOFT_RESET, 0,
149 			~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
150 		mdelay(10);
151 	}
152 
153 	return -ETIMEDOUT;
154 }
155 
156 static void vce_v1_0_init_cg(struct amdgpu_device *adev)
157 {
158 	u32 tmp;
159 
160 	tmp = RREG32(mmVCE_CLOCK_GATING_A);
161 	tmp |= VCE_CLOCK_GATING_A__CGC_DYN_CLOCK_MODE_MASK;
162 	WREG32(mmVCE_CLOCK_GATING_A, tmp);
163 
164 	tmp = RREG32(mmVCE_CLOCK_GATING_B);
165 	tmp |= 0x1e;
166 	tmp &= ~0xe100e1;
167 	WREG32(mmVCE_CLOCK_GATING_B, tmp);
168 
169 	tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
170 	tmp &= ~0xff9ff000;
171 	WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
172 
173 	tmp = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
174 	tmp &= ~0x3ff;
175 	WREG32(mmVCE_UENC_REG_CLOCK_GATING, tmp);
176 }
177 
178 /**
179  * vce_v1_0_load_fw_signature - load firmware signature into VCPU BO
180  *
181  * @adev: amdgpu_device pointer
182  *
183  * The VCE1 firmware validation mechanism needs a firmware signature.
184  * This function finds the signature appropriate for the current
185  * ASIC and writes that into the VCPU BO.
186  */
187 static int vce_v1_0_load_fw_signature(struct amdgpu_device *adev)
188 {
189 	const struct common_firmware_header *hdr;
190 	struct vce_v1_0_fw_signature *sign;
191 	unsigned int ucode_offset;
192 	uint32_t chip_id;
193 	u32 *cpu_addr;
194 	int i;
195 
196 	hdr = (const struct common_firmware_header *)adev->vce.fw->data;
197 	ucode_offset = le32_to_cpu(hdr->ucode_array_offset_bytes);
198 	cpu_addr = adev->vce.cpu_addr;
199 
200 	sign = (void *)adev->vce.fw->data + ucode_offset;
201 
202 	switch (adev->asic_type) {
203 	case CHIP_TAHITI:
204 		chip_id = 0x01000014;
205 		break;
206 	case CHIP_VERDE:
207 		chip_id = 0x01000015;
208 		break;
209 	case CHIP_PITCAIRN:
210 		chip_id = 0x01000016;
211 		break;
212 	default:
213 		dev_err(adev->dev, "asic_type %#010x was not found!", adev->asic_type);
214 		return -EINVAL;
215 	}
216 
217 	for (i = 0; i < le32_to_cpu(sign->number); ++i) {
218 		if (le32_to_cpu(sign->val[i].chip_id) == chip_id)
219 			break;
220 	}
221 
222 	if (i == le32_to_cpu(sign->number)) {
223 		dev_err(adev->dev, "chip_id 0x%x for %s was not found in VCE firmware",
224 			chip_id, amdgpu_asic_name[adev->asic_type]);
225 		return -EINVAL;
226 	}
227 
228 	cpu_addr += (256 - 64) / 4;
229 	memcpy_toio(&cpu_addr[0], &sign->val[i].nonce[0], 16);
230 	cpu_addr[4] = cpu_to_le32(le32_to_cpu(sign->length) + 64);
231 
232 	memset_io(&cpu_addr[5], 0, 44);
233 	memcpy_toio(&cpu_addr[16], &sign[1], hdr->ucode_size_bytes - sizeof(*sign));
234 
235 	cpu_addr += (le32_to_cpu(sign->length) + 64) / 4;
236 	memcpy_toio(&cpu_addr[0], &sign->val[i].sigval[0], 16);
237 
238 	adev->vce.keyselect = le32_to_cpu(sign->val[i].keyselect);
239 
240 	return 0;
241 }
242 
243 static int vce_v1_0_wait_for_fw_validation(struct amdgpu_device *adev)
244 {
245 	int i;
246 
247 	dev_dbg(adev->dev, "VCE keyselect: %d", adev->vce.keyselect);
248 	WREG32(mmVCE_LMI_FW_START_KEYSEL, adev->vce.keyselect);
249 
250 	for (i = 0; i < 10; ++i) {
251 		mdelay(10);
252 		if (RREG32(mmVCE_FW_REG_STATUS) & VCE_FW_REG_STATUS__DONE_MASK)
253 			break;
254 	}
255 
256 	if (!(RREG32(mmVCE_FW_REG_STATUS) & VCE_FW_REG_STATUS__DONE_MASK)) {
257 		dev_err(adev->dev, "VCE FW validation timeout\n");
258 		return -ETIMEDOUT;
259 	}
260 
261 	if (!(RREG32(mmVCE_FW_REG_STATUS) & VCE_FW_REG_STATUS__PASS_MASK)) {
262 		dev_err(adev->dev, "VCE FW validation failed\n");
263 		return -EINVAL;
264 	}
265 
266 	for (i = 0; i < 10; ++i) {
267 		mdelay(10);
268 		if (!(RREG32(mmVCE_FW_REG_STATUS) & VCE_FW_REG_STATUS__BUSY_MASK))
269 			break;
270 	}
271 
272 	if (RREG32(mmVCE_FW_REG_STATUS) & VCE_FW_REG_STATUS__BUSY_MASK) {
273 		dev_err(adev->dev, "VCE FW busy timeout\n");
274 		return -ETIMEDOUT;
275 	}
276 
277 	return 0;
278 }
279 
280 static int vce_v1_0_mc_resume(struct amdgpu_device *adev)
281 {
282 	uint32_t offset;
283 	uint32_t size;
284 
285 	/*
286 	 * When the keyselect is already set, don't perturb VCE FW.
287 	 * Validation seems to always fail the second time.
288 	 */
289 	if (RREG32(mmVCE_LMI_FW_START_KEYSEL)) {
290 		dev_dbg(adev->dev, "keyselect already set: 0x%x (on CPU: 0x%x)\n",
291 			RREG32(mmVCE_LMI_FW_START_KEYSEL), adev->vce.keyselect);
292 
293 		WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100);
294 		return 0;
295 	}
296 
297 	WREG32_P(mmVCE_CLOCK_GATING_A, 0, ~(1 << 16));
298 	WREG32_P(mmVCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000);
299 	WREG32_P(mmVCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F);
300 	WREG32(mmVCE_CLOCK_GATING_B, 0);
301 
302 	WREG32_P(mmVCE_LMI_FW_PERIODIC_CTRL, 0x4, ~0x4);
303 
304 	WREG32(mmVCE_LMI_CTRL, 0x00398000);
305 
306 	WREG32_P(mmVCE_LMI_CACHE_CTRL, 0x0, ~0x1);
307 	WREG32(mmVCE_LMI_SWAP_CNTL, 0);
308 	WREG32(mmVCE_LMI_SWAP_CNTL1, 0);
309 	WREG32(mmVCE_LMI_VM_CTRL, 0);
310 
311 	WREG32(mmVCE_VCPU_SCRATCH7, AMDGPU_MAX_VCE_HANDLES);
312 
313 	offset =  adev->vce.gpu_addr + AMDGPU_VCE_FIRMWARE_OFFSET;
314 	size = VCE_V1_0_FW_SIZE;
315 	WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff);
316 	WREG32(mmVCE_VCPU_CACHE_SIZE0, size);
317 
318 	offset += size;
319 	size = VCE_V1_0_STACK_SIZE;
320 	WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0x7fffffff);
321 	WREG32(mmVCE_VCPU_CACHE_SIZE1, size);
322 
323 	offset += size;
324 	size = VCE_V1_0_DATA_SIZE;
325 	WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0x7fffffff);
326 	WREG32(mmVCE_VCPU_CACHE_SIZE2, size);
327 
328 	WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100);
329 
330 	return vce_v1_0_wait_for_fw_validation(adev);
331 }
332 
333 /**
334  * vce_v1_0_is_idle() - Check idle status of VCE1 IP block
335  *
336  * @ip_block: amdgpu_ip_block pointer
337  *
338  * Check whether VCE is busy according to VCE_STATUS.
339  * Also check whether the SRBM thinks VCE is busy, although
340  * SRBM_STATUS.VCE_BUSY seems to be bogus because it
341  * appears to mirror the VCE_STATUS.VCPU_REPORT_FW_LOADED bit.
342  */
343 static bool vce_v1_0_is_idle(struct amdgpu_ip_block *ip_block)
344 {
345 	struct amdgpu_device *adev = ip_block->adev;
346 	bool busy =
347 		(RREG32(mmVCE_STATUS) & (VCE_STATUS__JOB_BUSY_MASK | VCE_STATUS__UENC_BUSY_MASK)) ||
348 		(RREG32(mmSRBM_STATUS2) & SRBM_STATUS2__VCE_BUSY_MASK);
349 
350 	return !busy;
351 }
352 
353 static int vce_v1_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
354 {
355 	struct amdgpu_device *adev = ip_block->adev;
356 	unsigned int i;
357 
358 	for (i = 0; i < adev->usec_timeout; i++) {
359 		udelay(1);
360 		if (vce_v1_0_is_idle(ip_block))
361 			return 0;
362 	}
363 	return -ETIMEDOUT;
364 }
365 
366 /**
367  * vce_v1_0_start - start VCE block
368  *
369  * @adev: amdgpu_device pointer
370  *
371  * Setup and start the VCE block
372  */
373 static int vce_v1_0_start(struct amdgpu_device *adev)
374 {
375 	struct amdgpu_ring *ring;
376 	int r;
377 
378 	WREG32_P(mmVCE_STATUS, 1, ~1);
379 
380 	r = vce_v1_0_mc_resume(adev);
381 	if (r)
382 		return r;
383 
384 	ring = &adev->vce.ring[0];
385 	WREG32(mmVCE_RB_RPTR, lower_32_bits(ring->wptr));
386 	WREG32(mmVCE_RB_WPTR, lower_32_bits(ring->wptr));
387 	WREG32(mmVCE_RB_BASE_LO, lower_32_bits(ring->gpu_addr));
388 	WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
389 	WREG32(mmVCE_RB_SIZE, ring->ring_size / 4);
390 
391 	ring = &adev->vce.ring[1];
392 	WREG32(mmVCE_RB_RPTR2, lower_32_bits(ring->wptr));
393 	WREG32(mmVCE_RB_WPTR2, lower_32_bits(ring->wptr));
394 	WREG32(mmVCE_RB_BASE_LO2, lower_32_bits(ring->gpu_addr));
395 	WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
396 	WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4);
397 
398 	WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK,
399 		 ~VCE_VCPU_CNTL__CLK_EN_MASK);
400 
401 	WREG32_P(mmVCE_SOFT_RESET,
402 		VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK |
403 		VCE_SOFT_RESET__FME_SOFT_RESET_MASK,
404 		~(VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK |
405 		  VCE_SOFT_RESET__FME_SOFT_RESET_MASK));
406 
407 	mdelay(100);
408 
409 	WREG32_P(mmVCE_SOFT_RESET, 0,
410 		~(VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK |
411 		  VCE_SOFT_RESET__FME_SOFT_RESET_MASK));
412 
413 	r = vce_v1_0_firmware_loaded(adev);
414 
415 	/* Clear VCE_STATUS, otherwise SRBM thinks VCE1 is busy. */
416 	WREG32(mmVCE_STATUS, 0);
417 
418 	if (r) {
419 		dev_err(adev->dev, "VCE not responding, giving up\n");
420 		return r;
421 	}
422 
423 	return 0;
424 }
425 
426 static int vce_v1_0_stop(struct amdgpu_device *adev)
427 {
428 	struct amdgpu_ip_block *ip_block;
429 	int status;
430 	int i;
431 
432 	ip_block = amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_VCE);
433 	if (!ip_block)
434 		return -EINVAL;
435 
436 	if (vce_v1_0_lmi_clean(adev))
437 		dev_warn(adev->dev, "VCE not idle\n");
438 
439 	if (vce_v1_0_wait_for_idle(ip_block))
440 		dev_warn(adev->dev, "VCE busy: VCE_STATUS=0x%x, SRBM_STATUS2=0x%x\n",
441 			RREG32(mmVCE_STATUS), RREG32(mmSRBM_STATUS2));
442 
443 	/* Stall UMC and register bus before resetting VCPU */
444 	WREG32_P(mmVCE_LMI_CTRL2, 1 << 8, ~(1 << 8));
445 
446 	for (i = 0; i < 100; ++i) {
447 		status = RREG32(mmVCE_LMI_STATUS);
448 		if (status & 0x240)
449 			break;
450 		mdelay(1);
451 	}
452 
453 	WREG32_P(mmVCE_VCPU_CNTL, 0, ~VCE_VCPU_CNTL__CLK_EN_MASK);
454 
455 	WREG32_P(mmVCE_SOFT_RESET,
456 		VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK |
457 		VCE_SOFT_RESET__FME_SOFT_RESET_MASK,
458 		~(VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK |
459 		  VCE_SOFT_RESET__FME_SOFT_RESET_MASK));
460 
461 	WREG32(mmVCE_STATUS, 0);
462 
463 	return 0;
464 }
465 
466 static void vce_v1_0_enable_mgcg(struct amdgpu_device *adev, bool enable)
467 {
468 	u32 tmp;
469 
470 	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG)) {
471 		tmp = RREG32(mmVCE_CLOCK_GATING_A);
472 		tmp |= VCE_CLOCK_GATING_A__CGC_DYN_CLOCK_MODE_MASK;
473 		WREG32(mmVCE_CLOCK_GATING_A, tmp);
474 
475 		tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
476 		tmp &= ~0x1ff000;
477 		tmp |= 0xff800000;
478 		WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
479 
480 		tmp = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
481 		tmp &= ~0x3ff;
482 		WREG32(mmVCE_UENC_REG_CLOCK_GATING, tmp);
483 	} else {
484 		tmp = RREG32(mmVCE_CLOCK_GATING_A);
485 		tmp &= ~VCE_CLOCK_GATING_A__CGC_DYN_CLOCK_MODE_MASK;
486 		WREG32(mmVCE_CLOCK_GATING_A, tmp);
487 
488 		tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
489 		tmp |= 0x1ff000;
490 		tmp &= ~0xff800000;
491 		WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
492 
493 		tmp = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
494 		tmp |= 0x3ff;
495 		WREG32(mmVCE_UENC_REG_CLOCK_GATING, tmp);
496 	}
497 }
498 
499 static int vce_v1_0_early_init(struct amdgpu_ip_block *ip_block)
500 {
501 	struct amdgpu_device *adev = ip_block->adev;
502 	int r;
503 
504 	r = amdgpu_vce_early_init(adev);
505 	if (r)
506 		return r;
507 
508 	adev->vce.num_rings = 2;
509 
510 	vce_v1_0_set_ring_funcs(adev);
511 	vce_v1_0_set_irq_funcs(adev);
512 
513 	return 0;
514 }
515 
516 static int vce_v1_0_sw_init(struct amdgpu_ip_block *ip_block)
517 {
518 	struct amdgpu_device *adev = ip_block->adev;
519 	struct amdgpu_ring *ring;
520 	int r, i;
521 
522 	r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 167, &adev->vce.irq);
523 	if (r)
524 		return r;
525 
526 	r = amdgpu_vce_sw_init(adev, VCE_V1_0_FW_SIZE +
527 		VCE_V1_0_STACK_SIZE + VCE_V1_0_DATA_SIZE);
528 	if (r)
529 		return r;
530 
531 	r = amdgpu_vce_resume(adev);
532 	if (r)
533 		return r;
534 	r = vce_v1_0_load_fw_signature(adev);
535 	if (r)
536 		return r;
537 
538 	for (i = 0; i < adev->vce.num_rings; i++) {
539 		enum amdgpu_ring_priority_level hw_prio = amdgpu_vce_get_ring_prio(i);
540 
541 		ring = &adev->vce.ring[i];
542 		sprintf(ring->name, "vce%d", i);
543 		r = amdgpu_ring_init(adev, ring, 512, &adev->vce.irq, 0,
544 				     hw_prio, NULL);
545 		if (r)
546 			return r;
547 	}
548 
549 	return r;
550 }
551 
552 static int vce_v1_0_sw_fini(struct amdgpu_ip_block *ip_block)
553 {
554 	struct amdgpu_device *adev = ip_block->adev;
555 	int r;
556 
557 	r = amdgpu_vce_suspend(adev);
558 	if (r)
559 		return r;
560 
561 	return amdgpu_vce_sw_fini(adev);
562 }
563 
564 /**
565  * vce_v1_0_hw_init - start and test VCE block
566  *
567  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
568  *
569  * Initialize the hardware, boot up the VCPU and do some testing
570  */
571 static int vce_v1_0_hw_init(struct amdgpu_ip_block *ip_block)
572 {
573 	struct amdgpu_device *adev = ip_block->adev;
574 	int i, r;
575 
576 	if (adev->pm.dpm_enabled)
577 		amdgpu_dpm_enable_vce(adev, true);
578 	else
579 		amdgpu_asic_set_vce_clocks(adev, 10000, 10000);
580 
581 	for (i = 0; i < adev->vce.num_rings; i++) {
582 		r = amdgpu_ring_test_helper(&adev->vce.ring[i]);
583 		if (r)
584 			return r;
585 	}
586 
587 	dev_info(adev->dev, "VCE initialized successfully.\n");
588 
589 	return 0;
590 }
591 
592 static int vce_v1_0_hw_fini(struct amdgpu_ip_block *ip_block)
593 {
594 	int r;
595 
596 	r = vce_v1_0_stop(ip_block->adev);
597 	if (r)
598 		return r;
599 
600 	cancel_delayed_work_sync(&ip_block->adev->vce.idle_work);
601 	return 0;
602 }
603 
604 static int vce_v1_0_suspend(struct amdgpu_ip_block *ip_block)
605 {
606 	struct amdgpu_device *adev = ip_block->adev;
607 	int r;
608 
609 	/*
610 	 * Proper cleanups before halting the HW engine:
611 	 *   - cancel the delayed idle work
612 	 *   - enable powergating
613 	 *   - enable clockgating
614 	 *   - disable dpm
615 	 *
616 	 * TODO: to align with the VCN implementation, move the
617 	 * jobs for clockgating/powergating/dpm setting to
618 	 * ->set_powergating_state().
619 	 */
620 	cancel_delayed_work_sync(&adev->vce.idle_work);
621 
622 	if (adev->pm.dpm_enabled) {
623 		amdgpu_dpm_enable_vce(adev, false);
624 	} else {
625 		amdgpu_asic_set_vce_clocks(adev, 0, 0);
626 		amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
627 						       AMD_PG_STATE_GATE);
628 		amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
629 						       AMD_CG_STATE_GATE);
630 	}
631 
632 	r = vce_v1_0_hw_fini(ip_block);
633 	if (r) {
634 		dev_err(adev->dev, "vce_v1_0_hw_fini() failed with error %i", r);
635 		return r;
636 	}
637 
638 	return amdgpu_vce_suspend(adev);
639 }
640 
641 static int vce_v1_0_resume(struct amdgpu_ip_block *ip_block)
642 {
643 	struct amdgpu_device *adev = ip_block->adev;
644 	int r;
645 
646 	r = amdgpu_vce_resume(adev);
647 	if (r)
648 		return r;
649 	r = vce_v1_0_load_fw_signature(adev);
650 	if (r)
651 		return r;
652 
653 	return vce_v1_0_hw_init(ip_block);
654 }
655 
656 static int vce_v1_0_set_interrupt_state(struct amdgpu_device *adev,
657 					struct amdgpu_irq_src *source,
658 					unsigned int type,
659 					enum amdgpu_interrupt_state state)
660 {
661 	uint32_t val = 0;
662 
663 	if (state == AMDGPU_IRQ_STATE_ENABLE)
664 		val |= VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK;
665 
666 	WREG32_P(mmVCE_SYS_INT_EN, val,
667 		 ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
668 	return 0;
669 }
670 
671 static int vce_v1_0_process_interrupt(struct amdgpu_device *adev,
672 				      struct amdgpu_irq_src *source,
673 				      struct amdgpu_iv_entry *entry)
674 {
675 	dev_dbg(adev->dev, "IH: VCE\n");
676 	switch (entry->src_data[0]) {
677 	case 0:
678 	case 1:
679 		amdgpu_fence_process(&adev->vce.ring[entry->src_data[0]]);
680 		break;
681 	default:
682 		dev_err(adev->dev, "Unhandled interrupt: %d %d\n",
683 			  entry->src_id, entry->src_data[0]);
684 		break;
685 	}
686 
687 	return 0;
688 }
689 
690 static int vce_v1_0_set_clockgating_state(struct amdgpu_ip_block *ip_block,
691 					  enum amd_clockgating_state state)
692 {
693 	struct amdgpu_device *adev = ip_block->adev;
694 
695 	vce_v1_0_init_cg(adev);
696 	vce_v1_0_enable_mgcg(adev, state == AMD_CG_STATE_GATE);
697 
698 	return 0;
699 }
700 
701 static int vce_v1_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
702 					  enum amd_powergating_state state)
703 {
704 	struct amdgpu_device *adev = ip_block->adev;
705 
706 	/*
707 	 * This doesn't actually powergate the VCE block.
708 	 * That's done in the dpm code via the SMC.  This
709 	 * just re-inits the block as necessary.  The actual
710 	 * gating still happens in the dpm code.  We should
711 	 * revisit this when there is a cleaner line between
712 	 * the smc and the hw blocks
713 	 */
714 	if (state == AMD_PG_STATE_GATE)
715 		return vce_v1_0_stop(adev);
716 	else
717 		return vce_v1_0_start(adev);
718 }
719 
720 static const struct amd_ip_funcs vce_v1_0_ip_funcs = {
721 	.name = "vce_v1_0",
722 	.early_init = vce_v1_0_early_init,
723 	.sw_init = vce_v1_0_sw_init,
724 	.sw_fini = vce_v1_0_sw_fini,
725 	.hw_init = vce_v1_0_hw_init,
726 	.hw_fini = vce_v1_0_hw_fini,
727 	.suspend = vce_v1_0_suspend,
728 	.resume = vce_v1_0_resume,
729 	.is_idle = vce_v1_0_is_idle,
730 	.wait_for_idle = vce_v1_0_wait_for_idle,
731 	.set_clockgating_state = vce_v1_0_set_clockgating_state,
732 	.set_powergating_state = vce_v1_0_set_powergating_state,
733 };
734 
735 static const struct amdgpu_ring_funcs vce_v1_0_ring_funcs = {
736 	.type = AMDGPU_RING_TYPE_VCE,
737 	.align_mask = 0xf,
738 	.nop = VCE_CMD_NO_OP,
739 	.support_64bit_ptrs = false,
740 	.no_user_fence = true,
741 	.get_rptr = vce_v1_0_ring_get_rptr,
742 	.get_wptr = vce_v1_0_ring_get_wptr,
743 	.set_wptr = vce_v1_0_ring_set_wptr,
744 	.parse_cs = amdgpu_vce_ring_parse_cs,
745 	.emit_frame_size = 6, /* amdgpu_vce_ring_emit_fence  x1 no user fence */
746 	.emit_ib_size = 4, /* amdgpu_vce_ring_emit_ib */
747 	.emit_ib = amdgpu_vce_ring_emit_ib,
748 	.emit_fence = amdgpu_vce_ring_emit_fence,
749 	.test_ring = amdgpu_vce_ring_test_ring,
750 	.test_ib = amdgpu_vce_ring_test_ib,
751 	.insert_nop = amdgpu_ring_insert_nop,
752 	.pad_ib = amdgpu_ring_generic_pad_ib,
753 	.begin_use = amdgpu_vce_ring_begin_use,
754 	.end_use = amdgpu_vce_ring_end_use,
755 };
756 
757 static void vce_v1_0_set_ring_funcs(struct amdgpu_device *adev)
758 {
759 	int i;
760 
761 	for (i = 0; i < adev->vce.num_rings; i++) {
762 		adev->vce.ring[i].funcs = &vce_v1_0_ring_funcs;
763 		adev->vce.ring[i].me = i;
764 	}
765 };
766 
767 static const struct amdgpu_irq_src_funcs vce_v1_0_irq_funcs = {
768 	.set = vce_v1_0_set_interrupt_state,
769 	.process = vce_v1_0_process_interrupt,
770 };
771 
772 static void vce_v1_0_set_irq_funcs(struct amdgpu_device *adev)
773 {
774 	adev->vce.irq.num_types = 1;
775 	adev->vce.irq.funcs = &vce_v1_0_irq_funcs;
776 };
777 
778 const struct amdgpu_ip_block_version vce_v1_0_ip_block = {
779 	.type = AMD_IP_BLOCK_TYPE_VCE,
780 	.major = 1,
781 	.minor = 0,
782 	.rev = 0,
783 	.funcs = &vce_v1_0_ip_funcs,
784 };
785