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