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