xref: /linux/drivers/gpu/drm/amd/amdgpu/jpeg_v4_0_5.c (revision 220994d61cebfc04f071d69049127657c7e8191b)
1 /*
2  * Copyright 2023 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 "amdgpu.h"
25 #include "amdgpu_jpeg.h"
26 #include "amdgpu_pm.h"
27 #include "soc15.h"
28 #include "soc15d.h"
29 #include "jpeg_v2_0.h"
30 #include "jpeg_v4_0_5.h"
31 #include "mmsch_v4_0.h"
32 
33 #include "vcn/vcn_4_0_5_offset.h"
34 #include "vcn/vcn_4_0_5_sh_mask.h"
35 #include "ivsrcid/vcn/irqsrcs_vcn_4_0.h"
36 
37 #define mmUVD_DPG_LMA_CTL						regUVD_DPG_LMA_CTL
38 #define mmUVD_DPG_LMA_CTL_BASE_IDX					regUVD_DPG_LMA_CTL_BASE_IDX
39 #define mmUVD_DPG_LMA_DATA						regUVD_DPG_LMA_DATA
40 #define mmUVD_DPG_LMA_DATA_BASE_IDX					regUVD_DPG_LMA_DATA_BASE_IDX
41 
42 #define regUVD_JPEG_PITCH_INTERNAL_OFFSET		0x401f
43 #define regJPEG_DEC_GFX10_ADDR_CONFIG_INTERNAL_OFFSET	0x4026
44 #define regJPEG_SYS_INT_EN_INTERNAL_OFFSET		0x4141
45 #define regJPEG_CGC_CTRL_INTERNAL_OFFSET		0x4161
46 #define regJPEG_CGC_GATE_INTERNAL_OFFSET		0x4160
47 #define regUVD_NO_OP_INTERNAL_OFFSET			0x0029
48 
49 static const struct amdgpu_hwip_reg_entry jpeg_reg_list_4_0_5[] = {
50 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_POWER_STATUS),
51 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_INT_STAT),
52 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_RPTR),
53 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_WPTR),
54 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_CNTL),
55 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_SIZE),
56 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_STATUS),
57 	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_ADDR_MODE),
58 	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG),
59 	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_Y_GFX10_TILING_SURFACE),
60 	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_UV_GFX10_TILING_SURFACE),
61 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_PITCH),
62 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_UV_PITCH),
63 };
64 
65 static void jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device *adev);
66 static void jpeg_v4_0_5_set_irq_funcs(struct amdgpu_device *adev);
67 static int jpeg_v4_0_5_set_powergating_state(struct amdgpu_ip_block *ip_block,
68 				enum amd_powergating_state state);
69 static void jpeg_v4_0_5_dec_ring_set_wptr(struct amdgpu_ring *ring);
70 
71 static int amdgpu_ih_clientid_jpeg[] = {
72 	SOC15_IH_CLIENTID_VCN,
73 	SOC15_IH_CLIENTID_VCN1
74 };
75 
76 
77 
78 /**
79  * jpeg_v4_0_5_early_init - set function pointers
80  *
81  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
82  *
83  * Set ring and irq function pointers
84  */
jpeg_v4_0_5_early_init(struct amdgpu_ip_block * ip_block)85 static int jpeg_v4_0_5_early_init(struct amdgpu_ip_block *ip_block)
86 {
87 	struct amdgpu_device *adev = ip_block->adev;
88 
89 	switch (amdgpu_ip_version(adev, UVD_HWIP, 0)) {
90 	case IP_VERSION(4, 0, 5):
91 		adev->jpeg.num_jpeg_inst = 1;
92 		break;
93 	case IP_VERSION(4, 0, 6):
94 		adev->jpeg.num_jpeg_inst = 2;
95 		break;
96 	default:
97 		DRM_DEV_ERROR(adev->dev,
98 			"Failed to init vcn ip block(UVD_HWIP:0x%x)\n",
99 			amdgpu_ip_version(adev, UVD_HWIP, 0));
100 		return -EINVAL;
101 	}
102 
103 	adev->jpeg.num_jpeg_rings = 1;
104 
105 	jpeg_v4_0_5_set_dec_ring_funcs(adev);
106 	jpeg_v4_0_5_set_irq_funcs(adev);
107 
108 	return 0;
109 }
110 
111 /**
112  * jpeg_v4_0_5_sw_init - sw init for JPEG block
113  *
114  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
115  *
116  * Load firmware and sw initialization
117  */
jpeg_v4_0_5_sw_init(struct amdgpu_ip_block * ip_block)118 static int jpeg_v4_0_5_sw_init(struct amdgpu_ip_block *ip_block)
119 {
120 	struct amdgpu_device *adev = ip_block->adev;
121 	struct amdgpu_ring *ring;
122 	int r, i;
123 
124 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
125 		if (adev->jpeg.harvest_config & (1 << i))
126 			continue;
127 
128 		/* JPEG TRAP */
129 		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
130 				VCN_4_0__SRCID__JPEG_DECODE, &adev->jpeg.inst[i].irq);
131 		if (r)
132 			return r;
133 
134 		/* JPEG DJPEG POISON EVENT */
135 		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
136 			VCN_4_0__SRCID_DJPEG0_POISON, &adev->jpeg.inst[i].irq);
137 		if (r)
138 			return r;
139 
140 		/* JPEG EJPEG POISON EVENT */
141 		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
142 			VCN_4_0__SRCID_EJPEG0_POISON, &adev->jpeg.inst[i].irq);
143 		if (r)
144 			return r;
145 	}
146 
147 	r = amdgpu_jpeg_sw_init(adev);
148 	if (r)
149 		return r;
150 
151 	r = amdgpu_jpeg_resume(adev);
152 	if (r)
153 		return r;
154 
155 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
156 		if (adev->jpeg.harvest_config & (1 << i))
157 			continue;
158 
159 		ring = adev->jpeg.inst[i].ring_dec;
160 		ring->use_doorbell = true;
161 		ring->vm_hub = AMDGPU_MMHUB0(0);
162 		ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + 8 * i;
163 		sprintf(ring->name, "jpeg_dec_%d", i);
164 		r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst[i].irq,
165 				     0, AMDGPU_RING_PRIO_DEFAULT, NULL);
166 		if (r)
167 			return r;
168 
169 		adev->jpeg.internal.jpeg_pitch[0] = regUVD_JPEG_PITCH_INTERNAL_OFFSET;
170 		adev->jpeg.inst[i].external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, i, regUVD_JPEG_PITCH);
171 	}
172 
173 	r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_4_0_5, ARRAY_SIZE(jpeg_reg_list_4_0_5));
174 	if (r)
175 		return r;
176 
177 	adev->jpeg.supported_reset =
178 		amdgpu_get_soft_full_reset_mask(&adev->jpeg.inst[0].ring_dec[0]);
179 	if (!amdgpu_sriov_vf(adev))
180 		adev->jpeg.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
181 	r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
182 	if (r)
183 		return r;
184 
185 	return 0;
186 }
187 
188 /**
189  * jpeg_v4_0_5_sw_fini - sw fini for JPEG block
190  *
191  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
192  *
193  * JPEG suspend and free up sw allocation
194  */
jpeg_v4_0_5_sw_fini(struct amdgpu_ip_block * ip_block)195 static int jpeg_v4_0_5_sw_fini(struct amdgpu_ip_block *ip_block)
196 {
197 	struct amdgpu_device *adev = ip_block->adev;
198 	int r;
199 
200 	r = amdgpu_jpeg_suspend(adev);
201 	if (r)
202 		return r;
203 
204 	amdgpu_jpeg_sysfs_reset_mask_fini(adev);
205 	r = amdgpu_jpeg_sw_fini(adev);
206 
207 	return r;
208 }
209 
210 /**
211  * jpeg_v4_0_5_hw_init - start and test JPEG block
212  *
213  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
214  *
215  */
jpeg_v4_0_5_hw_init(struct amdgpu_ip_block * ip_block)216 static int jpeg_v4_0_5_hw_init(struct amdgpu_ip_block *ip_block)
217 {
218 	struct amdgpu_device *adev = ip_block->adev;
219 	struct amdgpu_ring *ring;
220 	int i, r = 0;
221 
222 	// TODO: Enable ring test with DPG support
223 	if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
224 		return 0;
225 	}
226 
227 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
228 		if (adev->jpeg.harvest_config & (1 << i))
229 			continue;
230 
231 		ring = adev->jpeg.inst[i].ring_dec;
232 		r = amdgpu_ring_test_helper(ring);
233 		if (r)
234 			return r;
235 	}
236 
237 	return 0;
238 }
239 
240 /**
241  * jpeg_v4_0_5_hw_fini - stop the hardware block
242  *
243  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
244  *
245  * Stop the JPEG block, mark ring as not ready any more
246  */
jpeg_v4_0_5_hw_fini(struct amdgpu_ip_block * ip_block)247 static int jpeg_v4_0_5_hw_fini(struct amdgpu_ip_block *ip_block)
248 {
249 	struct amdgpu_device *adev = ip_block->adev;
250 	int i;
251 
252 	cancel_delayed_work_sync(&adev->jpeg.idle_work);
253 
254 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
255 		if (adev->jpeg.harvest_config & (1 << i))
256 			continue;
257 
258 		if (!amdgpu_sriov_vf(adev)) {
259 			if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
260 			    RREG32_SOC15(JPEG, i, regUVD_JRBC_STATUS))
261 				jpeg_v4_0_5_set_powergating_state(ip_block, AMD_PG_STATE_GATE);
262 		}
263 	}
264 	return 0;
265 }
266 
267 /**
268  * jpeg_v4_0_5_suspend - suspend JPEG block
269  *
270  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
271  *
272  * HW fini and suspend JPEG block
273  */
jpeg_v4_0_5_suspend(struct amdgpu_ip_block * ip_block)274 static int jpeg_v4_0_5_suspend(struct amdgpu_ip_block *ip_block)
275 {
276 	int r;
277 
278 	r = jpeg_v4_0_5_hw_fini(ip_block);
279 	if (r)
280 		return r;
281 
282 	r = amdgpu_jpeg_suspend(ip_block->adev);
283 
284 	return r;
285 }
286 
287 /**
288  * jpeg_v4_0_5_resume - resume JPEG block
289  *
290  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
291  *
292  * Resume firmware and hw init JPEG block
293  */
jpeg_v4_0_5_resume(struct amdgpu_ip_block * ip_block)294 static int jpeg_v4_0_5_resume(struct amdgpu_ip_block *ip_block)
295 {
296 	int r;
297 
298 	r = amdgpu_jpeg_resume(ip_block->adev);
299 	if (r)
300 		return r;
301 
302 	r = jpeg_v4_0_5_hw_init(ip_block);
303 
304 	return r;
305 }
306 
jpeg_v4_0_5_disable_clock_gating(struct amdgpu_device * adev,int inst)307 static void jpeg_v4_0_5_disable_clock_gating(struct amdgpu_device *adev, int inst)
308 {
309 	uint32_t data = 0;
310 
311 	data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL);
312 	if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) {
313 		data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
314 		data &= (~JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK);
315 	} else {
316 		data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
317 	}
318 
319 	data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
320 	data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
321 	WREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL, data);
322 
323 	data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE);
324 	data &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK
325 		| JPEG_CGC_GATE__JPEG2_DEC_MASK
326 		| JPEG_CGC_GATE__JMCIF_MASK
327 		| JPEG_CGC_GATE__JRBBM_MASK);
328 	WREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE, data);
329 }
330 
jpeg_v4_0_5_enable_clock_gating(struct amdgpu_device * adev,int inst)331 static void jpeg_v4_0_5_enable_clock_gating(struct amdgpu_device *adev, int inst)
332 {
333 	uint32_t data = 0;
334 
335 	data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL);
336 	if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) {
337 		data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
338 		data |= JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK;
339 	} else {
340 		data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
341 	}
342 
343 	data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
344 	data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
345 	WREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL, data);
346 
347 	data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE);
348 	data |= (JPEG_CGC_GATE__JPEG_DEC_MASK
349 		|JPEG_CGC_GATE__JPEG2_DEC_MASK
350 		|JPEG_CGC_GATE__JMCIF_MASK
351 		|JPEG_CGC_GATE__JRBBM_MASK);
352 	WREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE, data);
353 }
354 
jpeg_engine_4_0_5_dpg_clock_gating_mode(struct amdgpu_device * adev,int inst_idx,uint8_t indirect)355 static void jpeg_engine_4_0_5_dpg_clock_gating_mode(struct amdgpu_device *adev,
356 			int inst_idx, uint8_t indirect)
357 {
358 	uint32_t data = 0;
359 
360 	if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG)
361 		data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
362 	else
363 		data |= 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
364 
365 	data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
366 	data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
367 	WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_CGC_CTRL_INTERNAL_OFFSET, data, indirect);
368 
369 	data = 0;
370 	WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_CGC_GATE_INTERNAL_OFFSET,
371 				data, indirect);
372 }
373 
jpeg_v4_0_5_disable_static_power_gating(struct amdgpu_device * adev,int inst)374 static int jpeg_v4_0_5_disable_static_power_gating(struct amdgpu_device *adev, int inst)
375 {
376 	if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
377 		WREG32(SOC15_REG_OFFSET(JPEG, inst, regUVD_IPX_DLDO_CONFIG),
378 			1 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT);
379 		SOC15_WAIT_ON_RREG(JPEG, inst, regUVD_IPX_DLDO_STATUS,
380 			0, UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK);
381 	}
382 
383 	/* disable anti hang mechanism */
384 	WREG32_P(SOC15_REG_OFFSET(JPEG, inst, regUVD_JPEG_POWER_STATUS), 0,
385 		~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
386 
387 	/* keep the JPEG in static PG mode */
388 	WREG32_P(SOC15_REG_OFFSET(JPEG, inst, regUVD_JPEG_POWER_STATUS), 0,
389 		~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK);
390 
391 	return 0;
392 }
393 
jpeg_v4_0_5_enable_static_power_gating(struct amdgpu_device * adev,int inst)394 static int jpeg_v4_0_5_enable_static_power_gating(struct amdgpu_device *adev, int inst)
395 {
396 	/* enable anti hang mechanism */
397 	WREG32_P(SOC15_REG_OFFSET(JPEG, inst, regUVD_JPEG_POWER_STATUS),
398 		UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
399 		~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
400 
401 	if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
402 		WREG32(SOC15_REG_OFFSET(JPEG, inst, regUVD_IPX_DLDO_CONFIG),
403 			2 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT);
404 		SOC15_WAIT_ON_RREG(JPEG, inst, regUVD_IPX_DLDO_STATUS,
405 			1 << UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS__SHIFT,
406 			UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK);
407 	}
408 
409 	return 0;
410 }
411 
412 /**
413  * jpeg_v4_0_5_start_dpg_mode - Jpeg start with dpg mode
414  *
415  * @adev: amdgpu_device pointer
416  * @inst_idx: instance number index
417  * @indirect: indirectly write sram
418  *
419  * Start JPEG block with dpg mode
420  */
jpeg_v4_0_5_start_dpg_mode(struct amdgpu_device * adev,int inst_idx,bool indirect)421 static void jpeg_v4_0_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
422 {
423 	struct amdgpu_ring *ring = adev->jpeg.inst[inst_idx].ring_dec;
424 	uint32_t reg_data = 0;
425 
426 	/* enable anti hang mechanism */
427 	reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS);
428 	reg_data &= ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK;
429 	reg_data |=  0x1;
430 	WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
431 
432 	if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
433 		WREG32(SOC15_REG_OFFSET(JPEG, inst_idx, regUVD_IPX_DLDO_CONFIG),
434 			2 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT);
435 		SOC15_WAIT_ON_RREG(JPEG, inst_idx, regUVD_IPX_DLDO_STATUS,
436 			1 << UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS__SHIFT,
437 			UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK);
438 	}
439 
440 	reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS);
441 	reg_data |= UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK;
442 	WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
443 
444 	if (indirect)
445 		adev->jpeg.inst[inst_idx].dpg_sram_curr_addr =
446 					(uint32_t *)adev->jpeg.inst[inst_idx].dpg_sram_cpu_addr;
447 
448 	jpeg_engine_4_0_5_dpg_clock_gating_mode(adev, inst_idx, indirect);
449 
450 	/* MJPEG global tiling registers */
451 	WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_DEC_GFX10_ADDR_CONFIG_INTERNAL_OFFSET,
452 	adev->gfx.config.gb_addr_config, indirect);
453 	/* enable System Interrupt for JRBC */
454 	WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_SYS_INT_EN_INTERNAL_OFFSET,
455 	JPEG_SYS_INT_EN__DJRBC_MASK, indirect);
456 
457 	/* add nop to workaround PSP size check */
458 	WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regUVD_NO_OP_INTERNAL_OFFSET, 0, indirect);
459 
460 	if (indirect)
461 		amdgpu_jpeg_psp_update_sram(adev, inst_idx, 0);
462 
463 	WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_VMID, 0);
464 	WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
465 	WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
466 		lower_32_bits(ring->gpu_addr));
467 	WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
468 		upper_32_bits(ring->gpu_addr));
469 	WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_RPTR, 0);
470 	WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_WPTR, 0);
471 	WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_CNTL, 0x00000002L);
472 	WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_SIZE, ring->ring_size / 4);
473 	ring->wptr = RREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_WPTR);
474 }
475 
476 /**
477  * jpeg_v4_0_5_stop_dpg_mode - Jpeg stop with dpg mode
478  *
479  * @adev: amdgpu_device pointer
480  * @inst_idx: instance number index
481  *
482  * Stop JPEG block with dpg mode
483  */
jpeg_v4_0_5_stop_dpg_mode(struct amdgpu_device * adev,int inst_idx)484 static void jpeg_v4_0_5_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
485 {
486 	uint32_t reg_data = 0;
487 
488 	reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS);
489 	reg_data &= ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK;
490 	WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
491 
492 }
493 
494 /**
495  * jpeg_v4_0_5_start - start JPEG block
496  *
497  * @adev: amdgpu_device pointer
498  *
499  * Setup and start the JPEG block
500  */
jpeg_v4_0_5_start(struct amdgpu_device * adev)501 static int jpeg_v4_0_5_start(struct amdgpu_device *adev)
502 {
503 	struct amdgpu_ring *ring;
504 	int r, i;
505 
506 	if (adev->pm.dpm_enabled)
507 		amdgpu_dpm_enable_jpeg(adev, true);
508 
509 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
510 		if (adev->jpeg.harvest_config & (1 << i))
511 			continue;
512 
513 		ring = adev->jpeg.inst[i].ring_dec;
514 		/* doorbell programming is done for every playback */
515 		adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
516 				(adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i, i);
517 
518 		WREG32_SOC15(VCN, i, regVCN_JPEG_DB_CTRL,
519 			ring->doorbell_index << VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
520 			VCN_JPEG_DB_CTRL__EN_MASK);
521 
522 		if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
523 			jpeg_v4_0_5_start_dpg_mode(adev, i, adev->jpeg.indirect_sram);
524 			continue;
525 		}
526 
527 		/* disable power gating */
528 		r = jpeg_v4_0_5_disable_static_power_gating(adev, i);
529 		if (r)
530 			return r;
531 
532 		/* JPEG disable CGC */
533 		jpeg_v4_0_5_disable_clock_gating(adev, i);
534 
535 		/* MJPEG global tiling registers */
536 		WREG32_SOC15(JPEG, i, regJPEG_DEC_GFX10_ADDR_CONFIG,
537 			adev->gfx.config.gb_addr_config);
538 
539 		/* enable JMI channel */
540 		WREG32_P(SOC15_REG_OFFSET(JPEG, i, regUVD_JMI_CNTL), 0,
541 			~UVD_JMI_CNTL__SOFT_RESET_MASK);
542 
543 		/* enable System Interrupt for JRBC */
544 		WREG32_P(SOC15_REG_OFFSET(JPEG, i, regJPEG_SYS_INT_EN),
545 			JPEG_SYS_INT_EN__DJRBC_MASK,
546 			~JPEG_SYS_INT_EN__DJRBC_MASK);
547 
548 		WREG32_SOC15(JPEG, i, regUVD_LMI_JRBC_RB_VMID, 0);
549 		WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
550 		WREG32_SOC15(JPEG, i, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
551 			lower_32_bits(ring->gpu_addr));
552 		WREG32_SOC15(JPEG, i, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
553 			upper_32_bits(ring->gpu_addr));
554 		WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_RPTR, 0);
555 		WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_WPTR, 0);
556 		WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_CNTL, 0x00000002L);
557 		WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_SIZE, ring->ring_size / 4);
558 		ring->wptr = RREG32_SOC15(JPEG, i, regUVD_JRBC_RB_WPTR);
559 	}
560 
561 	return 0;
562 }
563 
564 /**
565  * jpeg_v4_0_5_stop - stop JPEG block
566  *
567  * @adev: amdgpu_device pointer
568  *
569  * stop the JPEG block
570  */
jpeg_v4_0_5_stop(struct amdgpu_device * adev)571 static int jpeg_v4_0_5_stop(struct amdgpu_device *adev)
572 {
573 	int r, i;
574 
575 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
576 		if (adev->jpeg.harvest_config & (1 << i))
577 			continue;
578 
579 		if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
580 			jpeg_v4_0_5_stop_dpg_mode(adev, i);
581 			continue;
582 		}
583 
584 		/* reset JMI */
585 		WREG32_P(SOC15_REG_OFFSET(JPEG, i, regUVD_JMI_CNTL),
586 			UVD_JMI_CNTL__SOFT_RESET_MASK,
587 			~UVD_JMI_CNTL__SOFT_RESET_MASK);
588 
589 		jpeg_v4_0_5_enable_clock_gating(adev, i);
590 
591 		/* enable power gating */
592 		r = jpeg_v4_0_5_enable_static_power_gating(adev, i);
593 		if (r)
594 			return r;
595 	}
596 	if (adev->pm.dpm_enabled)
597 		amdgpu_dpm_enable_jpeg(adev, false);
598 
599 	return 0;
600 }
601 
602 /**
603  * jpeg_v4_0_5_dec_ring_get_rptr - get read pointer
604  *
605  * @ring: amdgpu_ring pointer
606  *
607  * Returns the current hardware read pointer
608  */
jpeg_v4_0_5_dec_ring_get_rptr(struct amdgpu_ring * ring)609 static uint64_t jpeg_v4_0_5_dec_ring_get_rptr(struct amdgpu_ring *ring)
610 {
611 	struct amdgpu_device *adev = ring->adev;
612 
613 	return RREG32_SOC15(JPEG, ring->me, regUVD_JRBC_RB_RPTR);
614 }
615 
616 /**
617  * jpeg_v4_0_5_dec_ring_get_wptr - get write pointer
618  *
619  * @ring: amdgpu_ring pointer
620  *
621  * Returns the current hardware write pointer
622  */
jpeg_v4_0_5_dec_ring_get_wptr(struct amdgpu_ring * ring)623 static uint64_t jpeg_v4_0_5_dec_ring_get_wptr(struct amdgpu_ring *ring)
624 {
625 	struct amdgpu_device *adev = ring->adev;
626 
627 	if (ring->use_doorbell)
628 		return *ring->wptr_cpu_addr;
629 	else
630 		return RREG32_SOC15(JPEG, ring->me, regUVD_JRBC_RB_WPTR);
631 }
632 
633 /**
634  * jpeg_v4_0_5_dec_ring_set_wptr - set write pointer
635  *
636  * @ring: amdgpu_ring pointer
637  *
638  * Commits the write pointer to the hardware
639  */
jpeg_v4_0_5_dec_ring_set_wptr(struct amdgpu_ring * ring)640 static void jpeg_v4_0_5_dec_ring_set_wptr(struct amdgpu_ring *ring)
641 {
642 	struct amdgpu_device *adev = ring->adev;
643 
644 	if (ring->use_doorbell) {
645 		*ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
646 		WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
647 	} else {
648 		WREG32_SOC15(JPEG, ring->me, regUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
649 	}
650 }
651 
jpeg_v4_0_5_is_idle(struct amdgpu_ip_block * ip_block)652 static bool jpeg_v4_0_5_is_idle(struct amdgpu_ip_block *ip_block)
653 {
654 	struct amdgpu_device *adev = ip_block->adev;
655 	int i, ret = 1;
656 
657 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
658 		if (adev->jpeg.harvest_config & (1 << i))
659 			continue;
660 
661 		ret &= (((RREG32_SOC15(JPEG, i, regUVD_JRBC_STATUS) &
662 			UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
663 			UVD_JRBC_STATUS__RB_JOB_DONE_MASK));
664 	}
665 	return ret;
666 }
667 
jpeg_v4_0_5_wait_for_idle(struct amdgpu_ip_block * ip_block)668 static int jpeg_v4_0_5_wait_for_idle(struct amdgpu_ip_block *ip_block)
669 {
670 	struct amdgpu_device *adev = ip_block->adev;
671 	int i;
672 
673 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
674 		if (adev->jpeg.harvest_config & (1 << i))
675 			continue;
676 
677 		return SOC15_WAIT_ON_RREG(JPEG, i, regUVD_JRBC_STATUS,
678 			UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
679 			UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
680 	}
681 
682 	return 0;
683 }
684 
jpeg_v4_0_5_set_clockgating_state(struct amdgpu_ip_block * ip_block,enum amd_clockgating_state state)685 static int jpeg_v4_0_5_set_clockgating_state(struct amdgpu_ip_block *ip_block,
686 					  enum amd_clockgating_state state)
687 {
688 	struct amdgpu_device *adev = ip_block->adev;
689 	bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
690 	int i;
691 
692 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
693 		if (adev->jpeg.harvest_config & (1 << i))
694 			continue;
695 
696 		if (enable) {
697 			if (!jpeg_v4_0_5_is_idle(ip_block))
698 				return -EBUSY;
699 
700 			jpeg_v4_0_5_enable_clock_gating(adev, i);
701 		} else {
702 			jpeg_v4_0_5_disable_clock_gating(adev, i);
703 		}
704 	}
705 
706 	return 0;
707 }
708 
jpeg_v4_0_5_set_powergating_state(struct amdgpu_ip_block * ip_block,enum amd_powergating_state state)709 static int jpeg_v4_0_5_set_powergating_state(struct amdgpu_ip_block *ip_block,
710 					  enum amd_powergating_state state)
711 {
712 	struct amdgpu_device *adev = ip_block->adev;
713 	int ret;
714 
715 	if (amdgpu_sriov_vf(adev)) {
716 		adev->jpeg.cur_state = AMD_PG_STATE_UNGATE;
717 		return 0;
718 	}
719 
720 	if (state == adev->jpeg.cur_state)
721 		return 0;
722 
723 	if (state == AMD_PG_STATE_GATE)
724 		ret = jpeg_v4_0_5_stop(adev);
725 	else
726 		ret = jpeg_v4_0_5_start(adev);
727 
728 	if (!ret)
729 		adev->jpeg.cur_state = state;
730 
731 	return ret;
732 }
733 
jpeg_v4_0_5_process_interrupt(struct amdgpu_device * adev,struct amdgpu_irq_src * source,struct amdgpu_iv_entry * entry)734 static int jpeg_v4_0_5_process_interrupt(struct amdgpu_device *adev,
735 				      struct amdgpu_irq_src *source,
736 				      struct amdgpu_iv_entry *entry)
737 {
738 	uint32_t ip_instance;
739 
740 	DRM_DEBUG("IH: JPEG TRAP\n");
741 
742 	switch (entry->client_id) {
743 	case SOC15_IH_CLIENTID_VCN:
744 		ip_instance = 0;
745 		break;
746 	case SOC15_IH_CLIENTID_VCN1:
747 		ip_instance = 1;
748 		break;
749 	default:
750 		DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
751 		return 0;
752 	}
753 
754 	switch (entry->src_id) {
755 	case VCN_4_0__SRCID__JPEG_DECODE:
756 		amdgpu_fence_process(adev->jpeg.inst[ip_instance].ring_dec);
757 		break;
758 	case VCN_4_0__SRCID_DJPEG0_POISON:
759 	case VCN_4_0__SRCID_EJPEG0_POISON:
760 		amdgpu_jpeg_process_poison_irq(adev, source, entry);
761 		break;
762 	default:
763 		DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n",
764 			  entry->src_id, entry->src_data[0]);
765 		break;
766 	}
767 
768 	return 0;
769 }
770 
jpeg_v4_0_5_ring_reset(struct amdgpu_ring * ring,unsigned int vmid,struct amdgpu_fence * timedout_fence)771 static int jpeg_v4_0_5_ring_reset(struct amdgpu_ring *ring,
772 				  unsigned int vmid,
773 				  struct amdgpu_fence *timedout_fence)
774 {
775 	int r;
776 
777 	amdgpu_ring_reset_helper_begin(ring, timedout_fence);
778 	r = jpeg_v4_0_5_stop(ring->adev);
779 	if (r)
780 		return r;
781 	r = jpeg_v4_0_5_start(ring->adev);
782 	if (r)
783 		return r;
784 	return amdgpu_ring_reset_helper_end(ring, timedout_fence);
785 }
786 
787 static const struct amd_ip_funcs jpeg_v4_0_5_ip_funcs = {
788 	.name = "jpeg_v4_0_5",
789 	.early_init = jpeg_v4_0_5_early_init,
790 	.sw_init = jpeg_v4_0_5_sw_init,
791 	.sw_fini = jpeg_v4_0_5_sw_fini,
792 	.hw_init = jpeg_v4_0_5_hw_init,
793 	.hw_fini = jpeg_v4_0_5_hw_fini,
794 	.suspend = jpeg_v4_0_5_suspend,
795 	.resume = jpeg_v4_0_5_resume,
796 	.is_idle = jpeg_v4_0_5_is_idle,
797 	.wait_for_idle = jpeg_v4_0_5_wait_for_idle,
798 	.set_clockgating_state = jpeg_v4_0_5_set_clockgating_state,
799 	.set_powergating_state = jpeg_v4_0_5_set_powergating_state,
800 	.dump_ip_state = amdgpu_jpeg_dump_ip_state,
801 	.print_ip_state = amdgpu_jpeg_print_ip_state,
802 };
803 
804 static const struct amdgpu_ring_funcs jpeg_v4_0_5_dec_ring_vm_funcs = {
805 	.type = AMDGPU_RING_TYPE_VCN_JPEG,
806 	.align_mask = 0xf,
807 	.get_rptr = jpeg_v4_0_5_dec_ring_get_rptr,
808 	.get_wptr = jpeg_v4_0_5_dec_ring_get_wptr,
809 	.set_wptr = jpeg_v4_0_5_dec_ring_set_wptr,
810 	.parse_cs = jpeg_v2_dec_ring_parse_cs,
811 	.emit_frame_size =
812 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
813 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
814 		8 + /* jpeg_v4_0_5_dec_ring_emit_vm_flush */
815 		18 + 18 + /* jpeg_v4_0_5_dec_ring_emit_fence x2 vm fence */
816 		8 + 16,
817 	.emit_ib_size = 22, /* jpeg_v4_0_5_dec_ring_emit_ib */
818 	.emit_ib = jpeg_v2_0_dec_ring_emit_ib,
819 	.emit_fence = jpeg_v2_0_dec_ring_emit_fence,
820 	.emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush,
821 	.test_ring = amdgpu_jpeg_dec_ring_test_ring,
822 	.test_ib = amdgpu_jpeg_dec_ring_test_ib,
823 	.insert_nop = jpeg_v2_0_dec_ring_nop,
824 	.insert_start = jpeg_v2_0_dec_ring_insert_start,
825 	.insert_end = jpeg_v2_0_dec_ring_insert_end,
826 	.pad_ib = amdgpu_ring_generic_pad_ib,
827 	.begin_use = amdgpu_jpeg_ring_begin_use,
828 	.end_use = amdgpu_jpeg_ring_end_use,
829 	.emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
830 	.emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
831 	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
832 	.reset = jpeg_v4_0_5_ring_reset,
833 };
834 
jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device * adev)835 static void jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device *adev)
836 {
837 	int i;
838 
839 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
840 		if (adev->jpeg.harvest_config & (1 << i))
841 			continue;
842 
843 		adev->jpeg.inst[i].ring_dec->funcs = &jpeg_v4_0_5_dec_ring_vm_funcs;
844 		adev->jpeg.inst[i].ring_dec->me = i;
845 	}
846 }
847 
848 static const struct amdgpu_irq_src_funcs jpeg_v4_0_5_irq_funcs = {
849 	.process = jpeg_v4_0_5_process_interrupt,
850 };
851 
jpeg_v4_0_5_set_irq_funcs(struct amdgpu_device * adev)852 static void jpeg_v4_0_5_set_irq_funcs(struct amdgpu_device *adev)
853 {
854 	int i;
855 
856 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
857 		if (adev->jpeg.harvest_config & (1 << i))
858 			continue;
859 
860 		adev->jpeg.inst[i].irq.num_types = 1;
861 		adev->jpeg.inst[i].irq.funcs = &jpeg_v4_0_5_irq_funcs;
862 	}
863 }
864 
865 const struct amdgpu_ip_block_version jpeg_v4_0_5_ip_block = {
866 	.type = AMD_IP_BLOCK_TYPE_JPEG,
867 	.major = 4,
868 	.minor = 0,
869 	.rev = 5,
870 	.funcs = &jpeg_v4_0_5_ip_funcs,
871 };
872 
873