xref: /openbmc/linux/drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c (revision 2b77dcc5)
1 /*
2  * Copyright 2019 Advanced Micro Devices, Inc.
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 
26 #include "amdgpu.h"
27 #include "amdgpu_vcn.h"
28 #include "amdgpu_pm.h"
29 #include "soc15.h"
30 #include "soc15d.h"
31 #include "vcn_v2_0.h"
32 
33 #include "vcn/vcn_2_5_offset.h"
34 #include "vcn/vcn_2_5_sh_mask.h"
35 #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
36 
37 #define mmUVD_CONTEXT_ID_INTERNAL_OFFSET			0x27
38 #define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET			0x0f
39 #define mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET			0x10
40 #define mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET			0x11
41 #define mmUVD_NO_OP_INTERNAL_OFFSET				0x29
42 #define mmUVD_GP_SCRATCH8_INTERNAL_OFFSET			0x66
43 #define mmUVD_SCRATCH9_INTERNAL_OFFSET				0xc01d
44 
45 #define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET			0x431
46 #define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET		0x3b4
47 #define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET 	0x3b5
48 #define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET			0x25c
49 
50 #define VCN25_MAX_HW_INSTANCES_ARCTURUS			2
51 
52 static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev);
53 static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev);
54 static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev);
55 static int vcn_v2_5_set_powergating_state(void *handle,
56 				enum amd_powergating_state state);
57 
58 static int amdgpu_ih_clientid_vcns[] = {
59 	SOC15_IH_CLIENTID_VCN,
60 	SOC15_IH_CLIENTID_VCN1
61 };
62 
63 /**
64  * vcn_v2_5_early_init - set function pointers
65  *
66  * @handle: amdgpu_device pointer
67  *
68  * Set ring and irq function pointers
69  */
70 static int vcn_v2_5_early_init(void *handle)
71 {
72 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
73 	if (adev->asic_type == CHIP_ARCTURUS) {
74 		u32 harvest;
75 		int i;
76 
77 		adev->vcn.num_vcn_inst = VCN25_MAX_HW_INSTANCES_ARCTURUS;
78 		for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
79 			harvest = RREG32_SOC15(UVD, i, mmCC_UVD_HARVESTING);
80 			if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK)
81 				adev->vcn.harvest_config |= 1 << i;
82 		}
83 
84 		if (adev->vcn.harvest_config == (AMDGPU_VCN_HARVEST_VCN0 |
85 						 AMDGPU_VCN_HARVEST_VCN1))
86 			/* both instances are harvested, disable the block */
87 			return -ENOENT;
88 	} else
89 		adev->vcn.num_vcn_inst = 1;
90 
91 	adev->vcn.num_enc_rings = 2;
92 
93 	vcn_v2_5_set_dec_ring_funcs(adev);
94 	vcn_v2_5_set_enc_ring_funcs(adev);
95 	vcn_v2_5_set_irq_funcs(adev);
96 
97 	return 0;
98 }
99 
100 /**
101  * vcn_v2_5_sw_init - sw init for VCN block
102  *
103  * @handle: amdgpu_device pointer
104  *
105  * Load firmware and sw initialization
106  */
107 static int vcn_v2_5_sw_init(void *handle)
108 {
109 	struct amdgpu_ring *ring;
110 	int i, j, r;
111 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
112 
113 	for (j = 0; j < adev->vcn.num_vcn_inst; j++) {
114 		if (adev->vcn.harvest_config & (1 << j))
115 			continue;
116 		/* VCN DEC TRAP */
117 		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
118 				VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->vcn.inst[j].irq);
119 		if (r)
120 			return r;
121 
122 		/* VCN ENC TRAP */
123 		for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
124 			r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
125 				i + VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst[j].irq);
126 			if (r)
127 				return r;
128 		}
129 	}
130 
131 	r = amdgpu_vcn_sw_init(adev);
132 	if (r)
133 		return r;
134 
135 	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
136 		const struct common_firmware_header *hdr;
137 		hdr = (const struct common_firmware_header *)adev->vcn.fw->data;
138 		adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].ucode_id = AMDGPU_UCODE_ID_VCN;
139 		adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].fw = adev->vcn.fw;
140 		adev->firmware.fw_size +=
141 			ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
142 
143 		if (adev->vcn.num_vcn_inst == VCN25_MAX_HW_INSTANCES_ARCTURUS) {
144 			adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].ucode_id = AMDGPU_UCODE_ID_VCN1;
145 			adev->firmware.ucode[AMDGPU_UCODE_ID_VCN1].fw = adev->vcn.fw;
146 			adev->firmware.fw_size +=
147 				ALIGN(le32_to_cpu(hdr->ucode_size_bytes), PAGE_SIZE);
148 		}
149 		DRM_INFO("PSP loading VCN firmware\n");
150 	}
151 
152 	r = amdgpu_vcn_resume(adev);
153 	if (r)
154 		return r;
155 
156 	for (j = 0; j < adev->vcn.num_vcn_inst; j++) {
157 		if (adev->vcn.harvest_config & (1 << j))
158 			continue;
159 		adev->vcn.internal.context_id = mmUVD_CONTEXT_ID_INTERNAL_OFFSET;
160 		adev->vcn.internal.ib_vmid = mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET;
161 		adev->vcn.internal.ib_bar_low = mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET;
162 		adev->vcn.internal.ib_bar_high = mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET;
163 		adev->vcn.internal.ib_size = mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET;
164 		adev->vcn.internal.gp_scratch8 = mmUVD_GP_SCRATCH8_INTERNAL_OFFSET;
165 
166 		adev->vcn.internal.scratch9 = mmUVD_SCRATCH9_INTERNAL_OFFSET;
167 		adev->vcn.inst[j].external.scratch9 = SOC15_REG_OFFSET(UVD, j, mmUVD_SCRATCH9);
168 		adev->vcn.internal.data0 = mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET;
169 		adev->vcn.inst[j].external.data0 = SOC15_REG_OFFSET(UVD, j, mmUVD_GPCOM_VCPU_DATA0);
170 		adev->vcn.internal.data1 = mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET;
171 		adev->vcn.inst[j].external.data1 = SOC15_REG_OFFSET(UVD, j, mmUVD_GPCOM_VCPU_DATA1);
172 		adev->vcn.internal.cmd = mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET;
173 		adev->vcn.inst[j].external.cmd = SOC15_REG_OFFSET(UVD, j, mmUVD_GPCOM_VCPU_CMD);
174 		adev->vcn.internal.nop = mmUVD_NO_OP_INTERNAL_OFFSET;
175 		adev->vcn.inst[j].external.nop = SOC15_REG_OFFSET(UVD, j, mmUVD_NO_OP);
176 
177 		ring = &adev->vcn.inst[j].ring_dec;
178 		ring->use_doorbell = true;
179 		ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8*j;
180 		sprintf(ring->name, "vcn_dec_%d", j);
181 		r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq, 0);
182 		if (r)
183 			return r;
184 
185 		for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
186 			ring = &adev->vcn.inst[j].ring_enc[i];
187 			ring->use_doorbell = true;
188 			ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 2 + i + 8*j;
189 			sprintf(ring->name, "vcn_enc_%d.%d", j, i);
190 			r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq, 0);
191 			if (r)
192 				return r;
193 		}
194 	}
195 
196 	return 0;
197 }
198 
199 /**
200  * vcn_v2_5_sw_fini - sw fini for VCN block
201  *
202  * @handle: amdgpu_device pointer
203  *
204  * VCN suspend and free up sw allocation
205  */
206 static int vcn_v2_5_sw_fini(void *handle)
207 {
208 	int r;
209 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
210 
211 	r = amdgpu_vcn_suspend(adev);
212 	if (r)
213 		return r;
214 
215 	r = amdgpu_vcn_sw_fini(adev);
216 
217 	return r;
218 }
219 
220 /**
221  * vcn_v2_5_hw_init - start and test VCN block
222  *
223  * @handle: amdgpu_device pointer
224  *
225  * Initialize the hardware, boot up the VCPU and do some testing
226  */
227 static int vcn_v2_5_hw_init(void *handle)
228 {
229 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
230 	struct amdgpu_ring *ring;
231 	int i, j, r;
232 
233 	for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
234 		if (adev->vcn.harvest_config & (1 << j))
235 			continue;
236 		ring = &adev->vcn.inst[j].ring_dec;
237 
238 		adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
239 						     ring->doorbell_index, j);
240 
241 		r = amdgpu_ring_test_helper(ring);
242 		if (r)
243 			goto done;
244 
245 		for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
246 			ring = &adev->vcn.inst[j].ring_enc[i];
247 			r = amdgpu_ring_test_helper(ring);
248 			if (r)
249 				goto done;
250 		}
251 	}
252 
253 done:
254 	if (!r)
255 		DRM_INFO("VCN decode and encode initialized successfully.\n");
256 
257 	return r;
258 }
259 
260 /**
261  * vcn_v2_5_hw_fini - stop the hardware block
262  *
263  * @handle: amdgpu_device pointer
264  *
265  * Stop the VCN block, mark ring as not ready any more
266  */
267 static int vcn_v2_5_hw_fini(void *handle)
268 {
269 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
270 	struct amdgpu_ring *ring;
271 	int i, j;
272 
273 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
274 		if (adev->vcn.harvest_config & (1 << i))
275 			continue;
276 		ring = &adev->vcn.inst[i].ring_dec;
277 
278 		if (RREG32_SOC15(VCN, i, mmUVD_STATUS))
279 			vcn_v2_5_set_powergating_state(adev, AMD_PG_STATE_GATE);
280 
281 		ring->sched.ready = false;
282 
283 		for (j = 0; j < adev->vcn.num_enc_rings; ++j) {
284 			ring = &adev->vcn.inst[i].ring_enc[j];
285 			ring->sched.ready = false;
286 		}
287 	}
288 
289 	return 0;
290 }
291 
292 /**
293  * vcn_v2_5_suspend - suspend VCN block
294  *
295  * @handle: amdgpu_device pointer
296  *
297  * HW fini and suspend VCN block
298  */
299 static int vcn_v2_5_suspend(void *handle)
300 {
301 	int r;
302 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
303 
304 	r = vcn_v2_5_hw_fini(adev);
305 	if (r)
306 		return r;
307 
308 	r = amdgpu_vcn_suspend(adev);
309 
310 	return r;
311 }
312 
313 /**
314  * vcn_v2_5_resume - resume VCN block
315  *
316  * @handle: amdgpu_device pointer
317  *
318  * Resume firmware and hw init VCN block
319  */
320 static int vcn_v2_5_resume(void *handle)
321 {
322 	int r;
323 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
324 
325 	r = amdgpu_vcn_resume(adev);
326 	if (r)
327 		return r;
328 
329 	r = vcn_v2_5_hw_init(adev);
330 
331 	return r;
332 }
333 
334 /**
335  * vcn_v2_5_mc_resume - memory controller programming
336  *
337  * @adev: amdgpu_device pointer
338  *
339  * Let the VCN memory controller know it's offsets
340  */
341 static void vcn_v2_5_mc_resume(struct amdgpu_device *adev)
342 {
343 	uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
344 	uint32_t offset;
345 	int i;
346 
347 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
348 		if (adev->vcn.harvest_config & (1 << i))
349 			continue;
350 		/* cache window 0: fw */
351 		if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
352 			WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
353 				(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_lo));
354 			WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
355 				(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN].tmr_mc_addr_hi));
356 			WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET0, 0);
357 			offset = 0;
358 		} else {
359 			WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
360 				lower_32_bits(adev->vcn.inst[i].gpu_addr));
361 			WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
362 				upper_32_bits(adev->vcn.inst[i].gpu_addr));
363 			offset = size;
364 			WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET0,
365 				AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
366 		}
367 		WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE0, size);
368 
369 		/* cache window 1: stack */
370 		WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
371 			lower_32_bits(adev->vcn.inst[i].gpu_addr + offset));
372 		WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
373 			upper_32_bits(adev->vcn.inst[i].gpu_addr + offset));
374 		WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET1, 0);
375 		WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE);
376 
377 		/* cache window 2: context */
378 		WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
379 			lower_32_bits(adev->vcn.inst[i].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
380 		WREG32_SOC15(UVD, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
381 			upper_32_bits(adev->vcn.inst[i].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
382 		WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_OFFSET2, 0);
383 		WREG32_SOC15(UVD, i, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);
384 	}
385 }
386 
387 /**
388  * vcn_v2_5_disable_clock_gating - disable VCN clock gating
389  *
390  * @adev: amdgpu_device pointer
391  *
392  * Disable clock gating for VCN block
393  */
394 static void vcn_v2_5_disable_clock_gating(struct amdgpu_device *adev)
395 {
396 	uint32_t data;
397 	int ret = 0;
398 	int i;
399 
400 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
401 		if (adev->vcn.harvest_config & (1 << i))
402 			continue;
403 		/* UVD disable CGC */
404 		data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
405 		if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
406 			data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
407 		else
408 			data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
409 		data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
410 		data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
411 		WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
412 
413 		data = RREG32_SOC15(VCN, i, mmUVD_CGC_GATE);
414 		data &= ~(UVD_CGC_GATE__SYS_MASK
415 			| UVD_CGC_GATE__UDEC_MASK
416 			| UVD_CGC_GATE__MPEG2_MASK
417 			| UVD_CGC_GATE__REGS_MASK
418 			| UVD_CGC_GATE__RBC_MASK
419 			| UVD_CGC_GATE__LMI_MC_MASK
420 			| UVD_CGC_GATE__LMI_UMC_MASK
421 			| UVD_CGC_GATE__IDCT_MASK
422 			| UVD_CGC_GATE__MPRD_MASK
423 			| UVD_CGC_GATE__MPC_MASK
424 			| UVD_CGC_GATE__LBSI_MASK
425 			| UVD_CGC_GATE__LRBBM_MASK
426 			| UVD_CGC_GATE__UDEC_RE_MASK
427 			| UVD_CGC_GATE__UDEC_CM_MASK
428 			| UVD_CGC_GATE__UDEC_IT_MASK
429 			| UVD_CGC_GATE__UDEC_DB_MASK
430 			| UVD_CGC_GATE__UDEC_MP_MASK
431 			| UVD_CGC_GATE__WCB_MASK
432 			| UVD_CGC_GATE__VCPU_MASK
433 			| UVD_CGC_GATE__MMSCH_MASK);
434 
435 		WREG32_SOC15(VCN, i, mmUVD_CGC_GATE, data);
436 
437 		SOC15_WAIT_ON_RREG(VCN, i, mmUVD_CGC_GATE, 0,  0xFFFFFFFF, ret);
438 
439 		data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
440 		data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK
441 			| UVD_CGC_CTRL__UDEC_CM_MODE_MASK
442 			| UVD_CGC_CTRL__UDEC_IT_MODE_MASK
443 			| UVD_CGC_CTRL__UDEC_DB_MODE_MASK
444 			| UVD_CGC_CTRL__UDEC_MP_MODE_MASK
445 			| UVD_CGC_CTRL__SYS_MODE_MASK
446 			| UVD_CGC_CTRL__UDEC_MODE_MASK
447 			| UVD_CGC_CTRL__MPEG2_MODE_MASK
448 			| UVD_CGC_CTRL__REGS_MODE_MASK
449 			| UVD_CGC_CTRL__RBC_MODE_MASK
450 			| UVD_CGC_CTRL__LMI_MC_MODE_MASK
451 			| UVD_CGC_CTRL__LMI_UMC_MODE_MASK
452 			| UVD_CGC_CTRL__IDCT_MODE_MASK
453 			| UVD_CGC_CTRL__MPRD_MODE_MASK
454 			| UVD_CGC_CTRL__MPC_MODE_MASK
455 			| UVD_CGC_CTRL__LBSI_MODE_MASK
456 			| UVD_CGC_CTRL__LRBBM_MODE_MASK
457 			| UVD_CGC_CTRL__WCB_MODE_MASK
458 			| UVD_CGC_CTRL__VCPU_MODE_MASK
459 			| UVD_CGC_CTRL__MMSCH_MODE_MASK);
460 		WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
461 
462 		/* turn on */
463 		data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_GATE);
464 		data |= (UVD_SUVD_CGC_GATE__SRE_MASK
465 			| UVD_SUVD_CGC_GATE__SIT_MASK
466 			| UVD_SUVD_CGC_GATE__SMP_MASK
467 			| UVD_SUVD_CGC_GATE__SCM_MASK
468 			| UVD_SUVD_CGC_GATE__SDB_MASK
469 			| UVD_SUVD_CGC_GATE__SRE_H264_MASK
470 			| UVD_SUVD_CGC_GATE__SRE_HEVC_MASK
471 			| UVD_SUVD_CGC_GATE__SIT_H264_MASK
472 			| UVD_SUVD_CGC_GATE__SIT_HEVC_MASK
473 			| UVD_SUVD_CGC_GATE__SCM_H264_MASK
474 			| UVD_SUVD_CGC_GATE__SCM_HEVC_MASK
475 			| UVD_SUVD_CGC_GATE__SDB_H264_MASK
476 			| UVD_SUVD_CGC_GATE__SDB_HEVC_MASK
477 			| UVD_SUVD_CGC_GATE__SCLR_MASK
478 			| UVD_SUVD_CGC_GATE__UVD_SC_MASK
479 			| UVD_SUVD_CGC_GATE__ENT_MASK
480 			| UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK
481 			| UVD_SUVD_CGC_GATE__SIT_HEVC_ENC_MASK
482 			| UVD_SUVD_CGC_GATE__SITE_MASK
483 			| UVD_SUVD_CGC_GATE__SRE_VP9_MASK
484 			| UVD_SUVD_CGC_GATE__SCM_VP9_MASK
485 			| UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK
486 			| UVD_SUVD_CGC_GATE__SDB_VP9_MASK
487 			| UVD_SUVD_CGC_GATE__IME_HEVC_MASK);
488 		WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_GATE, data);
489 
490 		data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL);
491 		data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
492 			| UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
493 			| UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
494 			| UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
495 			| UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
496 			| UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
497 			| UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
498 			| UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
499 			| UVD_SUVD_CGC_CTRL__IME_MODE_MASK
500 			| UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
501 		WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL, data);
502 	}
503 }
504 
505 /**
506  * vcn_v2_5_enable_clock_gating - enable VCN clock gating
507  *
508  * @adev: amdgpu_device pointer
509  *
510  * Enable clock gating for VCN block
511  */
512 static void vcn_v2_5_enable_clock_gating(struct amdgpu_device *adev)
513 {
514 	uint32_t data = 0;
515 	int i;
516 
517 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
518 		if (adev->vcn.harvest_config & (1 << i))
519 			continue;
520 		/* enable UVD CGC */
521 		data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
522 		if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
523 			data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
524 		else
525 			data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
526 		data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
527 		data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
528 		WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
529 
530 		data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
531 		data |= (UVD_CGC_CTRL__UDEC_RE_MODE_MASK
532 			| UVD_CGC_CTRL__UDEC_CM_MODE_MASK
533 			| UVD_CGC_CTRL__UDEC_IT_MODE_MASK
534 			| UVD_CGC_CTRL__UDEC_DB_MODE_MASK
535 			| UVD_CGC_CTRL__UDEC_MP_MODE_MASK
536 			| UVD_CGC_CTRL__SYS_MODE_MASK
537 			| UVD_CGC_CTRL__UDEC_MODE_MASK
538 			| UVD_CGC_CTRL__MPEG2_MODE_MASK
539 			| UVD_CGC_CTRL__REGS_MODE_MASK
540 			| UVD_CGC_CTRL__RBC_MODE_MASK
541 			| UVD_CGC_CTRL__LMI_MC_MODE_MASK
542 			| UVD_CGC_CTRL__LMI_UMC_MODE_MASK
543 			| UVD_CGC_CTRL__IDCT_MODE_MASK
544 			| UVD_CGC_CTRL__MPRD_MODE_MASK
545 			| UVD_CGC_CTRL__MPC_MODE_MASK
546 			| UVD_CGC_CTRL__LBSI_MODE_MASK
547 			| UVD_CGC_CTRL__LRBBM_MODE_MASK
548 			| UVD_CGC_CTRL__WCB_MODE_MASK
549 			| UVD_CGC_CTRL__VCPU_MODE_MASK);
550 		WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
551 
552 		data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL);
553 		data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
554 			| UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
555 			| UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
556 			| UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
557 			| UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
558 			| UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
559 			| UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
560 			| UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
561 			| UVD_SUVD_CGC_CTRL__IME_MODE_MASK
562 			| UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
563 		WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL, data);
564 	}
565 }
566 
567 static int vcn_v2_5_start(struct amdgpu_device *adev)
568 {
569 	struct amdgpu_ring *ring;
570 	uint32_t rb_bufsz, tmp;
571 	int i, j, k, r;
572 
573 	if (adev->pm.dpm_enabled)
574 		amdgpu_dpm_enable_uvd(adev, true);
575 
576 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
577 		if (adev->vcn.harvest_config & (1 << i))
578 			continue;
579 		/* disable register anti-hang mechanism */
580 		WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_POWER_STATUS), 0,
581 			~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
582 
583 		/* set uvd status busy */
584 		tmp = RREG32_SOC15(UVD, i, mmUVD_STATUS) | UVD_STATUS__UVD_BUSY;
585 		WREG32_SOC15(UVD, i, mmUVD_STATUS, tmp);
586 	}
587 
588 	/*SW clock gating */
589 	vcn_v2_5_disable_clock_gating(adev);
590 
591 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
592 		if (adev->vcn.harvest_config & (1 << i))
593 			continue;
594 		/* enable VCPU clock */
595 		WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL),
596 			UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK);
597 
598 		/* disable master interrupt */
599 		WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_MASTINT_EN), 0,
600 			~UVD_MASTINT_EN__VCPU_EN_MASK);
601 
602 		/* setup mmUVD_LMI_CTRL */
603 		tmp = RREG32_SOC15(UVD, i, mmUVD_LMI_CTRL);
604 		tmp &= ~0xff;
605 		WREG32_SOC15(UVD, i, mmUVD_LMI_CTRL, tmp | 0x8|
606 			UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK	|
607 			UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
608 			UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
609 			UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
610 
611 		/* setup mmUVD_MPC_CNTL */
612 		tmp = RREG32_SOC15(UVD, i, mmUVD_MPC_CNTL);
613 		tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;
614 		tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;
615 		WREG32_SOC15(VCN, i, mmUVD_MPC_CNTL, tmp);
616 
617 		/* setup UVD_MPC_SET_MUXA0 */
618 		WREG32_SOC15(UVD, i, mmUVD_MPC_SET_MUXA0,
619 			((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
620 			(0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
621 			(0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
622 			(0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));
623 
624 		/* setup UVD_MPC_SET_MUXB0 */
625 		WREG32_SOC15(UVD, i, mmUVD_MPC_SET_MUXB0,
626 			((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
627 			(0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
628 			(0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
629 			(0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));
630 
631 		/* setup mmUVD_MPC_SET_MUX */
632 		WREG32_SOC15(UVD, i, mmUVD_MPC_SET_MUX,
633 			((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
634 			(0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
635 			(0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));
636 	}
637 
638 	vcn_v2_5_mc_resume(adev);
639 
640 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
641 		if (adev->vcn.harvest_config & (1 << i))
642 			continue;
643 		/* VCN global tiling registers */
644 		WREG32_SOC15(UVD, i, mmUVD_GFX8_ADDR_CONFIG,
645 			adev->gfx.config.gb_addr_config);
646 		WREG32_SOC15(UVD, i, mmUVD_GFX8_ADDR_CONFIG,
647 			adev->gfx.config.gb_addr_config);
648 
649 		/* enable LMI MC and UMC channels */
650 		WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_LMI_CTRL2), 0,
651 			~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
652 
653 		/* unblock VCPU register access */
654 		WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_ARB_CTRL), 0,
655 			~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
656 
657 		WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL), 0,
658 			~UVD_VCPU_CNTL__BLK_RST_MASK);
659 
660 		for (k = 0; k < 10; ++k) {
661 			uint32_t status;
662 
663 			for (j = 0; j < 100; ++j) {
664 				status = RREG32_SOC15(UVD, i, mmUVD_STATUS);
665 				if (status & 2)
666 					break;
667 				if (amdgpu_emu_mode == 1)
668 					msleep(500);
669 				else
670 					mdelay(10);
671 			}
672 			r = 0;
673 			if (status & 2)
674 				break;
675 
676 			DRM_ERROR("VCN decode not responding, trying to reset the VCPU!!!\n");
677 			WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL),
678 				UVD_VCPU_CNTL__BLK_RST_MASK,
679 				~UVD_VCPU_CNTL__BLK_RST_MASK);
680 			mdelay(10);
681 			WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL), 0,
682 				~UVD_VCPU_CNTL__BLK_RST_MASK);
683 
684 			mdelay(10);
685 			r = -1;
686 		}
687 
688 		if (r) {
689 			DRM_ERROR("VCN decode not responding, giving up!!!\n");
690 			return r;
691 		}
692 
693 		/* enable master interrupt */
694 		WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_MASTINT_EN),
695 			UVD_MASTINT_EN__VCPU_EN_MASK,
696 			~UVD_MASTINT_EN__VCPU_EN_MASK);
697 
698 		/* clear the busy bit of VCN_STATUS */
699 		WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_STATUS), 0,
700 			~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
701 
702 		WREG32_SOC15(UVD, i, mmUVD_LMI_RBC_RB_VMID, 0);
703 
704 		ring = &adev->vcn.inst[i].ring_dec;
705 		/* force RBC into idle state */
706 		rb_bufsz = order_base_2(ring->ring_size);
707 		tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
708 		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
709 		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
710 		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
711 		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
712 		WREG32_SOC15(UVD, i, mmUVD_RBC_RB_CNTL, tmp);
713 
714 		/* programm the RB_BASE for ring buffer */
715 		WREG32_SOC15(UVD, i, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
716 			lower_32_bits(ring->gpu_addr));
717 		WREG32_SOC15(UVD, i, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
718 			upper_32_bits(ring->gpu_addr));
719 
720 		/* Initialize the ring buffer's read and write pointers */
721 		WREG32_SOC15(UVD, i, mmUVD_RBC_RB_RPTR, 0);
722 
723 		ring->wptr = RREG32_SOC15(UVD, i, mmUVD_RBC_RB_RPTR);
724 		WREG32_SOC15(UVD, i, mmUVD_RBC_RB_WPTR,
725 				lower_32_bits(ring->wptr));
726 		ring = &adev->vcn.inst[i].ring_enc[0];
727 		WREG32_SOC15(UVD, i, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
728 		WREG32_SOC15(UVD, i, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
729 		WREG32_SOC15(UVD, i, mmUVD_RB_BASE_LO, ring->gpu_addr);
730 		WREG32_SOC15(UVD, i, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
731 		WREG32_SOC15(UVD, i, mmUVD_RB_SIZE, ring->ring_size / 4);
732 
733 		ring = &adev->vcn.inst[i].ring_enc[1];
734 		WREG32_SOC15(UVD, i, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
735 		WREG32_SOC15(UVD, i, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
736 		WREG32_SOC15(UVD, i, mmUVD_RB_BASE_LO2, ring->gpu_addr);
737 		WREG32_SOC15(UVD, i, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
738 		WREG32_SOC15(UVD, i, mmUVD_RB_SIZE2, ring->ring_size / 4);
739 	}
740 
741 	return 0;
742 }
743 
744 static int vcn_v2_5_stop(struct amdgpu_device *adev)
745 {
746 	uint32_t tmp;
747 	int i, r = 0;
748 
749 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
750 		if (adev->vcn.harvest_config & (1 << i))
751 			continue;
752 		/* wait for vcn idle */
753 		SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7, r);
754 		if (r)
755 			return r;
756 
757 		tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
758 			UVD_LMI_STATUS__READ_CLEAN_MASK |
759 			UVD_LMI_STATUS__WRITE_CLEAN_MASK |
760 			UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
761 		SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp, r);
762 		if (r)
763 			return r;
764 
765 		/* block LMI UMC channel */
766 		tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2);
767 		tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK;
768 		WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2, tmp);
769 
770 		tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK|
771 			UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
772 		SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp, r);
773 		if (r)
774 			return r;
775 
776 		/* block VCPU register access */
777 		WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_RB_ARB_CTRL),
778 			UVD_RB_ARB_CTRL__VCPU_DIS_MASK,
779 			~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
780 
781 		/* reset VCPU */
782 		WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL),
783 			UVD_VCPU_CNTL__BLK_RST_MASK,
784 			~UVD_VCPU_CNTL__BLK_RST_MASK);
785 
786 		/* disable VCPU clock */
787 		WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_VCPU_CNTL), 0,
788 			~(UVD_VCPU_CNTL__CLK_EN_MASK));
789 
790 		/* clear status */
791 		WREG32_SOC15(VCN, i, mmUVD_STATUS, 0);
792 
793 		vcn_v2_5_enable_clock_gating(adev);
794 
795 		/* enable register anti-hang mechanism */
796 		WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_POWER_STATUS),
797 			UVD_POWER_STATUS__UVD_POWER_STATUS_MASK,
798 			~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
799 	}
800 
801 	if (adev->pm.dpm_enabled)
802 		amdgpu_dpm_enable_uvd(adev, false);
803 
804 	return 0;
805 }
806 
807 /**
808  * vcn_v2_5_dec_ring_get_rptr - get read pointer
809  *
810  * @ring: amdgpu_ring pointer
811  *
812  * Returns the current hardware read pointer
813  */
814 static uint64_t vcn_v2_5_dec_ring_get_rptr(struct amdgpu_ring *ring)
815 {
816 	struct amdgpu_device *adev = ring->adev;
817 
818 	return RREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_RPTR);
819 }
820 
821 /**
822  * vcn_v2_5_dec_ring_get_wptr - get write pointer
823  *
824  * @ring: amdgpu_ring pointer
825  *
826  * Returns the current hardware write pointer
827  */
828 static uint64_t vcn_v2_5_dec_ring_get_wptr(struct amdgpu_ring *ring)
829 {
830 	struct amdgpu_device *adev = ring->adev;
831 
832 	if (ring->use_doorbell)
833 		return adev->wb.wb[ring->wptr_offs];
834 	else
835 		return RREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_WPTR);
836 }
837 
838 /**
839  * vcn_v2_5_dec_ring_set_wptr - set write pointer
840  *
841  * @ring: amdgpu_ring pointer
842  *
843  * Commits the write pointer to the hardware
844  */
845 static void vcn_v2_5_dec_ring_set_wptr(struct amdgpu_ring *ring)
846 {
847 	struct amdgpu_device *adev = ring->adev;
848 
849 	if (ring->use_doorbell) {
850 		adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
851 		WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
852 	} else {
853 		WREG32_SOC15(UVD, ring->me, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));
854 	}
855 }
856 
857 static const struct amdgpu_ring_funcs vcn_v2_5_dec_ring_vm_funcs = {
858 	.type = AMDGPU_RING_TYPE_VCN_DEC,
859 	.align_mask = 0xf,
860 	.vmhub = AMDGPU_MMHUB_1,
861 	.get_rptr = vcn_v2_5_dec_ring_get_rptr,
862 	.get_wptr = vcn_v2_5_dec_ring_get_wptr,
863 	.set_wptr = vcn_v2_5_dec_ring_set_wptr,
864 	.emit_frame_size =
865 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
866 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
867 		8 + /* vcn_v2_0_dec_ring_emit_vm_flush */
868 		14 + 14 + /* vcn_v2_0_dec_ring_emit_fence x2 vm fence */
869 		6,
870 	.emit_ib_size = 8, /* vcn_v2_0_dec_ring_emit_ib */
871 	.emit_ib = vcn_v2_0_dec_ring_emit_ib,
872 	.emit_fence = vcn_v2_0_dec_ring_emit_fence,
873 	.emit_vm_flush = vcn_v2_0_dec_ring_emit_vm_flush,
874 	.test_ring = amdgpu_vcn_dec_ring_test_ring,
875 	.test_ib = amdgpu_vcn_dec_ring_test_ib,
876 	.insert_nop = vcn_v2_0_dec_ring_insert_nop,
877 	.insert_start = vcn_v2_0_dec_ring_insert_start,
878 	.insert_end = vcn_v2_0_dec_ring_insert_end,
879 	.pad_ib = amdgpu_ring_generic_pad_ib,
880 	.begin_use = amdgpu_vcn_ring_begin_use,
881 	.end_use = amdgpu_vcn_ring_end_use,
882 	.emit_wreg = vcn_v2_0_dec_ring_emit_wreg,
883 	.emit_reg_wait = vcn_v2_0_dec_ring_emit_reg_wait,
884 	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
885 };
886 
887 /**
888  * vcn_v2_5_enc_ring_get_rptr - get enc read pointer
889  *
890  * @ring: amdgpu_ring pointer
891  *
892  * Returns the current hardware enc read pointer
893  */
894 static uint64_t vcn_v2_5_enc_ring_get_rptr(struct amdgpu_ring *ring)
895 {
896 	struct amdgpu_device *adev = ring->adev;
897 
898 	if (ring == &adev->vcn.inst[ring->me].ring_enc[0])
899 		return RREG32_SOC15(UVD, ring->me, mmUVD_RB_RPTR);
900 	else
901 		return RREG32_SOC15(UVD, ring->me, mmUVD_RB_RPTR2);
902 }
903 
904 /**
905  * vcn_v2_5_enc_ring_get_wptr - get enc write pointer
906  *
907  * @ring: amdgpu_ring pointer
908  *
909  * Returns the current hardware enc write pointer
910  */
911 static uint64_t vcn_v2_5_enc_ring_get_wptr(struct amdgpu_ring *ring)
912 {
913 	struct amdgpu_device *adev = ring->adev;
914 
915 	if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
916 		if (ring->use_doorbell)
917 			return adev->wb.wb[ring->wptr_offs];
918 		else
919 			return RREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR);
920 	} else {
921 		if (ring->use_doorbell)
922 			return adev->wb.wb[ring->wptr_offs];
923 		else
924 			return RREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR2);
925 	}
926 }
927 
928 /**
929  * vcn_v2_5_enc_ring_set_wptr - set enc write pointer
930  *
931  * @ring: amdgpu_ring pointer
932  *
933  * Commits the enc write pointer to the hardware
934  */
935 static void vcn_v2_5_enc_ring_set_wptr(struct amdgpu_ring *ring)
936 {
937 	struct amdgpu_device *adev = ring->adev;
938 
939 	if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
940 		if (ring->use_doorbell) {
941 			adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
942 			WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
943 		} else {
944 			WREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
945 		}
946 	} else {
947 		if (ring->use_doorbell) {
948 			adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
949 			WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
950 		} else {
951 			WREG32_SOC15(UVD, ring->me, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
952 		}
953 	}
954 }
955 
956 static const struct amdgpu_ring_funcs vcn_v2_5_enc_ring_vm_funcs = {
957 	.type = AMDGPU_RING_TYPE_VCN_ENC,
958 	.align_mask = 0x3f,
959 	.nop = VCN_ENC_CMD_NO_OP,
960 	.vmhub = AMDGPU_MMHUB_1,
961 	.get_rptr = vcn_v2_5_enc_ring_get_rptr,
962 	.get_wptr = vcn_v2_5_enc_ring_get_wptr,
963 	.set_wptr = vcn_v2_5_enc_ring_set_wptr,
964 	.emit_frame_size =
965 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
966 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
967 		4 + /* vcn_v2_0_enc_ring_emit_vm_flush */
968 		5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */
969 		1, /* vcn_v2_0_enc_ring_insert_end */
970 	.emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */
971 	.emit_ib = vcn_v2_0_enc_ring_emit_ib,
972 	.emit_fence = vcn_v2_0_enc_ring_emit_fence,
973 	.emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush,
974 	.test_ring = amdgpu_vcn_enc_ring_test_ring,
975 	.test_ib = amdgpu_vcn_enc_ring_test_ib,
976 	.insert_nop = amdgpu_ring_insert_nop,
977 	.insert_end = vcn_v2_0_enc_ring_insert_end,
978 	.pad_ib = amdgpu_ring_generic_pad_ib,
979 	.begin_use = amdgpu_vcn_ring_begin_use,
980 	.end_use = amdgpu_vcn_ring_end_use,
981 	.emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
982 	.emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
983 	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
984 };
985 
986 static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev)
987 {
988 	int i;
989 
990 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
991 		if (adev->vcn.harvest_config & (1 << i))
992 			continue;
993 		adev->vcn.inst[i].ring_dec.funcs = &vcn_v2_5_dec_ring_vm_funcs;
994 		adev->vcn.inst[i].ring_dec.me = i;
995 		DRM_INFO("VCN(%d) decode is enabled in VM mode\n", i);
996 	}
997 }
998 
999 static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev)
1000 {
1001 	int i, j;
1002 
1003 	for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
1004 		if (adev->vcn.harvest_config & (1 << j))
1005 			continue;
1006 		for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
1007 			adev->vcn.inst[j].ring_enc[i].funcs = &vcn_v2_5_enc_ring_vm_funcs;
1008 			adev->vcn.inst[j].ring_enc[i].me = j;
1009 		}
1010 		DRM_INFO("VCN(%d) encode is enabled in VM mode\n", j);
1011 	}
1012 }
1013 
1014 static bool vcn_v2_5_is_idle(void *handle)
1015 {
1016 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1017 	int i, ret = 1;
1018 
1019 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1020 		if (adev->vcn.harvest_config & (1 << i))
1021 			continue;
1022 		ret &= (RREG32_SOC15(VCN, i, mmUVD_STATUS) == UVD_STATUS__IDLE);
1023 	}
1024 
1025 	return ret;
1026 }
1027 
1028 static int vcn_v2_5_wait_for_idle(void *handle)
1029 {
1030 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1031 	int i, ret = 0;
1032 
1033 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1034 		if (adev->vcn.harvest_config & (1 << i))
1035 			continue;
1036 		SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE,
1037 			UVD_STATUS__IDLE, ret);
1038 		if (ret)
1039 			return ret;
1040 	}
1041 
1042 	return ret;
1043 }
1044 
1045 static int vcn_v2_5_set_clockgating_state(void *handle,
1046 					  enum amd_clockgating_state state)
1047 {
1048 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1049 	bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
1050 
1051 	if (enable) {
1052 		if (vcn_v2_5_is_idle(handle))
1053 			return -EBUSY;
1054 		vcn_v2_5_enable_clock_gating(adev);
1055 	} else {
1056 		vcn_v2_5_disable_clock_gating(adev);
1057 	}
1058 
1059 	return 0;
1060 }
1061 
1062 static int vcn_v2_5_set_powergating_state(void *handle,
1063 					  enum amd_powergating_state state)
1064 {
1065 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1066 	int ret;
1067 
1068 	if(state == adev->vcn.cur_state)
1069 		return 0;
1070 
1071 	if (state == AMD_PG_STATE_GATE)
1072 		ret = vcn_v2_5_stop(adev);
1073 	else
1074 		ret = vcn_v2_5_start(adev);
1075 
1076 	if(!ret)
1077 		adev->vcn.cur_state = state;
1078 
1079 	return ret;
1080 }
1081 
1082 static int vcn_v2_5_set_interrupt_state(struct amdgpu_device *adev,
1083 					struct amdgpu_irq_src *source,
1084 					unsigned type,
1085 					enum amdgpu_interrupt_state state)
1086 {
1087 	return 0;
1088 }
1089 
1090 static int vcn_v2_5_process_interrupt(struct amdgpu_device *adev,
1091 				      struct amdgpu_irq_src *source,
1092 				      struct amdgpu_iv_entry *entry)
1093 {
1094 	uint32_t ip_instance;
1095 
1096 	switch (entry->client_id) {
1097 	case SOC15_IH_CLIENTID_VCN:
1098 		ip_instance = 0;
1099 		break;
1100 	case SOC15_IH_CLIENTID_VCN1:
1101 		ip_instance = 1;
1102 		break;
1103 	default:
1104 		DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
1105 		return 0;
1106 	}
1107 
1108 	DRM_DEBUG("IH: VCN TRAP\n");
1109 
1110 	switch (entry->src_id) {
1111 	case VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT:
1112 		amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_dec);
1113 		break;
1114 	case VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
1115 		amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[0]);
1116 		break;
1117 	case VCN_2_0__SRCID__UVD_ENC_LOW_LATENCY:
1118 		amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[1]);
1119 		break;
1120 	default:
1121 		DRM_ERROR("Unhandled interrupt: %d %d\n",
1122 			  entry->src_id, entry->src_data[0]);
1123 		break;
1124 	}
1125 
1126 	return 0;
1127 }
1128 
1129 static const struct amdgpu_irq_src_funcs vcn_v2_5_irq_funcs = {
1130 	.set = vcn_v2_5_set_interrupt_state,
1131 	.process = vcn_v2_5_process_interrupt,
1132 };
1133 
1134 static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev)
1135 {
1136 	int i;
1137 
1138 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1139 		if (adev->vcn.harvest_config & (1 << i))
1140 			continue;
1141 		adev->vcn.inst[i].irq.num_types = adev->vcn.num_enc_rings + 2;
1142 		adev->vcn.inst[i].irq.funcs = &vcn_v2_5_irq_funcs;
1143 	}
1144 }
1145 
1146 static const struct amd_ip_funcs vcn_v2_5_ip_funcs = {
1147 	.name = "vcn_v2_5",
1148 	.early_init = vcn_v2_5_early_init,
1149 	.late_init = NULL,
1150 	.sw_init = vcn_v2_5_sw_init,
1151 	.sw_fini = vcn_v2_5_sw_fini,
1152 	.hw_init = vcn_v2_5_hw_init,
1153 	.hw_fini = vcn_v2_5_hw_fini,
1154 	.suspend = vcn_v2_5_suspend,
1155 	.resume = vcn_v2_5_resume,
1156 	.is_idle = vcn_v2_5_is_idle,
1157 	.wait_for_idle = vcn_v2_5_wait_for_idle,
1158 	.check_soft_reset = NULL,
1159 	.pre_soft_reset = NULL,
1160 	.soft_reset = NULL,
1161 	.post_soft_reset = NULL,
1162 	.set_clockgating_state = vcn_v2_5_set_clockgating_state,
1163 	.set_powergating_state = vcn_v2_5_set_powergating_state,
1164 };
1165 
1166 const struct amdgpu_ip_block_version vcn_v2_5_ip_block =
1167 {
1168 		.type = AMD_IP_BLOCK_TYPE_VCN,
1169 		.major = 2,
1170 		.minor = 5,
1171 		.rev = 0,
1172 		.funcs = &vcn_v2_5_ip_funcs,
1173 };
1174