xref: /linux/drivers/gpu/drm/amd/amdgpu/vcn_v5_0_1.c (revision 148ab873d8194cb44f29474da3b4428fa2e100d1)
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,
1339 					  jiffies_to_usecs(adev->video_timeout));
1340        }
1341 
1342 	return 0;
1343 }
1344 
1345 static int vcn_v5_0_1_reset_jpeg_post_helper(struct amdgpu_device *adev, int inst)
1346 {
1347 	struct amdgpu_ring *ring;
1348 	int i, r = 0;
1349 
1350 	for (i = 0; i < adev->jpeg.num_jpeg_rings; ++i) {
1351 		ring = &adev->jpeg.inst[inst].ring_dec[i];
1352 		/* Force completion of any remaining jobs */
1353 		amdgpu_fence_driver_force_completion(ring, NULL);
1354 
1355 		if (ring->use_doorbell)
1356 			WREG32_SOC15_OFFSET(
1357 				VCN, GET_INST(VCN, inst),
1358 				regVCN_JPEG_DB_CTRL,
1359 				(ring->pipe ? (ring->pipe - 0x15) : 0),
1360 				ring->doorbell_index << VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
1361 				VCN_JPEG_DB_CTRL__EN_MASK);
1362 
1363 		r = amdgpu_ring_test_helper(ring);
1364 		if (r)
1365 			return r;
1366 
1367 		drm_sched_wqueue_start(&ring->sched);
1368 
1369 		DRM_DEV_DEBUG(adev->dev, "JPEG ring %d (inst %d) restored and sched restarted\n",
1370 		      i, inst);
1371 	}
1372 	return 0;
1373 }
1374 
1375 static int vcn_v5_0_1_ring_reset(struct amdgpu_ring *ring,
1376 				 unsigned int vmid,
1377 				 struct amdgpu_fence *timedout_fence)
1378 {
1379 	int r = 0;
1380 	int vcn_inst;
1381 	struct amdgpu_device *adev = ring->adev;
1382 	struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[ring->me];
1383 	bool pg_state = false;
1384 
1385 	/* take the vcn reset mutex here because resetting VCN will reset jpeg as well */
1386 	mutex_lock(&vinst->engine_reset_mutex);
1387 	vcn_v5_0_1_reset_jpeg_pre_helper(adev, ring->me);
1388 	mutex_lock(&adev->jpeg.jpeg_pg_lock);
1389 	/* Ensure JPEG is powered on during reset if currently gated */
1390 	if (adev->jpeg.cur_state == AMD_PG_STATE_GATE) {
1391 		amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_JPEG,
1392 					       AMD_PG_STATE_UNGATE);
1393 		pg_state = true;
1394 	}
1395 
1396 	amdgpu_ring_reset_helper_begin(ring, timedout_fence);
1397 
1398 	vcn_inst = GET_INST(VCN, ring->me);
1399 	r = amdgpu_dpm_reset_vcn(adev, 1 << vcn_inst);
1400 
1401 	if (r) {
1402 		DRM_DEV_ERROR(adev->dev, "VCN reset fail : %d\n", r);
1403 		/* Restore JPEG power gating state if it was originally gated */
1404 		if (pg_state)
1405 			amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_JPEG,
1406 							       AMD_PG_STATE_GATE);
1407 		mutex_unlock(&adev->jpeg.jpeg_pg_lock);
1408 		goto unlock;
1409 	}
1410 
1411 	vcn_v5_0_1_hw_init_inst(adev, ring->me);
1412 	vcn_v5_0_1_start_dpg_mode(vinst, vinst->indirect_sram);
1413 
1414 	r = amdgpu_ring_reset_helper_end(ring, timedout_fence);
1415 	if (r) {
1416 		if (pg_state)
1417 			amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_JPEG,
1418 							       AMD_PG_STATE_GATE);
1419 		mutex_unlock(&adev->jpeg.jpeg_pg_lock);
1420 		goto unlock;
1421 	}
1422 
1423 	if (pg_state)
1424 		amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_JPEG,
1425 						       AMD_PG_STATE_GATE);
1426 	mutex_unlock(&adev->jpeg.jpeg_pg_lock);
1427 
1428 	r = vcn_v5_0_1_reset_jpeg_post_helper(adev, ring->me);
1429 
1430 unlock:
1431 	mutex_unlock(&vinst->engine_reset_mutex);
1432 
1433 	return r;
1434 }
1435 
1436 static const struct amdgpu_ring_funcs vcn_v5_0_1_unified_ring_vm_funcs = {
1437 	.type = AMDGPU_RING_TYPE_VCN_ENC,
1438 	.align_mask = 0x3f,
1439 	.nop = VCN_ENC_CMD_NO_OP,
1440 	.no_user_fence = true,
1441 	.get_rptr = vcn_v5_0_1_unified_ring_get_rptr,
1442 	.get_wptr = vcn_v5_0_1_unified_ring_get_wptr,
1443 	.set_wptr = vcn_v5_0_1_unified_ring_set_wptr,
1444 	.emit_frame_size = SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
1445 			   SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
1446 			   4 + /* vcn_v2_0_enc_ring_emit_vm_flush */
1447 			   5 +
1448 			   5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */
1449 			   1, /* vcn_v2_0_enc_ring_insert_end */
1450 	.emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */
1451 	.emit_ib = vcn_v2_0_enc_ring_emit_ib,
1452 	.emit_fence = vcn_v2_0_enc_ring_emit_fence,
1453 	.emit_vm_flush = vcn_v4_0_3_enc_ring_emit_vm_flush,
1454 	.emit_hdp_flush = vcn_v4_0_3_ring_emit_hdp_flush,
1455 	.test_ring = amdgpu_vcn_enc_ring_test_ring,
1456 	.test_ib = amdgpu_vcn_unified_ring_test_ib,
1457 	.insert_nop = amdgpu_ring_insert_nop,
1458 	.insert_end = vcn_v2_0_enc_ring_insert_end,
1459 	.pad_ib = amdgpu_ring_generic_pad_ib,
1460 	.begin_use = amdgpu_vcn_ring_begin_use,
1461 	.end_use = amdgpu_vcn_ring_end_use,
1462 	.emit_wreg = vcn_v4_0_3_enc_ring_emit_wreg,
1463 	.emit_reg_wait = vcn_v4_0_3_enc_ring_emit_reg_wait,
1464 	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1465 	.reset = vcn_v5_0_1_ring_reset,
1466 };
1467 
1468 /**
1469  * vcn_v5_0_1_set_unified_ring_funcs - set unified ring functions
1470  *
1471  * @adev: amdgpu_device pointer
1472  *
1473  * Set unified ring functions
1474  */
1475 static void vcn_v5_0_1_set_unified_ring_funcs(struct amdgpu_device *adev)
1476 {
1477 	int i, vcn_inst;
1478 
1479 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1480 		adev->vcn.inst[i].ring_enc[0].funcs = &vcn_v5_0_1_unified_ring_vm_funcs;
1481 		adev->vcn.inst[i].ring_enc[0].me = i;
1482 		vcn_inst = GET_INST(VCN, i);
1483 		adev->vcn.inst[i].aid_id = vcn_inst / adev->vcn.num_inst_per_aid;
1484 	}
1485 }
1486 
1487 /**
1488  * vcn_v5_0_1_is_idle - check VCN block is idle
1489  *
1490  * @ip_block: Pointer to the amdgpu_ip_block structure
1491  *
1492  * Check whether VCN block is idle
1493  */
1494 static bool vcn_v5_0_1_is_idle(struct amdgpu_ip_block *ip_block)
1495 {
1496 	struct amdgpu_device *adev = ip_block->adev;
1497 	int i, ret = 1;
1498 
1499 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i)
1500 		ret &= (RREG32_SOC15(VCN, GET_INST(VCN, i), regUVD_STATUS) == UVD_STATUS__IDLE);
1501 
1502 	return ret;
1503 }
1504 
1505 /**
1506  * vcn_v5_0_1_wait_for_idle - wait for VCN block idle
1507  *
1508  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
1509  *
1510  * Wait for VCN block idle
1511  */
1512 static int vcn_v5_0_1_wait_for_idle(struct amdgpu_ip_block *ip_block)
1513 {
1514 	struct amdgpu_device *adev = ip_block->adev;
1515 	int i, ret = 0;
1516 
1517 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1518 		ret = SOC15_WAIT_ON_RREG(VCN, GET_INST(VCN, i), regUVD_STATUS, UVD_STATUS__IDLE,
1519 			UVD_STATUS__IDLE);
1520 		if (ret)
1521 			return ret;
1522 	}
1523 
1524 	return ret;
1525 }
1526 
1527 /**
1528  * vcn_v5_0_1_set_clockgating_state - set VCN block clockgating state
1529  *
1530  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
1531  * @state: clock gating state
1532  *
1533  * Set VCN block clockgating state
1534  */
1535 static int vcn_v5_0_1_set_clockgating_state(struct amdgpu_ip_block *ip_block,
1536 					    enum amd_clockgating_state state)
1537 {
1538 	struct amdgpu_device *adev = ip_block->adev;
1539 	bool enable = state == AMD_CG_STATE_GATE;
1540 	int i;
1541 
1542 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1543 		struct amdgpu_vcn_inst *vinst = &adev->vcn.inst[i];
1544 
1545 		if (enable) {
1546 			if (RREG32_SOC15(VCN, GET_INST(VCN, i), regUVD_STATUS) != UVD_STATUS__IDLE)
1547 				return -EBUSY;
1548 			vcn_v5_0_1_enable_clock_gating(vinst);
1549 		} else {
1550 			vcn_v5_0_1_disable_clock_gating(vinst);
1551 		}
1552 	}
1553 
1554 	return 0;
1555 }
1556 
1557 static int vcn_v5_0_1_set_pg_state(struct amdgpu_vcn_inst *vinst,
1558 				   enum amd_powergating_state state)
1559 {
1560 	struct amdgpu_device *adev = vinst->adev;
1561 	int ret = 0;
1562 
1563 	/* for SRIOV, guest should not control VCN Power-gating
1564 	 * MMSCH FW should control Power-gating and clock-gating
1565 	 * guest should avoid touching CGC and PG
1566 	 */
1567 	if (amdgpu_sriov_vf(adev)) {
1568 		vinst->cur_state = AMD_PG_STATE_UNGATE;
1569 		return 0;
1570 	}
1571 
1572 	if (state == vinst->cur_state)
1573 		return 0;
1574 
1575 	if (state == AMD_PG_STATE_GATE)
1576 		ret = vcn_v5_0_1_stop(vinst);
1577 	else
1578 		ret = vcn_v5_0_1_start(vinst);
1579 
1580 	if (!ret)
1581 		vinst->cur_state = state;
1582 
1583 	return ret;
1584 }
1585 
1586 /**
1587  * vcn_v5_0_1_process_interrupt - process VCN block interrupt
1588  *
1589  * @adev: amdgpu_device pointer
1590  * @source: interrupt sources
1591  * @entry: interrupt entry from clients and sources
1592  *
1593  * Process VCN block interrupt
1594  */
1595 static int vcn_v5_0_1_process_interrupt(struct amdgpu_device *adev, struct amdgpu_irq_src *source,
1596 	struct amdgpu_iv_entry *entry)
1597 {
1598 	uint32_t i, inst;
1599 
1600 	i = node_id_to_phys_map[entry->node_id];
1601 
1602 	DRM_DEV_DEBUG(adev->dev, "IH: VCN TRAP\n");
1603 
1604 	for (inst = 0; inst < adev->vcn.num_vcn_inst; ++inst)
1605 		if (adev->vcn.inst[inst].aid_id == i)
1606 			break;
1607 	if (inst >= adev->vcn.num_vcn_inst) {
1608 		dev_WARN_ONCE(adev->dev, 1,
1609 				"Interrupt received for unknown VCN instance %d",
1610 				entry->node_id);
1611 		return 0;
1612 	}
1613 
1614 	switch (entry->src_id) {
1615 	case VCN_5_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
1616 		amdgpu_fence_process(&adev->vcn.inst[inst].ring_enc[0]);
1617 		break;
1618 	default:
1619 		DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n",
1620 			  entry->src_id, entry->src_data[0]);
1621 		break;
1622 	}
1623 
1624 	return 0;
1625 }
1626 
1627 static int vcn_v5_0_1_set_ras_interrupt_state(struct amdgpu_device *adev,
1628 					struct amdgpu_irq_src *source,
1629 					unsigned int type,
1630 					enum amdgpu_interrupt_state state)
1631 {
1632 	return 0;
1633 }
1634 
1635 static const struct amdgpu_irq_src_funcs vcn_v5_0_1_irq_funcs = {
1636 	.process = vcn_v5_0_1_process_interrupt,
1637 };
1638 
1639 static const struct amdgpu_irq_src_funcs vcn_v5_0_1_ras_irq_funcs = {
1640 	.set = vcn_v5_0_1_set_ras_interrupt_state,
1641 	.process = amdgpu_vcn_process_poison_irq,
1642 };
1643 
1644 
1645 /**
1646  * vcn_v5_0_1_set_irq_funcs - set VCN block interrupt irq functions
1647  *
1648  * @adev: amdgpu_device pointer
1649  *
1650  * Set VCN block interrupt irq functions
1651  */
1652 static void vcn_v5_0_1_set_irq_funcs(struct amdgpu_device *adev)
1653 {
1654 	int i;
1655 
1656 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i)
1657 		adev->vcn.inst->irq.num_types++;
1658 
1659 	adev->vcn.inst->irq.funcs = &vcn_v5_0_1_irq_funcs;
1660 
1661 	adev->vcn.inst->ras_poison_irq.num_types = 1;
1662 	adev->vcn.inst->ras_poison_irq.funcs = &vcn_v5_0_1_ras_irq_funcs;
1663 
1664 }
1665 
1666 static const struct amd_ip_funcs vcn_v5_0_1_ip_funcs = {
1667 	.name = "vcn_v5_0_1",
1668 	.early_init = vcn_v5_0_1_early_init,
1669 	.late_init = vcn_v5_0_1_late_init,
1670 	.sw_init = vcn_v5_0_1_sw_init,
1671 	.sw_fini = vcn_v5_0_1_sw_fini,
1672 	.hw_init = vcn_v5_0_1_hw_init,
1673 	.hw_fini = vcn_v5_0_1_hw_fini,
1674 	.suspend = vcn_v5_0_1_suspend,
1675 	.resume = vcn_v5_0_1_resume,
1676 	.is_idle = vcn_v5_0_1_is_idle,
1677 	.wait_for_idle = vcn_v5_0_1_wait_for_idle,
1678 	.soft_reset = NULL,
1679 	.set_clockgating_state = vcn_v5_0_1_set_clockgating_state,
1680 	.set_powergating_state = vcn_set_powergating_state,
1681 	.dump_ip_state = amdgpu_vcn_dump_ip_state,
1682 	.print_ip_state = amdgpu_vcn_print_ip_state,
1683 };
1684 
1685 const struct amdgpu_ip_block_version vcn_v5_0_1_ip_block = {
1686 	.type = AMD_IP_BLOCK_TYPE_VCN,
1687 	.major = 5,
1688 	.minor = 0,
1689 	.rev = 1,
1690 	.funcs = &vcn_v5_0_1_ip_funcs,
1691 };
1692 
1693 static uint32_t vcn_v5_0_1_query_poison_by_instance(struct amdgpu_device *adev,
1694 			uint32_t instance, uint32_t sub_block)
1695 {
1696 	uint32_t poison_stat = 0, reg_value = 0;
1697 
1698 	switch (sub_block) {
1699 	case AMDGPU_VCN_V5_0_1_VCPU_VCODEC:
1700 		reg_value = RREG32_SOC15(VCN, instance, regUVD_RAS_VCPU_VCODEC_STATUS);
1701 		poison_stat = REG_GET_FIELD(reg_value, UVD_RAS_VCPU_VCODEC_STATUS, POISONED_PF);
1702 		break;
1703 	default:
1704 		break;
1705 	}
1706 
1707 	if (poison_stat)
1708 		dev_info(adev->dev, "Poison detected in VCN%d, sub_block%d\n",
1709 			instance, sub_block);
1710 
1711 	return poison_stat;
1712 }
1713 
1714 static bool vcn_v5_0_1_query_poison_status(struct amdgpu_device *adev)
1715 {
1716 	uint32_t inst, sub;
1717 	uint32_t poison_stat = 0;
1718 
1719 	for (inst = 0; inst < adev->vcn.num_vcn_inst; inst++)
1720 		for (sub = 0; sub < AMDGPU_VCN_V5_0_1_MAX_SUB_BLOCK; sub++)
1721 			poison_stat +=
1722 			vcn_v5_0_1_query_poison_by_instance(adev, inst, sub);
1723 
1724 	return !!poison_stat;
1725 }
1726 
1727 static const struct amdgpu_ras_block_hw_ops vcn_v5_0_1_ras_hw_ops = {
1728 	.query_poison_status = vcn_v5_0_1_query_poison_status,
1729 };
1730 
1731 static int vcn_v5_0_1_ras_late_init(struct amdgpu_device *adev, struct ras_common_if *ras_block)
1732 {
1733 	int r;
1734 
1735 	r = amdgpu_ras_block_late_init(adev, ras_block);
1736 	if (r)
1737 		return r;
1738 
1739 	if (amdgpu_ras_is_supported(adev, ras_block->block) &&
1740 		adev->vcn.inst->ras_poison_irq.funcs) {
1741 		r = amdgpu_irq_get(adev, &adev->vcn.inst->ras_poison_irq, 0);
1742 		if (r)
1743 			goto late_fini;
1744 	}
1745 
1746 	return 0;
1747 
1748 late_fini:
1749 	amdgpu_ras_block_late_fini(adev, ras_block);
1750 
1751 	return r;
1752 }
1753 
1754 static struct amdgpu_vcn_ras vcn_v5_0_1_ras = {
1755 	.ras_block = {
1756 		.hw_ops = &vcn_v5_0_1_ras_hw_ops,
1757 		.ras_late_init = vcn_v5_0_1_ras_late_init,
1758 	},
1759 };
1760 
1761 static void vcn_v5_0_1_set_ras_funcs(struct amdgpu_device *adev)
1762 {
1763 	adev->vcn.ras = &vcn_v5_0_1_ras;
1764 }
1765