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