Linux Audio

Check our new training course

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