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