1 /*
2  * Copyright 2024 Advanced Micro Devices, Inc. All rights reserved.
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 "amdgpu.h"
26 #include "amdgpu_vcn.h"
27 #include "amdgpu_pm.h"
28 #include "soc15.h"
29 #include "soc15d.h"
30 #include "soc15_hw_ip.h"
31 #include "vcn_v2_0.h"
32 
33 #include "vcn/vcn_5_0_0_offset.h"
34 #include "vcn/vcn_5_0_0_sh_mask.h"
35 #include "ivsrcid/vcn/irqsrcs_vcn_5_0.h"
36 #include "vcn_v5_0_0.h"
37 #include "vcn_v5_0_1.h"
38 
39 #include <drm/drm_drv.h>
40 
41 static void vcn_v5_0_1_set_unified_ring_funcs(struct amdgpu_device *adev);
42 static void vcn_v5_0_1_set_irq_funcs(struct amdgpu_device *adev);
43 static int vcn_v5_0_1_set_powergating_state(struct amdgpu_ip_block *ip_block,
44 		enum amd_powergating_state state);
45 static void vcn_v5_0_1_unified_ring_set_wptr(struct amdgpu_ring *ring);
46 
47 /**
48  * vcn_v5_0_1_early_init - set function pointers and load microcode
49  *
50  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
51  *
52  * Set ring and irq function pointers
53  * Load microcode from filesystem
54  */
vcn_v5_0_1_early_init(struct amdgpu_ip_block * ip_block)55 static int vcn_v5_0_1_early_init(struct amdgpu_ip_block *ip_block)
56 {
57 	struct amdgpu_device *adev = ip_block->adev;
58 
59 	/* re-use enc ring as unified ring */
60 	adev->vcn.num_enc_rings = 1;
61 
62 	vcn_v5_0_1_set_unified_ring_funcs(adev);
63 	vcn_v5_0_1_set_irq_funcs(adev);
64 
65 	return amdgpu_vcn_early_init(adev);
66 }
67 
68 /**
69  * vcn_v5_0_1_sw_init - sw init for VCN block
70  *
71  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
72  *
73  * Load firmware and sw initialization
74  */
vcn_v5_0_1_sw_init(struct amdgpu_ip_block * ip_block)75 static int vcn_v5_0_1_sw_init(struct amdgpu_ip_block *ip_block)
76 {
77 	struct amdgpu_device *adev = ip_block->adev;
78 	struct amdgpu_ring *ring;
79 	int i, r, vcn_inst;
80 
81 	r = amdgpu_vcn_sw_init(adev);
82 	if (r)
83 		return r;
84 
85 	amdgpu_vcn_setup_ucode(adev);
86 
87 	r = amdgpu_vcn_resume(adev);
88 	if (r)
89 		return r;
90 
91 	/* VCN UNIFIED TRAP */
92 	r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
93 		VCN_5_0__SRCID__UVD_ENC_GENERAL_PURPOSE, &adev->vcn.inst->irq);
94 	if (r)
95 		return r;
96 
97 	for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
98 		volatile struct amdgpu_vcn5_fw_shared *fw_shared;
99 
100 		vcn_inst = GET_INST(VCN, i);
101 
102 		ring = &adev->vcn.inst[i].ring_enc[0];
103 		ring->use_doorbell = true;
104 		ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 9 * vcn_inst;
105 
106 		ring->vm_hub = AMDGPU_MMHUB0(adev->vcn.inst[i].aid_id);
107 		sprintf(ring->name, "vcn_unified_%d", adev->vcn.inst[i].aid_id);
108 
109 		r = amdgpu_ring_init(adev, ring, 512, &adev->vcn.inst[i].irq, 0,
110 					AMDGPU_RING_PRIO_DEFAULT, &adev->vcn.inst[i].sched_score);
111 		if (r)
112 			return r;
113 
114 		fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
115 		fw_shared->present_flag_0 = cpu_to_le32(AMDGPU_FW_SHARED_FLAG_0_UNIFIED_QUEUE);
116 		fw_shared->sq.is_enabled = true;
117 
118 		if (amdgpu_vcnfw_log)
119 			amdgpu_vcn_fwlog_init(&adev->vcn.inst[i]);
120 	}
121 
122 	/* TODO: Add queue reset mask when FW fully supports it */
123 	adev->vcn.supported_reset =
124 		amdgpu_get_soft_full_reset_mask(&adev->vcn.inst[0].ring_enc[0]);
125 
126 	vcn_v5_0_0_alloc_ip_dump(adev);
127 
128 	return amdgpu_vcn_sysfs_reset_mask_init(adev);
129 }
130 
131 /**
132  * vcn_v5_0_1_sw_fini - sw fini for VCN block
133  *
134  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
135  *
136  * VCN suspend and free up sw allocation
137  */
vcn_v5_0_1_sw_fini(struct amdgpu_ip_block * ip_block)138 static int vcn_v5_0_1_sw_fini(struct amdgpu_ip_block *ip_block)
139 {
140 	struct amdgpu_device *adev = ip_block->adev;
141 	int i, r, idx;
142 
143 	if (drm_dev_enter(adev_to_drm(adev), &idx)) {
144 		for (i = 0; i < adev->vcn.num_vcn_inst; i++) {
145 			volatile struct amdgpu_vcn4_fw_shared *fw_shared;
146 
147 			fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
148 			fw_shared->present_flag_0 = 0;
149 			fw_shared->sq.is_enabled = 0;
150 		}
151 
152 		drm_dev_exit(idx);
153 	}
154 
155 	r = amdgpu_vcn_suspend(adev);
156 	if (r)
157 		return r;
158 
159 	r = amdgpu_vcn_sw_fini(adev);
160 
161 	amdgpu_vcn_sysfs_reset_mask_fini(adev);
162 
163 	kfree(adev->vcn.ip_dump);
164 
165 	return r;
166 }
167 
168 /**
169  * vcn_v5_0_1_hw_init - start and test VCN block
170  *
171  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
172  *
173  * Initialize the hardware, boot up the VCPU and do some testing
174  */
vcn_v5_0_1_hw_init(struct amdgpu_ip_block * ip_block)175 static int vcn_v5_0_1_hw_init(struct amdgpu_ip_block *ip_block)
176 {
177 	struct amdgpu_device *adev = ip_block->adev;
178 	struct amdgpu_ring *ring;
179 	int i, r, vcn_inst;
180 
181 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
182 		vcn_inst = GET_INST(VCN, i);
183 		ring = &adev->vcn.inst[i].ring_enc[0];
184 
185 		if (ring->use_doorbell)
186 			adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
187 				((adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
188 				 9 * vcn_inst),
189 				adev->vcn.inst[i].aid_id);
190 
191 		r = amdgpu_ring_test_helper(ring);
192 		if (r)
193 			return r;
194 	}
195 
196 	return 0;
197 }
198 
199 /**
200  * vcn_v5_0_1_hw_fini - stop the hardware block
201  *
202  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
203  *
204  * Stop the VCN block, mark ring as not ready any more
205  */
vcn_v5_0_1_hw_fini(struct amdgpu_ip_block * ip_block)206 static int vcn_v5_0_1_hw_fini(struct amdgpu_ip_block *ip_block)
207 {
208 	struct amdgpu_device *adev = ip_block->adev;
209 
210 	cancel_delayed_work_sync(&adev->vcn.idle_work);
211 
212 	return 0;
213 }
214 
215 /**
216  * vcn_v5_0_1_suspend - suspend VCN block
217  *
218  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
219  *
220  * HW fini and suspend VCN block
221  */
vcn_v5_0_1_suspend(struct amdgpu_ip_block * ip_block)222 static int vcn_v5_0_1_suspend(struct amdgpu_ip_block *ip_block)
223 {
224 	struct amdgpu_device *adev = ip_block->adev;
225 	int r;
226 
227 	r = vcn_v5_0_1_hw_fini(ip_block);
228 	if (r)
229 		return r;
230 
231 	r = amdgpu_vcn_suspend(adev);
232 
233 	return r;
234 }
235 
236 /**
237  * vcn_v5_0_1_resume - resume VCN block
238  *
239  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
240  *
241  * Resume firmware and hw init VCN block
242  */
vcn_v5_0_1_resume(struct amdgpu_ip_block * ip_block)243 static int vcn_v5_0_1_resume(struct amdgpu_ip_block *ip_block)
244 {
245 	struct amdgpu_device *adev = ip_block->adev;
246 	int r;
247 
248 	r = amdgpu_vcn_resume(adev);
249 	if (r)
250 		return r;
251 
252 	r = vcn_v5_0_1_hw_init(ip_block);
253 
254 	return r;
255 }
256 
257 /**
258  * vcn_v5_0_1_mc_resume - memory controller programming
259  *
260  * @adev: amdgpu_device pointer
261  * @inst: instance number
262  *
263  * Let the VCN memory controller know it's offsets
264  */
vcn_v5_0_1_mc_resume(struct amdgpu_device * adev,int inst)265 static void vcn_v5_0_1_mc_resume(struct amdgpu_device *adev, int inst)
266 {
267 	uint32_t offset, size, vcn_inst;
268 	const struct common_firmware_header *hdr;
269 
270 	hdr = (const struct common_firmware_header *)adev->vcn.inst[inst].fw->data;
271 	size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
272 
273 	vcn_inst = GET_INST(VCN, inst);
274 	/* cache window 0: fw */
275 	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
276 		WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
277 			(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_lo));
278 		WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
279 			(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst].tmr_mc_addr_hi));
280 		WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_OFFSET0, 0);
281 		offset = 0;
282 	} else {
283 		WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW,
284 			lower_32_bits(adev->vcn.inst[inst].gpu_addr));
285 		WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH,
286 			upper_32_bits(adev->vcn.inst[inst].gpu_addr));
287 		offset = size;
288 		WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_OFFSET0,
289 				AMDGPU_UVD_FIRMWARE_OFFSET >> 3);
290 	}
291 	WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_SIZE0, size);
292 
293 	/* cache window 1: stack */
294 	WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW,
295 		lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset));
296 	WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH,
297 		upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset));
298 	WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_OFFSET1, 0);
299 	WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_SIZE1, AMDGPU_VCN_STACK_SIZE);
300 
301 	/* cache window 2: context */
302 	WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW,
303 		lower_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
304 	WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH,
305 		upper_32_bits(adev->vcn.inst[inst].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE));
306 	WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_OFFSET2, 0);
307 	WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_CACHE_SIZE2, AMDGPU_VCN_CONTEXT_SIZE);
308 
309 	/* non-cache window */
310 	WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW,
311 		lower_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr));
312 	WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH,
313 		upper_32_bits(adev->vcn.inst[inst].fw_shared.gpu_addr));
314 	WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_NONCACHE_OFFSET0, 0);
315 	WREG32_SOC15(VCN, vcn_inst, regUVD_VCPU_NONCACHE_SIZE0,
316 		AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared)));
317 }
318 
319 /**
320  * vcn_v5_0_1_mc_resume_dpg_mode - memory controller programming for dpg mode
321  *
322  * @adev: amdgpu_device pointer
323  * @inst_idx: instance number index
324  * @indirect: indirectly write sram
325  *
326  * Let the VCN memory controller know it's offsets with dpg mode
327  */
vcn_v5_0_1_mc_resume_dpg_mode(struct amdgpu_device * adev,int inst_idx,bool indirect)328 static void vcn_v5_0_1_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
329 {
330 	uint32_t offset, size;
331 	const struct common_firmware_header *hdr;
332 
333 	hdr = (const struct common_firmware_header *)adev->vcn.inst[inst_idx].fw->data;
334 	size = AMDGPU_GPU_PAGE_ALIGN(le32_to_cpu(hdr->ucode_size_bytes) + 8);
335 
336 	/* cache window 0: fw */
337 	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
338 		if (!indirect) {
339 			WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
340 				VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
341 				(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN +
342 				 inst_idx].tmr_mc_addr_lo), 0, indirect);
343 			WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
344 				VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
345 				(adev->firmware.ucode[AMDGPU_UCODE_ID_VCN +
346 				 inst_idx].tmr_mc_addr_hi), 0, indirect);
347 			WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
348 				VCN, 0, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
349 		} else {
350 			WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
351 				VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect);
352 			WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
353 				VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect);
354 			WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
355 				VCN, 0, regUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
356 		}
357 		offset = 0;
358 	} else {
359 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
360 			VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
361 			lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
362 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
363 			VCN, 0, regUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
364 			upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
365 		offset = size;
366 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
367 			VCN, 0, regUVD_VCPU_CACHE_OFFSET0),
368 			AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect);
369 	}
370 
371 	if (!indirect)
372 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
373 			VCN, 0, regUVD_VCPU_CACHE_SIZE0), size, 0, indirect);
374 	else
375 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
376 			VCN, 0, regUVD_VCPU_CACHE_SIZE0), 0, 0, indirect);
377 
378 	/* cache window 1: stack */
379 	if (!indirect) {
380 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
381 			VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
382 			lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
383 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
384 			VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
385 			upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
386 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
387 			VCN, 0, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
388 	} else {
389 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
390 			VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect);
391 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
392 			VCN, 0, regUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect);
393 		WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
394 			VCN, 0, regUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
395 	}
396 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
397 			VCN, 0, regUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect);
398 
399 	/* cache window 2: context */
400 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
401 		VCN, 0, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
402 		lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset +
403 			AMDGPU_VCN_STACK_SIZE), 0, indirect);
404 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
405 		VCN, 0, regUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
406 		upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset +
407 			AMDGPU_VCN_STACK_SIZE), 0, indirect);
408 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
409 		VCN, 0, regUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect);
410 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
411 		VCN, 0, regUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect);
412 
413 	/* non-cache window */
414 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
415 		VCN, 0, regUVD_LMI_VCPU_NC0_64BIT_BAR_LOW),
416 		lower_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
417 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
418 		VCN, 0, regUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH),
419 		upper_32_bits(adev->vcn.inst[inst_idx].fw_shared.gpu_addr), 0, indirect);
420 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
421 		VCN, 0, regUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
422 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
423 		VCN, 0, regUVD_VCPU_NONCACHE_SIZE0),
424 		AMDGPU_GPU_PAGE_ALIGN(sizeof(struct amdgpu_vcn4_fw_shared)), 0, indirect);
425 
426 	/* VCN global tiling registers */
427 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
428 		VCN, 0, regUVD_GFX10_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect);
429 }
430 
431 /**
432  * vcn_v5_0_1_disable_clock_gating - disable VCN clock gating
433  *
434  * @adev: amdgpu_device pointer
435  * @inst: instance number
436  *
437  * Disable clock gating for VCN block
438  */
vcn_v5_0_1_disable_clock_gating(struct amdgpu_device * adev,int inst)439 static void vcn_v5_0_1_disable_clock_gating(struct amdgpu_device *adev, int inst)
440 {
441 }
442 
443 /**
444  * vcn_v5_0_1_enable_clock_gating - enable VCN clock gating
445  *
446  * @adev: amdgpu_device pointer
447  * @inst: instance number
448  *
449  * Enable clock gating for VCN block
450  */
vcn_v5_0_1_enable_clock_gating(struct amdgpu_device * adev,int inst)451 static void vcn_v5_0_1_enable_clock_gating(struct amdgpu_device *adev, int inst)
452 {
453 }
454 
455 /**
456  * vcn_v5_0_1_start_dpg_mode - VCN start with dpg mode
457  *
458  * @adev: amdgpu_device pointer
459  * @inst_idx: instance number index
460  * @indirect: indirectly write sram
461  *
462  * Start VCN block with dpg mode
463  */
vcn_v5_0_1_start_dpg_mode(struct amdgpu_device * adev,int inst_idx,bool indirect)464 static int vcn_v5_0_1_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
465 {
466 	volatile struct amdgpu_vcn4_fw_shared *fw_shared =
467 		adev->vcn.inst[inst_idx].fw_shared.cpu_addr;
468 	struct amdgpu_ring *ring;
469 	int vcn_inst;
470 	uint32_t tmp;
471 
472 	vcn_inst = GET_INST(VCN, inst_idx);
473 
474 	/* disable register anti-hang mechanism */
475 	WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_POWER_STATUS), 1,
476 		~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
477 
478 	/* enable dynamic power gating mode */
479 	tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_POWER_STATUS);
480 	tmp |= UVD_POWER_STATUS__UVD_PG_MODE_MASK;
481 	WREG32_SOC15(VCN, vcn_inst, regUVD_POWER_STATUS, tmp);
482 
483 	if (indirect) {
484 		adev->vcn.inst[inst_idx].dpg_sram_curr_addr =
485 			(uint32_t *)adev->vcn.inst[inst_idx].dpg_sram_cpu_addr;
486 		/* Use dummy register 0xDEADBEEF passing AID selection to PSP FW */
487 		WREG32_SOC24_DPG_MODE(inst_idx, 0xDEADBEEF,
488 				adev->vcn.inst[inst_idx].aid_id, 0, true);
489 	}
490 
491 	/* enable VCPU clock */
492 	tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
493 	tmp |= UVD_VCPU_CNTL__CLK_EN_MASK | UVD_VCPU_CNTL__BLK_RST_MASK;
494 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
495 		VCN, 0, regUVD_VCPU_CNTL), tmp, 0, indirect);
496 
497 	/* disable master interrupt */
498 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
499 		VCN, 0, regUVD_MASTINT_EN), 0, 0, indirect);
500 
501 	/* setup regUVD_LMI_CTRL */
502 	tmp = (UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
503 		UVD_LMI_CTRL__REQ_MODE_MASK |
504 		UVD_LMI_CTRL__CRC_RESET_MASK |
505 		UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
506 		UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
507 		UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK |
508 		(8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
509 		0x00100000L);
510 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
511 		VCN, 0, regUVD_LMI_CTRL), tmp, 0, indirect);
512 
513 	vcn_v5_0_1_mc_resume_dpg_mode(adev, inst_idx, indirect);
514 
515 	tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
516 	tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
517 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
518 		VCN, 0, regUVD_VCPU_CNTL), tmp, 0, indirect);
519 
520 	/* enable LMI MC and UMC channels */
521 	tmp = 0x1f << UVD_LMI_CTRL2__RE_OFLD_MIF_WR_REQ_NUM__SHIFT;
522 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
523 		VCN, 0, regUVD_LMI_CTRL2), tmp, 0, indirect);
524 
525 	/* enable master interrupt */
526 	WREG32_SOC24_DPG_MODE(inst_idx, SOC24_DPG_MODE_OFFSET(
527 		VCN, 0, regUVD_MASTINT_EN),
528 		UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect);
529 
530 	if (indirect)
531 		amdgpu_vcn_psp_update_sram(adev, inst_idx, AMDGPU_UCODE_ID_VCN0_RAM);
532 
533 	ring = &adev->vcn.inst[inst_idx].ring_enc[0];
534 
535 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_LO, lower_32_bits(ring->gpu_addr));
536 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
537 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_SIZE, ring->ring_size / sizeof(uint32_t));
538 
539 	tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE);
540 	tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK);
541 	WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp);
542 	fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET;
543 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR, 0);
544 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, 0);
545 
546 	tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR);
547 	WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, tmp);
548 	ring->wptr = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR);
549 
550 	tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE);
551 	tmp |= VCN_RB_ENABLE__RB1_EN_MASK;
552 	WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp);
553 	fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF);
554 
555 	WREG32_SOC15(VCN, vcn_inst, regVCN_RB1_DB_CTRL,
556 		ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT |
557 		VCN_RB1_DB_CTRL__EN_MASK);
558 	/* Read DB_CTRL to flush the write DB_CTRL command. */
559 	RREG32_SOC15(VCN, vcn_inst, regVCN_RB1_DB_CTRL);
560 
561 	return 0;
562 }
563 
564 /**
565  * vcn_v5_0_1_start - VCN start
566  *
567  * @adev: amdgpu_device pointer
568  *
569  * Start VCN block
570  */
vcn_v5_0_1_start(struct amdgpu_device * adev)571 static int vcn_v5_0_1_start(struct amdgpu_device *adev)
572 {
573 	volatile struct amdgpu_vcn4_fw_shared *fw_shared;
574 	struct amdgpu_ring *ring;
575 	uint32_t tmp;
576 	int i, j, k, r, vcn_inst;
577 
578 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
579 		if (adev->pm.dpm_enabled)
580 			amdgpu_dpm_enable_vcn(adev, true, i);
581 	}
582 
583 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
584 		fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
585 
586 		if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
587 			r = vcn_v5_0_1_start_dpg_mode(adev, i, adev->vcn.indirect_sram);
588 			continue;
589 		}
590 
591 		vcn_inst = GET_INST(VCN, i);
592 
593 		/* set VCN status busy */
594 		tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS) | UVD_STATUS__UVD_BUSY;
595 		WREG32_SOC15(VCN, vcn_inst, regUVD_STATUS, tmp);
596 
597 		/* enable VCPU clock */
598 		WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL),
599 			UVD_VCPU_CNTL__CLK_EN_MASK, ~UVD_VCPU_CNTL__CLK_EN_MASK);
600 
601 		/* disable master interrupt */
602 		WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_MASTINT_EN), 0,
603 			~UVD_MASTINT_EN__VCPU_EN_MASK);
604 
605 		/* enable LMI MC and UMC channels */
606 		WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_LMI_CTRL2), 0,
607 			~UVD_LMI_CTRL2__STALL_ARB_UMC_MASK);
608 
609 		tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET);
610 		tmp &= ~UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
611 		tmp &= ~UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
612 		WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp);
613 
614 		/* setup regUVD_LMI_CTRL */
615 		tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL);
616 		WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL, tmp |
617 			UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
618 			UVD_LMI_CTRL__MASK_MC_URGENT_MASK |
619 			UVD_LMI_CTRL__DATA_COHERENCY_EN_MASK |
620 			UVD_LMI_CTRL__VCPU_DATA_COHERENCY_EN_MASK);
621 
622 		vcn_v5_0_1_mc_resume(adev, i);
623 
624 		/* VCN global tiling registers */
625 		WREG32_SOC15(VCN, vcn_inst, regUVD_GFX10_ADDR_CONFIG,
626 			adev->gfx.config.gb_addr_config);
627 
628 		/* unblock VCPU register access */
629 		WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_RB_ARB_CTRL), 0,
630 			~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
631 
632 		/* release VCPU reset to boot */
633 		WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 0,
634 			~UVD_VCPU_CNTL__BLK_RST_MASK);
635 
636 		for (j = 0; j < 10; ++j) {
637 			uint32_t status;
638 
639 			for (k = 0; k < 100; ++k) {
640 				status = RREG32_SOC15(VCN, vcn_inst, regUVD_STATUS);
641 				if (status & 2)
642 					break;
643 				mdelay(100);
644 				if (amdgpu_emu_mode == 1)
645 					msleep(20);
646 			}
647 
648 			if (amdgpu_emu_mode == 1) {
649 				r = -1;
650 				if (status & 2) {
651 					r = 0;
652 					break;
653 				}
654 			} else {
655 				r = 0;
656 				if (status & 2)
657 					break;
658 
659 				dev_err(adev->dev,
660 				    "VCN[%d] is not responding, trying to reset the VCPU!!!\n", i);
661 				WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL),
662 							UVD_VCPU_CNTL__BLK_RST_MASK,
663 							~UVD_VCPU_CNTL__BLK_RST_MASK);
664 				mdelay(10);
665 				WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 0,
666 							~UVD_VCPU_CNTL__BLK_RST_MASK);
667 
668 				mdelay(10);
669 				r = -1;
670 			}
671 		}
672 
673 		if (r) {
674 			dev_err(adev->dev, "VCN[%d] is not responding, giving up!!!\n", i);
675 			return r;
676 		}
677 
678 		/* enable master interrupt */
679 		WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_MASTINT_EN),
680 				UVD_MASTINT_EN__VCPU_EN_MASK,
681 				~UVD_MASTINT_EN__VCPU_EN_MASK);
682 
683 		/* clear the busy bit of VCN_STATUS */
684 		WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_STATUS), 0,
685 			~(2 << UVD_STATUS__VCPU_REPORT__SHIFT));
686 
687 		ring = &adev->vcn.inst[i].ring_enc[0];
688 
689 		WREG32_SOC15(VCN, vcn_inst, regVCN_RB1_DB_CTRL,
690 			ring->doorbell_index << VCN_RB1_DB_CTRL__OFFSET__SHIFT |
691 			VCN_RB1_DB_CTRL__EN_MASK);
692 
693 		/* Read DB_CTRL to flush the write DB_CTRL command. */
694 		RREG32_SOC15(VCN, vcn_inst, regVCN_RB1_DB_CTRL);
695 
696 		WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_LO, ring->gpu_addr);
697 		WREG32_SOC15(VCN, vcn_inst, regUVD_RB_BASE_HI, upper_32_bits(ring->gpu_addr));
698 		WREG32_SOC15(VCN, vcn_inst, regUVD_RB_SIZE, ring->ring_size / 4);
699 
700 		tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE);
701 		tmp &= ~(VCN_RB_ENABLE__RB1_EN_MASK);
702 		WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp);
703 		fw_shared->sq.queue_mode |= FW_QUEUE_RING_RESET;
704 		WREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR, 0);
705 		WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, 0);
706 
707 		tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_RPTR);
708 		WREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR, tmp);
709 		ring->wptr = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR);
710 
711 		tmp = RREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE);
712 		tmp |= VCN_RB_ENABLE__RB1_EN_MASK;
713 		WREG32_SOC15(VCN, vcn_inst, regVCN_RB_ENABLE, tmp);
714 		fw_shared->sq.queue_mode &= ~(FW_QUEUE_RING_RESET | FW_QUEUE_DPG_HOLD_OFF);
715 	}
716 
717 	return 0;
718 }
719 
720 /**
721  * vcn_v5_0_1_stop_dpg_mode - VCN stop with dpg mode
722  *
723  * @adev: amdgpu_device pointer
724  * @inst_idx: instance number index
725  *
726  * Stop VCN block with dpg mode
727  */
vcn_v5_0_1_stop_dpg_mode(struct amdgpu_device * adev,int inst_idx)728 static void vcn_v5_0_1_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
729 {
730 	uint32_t tmp;
731 	int vcn_inst;
732 
733 	vcn_inst = GET_INST(VCN, inst_idx);
734 
735 	/* Wait for power status to be 1 */
736 	SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_POWER_STATUS, 1,
737 		UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
738 
739 	/* wait for read ptr to be equal to write ptr */
740 	tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_RB_WPTR);
741 	SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_RB_RPTR, tmp, 0xFFFFFFFF);
742 
743 	/* disable dynamic power gating mode */
744 	WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_POWER_STATUS), 0,
745 		~UVD_POWER_STATUS__UVD_PG_MODE_MASK);
746 }
747 
748 /**
749  * vcn_v5_0_1_stop - VCN stop
750  *
751  * @adev: amdgpu_device pointer
752  *
753  * Stop VCN block
754  */
vcn_v5_0_1_stop(struct amdgpu_device * adev)755 static int vcn_v5_0_1_stop(struct amdgpu_device *adev)
756 {
757 	volatile struct amdgpu_vcn4_fw_shared *fw_shared;
758 	uint32_t tmp;
759 	int i, r = 0, vcn_inst;
760 
761 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
762 		vcn_inst = GET_INST(VCN, i);
763 
764 		fw_shared = adev->vcn.inst[i].fw_shared.cpu_addr;
765 		fw_shared->sq.queue_mode |= FW_QUEUE_DPG_HOLD_OFF;
766 
767 		if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
768 			vcn_v5_0_1_stop_dpg_mode(adev, i);
769 			continue;
770 		}
771 
772 		/* wait for vcn idle */
773 		r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_STATUS, UVD_STATUS__IDLE, 0x7);
774 		if (r)
775 			return r;
776 
777 		tmp = UVD_LMI_STATUS__VCPU_LMI_WRITE_CLEAN_MASK |
778 		      UVD_LMI_STATUS__READ_CLEAN_MASK |
779 		      UVD_LMI_STATUS__WRITE_CLEAN_MASK |
780 		      UVD_LMI_STATUS__WRITE_CLEAN_RAW_MASK;
781 		r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_LMI_STATUS, tmp, tmp);
782 		if (r)
783 			return r;
784 
785 		/* disable LMI UMC channel */
786 		tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL2);
787 		tmp |= UVD_LMI_CTRL2__STALL_ARB_UMC_MASK;
788 		WREG32_SOC15(VCN, vcn_inst, regUVD_LMI_CTRL2, tmp);
789 		tmp = UVD_LMI_STATUS__UMC_READ_CLEAN_RAW_MASK |
790 		      UVD_LMI_STATUS__UMC_WRITE_CLEAN_RAW_MASK;
791 		r = SOC15_WAIT_ON_RREG(VCN, vcn_inst, regUVD_LMI_STATUS, tmp, tmp);
792 		if (r)
793 			return r;
794 
795 		/* block VCPU register access */
796 		WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_RB_ARB_CTRL),
797 			UVD_RB_ARB_CTRL__VCPU_DIS_MASK,
798 			~UVD_RB_ARB_CTRL__VCPU_DIS_MASK);
799 
800 		/* reset VCPU */
801 		WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL),
802 			UVD_VCPU_CNTL__BLK_RST_MASK,
803 			~UVD_VCPU_CNTL__BLK_RST_MASK);
804 
805 		/* disable VCPU clock */
806 		WREG32_P(SOC15_REG_OFFSET(VCN, vcn_inst, regUVD_VCPU_CNTL), 0,
807 			~(UVD_VCPU_CNTL__CLK_EN_MASK));
808 
809 		/* apply soft reset */
810 		tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET);
811 		tmp |= UVD_SOFT_RESET__LMI_UMC_SOFT_RESET_MASK;
812 		WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp);
813 		tmp = RREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET);
814 		tmp |= UVD_SOFT_RESET__LMI_SOFT_RESET_MASK;
815 		WREG32_SOC15(VCN, vcn_inst, regUVD_SOFT_RESET, tmp);
816 
817 		/* clear status */
818 		WREG32_SOC15(VCN, vcn_inst, regUVD_STATUS, 0);
819 	}
820 
821 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
822 		if (adev->pm.dpm_enabled)
823 			amdgpu_dpm_enable_vcn(adev, false, i);
824 	}
825 
826 	return 0;
827 }
828 
829 /**
830  * vcn_v5_0_1_unified_ring_get_rptr - get unified read pointer
831  *
832  * @ring: amdgpu_ring pointer
833  *
834  * Returns the current hardware unified read pointer
835  */
vcn_v5_0_1_unified_ring_get_rptr(struct amdgpu_ring * ring)836 static uint64_t vcn_v5_0_1_unified_ring_get_rptr(struct amdgpu_ring *ring)
837 {
838 	struct amdgpu_device *adev = ring->adev;
839 
840 	if (ring != &adev->vcn.inst[ring->me].ring_enc[0])
841 		DRM_ERROR("wrong ring id is identified in %s", __func__);
842 
843 	return RREG32_SOC15(VCN, GET_INST(VCN, ring->me), regUVD_RB_RPTR);
844 }
845 
846 /**
847  * vcn_v5_0_1_unified_ring_get_wptr - get unified write pointer
848  *
849  * @ring: amdgpu_ring pointer
850  *
851  * Returns the current hardware unified write pointer
852  */
vcn_v5_0_1_unified_ring_get_wptr(struct amdgpu_ring * ring)853 static uint64_t vcn_v5_0_1_unified_ring_get_wptr(struct amdgpu_ring *ring)
854 {
855 	struct amdgpu_device *adev = ring->adev;
856 
857 	if (ring != &adev->vcn.inst[ring->me].ring_enc[0])
858 		DRM_ERROR("wrong ring id is identified in %s", __func__);
859 
860 	if (ring->use_doorbell)
861 		return *ring->wptr_cpu_addr;
862 	else
863 		return RREG32_SOC15(VCN, GET_INST(VCN, ring->me), regUVD_RB_WPTR);
864 }
865 
866 /**
867  * vcn_v5_0_1_unified_ring_set_wptr - set enc write pointer
868  *
869  * @ring: amdgpu_ring pointer
870  *
871  * Commits the enc write pointer to the hardware
872  */
vcn_v5_0_1_unified_ring_set_wptr(struct amdgpu_ring * ring)873 static void vcn_v5_0_1_unified_ring_set_wptr(struct amdgpu_ring *ring)
874 {
875 	struct amdgpu_device *adev = ring->adev;
876 
877 	if (ring != &adev->vcn.inst[ring->me].ring_enc[0])
878 		DRM_ERROR("wrong ring id is identified in %s", __func__);
879 
880 	if (ring->use_doorbell) {
881 		*ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
882 		WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
883 	} else {
884 		WREG32_SOC15(VCN, GET_INST(VCN, ring->me), regUVD_RB_WPTR,
885 				lower_32_bits(ring->wptr));
886 	}
887 }
888 
889 static const struct amdgpu_ring_funcs vcn_v5_0_1_unified_ring_vm_funcs = {
890 	.type = AMDGPU_RING_TYPE_VCN_ENC,
891 	.align_mask = 0x3f,
892 	.nop = VCN_ENC_CMD_NO_OP,
893 	.get_rptr = vcn_v5_0_1_unified_ring_get_rptr,
894 	.get_wptr = vcn_v5_0_1_unified_ring_get_wptr,
895 	.set_wptr = vcn_v5_0_1_unified_ring_set_wptr,
896 	.emit_frame_size =
897 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 3 +
898 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 4 +
899 		4 + /* vcn_v2_0_enc_ring_emit_vm_flush */
900 		5 + 5 + /* vcn_v2_0_enc_ring_emit_fence x2 vm fence */
901 		1, /* vcn_v2_0_enc_ring_insert_end */
902 	.emit_ib_size = 5, /* vcn_v2_0_enc_ring_emit_ib */
903 	.emit_ib = vcn_v2_0_enc_ring_emit_ib,
904 	.emit_fence = vcn_v2_0_enc_ring_emit_fence,
905 	.emit_vm_flush = vcn_v2_0_enc_ring_emit_vm_flush,
906 	.test_ring = amdgpu_vcn_enc_ring_test_ring,
907 	.test_ib = amdgpu_vcn_unified_ring_test_ib,
908 	.insert_nop = amdgpu_ring_insert_nop,
909 	.insert_end = vcn_v2_0_enc_ring_insert_end,
910 	.pad_ib = amdgpu_ring_generic_pad_ib,
911 	.begin_use = amdgpu_vcn_ring_begin_use,
912 	.end_use = amdgpu_vcn_ring_end_use,
913 	.emit_wreg = vcn_v2_0_enc_ring_emit_wreg,
914 	.emit_reg_wait = vcn_v2_0_enc_ring_emit_reg_wait,
915 	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
916 };
917 
918 /**
919  * vcn_v5_0_1_set_unified_ring_funcs - set unified ring functions
920  *
921  * @adev: amdgpu_device pointer
922  *
923  * Set unified ring functions
924  */
vcn_v5_0_1_set_unified_ring_funcs(struct amdgpu_device * adev)925 static void vcn_v5_0_1_set_unified_ring_funcs(struct amdgpu_device *adev)
926 {
927 	int i, vcn_inst;
928 
929 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
930 		adev->vcn.inst[i].ring_enc[0].funcs = &vcn_v5_0_1_unified_ring_vm_funcs;
931 		adev->vcn.inst[i].ring_enc[0].me = i;
932 		vcn_inst = GET_INST(VCN, i);
933 		adev->vcn.inst[i].aid_id = vcn_inst / adev->vcn.num_inst_per_aid;
934 	}
935 }
936 
937 /**
938  * vcn_v5_0_1_is_idle - check VCN block is idle
939  *
940  * @handle: amdgpu_device pointer
941  *
942  * Check whether VCN block is idle
943  */
vcn_v5_0_1_is_idle(void * handle)944 static bool vcn_v5_0_1_is_idle(void *handle)
945 {
946 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
947 	int i, ret = 1;
948 
949 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i)
950 		ret &= (RREG32_SOC15(VCN, GET_INST(VCN, i), regUVD_STATUS) == UVD_STATUS__IDLE);
951 
952 	return ret;
953 }
954 
955 /**
956  * vcn_v5_0_1_wait_for_idle - wait for VCN block idle
957  *
958  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
959  *
960  * Wait for VCN block idle
961  */
vcn_v5_0_1_wait_for_idle(struct amdgpu_ip_block * ip_block)962 static int vcn_v5_0_1_wait_for_idle(struct amdgpu_ip_block *ip_block)
963 {
964 	struct amdgpu_device *adev = ip_block->adev;
965 	int i, ret = 0;
966 
967 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
968 		ret = SOC15_WAIT_ON_RREG(VCN, GET_INST(VCN, i), regUVD_STATUS, UVD_STATUS__IDLE,
969 			UVD_STATUS__IDLE);
970 		if (ret)
971 			return ret;
972 	}
973 
974 	return ret;
975 }
976 
977 /**
978  * vcn_v5_0_1_set_clockgating_state - set VCN block clockgating state
979  *
980  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
981  * @state: clock gating state
982  *
983  * Set VCN block clockgating state
984  */
vcn_v5_0_1_set_clockgating_state(struct amdgpu_ip_block * ip_block,enum amd_clockgating_state state)985 static int vcn_v5_0_1_set_clockgating_state(struct amdgpu_ip_block *ip_block,
986 					    enum amd_clockgating_state state)
987 {
988 	struct amdgpu_device *adev = ip_block->adev;
989 	bool enable = state == AMD_CG_STATE_GATE;
990 	int i;
991 
992 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
993 		if (enable) {
994 			if (RREG32_SOC15(VCN, GET_INST(VCN, i), regUVD_STATUS) != UVD_STATUS__IDLE)
995 				return -EBUSY;
996 			vcn_v5_0_1_enable_clock_gating(adev, i);
997 		} else {
998 			vcn_v5_0_1_disable_clock_gating(adev, i);
999 		}
1000 	}
1001 
1002 	return 0;
1003 }
1004 
1005 /**
1006  * vcn_v5_0_1_set_powergating_state - set VCN block powergating state
1007  *
1008  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
1009  * @state: power gating state
1010  *
1011  * Set VCN block powergating state
1012  */
vcn_v5_0_1_set_powergating_state(struct amdgpu_ip_block * ip_block,enum amd_powergating_state state)1013 static int vcn_v5_0_1_set_powergating_state(struct amdgpu_ip_block *ip_block,
1014 					    enum amd_powergating_state state)
1015 {
1016 	struct amdgpu_device *adev = ip_block->adev;
1017 	int ret;
1018 
1019 	if (state == adev->vcn.cur_state)
1020 		return 0;
1021 
1022 	if (state == AMD_PG_STATE_GATE)
1023 		ret = vcn_v5_0_1_stop(adev);
1024 	else
1025 		ret = vcn_v5_0_1_start(adev);
1026 
1027 	if (!ret)
1028 		adev->vcn.cur_state = state;
1029 
1030 	return ret;
1031 }
1032 
1033 /**
1034  * vcn_v5_0_1_process_interrupt - process VCN block interrupt
1035  *
1036  * @adev: amdgpu_device pointer
1037  * @source: interrupt sources
1038  * @entry: interrupt entry from clients and sources
1039  *
1040  * Process VCN block interrupt
1041  */
vcn_v5_0_1_process_interrupt(struct amdgpu_device * adev,struct amdgpu_irq_src * source,struct amdgpu_iv_entry * entry)1042 static int vcn_v5_0_1_process_interrupt(struct amdgpu_device *adev, struct amdgpu_irq_src *source,
1043 	struct amdgpu_iv_entry *entry)
1044 {
1045 	uint32_t i, inst;
1046 
1047 	i = node_id_to_phys_map[entry->node_id];
1048 
1049 	DRM_DEV_DEBUG(adev->dev, "IH: VCN TRAP\n");
1050 
1051 	for (inst = 0; inst < adev->vcn.num_vcn_inst; ++inst)
1052 		if (adev->vcn.inst[inst].aid_id == i)
1053 			break;
1054 	if (inst >= adev->vcn.num_vcn_inst) {
1055 		dev_WARN_ONCE(adev->dev, 1,
1056 				"Interrupt received for unknown VCN instance %d",
1057 				entry->node_id);
1058 		return 0;
1059 	}
1060 
1061 	switch (entry->src_id) {
1062 	case VCN_5_0__SRCID__UVD_ENC_GENERAL_PURPOSE:
1063 		amdgpu_fence_process(&adev->vcn.inst[inst].ring_enc[0]);
1064 		break;
1065 	default:
1066 		DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n",
1067 			  entry->src_id, entry->src_data[0]);
1068 		break;
1069 	}
1070 
1071 	return 0;
1072 }
1073 
1074 static const struct amdgpu_irq_src_funcs vcn_v5_0_1_irq_funcs = {
1075 	.process = vcn_v5_0_1_process_interrupt,
1076 };
1077 
1078 /**
1079  * vcn_v5_0_1_set_irq_funcs - set VCN block interrupt irq functions
1080  *
1081  * @adev: amdgpu_device pointer
1082  *
1083  * Set VCN block interrupt irq functions
1084  */
vcn_v5_0_1_set_irq_funcs(struct amdgpu_device * adev)1085 static void vcn_v5_0_1_set_irq_funcs(struct amdgpu_device *adev)
1086 {
1087 	int i;
1088 
1089 	for (i = 0; i < adev->vcn.num_vcn_inst; ++i)
1090 		adev->vcn.inst->irq.num_types++;
1091 	adev->vcn.inst->irq.funcs = &vcn_v5_0_1_irq_funcs;
1092 }
1093 
1094 static const struct amd_ip_funcs vcn_v5_0_1_ip_funcs = {
1095 	.name = "vcn_v5_0_1",
1096 	.early_init = vcn_v5_0_1_early_init,
1097 	.late_init = NULL,
1098 	.sw_init = vcn_v5_0_1_sw_init,
1099 	.sw_fini = vcn_v5_0_1_sw_fini,
1100 	.hw_init = vcn_v5_0_1_hw_init,
1101 	.hw_fini = vcn_v5_0_1_hw_fini,
1102 	.suspend = vcn_v5_0_1_suspend,
1103 	.resume = vcn_v5_0_1_resume,
1104 	.is_idle = vcn_v5_0_1_is_idle,
1105 	.wait_for_idle = vcn_v5_0_1_wait_for_idle,
1106 	.check_soft_reset = NULL,
1107 	.pre_soft_reset = NULL,
1108 	.soft_reset = NULL,
1109 	.post_soft_reset = NULL,
1110 	.set_clockgating_state = vcn_v5_0_1_set_clockgating_state,
1111 	.set_powergating_state = vcn_v5_0_1_set_powergating_state,
1112 	.dump_ip_state = vcn_v5_0_0_dump_ip_state,
1113 	.print_ip_state = vcn_v5_0_0_print_ip_state,
1114 };
1115 
1116 const struct amdgpu_ip_block_version vcn_v5_0_1_ip_block = {
1117 	.type = AMD_IP_BLOCK_TYPE_VCN,
1118 	.major = 5,
1119 	.minor = 0,
1120 	.rev = 1,
1121 	.funcs = &vcn_v5_0_1_ip_funcs,
1122 };
1123