xref: /linux/drivers/gpu/drm/amd/amdgpu/jpeg_v5_3_0.c (revision 570f7e331f5febb30f1384817463c7e42b65ca7d)
1 /*
2  * Copyright 2025 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_3.h"
31 
32 #include "vcn/vcn_5_3_0_offset.h"
33 #include "vcn/vcn_5_3_0_sh_mask.h"
34 #include "ivsrcid/vcn/irqsrcs_vcn_5_0.h"
35 #include "jpeg_v5_0_0.h"
36 #include "jpeg_v5_3_0.h"
37 
38 static void jpeg_v5_3_0_set_dec_ring_funcs(struct amdgpu_device *adev);
39 static void jpeg_v5_3_0_set_irq_funcs(struct amdgpu_device *adev);
40 static int jpeg_v5_3_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
41 				enum amd_powergating_state state);
42 
43 
44 /**
45  * jpeg_v5_3_0_early_init - set function pointers
46  *
47  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
48  *
49  * Set ring and irq function pointers
50  */
51 static int jpeg_v5_3_0_early_init(struct amdgpu_ip_block *ip_block)
52 {
53 	struct amdgpu_device *adev = ip_block->adev;
54 
55 	adev->jpeg.num_jpeg_inst = 1;
56 	adev->jpeg.num_jpeg_rings = 1;
57 
58 	jpeg_v5_3_0_set_dec_ring_funcs(adev);
59 	jpeg_v5_3_0_set_irq_funcs(adev);
60 
61 	return 0;
62 }
63 
64 /**
65  * jpeg_v5_3_0_sw_init - sw init for JPEG block
66  *
67  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
68  *
69  * Load firmware and sw initialization
70  */
71 static int jpeg_v5_3_0_sw_init(struct amdgpu_ip_block *ip_block)
72 {
73 	struct amdgpu_device *adev = ip_block->adev;
74 	struct amdgpu_ring *ring;
75 	int r;
76 
77 	/* JPEG TRAP */
78 	r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
79 		VCN_5_0__SRCID__JPEG_DECODE, &adev->jpeg.inst->irq);
80 	if (r)
81 		return r;
82 
83 	r = amdgpu_jpeg_sw_init(adev);
84 	if (r)
85 		return r;
86 
87 	r = amdgpu_jpeg_resume(adev);
88 	if (r)
89 		return r;
90 
91 	ring = adev->jpeg.inst->ring_dec;
92 	ring->use_doorbell = true;
93 	ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1;
94 	ring->vm_hub = AMDGPU_MMHUB0(0);
95 
96 	sprintf(ring->name, "jpeg_dec");
97 	r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0,
98 			     AMDGPU_RING_PRIO_DEFAULT, NULL);
99 	if (r)
100 		return r;
101 
102 	adev->jpeg.internal.jpeg_pitch[0] = regUVD_JPEG_PITCH_INTERNAL_OFFSET;
103 	adev->jpeg.inst->external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_PITCH);
104 
105 	/* TODO: Add queue reset mask when FW fully supports it */
106 	adev->jpeg.supported_reset =
107 		amdgpu_get_soft_full_reset_mask(&adev->jpeg.inst[0].ring_dec[0]);
108 	if (!amdgpu_sriov_vf(adev))
109 		adev->jpeg.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
110 	r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
111 	if (r)
112 		return r;
113 	return 0;
114 }
115 
116 /**
117  * jpeg_v5_3_0_sw_fini - sw fini for JPEG block
118  *
119  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
120  *
121  * JPEG suspend and free up sw allocation
122  */
123 static int jpeg_v5_3_0_sw_fini(struct amdgpu_ip_block *ip_block)
124 {
125 	struct amdgpu_device *adev = ip_block->adev;
126 	int r;
127 
128 	r = amdgpu_jpeg_suspend(adev);
129 	if (r)
130 		return r;
131 
132 	amdgpu_jpeg_sysfs_reset_mask_fini(adev);
133 	r = amdgpu_jpeg_sw_fini(adev);
134 
135 	return r;
136 }
137 
138 /**
139  * jpeg_v5_3_0_hw_init - start and test JPEG block
140  *
141  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
142  *
143  */
144 static int jpeg_v5_3_0_hw_init(struct amdgpu_ip_block *ip_block)
145 {
146 	struct amdgpu_device *adev = ip_block->adev;
147 	struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec;
148 	int r;
149 
150 	adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
151 			(adev->doorbell_index.vcn.vcn_ring0_1 << 1), 0);
152 
153 	/* Skip ring test because pause DPG is not implemented. */
154 	if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG)
155 		return 0;
156 
157 	r = amdgpu_ring_test_helper(ring);
158 	if (r)
159 		return r;
160 
161 	return 0;
162 }
163 
164 /**
165  * jpeg_v5_3_0_hw_fini - stop the hardware block
166  *
167  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
168  *
169  * Stop the JPEG block, mark ring as not ready any more
170  */
171 static int jpeg_v5_3_0_hw_fini(struct amdgpu_ip_block *ip_block)
172 {
173 	struct amdgpu_device *adev = ip_block->adev;
174 
175 	cancel_delayed_work_sync(&adev->jpeg.idle_work);
176 
177 	if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
178 	      RREG32_SOC15(JPEG, 0, regUVD_JRBC0_UVD_JRBC_STATUS))
179 		jpeg_v5_3_0_set_powergating_state(ip_block, AMD_PG_STATE_GATE);
180 
181 	return 0;
182 }
183 
184 /**
185  * jpeg_v5_3_0_suspend - suspend JPEG block
186  *
187  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
188  *
189  * HW fini and suspend JPEG block
190  */
191 static int jpeg_v5_3_0_suspend(struct amdgpu_ip_block *ip_block)
192 {
193 	int r;
194 
195 	r = jpeg_v5_3_0_hw_fini(ip_block);
196 	if (r)
197 		return r;
198 
199 	r = amdgpu_jpeg_suspend(ip_block->adev);
200 
201 	return r;
202 }
203 
204 /**
205  * jpeg_v5_3_0_resume - resume JPEG block
206  *
207  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
208  *
209  * Resume firmware and hw init JPEG block
210  */
211 static int jpeg_v5_3_0_resume(struct amdgpu_ip_block *ip_block)
212 {
213 	int r;
214 
215 	r = amdgpu_jpeg_resume(ip_block->adev);
216 	if (r)
217 		return r;
218 
219 	r = jpeg_v5_3_0_hw_init(ip_block);
220 
221 	return r;
222 }
223 
224 static void jpeg_v5_3_0_disable_clock_gating(struct amdgpu_device *adev)
225 {
226 	uint32_t data = 0;
227 
228 	WREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE, data);
229 
230 	data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL);
231 	data &= ~(JPEG_CGC_CTRL__JPEG0_DEC_MODE_MASK
232 		| JPEG_CGC_CTRL__JPEG_ENC_MODE_MASK);
233 	WREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL, data);
234 }
235 
236 static void jpeg_v5_3_0_enable_clock_gating(struct amdgpu_device *adev)
237 {
238 	uint32_t data = 0;
239 
240 	data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL);
241 
242 	data |= 1 << JPEG_CGC_CTRL__JPEG0_DEC_MODE__SHIFT;
243 	WREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL, data);
244 
245 	data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE);
246 	data |= (JPEG_CGC_GATE__JPEG0_DEC_MASK
247 		|JPEG_CGC_GATE__JPEG_ENC_MASK
248 		|JPEG_CGC_GATE__JMCIF_MASK
249 		|JPEG_CGC_GATE__JRBBM_MASK);
250 	WREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE, data);
251 }
252 
253 static int jpeg_v5_3_0_disable_power_gating(struct amdgpu_device *adev)
254 {
255 	uint32_t data = 0;
256 
257 	data = 1 << UVD_IPX_DLDO_CONFIG_ONO1__ONO1_PWR_CONFIG__SHIFT;
258 	WREG32_SOC15(JPEG, 0, regUVD_IPX_DLDO_CONFIG_ONO1, data);
259 	SOC15_WAIT_ON_RREG(JPEG, 0, regUVD_IPX_DLDO_STATUS, 0,
260 			UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK);
261 
262 	/* disable anti hang mechanism */
263 	WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_POWER_STATUS), 0,
264 		~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
265 
266 	return 0;
267 }
268 
269 static int jpeg_v5_3_0_enable_power_gating(struct amdgpu_device *adev)
270 {
271 	/* enable anti hang mechanism */
272 	WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_POWER_STATUS),
273 		UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
274 		~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
275 
276 	if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
277 		WREG32(SOC15_REG_OFFSET(JPEG, 0, regUVD_IPX_DLDO_CONFIG_ONO1),
278 			2 << UVD_IPX_DLDO_CONFIG_ONO1__ONO1_PWR_CONFIG__SHIFT);
279 		SOC15_WAIT_ON_RREG(JPEG, 0, regUVD_IPX_DLDO_STATUS,
280 			1 << UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS__SHIFT,
281 			UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK);
282 	}
283 
284 	return 0;
285 }
286 
287 static void jpeg_engine_5_0_0_dpg_clock_gating_mode(struct amdgpu_device *adev,
288 	       int inst_idx, uint8_t indirect)
289 {
290 	uint32_t data = 0;
291 
292 	// JPEG disable CGC
293 	if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG)
294 		data = 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
295 	else
296 		data = 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
297 
298 	data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
299 	data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
300 
301 	if (indirect) {
302 		ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipJPEG_CGC_CTRL, data, indirect);
303 
304 		// Turn on All JPEG clocks
305 		data = 0;
306 		ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipJPEG_CGC_GATE, data, indirect);
307 	} else {
308 		WREG32_SOC24_JPEG_DPG_MODE(inst_idx, vcnipJPEG_CGC_CTRL, data, indirect);
309 
310 		// Turn on All JPEG clocks
311 		data = 0;
312 		WREG32_SOC24_JPEG_DPG_MODE(inst_idx, vcnipJPEG_CGC_GATE, data, indirect);
313 	}
314 }
315 
316 /**
317  * jpeg_v5_3_0_start_dpg_mode - Jpeg start with dpg mode
318  *
319  * @adev: amdgpu_device pointer
320  * @inst_idx: instance number index
321  * @indirect: indirectly write sram
322  *
323  * Start JPEG block with dpg mode
324  */
325 static int jpeg_v5_3_0_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
326 {
327 	struct amdgpu_ring *ring = adev->jpeg.inst[inst_idx].ring_dec;
328 	uint32_t reg_data = 0;
329 
330 	jpeg_v5_3_0_enable_power_gating(adev);
331 
332 	// enable dynamic power gating mode
333 	reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS);
334 	reg_data |= UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK;
335 	WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
336 
337 	if (indirect)
338 		adev->jpeg.inst[inst_idx].dpg_sram_curr_addr =
339 			(uint32_t *)adev->jpeg.inst[inst_idx].dpg_sram_cpu_addr;
340 
341 	jpeg_engine_5_0_0_dpg_clock_gating_mode(adev, inst_idx, indirect);
342 
343 	/* MJPEG global tiling registers */
344 	if (indirect)
345 		ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipJPEG_DEC_GFX10_ADDR_CONFIG,
346 			adev->gfx.config.gb_addr_config, indirect);
347 	else
348 		WREG32_SOC24_JPEG_DPG_MODE(inst_idx, vcnipJPEG_DEC_GFX10_ADDR_CONFIG,
349 			adev->gfx.config.gb_addr_config, 1);
350 
351 	/* enable System Interrupt for JRBC */
352 	if (indirect)
353 		ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipJPEG_SYS_INT_EN,
354 			JPEG_SYS_INT_EN__DJRBC0_MASK, indirect);
355 	else
356 		WREG32_SOC24_JPEG_DPG_MODE(inst_idx, vcnipJPEG_SYS_INT_EN,
357 			JPEG_SYS_INT_EN__DJRBC0_MASK, 1);
358 
359 	if (indirect) {
360 		/* add nop to workaround PSP size check */
361 		ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipUVD_NO_OP, 0, indirect);
362 
363 		amdgpu_jpeg_psp_update_sram(adev, inst_idx, 0);
364 	}
365 
366 	WREG32_SOC15(VCN, 0, regVCN_JPEG_DB_CTRL,
367 		ring->doorbell_index << VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
368 		VCN_JPEG_DB_CTRL__EN_MASK);
369 
370 	WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_VMID, 0);
371 	WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC0_UVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
372 	WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
373 		lower_32_bits(ring->gpu_addr));
374 	WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
375 		upper_32_bits(ring->gpu_addr));
376 	WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC0_UVD_JRBC_RB_RPTR, 0);
377 	WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC0_UVD_JRBC_RB_WPTR, 0);
378 	WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC0_UVD_JRBC_RB_CNTL, 0x00000002L);
379 	WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC0_UVD_JRBC_RB_SIZE, ring->ring_size / 4);
380 	ring->wptr = RREG32_SOC15(JPEG, inst_idx, regUVD_JRBC0_UVD_JRBC_RB_WPTR);
381 
382 	return 0;
383 }
384 
385 /**
386  * jpeg_v5_3_0_stop_dpg_mode - Jpeg stop with dpg mode
387  *
388  * @adev: amdgpu_device pointer
389  * @inst_idx: instance number index
390  *
391  * Stop JPEG block with dpg mode
392  */
393 static void jpeg_v5_3_0_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
394 {
395 	uint32_t reg_data = 0;
396 
397 	reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS);
398 	reg_data &= ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK;
399 	WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
400 }
401 
402 /**
403  * jpeg_v5_3_0_set_mmhub_eco_sec_level - set jpeg sec lvl reg
404  *
405  * @adev: amdgpu_device pointer
406  *
407  * request psp to set secure lvl
408  */
409 static int jpeg_v5_3_0_set_mmhub_eco_sec_level(struct amdgpu_device *adev)
410 {
411 	int r = 0;
412 
413 	if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
414 		/* Request to PSP to program JPEG secure lvl */
415 		r = psp_set_mmhub_eco_sec_level(adev);
416 	}
417 
418 	return r;
419 }
420 
421 /**
422  * jpeg_v5_3_0_start - start JPEG block
423  *
424  * @adev: amdgpu_device pointer
425  *
426  * Setup and start the JPEG block
427  */
428 static int jpeg_v5_3_0_start(struct amdgpu_device *adev)
429 {
430 	struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec;
431 	int r;
432 
433 	if (adev->pm.dpm_enabled)
434 		amdgpu_dpm_enable_jpeg(adev, true);
435 
436 	if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
437 		r = jpeg_v5_3_0_start_dpg_mode(adev, 0, adev->jpeg.indirect_sram);
438 		return r;
439 	}
440 
441 	/* disable power gating */
442 	r = jpeg_v5_3_0_disable_power_gating(adev);
443 	if (r)
444 		return r;
445 
446 	/* program JPEG secure lvl register */
447 	r = jpeg_v5_3_0_set_mmhub_eco_sec_level(adev);
448 	if (r)
449 		return r;
450 
451 	/* JPEG disable CGC */
452 	jpeg_v5_3_0_disable_clock_gating(adev);
453 
454 	/* MJPEG global tiling registers */
455 	WREG32_SOC15(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG,
456 		adev->gfx.config.gb_addr_config);
457 
458 	/* enable JMI channel */
459 	WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI_CNTL), 0,
460 		~UVD_JMI_CNTL__SOFT_RESET_MASK);
461 
462 	/* enable System Interrupt for JRBC */
463 	WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regJPEG_SYS_INT_EN),
464 		JPEG_SYS_INT_EN__DJRBC0_MASK,
465 		~JPEG_SYS_INT_EN__DJRBC0_MASK);
466 
467 	WREG32_SOC15(VCN, 0, regVCN_JPEG_DB_CTRL,
468 		ring->doorbell_index << VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
469 		VCN_JPEG_DB_CTRL__EN_MASK);
470 
471 	WREG32_SOC15(JPEG, 0, regUVD_LMI_JRBC_RB_VMID, 0);
472 	WREG32_SOC15(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
473 	WREG32_SOC15(JPEG, 0, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
474 		lower_32_bits(ring->gpu_addr));
475 	WREG32_SOC15(JPEG, 0, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
476 		upper_32_bits(ring->gpu_addr));
477 	WREG32_SOC15(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_RPTR, 0);
478 	WREG32_SOC15(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_WPTR, 0);
479 	WREG32_SOC15(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_CNTL, 0x00000002L);
480 	WREG32_SOC15(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_SIZE, ring->ring_size / 4);
481 	ring->wptr = RREG32_SOC15(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_WPTR);
482 
483 	return 0;
484 }
485 
486 /**
487  * jpeg_v5_3_0_stop - stop JPEG block
488  *
489  * @adev: amdgpu_device pointer
490  *
491  * stop the JPEG block
492  */
493 static int jpeg_v5_3_0_stop(struct amdgpu_device *adev)
494 {
495 	int r;
496 
497 	if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
498 		jpeg_v5_3_0_stop_dpg_mode(adev, 0);
499 	} else {
500 
501 		/* reset JMI */
502 		WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI_CNTL),
503 			UVD_JMI_CNTL__SOFT_RESET_MASK,
504 			~UVD_JMI_CNTL__SOFT_RESET_MASK);
505 
506 		jpeg_v5_3_0_enable_clock_gating(adev);
507 
508 		/* enable power gating */
509 		r = jpeg_v5_3_0_enable_power_gating(adev);
510 		if (r)
511 			return r;
512 	}
513 
514 	if (adev->pm.dpm_enabled)
515 		amdgpu_dpm_enable_jpeg(adev, false);
516 
517 	return 0;
518 }
519 
520 /**
521  * jpeg_v5_3_0_dec_ring_get_rptr - get read pointer
522  *
523  * @ring: amdgpu_ring pointer
524  *
525  * Returns the current hardware read pointer
526  */
527 static uint64_t jpeg_v5_3_0_dec_ring_get_rptr(struct amdgpu_ring *ring)
528 {
529 	struct amdgpu_device *adev = ring->adev;
530 
531 	return RREG32_SOC15(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_RPTR);
532 }
533 
534 /**
535  * jpeg_v5_3_0_dec_ring_get_wptr - get write pointer
536  *
537  * @ring: amdgpu_ring pointer
538  *
539  * Returns the current hardware write pointer
540  */
541 static uint64_t jpeg_v5_3_0_dec_ring_get_wptr(struct amdgpu_ring *ring)
542 {
543 	struct amdgpu_device *adev = ring->adev;
544 
545 	if (ring->use_doorbell)
546 		return *ring->wptr_cpu_addr;
547 	else
548 		return RREG32_SOC15(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_WPTR);
549 }
550 
551 /**
552  * jpeg_v5_3_0_dec_ring_set_wptr - set write pointer
553  *
554  * @ring: amdgpu_ring pointer
555  *
556  * Commits the write pointer to the hardware
557  */
558 static void jpeg_v5_3_0_dec_ring_set_wptr(struct amdgpu_ring *ring)
559 {
560 	struct amdgpu_device *adev = ring->adev;
561 
562 	if (ring->use_doorbell) {
563 		*ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
564 		WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
565 	} else {
566 		WREG32_SOC15(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
567 	}
568 }
569 
570 static bool jpeg_v5_3_0_is_idle(struct amdgpu_ip_block *ip_block)
571 {
572 	struct amdgpu_device *adev = ip_block->adev;
573 	int ret = 1;
574 
575 	ret &= (((RREG32_SOC15(JPEG, 0, regUVD_JRBC0_UVD_JRBC_STATUS) &
576 		UVD_JRBC0_UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
577 		UVD_JRBC0_UVD_JRBC_STATUS__RB_JOB_DONE_MASK));
578 
579 	return ret;
580 }
581 
582 static int jpeg_v5_3_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
583 {
584 	struct amdgpu_device *adev = ip_block->adev;
585 
586 	return SOC15_WAIT_ON_RREG(JPEG, 0, regUVD_JRBC0_UVD_JRBC_STATUS,
587 		UVD_JRBC0_UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
588 		UVD_JRBC0_UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
589 }
590 
591 static int jpeg_v5_3_0_set_clockgating_state(struct amdgpu_ip_block *ip_block,
592 					  enum amd_clockgating_state state)
593 {
594 	struct amdgpu_device *adev = ip_block->adev;
595 	bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
596 
597 	if (enable) {
598 		if (!jpeg_v5_3_0_is_idle(ip_block))
599 			return -EBUSY;
600 		jpeg_v5_3_0_enable_clock_gating(adev);
601 	} else {
602 		jpeg_v5_3_0_disable_clock_gating(adev);
603 	}
604 
605 	return 0;
606 }
607 
608 static int jpeg_v5_3_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
609 					  enum amd_powergating_state state)
610 {
611 	struct amdgpu_device *adev = ip_block->adev;
612 	int ret;
613 
614 	if (state == adev->jpeg.cur_state)
615 		return 0;
616 
617 	if (state == AMD_PG_STATE_GATE)
618 		ret = jpeg_v5_3_0_stop(adev);
619 	else
620 		ret = jpeg_v5_3_0_start(adev);
621 
622 	if (!ret)
623 		adev->jpeg.cur_state = state;
624 
625 	return ret;
626 }
627 
628 static int jpeg_v5_3_0_set_interrupt_state(struct amdgpu_device *adev,
629 					struct amdgpu_irq_src *source,
630 					unsigned int type,
631 					enum amdgpu_interrupt_state state)
632 {
633 	return 0;
634 }
635 
636 static int jpeg_v5_3_0_ring_reset(struct amdgpu_ring *ring,
637 				  unsigned int vmid,
638 				  struct amdgpu_fence *timedout_fence)
639 {
640 	struct amdgpu_device *adev = ring->adev;
641 	u32 pg_flags = adev->pg_flags;
642 	int r;
643 
644 	amdgpu_ring_reset_helper_begin(ring, timedout_fence);
645 
646 	/*
647 	 * The DPG stop path only clears the JPEG_PG_MODE bit and never resets a
648 	 * hung JRBC, so the post-reset ring test times out and the driver falls
649 	 * back to a full MODE1 reset. Temporarily force the static power-gating
650 	 * path so the stop/start sequence actually power-cycles the JPEG block
651 	 * (JMI soft reset + static power off/on), matching the working jpeg_v4_0
652 	 * reset.
653 	 */
654 	adev->pg_flags &= ~AMD_PG_SUPPORT_JPEG_DPG;
655 	r = jpeg_v5_3_0_stop(adev);
656 	if (!r)
657 		r = jpeg_v5_3_0_start(adev);
658 	adev->pg_flags = pg_flags;
659 	if (r)
660 		return r;
661 
662 	return amdgpu_ring_reset_helper_end(ring, timedout_fence);
663 }
664 
665 static const struct amd_ip_funcs jpeg_v5_3_0_ip_funcs = {
666 	.name = "jpeg_v5_3_0",
667 	.early_init = jpeg_v5_3_0_early_init,
668 	.sw_init = jpeg_v5_3_0_sw_init,
669 	.sw_fini = jpeg_v5_3_0_sw_fini,
670 	.hw_init = jpeg_v5_3_0_hw_init,
671 	.hw_fini = jpeg_v5_3_0_hw_fini,
672 	.suspend = jpeg_v5_3_0_suspend,
673 	.resume = jpeg_v5_3_0_resume,
674 	.is_idle = jpeg_v5_3_0_is_idle,
675 	.wait_for_idle = jpeg_v5_3_0_wait_for_idle,
676 	.set_clockgating_state = jpeg_v5_3_0_set_clockgating_state,
677 	.set_powergating_state = jpeg_v5_3_0_set_powergating_state,
678 };
679 
680 static const struct amdgpu_ring_funcs jpeg_v5_3_0_dec_ring_vm_funcs = {
681 	.type = AMDGPU_RING_TYPE_VCN_JPEG,
682 	.align_mask = 0xf,
683 	.no_user_fence = true,
684 	.get_rptr = jpeg_v5_3_0_dec_ring_get_rptr,
685 	.get_wptr = jpeg_v5_3_0_dec_ring_get_wptr,
686 	.set_wptr = jpeg_v5_3_0_dec_ring_set_wptr,
687 	.parse_cs = amdgpu_jpeg_dec_parse_cs,
688 	.emit_frame_size =
689 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
690 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
691 		8 + /* jpeg_v5_3_0_dec_ring_emit_vm_flush */
692 		22 + 22 + /* jpeg_v5_3_0_dec_ring_emit_fence x2 vm fence */
693 		8 + 16,
694 	.emit_ib_size = 22, /* jpeg_v5_3_0_dec_ring_emit_ib */
695 	.emit_ib = jpeg_v4_0_3_dec_ring_emit_ib,
696 	.emit_fence = jpeg_v4_0_3_dec_ring_emit_fence,
697 	.emit_vm_flush = jpeg_v4_0_3_dec_ring_emit_vm_flush,
698 	.test_ring = amdgpu_jpeg_dec_ring_test_ring,
699 	.test_ib = amdgpu_jpeg_dec_ring_test_ib,
700 	.insert_nop = jpeg_v4_0_3_dec_ring_nop,
701 	.insert_start = jpeg_v4_0_3_dec_ring_insert_start,
702 	.insert_end = jpeg_v4_0_3_dec_ring_insert_end,
703 	.pad_ib = amdgpu_ring_generic_pad_ib,
704 	.begin_use = amdgpu_jpeg_ring_begin_use,
705 	.end_use = amdgpu_jpeg_ring_end_use,
706 	.emit_wreg = jpeg_v4_0_3_dec_ring_emit_wreg,
707 	.emit_reg_wait = jpeg_v4_0_3_dec_ring_emit_reg_wait,
708 	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
709 	.reset = jpeg_v5_3_0_ring_reset,
710 };
711 
712 static void jpeg_v5_3_0_set_dec_ring_funcs(struct amdgpu_device *adev)
713 {
714 	adev->jpeg.inst->ring_dec->funcs = &jpeg_v5_3_0_dec_ring_vm_funcs;
715 }
716 
717 static const struct amdgpu_irq_src_funcs jpeg_v5_3_0_irq_funcs = {
718 	.set = jpeg_v5_3_0_set_interrupt_state,
719 	.process = jpeg_v5_0_0_process_interrupt,
720 };
721 
722 static void jpeg_v5_3_0_set_irq_funcs(struct amdgpu_device *adev)
723 {
724 	adev->jpeg.inst->irq.num_types = 1;
725 	adev->jpeg.inst->irq.funcs = &jpeg_v5_3_0_irq_funcs;
726 }
727 
728 const struct amdgpu_ip_block_version jpeg_v5_3_0_ip_block = {
729 	.type = AMD_IP_BLOCK_TYPE_JPEG,
730 	.major = 5,
731 	.minor = 3,
732 	.rev = 0,
733 	.funcs = &jpeg_v5_3_0_ip_funcs,
734 };
735