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