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