xref: /linux/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c (revision 07fdad3a93756b872da7b53647715c48d0f4a2d0)
1 /*
2  * Copyright 2024 Advanced Micro Devices, Inc. All rights reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  */
23 
24 #include <linux/firmware.h>
25 #include "amdgpu.h"
26 #include "amdgpu_vcn.h"
27 #include "amdgpu_pm.h"
28 #include "soc15.h"
29 #include "soc15d.h"
30 #include "soc15_hw_ip.h"
31 #include "vcn_v2_0.h"
32 #include "vcn_v4_0_3.h"
33 #include "mmsch_v5_0.h"
34 
35 #include "vcn/vcn_5_0_0_offset.h"
36 #include "vcn/vcn_5_0_0_sh_mask.h"
37 #include "ivsrcid/vcn/irqsrcs_vcn_5_0.h"
38 #include "vcn_v5_0_0.h"
39 #include "vcn_v5_0_1.h"
40 
41 #include <drm/drm_drv.h>
42 
43 static const struct amdgpu_hwip_reg_entry vcn_reg_list_5_0_1[] = {
44 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_POWER_STATUS),
45 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_STATUS),
46 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_CONTEXT_ID),
47 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_CONTEXT_ID2),
48 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_DATA0),
49 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_DATA1),
50 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_GPCOM_VCPU_CMD),
51 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI),
52 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO),
53 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI2),
54 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO2),
55 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI3),
56 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO3),
57 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_HI4),
58 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_BASE_LO4),
59 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR),
60 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR),
61 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR2),
62 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR2),
63 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR3),
64 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR3),
65 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_RPTR4),
66 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_WPTR4),
67 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE),
68 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE2),
69 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE3),
70 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_RB_SIZE4),
71 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_CTL),
72 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_DATA),
73 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_LMA_MASK),
74 	SOC15_REG_ENTRY_STR(VCN, 0, regUVD_DPG_PAUSE)
75 };
76 
77 static int vcn_v5_0_1_start_sriov(struct amdgpu_device *adev);
78 static void vcn_v5_0_1_set_unified_ring_funcs(struct amdgpu_device *adev);
79 static void vcn_v5_0_1_set_irq_funcs(struct amdgpu_device *adev);
80 static int vcn_v5_0_1_set_pg_state(struct amdgpu_vcn_inst *vinst,
81 				   enum amd_powergating_state state);
82 static void vcn_v5_0_1_unified_ring_set_wptr(struct amdgpu_ring *ring);
83 static void vcn_v5_0_1_set_ras_funcs(struct amdgpu_device *adev);
84 /**
85  * vcn_v5_0_1_early_init - set function pointers and load microcode
86  *
87  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
88  *
89  * Set ring and irq function pointers
90  * Load microcode from filesystem
91  */
92 static int vcn_v5_0_1_early_init(struct amdgpu_ip_block *ip_block)
93 {
94 	struct amdgpu_device *adev = ip_block->adev;
95 	int i, r;
96 
97 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i)
98 		/* re-use enc ring as unified ring */
99 		adev->vcn.inst[i].num_enc_rings = 1;
100 
101 	vcn_v5_0_1_set_unified_ring_funcs(adev);
102 	vcn_v5_0_1_set_irq_funcs(adev);
103 	vcn_v5_0_1_set_ras_funcs(adev);
104 
105 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
106 		adev->vcn.inst[i].set_pg_state = vcn_v5_0_1_set_pg_state;
107 
108 		r = amdgpu_vcn_early_init(adev, i);
109 		if (r)
110 			return r;
111 	}
112 
113 	return 0;
114 }
115 
116 static int vcn_v5_0_1_late_init(struct amdgpu_ip_block *ip_block)
117 {
118 	struct amdgpu_device *adev = ip_block->adev;
119 
120 	adev->vcn.supported_reset =
121 		amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]);
122 
123 	switch (amdgpu_ip_version(adev, MP0_HWIP, 0)) {
124 	case IP_VERSION(13, 0, 12):
125 		if ((adev->psp.sos.fw_version >= 0x00450025) && amdgpu_dpm_reset_vcn_is_supported(adev))
126 			adev->vcn.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
127 		break;
128 	default:
129 		break;
130 	}
131 
132 	return 0;
133 }
134 
135 static void vcn_v5_0_1_fw_shared_init(struct amdgpu_device *adev, int inst_idx)
136 {
137 	struct amdgpu_vcn5_fw_shared *fw_shared;
138 
139 	fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
140 
141 	if (fw_shared->sq.is_enabled)
142 		return;
143 	fw_shared->present_flag_0 =
144 		cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE);
145 	fw_shared->sq.is_enabled = 1;
146 
147 	if (amdgpu_vcnfw_log)
148 		amdgpu_vcn_fwlog_init(&adev->vcn.inst[inst_idx]);
149 }
150 
151 /**
152  * vcn_v5_0_1_sw_init - sw init for VCN block
153  *
154  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
155  *
156  * Load firmware and sw initialization
157  */
158 static int vcn_v5_0_1_sw_init(struct amdgpu_ip_block *ip_block)
159 {
160 	struct amdgpu_device *adev = ip_block->adev;
161 	struct amdgpu_ring *ring;
162 	int i, r, vcn_inst;
163 
164 	/* VCN UNIFIED TRAP */
165 	r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
166 		VCN_5_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst->irq);
167 	if (r)
168 		return r;
169 
170 	/* VCN POISON TRAP */
171 	r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
172 		VCN_5_0__SRCID_UVD_POISON, &adev->vcn.inst->ras_poison_irq);
173 
174 	for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
175 		vcn_inst = GET_INST(VCN, i);
176 
177 		r = amdgpu_vcn_sw_init(adev, i);
178 		if (r)
179 			return r;
180 
181 		amdgpu_vcn_setup_ucode(adev, i);
182 
183 		r = amdgpu_vcn_resume(adev, i);
184 		if (r)
185 			return r;
186 
187 		ring = &adev->vcn.inst[i].ring_enc[0];
188 		ring->use_doorbell = true;
189 		if (!amdgpu_sriov_vf(adev))
190 			ring->doorbell_index =
191 				(adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
192 				11 * vcn_inst;
193 		else
194 			ring->doorbell_index =
195 				(adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
196 				32 * vcn_inst;
197 
198 		ring->vm_hub = AMDGPU_MMHUB0(adev->vcn.inst[i].aid_id);
199 		sprintf(ring->name, "vcn_unified_%d", adev->vcn.inst[i].aid_id);
200 
201 		r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[i].irq, 0,
202 					AMDGPU_RING_PRIO_DEFAULT, &adev->vcn.inst[i].sched_score);
203 		if (r)
204 			return r;
205 
206 		vcn_v5_0_1_fw_shared_init(adev, i);
207 	}
208 
209 	if (amdgpu_sriov_vf(adev)) {
210 		r = amdgpu_virt_alloc_mm_table(adev);
211 		if (r)
212 			return r;
213 	}
214 
215 	if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN)) {
216 		r = amdgpu_vcn_ras_sw_init(adev);
217 		if (r) {
218 			dev_err(adev->dev, "Failed to initialize vcn ras block!\n");
219 			return r;
220 		}
221 	}
222 
223 	r = amdgpu_vcn_reg_dump_init(adev, vcn_reg_list_5_0_1, ARRAY_SIZE(vcn_reg_list_5_0_1));
224 	if (r)
225 		return r;
226 
227 	return amdgpu_vcn_sysfs_reset_mask_init(adev);
228 }
229 
230 /**
231  * vcn_v5_0_1_sw_fini - sw fini for VCN block
232  *
233  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
234  *
235  * VCN suspend and free up sw allocation
236  */
237 static int vcn_v5_0_1_sw_fini(struct amdgpu_ip_block *ip_block)
238 {
239 	struct amdgpu_device *adev = ip_block->adev;
240 	int i, r, idx;
241 
242 	if (drm_dev_enter(adev_to_drm(adev), &idx)) {
243 		for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
244 			struct amdgpu_vcn5_fw_shared *fw_shared;
245 
246 			fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
247 			fw_shared->present_flag_0 = 0;
248 			fw_shared->sq.is_enabled = 0;
249 		}
250 
251 		drm_dev_exit(idx);
252 	}
253 
254 	if (amdgpu_sriov_vf(adev))
255 		amdgpu_virt_free_mm_table(adev);
256 
257 	for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
258 		r = amdgpu_vcn_suspend(adev, i);
259 		if (r)
260 			return r;
261 	}
262 
263 	amdgpu_vcn_sysfs_reset_mask_fini(adev);
264 
265 	for (i = 0; i < adev->vcn.num_vcn_inst; i++)
266 		amdgpu_vcn_sw_fini(adev, i);
267 
268 	return 0;
269 }
270 
271 static int vcn_v5_0_1_hw_init_inst(struct amdgpu_device *adev, int i)
272 {
273 	struct amdgpu_ring *ring;
274 	int vcn_inst;
275 
276 	vcn_inst = GET_INST(VCN, i);
277 	ring = &adev->vcn.inst[i].ring_enc[0];
278 
279 	if (ring->use_doorbell)
280 		adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
281 			((adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
282 			11 * vcn_inst),
283 			adev->vcn.inst[i].aid_id);
284 
285 	return 0;
286 }
287 
288 /**
289  * vcn_v5_0_1_hw_init - start and test VCN block
290  *
291  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
292  *
293  * Initialize the hardware, boot up the VCPU and do some testing
294  */
295 static int vcn_v5_0_1_hw_init(struct amdgpu_ip_block *ip_block)
296 {
297 	struct amdgpu_device *adev = ip_block->adev;
298 	struct amdgpu_ring *ring;
299 	int i, r;
300 
301 	if (amdgpu_sriov_vf(adev)) {
302 		r = vcn_v5_0_1_start_sriov(adev);
303 		if (r)
304 			return r;
305 
306 		for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
307 			ring = &adev->vcn.inst[i].ring_enc[0];
308 			ring->wptr = 0;
309 			ring->wptr_old = 0;
310 			vcn_v5_0_1_unified_ring_set_wptr(ring);
311 			ring->sched.ready = true;
312 		}
313 	} else {
314 		if (RREG32_SOC15(VCN, GET_INST(VCN, 0), regVCN_RRMT_CNTL) & 0x100)
315 			adev->vcn.caps |= AMDGPU_VCN_CAPS(RRMT_ENABLED);
316 		for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
317 			ring = &adev->vcn.inst[i].ring_enc[0];
318 			vcn_v5_0_1_hw_init_inst(adev, i);
319 
320 			/* Re-init fw_shared, if required */
321 			vcn_v5_0_1_fw_shared_init(adev, i);
322 
323 			r = amdgpu_ring_test_helper(ring);
324 			if (r)
325 				return r;
326 		}
327 	}
328 
329 	return 0;
330 }
331 
332 /**
333  * vcn_v5_0_1_hw_fini - stop the hardware block
334  *
335  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
336  *
337  * Stop the VCN block, mark ring as not ready any more
338  */
339 static int vcn_v5_0_1_hw_fini(struct amdgpu_ip_block *ip_block)
340 {
341 	struct amdgpu_device *adev = ip_block->adev;
342 	int i;
343 
344 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
345 		struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i];
346 
347 		cancel_delayed_work_sync(&adev->vcn.inst[i].idle_work);
348 		if (vinst->cur_state != AMD_PG_STATE_GATE)
349 			vinst->set_pg_state(vinst, AMD_PG_STATE_GATE);
350 	}
351 
352 	if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN) && !amdgpu_sriov_vf(adev))
353 		amdgpu_irq_put(adev, &adev->vcn.inst->ras_poison_irq, 0);
354 
355 	return 0;
356 }
357 
358 /**
359  * vcn_v5_0_1_suspend - suspend VCN block
360  *
361  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
362  *
363  * HW fini and suspend VCN block
364  */
365 static int vcn_v5_0_1_suspend(struct amdgpu_ip_block *ip_block)
366 {
367 	struct amdgpu_device *adev = ip_block->adev;
368 	int r, i;
369 
370 	r = vcn_v5_0_1_hw_fini(ip_block);
371 	if (r)
372 		return r;
373 
374 	for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
375 		r = amdgpu_vcn_suspend(ip_block->adev, i);
376 		if (r)
377 			return r;
378 	}
379 
380 	return r;
381 }
382 
383 /**
384  * vcn_v5_0_1_resume - resume VCN block
385  *
386  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
387  *
388  * Resume firmware and hw init VCN block
389  */
390 static int vcn_v5_0_1_resume(struct amdgpu_ip_block *ip_block)
391 {
392 	struct amdgpu_device *adev = ip_block->adev;
393 	int r, i;
394 
395 	for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
396 		struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i];
397 
398 		if (amdgpu_in_reset(adev))
399 			vinst->cur_state = AMD_PG_STATE_GATE;
400 
401 		r = amdgpu_vcn_resume(ip_block->adev, i);
402 		if (r)
403 			return r;
404 	}
405 
406 	r = vcn_v5_0_1_hw_init(ip_block);
407 
408 	return r;
409 }
410 
411 /**
412  * vcn_v5_0_1_mc_resume - memory controller programming
413  *
414  * @vinst: VCN instance
415  *
416  * Let the VCN memory controller know it's offsets
417  */
418 static void vcn_v5_0_1_mc_resume(struct amdgpu_vcn_inst *vinst)
419 {
420 	struct amdgpu_device *adev = vinst->adev;
421 	int inst = vinst->inst;
422 	uint32_t offset, size, vcn_inst;
423 	const struct common_firmware_header *hdr;
424 
425 	hdr = (const struct common_firmware_header *)adev->vcn.inst[inst].fw->data;
426 	size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
427 
428 	vcn_inst = GET_INST(VCN, inst);
429 	/* cache window 0: fw */
430 	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
431 		WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
432 			(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_lo));
433 		WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
434 			(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_hi));
435 		WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_OFFSET0, 0);
436 		offset = 0;
437 	} else {
438 		WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
439 			lower_32_bits(adev->vcn.inst[inst].gpu_addr));
440 		WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
441 			upper_32_bits(adev->vcn.inst[inst].gpu_addr));
442 		offset = size;
443 		WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_OFFSET0,
444 				AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
445 	}
446 	WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_SIZE0, size);
447 
448 	/* cache window 1: stack */
449 	WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
450 		lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset));
451 	WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
452 		upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset));
453 	WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_OFFSET1, 0);
454 	WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE);
455 
456 	/* cache window 2: context */
457 	WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
458 		lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
459 	WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
460 		upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
461 	WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_OFFSET2, 0);
462 	WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);
463 
464 	/* non-cache window */
465 	WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW,
466 		lower_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr));
467 	WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH,
468 		upper_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr));
469 	WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_NONCACHE_OFFSET0, 0);
470 	WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_NONCACHE_SIZE0,
471 		AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn5_fw_shared)));
472 }
473 
474 /**
475  * vcn_v5_0_1_mc_resume_dpg_mode - memory controller programming for dpg mode
476  *
477  * @vinst: VCN instance
478  * @indirect: indirectly write sram
479  *
480  * Let the VCN memory controller know it's offsets with dpg mode
481  */
482 static void vcn_v5_0_1_mc_resume_dpg_mode(struct amdgpu_vcn_inst *vinst,
483 					  bool indirect)
484 {
485 	struct amdgpu_device *adev = vinst->adev;
486 	int inst_idx = vinst->inst;
487 	uint32_t offset, size;
488 	const struct common_firmware_header *hdr;
489 
490 	hdr = (const struct common_firmware_header *)adev->vcn.inst[inst_idx].fw->data;
491 	size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
492 
493 	/* cache window 0: fw */
494 	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
495 		if (!indirect) {
496 			WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
497 				VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
498 				(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN +
499 				 inst_idx].tmr_mc_addr_lo), 0, indirect);
500 			WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
501 				VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
502 				(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN +
503 				 inst_idx].tmr_mc_addr_hi), 0, indirect);
504 			WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
505 				VCN, 0, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
506 		} else {
507 			WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
508 				VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect);
509 			WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
510 				VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect);
511 			WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
512 				VCN, 0, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
513 		}
514 		offset = 0;
515 	} else {
516 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
517 			VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
518 			lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
519 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
520 			VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
521 			upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
522 		offset = size;
523 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
524 			VCN, 0, regUVD_VCPU_CACHE_OFFSET0),
525 			AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect);
526 	}
527 
528 	if (!indirect)
529 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
530 			VCN, 0, regUVD_VCPU_CACHE_SIZE0), size, 0, indirect);
531 	else
532 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
533 			VCN, 0, regUVD_VCPU_CACHE_SIZE0), 0, 0, indirect);
534 
535 	/* cache window 1: stack */
536 	if (!indirect) {
537 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
538 			VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
539 			lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
540 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
541 			VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
542 			upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
543 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
544 			VCN, 0, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
545 	} else {
546 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
547 			VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect);
548 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
549 			VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect);
550 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
551 			VCN, 0, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
552 	}
553 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
554 			VCN, 0, regUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect);
555 
556 	/* cache window 2: context */
557 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
558 		VCN, 0, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
559 		lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset +
560 			AMDGPU_VCN_STACK_SIZE), 0, indirect);
561 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
562 		VCN, 0, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
563 		upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset +
564 			AMDGPU_VCN_STACK_SIZE), 0, indirect);
565 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
566 		VCN, 0, regUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect);
567 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
568 		VCN, 0, regUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect);
569 
570 	/* non-cache window */
571 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
572 		VCN, 0, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
573 		lower_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
574 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
575 		VCN, 0, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
576 		upper_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
577 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
578 		VCN, 0, regUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
579 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
580 		VCN, 0, regUVD_VCPU_NONCACHE_SIZE0),
581 		AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn5_fw_shared)), 0, indirect);
582 
583 	/* VCN global tiling registers */
584 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
585 		VCN, 0, regUVD_GFX10_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect);
586 }
587 
588 /**
589  * vcn_v5_0_1_disable_clock_gating - disable VCN clock gating
590  *
591  * @vinst: VCN instance
592  *
593  * Disable clock gating for VCN block
594  */
595 static void vcn_v5_0_1_disable_clock_gating(struct amdgpu_vcn_inst *vinst)
596 {
597 }
598 
599 /**
600  * vcn_v5_0_1_enable_clock_gating - enable VCN clock gating
601  *
602  * @vinst: VCN instance
603  *
604  * Enable clock gating for VCN block
605  */
606 static void vcn_v5_0_1_enable_clock_gating(struct amdgpu_vcn_inst *vinst)
607 {
608 }
609 
610 /**
611  * vcn_v5_0_1_pause_dpg_mode - VCN pause with dpg mode
612  *
613  * @vinst: VCN instance
614  * @new_state: pause state
615  *
616  * Pause dpg mode for VCN block
617  */
618 static int vcn_v5_0_1_pause_dpg_mode(struct amdgpu_vcn_inst *vinst,
619 				     struct dpg_pause_state *new_state)
620 {
621 	struct amdgpu_device *adev = vinst->adev;
622 	uint32_t reg_data = 0;
623 	int vcn_inst;
624 
625 	vcn_inst = GET_INST(VCN, vinst->inst);
626 
627 	/* pause/unpause if state is changed */
628 	if (vinst->pause_state.fw_based != new_state->fw_based) {
629 		DRM_DEV_DEBUG(adev->dev, "dpg pause state changed %d -> %d %s\n",
630 			vinst->pause_state.fw_based, new_state->fw_based,
631 			new_state->fw_based ? "VCN_DPG_STATE__PAUSE" : "VCN_DPG_STATE__UNPAUSE");
632 		reg_data = RREG32_SOC15(VCN, vcn_inst, regUVD_DPG_PAUSE) &
633 			(~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
634 
635 		if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {
636 			/* pause DPG */
637 			reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
638 			WREG32_SOC15(VCN, vcn_inst, regUVD_DPG_PAUSE, reg_data);
639 
640 			/* wait for ACK */
641 			SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_DPG_PAUSE,
642 					UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,
643 					UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
644 		} else {
645 			/* unpause DPG, no need to wait */
646 			reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
647 			WREG32_SOC15(VCN, vcn_inst, regUVD_DPG_PAUSE, reg_data);
648 		}
649 		vinst->pause_state.fw_based = new_state->fw_based;
650 	}
651 
652 	return 0;
653 }
654 
655 
656 /**
657  * vcn_v5_0_1_start_dpg_mode - VCN start with dpg mode
658  *
659  * @vinst: VCN instance
660  * @indirect: indirectly write sram
661  *
662  * Start VCN block with dpg mode
663  */
664 static int vcn_v5_0_1_start_dpg_mode(struct amdgpu_vcn_inst *vinst,
665 				     bool indirect)
666 {
667 	struct amdgpu_device *adev = vinst->adev;
668 	int inst_idx = vinst->inst;
669 	struct amdgpu_vcn5_fw_shared *fw_shared =
670 		adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
671 	struct amdgpu_ring *ring;
672 	struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__PAUSE};
673 	int vcn_inst, ret;
674 	uint32_t tmp;
675 
676 	vcn_inst = GET_INST(VCN, inst_idx);
677 
678 	/* disable register anti-hang mechanism */
679 	WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_POWER_STATUS), 1,
680 		~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
681 
682 	/* enable dynamic power gating mode */
683 	tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_POWER_STATUS);
684 	tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK;
685 	WREG32_SOC15(VCN, vcn_inst, regUVD_POWER_STATUS, tmp);
686 
687 	if (indirect) {
688 		adev->vcn.inst[inst_idx].dpg_sram_curr_addr =
689 			(uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr;
690 		/* Use dummy register 0xDEADBEEF passing AID selection to PSP FW */
691 		WREG32_SOC24_DPG_MODE(inst_idx, 0xDEADBEEF,
692 				adev->vcn.inst[inst_idx].aid_id, 0, true);
693 	}
694 
695 	/* enable VCPU clock */
696 	tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
697 	tmp |= UVD_VCPU_CNTL__CLK_EN_MASK | UVD_VCPU_CNTL__BLK_RST_MASK;
698 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
699 		VCN, 0, regUVD_VCPU_CNTL), tmp, 0, indirect);
700 
701 	/* disable master interrupt */
702 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
703 		VCN, 0, regUVD_MASTINT_EN), 0, 0, indirect);
704 
705 	/* setup regUVD_LMI_CTRL */
706 	tmp = (UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
707 		UVD_LMI_CTRL__REQ_MODE_MASK |
708 		UVD_LMI_CTRL__CRC_RESET_MASK |
709 		UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
710 		UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
711 		UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
712 		(8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
713 		0x00100000L);
714 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
715 		VCN, 0, regUVD_LMI_CTRL), tmp, 0, indirect);
716 
717 	vcn_v5_0_1_mc_resume_dpg_mode(vinst, indirect);
718 
719 	tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
720 	tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
721 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
722 		VCN, 0, regUVD_VCPU_CNTL), tmp, 0, indirect);
723 
724 	/* enable LMI MC and UMC channels */
725 	tmp = 0x1f << UVD_LMI_CTRL2__RE_OFLD_MIF_WR_REQ_NUM__SHIFT;
726 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
727 		VCN, 0, regUVD_LMI_CTRL2), tmp, 0, indirect);
728 
729 	/* enable master interrupt */
730 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
731 		VCN, 0, regUVD_MASTINT_EN),
732 		UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect);
733 
734 	if (indirect) {
735 		ret = amdgpu_vcn_psp_update_sram(adev, inst_idx, AMDGPU_UCODE_ID_VCN0_RAM);
736 		if (ret) {
737 			dev_err(adev->dev, "vcn sram load failed %d\n", ret);
738 			return ret;
739 		}
740 	}
741 
742 	/* resetting ring, fw should not check RB ring */
743 	fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET;
744 
745 	/* Pause dpg */
746 	vcn_v5_0_1_pause_dpg_mode(vinst, &state);
747 
748 	ring = &adev->vcn.inst[inst_idx].ring_enc[0];
749 
750 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_LO, lower_32_bits(ring->gpu_addr));
751 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
752 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_SIZE, ring->ring_size / sizeof(uint32_t));
753 
754 	tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE);
755 	tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK);
756 	WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp);
757 
758 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR, 0);
759 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, 0);
760 
761 	tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR);
762 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, tmp);
763 	ring->wptr = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR);
764 
765 	tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE);
766 	tmp |= VCN_RB_ENABLE__RB1_EN_MASK;
767 	WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp);
768 	/* resetting done, fw can check RB ring */
769 	fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF);
770 
771 	WREG32_SOC15(VCN, vcn_inst, regVCN_RB1_DB_CTRL,
772 		ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT |
773 		VCN_RB1_DB_CTRL__EN_MASK);
774 	/* Read DB_CTRL to flush the write DB_CTRL command. */
775 	RREG32_SOC15(VCN, vcn_inst, regVCN_RB1_DB_CTRL);
776 
777 	return 0;
778 }
779 
780 static int vcn_v5_0_1_start_sriov(struct amdgpu_device *adev)
781 {
782 	int i, vcn_inst;
783 	struct amdgpu_ring *ring_enc;
784 	uint64_t cache_addr;
785 	uint64_t rb_enc_addr;
786 	uint64_t ctx_addr;
787 	uint32_t param, resp, expected;
788 	uint32_t offset, cache_size;
789 	uint32_t tmp, timeout;
790 
791 	struct amdgpu_mm_table *table = &adev->virt.mm_table;
792 	uint32_t *table_loc;
793 	uint32_t table_size;
794 	uint32_t size, size_dw;
795 	uint32_t init_status;
796 	uint32_t enabled_vcn;
797 
798 	struct mmsch_v5_0_cmd_direct_write
799 		direct_wt = { {0} };
800 	struct mmsch_v5_0_cmd_direct_read_modify_write
801 		direct_rd_mod_wt = { {0} };
802 	struct mmsch_v5_0_cmd_end end = { {0} };
803 	struct mmsch_v5_0_init_header header;
804 
805 	struct amdgpu_vcn5_fw_shared *fw_shared;
806 	struct amdgpu_fw_shared_rb_setup *rb_setup;
807 
808 	direct_wt.cmd_header.command_type =
809 		MMSCH_COMMAND__DIRECT_REG_WRITE;
810 	direct_rd_mod_wt.cmd_header.command_type =
811 		MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE;
812 	end.cmd_header.command_type = MMSCH_COMMAND__END;
813 
814 	for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
815 		vcn_inst = GET_INST(VCN, i);
816 
817 		vcn_v5_0_1_fw_shared_init(adev, vcn_inst);
818 
819 		memset(&header, 0, sizeof(struct mmsch_v5_0_init_header));
820 		header.version = MMSCH_VERSION;
821 		header.total_size = sizeof(struct mmsch_v5_0_init_header) >> 2;
822 
823 		table_loc = (uint32_t *)table->cpu_addr;
824 		table_loc += header.total_size;
825 
826 		table_size = 0;
827 
828 		MMSCH_V5_0_INSERT_DIRECT_RD_MOD_WT(SOC15_REG_OFFSET(VCN, 0, regUVD_STATUS),
829 			~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY);
830 
831 		cache_size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.inst[i].fw->size + 4);
832 
833 		if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
834 			MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
835 				regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
836 				adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo);
837 
838 			MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
839 				regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
840 				adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi);
841 
842 			offset = 0;
843 			MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
844 				regUVD_VCPU_CACHE_OFFSET0), 0);
845 		} else {
846 			MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
847 				regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
848 				lower_32_bits(adev->vcn.inst[i].gpu_addr));
849 			MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
850 				regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
851 				upper_32_bits(adev->vcn.inst[i].gpu_addr));
852 			offset = cache_size;
853 			MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
854 				regUVD_VCPU_CACHE_OFFSET0),
855 				AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
856 		}
857 
858 		MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
859 			regUVD_VCPU_CACHE_SIZE0),
860 			cache_size);
861 
862 		cache_addr = adev->vcn.inst[vcn_inst].gpu_addr + offset;
863 		MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
864 			regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), lower_32_bits(cache_addr));
865 		MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
866 			regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), upper_32_bits(cache_addr));
867 		MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
868 			regUVD_VCPU_CACHE_OFFSET1), 0);
869 		MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
870 			regUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE);
871 
872 		cache_addr = adev->vcn.inst[vcn_inst].gpu_addr + offset +
873 			AMDGPU_VCN_STACK_SIZE;
874 
875 		MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
876 			regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW), lower_32_bits(cache_addr));
877 
878 		MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
879 			regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH), upper_32_bits(cache_addr));
880 
881 		MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
882 			regUVD_VCPU_CACHE_OFFSET2), 0);
883 
884 		MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
885 			regUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE);
886 
887 		fw_shared = adev->vcn.inst[vcn_inst].fw_shared.cpu_addr;
888 		rb_setup = &fw_shared->rb_setup;
889 
890 		ring_enc = &adev->vcn.inst[vcn_inst].ring_enc[0];
891 		ring_enc->wptr = 0;
892 		rb_enc_addr = ring_enc->gpu_addr;
893 
894 		rb_setup->is_rb_enabled_flags |= RB_ENABLED;
895 		rb_setup->rb_addr_lo = lower_32_bits(rb_enc_addr);
896 		rb_setup->rb_addr_hi = upper_32_bits(rb_enc_addr);
897 		rb_setup->rb_size = ring_enc->ring_size / 4;
898 		fw_shared->present_flag_0 |= cpu_to_le32(AMDGPU_VCN_VF_RB_SETUP_FLAG);
899 
900 		MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
901 			regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
902 			lower_32_bits(adev->vcn.inst[vcn_inst].fw_shared.gpu_addr));
903 		MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
904 			regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
905 			upper_32_bits(adev->vcn.inst[vcn_inst].fw_shared.gpu_addr));
906 		MMSCH_V5_0_INSERT_DIRECT_WT(SOC15_REG_OFFSET(VCN, 0,
907 			regUVD_VCPU_NONCACHE_SIZE0),
908 			AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared)));
909 		MMSCH_V5_0_INSERT_END();
910 
911 		header.vcn0.init_status = 0;
912 		header.vcn0.table_offset = header.total_size;
913 		header.vcn0.table_size = table_size;
914 		header.total_size += table_size;
915 
916 		/* Send init table to mmsch */
917 		size = sizeof(struct mmsch_v5_0_init_header);
918 		table_loc = (uint32_t *)table->cpu_addr;
919 		memcpy((void *)table_loc, &header, size);
920 
921 		ctx_addr = table->gpu_addr;
922 		WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr));
923 		WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr));
924 
925 		tmp = RREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_VMID);
926 		tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK;
927 		tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT);
928 		WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_VMID, tmp);
929 
930 		size = header.total_size;
931 		WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_CTX_SIZE, size);
932 
933 		WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_MAILBOX_RESP, 0);
934 
935 		param = 0x00000001;
936 		WREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_MAILBOX_HOST, param);
937 		tmp = 0;
938 		timeout = 1000;
939 		resp = 0;
940 		expected = MMSCH_VF_MAILBOX_RESP__OK;
941 		while (resp != expected) {
942 			resp = RREG32_SOC15(VCN, vcn_inst, regMMSCH_VF_MAILBOX_RESP);
943 			if (resp != 0)
944 				break;
945 
946 			udelay(10);
947 			tmp = tmp + 10;
948 			if (tmp >= timeout) {
949 				DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\
950 					" waiting for regMMSCH_VF_MAILBOX_RESP "\
951 					"(expected=0x%08x, readback=0x%08x)\n",
952 					tmp, expected, resp);
953 				return -EBUSY;
954 			}
955 		}
956 
957 		enabled_vcn = amdgpu_vcn_is_disabled_vcn(adev, VCN_DECODE_RING, 0) ? 1 : 0;
958 		init_status = ((struct mmsch_v5_0_init_header *)(table_loc))->vcn0.init_status;
959 		if (resp != expected && resp != MMSCH_VF_MAILBOX_RESP__INCOMPLETE
960 					&& init_status != MMSCH_VF_ENGINE_STATUS__PASS) {
961 			DRM_ERROR("MMSCH init status is incorrect! readback=0x%08x, header init "\
962 				"status for VCN%x: 0x%x\n", resp, enabled_vcn, init_status);
963 		}
964 	}
965 
966 	return 0;
967 }
968 
969 /**
970  * vcn_v5_0_1_start - VCN start
971  *
972  * @vinst: VCN instance
973  *
974  * Start VCN block
975  */
976 static int vcn_v5_0_1_start(struct amdgpu_vcn_inst *vinst)
977 {
978 	struct amdgpu_device *adev = vinst->adev;
979 	int i = vinst->inst;
980 	struct amdgpu_vcn5_fw_shared *fw_shared;
981 	struct amdgpu_ring *ring;
982 	uint32_t tmp;
983 	int j, k, r, vcn_inst;
984 
985 	fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
986 
987 	if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
988 		return vcn_v5_0_1_start_dpg_mode(vinst, adev->vcn.inst[i].indirect_sram);
989 
990 	vcn_inst = GET_INST(VCN, i);
991 
992 	/* set VCN status busy */
993 	tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS) | UVD_STATUS__UVD_BUSY;
994 	WREG32_SOC15(VCN, vcn_inst, regUVD_STATUS, tmp);
995 
996 	/* enable VCPU clock */
997 	WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL),
998 		 UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK);
999 
1000 	/* disable master interrupt */
1001 	WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_MASTINT_EN), 0,
1002 		 ~UVD_MASTINT_EN__VCPU_EN_MASK);
1003 
1004 	/* enable LMI MC and UMC channels */
1005 	WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_LMI_CTRL2), 0,
1006 		 ~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
1007 
1008 	tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET);
1009 	tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
1010 	tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
1011 	WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp);
1012 
1013 	/* setup regUVD_LMI_CTRL */
1014 	tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL);
1015 	WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL, tmp |
1016 		     UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
1017 		     UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
1018 		     UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
1019 		     UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
1020 
1021 	vcn_v5_0_1_mc_resume(vinst);
1022 
1023 	/* VCN global tiling registers */
1024 	WREG32_SOC15(VCN, vcn_inst, regUVD_GFX10_ADDR_CONFIG,
1025 		     adev->gfx.config.gb_addr_config);
1026 
1027 	/* unblock VCPU register access */
1028 	WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_RB_ARB_CTRL), 0,
1029 		 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
1030 
1031 	/* release VCPU reset to boot */
1032 	WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 0,
1033 		 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1034 
1035 	for (j = 0; j < 10; ++j) {
1036 		uint32_t status;
1037 
1038 		for (k = 0; k < 100; ++k) {
1039 			status = RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS);
1040 			if (status & 2)
1041 				break;
1042 			mdelay(100);
1043 			if (amdgpu_emu_mode == 1)
1044 				msleep(20);
1045 		}
1046 
1047 		if (amdgpu_emu_mode == 1) {
1048 			r = -1;
1049 			if (status & 2) {
1050 				r = 0;
1051 				break;
1052 			}
1053 		} else {
1054 			r = 0;
1055 			if (status & 2)
1056 				break;
1057 
1058 			dev_err(adev->dev,
1059 				"VCN[%d] is not responding, trying to reset the VCPU!!!\n", i);
1060 			WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL),
1061 				 UVD_VCPU_CNTL__BLK_RST_MASK,
1062 				 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1063 			mdelay(10);
1064 			WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 0,
1065 				 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1066 
1067 			mdelay(10);
1068 			r = -1;
1069 		}
1070 	}
1071 
1072 	if (r) {
1073 		dev_err(adev->dev, "VCN[%d] is not responding, giving up!!!\n", i);
1074 		return r;
1075 	}
1076 
1077 	/* enable master interrupt */
1078 	WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_MASTINT_EN),
1079 		 UVD_MASTINT_EN__VCPU_EN_MASK,
1080 		 ~UVD_MASTINT_EN__VCPU_EN_MASK);
1081 
1082 	/* clear the busy bit of VCN_STATUS */
1083 	WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_STATUS), 0,
1084 		 ~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
1085 
1086 	ring = &adev->vcn.inst[i].ring_enc[0];
1087 
1088 	WREG32_SOC15(VCN, vcn_inst, regVCN_RB1_DB_CTRL,
1089 		     ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT |
1090 		     VCN_RB1_DB_CTRL__EN_MASK);
1091 
1092 	/* Read DB_CTRL to flush the write DB_CTRL command. */
1093 	RREG32_SOC15(VCN, vcn_inst, regVCN_RB1_DB_CTRL);
1094 
1095 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_LO, ring->gpu_addr);
1096 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
1097 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_SIZE, ring->ring_size / 4);
1098 
1099 	tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE);
1100 	tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK);
1101 	WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp);
1102 	fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET;
1103 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR, 0);
1104 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, 0);
1105 
1106 	tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR);
1107 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, tmp);
1108 	ring->wptr = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR);
1109 
1110 	tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE);
1111 	tmp |= VCN_RB_ENABLE__RB1_EN_MASK;
1112 	WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp);
1113 	fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF);
1114 
1115 	/* Keeping one read-back to ensure all register writes are done,
1116 	 * otherwise it may introduce race conditions.
1117 	 */
1118 	RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS);
1119 
1120 	return 0;
1121 }
1122 
1123 /**
1124  * vcn_v5_0_1_stop_dpg_mode - VCN stop with dpg mode
1125  *
1126  * @vinst: VCN instance
1127  *
1128  * Stop VCN block with dpg mode
1129  */
1130 static void vcn_v5_0_1_stop_dpg_mode(struct amdgpu_vcn_inst *vinst)
1131 {
1132 	struct amdgpu_device *adev = vinst->adev;
1133 	int inst_idx = vinst->inst;
1134 	uint32_t tmp;
1135 	int vcn_inst;
1136 	struct dpg_pause_state state = {.fw_based = VCN_DPG_STATE__UNPAUSE};
1137 
1138 	vcn_inst = GET_INST(VCN, inst_idx);
1139 
1140 	/* Unpause dpg */
1141 	vcn_v5_0_1_pause_dpg_mode(vinst, &state);
1142 
1143 	/* Wait for power status to be 1 */
1144 	SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_POWER_STATUS, 1,
1145 		UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1146 
1147 	/* wait for read ptr to be equal to write ptr */
1148 	tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR);
1149 	SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_RB_RPTR, tmp, 0xFFFFFFFF);
1150 
1151 	/* disable dynamic power gating mode */
1152 	WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_POWER_STATUS), 0,
1153 		~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
1154 
1155 	/* Keeping one read-back to ensure all register writes are done,
1156 	 * otherwise it may introduce race conditions.
1157 	 */
1158 	RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS);
1159 }
1160 
1161 /**
1162  * vcn_v5_0_1_stop - VCN stop
1163  *
1164  * @vinst: VCN instance
1165  *
1166  * Stop VCN block
1167  */
1168 static int vcn_v5_0_1_stop(struct amdgpu_vcn_inst *vinst)
1169 {
1170 	struct amdgpu_device *adev = vinst->adev;
1171 	int i = vinst->inst;
1172 	struct amdgpu_vcn5_fw_shared *fw_shared;
1173 	uint32_t tmp;
1174 	int r = 0, vcn_inst;
1175 
1176 	vcn_inst = GET_INST(VCN, i);
1177 
1178 	fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
1179 	fw_shared->sq.queue_mode |= FW_QUEUE_DPG_HOLD_OFF;
1180 
1181 	if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
1182 		vcn_v5_0_1_stop_dpg_mode(vinst);
1183 		return 0;
1184 	}
1185 
1186 	/* wait for vcn idle */
1187 	r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_STATUS, UVD_STATUS__IDLE, 0x7);
1188 	if (r)
1189 		return r;
1190 
1191 	tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
1192 		UVD_LMI_STATUS__READ_CLEAN_MASK |
1193 		UVD_LMI_STATUS__WRITE_CLEAN_MASK |
1194 		UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
1195 	r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_LMI_STATUS, tmp, tmp);
1196 	if (r)
1197 		return r;
1198 
1199 	/* disable LMI UMC channel */
1200 	tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL2);
1201 	tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK;
1202 	WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL2, tmp);
1203 	tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK |
1204 		UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
1205 	r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_LMI_STATUS, tmp, tmp);
1206 	if (r)
1207 		return r;
1208 
1209 	/* block VCPU register access */
1210 	WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_RB_ARB_CTRL),
1211 		 UVD_RB_ARB_CTRL__VCPU_DIS_MASK,
1212 		 ~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
1213 
1214 	/* reset VCPU */
1215 	WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL),
1216 		 UVD_VCPU_CNTL__BLK_RST_MASK,
1217 		 ~UVD_VCPU_CNTL__BLK_RST_MASK);
1218 
1219 	/* disable VCPU clock */
1220 	WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 0,
1221 		 ~(UVD_VCPU_CNTL__CLK_EN_MASK));
1222 
1223 	/* apply soft reset */
1224 	tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET);
1225 	tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
1226 	WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp);
1227 	tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET);
1228 	tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
1229 	WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp);
1230 
1231 	/* clear status */
1232 	WREG32_SOC15(VCN, vcn_inst, regUVD_STATUS, 0);
1233 
1234 	/* Keeping one read-back to ensure all register writes are done,
1235 	 * otherwise it may introduce race conditions.
1236 	 */
1237 	RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS);
1238 
1239 	return 0;
1240 }
1241 
1242 /**
1243  * vcn_v5_0_1_unified_ring_get_rptr - get unified read pointer
1244  *
1245  * @ring: amdgpu_ring pointer
1246  *
1247  * Returns the current hardware unified read pointer
1248  */
1249 static uint64_t vcn_v5_0_1_unified_ring_get_rptr(struct amdgpu_ring *ring)
1250 {
1251 	struct amdgpu_device *adev = ring->adev;
1252 
1253 	if (ring != &adev->vcn.inst[ring->me].ring_enc[0])
1254 		DRM_ERROR("wrong ring id is identified in %s", __func__);
1255 
1256 	return RREG32_SOC15(VCN, GET_INST(VCN, ring->me), regUVD_RB_RPTR);
1257 }
1258 
1259 /**
1260  * vcn_v5_0_1_unified_ring_get_wptr - get unified write pointer
1261  *
1262  * @ring: amdgpu_ring pointer
1263  *
1264  * Returns the current hardware unified write pointer
1265  */
1266 static uint64_t vcn_v5_0_1_unified_ring_get_wptr(struct amdgpu_ring *ring)
1267 {
1268 	struct amdgpu_device *adev = ring->adev;
1269 
1270 	if (ring != &adev->vcn.inst[ring->me].ring_enc[0])
1271 		DRM_ERROR("wrong ring id is identified in %s", __func__);
1272 
1273 	if (ring->use_doorbell)
1274 		return *ring->wptr_cpu_addr;
1275 	else
1276 		return RREG32_SOC15(VCN, GET_INST(VCN, ring->me), regUVD_RB_WPTR);
1277 }
1278 
1279 /**
1280  * vcn_v5_0_1_unified_ring_set_wptr - set enc write pointer
1281  *
1282  * @ring: amdgpu_ring pointer
1283  *
1284  * Commits the enc write pointer to the hardware
1285  */
1286 static void vcn_v5_0_1_unified_ring_set_wptr(struct amdgpu_ring *ring)
1287 {
1288 	struct amdgpu_device *adev = ring->adev;
1289 
1290 	if (ring != &adev->vcn.inst[ring->me].ring_enc[0])
1291 		DRM_ERROR("wrong ring id is identified in %s", __func__);
1292 
1293 	if (ring->use_doorbell) {
1294 		*ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
1295 		WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1296 	} else {
1297 		WREG32_SOC15(VCN, GET_INST(VCN, ring->me), regUVD_RB_WPTR,
1298 				lower_32_bits(ring->wptr));
1299 	}
1300 }
1301 
1302 static int vcn_v5_0_1_ring_reset(struct amdgpu_ring *ring,
1303 				 unsigned int vmid,
1304 				 struct amdgpu_fence *timedout_fence)
1305 {
1306 	int r = 0;
1307 	int vcn_inst;
1308 	struct amdgpu_device *adev = ring->adev;
1309 	struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[ring->me];
1310 
1311 	amdgpu_ring_reset_helper_begin(ring, timedout_fence);
1312 
1313 	vcn_inst = GET_INST(VCN, ring->me);
1314 	r = amdgpu_dpm_reset_vcn(adev, 1 << vcn_inst);
1315 
1316 	if (r) {
1317 		DRM_DEV_ERROR(adev->dev, "VCN reset fail : %d\n", r);
1318 		return r;
1319 	}
1320 
1321 	vcn_v5_0_1_hw_init_inst(adev, ring->me);
1322 	vcn_v5_0_1_start_dpg_mode(vinst, vinst->indirect_sram);
1323 
1324 	return amdgpu_ring_reset_helper_end(ring, timedout_fence);
1325 }
1326 
1327 static const struct amdgpu_ring_funcs vcn_v5_0_1_unified_ring_vm_funcs = {
1328 	.type = AMDGPU_RING_TYPE_VCN_ENC,
1329 	.align_mask = 0x3f,
1330 	.nop = VCN_ENC_CMD_NO_OP,
1331 	.get_rptr = vcn_v5_0_1_unified_ring_get_rptr,
1332 	.get_wptr = vcn_v5_0_1_unified_ring_get_wptr,
1333 	.set_wptr = vcn_v5_0_1_unified_ring_set_wptr,
1334 	.emit_frame_size = SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
1335 			   SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
1336 			   4 + /* vcn_v2_0_enc_ring_emit_vm_flush */
1337 			   5 +
1338 			   5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */
1339 			   1, /* vcn_v2_0_enc_ring_insert_end */
1340 	.emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */
1341 	.emit_ib = vcn_v2_0_enc_ring_emit_ib,
1342 	.emit_fence = vcn_v2_0_enc_ring_emit_fence,
1343 	.emit_vm_flush = vcn_v4_0_3_enc_ring_emit_vm_flush,
1344 	.emit_hdp_flush = vcn_v4_0_3_ring_emit_hdp_flush,
1345 	.test_ring = amdgpu_vcn_enc_ring_test_ring,
1346 	.test_ib = amdgpu_vcn_unified_ring_test_ib,
1347 	.insert_nop = amdgpu_ring_insert_nop,
1348 	.insert_end = vcn_v2_0_enc_ring_insert_end,
1349 	.pad_ib = amdgpu_ring_generic_pad_ib,
1350 	.begin_use = amdgpu_vcn_ring_begin_use,
1351 	.end_use = amdgpu_vcn_ring_end_use,
1352 	.emit_wreg = vcn_v4_0_3_enc_ring_emit_wreg,
1353 	.emit_reg_wait = vcn_v4_0_3_enc_ring_emit_reg_wait,
1354 	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1355 	.reset = vcn_v5_0_1_ring_reset,
1356 };
1357 
1358 /**
1359  * vcn_v5_0_1_set_unified_ring_funcs - set unified ring functions
1360  *
1361  * @adev: amdgpu_device pointer
1362  *
1363  * Set unified ring functions
1364  */
1365 static void vcn_v5_0_1_set_unified_ring_funcs(struct amdgpu_device *adev)
1366 {
1367 	int i, vcn_inst;
1368 
1369 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1370 		adev->vcn.inst[i].ring_enc[0].funcs = &vcn_v5_0_1_unified_ring_vm_funcs;
1371 		adev->vcn.inst[i].ring_enc[0].me = i;
1372 		vcn_inst = GET_INST(VCN, i);
1373 		adev->vcn.inst[i].aid_id = vcn_inst / adev->vcn.num_inst_per_aid;
1374 	}
1375 }
1376 
1377 /**
1378  * vcn_v5_0_1_is_idle - check VCN block is idle
1379  *
1380  * @ip_block: Pointer to the amdgpu_ip_block structure
1381  *
1382  * Check whether VCN block is idle
1383  */
1384 static bool vcn_v5_0_1_is_idle(struct amdgpu_ip_block *ip_block)
1385 {
1386 	struct amdgpu_device *adev = ip_block->adev;
1387 	int i, ret = 1;
1388 
1389 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i)
1390 		ret &= (RREG32_SOC15(VCN, GET_INST(VCN, i), regUVD_STATUS) == UVD_STATUS__IDLE);
1391 
1392 	return ret;
1393 }
1394 
1395 /**
1396  * vcn_v5_0_1_wait_for_idle - wait for VCN block idle
1397  *
1398  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
1399  *
1400  * Wait for VCN block idle
1401  */
1402 static int vcn_v5_0_1_wait_for_idle(struct amdgpu_ip_block *ip_block)
1403 {
1404 	struct amdgpu_device *adev = ip_block->adev;
1405 	int i, ret = 0;
1406 
1407 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1408 		ret = SOC15_WAIT_ON_RREG(VCN, GET_INST(VCN, i), regUVD_STATUS, UVD_STATUS__IDLE,
1409 			UVD_STATUS__IDLE);
1410 		if (ret)
1411 			return ret;
1412 	}
1413 
1414 	return ret;
1415 }
1416 
1417 /**
1418  * vcn_v5_0_1_set_clockgating_state - set VCN block clockgating state
1419  *
1420  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
1421  * @state: clock gating state
1422  *
1423  * Set VCN block clockgating state
1424  */
1425 static int vcn_v5_0_1_set_clockgating_state(struct amdgpu_ip_block *ip_block,
1426 					    enum amd_clockgating_state state)
1427 {
1428 	struct amdgpu_device *adev = ip_block->adev;
1429 	bool enable = state == AMD_CG_STATE_GATE;
1430 	int i;
1431 
1432 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1433 		struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i];
1434 
1435 		if (enable) {
1436 			if (RREG32_SOC15(VCN, GET_INST(VCN, i), regUVD_STATUS) != UVD_STATUS__IDLE)
1437 				return -EBUSY;
1438 			vcn_v5_0_1_enable_clock_gating(vinst);
1439 		} else {
1440 			vcn_v5_0_1_disable_clock_gating(vinst);
1441 		}
1442 	}
1443 
1444 	return 0;
1445 }
1446 
1447 static int vcn_v5_0_1_set_pg_state(struct amdgpu_vcn_inst *vinst,
1448 				   enum amd_powergating_state state)
1449 {
1450 	struct amdgpu_device *adev = vinst->adev;
1451 	int ret = 0;
1452 
1453 	/* for SRIOV, guest should not control VCN Power-gating
1454 	 * MMSCH FW should control Power-gating and clock-gating
1455 	 * guest should avoid touching CGC and PG
1456 	 */
1457 	if (amdgpu_sriov_vf(adev)) {
1458 		vinst->cur_state = AMD_PG_STATE_UNGATE;
1459 		return 0;
1460 	}
1461 
1462 	if (state == vinst->cur_state)
1463 		return 0;
1464 
1465 	if (state == AMD_PG_STATE_GATE)
1466 		ret = vcn_v5_0_1_stop(vinst);
1467 	else
1468 		ret = vcn_v5_0_1_start(vinst);
1469 
1470 	if (!ret)
1471 		vinst->cur_state = state;
1472 
1473 	return ret;
1474 }
1475 
1476 /**
1477  * vcn_v5_0_1_process_interrupt - process VCN block interrupt
1478  *
1479  * @adev: amdgpu_device pointer
1480  * @source: interrupt sources
1481  * @entry: interrupt entry from clients and sources
1482  *
1483  * Process VCN block interrupt
1484  */
1485 static int vcn_v5_0_1_process_interrupt(struct amdgpu_device *adev, struct amdgpu_irq_src *source,
1486 	struct amdgpu_iv_entry *entry)
1487 {
1488 	uint32_t i, inst;
1489 
1490 	i = node_id_to_phys_map[entry->node_id];
1491 
1492 	DRM_DEV_DEBUG(adev->dev, "IH: VCN TRAP\n");
1493 
1494 	for (inst = 0; inst < adev->vcn.num_vcn_inst; ++inst)
1495 		if (adev->vcn.inst[inst].aid_id == i)
1496 			break;
1497 	if (inst >= adev->vcn.num_vcn_inst) {
1498 		dev_WARN_ONCE(adev->dev, 1,
1499 				"Interrupt received for unknown VCN instance %d",
1500 				entry->node_id);
1501 		return 0;
1502 	}
1503 
1504 	switch (entry->src_id) {
1505 	case VCN_5_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
1506 		amdgpu_fence_process(&adev->vcn.inst[inst].ring_enc[0]);
1507 		break;
1508 	default:
1509 		DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n",
1510 			  entry->src_id, entry->src_data[0]);
1511 		break;
1512 	}
1513 
1514 	return 0;
1515 }
1516 
1517 static int vcn_v5_0_1_set_ras_interrupt_state(struct amdgpu_device *adev,
1518 					struct amdgpu_irq_src *source,
1519 					unsigned int type,
1520 					enum amdgpu_interrupt_state state)
1521 {
1522 	return 0;
1523 }
1524 
1525 static const struct amdgpu_irq_src_funcs vcn_v5_0_1_irq_funcs = {
1526 	.process = vcn_v5_0_1_process_interrupt,
1527 };
1528 
1529 static const struct amdgpu_irq_src_funcs vcn_v5_0_1_ras_irq_funcs = {
1530 	.set = vcn_v5_0_1_set_ras_interrupt_state,
1531 	.process = amdgpu_vcn_process_poison_irq,
1532 };
1533 
1534 
1535 /**
1536  * vcn_v5_0_1_set_irq_funcs - set VCN block interrupt irq functions
1537  *
1538  * @adev: amdgpu_device pointer
1539  *
1540  * Set VCN block interrupt irq functions
1541  */
1542 static void vcn_v5_0_1_set_irq_funcs(struct amdgpu_device *adev)
1543 {
1544 	int i;
1545 
1546 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i)
1547 		adev->vcn.inst->irq.num_types++;
1548 
1549 	adev->vcn.inst->irq.funcs = &vcn_v5_0_1_irq_funcs;
1550 
1551 	adev->vcn.inst->ras_poison_irq.num_types = 1;
1552 	adev->vcn.inst->ras_poison_irq.funcs = &vcn_v5_0_1_ras_irq_funcs;
1553 
1554 }
1555 
1556 static const struct amd_ip_funcs vcn_v5_0_1_ip_funcs = {
1557 	.name = "vcn_v5_0_1",
1558 	.early_init = vcn_v5_0_1_early_init,
1559 	.late_init = vcn_v5_0_1_late_init,
1560 	.sw_init = vcn_v5_0_1_sw_init,
1561 	.sw_fini = vcn_v5_0_1_sw_fini,
1562 	.hw_init = vcn_v5_0_1_hw_init,
1563 	.hw_fini = vcn_v5_0_1_hw_fini,
1564 	.suspend = vcn_v5_0_1_suspend,
1565 	.resume = vcn_v5_0_1_resume,
1566 	.is_idle = vcn_v5_0_1_is_idle,
1567 	.wait_for_idle = vcn_v5_0_1_wait_for_idle,
1568 	.check_soft_reset = NULL,
1569 	.pre_soft_reset = NULL,
1570 	.soft_reset = NULL,
1571 	.post_soft_reset = NULL,
1572 	.set_clockgating_state = vcn_v5_0_1_set_clockgating_state,
1573 	.set_powergating_state = vcn_set_powergating_state,
1574 	.dump_ip_state = amdgpu_vcn_dump_ip_state,
1575 	.print_ip_state = amdgpu_vcn_print_ip_state,
1576 };
1577 
1578 const struct amdgpu_ip_block_version vcn_v5_0_1_ip_block = {
1579 	.type = AMD_IP_BLOCK_TYPE_VCN,
1580 	.major = 5,
1581 	.minor = 0,
1582 	.rev = 1,
1583 	.funcs = &vcn_v5_0_1_ip_funcs,
1584 };
1585 
1586 static uint32_t vcn_v5_0_1_query_poison_by_instance(struct amdgpu_device *adev,
1587 			uint32_t instance, uint32_t sub_block)
1588 {
1589 	uint32_t poison_stat = 0, reg_value = 0;
1590 
1591 	switch (sub_block) {
1592 	case AMDGPU_VCN_V5_0_1_VCPU_VCODEC:
1593 		reg_value = RREG32_SOC15(VCN, instance, regUVD_RAS_VCPU_VCODEC_STATUS);
1594 		poison_stat = REG_GET_FIELD(reg_value, UVD_RAS_VCPU_VCODEC_STATUS, POISONED_PF);
1595 		break;
1596 	default:
1597 		break;
1598 	}
1599 
1600 	if (poison_stat)
1601 		dev_info(adev->dev, "Poison detected in VCN%d, sub_block%d\n",
1602 			instance, sub_block);
1603 
1604 	return poison_stat;
1605 }
1606 
1607 static bool vcn_v5_0_1_query_poison_status(struct amdgpu_device *adev)
1608 {
1609 	uint32_t inst, sub;
1610 	uint32_t poison_stat = 0;
1611 
1612 	for (inst = 0; inst < adev->vcn.num_vcn_inst; inst++)
1613 		for (sub = 0; sub < AMDGPU_VCN_V5_0_1_MAX_SUB_BLOCK; sub++)
1614 			poison_stat +=
1615 			vcn_v5_0_1_query_poison_by_instance(adev, inst, sub);
1616 
1617 	return !!poison_stat;
1618 }
1619 
1620 static const struct amdgpu_ras_block_hw_ops vcn_v5_0_1_ras_hw_ops = {
1621 	.query_poison_status = vcn_v5_0_1_query_poison_status,
1622 };
1623 
1624 static int vcn_v5_0_1_aca_bank_parser(struct aca_handle *handle, struct aca_bank *bank,
1625 				      enum aca_smu_type type, void *data)
1626 {
1627 	struct aca_bank_info info;
1628 	u64 misc0;
1629 	int ret;
1630 
1631 	ret = aca_bank_info_decode(bank, &info);
1632 	if (ret)
1633 		return ret;
1634 
1635 	misc0 = bank->regs[ACA_REG_IDX_MISC0];
1636 	switch (type) {
1637 	case ACA_SMU_TYPE_UE:
1638 		bank->aca_err_type = ACA_ERROR_TYPE_UE;
1639 		ret = aca_error_cache_log_bank_error(handle, &info, ACA_ERROR_TYPE_UE,
1640 						     1ULL);
1641 		break;
1642 	case ACA_SMU_TYPE_CE:
1643 		bank->aca_err_type = ACA_ERROR_TYPE_CE;
1644 		ret = aca_error_cache_log_bank_error(handle, &info, bank->aca_err_type,
1645 						     ACA_REG__MISC0__ERRCNT(misc0));
1646 		break;
1647 	default:
1648 		return -EINVAL;
1649 	}
1650 
1651 	return ret;
1652 }
1653 
1654 /* reference to smu driver if header file */
1655 static int vcn_v5_0_1_err_codes[] = {
1656 	14, 15, 47, /* VCN [D|V|S] */
1657 };
1658 
1659 static bool vcn_v5_0_1_aca_bank_is_valid(struct aca_handle *handle, struct aca_bank *bank,
1660 					 enum aca_smu_type type, void *data)
1661 {
1662 	u32 instlo;
1663 
1664 	instlo = ACA_REG__IPID__INSTANCEIDLO(bank->regs[ACA_REG_IDX_IPID]);
1665 	instlo &= GENMASK(31, 1);
1666 
1667 	if (instlo != mmSMNAID_AID0_MCA_SMU)
1668 		return false;
1669 
1670 	if (aca_bank_check_error_codes(handle->adev, bank,
1671 				       vcn_v5_0_1_err_codes,
1672 				       ARRAY_SIZE(vcn_v5_0_1_err_codes)))
1673 		return false;
1674 
1675 	return true;
1676 }
1677 
1678 static const struct aca_bank_ops vcn_v5_0_1_aca_bank_ops = {
1679 	.aca_bank_parser = vcn_v5_0_1_aca_bank_parser,
1680 	.aca_bank_is_valid = vcn_v5_0_1_aca_bank_is_valid,
1681 };
1682 
1683 static const struct aca_info vcn_v5_0_1_aca_info = {
1684 	.hwip = ACA_HWIP_TYPE_SMU,
1685 	.mask = ACA_ERROR_UE_MASK,
1686 	.bank_ops = &vcn_v5_0_1_aca_bank_ops,
1687 };
1688 
1689 static int vcn_v5_0_1_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block)
1690 {
1691 	int r;
1692 
1693 	r = amdgpu_ras_block_late_init(adev, ras_block);
1694 	if (r)
1695 		return r;
1696 
1697 	r = amdgpu_ras_bind_aca(adev, AMDGPU_RAS_BLOCK__VCN,
1698 				&vcn_v5_0_1_aca_info, NULL);
1699 	if (r)
1700 		goto late_fini;
1701 
1702 	if (amdgpu_ras_is_supported(adev, ras_block->block) &&
1703 		adev->vcn.inst->ras_poison_irq.funcs) {
1704 		r = amdgpu_irq_get(adev, &adev->vcn.inst->ras_poison_irq, 0);
1705 		if (r)
1706 			goto late_fini;
1707 	}
1708 
1709 	return 0;
1710 
1711 late_fini:
1712 	amdgpu_ras_block_late_fini(adev, ras_block);
1713 
1714 	return r;
1715 }
1716 
1717 static struct amdgpu_vcn_ras vcn_v5_0_1_ras = {
1718 	.ras_block = {
1719 		.hw_ops = &vcn_v5_0_1_ras_hw_ops,
1720 		.ras_late_init = vcn_v5_0_1_ras_late_init,
1721 	},
1722 };
1723 
1724 static void vcn_v5_0_1_set_ras_funcs(struct amdgpu_device *adev)
1725 {
1726 	adev->vcn.ras = &vcn_v5_0_1_ras;
1727 }
1728