1/*
2 * Copyright 2019 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#include <linux/firmware.h>
25#include <drm/drm_drv.h>
26
27#include "amdgpu.h"
28#include "amdgpu_vcn.h"
29#include "amdgpu_pm.h"
30#include "soc15.h"
31#include "soc15d.h"
32#include "vcn_v2_0.h"
33#include "mmsch_v1_0.h"
34#include "vcn_v2_5.h"
35
36#include "vcn/vcn_2_5_offset.h"
37#include "vcn/vcn_2_5_sh_mask.h"
38#include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
39
40#define VCN_VID_SOC_ADDRESS_2_0					0x1fa00
41#define VCN1_VID_SOC_ADDRESS_3_0				0x48200
42
43#define mmUVD_CONTEXT_ID_INTERNAL_OFFSET			0x27
44#define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET			0x0f
45#define mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET			0x10
46#define mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET			0x11
47#define mmUVD_NO_OP_INTERNAL_OFFSET				0x29
48#define mmUVD_GP_SCRATCH8_INTERNAL_OFFSET			0x66
49#define mmUVD_SCRATCH9_INTERNAL_OFFSET				0xc01d
50
51#define mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET			0x431
52#define mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET		0x3b4
53#define mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET		0x3b5
54#define mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET			0x25c
55
56#define VCN25_MAX_HW_INSTANCES_ARCTURUS			2
57
58static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev);
59static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev);
60static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev);
61static int vcn_v2_5_set_powergating_state(void *handle,
62				enum amd_powergating_state state);
63static int vcn_v2_5_pause_dpg_mode(struct amdgpu_device *adev,
64				int inst_idx, struct dpg_pause_state *new_state);
65static int vcn_v2_5_sriov_start(struct amdgpu_device *adev);
66static void vcn_v2_5_set_ras_funcs(struct amdgpu_device *adev);
67
68static int amdgpu_ih_clientid_vcns[] = {
69	SOC15_IH_CLIENTID_VCN,
70	SOC15_IH_CLIENTID_VCN1
71};
72
73/**
74 * vcn_v2_5_early_init - set function pointers and load microcode
75 *
76 * @handle: amdgpu_device pointer
77 *
78 * Set ring and irq function pointers
79 * Load microcode from filesystem
80 */
81static int vcn_v2_5_early_init(void *handle)
82{
83	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
84
85	if (amdgpu_sriov_vf(adev)) {
86		adev->vcn.num_vcn_inst = 2;
87		adev->vcn.harvest_config = 0;
88		adev->vcn.num_enc_rings = 1;
89	} else {
90		u32 harvest;
91		int i;
92
93		for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
94			harvest = RREG32_SOC15(VCN, i, mmCC_UVD_HARVESTING);
95			if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK)
96				adev->vcn.harvest_config |= 1 << i;
97		}
98		if (adev->vcn.harvest_config == (AMDGPU_VCN_HARVEST_VCN0 |
99					AMDGPU_VCN_HARVEST_VCN1))
100			/* both instances are harvested, disable the block */
101			return -ENOENT;
102
103		adev->vcn.num_enc_rings = 2;
104	}
105
106	vcn_v2_5_set_dec_ring_funcs(adev);
107	vcn_v2_5_set_enc_ring_funcs(adev);
108	vcn_v2_5_set_irq_funcs(adev);
109	vcn_v2_5_set_ras_funcs(adev);
110
111	return amdgpu_vcn_early_init(adev);
112}
113
114/**
115 * vcn_v2_5_sw_init - sw init for VCN block
116 *
117 * @handle: amdgpu_device pointer
118 *
119 * Load firmware and sw initialization
120 */
121static int vcn_v2_5_sw_init(void *handle)
122{
123	struct amdgpu_ring *ring;
124	int i, j, r;
125	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
126
127	for (j = 0; j < adev->vcn.num_vcn_inst; j++) {
128		if (adev->vcn.harvest_config & (1 << j))
129			continue;
130		/* VCN DEC TRAP */
131		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
132				VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT, &adev->vcn.inst[j].irq);
133		if (r)
134			return r;
135
136		/* VCN ENC TRAP */
137		for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
138			r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
139				i + VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst[j].irq);
140			if (r)
141				return r;
142		}
143
144		/* VCN POISON TRAP */
145		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_vcns[j],
146			VCN_2_6__SRCID_UVD_POISON, &adev->vcn.inst[j].ras_poison_irq);
147		if (r)
148			return r;
149	}
150
151	r = amdgpu_vcn_sw_init(adev);
152	if (r)
153		return r;
154
155	amdgpu_vcn_setup_ucode(adev);
156
157	r = amdgpu_vcn_resume(adev);
158	if (r)
159		return r;
160
161	for (j = 0; j < adev->vcn.num_vcn_inst; j++) {
162		volatile struct amdgpu_fw_shared *fw_shared;
163
164		if (adev->vcn.harvest_config & (1 << j))
165			continue;
166		adev->vcn.internal.context_id = mmUVD_CONTEXT_ID_INTERNAL_OFFSET;
167		adev->vcn.internal.ib_vmid = mmUVD_LMI_RBC_IB_VMID_INTERNAL_OFFSET;
168		adev->vcn.internal.ib_bar_low = mmUVD_LMI_RBC_IB_64BIT_BAR_LOW_INTERNAL_OFFSET;
169		adev->vcn.internal.ib_bar_high = mmUVD_LMI_RBC_IB_64BIT_BAR_HIGH_INTERNAL_OFFSET;
170		adev->vcn.internal.ib_size = mmUVD_RBC_IB_SIZE_INTERNAL_OFFSET;
171		adev->vcn.internal.gp_scratch8 = mmUVD_GP_SCRATCH8_INTERNAL_OFFSET;
172
173		adev->vcn.internal.scratch9 = mmUVD_SCRATCH9_INTERNAL_OFFSET;
174		adev->vcn.inst[j].external.scratch9 = SOC15_REG_OFFSET(VCN, j, mmUVD_SCRATCH9);
175		adev->vcn.internal.data0 = mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET;
176		adev->vcn.inst[j].external.data0 = SOC15_REG_OFFSET(VCN, j, mmUVD_GPCOM_VCPU_DATA0);
177		adev->vcn.internal.data1 = mmUVD_GPCOM_VCPU_DATA1_INTERNAL_OFFSET;
178		adev->vcn.inst[j].external.data1 = SOC15_REG_OFFSET(VCN, j, mmUVD_GPCOM_VCPU_DATA1);
179		adev->vcn.internal.cmd = mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET;
180		adev->vcn.inst[j].external.cmd = SOC15_REG_OFFSET(VCN, j, mmUVD_GPCOM_VCPU_CMD);
181		adev->vcn.internal.nop = mmUVD_NO_OP_INTERNAL_OFFSET;
182		adev->vcn.inst[j].external.nop = SOC15_REG_OFFSET(VCN, j, mmUVD_NO_OP);
183
184		ring = &adev->vcn.inst[j].ring_dec;
185		ring->use_doorbell = true;
186
187		ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
188				(amdgpu_sriov_vf(adev) ? 2*j : 8*j);
189
190		if (adev->ip_versions[UVD_HWIP][0] == IP_VERSION(2, 5, 0))
191			ring->vm_hub = AMDGPU_MMHUB1(0);
192		else
193			ring->vm_hub = AMDGPU_MMHUB0(0);
194
195		snprintf(ring->name, sizeof(ring->name), "vcn_dec_%d", j);
196		r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[j].irq,
197				     0, AMDGPU_RING_PRIO_DEFAULT, NULL);
198		if (r)
199			return r;
200
201		for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
202			enum amdgpu_ring_priority_level hw_prio = amdgpu_vcn_get_enc_ring_prio(i);
203
204			ring = &adev->vcn.inst[j].ring_enc[i];
205			ring->use_doorbell = true;
206
207			ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
208					(amdgpu_sriov_vf(adev) ? (1 + i + 2*j) : (2 + i + 8*j));
209
210			if (adev->ip_versions[UVD_HWIP][0] == IP_VERSION(2, 5, 0))
211				ring->vm_hub = AMDGPU_MMHUB1(0);
212			else
213				ring->vm_hub = AMDGPU_MMHUB0(0);
214
215			snprintf(ring->name, sizeof(ring->name), "vcn_enc_%d.%d", j, i);
216			r = amdgpu_ring_init(adev, ring, 512,
217					     &adev->vcn.inst[j].irq, 0,
218					     hw_prio, NULL);
219			if (r)
220				return r;
221		}
222
223		fw_shared = adev->vcn.inst[j].fw_shared.cpu_addr;
224		fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_VCN_MULTI_QUEUE_FLAG);
225
226		if (amdgpu_vcnfw_log)
227			amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
228	}
229
230	if (amdgpu_sriov_vf(adev)) {
231		r = amdgpu_virt_alloc_mm_table(adev);
232		if (r)
233			return r;
234	}
235
236	if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
237		adev->vcn.pause_dpg_mode = vcn_v2_5_pause_dpg_mode;
238
239	r = amdgpu_vcn_ras_sw_init(adev);
240	if (r)
241		return r;
242
243	return 0;
244}
245
246/**
247 * vcn_v2_5_sw_fini - sw fini for VCN block
248 *
249 * @handle: amdgpu_device pointer
250 *
251 * VCN suspend and free up sw allocation
252 */
253static int vcn_v2_5_sw_fini(void *handle)
254{
255	int i, r, idx;
256	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
257	volatile struct amdgpu_fw_shared *fw_shared;
258
259	if (drm_dev_enter(adev_to_drm(adev), &idx)) {
260		for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
261			if (adev->vcn.harvest_config & (1 << i))
262				continue;
263			fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
264			fw_shared->present_flag_0 = 0;
265		}
266		drm_dev_exit(idx);
267	}
268
269
270	if (amdgpu_sriov_vf(adev))
271		amdgpu_virt_free_mm_table(adev);
272
273	r = amdgpu_vcn_suspend(adev);
274	if (r)
275		return r;
276
277	r = amdgpu_vcn_sw_fini(adev);
278
279	return r;
280}
281
282/**
283 * vcn_v2_5_hw_init - start and test VCN block
284 *
285 * @handle: amdgpu_device pointer
286 *
287 * Initialize the hardware, boot up the VCPU and do some testing
288 */
289static int vcn_v2_5_hw_init(void *handle)
290{
291	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
292	struct amdgpu_ring *ring;
293	int i, j, r = 0;
294
295	if (amdgpu_sriov_vf(adev))
296		r = vcn_v2_5_sriov_start(adev);
297
298	for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
299		if (adev->vcn.harvest_config & (1 << j))
300			continue;
301
302		if (amdgpu_sriov_vf(adev)) {
303			adev->vcn.inst[j].ring_enc[0].sched.ready = true;
304			adev->vcn.inst[j].ring_enc[1].sched.ready = false;
305			adev->vcn.inst[j].ring_enc[2].sched.ready = false;
306			adev->vcn.inst[j].ring_dec.sched.ready = true;
307		} else {
308
309			ring = &adev->vcn.inst[j].ring_dec;
310
311			adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
312						     ring->doorbell_index, j);
313
314			r = amdgpu_ring_test_helper(ring);
315			if (r)
316				goto done;
317
318			for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
319				ring = &adev->vcn.inst[j].ring_enc[i];
320				r = amdgpu_ring_test_helper(ring);
321				if (r)
322					goto done;
323			}
324		}
325	}
326
327done:
328	if (!r)
329		DRM_INFO("VCN decode and encode initialized successfully(under %s).\n",
330			(adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)?"DPG Mode":"SPG Mode");
331
332	return r;
333}
334
335/**
336 * vcn_v2_5_hw_fini - stop the hardware block
337 *
338 * @handle: amdgpu_device pointer
339 *
340 * Stop the VCN block, mark ring as not ready any more
341 */
342static int vcn_v2_5_hw_fini(void *handle)
343{
344	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
345	int i;
346
347	cancel_delayed_work_sync(&adev->vcn.idle_work);
348
349	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
350		if (adev->vcn.harvest_config & (1 << i))
351			continue;
352
353		if ((adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) ||
354		    (adev->vcn.cur_state != AMD_PG_STATE_GATE &&
355		     RREG32_SOC15(VCN, i, mmUVD_STATUS)))
356			vcn_v2_5_set_powergating_state(adev, AMD_PG_STATE_GATE);
357
358		if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__VCN))
359			amdgpu_irq_put(adev, &adev->vcn.inst[i].ras_poison_irq, 0);
360	}
361
362	return 0;
363}
364
365/**
366 * vcn_v2_5_suspend - suspend VCN block
367 *
368 * @handle: amdgpu_device pointer
369 *
370 * HW fini and suspend VCN block
371 */
372static int vcn_v2_5_suspend(void *handle)
373{
374	int r;
375	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
376
377	r = vcn_v2_5_hw_fini(adev);
378	if (r)
379		return r;
380
381	r = amdgpu_vcn_suspend(adev);
382
383	return r;
384}
385
386/**
387 * vcn_v2_5_resume - resume VCN block
388 *
389 * @handle: amdgpu_device pointer
390 *
391 * Resume firmware and hw init VCN block
392 */
393static int vcn_v2_5_resume(void *handle)
394{
395	int r;
396	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
397
398	r = amdgpu_vcn_resume(adev);
399	if (r)
400		return r;
401
402	r = vcn_v2_5_hw_init(adev);
403
404	return r;
405}
406
407/**
408 * vcn_v2_5_mc_resume - memory controller programming
409 *
410 * @adev: amdgpu_device pointer
411 *
412 * Let the VCN memory controller know it's offsets
413 */
414static void vcn_v2_5_mc_resume(struct amdgpu_device *adev)
415{
416	uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
417	uint32_t offset;
418	int i;
419
420	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
421		if (adev->vcn.harvest_config & (1 << i))
422			continue;
423		/* cache window 0: fw */
424		if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
425			WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
426				(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo));
427			WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
428				(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi));
429			WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_OFFSET0, 0);
430			offset = 0;
431		} else {
432			WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
433				lower_32_bits(adev->vcn.inst[i].gpu_addr));
434			WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
435				upper_32_bits(adev->vcn.inst[i].gpu_addr));
436			offset = size;
437			WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_OFFSET0,
438				AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
439		}
440		WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_SIZE0, size);
441
442		/* cache window 1: stack */
443		WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
444			lower_32_bits(adev->vcn.inst[i].gpu_addr + offset));
445		WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
446			upper_32_bits(adev->vcn.inst[i].gpu_addr + offset));
447		WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_OFFSET1, 0);
448		WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE);
449
450		/* cache window 2: context */
451		WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
452			lower_32_bits(adev->vcn.inst[i].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
453		WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
454			upper_32_bits(adev->vcn.inst[i].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
455		WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_OFFSET2, 0);
456		WREG32_SOC15(VCN, i, mmUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);
457
458		/* non-cache window */
459		WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW,
460			lower_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
461		WREG32_SOC15(VCN, i, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH,
462			upper_32_bits(adev->vcn.inst[i].fw_shared.gpu_addr));
463		WREG32_SOC15(VCN, i, mmUVD_VCPU_NONCACHE_OFFSET0, 0);
464		WREG32_SOC15(VCN, i, mmUVD_VCPU_NONCACHE_SIZE0,
465			AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)));
466	}
467}
468
469static void vcn_v2_5_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
470{
471	uint32_t size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
472	uint32_t offset;
473
474	/* cache window 0: fw */
475	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
476		if (!indirect) {
477			WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
478				VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
479				(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_lo), 0, indirect);
480			WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
481				VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
482				(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_hi), 0, indirect);
483			WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
484				VCN, 0, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
485		} else {
486			WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
487				VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect);
488			WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
489				VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect);
490			WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
491				VCN, 0, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
492		}
493		offset = 0;
494	} else {
495		WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
496			VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
497			lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
498		WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
499			VCN, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
500			upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
501		offset = size;
502		WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
503			VCN, 0, mmUVD_VCPU_CACHE_OFFSET0),
504			AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect);
505	}
506
507	if (!indirect)
508		WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
509			VCN, 0, mmUVD_VCPU_CACHE_SIZE0), size, 0, indirect);
510	else
511		WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
512			VCN, 0, mmUVD_VCPU_CACHE_SIZE0), 0, 0, indirect);
513
514	/* cache window 1: stack */
515	if (!indirect) {
516		WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
517			VCN, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
518			lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
519		WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
520			VCN, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
521			upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
522		WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
523			VCN, 0, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
524	} else {
525		WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
526			VCN, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect);
527		WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
528			VCN, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect);
529		WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
530			VCN, 0, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
531	}
532	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
533		VCN, 0, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect);
534
535	/* cache window 2: context */
536	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
537		VCN, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
538		lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
539	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
540		VCN, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
541		upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
542	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
543		VCN, 0, mmUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect);
544	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
545		VCN, 0, mmUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect);
546
547	/* non-cache window */
548	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
549		VCN, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
550		lower_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
551	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
552		VCN, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
553		upper_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
554	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
555		VCN, 0, mmUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
556	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
557		VCN, 0, mmUVD_VCPU_NONCACHE_SIZE0),
558		AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_fw_shared)), 0, indirect);
559
560	/* VCN global tiling registers */
561	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
562		VCN, 0, mmUVD_GFX8_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect);
563}
564
565/**
566 * vcn_v2_5_disable_clock_gating - disable VCN clock gating
567 *
568 * @adev: amdgpu_device pointer
569 *
570 * Disable clock gating for VCN block
571 */
572static void vcn_v2_5_disable_clock_gating(struct amdgpu_device *adev)
573{
574	uint32_t data;
575	int i;
576
577	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
578		if (adev->vcn.harvest_config & (1 << i))
579			continue;
580		/* UVD disable CGC */
581		data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
582		if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
583			data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
584		else
585			data &= ~UVD_CGC_CTRL__DYN_CLOCK_MODE_MASK;
586		data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
587		data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
588		WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
589
590		data = RREG32_SOC15(VCN, i, mmUVD_CGC_GATE);
591		data &= ~(UVD_CGC_GATE__SYS_MASK
592			| UVD_CGC_GATE__UDEC_MASK
593			| UVD_CGC_GATE__MPEG2_MASK
594			| UVD_CGC_GATE__REGS_MASK
595			| UVD_CGC_GATE__RBC_MASK
596			| UVD_CGC_GATE__LMI_MC_MASK
597			| UVD_CGC_GATE__LMI_UMC_MASK
598			| UVD_CGC_GATE__IDCT_MASK
599			| UVD_CGC_GATE__MPRD_MASK
600			| UVD_CGC_GATE__MPC_MASK
601			| UVD_CGC_GATE__LBSI_MASK
602			| UVD_CGC_GATE__LRBBM_MASK
603			| UVD_CGC_GATE__UDEC_RE_MASK
604			| UVD_CGC_GATE__UDEC_CM_MASK
605			| UVD_CGC_GATE__UDEC_IT_MASK
606			| UVD_CGC_GATE__UDEC_DB_MASK
607			| UVD_CGC_GATE__UDEC_MP_MASK
608			| UVD_CGC_GATE__WCB_MASK
609			| UVD_CGC_GATE__VCPU_MASK
610			| UVD_CGC_GATE__MMSCH_MASK);
611
612		WREG32_SOC15(VCN, i, mmUVD_CGC_GATE, data);
613
614		SOC15_WAIT_ON_RREG(VCN, i, mmUVD_CGC_GATE, 0,  0xFFFFFFFF);
615
616		data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
617		data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK
618			| UVD_CGC_CTRL__UDEC_CM_MODE_MASK
619			| UVD_CGC_CTRL__UDEC_IT_MODE_MASK
620			| UVD_CGC_CTRL__UDEC_DB_MODE_MASK
621			| UVD_CGC_CTRL__UDEC_MP_MODE_MASK
622			| UVD_CGC_CTRL__SYS_MODE_MASK
623			| UVD_CGC_CTRL__UDEC_MODE_MASK
624			| UVD_CGC_CTRL__MPEG2_MODE_MASK
625			| UVD_CGC_CTRL__REGS_MODE_MASK
626			| UVD_CGC_CTRL__RBC_MODE_MASK
627			| UVD_CGC_CTRL__LMI_MC_MODE_MASK
628			| UVD_CGC_CTRL__LMI_UMC_MODE_MASK
629			| UVD_CGC_CTRL__IDCT_MODE_MASK
630			| UVD_CGC_CTRL__MPRD_MODE_MASK
631			| UVD_CGC_CTRL__MPC_MODE_MASK
632			| UVD_CGC_CTRL__LBSI_MODE_MASK
633			| UVD_CGC_CTRL__LRBBM_MODE_MASK
634			| UVD_CGC_CTRL__WCB_MODE_MASK
635			| UVD_CGC_CTRL__VCPU_MODE_MASK
636			| UVD_CGC_CTRL__MMSCH_MODE_MASK);
637		WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
638
639		/* turn on */
640		data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_GATE);
641		data |= (UVD_SUVD_CGC_GATE__SRE_MASK
642			| UVD_SUVD_CGC_GATE__SIT_MASK
643			| UVD_SUVD_CGC_GATE__SMP_MASK
644			| UVD_SUVD_CGC_GATE__SCM_MASK
645			| UVD_SUVD_CGC_GATE__SDB_MASK
646			| UVD_SUVD_CGC_GATE__SRE_H264_MASK
647			| UVD_SUVD_CGC_GATE__SRE_HEVC_MASK
648			| UVD_SUVD_CGC_GATE__SIT_H264_MASK
649			| UVD_SUVD_CGC_GATE__SIT_HEVC_MASK
650			| UVD_SUVD_CGC_GATE__SCM_H264_MASK
651			| UVD_SUVD_CGC_GATE__SCM_HEVC_MASK
652			| UVD_SUVD_CGC_GATE__SDB_H264_MASK
653			| UVD_SUVD_CGC_GATE__SDB_HEVC_MASK
654			| UVD_SUVD_CGC_GATE__SCLR_MASK
655			| UVD_SUVD_CGC_GATE__UVD_SC_MASK
656			| UVD_SUVD_CGC_GATE__ENT_MASK
657			| UVD_SUVD_CGC_GATE__SIT_HEVC_DEC_MASK
658			| UVD_SUVD_CGC_GATE__SIT_HEVC_ENC_MASK
659			| UVD_SUVD_CGC_GATE__SITE_MASK
660			| UVD_SUVD_CGC_GATE__SRE_VP9_MASK
661			| UVD_SUVD_CGC_GATE__SCM_VP9_MASK
662			| UVD_SUVD_CGC_GATE__SIT_VP9_DEC_MASK
663			| UVD_SUVD_CGC_GATE__SDB_VP9_MASK
664			| UVD_SUVD_CGC_GATE__IME_HEVC_MASK);
665		WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_GATE, data);
666
667		data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL);
668		data &= ~(UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
669			| UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
670			| UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
671			| UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
672			| UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
673			| UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
674			| UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
675			| UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
676			| UVD_SUVD_CGC_CTRL__IME_MODE_MASK
677			| UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
678		WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL, data);
679	}
680}
681
682static void vcn_v2_5_clock_gating_dpg_mode(struct amdgpu_device *adev,
683		uint8_t sram_sel, int inst_idx, uint8_t indirect)
684{
685	uint32_t reg_data = 0;
686
687	/* enable sw clock gating control */
688	if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
689		reg_data = 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
690	else
691		reg_data = 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
692	reg_data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
693	reg_data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
694	reg_data &= ~(UVD_CGC_CTRL__UDEC_RE_MODE_MASK |
695		 UVD_CGC_CTRL__UDEC_CM_MODE_MASK |
696		 UVD_CGC_CTRL__UDEC_IT_MODE_MASK |
697		 UVD_CGC_CTRL__UDEC_DB_MODE_MASK |
698		 UVD_CGC_CTRL__UDEC_MP_MODE_MASK |
699		 UVD_CGC_CTRL__SYS_MODE_MASK |
700		 UVD_CGC_CTRL__UDEC_MODE_MASK |
701		 UVD_CGC_CTRL__MPEG2_MODE_MASK |
702		 UVD_CGC_CTRL__REGS_MODE_MASK |
703		 UVD_CGC_CTRL__RBC_MODE_MASK |
704		 UVD_CGC_CTRL__LMI_MC_MODE_MASK |
705		 UVD_CGC_CTRL__LMI_UMC_MODE_MASK |
706		 UVD_CGC_CTRL__IDCT_MODE_MASK |
707		 UVD_CGC_CTRL__MPRD_MODE_MASK |
708		 UVD_CGC_CTRL__MPC_MODE_MASK |
709		 UVD_CGC_CTRL__LBSI_MODE_MASK |
710		 UVD_CGC_CTRL__LRBBM_MODE_MASK |
711		 UVD_CGC_CTRL__WCB_MODE_MASK |
712		 UVD_CGC_CTRL__VCPU_MODE_MASK |
713		 UVD_CGC_CTRL__MMSCH_MODE_MASK);
714	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
715		VCN, 0, mmUVD_CGC_CTRL), reg_data, sram_sel, indirect);
716
717	/* turn off clock gating */
718	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
719		VCN, 0, mmUVD_CGC_GATE), 0, sram_sel, indirect);
720
721	/* turn on SUVD clock gating */
722	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
723		VCN, 0, mmUVD_SUVD_CGC_GATE), 1, sram_sel, indirect);
724
725	/* turn on sw mode in UVD_SUVD_CGC_CTRL */
726	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
727		VCN, 0, mmUVD_SUVD_CGC_CTRL), 0, sram_sel, indirect);
728}
729
730/**
731 * vcn_v2_5_enable_clock_gating - enable VCN clock gating
732 *
733 * @adev: amdgpu_device pointer
734 *
735 * Enable clock gating for VCN block
736 */
737static void vcn_v2_5_enable_clock_gating(struct amdgpu_device *adev)
738{
739	uint32_t data = 0;
740	int i;
741
742	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
743		if (adev->vcn.harvest_config & (1 << i))
744			continue;
745		/* enable UVD CGC */
746		data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
747		if (adev->cg_flags & AMD_CG_SUPPORT_VCN_MGCG)
748			data |= 1 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
749		else
750			data |= 0 << UVD_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
751		data |= 1 << UVD_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
752		data |= 4 << UVD_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
753		WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
754
755		data = RREG32_SOC15(VCN, i, mmUVD_CGC_CTRL);
756		data |= (UVD_CGC_CTRL__UDEC_RE_MODE_MASK
757			| UVD_CGC_CTRL__UDEC_CM_MODE_MASK
758			| UVD_CGC_CTRL__UDEC_IT_MODE_MASK
759			| UVD_CGC_CTRL__UDEC_DB_MODE_MASK
760			| UVD_CGC_CTRL__UDEC_MP_MODE_MASK
761			| UVD_CGC_CTRL__SYS_MODE_MASK
762			| UVD_CGC_CTRL__UDEC_MODE_MASK
763			| UVD_CGC_CTRL__MPEG2_MODE_MASK
764			| UVD_CGC_CTRL__REGS_MODE_MASK
765			| UVD_CGC_CTRL__RBC_MODE_MASK
766			| UVD_CGC_CTRL__LMI_MC_MODE_MASK
767			| UVD_CGC_CTRL__LMI_UMC_MODE_MASK
768			| UVD_CGC_CTRL__IDCT_MODE_MASK
769			| UVD_CGC_CTRL__MPRD_MODE_MASK
770			| UVD_CGC_CTRL__MPC_MODE_MASK
771			| UVD_CGC_CTRL__LBSI_MODE_MASK
772			| UVD_CGC_CTRL__LRBBM_MODE_MASK
773			| UVD_CGC_CTRL__WCB_MODE_MASK
774			| UVD_CGC_CTRL__VCPU_MODE_MASK);
775		WREG32_SOC15(VCN, i, mmUVD_CGC_CTRL, data);
776
777		data = RREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL);
778		data |= (UVD_SUVD_CGC_CTRL__SRE_MODE_MASK
779			| UVD_SUVD_CGC_CTRL__SIT_MODE_MASK
780			| UVD_SUVD_CGC_CTRL__SMP_MODE_MASK
781			| UVD_SUVD_CGC_CTRL__SCM_MODE_MASK
782			| UVD_SUVD_CGC_CTRL__SDB_MODE_MASK
783			| UVD_SUVD_CGC_CTRL__SCLR_MODE_MASK
784			| UVD_SUVD_CGC_CTRL__UVD_SC_MODE_MASK
785			| UVD_SUVD_CGC_CTRL__ENT_MODE_MASK
786			| UVD_SUVD_CGC_CTRL__IME_MODE_MASK
787			| UVD_SUVD_CGC_CTRL__SITE_MODE_MASK);
788		WREG32_SOC15(VCN, i, mmUVD_SUVD_CGC_CTRL, data);
789	}
790}
791
792static void vcn_v2_6_enable_ras(struct amdgpu_device *adev, int inst_idx,
793				bool indirect)
794{
795	uint32_t tmp;
796
797	if (adev->ip_versions[UVD_HWIP][0] != IP_VERSION(2, 6, 0))
798		return;
799
800	tmp = VCN_RAS_CNTL__VCPU_VCODEC_REARM_MASK |
801	      VCN_RAS_CNTL__VCPU_VCODEC_IH_EN_MASK |
802	      VCN_RAS_CNTL__VCPU_VCODEC_PMI_EN_MASK |
803	      VCN_RAS_CNTL__VCPU_VCODEC_STALL_EN_MASK;
804	WREG32_SOC15_DPG_MODE(inst_idx,
805			      SOC15_DPG_MODE_OFFSET(VCN, 0, mmVCN_RAS_CNTL),
806			      tmp, 0, indirect);
807
808	tmp = UVD_VCPU_INT_EN__RASCNTL_VCPU_VCODEC_EN_MASK;
809	WREG32_SOC15_DPG_MODE(inst_idx,
810			      SOC15_DPG_MODE_OFFSET(VCN, 0, mmUVD_VCPU_INT_EN),
811			      tmp, 0, indirect);
812
813	tmp = UVD_SYS_INT_EN__RASCNTL_VCPU_VCODEC_EN_MASK;
814	WREG32_SOC15_DPG_MODE(inst_idx,
815			      SOC15_DPG_MODE_OFFSET(VCN, 0, mmUVD_SYS_INT_EN),
816			      tmp, 0, indirect);
817}
818
819static int vcn_v2_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
820{
821	volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
822	struct amdgpu_ring *ring;
823	uint32_t rb_bufsz, tmp;
824
825	/* disable register anti-hang mechanism */
826	WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 1,
827		~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
828	/* enable dynamic power gating mode */
829	tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS);
830	tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK;
831	tmp |= UVD_POWER_STATUS__UVD_PG_EN_MASK;
832	WREG32_SOC15(VCN, inst_idx, mmUVD_POWER_STATUS, tmp);
833
834	if (indirect)
835		adev->vcn.inst[inst_idx].dpg_sram_curr_addr = (uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr;
836
837	/* enable clock gating */
838	vcn_v2_5_clock_gating_dpg_mode(adev, 0, inst_idx, indirect);
839
840	/* enable VCPU clock */
841	tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
842	tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
843	tmp |= UVD_VCPU_CNTL__BLK_RST_MASK;
844	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
845		VCN, 0, mmUVD_VCPU_CNTL), tmp, 0, indirect);
846
847	/* disable master interupt */
848	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
849		VCN, 0, mmUVD_MASTINT_EN), 0, 0, indirect);
850
851	/* setup mmUVD_LMI_CTRL */
852	tmp = (0x8 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
853		UVD_LMI_CTRL__REQ_MODE_MASK |
854		UVD_LMI_CTRL__CRC_RESET_MASK |
855		UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
856		UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
857		UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
858		(8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
859		0x00100000L);
860	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
861		VCN, 0, mmUVD_LMI_CTRL), tmp, 0, indirect);
862
863	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
864		VCN, 0, mmUVD_MPC_CNTL),
865		0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0, indirect);
866
867	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
868		VCN, 0, mmUVD_MPC_SET_MUXA0),
869		((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
870		 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
871		 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
872		 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0, indirect);
873
874	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
875		VCN, 0, mmUVD_MPC_SET_MUXB0),
876		((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
877		 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
878		 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
879		 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0, indirect);
880
881	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
882		VCN, 0, mmUVD_MPC_SET_MUX),
883		((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
884		 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
885		 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0, indirect);
886
887	vcn_v2_5_mc_resume_dpg_mode(adev, inst_idx, indirect);
888
889	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
890		VCN, 0, mmUVD_REG_XX_MASK), 0x10, 0, indirect);
891	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
892		VCN, 0, mmUVD_RBC_XX_IB_REG_CHECK), 0x3, 0, indirect);
893
894	/* enable LMI MC and UMC channels */
895	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
896		VCN, 0, mmUVD_LMI_CTRL2), 0, 0, indirect);
897
898	vcn_v2_6_enable_ras(adev, inst_idx, indirect);
899
900	/* unblock VCPU register access */
901	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
902		VCN, 0, mmUVD_RB_ARB_CTRL), 0, 0, indirect);
903
904	tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
905	tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
906	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
907		VCN, 0, mmUVD_VCPU_CNTL), tmp, 0, indirect);
908
909	/* enable master interrupt */
910	WREG32_SOC15_DPG_MODE(inst_idx, SOC15_DPG_MODE_OFFSET(
911		VCN, 0, mmUVD_MASTINT_EN),
912		UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect);
913
914	if (indirect)
915		amdgpu_vcn_psp_update_sram(adev, inst_idx, 0);
916
917	ring = &adev->vcn.inst[inst_idx].ring_dec;
918	/* force RBC into idle state */
919	rb_bufsz = order_base_2(ring->ring_size);
920	tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
921	tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
922	tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
923	tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
924	tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
925	WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_CNTL, tmp);
926
927	/* Stall DPG before WPTR/RPTR reset */
928	WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
929		UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK,
930		~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
931	fw_shared->multi_queue.decode_queue_mode |= FW_QUEUE_RING_RESET;
932
933	/* set the write pointer delay */
934	WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR_CNTL, 0);
935
936	/* set the wb address */
937	WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR_ADDR,
938		(upper_32_bits(ring->gpu_addr) >> 2));
939
940	/* program the RB_BASE for ring buffer */
941	WREG32_SOC15(VCN, inst_idx, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
942		lower_32_bits(ring->gpu_addr));
943	WREG32_SOC15(VCN, inst_idx, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
944		upper_32_bits(ring->gpu_addr));
945
946	/* Initialize the ring buffer's read and write pointers */
947	WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR, 0);
948
949	WREG32_SOC15(VCN, inst_idx, mmUVD_SCRATCH2, 0);
950
951	ring->wptr = RREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_RPTR);
952	WREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR,
953		lower_32_bits(ring->wptr));
954
955	fw_shared->multi_queue.decode_queue_mode &= ~FW_QUEUE_RING_RESET;
956	/* Unstall DPG */
957	WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
958		0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
959
960	return 0;
961}
962
963static int vcn_v2_5_start(struct amdgpu_device *adev)
964{
965	struct amdgpu_ring *ring;
966	uint32_t rb_bufsz, tmp;
967	int i, j, k, r;
968
969	if (adev->pm.dpm_enabled)
970		amdgpu_dpm_enable_uvd(adev, true);
971
972	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
973		if (adev->vcn.harvest_config & (1 << i))
974			continue;
975		if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
976			r = vcn_v2_5_start_dpg_mode(adev, i, adev->vcn.indirect_sram);
977			continue;
978		}
979
980		/* disable register anti-hang mechanism */
981		WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_POWER_STATUS), 0,
982			~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
983
984		/* set uvd status busy */
985		tmp = RREG32_SOC15(VCN, i, mmUVD_STATUS) | UVD_STATUS__UVD_BUSY;
986		WREG32_SOC15(VCN, i, mmUVD_STATUS, tmp);
987	}
988
989	if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
990		return 0;
991
992	/*SW clock gating */
993	vcn_v2_5_disable_clock_gating(adev);
994
995	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
996		if (adev->vcn.harvest_config & (1 << i))
997			continue;
998		/* enable VCPU clock */
999		WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
1000			UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK);
1001
1002		/* disable master interrupt */
1003		WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_MASTINT_EN), 0,
1004			~UVD_MASTINT_EN__VCPU_EN_MASK);
1005
1006		/* setup mmUVD_LMI_CTRL */
1007		tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL);
1008		tmp &= ~0xff;
1009		WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL, tmp | 0x8|
1010			UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK	|
1011			UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
1012			UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
1013			UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
1014
1015		/* setup mmUVD_MPC_CNTL */
1016		tmp = RREG32_SOC15(VCN, i, mmUVD_MPC_CNTL);
1017		tmp &= ~UVD_MPC_CNTL__REPLACEMENT_MODE_MASK;
1018		tmp |= 0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT;
1019		WREG32_SOC15(VCN, i, mmUVD_MPC_CNTL, tmp);
1020
1021		/* setup UVD_MPC_SET_MUXA0 */
1022		WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUXA0,
1023			((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
1024			(0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
1025			(0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
1026			(0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)));
1027
1028		/* setup UVD_MPC_SET_MUXB0 */
1029		WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUXB0,
1030			((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
1031			(0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
1032			(0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
1033			(0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)));
1034
1035		/* setup mmUVD_MPC_SET_MUX */
1036		WREG32_SOC15(VCN, i, mmUVD_MPC_SET_MUX,
1037			((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
1038			(0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
1039			(0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)));
1040	}
1041
1042	vcn_v2_5_mc_resume(adev);
1043
1044	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1045		volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
1046		if (adev->vcn.harvest_config & (1 << i))
1047			continue;
1048		/* VCN global tiling registers */
1049		WREG32_SOC15(VCN, i, mmUVD_GFX8_ADDR_CONFIG,
1050			adev->gfx.config.gb_addr_config);
1051		WREG32_SOC15(VCN, i, mmUVD_GFX8_ADDR_CONFIG,
1052			adev->gfx.config.gb_addr_config);
1053
1054		/* enable LMI MC and UMC channels */
1055		WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_LMI_CTRL2), 0,
1056			~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
1057
1058		/* unblock VCPU register access */
1059		WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_RB_ARB_CTRL), 0,
1060			~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
1061
1062		WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
1063			~UVD_VCPU_CNTL__BLK_RST_MASK);
1064
1065		for (k = 0; k < 10; ++k) {
1066			uint32_t status;
1067
1068			for (j = 0; j < 100; ++j) {
1069				status = RREG32_SOC15(VCN, i, mmUVD_STATUS);
1070				if (status & 2)
1071					break;
1072				if (amdgpu_emu_mode == 1)
1073					drm_msleep(500);
1074				else
1075					mdelay(10);
1076			}
1077			r = 0;
1078			if (status & 2)
1079				break;
1080
1081			DRM_ERROR("VCN decode not responding, trying to reset the VCPU!!!\n");
1082			WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
1083				UVD_VCPU_CNTL__BLK_RST_MASK,
1084				~UVD_VCPU_CNTL__BLK_RST_MASK);
1085			mdelay(10);
1086			WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
1087				~UVD_VCPU_CNTL__BLK_RST_MASK);
1088
1089			mdelay(10);
1090			r = -1;
1091		}
1092
1093		if (r) {
1094			DRM_ERROR("VCN decode not responding, giving up!!!\n");
1095			return r;
1096		}
1097
1098		/* enable master interrupt */
1099		WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_MASTINT_EN),
1100			UVD_MASTINT_EN__VCPU_EN_MASK,
1101			~UVD_MASTINT_EN__VCPU_EN_MASK);
1102
1103		/* clear the busy bit of VCN_STATUS */
1104		WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_STATUS), 0,
1105			~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
1106
1107		WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_VMID, 0);
1108
1109		ring = &adev->vcn.inst[i].ring_dec;
1110		/* force RBC into idle state */
1111		rb_bufsz = order_base_2(ring->ring_size);
1112		tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
1113		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
1114		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
1115		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
1116		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
1117		WREG32_SOC15(VCN, i, mmUVD_RBC_RB_CNTL, tmp);
1118
1119		fw_shared->multi_queue.decode_queue_mode |= FW_QUEUE_RING_RESET;
1120		/* program the RB_BASE for ring buffer */
1121		WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_64BIT_BAR_LOW,
1122			lower_32_bits(ring->gpu_addr));
1123		WREG32_SOC15(VCN, i, mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH,
1124			upper_32_bits(ring->gpu_addr));
1125
1126		/* Initialize the ring buffer's read and write pointers */
1127		WREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR, 0);
1128
1129		ring->wptr = RREG32_SOC15(VCN, i, mmUVD_RBC_RB_RPTR);
1130		WREG32_SOC15(VCN, i, mmUVD_RBC_RB_WPTR,
1131				lower_32_bits(ring->wptr));
1132		fw_shared->multi_queue.decode_queue_mode &= ~FW_QUEUE_RING_RESET;
1133
1134		fw_shared->multi_queue.encode_generalpurpose_queue_mode |= FW_QUEUE_RING_RESET;
1135		ring = &adev->vcn.inst[i].ring_enc[0];
1136		WREG32_SOC15(VCN, i, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
1137		WREG32_SOC15(VCN, i, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1138		WREG32_SOC15(VCN, i, mmUVD_RB_BASE_LO, ring->gpu_addr);
1139		WREG32_SOC15(VCN, i, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
1140		WREG32_SOC15(VCN, i, mmUVD_RB_SIZE, ring->ring_size / 4);
1141		fw_shared->multi_queue.encode_generalpurpose_queue_mode &= ~FW_QUEUE_RING_RESET;
1142
1143		fw_shared->multi_queue.encode_lowlatency_queue_mode |= FW_QUEUE_RING_RESET;
1144		ring = &adev->vcn.inst[i].ring_enc[1];
1145		WREG32_SOC15(VCN, i, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
1146		WREG32_SOC15(VCN, i, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1147		WREG32_SOC15(VCN, i, mmUVD_RB_BASE_LO2, ring->gpu_addr);
1148		WREG32_SOC15(VCN, i, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
1149		WREG32_SOC15(VCN, i, mmUVD_RB_SIZE2, ring->ring_size / 4);
1150		fw_shared->multi_queue.encode_lowlatency_queue_mode &= ~FW_QUEUE_RING_RESET;
1151	}
1152
1153	return 0;
1154}
1155
1156static int vcn_v2_5_mmsch_start(struct amdgpu_device *adev,
1157				struct amdgpu_mm_table *table)
1158{
1159	uint32_t data = 0, loop = 0, size = 0;
1160	uint64_t addr = table->gpu_addr;
1161	struct mmsch_v1_1_init_header *header = NULL;
1162
1163	header = (struct mmsch_v1_1_init_header *)table->cpu_addr;
1164	size = header->total_size;
1165
1166	/*
1167	 * 1, write to vce_mmsch_vf_ctx_addr_lo/hi register with GPU mc addr of
1168	 *  memory descriptor location
1169	 */
1170	WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_ADDR_LO, lower_32_bits(addr));
1171	WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_ADDR_HI, upper_32_bits(addr));
1172
1173	/* 2, update vmid of descriptor */
1174	data = RREG32_SOC15(VCN, 0, mmMMSCH_VF_VMID);
1175	data &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK;
1176	/* use domain0 for MM scheduler */
1177	data |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT);
1178	WREG32_SOC15(VCN, 0, mmMMSCH_VF_VMID, data);
1179
1180	/* 3, notify mmsch about the size of this descriptor */
1181	WREG32_SOC15(VCN, 0, mmMMSCH_VF_CTX_SIZE, size);
1182
1183	/* 4, set resp to zero */
1184	WREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP, 0);
1185
1186	/*
1187	 * 5, kick off the initialization and wait until
1188	 * VCE_MMSCH_VF_MAILBOX_RESP becomes non-zero
1189	 */
1190	WREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_HOST, 0x10000001);
1191
1192	data = RREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP);
1193	loop = 10;
1194	while ((data & 0x10000002) != 0x10000002) {
1195		udelay(100);
1196		data = RREG32_SOC15(VCN, 0, mmMMSCH_VF_MAILBOX_RESP);
1197		loop--;
1198		if (!loop)
1199			break;
1200	}
1201
1202	if (!loop) {
1203		dev_err(adev->dev,
1204			"failed to init MMSCH, mmMMSCH_VF_MAILBOX_RESP = %x\n",
1205			data);
1206		return -EBUSY;
1207	}
1208
1209	return 0;
1210}
1211
1212static int vcn_v2_5_sriov_start(struct amdgpu_device *adev)
1213{
1214	struct amdgpu_ring *ring;
1215	uint32_t offset, size, tmp, i, rb_bufsz;
1216	uint32_t table_size = 0;
1217	struct mmsch_v1_0_cmd_direct_write direct_wt = { { 0 } };
1218	struct mmsch_v1_0_cmd_direct_read_modify_write direct_rd_mod_wt = { { 0 } };
1219	struct mmsch_v1_0_cmd_end end = { { 0 } };
1220	uint32_t *init_table = adev->virt.mm_table.cpu_addr;
1221	struct mmsch_v1_1_init_header *header = (struct mmsch_v1_1_init_header *)init_table;
1222
1223	direct_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_WRITE;
1224	direct_rd_mod_wt.cmd_header.command_type = MMSCH_COMMAND__DIRECT_REG_READ_MODIFY_WRITE;
1225	end.cmd_header.command_type = MMSCH_COMMAND__END;
1226
1227	header->version = MMSCH_VERSION;
1228	header->total_size = sizeof(struct mmsch_v1_1_init_header) >> 2;
1229	init_table += header->total_size;
1230
1231	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1232		header->eng[i].table_offset = header->total_size;
1233		header->eng[i].init_status = 0;
1234		header->eng[i].table_size = 0;
1235
1236		table_size = 0;
1237
1238		MMSCH_V1_0_INSERT_DIRECT_RD_MOD_WT(
1239			SOC15_REG_OFFSET(VCN, i, mmUVD_STATUS),
1240			~UVD_STATUS__UVD_BUSY, UVD_STATUS__UVD_BUSY);
1241
1242		size = AMDGPU_GPU_PAGE_ALIGN(adev->vcn.fw->size + 4);
1243		/* mc resume*/
1244		if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
1245			MMSCH_V1_0_INSERT_DIRECT_WT(
1246				SOC15_REG_OFFSET(VCN, i,
1247					mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
1248				adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_lo);
1249			MMSCH_V1_0_INSERT_DIRECT_WT(
1250				SOC15_REG_OFFSET(VCN, i,
1251					mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
1252				adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + i].tmr_mc_addr_hi);
1253			offset = 0;
1254			MMSCH_V1_0_INSERT_DIRECT_WT(
1255				SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET0), 0);
1256		} else {
1257			MMSCH_V1_0_INSERT_DIRECT_WT(
1258				SOC15_REG_OFFSET(VCN, i,
1259					mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
1260				lower_32_bits(adev->vcn.inst[i].gpu_addr));
1261			MMSCH_V1_0_INSERT_DIRECT_WT(
1262				SOC15_REG_OFFSET(VCN, i,
1263					mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
1264				upper_32_bits(adev->vcn.inst[i].gpu_addr));
1265			offset = size;
1266			MMSCH_V1_0_INSERT_DIRECT_WT(
1267				SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET0),
1268				AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
1269		}
1270
1271		MMSCH_V1_0_INSERT_DIRECT_WT(
1272			SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_SIZE0),
1273			size);
1274		MMSCH_V1_0_INSERT_DIRECT_WT(
1275			SOC15_REG_OFFSET(VCN, i,
1276				mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
1277			lower_32_bits(adev->vcn.inst[i].gpu_addr + offset));
1278		MMSCH_V1_0_INSERT_DIRECT_WT(
1279			SOC15_REG_OFFSET(VCN, i,
1280				mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
1281			upper_32_bits(adev->vcn.inst[i].gpu_addr + offset));
1282		MMSCH_V1_0_INSERT_DIRECT_WT(
1283			SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET1),
1284			0);
1285		MMSCH_V1_0_INSERT_DIRECT_WT(
1286			SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_SIZE1),
1287			AMDGPU_VCN_STACK_SIZE);
1288		MMSCH_V1_0_INSERT_DIRECT_WT(
1289			SOC15_REG_OFFSET(VCN, i,
1290				mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
1291			lower_32_bits(adev->vcn.inst[i].gpu_addr + offset +
1292				AMDGPU_VCN_STACK_SIZE));
1293		MMSCH_V1_0_INSERT_DIRECT_WT(
1294			SOC15_REG_OFFSET(VCN, i,
1295				mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
1296			upper_32_bits(adev->vcn.inst[i].gpu_addr + offset +
1297				AMDGPU_VCN_STACK_SIZE));
1298		MMSCH_V1_0_INSERT_DIRECT_WT(
1299			SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_OFFSET2),
1300			0);
1301		MMSCH_V1_0_INSERT_DIRECT_WT(
1302			SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CACHE_SIZE2),
1303			AMDGPU_VCN_CONTEXT_SIZE);
1304
1305		ring = &adev->vcn.inst[i].ring_enc[0];
1306		ring->wptr = 0;
1307
1308		MMSCH_V1_0_INSERT_DIRECT_WT(
1309			SOC15_REG_OFFSET(VCN, i, mmUVD_RB_BASE_LO),
1310			lower_32_bits(ring->gpu_addr));
1311		MMSCH_V1_0_INSERT_DIRECT_WT(
1312			SOC15_REG_OFFSET(VCN, i, mmUVD_RB_BASE_HI),
1313			upper_32_bits(ring->gpu_addr));
1314		MMSCH_V1_0_INSERT_DIRECT_WT(
1315			SOC15_REG_OFFSET(VCN, i, mmUVD_RB_SIZE),
1316			ring->ring_size / 4);
1317
1318		ring = &adev->vcn.inst[i].ring_dec;
1319		ring->wptr = 0;
1320		MMSCH_V1_0_INSERT_DIRECT_WT(
1321			SOC15_REG_OFFSET(VCN, i,
1322				mmUVD_LMI_RBC_RB_64BIT_BAR_LOW),
1323			lower_32_bits(ring->gpu_addr));
1324		MMSCH_V1_0_INSERT_DIRECT_WT(
1325			SOC15_REG_OFFSET(VCN, i,
1326				mmUVD_LMI_RBC_RB_64BIT_BAR_HIGH),
1327			upper_32_bits(ring->gpu_addr));
1328
1329		/* force RBC into idle state */
1330		rb_bufsz = order_base_2(ring->ring_size);
1331		tmp = REG_SET_FIELD(0, UVD_RBC_RB_CNTL, RB_BUFSZ, rb_bufsz);
1332		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_BLKSZ, 1);
1333		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_FETCH, 1);
1334		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_NO_UPDATE, 1);
1335		tmp = REG_SET_FIELD(tmp, UVD_RBC_RB_CNTL, RB_RPTR_WR_EN, 1);
1336		MMSCH_V1_0_INSERT_DIRECT_WT(
1337			SOC15_REG_OFFSET(VCN, i, mmUVD_RBC_RB_CNTL), tmp);
1338
1339		/* add end packet */
1340		memcpy((void *)init_table, &end, sizeof(struct mmsch_v1_0_cmd_end));
1341		table_size += sizeof(struct mmsch_v1_0_cmd_end) / 4;
1342		init_table += sizeof(struct mmsch_v1_0_cmd_end) / 4;
1343
1344		/* refine header */
1345		header->eng[i].table_size = table_size;
1346		header->total_size += table_size;
1347	}
1348
1349	return vcn_v2_5_mmsch_start(adev, &adev->virt.mm_table);
1350}
1351
1352static int vcn_v2_5_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
1353{
1354	uint32_t tmp;
1355
1356	/* Wait for power status to be 1 */
1357	SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1,
1358		UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1359
1360	/* wait for read ptr to be equal to write ptr */
1361	tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR);
1362	SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RB_RPTR, tmp, 0xFFFFFFFF);
1363
1364	tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR2);
1365	SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RB_RPTR2, tmp, 0xFFFFFFFF);
1366
1367	tmp = RREG32_SOC15(VCN, inst_idx, mmUVD_RBC_RB_WPTR) & 0x7FFFFFFF;
1368	SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_RBC_RB_RPTR, tmp, 0xFFFFFFFF);
1369
1370	SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 1,
1371		UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1372
1373	/* disable dynamic power gating mode */
1374	WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS), 0,
1375			~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
1376
1377	return 0;
1378}
1379
1380static int vcn_v2_5_stop(struct amdgpu_device *adev)
1381{
1382	uint32_t tmp;
1383	int i, r = 0;
1384
1385	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1386		if (adev->vcn.harvest_config & (1 << i))
1387			continue;
1388		if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
1389			r = vcn_v2_5_stop_dpg_mode(adev, i);
1390			continue;
1391		}
1392
1393		/* wait for vcn idle */
1394		r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE, 0x7);
1395		if (r)
1396			return r;
1397
1398		tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
1399			UVD_LMI_STATUS__READ_CLEAN_MASK |
1400			UVD_LMI_STATUS__WRITE_CLEAN_MASK |
1401			UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
1402		r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp);
1403		if (r)
1404			return r;
1405
1406		/* block LMI UMC channel */
1407		tmp = RREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2);
1408		tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK;
1409		WREG32_SOC15(VCN, i, mmUVD_LMI_CTRL2, tmp);
1410
1411		tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK|
1412			UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
1413		r = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_LMI_STATUS, tmp, tmp);
1414		if (r)
1415			return r;
1416
1417		/* block VCPU register access */
1418		WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_RB_ARB_CTRL),
1419			UVD_RB_ARB_CTRL__VCPU_DIS_MASK,
1420			~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
1421
1422		/* reset VCPU */
1423		WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL),
1424			UVD_VCPU_CNTL__BLK_RST_MASK,
1425			~UVD_VCPU_CNTL__BLK_RST_MASK);
1426
1427		/* disable VCPU clock */
1428		WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_VCPU_CNTL), 0,
1429			~(UVD_VCPU_CNTL__CLK_EN_MASK));
1430
1431		/* clear status */
1432		WREG32_SOC15(VCN, i, mmUVD_STATUS, 0);
1433
1434		vcn_v2_5_enable_clock_gating(adev);
1435
1436		/* enable register anti-hang mechanism */
1437		WREG32_P(SOC15_REG_OFFSET(VCN, i, mmUVD_POWER_STATUS),
1438			UVD_POWER_STATUS__UVD_POWER_STATUS_MASK,
1439			~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1440	}
1441
1442	if (adev->pm.dpm_enabled)
1443		amdgpu_dpm_enable_uvd(adev, false);
1444
1445	return 0;
1446}
1447
1448static int vcn_v2_5_pause_dpg_mode(struct amdgpu_device *adev,
1449				int inst_idx, struct dpg_pause_state *new_state)
1450{
1451	struct amdgpu_ring *ring;
1452	uint32_t reg_data = 0;
1453	int ret_code = 0;
1454
1455	/* pause/unpause if state is changed */
1456	if (adev->vcn.inst[inst_idx].pause_state.fw_based != new_state->fw_based) {
1457		DRM_DEBUG("dpg pause state changed %d -> %d",
1458			adev->vcn.inst[inst_idx].pause_state.fw_based,	new_state->fw_based);
1459		reg_data = RREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE) &
1460			(~UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
1461
1462		if (new_state->fw_based == VCN_DPG_STATE__PAUSE) {
1463			ret_code = SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 0x1,
1464				UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1465
1466			if (!ret_code) {
1467				volatile struct amdgpu_fw_shared *fw_shared = adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
1468
1469				/* pause DPG */
1470				reg_data |= UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
1471				WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE, reg_data);
1472
1473				/* wait for ACK */
1474				SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_DPG_PAUSE,
1475					   UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK,
1476					   UVD_DPG_PAUSE__NJ_PAUSE_DPG_ACK_MASK);
1477
1478				/* Stall DPG before WPTR/RPTR reset */
1479				WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
1480					   UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK,
1481					   ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
1482
1483				/* Restore */
1484				fw_shared->multi_queue.encode_generalpurpose_queue_mode |= FW_QUEUE_RING_RESET;
1485				ring = &adev->vcn.inst[inst_idx].ring_enc[0];
1486				ring->wptr = 0;
1487				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_LO, ring->gpu_addr);
1488				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
1489				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_SIZE, ring->ring_size / 4);
1490				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_RPTR, lower_32_bits(ring->wptr));
1491				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1492				fw_shared->multi_queue.encode_generalpurpose_queue_mode &= ~FW_QUEUE_RING_RESET;
1493
1494				fw_shared->multi_queue.encode_lowlatency_queue_mode |= FW_QUEUE_RING_RESET;
1495				ring = &adev->vcn.inst[inst_idx].ring_enc[1];
1496				ring->wptr = 0;
1497				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_LO2, ring->gpu_addr);
1498				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_BASE_HI2, upper_32_bits(ring->gpu_addr));
1499				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_SIZE2, ring->ring_size / 4);
1500				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_RPTR2, lower_32_bits(ring->wptr));
1501				WREG32_SOC15(VCN, inst_idx, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1502				fw_shared->multi_queue.encode_lowlatency_queue_mode &= ~FW_QUEUE_RING_RESET;
1503
1504				/* Unstall DPG */
1505				WREG32_P(SOC15_REG_OFFSET(VCN, inst_idx, mmUVD_POWER_STATUS),
1506					   0, ~UVD_POWER_STATUS__STALL_DPG_POWER_UP_MASK);
1507
1508				SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS,
1509					   UVD_PGFSM_CONFIG__UVDM_UVDU_PWR_ON, UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1510			}
1511		} else {
1512			reg_data &= ~UVD_DPG_PAUSE__NJ_PAUSE_DPG_REQ_MASK;
1513			WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_PAUSE, reg_data);
1514			SOC15_WAIT_ON_RREG(VCN, inst_idx, mmUVD_POWER_STATUS, 0x1,
1515				UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
1516		}
1517		adev->vcn.inst[inst_idx].pause_state.fw_based = new_state->fw_based;
1518	}
1519
1520	return 0;
1521}
1522
1523/**
1524 * vcn_v2_5_dec_ring_get_rptr - get read pointer
1525 *
1526 * @ring: amdgpu_ring pointer
1527 *
1528 * Returns the current hardware read pointer
1529 */
1530static uint64_t vcn_v2_5_dec_ring_get_rptr(struct amdgpu_ring *ring)
1531{
1532	struct amdgpu_device *adev = ring->adev;
1533
1534	return RREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_RPTR);
1535}
1536
1537/**
1538 * vcn_v2_5_dec_ring_get_wptr - get write pointer
1539 *
1540 * @ring: amdgpu_ring pointer
1541 *
1542 * Returns the current hardware write pointer
1543 */
1544static uint64_t vcn_v2_5_dec_ring_get_wptr(struct amdgpu_ring *ring)
1545{
1546	struct amdgpu_device *adev = ring->adev;
1547
1548	if (ring->use_doorbell)
1549		return *ring->wptr_cpu_addr;
1550	else
1551		return RREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_WPTR);
1552}
1553
1554/**
1555 * vcn_v2_5_dec_ring_set_wptr - set write pointer
1556 *
1557 * @ring: amdgpu_ring pointer
1558 *
1559 * Commits the write pointer to the hardware
1560 */
1561static void vcn_v2_5_dec_ring_set_wptr(struct amdgpu_ring *ring)
1562{
1563	struct amdgpu_device *adev = ring->adev;
1564
1565	if (ring->use_doorbell) {
1566		*ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
1567		WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1568	} else {
1569		WREG32_SOC15(VCN, ring->me, mmUVD_RBC_RB_WPTR, lower_32_bits(ring->wptr));
1570	}
1571}
1572
1573static const struct amdgpu_ring_funcs vcn_v2_5_dec_ring_vm_funcs = {
1574	.type = AMDGPU_RING_TYPE_VCN_DEC,
1575	.align_mask = 0xf,
1576	.secure_submission_supported = true,
1577	.get_rptr = vcn_v2_5_dec_ring_get_rptr,
1578	.get_wptr = vcn_v2_5_dec_ring_get_wptr,
1579	.set_wptr = vcn_v2_5_dec_ring_set_wptr,
1580	.emit_frame_size =
1581		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
1582		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
1583		8 + /* vcn_v2_0_dec_ring_emit_vm_flush */
1584		14 + 14 + /* vcn_v2_0_dec_ring_emit_fence x2 vm fence */
1585		6,
1586	.emit_ib_size = 8, /* vcn_v2_0_dec_ring_emit_ib */
1587	.emit_ib = vcn_v2_0_dec_ring_emit_ib,
1588	.emit_fence = vcn_v2_0_dec_ring_emit_fence,
1589	.emit_vm_flush = vcn_v2_0_dec_ring_emit_vm_flush,
1590	.test_ring = vcn_v2_0_dec_ring_test_ring,
1591	.test_ib = amdgpu_vcn_dec_ring_test_ib,
1592	.insert_nop = vcn_v2_0_dec_ring_insert_nop,
1593	.insert_start = vcn_v2_0_dec_ring_insert_start,
1594	.insert_end = vcn_v2_0_dec_ring_insert_end,
1595	.pad_ib = amdgpu_ring_generic_pad_ib,
1596	.begin_use = amdgpu_vcn_ring_begin_use,
1597	.end_use = amdgpu_vcn_ring_end_use,
1598	.emit_wreg = vcn_v2_0_dec_ring_emit_wreg,
1599	.emit_reg_wait = vcn_v2_0_dec_ring_emit_reg_wait,
1600	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1601};
1602
1603/**
1604 * vcn_v2_5_enc_ring_get_rptr - get enc read pointer
1605 *
1606 * @ring: amdgpu_ring pointer
1607 *
1608 * Returns the current hardware enc read pointer
1609 */
1610static uint64_t vcn_v2_5_enc_ring_get_rptr(struct amdgpu_ring *ring)
1611{
1612	struct amdgpu_device *adev = ring->adev;
1613
1614	if (ring == &adev->vcn.inst[ring->me].ring_enc[0])
1615		return RREG32_SOC15(VCN, ring->me, mmUVD_RB_RPTR);
1616	else
1617		return RREG32_SOC15(VCN, ring->me, mmUVD_RB_RPTR2);
1618}
1619
1620/**
1621 * vcn_v2_5_enc_ring_get_wptr - get enc write pointer
1622 *
1623 * @ring: amdgpu_ring pointer
1624 *
1625 * Returns the current hardware enc write pointer
1626 */
1627static uint64_t vcn_v2_5_enc_ring_get_wptr(struct amdgpu_ring *ring)
1628{
1629	struct amdgpu_device *adev = ring->adev;
1630
1631	if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
1632		if (ring->use_doorbell)
1633			return *ring->wptr_cpu_addr;
1634		else
1635			return RREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR);
1636	} else {
1637		if (ring->use_doorbell)
1638			return *ring->wptr_cpu_addr;
1639		else
1640			return RREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR2);
1641	}
1642}
1643
1644/**
1645 * vcn_v2_5_enc_ring_set_wptr - set enc write pointer
1646 *
1647 * @ring: amdgpu_ring pointer
1648 *
1649 * Commits the enc write pointer to the hardware
1650 */
1651static void vcn_v2_5_enc_ring_set_wptr(struct amdgpu_ring *ring)
1652{
1653	struct amdgpu_device *adev = ring->adev;
1654
1655	if (ring == &adev->vcn.inst[ring->me].ring_enc[0]) {
1656		if (ring->use_doorbell) {
1657			*ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
1658			WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1659		} else {
1660			WREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR, lower_32_bits(ring->wptr));
1661		}
1662	} else {
1663		if (ring->use_doorbell) {
1664			*ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
1665			WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
1666		} else {
1667			WREG32_SOC15(VCN, ring->me, mmUVD_RB_WPTR2, lower_32_bits(ring->wptr));
1668		}
1669	}
1670}
1671
1672static const struct amdgpu_ring_funcs vcn_v2_5_enc_ring_vm_funcs = {
1673	.type = AMDGPU_RING_TYPE_VCN_ENC,
1674	.align_mask = 0x3f,
1675	.nop = VCN_ENC_CMD_NO_OP,
1676	.get_rptr = vcn_v2_5_enc_ring_get_rptr,
1677	.get_wptr = vcn_v2_5_enc_ring_get_wptr,
1678	.set_wptr = vcn_v2_5_enc_ring_set_wptr,
1679	.emit_frame_size =
1680		SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
1681		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
1682		4 + /* vcn_v2_0_enc_ring_emit_vm_flush */
1683		5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */
1684		1, /* vcn_v2_0_enc_ring_insert_end */
1685	.emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */
1686	.emit_ib = vcn_v2_0_enc_ring_emit_ib,
1687	.emit_fence = vcn_v2_0_enc_ring_emit_fence,
1688	.emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush,
1689	.test_ring = amdgpu_vcn_enc_ring_test_ring,
1690	.test_ib = amdgpu_vcn_enc_ring_test_ib,
1691	.insert_nop = amdgpu_ring_insert_nop,
1692	.insert_end = vcn_v2_0_enc_ring_insert_end,
1693	.pad_ib = amdgpu_ring_generic_pad_ib,
1694	.begin_use = amdgpu_vcn_ring_begin_use,
1695	.end_use = amdgpu_vcn_ring_end_use,
1696	.emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
1697	.emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
1698	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
1699};
1700
1701static void vcn_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev)
1702{
1703	int i;
1704
1705	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1706		if (adev->vcn.harvest_config & (1 << i))
1707			continue;
1708		adev->vcn.inst[i].ring_dec.funcs = &vcn_v2_5_dec_ring_vm_funcs;
1709		adev->vcn.inst[i].ring_dec.me = i;
1710		DRM_INFO("VCN(%d) decode is enabled in VM mode\n", i);
1711	}
1712}
1713
1714static void vcn_v2_5_set_enc_ring_funcs(struct amdgpu_device *adev)
1715{
1716	int i, j;
1717
1718	for (j = 0; j < adev->vcn.num_vcn_inst; ++j) {
1719		if (adev->vcn.harvest_config & (1 << j))
1720			continue;
1721		for (i = 0; i < adev->vcn.num_enc_rings; ++i) {
1722			adev->vcn.inst[j].ring_enc[i].funcs = &vcn_v2_5_enc_ring_vm_funcs;
1723			adev->vcn.inst[j].ring_enc[i].me = j;
1724		}
1725		DRM_INFO("VCN(%d) encode is enabled in VM mode\n", j);
1726	}
1727}
1728
1729static bool vcn_v2_5_is_idle(void *handle)
1730{
1731	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1732	int i, ret = 1;
1733
1734	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1735		if (adev->vcn.harvest_config & (1 << i))
1736			continue;
1737		ret &= (RREG32_SOC15(VCN, i, mmUVD_STATUS) == UVD_STATUS__IDLE);
1738	}
1739
1740	return ret;
1741}
1742
1743static int vcn_v2_5_wait_for_idle(void *handle)
1744{
1745	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1746	int i, ret = 0;
1747
1748	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1749		if (adev->vcn.harvest_config & (1 << i))
1750			continue;
1751		ret = SOC15_WAIT_ON_RREG(VCN, i, mmUVD_STATUS, UVD_STATUS__IDLE,
1752			UVD_STATUS__IDLE);
1753		if (ret)
1754			return ret;
1755	}
1756
1757	return ret;
1758}
1759
1760static int vcn_v2_5_set_clockgating_state(void *handle,
1761					  enum amd_clockgating_state state)
1762{
1763	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1764	bool enable = (state == AMD_CG_STATE_GATE);
1765
1766	if (amdgpu_sriov_vf(adev))
1767		return 0;
1768
1769	if (enable) {
1770		if (!vcn_v2_5_is_idle(handle))
1771			return -EBUSY;
1772		vcn_v2_5_enable_clock_gating(adev);
1773	} else {
1774		vcn_v2_5_disable_clock_gating(adev);
1775	}
1776
1777	return 0;
1778}
1779
1780static int vcn_v2_5_set_powergating_state(void *handle,
1781					  enum amd_powergating_state state)
1782{
1783	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
1784	int ret;
1785
1786	if (amdgpu_sriov_vf(adev))
1787		return 0;
1788
1789	if(state == adev->vcn.cur_state)
1790		return 0;
1791
1792	if (state == AMD_PG_STATE_GATE)
1793		ret = vcn_v2_5_stop(adev);
1794	else
1795		ret = vcn_v2_5_start(adev);
1796
1797	if(!ret)
1798		adev->vcn.cur_state = state;
1799
1800	return ret;
1801}
1802
1803static int vcn_v2_5_set_interrupt_state(struct amdgpu_device *adev,
1804					struct amdgpu_irq_src *source,
1805					unsigned type,
1806					enum amdgpu_interrupt_state state)
1807{
1808	return 0;
1809}
1810
1811static int vcn_v2_6_set_ras_interrupt_state(struct amdgpu_device *adev,
1812					struct amdgpu_irq_src *source,
1813					unsigned int type,
1814					enum amdgpu_interrupt_state state)
1815{
1816	return 0;
1817}
1818
1819static int vcn_v2_5_process_interrupt(struct amdgpu_device *adev,
1820				      struct amdgpu_irq_src *source,
1821				      struct amdgpu_iv_entry *entry)
1822{
1823	uint32_t ip_instance;
1824
1825	switch (entry->client_id) {
1826	case SOC15_IH_CLIENTID_VCN:
1827		ip_instance = 0;
1828		break;
1829	case SOC15_IH_CLIENTID_VCN1:
1830		ip_instance = 1;
1831		break;
1832	default:
1833		DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
1834		return 0;
1835	}
1836
1837	DRM_DEBUG("IH: VCN TRAP\n");
1838
1839	switch (entry->src_id) {
1840	case VCN_2_0__SRCID__UVD_SYSTEM_MESSAGE_INTERRUPT:
1841		amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_dec);
1842		break;
1843	case VCN_2_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
1844		amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[0]);
1845		break;
1846	case VCN_2_0__SRCID__UVD_ENC_LOW_LATENCY:
1847		amdgpu_fence_process(&adev->vcn.inst[ip_instance].ring_enc[1]);
1848		break;
1849	default:
1850		DRM_ERROR("Unhandled interrupt: %d %d\n",
1851			  entry->src_id, entry->src_data[0]);
1852		break;
1853	}
1854
1855	return 0;
1856}
1857
1858static const struct amdgpu_irq_src_funcs vcn_v2_5_irq_funcs = {
1859	.set = vcn_v2_5_set_interrupt_state,
1860	.process = vcn_v2_5_process_interrupt,
1861};
1862
1863static const struct amdgpu_irq_src_funcs vcn_v2_6_ras_irq_funcs = {
1864	.set = vcn_v2_6_set_ras_interrupt_state,
1865	.process = amdgpu_vcn_process_poison_irq,
1866};
1867
1868static void vcn_v2_5_set_irq_funcs(struct amdgpu_device *adev)
1869{
1870	int i;
1871
1872	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
1873		if (adev->vcn.harvest_config & (1 << i))
1874			continue;
1875		adev->vcn.inst[i].irq.num_types = adev->vcn.num_enc_rings + 1;
1876		adev->vcn.inst[i].irq.funcs = &vcn_v2_5_irq_funcs;
1877
1878		adev->vcn.inst[i].ras_poison_irq.num_types = adev->vcn.num_enc_rings + 1;
1879		adev->vcn.inst[i].ras_poison_irq.funcs = &vcn_v2_6_ras_irq_funcs;
1880	}
1881}
1882
1883static const struct amd_ip_funcs vcn_v2_5_ip_funcs = {
1884	.name = "vcn_v2_5",
1885	.early_init = vcn_v2_5_early_init,
1886	.late_init = NULL,
1887	.sw_init = vcn_v2_5_sw_init,
1888	.sw_fini = vcn_v2_5_sw_fini,
1889	.hw_init = vcn_v2_5_hw_init,
1890	.hw_fini = vcn_v2_5_hw_fini,
1891	.suspend = vcn_v2_5_suspend,
1892	.resume = vcn_v2_5_resume,
1893	.is_idle = vcn_v2_5_is_idle,
1894	.wait_for_idle = vcn_v2_5_wait_for_idle,
1895	.check_soft_reset = NULL,
1896	.pre_soft_reset = NULL,
1897	.soft_reset = NULL,
1898	.post_soft_reset = NULL,
1899	.set_clockgating_state = vcn_v2_5_set_clockgating_state,
1900	.set_powergating_state = vcn_v2_5_set_powergating_state,
1901};
1902
1903static const struct amd_ip_funcs vcn_v2_6_ip_funcs = {
1904        .name = "vcn_v2_6",
1905        .early_init = vcn_v2_5_early_init,
1906        .late_init = NULL,
1907        .sw_init = vcn_v2_5_sw_init,
1908        .sw_fini = vcn_v2_5_sw_fini,
1909        .hw_init = vcn_v2_5_hw_init,
1910        .hw_fini = vcn_v2_5_hw_fini,
1911        .suspend = vcn_v2_5_suspend,
1912        .resume = vcn_v2_5_resume,
1913        .is_idle = vcn_v2_5_is_idle,
1914        .wait_for_idle = vcn_v2_5_wait_for_idle,
1915        .check_soft_reset = NULL,
1916        .pre_soft_reset = NULL,
1917        .soft_reset = NULL,
1918        .post_soft_reset = NULL,
1919        .set_clockgating_state = vcn_v2_5_set_clockgating_state,
1920        .set_powergating_state = vcn_v2_5_set_powergating_state,
1921};
1922
1923const struct amdgpu_ip_block_version vcn_v2_5_ip_block =
1924{
1925		.type = AMD_IP_BLOCK_TYPE_VCN,
1926		.major = 2,
1927		.minor = 5,
1928		.rev = 0,
1929		.funcs = &vcn_v2_5_ip_funcs,
1930};
1931
1932const struct amdgpu_ip_block_version vcn_v2_6_ip_block =
1933{
1934		.type = AMD_IP_BLOCK_TYPE_VCN,
1935		.major = 2,
1936		.minor = 6,
1937		.rev = 0,
1938		.funcs = &vcn_v2_6_ip_funcs,
1939};
1940
1941static uint32_t vcn_v2_6_query_poison_by_instance(struct amdgpu_device *adev,
1942			uint32_t instance, uint32_t sub_block)
1943{
1944	uint32_t poison_stat = 0, reg_value = 0;
1945
1946	switch (sub_block) {
1947	case AMDGPU_VCN_V2_6_VCPU_VCODEC:
1948		reg_value = RREG32_SOC15(VCN, instance, mmUVD_RAS_VCPU_VCODEC_STATUS);
1949		poison_stat = REG_GET_FIELD(reg_value, UVD_RAS_VCPU_VCODEC_STATUS, POISONED_PF);
1950		break;
1951	default:
1952		break;
1953	}
1954
1955	if (poison_stat)
1956		dev_info(adev->dev, "Poison detected in VCN%d, sub_block%d\n",
1957			instance, sub_block);
1958
1959	return poison_stat;
1960}
1961
1962static bool vcn_v2_6_query_poison_status(struct amdgpu_device *adev)
1963{
1964	uint32_t inst, sub;
1965	uint32_t poison_stat = 0;
1966
1967	for (inst = 0; inst < adev->vcn.num_vcn_inst; inst++)
1968		for (sub = 0; sub < AMDGPU_VCN_V2_6_MAX_SUB_BLOCK; sub++)
1969			poison_stat +=
1970			vcn_v2_6_query_poison_by_instance(adev, inst, sub);
1971
1972	return !!poison_stat;
1973}
1974
1975const struct amdgpu_ras_block_hw_ops vcn_v2_6_ras_hw_ops = {
1976	.query_poison_status = vcn_v2_6_query_poison_status,
1977};
1978
1979static struct amdgpu_vcn_ras vcn_v2_6_ras = {
1980	.ras_block = {
1981		.hw_ops = &vcn_v2_6_ras_hw_ops,
1982		.ras_late_init = amdgpu_vcn_ras_late_init,
1983	},
1984};
1985
1986static void vcn_v2_5_set_ras_funcs(struct amdgpu_device *adev)
1987{
1988	switch (adev->ip_versions[VCN_HWIP][0]) {
1989	case IP_VERSION(2, 6, 0):
1990		adev->vcn.ras = &vcn_v2_6_ras;
1991		break;
1992	default:
1993		break;
1994	}
1995}
1996