xref: /linux/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c (revision 2c142b63c8ee982cdfdba49a616027c266294838)
1 /*
2  * Copyright 2013 Advanced Micro Devices, Inc.
3  * All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the
7  * "Software"), to deal in the Software without restriction, including
8  * without limitation the rights to use, copy, modify, merge, publish,
9  * distribute, sub license, and/or sell copies of the Software, and to
10  * permit persons to whom the Software is furnished to do so, subject to
11  * the following conditions:
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
16  * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
17  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19  * USE OR OTHER DEALINGS IN THE SOFTWARE.
20  *
21  * The above copyright notice and this permission notice (including the
22  * next paragraph) shall be included in all copies or substantial portions
23  * of the Software.
24  *
25  * Authors: Christian König <christian.koenig@amd.com>
26  */
27 
28 #include <linux/firmware.h>
29 
30 #include "amdgpu.h"
31 #include "amdgpu_vce.h"
32 #include "cikd.h"
33 #include "vce/vce_2_0_d.h"
34 #include "vce/vce_2_0_sh_mask.h"
35 #include "smu/smu_7_0_1_d.h"
36 #include "smu/smu_7_0_1_sh_mask.h"
37 #include "oss/oss_2_0_d.h"
38 #include "oss/oss_2_0_sh_mask.h"
39 
40 
41 /* Use 24K to be safe. The FW supposedly only requires 23744 bytes. */
42 #define VCE_V2_0_DATA_ENTRY_SIZE (24 * 1024)
43 
44 #define VCE_V2_0_FW_SIZE	(256 * 1024)
45 #define VCE_V2_0_STACK_SIZE	(64 * 1024)
46 #define VCE_V2_0_DATA_SIZE	(VCE_V2_0_DATA_ENTRY_SIZE * (AMDGPU_MAX_VCE_HANDLES + 1))
47 
48 #define VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK	0x02
49 
50 static void vce_v2_0_set_ring_funcs(struct amdgpu_device *adev);
51 static void vce_v2_0_set_irq_funcs(struct amdgpu_device *adev);
52 
53 /**
54  * vce_v2_0_ring_get_rptr - get read pointer
55  *
56  * @ring: amdgpu_ring pointer
57  *
58  * Returns the current hardware read pointer
59  */
vce_v2_0_ring_get_rptr(struct amdgpu_ring * ring)60 static uint64_t vce_v2_0_ring_get_rptr(struct amdgpu_ring *ring)
61 {
62 	struct amdgpu_device *adev = ring->adev;
63 
64 	if (ring->me == 0)
65 		return RREG32(mmVCE_RB_RPTR);
66 	else
67 		return RREG32(mmVCE_RB_RPTR2);
68 }
69 
70 /**
71  * vce_v2_0_ring_get_wptr - get write pointer
72  *
73  * @ring: amdgpu_ring pointer
74  *
75  * Returns the current hardware write pointer
76  */
vce_v2_0_ring_get_wptr(struct amdgpu_ring * ring)77 static uint64_t vce_v2_0_ring_get_wptr(struct amdgpu_ring *ring)
78 {
79 	struct amdgpu_device *adev = ring->adev;
80 
81 	if (ring->me == 0)
82 		return RREG32(mmVCE_RB_WPTR);
83 	else
84 		return RREG32(mmVCE_RB_WPTR2);
85 }
86 
87 /**
88  * vce_v2_0_ring_set_wptr - set write pointer
89  *
90  * @ring: amdgpu_ring pointer
91  *
92  * Commits the write pointer to the hardware
93  */
vce_v2_0_ring_set_wptr(struct amdgpu_ring * ring)94 static void vce_v2_0_ring_set_wptr(struct amdgpu_ring *ring)
95 {
96 	struct amdgpu_device *adev = ring->adev;
97 
98 	if (ring->me == 0)
99 		WREG32(mmVCE_RB_WPTR, lower_32_bits(ring->wptr));
100 	else
101 		WREG32(mmVCE_RB_WPTR2, lower_32_bits(ring->wptr));
102 }
103 
vce_v2_0_lmi_clean(struct amdgpu_device * adev)104 static int vce_v2_0_lmi_clean(struct amdgpu_device *adev)
105 {
106 	int i, j;
107 
108 	for (i = 0; i < 10; ++i) {
109 		for (j = 0; j < 100; ++j) {
110 			uint32_t status = RREG32(mmVCE_LMI_STATUS);
111 
112 			if (status & 0x337f)
113 				return 0;
114 			mdelay(10);
115 		}
116 	}
117 
118 	return -ETIMEDOUT;
119 }
120 
vce_v2_0_firmware_loaded(struct amdgpu_device * adev)121 static int vce_v2_0_firmware_loaded(struct amdgpu_device *adev)
122 {
123 	int i, j;
124 
125 	for (i = 0; i < 10; ++i) {
126 		for (j = 0; j < 100; ++j) {
127 			uint32_t status = RREG32(mmVCE_STATUS);
128 
129 			if (status & VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK)
130 				return 0;
131 			mdelay(10);
132 		}
133 
134 		DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n");
135 		WREG32_P(mmVCE_SOFT_RESET,
136 			VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
137 			~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
138 		mdelay(10);
139 		WREG32_P(mmVCE_SOFT_RESET, 0,
140 			~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
141 		mdelay(10);
142 	}
143 
144 	return -ETIMEDOUT;
145 }
146 
vce_v2_0_disable_cg(struct amdgpu_device * adev)147 static void vce_v2_0_disable_cg(struct amdgpu_device *adev)
148 {
149 	WREG32(mmVCE_CGTT_CLK_OVERRIDE, 7);
150 }
151 
vce_v2_0_init_cg(struct amdgpu_device * adev)152 static void vce_v2_0_init_cg(struct amdgpu_device *adev)
153 {
154 	u32 tmp;
155 
156 	tmp = RREG32(mmVCE_CLOCK_GATING_A);
157 	tmp &= ~0xfff;
158 	tmp |= ((0 << 0) | (4 << 4));
159 	tmp |= 0x40000;
160 	WREG32(mmVCE_CLOCK_GATING_A, tmp);
161 
162 	tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
163 	tmp &= ~0xfff;
164 	tmp |= ((0 << 0) | (4 << 4));
165 	WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
166 
167 	tmp = RREG32(mmVCE_CLOCK_GATING_B);
168 	tmp |= 0x10;
169 	tmp &= ~0x100000;
170 	WREG32(mmVCE_CLOCK_GATING_B, tmp);
171 }
172 
vce_v2_0_mc_resume(struct amdgpu_device * adev)173 static void vce_v2_0_mc_resume(struct amdgpu_device *adev)
174 {
175 	uint32_t size, offset;
176 
177 	WREG32_P(mmVCE_CLOCK_GATING_A, 0, ~(1 << 16));
178 	WREG32_P(mmVCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000);
179 	WREG32_P(mmVCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F);
180 	WREG32(mmVCE_CLOCK_GATING_B, 0xf7);
181 
182 	WREG32(mmVCE_LMI_CTRL, 0x00398000);
183 	WREG32_P(mmVCE_LMI_CACHE_CTRL, 0x0, ~0x1);
184 	WREG32(mmVCE_LMI_SWAP_CNTL, 0);
185 	WREG32(mmVCE_LMI_SWAP_CNTL1, 0);
186 	WREG32(mmVCE_LMI_VM_CTRL, 0);
187 
188 	WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8));
189 
190 	offset = AMDGPU_VCE_FIRMWARE_OFFSET;
191 	size = VCE_V2_0_FW_SIZE - AMDGPU_VCE_FIRMWARE_OFFSET;
192 	WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff);
193 	WREG32(mmVCE_VCPU_CACHE_SIZE0, size);
194 
195 	offset += size;
196 	size = VCE_V2_0_STACK_SIZE;
197 	WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0x7fffffff);
198 	WREG32(mmVCE_VCPU_CACHE_SIZE1, size);
199 
200 	offset += size;
201 	size = VCE_V2_0_DATA_SIZE;
202 	WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0x7fffffff);
203 	WREG32(mmVCE_VCPU_CACHE_SIZE2, size);
204 
205 	WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100);
206 	WREG32_FIELD(VCE_SYS_INT_EN, VCE_SYS_INT_TRAP_INTERRUPT_EN, 1);
207 }
208 
vce_v2_0_is_idle(struct amdgpu_ip_block * ip_block)209 static bool vce_v2_0_is_idle(struct amdgpu_ip_block *ip_block)
210 {
211 	struct amdgpu_device *adev = ip_block->adev;
212 
213 	return !(RREG32(mmSRBM_STATUS2) & SRBM_STATUS2__VCE_BUSY_MASK);
214 }
215 
vce_v2_0_wait_for_idle(struct amdgpu_ip_block * ip_block)216 static int vce_v2_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
217 {
218 	struct amdgpu_device *adev = ip_block->adev;
219 	unsigned i;
220 
221 	for (i = 0; i < adev->usec_timeout; i++) {
222 		if (vce_v2_0_is_idle(ip_block))
223 			return 0;
224 	}
225 	return -ETIMEDOUT;
226 }
227 
228 /**
229  * vce_v2_0_start - start VCE block
230  *
231  * @adev: amdgpu_device pointer
232  *
233  * Setup and start the VCE block
234  */
vce_v2_0_start(struct amdgpu_device * adev)235 static int vce_v2_0_start(struct amdgpu_device *adev)
236 {
237 	struct amdgpu_ring *ring;
238 	int r;
239 
240 	/* set BUSY flag */
241 	WREG32_P(mmVCE_STATUS, 1, ~1);
242 
243 	vce_v2_0_init_cg(adev);
244 	vce_v2_0_disable_cg(adev);
245 
246 	vce_v2_0_mc_resume(adev);
247 
248 	ring = &adev->vce.ring[0];
249 	WREG32(mmVCE_RB_RPTR, lower_32_bits(ring->wptr));
250 	WREG32(mmVCE_RB_WPTR, lower_32_bits(ring->wptr));
251 	WREG32(mmVCE_RB_BASE_LO, ring->gpu_addr);
252 	WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
253 	WREG32(mmVCE_RB_SIZE, ring->ring_size / 4);
254 
255 	ring = &adev->vce.ring[1];
256 	WREG32(mmVCE_RB_RPTR2, lower_32_bits(ring->wptr));
257 	WREG32(mmVCE_RB_WPTR2, lower_32_bits(ring->wptr));
258 	WREG32(mmVCE_RB_BASE_LO2, ring->gpu_addr);
259 	WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
260 	WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4);
261 
262 	WREG32_FIELD(VCE_VCPU_CNTL, CLK_EN, 1);
263 	WREG32_FIELD(VCE_SOFT_RESET, ECPU_SOFT_RESET, 1);
264 	mdelay(100);
265 	WREG32_FIELD(VCE_SOFT_RESET, ECPU_SOFT_RESET, 0);
266 
267 	r = vce_v2_0_firmware_loaded(adev);
268 
269 	/* clear BUSY flag */
270 	WREG32_P(mmVCE_STATUS, 0, ~1);
271 
272 	if (r) {
273 		DRM_ERROR("VCE not responding, giving up!!!\n");
274 		return r;
275 	}
276 
277 	return 0;
278 }
279 
vce_v2_0_stop(struct amdgpu_device * adev)280 static int vce_v2_0_stop(struct amdgpu_device *adev)
281 {
282 	struct amdgpu_ip_block *ip_block;
283 	int i;
284 	int status;
285 
286 
287 	if (vce_v2_0_lmi_clean(adev)) {
288 		drm_info(adev_to_drm(adev), "VCE is not idle\n");
289 		return 0;
290 	}
291 
292 	ip_block = amdgpu_device_ip_get_ip_block(adev, AMD_IP_BLOCK_TYPE_VCE);
293 	if (!ip_block)
294 		return -EINVAL;
295 
296 	if (vce_v2_0_wait_for_idle(ip_block)) {
297 		drm_info(adev_to_drm(adev), "VCE is busy, Can't set clock gating");
298 		return 0;
299 	}
300 
301 	/* Stall UMC and register bus before resetting VCPU */
302 	WREG32_P(mmVCE_LMI_CTRL2, 1 << 8, ~(1 << 8));
303 
304 	for (i = 0; i < 100; ++i) {
305 		status = RREG32(mmVCE_LMI_STATUS);
306 		if (status & 0x240)
307 			break;
308 		mdelay(1);
309 	}
310 
311 	WREG32_P(mmVCE_VCPU_CNTL, 0, ~0x80001);
312 
313 	/* put LMI, VCPU, RBC etc... into reset */
314 	WREG32_P(mmVCE_SOFT_RESET, 1, ~0x1);
315 
316 	WREG32(mmVCE_STATUS, 0);
317 
318 	return 0;
319 }
320 
vce_v2_0_set_sw_cg(struct amdgpu_device * adev,bool gated)321 static void vce_v2_0_set_sw_cg(struct amdgpu_device *adev, bool gated)
322 {
323 	u32 tmp;
324 
325 	if (gated) {
326 		tmp = RREG32(mmVCE_CLOCK_GATING_B);
327 		tmp |= 0xe70000;
328 		WREG32(mmVCE_CLOCK_GATING_B, tmp);
329 
330 		tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
331 		tmp |= 0xff000000;
332 		WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
333 
334 		tmp = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
335 		tmp &= ~0x3fc;
336 		WREG32(mmVCE_UENC_REG_CLOCK_GATING, tmp);
337 
338 		WREG32(mmVCE_CGTT_CLK_OVERRIDE, 0);
339 	} else {
340 		tmp = RREG32(mmVCE_CLOCK_GATING_B);
341 		tmp |= 0xe7;
342 		tmp &= ~0xe70000;
343 		WREG32(mmVCE_CLOCK_GATING_B, tmp);
344 
345 		tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
346 		tmp |= 0x1fe000;
347 		tmp &= ~0xff000000;
348 		WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
349 
350 		tmp = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
351 		tmp |= 0x3fc;
352 		WREG32(mmVCE_UENC_REG_CLOCK_GATING, tmp);
353 	}
354 }
355 
vce_v2_0_set_dyn_cg(struct amdgpu_device * adev,bool gated)356 static void vce_v2_0_set_dyn_cg(struct amdgpu_device *adev, bool gated)
357 {
358 	u32 orig, tmp;
359 
360 /* LMI_MC/LMI_UMC always set in dynamic,
361  * set {CGC_*_GATE_MODE, CGC_*_SW_GATE} = {0, 0}
362  */
363 	tmp = RREG32(mmVCE_CLOCK_GATING_B);
364 	tmp &= ~0x00060006;
365 
366 /* Exception for ECPU, IH, SEM, SYS blocks needs to be turned on/off by SW */
367 	if (gated) {
368 		tmp |= 0xe10000;
369 		WREG32(mmVCE_CLOCK_GATING_B, tmp);
370 	} else {
371 		tmp |= 0xe1;
372 		tmp &= ~0xe10000;
373 		WREG32(mmVCE_CLOCK_GATING_B, tmp);
374 	}
375 
376 	orig = tmp = RREG32(mmVCE_UENC_CLOCK_GATING);
377 	tmp &= ~0x1fe000;
378 	tmp &= ~0xff000000;
379 	if (tmp != orig)
380 		WREG32(mmVCE_UENC_CLOCK_GATING, tmp);
381 
382 	orig = tmp = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
383 	tmp &= ~0x3fc;
384 	if (tmp != orig)
385 		WREG32(mmVCE_UENC_REG_CLOCK_GATING, tmp);
386 
387 	/* set VCE_UENC_REG_CLOCK_GATING always in dynamic mode */
388 	WREG32(mmVCE_UENC_REG_CLOCK_GATING, 0x00);
389 
390 	if(gated)
391 		WREG32(mmVCE_CGTT_CLK_OVERRIDE, 0);
392 }
393 
vce_v2_0_enable_mgcg(struct amdgpu_device * adev,bool enable,bool sw_cg)394 static void vce_v2_0_enable_mgcg(struct amdgpu_device *adev, bool enable,
395 								bool sw_cg)
396 {
397 	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG)) {
398 		if (sw_cg)
399 			vce_v2_0_set_sw_cg(adev, true);
400 		else
401 			vce_v2_0_set_dyn_cg(adev, true);
402 	} else {
403 		vce_v2_0_disable_cg(adev);
404 
405 		if (sw_cg)
406 			vce_v2_0_set_sw_cg(adev, false);
407 		else
408 			vce_v2_0_set_dyn_cg(adev, false);
409 	}
410 }
411 
vce_v2_0_early_init(struct amdgpu_ip_block * ip_block)412 static int vce_v2_0_early_init(struct amdgpu_ip_block *ip_block)
413 {
414 	struct amdgpu_device *adev = ip_block->adev;
415 	int r;
416 
417 	r = amdgpu_vce_early_init(adev);
418 	if (r)
419 		return r;
420 
421 	adev->vce.num_rings = 2;
422 
423 	vce_v2_0_set_ring_funcs(adev);
424 	vce_v2_0_set_irq_funcs(adev);
425 
426 	return 0;
427 }
428 
vce_v2_0_sw_init(struct amdgpu_ip_block * ip_block)429 static int vce_v2_0_sw_init(struct amdgpu_ip_block *ip_block)
430 {
431 	struct amdgpu_ring *ring;
432 	int r, i;
433 	struct amdgpu_device *adev = ip_block->adev;
434 
435 	/* VCE */
436 	r = amdgpu_irq_add_id(adev, AMDGPU_IRQ_CLIENTID_LEGACY, 167, &adev->vce.irq);
437 	if (r)
438 		return r;
439 
440 	r = amdgpu_vce_sw_init(adev, VCE_V2_0_FW_SIZE +
441 		VCE_V2_0_STACK_SIZE + VCE_V2_0_DATA_SIZE);
442 	if (r)
443 		return r;
444 
445 	r = amdgpu_vce_resume(adev);
446 	if (r)
447 		return r;
448 
449 	for (i = 0; i < adev->vce.num_rings; i++) {
450 		enum amdgpu_ring_priority_level hw_prio = amdgpu_vce_get_ring_prio(i);
451 
452 		ring = &adev->vce.ring[i];
453 		sprintf(ring->name, "vce%d", i);
454 		r = amdgpu_ring_init(adev, ring, 512, &adev->vce.irq, 0,
455 				     hw_prio, NULL);
456 		if (r)
457 			return r;
458 	}
459 
460 	return r;
461 }
462 
vce_v2_0_sw_fini(struct amdgpu_ip_block * ip_block)463 static int vce_v2_0_sw_fini(struct amdgpu_ip_block *ip_block)
464 {
465 	int r;
466 	struct amdgpu_device *adev = ip_block->adev;
467 
468 	r = amdgpu_vce_suspend(adev);
469 	if (r)
470 		return r;
471 
472 	return amdgpu_vce_sw_fini(adev);
473 }
474 
vce_v2_0_hw_init(struct amdgpu_ip_block * ip_block)475 static int vce_v2_0_hw_init(struct amdgpu_ip_block *ip_block)
476 {
477 	int r, i;
478 	struct amdgpu_device *adev = ip_block->adev;
479 
480 	amdgpu_asic_set_vce_clocks(adev, 10000, 10000);
481 	vce_v2_0_enable_mgcg(adev, true, false);
482 
483 	for (i = 0; i < adev->vce.num_rings; i++) {
484 		r = amdgpu_ring_test_helper(&adev->vce.ring[i]);
485 		if (r)
486 			return r;
487 	}
488 
489 	drm_info(adev_to_drm(adev), "VCE initialized successfully.\n");
490 
491 	return 0;
492 }
493 
vce_v2_0_hw_fini(struct amdgpu_ip_block * ip_block)494 static int vce_v2_0_hw_fini(struct amdgpu_ip_block *ip_block)
495 {
496 	cancel_delayed_work_sync(&ip_block->adev->vce.idle_work);
497 
498 	return 0;
499 }
500 
vce_v2_0_suspend(struct amdgpu_ip_block * ip_block)501 static int vce_v2_0_suspend(struct amdgpu_ip_block *ip_block)
502 {
503 	int r;
504 	struct amdgpu_device *adev = ip_block->adev;
505 
506 
507 	/*
508 	 * Proper cleanups before halting the HW engine:
509 	 *   - cancel the delayed idle work
510 	 *   - enable powergating
511 	 *   - enable clockgating
512 	 *   - disable dpm
513 	 *
514 	 * TODO: to align with the VCN implementation, move the
515 	 * jobs for clockgating/powergating/dpm setting to
516 	 * ->set_powergating_state().
517 	 */
518 	cancel_delayed_work_sync(&adev->vce.idle_work);
519 
520 	if (adev->pm.dpm_enabled) {
521 		amdgpu_dpm_enable_vce(adev, false);
522 	} else {
523 		amdgpu_asic_set_vce_clocks(adev, 0, 0);
524 		amdgpu_device_ip_set_powergating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
525 						       AMD_PG_STATE_GATE);
526 		amdgpu_device_ip_set_clockgating_state(adev, AMD_IP_BLOCK_TYPE_VCE,
527 						       AMD_CG_STATE_GATE);
528 	}
529 
530 	r = vce_v2_0_hw_fini(ip_block);
531 	if (r)
532 		return r;
533 
534 	return amdgpu_vce_suspend(adev);
535 }
536 
vce_v2_0_resume(struct amdgpu_ip_block * ip_block)537 static int vce_v2_0_resume(struct amdgpu_ip_block *ip_block)
538 {
539 	int r;
540 
541 	r = amdgpu_vce_resume(ip_block->adev);
542 	if (r)
543 		return r;
544 
545 	return vce_v2_0_hw_init(ip_block);
546 }
547 
vce_v2_0_soft_reset(struct amdgpu_ip_block * ip_block)548 static int vce_v2_0_soft_reset(struct amdgpu_ip_block *ip_block)
549 {
550 	struct amdgpu_device *adev = ip_block->adev;
551 
552 	WREG32_FIELD(SRBM_SOFT_RESET, SOFT_RESET_VCE, 1);
553 	mdelay(5);
554 
555 	return vce_v2_0_start(adev);
556 }
557 
vce_v2_0_set_interrupt_state(struct amdgpu_device * adev,struct amdgpu_irq_src * source,unsigned type,enum amdgpu_interrupt_state state)558 static int vce_v2_0_set_interrupt_state(struct amdgpu_device *adev,
559 					struct amdgpu_irq_src *source,
560 					unsigned type,
561 					enum amdgpu_interrupt_state state)
562 {
563 	uint32_t val = 0;
564 
565 	if (state == AMDGPU_IRQ_STATE_ENABLE)
566 		val |= VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK;
567 
568 	WREG32_P(mmVCE_SYS_INT_EN, val, ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
569 	return 0;
570 }
571 
vce_v2_0_process_interrupt(struct amdgpu_device * adev,struct amdgpu_irq_src * source,struct amdgpu_iv_entry * entry)572 static int vce_v2_0_process_interrupt(struct amdgpu_device *adev,
573 				      struct amdgpu_irq_src *source,
574 				      struct amdgpu_iv_entry *entry)
575 {
576 	DRM_DEBUG("IH: VCE\n");
577 	switch (entry->src_data[0]) {
578 	case 0:
579 	case 1:
580 		amdgpu_fence_process(&adev->vce.ring[entry->src_data[0]]);
581 		break;
582 	default:
583 		DRM_ERROR("Unhandled interrupt: %d %d\n",
584 			  entry->src_id, entry->src_data[0]);
585 		break;
586 	}
587 
588 	return 0;
589 }
590 
vce_v2_0_set_clockgating_state(struct amdgpu_ip_block * ip_block,enum amd_clockgating_state state)591 static int vce_v2_0_set_clockgating_state(struct amdgpu_ip_block *ip_block,
592 					  enum amd_clockgating_state state)
593 {
594 	bool gate = false;
595 	bool sw_cg = false;
596 
597 	struct amdgpu_device *adev = ip_block->adev;
598 
599 	if (state == AMD_CG_STATE_GATE) {
600 		gate = true;
601 		sw_cg = true;
602 	}
603 
604 	vce_v2_0_enable_mgcg(adev, gate, sw_cg);
605 
606 	return 0;
607 }
608 
vce_v2_0_set_powergating_state(struct amdgpu_ip_block * ip_block,enum amd_powergating_state state)609 static int vce_v2_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
610 					  enum amd_powergating_state state)
611 {
612 	/* This doesn't actually powergate the VCE block.
613 	 * That's done in the dpm code via the SMC.  This
614 	 * just re-inits the block as necessary.  The actual
615 	 * gating still happens in the dpm code.  We should
616 	 * revisit this when there is a cleaner line between
617 	 * the smc and the hw blocks
618 	 */
619 	struct amdgpu_device *adev = ip_block->adev;
620 
621 	if (state == AMD_PG_STATE_GATE)
622 		return vce_v2_0_stop(adev);
623 	else
624 		return vce_v2_0_start(adev);
625 }
626 
627 static const struct amd_ip_funcs vce_v2_0_ip_funcs = {
628 	.name = "vce_v2_0",
629 	.early_init = vce_v2_0_early_init,
630 	.sw_init = vce_v2_0_sw_init,
631 	.sw_fini = vce_v2_0_sw_fini,
632 	.hw_init = vce_v2_0_hw_init,
633 	.hw_fini = vce_v2_0_hw_fini,
634 	.suspend = vce_v2_0_suspend,
635 	.resume = vce_v2_0_resume,
636 	.is_idle = vce_v2_0_is_idle,
637 	.wait_for_idle = vce_v2_0_wait_for_idle,
638 	.soft_reset = vce_v2_0_soft_reset,
639 	.set_clockgating_state = vce_v2_0_set_clockgating_state,
640 	.set_powergating_state = vce_v2_0_set_powergating_state,
641 };
642 
643 static const struct amdgpu_ring_funcs vce_v2_0_ring_funcs = {
644 	.type = AMDGPU_RING_TYPE_VCE,
645 	.align_mask = 0xf,
646 	.nop = VCE_CMD_NO_OP,
647 	.support_64bit_ptrs = false,
648 	.no_user_fence = true,
649 	.get_rptr = vce_v2_0_ring_get_rptr,
650 	.get_wptr = vce_v2_0_ring_get_wptr,
651 	.set_wptr = vce_v2_0_ring_set_wptr,
652 	.parse_cs = amdgpu_vce_ring_parse_cs,
653 	.emit_frame_size = 6, /* amdgpu_vce_ring_emit_fence  x1 no user fence */
654 	.emit_ib_size = 4, /* amdgpu_vce_ring_emit_ib */
655 	.emit_ib = amdgpu_vce_ring_emit_ib,
656 	.emit_fence = amdgpu_vce_ring_emit_fence,
657 	.test_ring = amdgpu_vce_ring_test_ring,
658 	.test_ib = amdgpu_vce_ring_test_ib,
659 	.insert_nop = amdgpu_ring_insert_nop,
660 	.pad_ib = amdgpu_ring_generic_pad_ib,
661 	.begin_use = amdgpu_vce_ring_begin_use,
662 	.end_use = amdgpu_vce_ring_end_use,
663 };
664 
vce_v2_0_set_ring_funcs(struct amdgpu_device * adev)665 static void vce_v2_0_set_ring_funcs(struct amdgpu_device *adev)
666 {
667 	int i;
668 
669 	for (i = 0; i < adev->vce.num_rings; i++) {
670 		adev->vce.ring[i].funcs = &vce_v2_0_ring_funcs;
671 		adev->vce.ring[i].me = i;
672 	}
673 }
674 
675 static const struct amdgpu_irq_src_funcs vce_v2_0_irq_funcs = {
676 	.set = vce_v2_0_set_interrupt_state,
677 	.process = vce_v2_0_process_interrupt,
678 };
679 
vce_v2_0_set_irq_funcs(struct amdgpu_device * adev)680 static void vce_v2_0_set_irq_funcs(struct amdgpu_device *adev)
681 {
682 	adev->vce.irq.num_types = 1;
683 	adev->vce.irq.funcs = &vce_v2_0_irq_funcs;
684 };
685 
686 const struct amdgpu_ip_block_version vce_v2_0_ip_block =
687 {
688 		.type = AMD_IP_BLOCK_TYPE_VCE,
689 		.major = 2,
690 		.minor = 0,
691 		.rev = 0,
692 		.funcs = &vce_v2_0_ip_funcs,
693 };
694