xref: /openbmc/linux/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c (revision 6f906814)
1 /*
2  * Copyright 2014 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 #include <drm/drmP.h>
30 #include "amdgpu.h"
31 #include "amdgpu_vce.h"
32 #include "vid.h"
33 #include "vce/vce_3_0_d.h"
34 #include "vce/vce_3_0_sh_mask.h"
35 #include "oss/oss_3_0_d.h"
36 #include "oss/oss_3_0_sh_mask.h"
37 #include "gca/gfx_8_0_d.h"
38 #include "smu/smu_7_1_2_d.h"
39 #include "smu/smu_7_1_2_sh_mask.h"
40 #include "gca/gfx_8_0_d.h"
41 #include "gca/gfx_8_0_sh_mask.h"
42 
43 
44 #define GRBM_GFX_INDEX__VCE_INSTANCE__SHIFT	0x04
45 #define GRBM_GFX_INDEX__VCE_INSTANCE_MASK	0x10
46 #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR0	0x8616
47 #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR1	0x8617
48 #define mmVCE_LMI_VCPU_CACHE_40BIT_BAR2	0x8618
49 #define VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK	0x02
50 
51 #define VCE_V3_0_FW_SIZE	(384 * 1024)
52 #define VCE_V3_0_STACK_SIZE	(64 * 1024)
53 #define VCE_V3_0_DATA_SIZE	((16 * 1024 * AMDGPU_MAX_VCE_HANDLES) + (52 * 1024))
54 
55 static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx);
56 static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev);
57 static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev);
58 static int vce_v3_0_wait_for_idle(void *handle);
59 
60 /**
61  * vce_v3_0_ring_get_rptr - get read pointer
62  *
63  * @ring: amdgpu_ring pointer
64  *
65  * Returns the current hardware read pointer
66  */
67 static uint32_t vce_v3_0_ring_get_rptr(struct amdgpu_ring *ring)
68 {
69 	struct amdgpu_device *adev = ring->adev;
70 
71 	if (ring == &adev->vce.ring[0])
72 		return RREG32(mmVCE_RB_RPTR);
73 	else
74 		return RREG32(mmVCE_RB_RPTR2);
75 }
76 
77 /**
78  * vce_v3_0_ring_get_wptr - get write pointer
79  *
80  * @ring: amdgpu_ring pointer
81  *
82  * Returns the current hardware write pointer
83  */
84 static uint32_t vce_v3_0_ring_get_wptr(struct amdgpu_ring *ring)
85 {
86 	struct amdgpu_device *adev = ring->adev;
87 
88 	if (ring == &adev->vce.ring[0])
89 		return RREG32(mmVCE_RB_WPTR);
90 	else
91 		return RREG32(mmVCE_RB_WPTR2);
92 }
93 
94 /**
95  * vce_v3_0_ring_set_wptr - set write pointer
96  *
97  * @ring: amdgpu_ring pointer
98  *
99  * Commits the write pointer to the hardware
100  */
101 static void vce_v3_0_ring_set_wptr(struct amdgpu_ring *ring)
102 {
103 	struct amdgpu_device *adev = ring->adev;
104 
105 	if (ring == &adev->vce.ring[0])
106 		WREG32(mmVCE_RB_WPTR, ring->wptr);
107 	else
108 		WREG32(mmVCE_RB_WPTR2, ring->wptr);
109 }
110 
111 static void vce_v3_0_override_vce_clock_gating(struct amdgpu_device *adev, bool override)
112 {
113 	u32 tmp, data;
114 
115 	tmp = data = RREG32(mmVCE_RB_ARB_CTRL);
116 	if (override)
117 		data |= VCE_RB_ARB_CTRL__VCE_CGTT_OVERRIDE_MASK;
118 	else
119 		data &= ~VCE_RB_ARB_CTRL__VCE_CGTT_OVERRIDE_MASK;
120 
121 	if (tmp != data)
122 		WREG32(mmVCE_RB_ARB_CTRL, data);
123 }
124 
125 static void vce_v3_0_set_vce_sw_clock_gating(struct amdgpu_device *adev,
126 					     bool gated)
127 {
128 	u32 tmp, data;
129 
130 	/* Set Override to disable Clock Gating */
131 	vce_v3_0_override_vce_clock_gating(adev, true);
132 
133 	/* This function enables MGCG which is controlled by firmware.
134 	   With the clocks in the gated state the core is still
135 	   accessible but the firmware will throttle the clocks on the
136 	   fly as necessary.
137 	*/
138 	if (gated) {
139 		tmp = data = RREG32(mmVCE_CLOCK_GATING_B);
140 		data |= 0x1ff;
141 		data &= ~0xef0000;
142 		if (tmp != data)
143 			WREG32(mmVCE_CLOCK_GATING_B, data);
144 
145 		tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING);
146 		data |= 0x3ff000;
147 		data &= ~0xffc00000;
148 		if (tmp != data)
149 			WREG32(mmVCE_UENC_CLOCK_GATING, data);
150 
151 		tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING_2);
152 		data |= 0x2;
153 		data &= ~0x00010000;
154 		if (tmp != data)
155 			WREG32(mmVCE_UENC_CLOCK_GATING_2, data);
156 
157 		tmp = data = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
158 		data |= 0x37f;
159 		if (tmp != data)
160 			WREG32(mmVCE_UENC_REG_CLOCK_GATING, data);
161 
162 		tmp = data = RREG32(mmVCE_UENC_DMA_DCLK_CTRL);
163 		data |= VCE_UENC_DMA_DCLK_CTRL__WRDMCLK_FORCEON_MASK |
164 			VCE_UENC_DMA_DCLK_CTRL__RDDMCLK_FORCEON_MASK |
165 			VCE_UENC_DMA_DCLK_CTRL__REGCLK_FORCEON_MASK  |
166 			0x8;
167 		if (tmp != data)
168 			WREG32(mmVCE_UENC_DMA_DCLK_CTRL, data);
169 	} else {
170 		tmp = data = RREG32(mmVCE_CLOCK_GATING_B);
171 		data &= ~0x80010;
172 		data |= 0xe70008;
173 		if (tmp != data)
174 			WREG32(mmVCE_CLOCK_GATING_B, data);
175 
176 		tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING);
177 		data |= 0xffc00000;
178 		if (tmp != data)
179 			WREG32(mmVCE_UENC_CLOCK_GATING, data);
180 
181 		tmp = data = RREG32(mmVCE_UENC_CLOCK_GATING_2);
182 		data |= 0x10000;
183 		if (tmp != data)
184 			WREG32(mmVCE_UENC_CLOCK_GATING_2, data);
185 
186 		tmp = data = RREG32(mmVCE_UENC_REG_CLOCK_GATING);
187 		data &= ~0xffc00000;
188 		if (tmp != data)
189 			WREG32(mmVCE_UENC_REG_CLOCK_GATING, data);
190 
191 		tmp = data = RREG32(mmVCE_UENC_DMA_DCLK_CTRL);
192 		data &= ~(VCE_UENC_DMA_DCLK_CTRL__WRDMCLK_FORCEON_MASK |
193 			  VCE_UENC_DMA_DCLK_CTRL__RDDMCLK_FORCEON_MASK |
194 			  VCE_UENC_DMA_DCLK_CTRL__REGCLK_FORCEON_MASK  |
195 			  0x8);
196 		if (tmp != data)
197 			WREG32(mmVCE_UENC_DMA_DCLK_CTRL, data);
198 	}
199 	vce_v3_0_override_vce_clock_gating(adev, false);
200 }
201 
202 static int vce_v3_0_firmware_loaded(struct amdgpu_device *adev)
203 {
204 	int i, j;
205 
206 	for (i = 0; i < 10; ++i) {
207 		for (j = 0; j < 100; ++j) {
208 			uint32_t status = RREG32(mmVCE_STATUS);
209 
210 			if (status & VCE_STATUS_VCPU_REPORT_FW_LOADED_MASK)
211 				return 0;
212 			mdelay(10);
213 		}
214 
215 		DRM_ERROR("VCE not responding, trying to reset the ECPU!!!\n");
216 		WREG32_P(mmVCE_SOFT_RESET,
217 			VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
218 			~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
219 		mdelay(10);
220 		WREG32_P(mmVCE_SOFT_RESET, 0,
221 			~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
222 		mdelay(10);
223 	}
224 
225 	return -ETIMEDOUT;
226 }
227 
228 /**
229  * vce_v3_0_start - start VCE block
230  *
231  * @adev: amdgpu_device pointer
232  *
233  * Setup and start the VCE block
234  */
235 static int vce_v3_0_start(struct amdgpu_device *adev)
236 {
237 	struct amdgpu_ring *ring;
238 	int idx, r;
239 
240 	ring = &adev->vce.ring[0];
241 	WREG32(mmVCE_RB_RPTR, ring->wptr);
242 	WREG32(mmVCE_RB_WPTR, ring->wptr);
243 	WREG32(mmVCE_RB_BASE_LO, ring->gpu_addr);
244 	WREG32(mmVCE_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
245 	WREG32(mmVCE_RB_SIZE, ring->ring_size / 4);
246 
247 	ring = &adev->vce.ring[1];
248 	WREG32(mmVCE_RB_RPTR2, ring->wptr);
249 	WREG32(mmVCE_RB_WPTR2, ring->wptr);
250 	WREG32(mmVCE_RB_BASE_LO2, ring->gpu_addr);
251 	WREG32(mmVCE_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
252 	WREG32(mmVCE_RB_SIZE2, ring->ring_size / 4);
253 
254 	mutex_lock(&adev->grbm_idx_mutex);
255 	for (idx = 0; idx < 2; ++idx) {
256 		if (adev->vce.harvest_config & (1 << idx))
257 			continue;
258 
259 		if (idx == 0)
260 			WREG32_P(mmGRBM_GFX_INDEX, 0,
261 				~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
262 		else
263 			WREG32_P(mmGRBM_GFX_INDEX,
264 				GRBM_GFX_INDEX__VCE_INSTANCE_MASK,
265 				~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
266 
267 		vce_v3_0_mc_resume(adev, idx);
268 
269 		WREG32_P(mmVCE_STATUS, VCE_STATUS__JOB_BUSY_MASK,
270 		         ~VCE_STATUS__JOB_BUSY_MASK);
271 
272 		if (adev->asic_type >= CHIP_STONEY)
273 			WREG32_P(mmVCE_VCPU_CNTL, 1, ~0x200001);
274 		else
275 			WREG32_P(mmVCE_VCPU_CNTL, VCE_VCPU_CNTL__CLK_EN_MASK,
276 				~VCE_VCPU_CNTL__CLK_EN_MASK);
277 
278 		WREG32_P(mmVCE_SOFT_RESET, 0,
279 			~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
280 
281 		mdelay(100);
282 
283 		r = vce_v3_0_firmware_loaded(adev);
284 
285 		/* clear BUSY flag */
286 		WREG32_P(mmVCE_STATUS, 0, ~VCE_STATUS__JOB_BUSY_MASK);
287 
288 		/* Set Clock-Gating off */
289 		if (adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG)
290 			vce_v3_0_set_vce_sw_clock_gating(adev, false);
291 
292 		if (r) {
293 			DRM_ERROR("VCE not responding, giving up!!!\n");
294 			mutex_unlock(&adev->grbm_idx_mutex);
295 			return r;
296 		}
297 	}
298 
299 	WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
300 	mutex_unlock(&adev->grbm_idx_mutex);
301 
302 	return 0;
303 }
304 
305 static int vce_v3_0_stop(struct amdgpu_device *adev)
306 {
307 	int idx;
308 
309 	mutex_lock(&adev->grbm_idx_mutex);
310 	for (idx = 0; idx < 2; ++idx) {
311 		if (adev->vce.harvest_config & (1 << idx))
312 			continue;
313 
314 		if (idx == 0)
315 			WREG32_P(mmGRBM_GFX_INDEX, 0,
316 				~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
317 		else
318 			WREG32_P(mmGRBM_GFX_INDEX,
319 				GRBM_GFX_INDEX__VCE_INSTANCE_MASK,
320 				~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
321 
322 		if (adev->asic_type >= CHIP_STONEY)
323 			WREG32_P(mmVCE_VCPU_CNTL, 0, ~0x200001);
324 		else
325 			WREG32_P(mmVCE_VCPU_CNTL, 0,
326 				~VCE_VCPU_CNTL__CLK_EN_MASK);
327 		/* hold on ECPU */
328 		WREG32_P(mmVCE_SOFT_RESET,
329 			 VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK,
330 			 ~VCE_SOFT_RESET__ECPU_SOFT_RESET_MASK);
331 
332 		/* clear BUSY flag */
333 		WREG32_P(mmVCE_STATUS, 0, ~VCE_STATUS__JOB_BUSY_MASK);
334 
335 		/* Set Clock-Gating off */
336 		if (adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG)
337 			vce_v3_0_set_vce_sw_clock_gating(adev, false);
338 	}
339 
340 	WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
341 	mutex_unlock(&adev->grbm_idx_mutex);
342 
343 	return 0;
344 }
345 
346 #define ixVCE_HARVEST_FUSE_MACRO__ADDRESS     0xC0014074
347 #define VCE_HARVEST_FUSE_MACRO__SHIFT       27
348 #define VCE_HARVEST_FUSE_MACRO__MASK        0x18000000
349 
350 static unsigned vce_v3_0_get_harvest_config(struct amdgpu_device *adev)
351 {
352 	u32 tmp;
353 
354 	/* Fiji, Stoney, Polaris10, Polaris11 are single pipe */
355 	if ((adev->asic_type == CHIP_FIJI) ||
356 	    (adev->asic_type == CHIP_STONEY) ||
357 	    (adev->asic_type == CHIP_POLARIS10) ||
358 	    (adev->asic_type == CHIP_POLARIS11))
359 		return AMDGPU_VCE_HARVEST_VCE1;
360 
361 	/* Tonga and CZ are dual or single pipe */
362 	if (adev->flags & AMD_IS_APU)
363 		tmp = (RREG32_SMC(ixVCE_HARVEST_FUSE_MACRO__ADDRESS) &
364 		       VCE_HARVEST_FUSE_MACRO__MASK) >>
365 			VCE_HARVEST_FUSE_MACRO__SHIFT;
366 	else
367 		tmp = (RREG32_SMC(ixCC_HARVEST_FUSES) &
368 		       CC_HARVEST_FUSES__VCE_DISABLE_MASK) >>
369 			CC_HARVEST_FUSES__VCE_DISABLE__SHIFT;
370 
371 	switch (tmp) {
372 	case 1:
373 		return AMDGPU_VCE_HARVEST_VCE0;
374 	case 2:
375 		return AMDGPU_VCE_HARVEST_VCE1;
376 	case 3:
377 		return AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1;
378 	default:
379 		return 0;
380 	}
381 }
382 
383 static int vce_v3_0_early_init(void *handle)
384 {
385 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
386 
387 	adev->vce.harvest_config = vce_v3_0_get_harvest_config(adev);
388 
389 	if ((adev->vce.harvest_config &
390 	     (AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1)) ==
391 	    (AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1))
392 		return -ENOENT;
393 
394 	vce_v3_0_set_ring_funcs(adev);
395 	vce_v3_0_set_irq_funcs(adev);
396 
397 	return 0;
398 }
399 
400 static int vce_v3_0_sw_init(void *handle)
401 {
402 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
403 	struct amdgpu_ring *ring;
404 	int r;
405 
406 	/* VCE */
407 	r = amdgpu_irq_add_id(adev, 167, &adev->vce.irq);
408 	if (r)
409 		return r;
410 
411 	r = amdgpu_vce_sw_init(adev, VCE_V3_0_FW_SIZE +
412 		(VCE_V3_0_STACK_SIZE + VCE_V3_0_DATA_SIZE) * 2);
413 	if (r)
414 		return r;
415 
416 	r = amdgpu_vce_resume(adev);
417 	if (r)
418 		return r;
419 
420 	ring = &adev->vce.ring[0];
421 	sprintf(ring->name, "vce0");
422 	r = amdgpu_ring_init(adev, ring, 512, VCE_CMD_NO_OP, 0xf,
423 			     &adev->vce.irq, 0, AMDGPU_RING_TYPE_VCE);
424 	if (r)
425 		return r;
426 
427 	ring = &adev->vce.ring[1];
428 	sprintf(ring->name, "vce1");
429 	r = amdgpu_ring_init(adev, ring, 512, VCE_CMD_NO_OP, 0xf,
430 			     &adev->vce.irq, 0, AMDGPU_RING_TYPE_VCE);
431 	if (r)
432 		return r;
433 
434 	return r;
435 }
436 
437 static int vce_v3_0_sw_fini(void *handle)
438 {
439 	int r;
440 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
441 
442 	r = amdgpu_vce_suspend(adev);
443 	if (r)
444 		return r;
445 
446 	r = amdgpu_vce_sw_fini(adev);
447 	if (r)
448 		return r;
449 
450 	return r;
451 }
452 
453 static int vce_v3_0_hw_init(void *handle)
454 {
455 	int r, i;
456 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
457 
458 	r = vce_v3_0_start(adev);
459 	if (r)
460 		return r;
461 
462 	adev->vce.ring[0].ready = false;
463 	adev->vce.ring[1].ready = false;
464 
465 	for (i = 0; i < 2; i++) {
466 		r = amdgpu_ring_test_ring(&adev->vce.ring[i]);
467 		if (r)
468 			return r;
469 		else
470 			adev->vce.ring[i].ready = true;
471 	}
472 
473 	DRM_INFO("VCE initialized successfully.\n");
474 
475 	return 0;
476 }
477 
478 static int vce_v3_0_hw_fini(void *handle)
479 {
480 	int r;
481 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
482 
483 	r = vce_v3_0_wait_for_idle(handle);
484 	if (r)
485 		return r;
486 
487 	return vce_v3_0_stop(adev);
488 }
489 
490 static int vce_v3_0_suspend(void *handle)
491 {
492 	int r;
493 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
494 
495 	r = vce_v3_0_hw_fini(adev);
496 	if (r)
497 		return r;
498 
499 	r = amdgpu_vce_suspend(adev);
500 	if (r)
501 		return r;
502 
503 	return r;
504 }
505 
506 static int vce_v3_0_resume(void *handle)
507 {
508 	int r;
509 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
510 
511 	r = amdgpu_vce_resume(adev);
512 	if (r)
513 		return r;
514 
515 	r = vce_v3_0_hw_init(adev);
516 	if (r)
517 		return r;
518 
519 	return r;
520 }
521 
522 static void vce_v3_0_mc_resume(struct amdgpu_device *adev, int idx)
523 {
524 	uint32_t offset, size;
525 
526 	WREG32_P(mmVCE_CLOCK_GATING_A, 0, ~(1 << 16));
527 	WREG32_P(mmVCE_UENC_CLOCK_GATING, 0x1FF000, ~0xFF9FF000);
528 	WREG32_P(mmVCE_UENC_REG_CLOCK_GATING, 0x3F, ~0x3F);
529 	WREG32(mmVCE_CLOCK_GATING_B, 0x1FF);
530 
531 	WREG32(mmVCE_LMI_CTRL, 0x00398000);
532 	WREG32_P(mmVCE_LMI_CACHE_CTRL, 0x0, ~0x1);
533 	WREG32(mmVCE_LMI_SWAP_CNTL, 0);
534 	WREG32(mmVCE_LMI_SWAP_CNTL1, 0);
535 	WREG32(mmVCE_LMI_VM_CTRL, 0);
536 	if (adev->asic_type >= CHIP_STONEY) {
537 		WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR0, (adev->vce.gpu_addr >> 8));
538 		WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR1, (adev->vce.gpu_addr >> 8));
539 		WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR2, (adev->vce.gpu_addr >> 8));
540 	} else
541 		WREG32(mmVCE_LMI_VCPU_CACHE_40BIT_BAR, (adev->vce.gpu_addr >> 8));
542 	offset = AMDGPU_VCE_FIRMWARE_OFFSET;
543 	size = VCE_V3_0_FW_SIZE;
544 	WREG32(mmVCE_VCPU_CACHE_OFFSET0, offset & 0x7fffffff);
545 	WREG32(mmVCE_VCPU_CACHE_SIZE0, size);
546 
547 	if (idx == 0) {
548 		offset += size;
549 		size = VCE_V3_0_STACK_SIZE;
550 		WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0x7fffffff);
551 		WREG32(mmVCE_VCPU_CACHE_SIZE1, size);
552 		offset += size;
553 		size = VCE_V3_0_DATA_SIZE;
554 		WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0x7fffffff);
555 		WREG32(mmVCE_VCPU_CACHE_SIZE2, size);
556 	} else {
557 		offset += size + VCE_V3_0_STACK_SIZE + VCE_V3_0_DATA_SIZE;
558 		size = VCE_V3_0_STACK_SIZE;
559 		WREG32(mmVCE_VCPU_CACHE_OFFSET1, offset & 0xfffffff);
560 		WREG32(mmVCE_VCPU_CACHE_SIZE1, size);
561 		offset += size;
562 		size = VCE_V3_0_DATA_SIZE;
563 		WREG32(mmVCE_VCPU_CACHE_OFFSET2, offset & 0xfffffff);
564 		WREG32(mmVCE_VCPU_CACHE_SIZE2, size);
565 	}
566 
567 	WREG32_P(mmVCE_LMI_CTRL2, 0x0, ~0x100);
568 
569 	WREG32_P(mmVCE_SYS_INT_EN, VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK,
570 		 ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
571 }
572 
573 static bool vce_v3_0_is_idle(void *handle)
574 {
575 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
576 	u32 mask = 0;
577 
578 	mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE0) ? 0 : SRBM_STATUS2__VCE0_BUSY_MASK;
579 	mask |= (adev->vce.harvest_config & AMDGPU_VCE_HARVEST_VCE1) ? 0 : SRBM_STATUS2__VCE1_BUSY_MASK;
580 
581 	return !(RREG32(mmSRBM_STATUS2) & mask);
582 }
583 
584 static int vce_v3_0_wait_for_idle(void *handle)
585 {
586 	unsigned i;
587 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
588 
589 	for (i = 0; i < adev->usec_timeout; i++)
590 		if (vce_v3_0_is_idle(handle))
591 			return 0;
592 
593 	return -ETIMEDOUT;
594 }
595 
596 #define AMDGPU_VCE_STATUS_BUSY_MASK    0x78
597 
598 static int vce_v3_0_check_soft_reset(void *handle)
599 {
600 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
601 	u32 srbm_soft_reset = 0;
602 	u32 tmp;
603 
604 	/* VCE BUG: it is always busy, so skip its checking now */
605 	return 0;
606 
607 	/* According to VCE team , we should use VCE_STATUS instead
608 	 * SRBM_STATUS.VCE_BUSY bit for busy status checking.
609 	 * GRBM_GFX_INDEX.INSTANCE_INDEX is used to specify which VCE
610 	 * instance's registers are accessed
611 	 * (0 for 1st instance, 10 for 2nd instance).
612 	 *
613 	 *VCE_STATUS
614 	 *|UENC|ACPI|AUTO ACTIVE|RB1 |RB0 |RB2 |          |FW_LOADED|JOB |
615 	 *|----+----+-----------+----+----+----+----------+---------+----|
616 	 *|bit8|bit7|    bit6   |bit5|bit4|bit3|   bit2   |  bit1   |bit0|
617 	 *
618 	 * VCE team suggest use bit 3--bit 6 for busy status check
619 	 */
620 	tmp = RREG32(mmGRBM_GFX_INDEX);
621 	tmp = REG_SET_FIELD(tmp, GRBM_GFX_INDEX, INSTANCE_INDEX, 0);
622 	WREG32(mmGRBM_GFX_INDEX, tmp);
623 	if (RREG32(mmVCE_STATUS) & AMDGPU_VCE_STATUS_BUSY_MASK) {
624 		srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_VCE0, 1);
625 		srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_VCE1, 1);
626 	}
627 	tmp = RREG32(mmGRBM_GFX_INDEX);
628 	tmp = REG_SET_FIELD(tmp, GRBM_GFX_INDEX, INSTANCE_INDEX, 0x10);
629 	WREG32(mmGRBM_GFX_INDEX, tmp);
630 	if (RREG32(mmVCE_STATUS) & AMDGPU_VCE_STATUS_BUSY_MASK) {
631 		srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_VCE0, 1);
632 		srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_VCE1, 1);
633 	}
634 	tmp = RREG32(mmGRBM_GFX_INDEX);
635 	tmp = REG_SET_FIELD(tmp, GRBM_GFX_INDEX, INSTANCE_INDEX, 0);
636 	WREG32(mmGRBM_GFX_INDEX, tmp);
637 
638 	if (adev->vce.harvest_config & (AMDGPU_VCE_HARVEST_VCE0 | AMDGPU_VCE_HARVEST_VCE1))
639 		srbm_soft_reset = 0;
640 
641 	if (srbm_soft_reset) {
642 		adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang = true;
643 		adev->vce.srbm_soft_reset = srbm_soft_reset;
644 	} else {
645 		adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang = false;
646 		adev->vce.srbm_soft_reset = 0;
647 	}
648 	return 0;
649 }
650 
651 static int vce_v3_0_soft_reset(void *handle)
652 {
653 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
654 	u32 srbm_soft_reset;
655 
656 	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang)
657 		return 0;
658 	srbm_soft_reset = adev->vce.srbm_soft_reset;
659 
660 	if (srbm_soft_reset) {
661 		u32 tmp;
662 
663 		tmp = RREG32(mmSRBM_SOFT_RESET);
664 		tmp |= srbm_soft_reset;
665 		dev_info(adev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
666 		WREG32(mmSRBM_SOFT_RESET, tmp);
667 		tmp = RREG32(mmSRBM_SOFT_RESET);
668 
669 		udelay(50);
670 
671 		tmp &= ~srbm_soft_reset;
672 		WREG32(mmSRBM_SOFT_RESET, tmp);
673 		tmp = RREG32(mmSRBM_SOFT_RESET);
674 
675 		/* Wait a little for things to settle down */
676 		udelay(50);
677 	}
678 
679 	return 0;
680 }
681 
682 static int vce_v3_0_pre_soft_reset(void *handle)
683 {
684 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
685 
686 	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang)
687 		return 0;
688 
689 	mdelay(5);
690 
691 	return vce_v3_0_suspend(adev);
692 }
693 
694 
695 static int vce_v3_0_post_soft_reset(void *handle)
696 {
697 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
698 
699 	if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang)
700 		return 0;
701 
702 	mdelay(5);
703 
704 	return vce_v3_0_resume(adev);
705 }
706 
707 static int vce_v3_0_set_interrupt_state(struct amdgpu_device *adev,
708 					struct amdgpu_irq_src *source,
709 					unsigned type,
710 					enum amdgpu_interrupt_state state)
711 {
712 	uint32_t val = 0;
713 
714 	if (state == AMDGPU_IRQ_STATE_ENABLE)
715 		val |= VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK;
716 
717 	WREG32_P(mmVCE_SYS_INT_EN, val, ~VCE_SYS_INT_EN__VCE_SYS_INT_TRAP_INTERRUPT_EN_MASK);
718 	return 0;
719 }
720 
721 static int vce_v3_0_process_interrupt(struct amdgpu_device *adev,
722 				      struct amdgpu_irq_src *source,
723 				      struct amdgpu_iv_entry *entry)
724 {
725 	DRM_DEBUG("IH: VCE\n");
726 
727 	WREG32_P(mmVCE_SYS_INT_STATUS,
728 		VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK,
729 		~VCE_SYS_INT_STATUS__VCE_SYS_INT_TRAP_INTERRUPT_INT_MASK);
730 
731 	switch (entry->src_data) {
732 	case 0:
733 	case 1:
734 		amdgpu_fence_process(&adev->vce.ring[entry->src_data]);
735 		break;
736 	default:
737 		DRM_ERROR("Unhandled interrupt: %d %d\n",
738 			  entry->src_id, entry->src_data);
739 		break;
740 	}
741 
742 	return 0;
743 }
744 
745 static void vce_v3_set_bypass_mode(struct amdgpu_device *adev, bool enable)
746 {
747 	u32 tmp = RREG32_SMC(ixGCK_DFS_BYPASS_CNTL);
748 
749 	if (enable)
750 		tmp |= GCK_DFS_BYPASS_CNTL__BYPASSECLK_MASK;
751 	else
752 		tmp &= ~GCK_DFS_BYPASS_CNTL__BYPASSECLK_MASK;
753 
754 	WREG32_SMC(ixGCK_DFS_BYPASS_CNTL, tmp);
755 }
756 
757 static int vce_v3_0_set_clockgating_state(void *handle,
758 					  enum amd_clockgating_state state)
759 {
760 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
761 	bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
762 	int i;
763 
764 	if (adev->asic_type == CHIP_POLARIS10)
765 		vce_v3_set_bypass_mode(adev, enable);
766 
767 	if (!(adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG))
768 		return 0;
769 
770 	mutex_lock(&adev->grbm_idx_mutex);
771 	for (i = 0; i < 2; i++) {
772 		/* Program VCE Instance 0 or 1 if not harvested */
773 		if (adev->vce.harvest_config & (1 << i))
774 			continue;
775 
776 		if (i == 0)
777 			WREG32_P(mmGRBM_GFX_INDEX, 0,
778 					~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
779 		else
780 			WREG32_P(mmGRBM_GFX_INDEX,
781 					GRBM_GFX_INDEX__VCE_INSTANCE_MASK,
782 					~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
783 
784 		if (enable) {
785 			/* initialize VCE_CLOCK_GATING_A: Clock ON/OFF delay */
786 			uint32_t data = RREG32(mmVCE_CLOCK_GATING_A);
787 			data &= ~(0xf | 0xff0);
788 			data |= ((0x0 << 0) | (0x04 << 4));
789 			WREG32(mmVCE_CLOCK_GATING_A, data);
790 
791 			/* initialize VCE_UENC_CLOCK_GATING: Clock ON/OFF delay */
792 			data = RREG32(mmVCE_UENC_CLOCK_GATING);
793 			data &= ~(0xf | 0xff0);
794 			data |= ((0x0 << 0) | (0x04 << 4));
795 			WREG32(mmVCE_UENC_CLOCK_GATING, data);
796 		}
797 
798 		vce_v3_0_set_vce_sw_clock_gating(adev, enable);
799 	}
800 
801 	WREG32_P(mmGRBM_GFX_INDEX, 0, ~GRBM_GFX_INDEX__VCE_INSTANCE_MASK);
802 	mutex_unlock(&adev->grbm_idx_mutex);
803 
804 	return 0;
805 }
806 
807 static int vce_v3_0_set_powergating_state(void *handle,
808 					  enum amd_powergating_state state)
809 {
810 	/* This doesn't actually powergate the VCE block.
811 	 * That's done in the dpm code via the SMC.  This
812 	 * just re-inits the block as necessary.  The actual
813 	 * gating still happens in the dpm code.  We should
814 	 * revisit this when there is a cleaner line between
815 	 * the smc and the hw blocks
816 	 */
817 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
818 
819 	if (!(adev->pg_flags & AMD_PG_SUPPORT_VCE))
820 		return 0;
821 
822 	if (state == AMD_PG_STATE_GATE)
823 		/* XXX do we need a vce_v3_0_stop()? */
824 		return 0;
825 	else
826 		return vce_v3_0_start(adev);
827 }
828 
829 const struct amd_ip_funcs vce_v3_0_ip_funcs = {
830 	.name = "vce_v3_0",
831 	.early_init = vce_v3_0_early_init,
832 	.late_init = NULL,
833 	.sw_init = vce_v3_0_sw_init,
834 	.sw_fini = vce_v3_0_sw_fini,
835 	.hw_init = vce_v3_0_hw_init,
836 	.hw_fini = vce_v3_0_hw_fini,
837 	.suspend = vce_v3_0_suspend,
838 	.resume = vce_v3_0_resume,
839 	.is_idle = vce_v3_0_is_idle,
840 	.wait_for_idle = vce_v3_0_wait_for_idle,
841 	.check_soft_reset = vce_v3_0_check_soft_reset,
842 	.pre_soft_reset = vce_v3_0_pre_soft_reset,
843 	.soft_reset = vce_v3_0_soft_reset,
844 	.post_soft_reset = vce_v3_0_post_soft_reset,
845 	.set_clockgating_state = vce_v3_0_set_clockgating_state,
846 	.set_powergating_state = vce_v3_0_set_powergating_state,
847 };
848 
849 static const struct amdgpu_ring_funcs vce_v3_0_ring_funcs = {
850 	.get_rptr = vce_v3_0_ring_get_rptr,
851 	.get_wptr = vce_v3_0_ring_get_wptr,
852 	.set_wptr = vce_v3_0_ring_set_wptr,
853 	.parse_cs = amdgpu_vce_ring_parse_cs,
854 	.emit_ib = amdgpu_vce_ring_emit_ib,
855 	.emit_fence = amdgpu_vce_ring_emit_fence,
856 	.test_ring = amdgpu_vce_ring_test_ring,
857 	.test_ib = amdgpu_vce_ring_test_ib,
858 	.insert_nop = amdgpu_ring_insert_nop,
859 	.pad_ib = amdgpu_ring_generic_pad_ib,
860 	.begin_use = amdgpu_vce_ring_begin_use,
861 	.end_use = amdgpu_vce_ring_end_use,
862 };
863 
864 static void vce_v3_0_set_ring_funcs(struct amdgpu_device *adev)
865 {
866 	adev->vce.ring[0].funcs = &vce_v3_0_ring_funcs;
867 	adev->vce.ring[1].funcs = &vce_v3_0_ring_funcs;
868 }
869 
870 static const struct amdgpu_irq_src_funcs vce_v3_0_irq_funcs = {
871 	.set = vce_v3_0_set_interrupt_state,
872 	.process = vce_v3_0_process_interrupt,
873 };
874 
875 static void vce_v3_0_set_irq_funcs(struct amdgpu_device *adev)
876 {
877 	adev->vce.irq.num_types = 1;
878 	adev->vce.irq.funcs = &vce_v3_0_irq_funcs;
879 };
880