xref: /linux/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_2.c (revision 4a57e0913e8c7fff407e97909f4ae48caa84d612)
1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /*
3  * Copyright 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21  * OTHER DEALINGS IN THE SOFTWARE.
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 #include "jpeg_v5_0_2.h"
31 #include "mmsch_v5_0.h"
32 
33 #include "vcn/vcn_5_0_0_offset.h"
34 #include "vcn/vcn_5_0_0_sh_mask.h"
35 #include "ivsrcid/vcn/irqsrcs_vcn_5_0.h"
36 
37 static void jpeg_v5_0_2_set_dec_ring_funcs(struct amdgpu_device *adev);
38 static void jpeg_v5_0_2_set_irq_funcs(struct amdgpu_device *adev);
39 static int jpeg_v5_0_2_set_powergating_state(struct amdgpu_ip_block *ip_block,
40 					     enum amd_powergating_state state);
41 static void jpeg_v5_0_2_dec_ring_set_wptr(struct amdgpu_ring *ring);
42 
43 static int amdgpu_ih_srcid_jpeg[] = {
44 	VCN_5_0__SRCID__JPEG_DECODE,
45 	VCN_5_0__SRCID__JPEG1_DECODE,
46 	VCN_5_0__SRCID__JPEG2_DECODE,
47 	VCN_5_0__SRCID__JPEG3_DECODE,
48 	VCN_5_0__SRCID__JPEG4_DECODE,
49 	VCN_5_0__SRCID__JPEG5_DECODE,
50 	VCN_5_0__SRCID__JPEG6_DECODE,
51 	VCN_5_0__SRCID__JPEG7_DECODE,
52 	VCN_5_0__SRCID__JPEG8_DECODE,
53 	VCN_5_0__SRCID__JPEG9_DECODE,
54 };
55 
56 static const struct amdgpu_hwip_reg_entry jpeg_reg_list_5_0_2[] = {
57 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_POWER_STATUS),
58 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_INT_STAT),
59 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_RPTR),
60 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_WPTR),
61 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_STATUS),
62 	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_ADDR_MODE),
63 	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG),
64 	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_Y_GFX10_TILING_SURFACE),
65 	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_UV_GFX10_TILING_SURFACE),
66 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_PITCH),
67 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_UV_PITCH),
68 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_RB_RPTR),
69 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_RB_WPTR),
70 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_STATUS),
71 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_RB_RPTR),
72 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_RB_WPTR),
73 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_STATUS),
74 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_RB_RPTR),
75 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_RB_WPTR),
76 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_STATUS),
77 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_RB_RPTR),
78 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_RB_WPTR),
79 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_STATUS),
80 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_RB_RPTR),
81 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_RB_WPTR),
82 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_STATUS),
83 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_RB_RPTR),
84 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_RB_WPTR),
85 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_STATUS),
86 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_RB_RPTR),
87 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_RB_WPTR),
88 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_STATUS),
89 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC8_UVD_JRBC_RB_RPTR),
90 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC8_UVD_JRBC_RB_WPTR),
91 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC8_UVD_JRBC_STATUS),
92 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC9_UVD_JRBC_RB_RPTR),
93 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC9_UVD_JRBC_RB_WPTR),
94 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC9_UVD_JRBC_STATUS),
95 };
96 
97 static int jpeg_v5_0_2_core_reg_offset(u32 pipe)
98 {
99 	if (pipe <= AMDGPU_MAX_JPEG_RINGS_4_0_3)
100 		return ((0x40 * pipe) - 0xc80);
101 	else
102 		return ((0x40 * pipe) - 0x440);
103 }
104 
105 /**
106  * jpeg_v5_0_2_early_init - set function pointers
107  *
108  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
109  *
110  * Set ring and irq function pointers
111  */
112 static int jpeg_v5_0_2_early_init(struct amdgpu_ip_block *ip_block)
113 {
114 	struct amdgpu_device *adev = ip_block->adev;
115 
116 	if (!adev->jpeg.num_jpeg_inst || adev->jpeg.num_jpeg_inst > AMDGPU_MAX_JPEG_INSTANCES)
117 		return -ENOENT;
118 
119 	adev->jpeg.num_jpeg_rings = AMDGPU_MAX_JPEG_RINGS;
120 	jpeg_v5_0_2_set_dec_ring_funcs(adev);
121 	jpeg_v5_0_2_set_irq_funcs(adev);
122 
123 	return 0;
124 }
125 
126 /**
127  * jpeg_v5_0_2_sw_init - sw init for JPEG block
128  *
129  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
130  *
131  * Load firmware and sw initialization
132  */
133 static int jpeg_v5_0_2_sw_init(struct amdgpu_ip_block *ip_block)
134 {
135 	struct amdgpu_device *adev = ip_block->adev;
136 	struct amdgpu_ring *ring;
137 	int i, j, r, jpeg_inst;
138 
139 	for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
140 		/* JPEG TRAP */
141 		r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
142 				      amdgpu_ih_srcid_jpeg[j], &adev->jpeg.inst->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 		jpeg_inst = GET_INST(JPEG, i);
157 
158 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
159 			ring = &adev->jpeg.inst[i].ring_dec[j];
160 			ring->use_doorbell = false;
161 			ring->vm_hub = AMDGPU_MMHUB0(adev->jpeg.inst[i].aid_id);
162 			ring->doorbell_index =
163 				(adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
164 				1 + j + 11 * jpeg_inst;
165 			sprintf(ring->name, "jpeg_dec_%d.%d", adev->jpeg.inst[i].aid_id, j);
166 			r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0,
167 					     AMDGPU_RING_PRIO_DEFAULT, NULL);
168 			if (r)
169 				return r;
170 
171 			adev->jpeg.internal.jpeg_pitch[j] =
172 				regUVD_JRBC0_UVD_JRBC_SCRATCH0_INTERNAL_OFFSET;
173 			adev->jpeg.inst[i].external.jpeg_pitch[j] =
174 				SOC15_REG_OFFSET1(JPEG, jpeg_inst, regUVD_JRBC_SCRATCH0,
175 						  (j ? jpeg_v5_0_2_core_reg_offset(j) : 0));
176 		}
177 	}
178 
179 	r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_5_0_2, ARRAY_SIZE(jpeg_reg_list_5_0_2));
180 	if (r)
181 		return r;
182 
183 	adev->jpeg.supported_reset =
184 		amdgpu_get_soft_full_reset_mask(&adev->jpeg.inst[0].ring_dec[0]);
185 	adev->jpeg.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
186 	r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
187 
188 	return r;
189 }
190 
191 /**
192  * jpeg_v5_0_2_sw_fini - sw fini for JPEG block
193  *
194  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
195  *
196  * JPEG suspend and free up sw allocation
197  */
198 static int jpeg_v5_0_2_sw_fini(struct amdgpu_ip_block *ip_block)
199 {
200 	struct amdgpu_device *adev = ip_block->adev;
201 	int r;
202 
203 	r = amdgpu_jpeg_suspend(adev);
204 	if (r)
205 		return r;
206 
207 	amdgpu_jpeg_sysfs_reset_mask_fini(adev);
208 
209 	r = amdgpu_jpeg_sw_fini(adev);
210 
211 	return r;
212 }
213 
214 /**
215  * jpeg_v5_0_2_hw_init - start and test JPEG block
216  *
217  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
218  *
219  */
220 static int jpeg_v5_0_2_hw_init(struct amdgpu_ip_block *ip_block)
221 {
222 	struct amdgpu_device *adev = ip_block->adev;
223 	struct amdgpu_ring *ring;
224 	int i, j, r, jpeg_inst, tmp;
225 
226 	if (RREG32_SOC15(VCN, GET_INST(VCN, 0), regVCN_RRMT_CNTL) & 0x100)
227 		adev->jpeg.caps |= AMDGPU_JPEG_CAPS(RRMT_ENABLED);
228 
229 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
230 		jpeg_inst = GET_INST(JPEG, i);
231 		ring = adev->jpeg.inst[i].ring_dec;
232 
233 		/* Remove JPEG Tile antihang mechanism */
234 		tmp = RREG32_SOC15(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS);
235 		tmp &= (~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
236 		WREG32_SOC15(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS, tmp);
237 
238 		if (ring->use_doorbell)
239 			adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
240 				 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 11 * jpeg_inst,
241 				 adev->jpeg.inst[i].aid_id);
242 
243 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
244 			ring = &adev->jpeg.inst[i].ring_dec[j];
245 			if (ring->use_doorbell)
246 				WREG32_SOC15_OFFSET(VCN, GET_INST(VCN, i), regVCN_JPEG_DB_CTRL,
247 						    ring->pipe,
248 						    ring->doorbell_index <<
249 						    VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
250 						    VCN_JPEG_DB_CTRL__EN_MASK);
251 			r = amdgpu_ring_test_helper(ring);
252 			if (r)
253 				return r;
254 		}
255 	}
256 
257 	return 0;
258 }
259 
260 /**
261  * jpeg_v5_0_2_hw_fini - stop the hardware block
262  *
263  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
264  *
265  * Stop the JPEG block, mark ring as not ready any more
266  */
267 static int jpeg_v5_0_2_hw_fini(struct amdgpu_ip_block *ip_block)
268 {
269 	struct amdgpu_device *adev = ip_block->adev;
270 	int ret = 0;
271 
272 	cancel_delayed_work_sync(&adev->jpeg.idle_work);
273 
274 		if (adev->jpeg.cur_state != AMD_PG_STATE_GATE)
275 			ret = jpeg_v5_0_2_set_powergating_state(ip_block, AMD_PG_STATE_GATE);
276 
277 	return ret;
278 }
279 
280 /**
281  * jpeg_v5_0_2_suspend - suspend JPEG block
282  *
283  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
284  *
285  * HW fini and suspend JPEG block
286  */
287 static int jpeg_v5_0_2_suspend(struct amdgpu_ip_block *ip_block)
288 {
289 	struct amdgpu_device *adev = ip_block->adev;
290 	int r;
291 
292 	r = jpeg_v5_0_2_hw_fini(ip_block);
293 	if (r)
294 		return r;
295 
296 	r = amdgpu_jpeg_suspend(adev);
297 
298 	return r;
299 }
300 
301 /**
302  * jpeg_v5_0_2_resume - resume JPEG block
303  *
304  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
305  *
306  * Resume firmware and hw init JPEG block
307  */
308 static int jpeg_v5_0_2_resume(struct amdgpu_ip_block *ip_block)
309 {
310 	struct amdgpu_device *adev = ip_block->adev;
311 	int r;
312 
313 	r = amdgpu_jpeg_resume(adev);
314 	if (r)
315 		return r;
316 
317 	r = jpeg_v5_0_2_hw_init(ip_block);
318 
319 	return r;
320 }
321 
322 static void jpeg_v5_0_2_init_inst(struct amdgpu_device *adev, int i)
323 {
324 	int jpeg_inst = GET_INST(JPEG, i);
325 
326 	/* disable anti hang mechanism */
327 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS), 0,
328 		 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
329 
330 	/* keep the JPEG in static PG mode */
331 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS), 0,
332 		 ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK);
333 
334 	/* MJPEG global tiling registers */
335 	WREG32_SOC15(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG,
336 		     adev->gfx.config.gb_addr_config);
337 
338 	/* enable JMI channel */
339 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL), 0,
340 		 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
341 }
342 
343 static void jpeg_v5_0_2_deinit_inst(struct amdgpu_device *adev, int i)
344 {
345 	int jpeg_inst = GET_INST(JPEG, i);
346 	/* reset JMI */
347 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL),
348 		 UVD_JMI_CNTL__SOFT_RESET_MASK,
349 		 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
350 
351 	/* enable anti hang mechanism */
352 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS),
353 		 UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
354 		 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
355 }
356 
357 static void jpeg_v5_0_2_init_jrbc(struct amdgpu_ring *ring)
358 {
359 	struct amdgpu_device *adev = ring->adev;
360 	u32 reg, data, mask;
361 	int jpeg_inst = GET_INST(JPEG, ring->me);
362 	int reg_offset = ring->pipe ? jpeg_v5_0_2_core_reg_offset(ring->pipe) : 0;
363 
364 	/* enable System Interrupt for JRBC */
365 	reg = SOC15_REG_OFFSET(JPEG, jpeg_inst, regJPEG_SYS_INT_EN);
366 	if (ring->pipe < AMDGPU_MAX_JPEG_RINGS_4_0_3) {
367 		data = JPEG_SYS_INT_EN__DJRBC0_MASK << ring->pipe;
368 		mask = ~(JPEG_SYS_INT_EN__DJRBC0_MASK << ring->pipe);
369 		WREG32_P(reg, data, mask);
370 	} else {
371 		data = JPEG_SYS_INT_EN__DJRBC0_MASK << (ring->pipe+12);
372 		mask = ~(JPEG_SYS_INT_EN__DJRBC0_MASK << (ring->pipe+12));
373 		WREG32_P(reg, data, mask);
374 	}
375 
376 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
377 			    regUVD_LMI_JRBC_RB_VMID,
378 			    reg_offset, 0);
379 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
380 			    regUVD_JRBC_RB_CNTL,
381 			    reg_offset,
382 			    (0x00000001L | 0x00000002L));
383 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
384 			    regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
385 			    reg_offset, lower_32_bits(ring->gpu_addr));
386 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
387 			    regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
388 			    reg_offset, upper_32_bits(ring->gpu_addr));
389 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
390 			    regUVD_JRBC_RB_RPTR,
391 			    reg_offset, 0);
392 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
393 			    regUVD_JRBC_RB_WPTR,
394 			    reg_offset, 0);
395 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
396 			    regUVD_JRBC_RB_CNTL,
397 			    reg_offset, 0x00000002L);
398 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
399 			    regUVD_JRBC_RB_SIZE,
400 			    reg_offset, ring->ring_size / 4);
401 	ring->wptr = RREG32_SOC15_OFFSET(JPEG, jpeg_inst, regUVD_JRBC_RB_WPTR,
402 					 reg_offset);
403 }
404 
405 /**
406  * jpeg_v5_0_2_start - start JPEG block
407  *
408  * @adev: amdgpu_device pointer
409  *
410  * Setup and start the JPEG block
411  */
412 static int jpeg_v5_0_2_start(struct amdgpu_device *adev)
413 {
414 	struct amdgpu_ring *ring;
415 	int i, j;
416 
417 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
418 		jpeg_v5_0_2_init_inst(adev, i);
419 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
420 			ring = &adev->jpeg.inst[i].ring_dec[j];
421 			jpeg_v5_0_2_init_jrbc(ring);
422 		}
423 	}
424 
425 	return 0;
426 }
427 
428 /**
429  * jpeg_v5_0_2_stop - stop JPEG block
430  *
431  * @adev: amdgpu_device pointer
432  *
433  * stop the JPEG block
434  */
435 static int jpeg_v5_0_2_stop(struct amdgpu_device *adev)
436 {
437 	int i;
438 
439 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i)
440 		jpeg_v5_0_2_deinit_inst(adev, i);
441 
442 	return 0;
443 }
444 
445 /**
446  * jpeg_v5_0_2_dec_ring_get_rptr - get read pointer
447  *
448  * @ring: amdgpu_ring pointer
449  *
450  * Returns the current hardware read pointer
451  */
452 static uint64_t jpeg_v5_0_2_dec_ring_get_rptr(struct amdgpu_ring *ring)
453 {
454 	struct amdgpu_device *adev = ring->adev;
455 
456 	return RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC_RB_RPTR,
457 				   ring->pipe ? jpeg_v5_0_2_core_reg_offset(ring->pipe) : 0);
458 }
459 
460 /**
461  * jpeg_v5_0_2_dec_ring_get_wptr - get write pointer
462  *
463  * @ring: amdgpu_ring pointer
464  *
465  * Returns the current hardware write pointer
466  */
467 static uint64_t jpeg_v5_0_2_dec_ring_get_wptr(struct amdgpu_ring *ring)
468 {
469 	struct amdgpu_device *adev = ring->adev;
470 
471 	if (ring->use_doorbell)
472 		return adev->wb.wb[ring->wptr_offs];
473 
474 	return RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC_RB_WPTR,
475 				   ring->pipe ? jpeg_v5_0_2_core_reg_offset(ring->pipe) : 0);
476 }
477 
478 /**
479  * jpeg_v5_0_2_dec_ring_set_wptr - set write pointer
480  *
481  * @ring: amdgpu_ring pointer
482  *
483  * Commits the write pointer to the hardware
484  */
485 static void jpeg_v5_0_2_dec_ring_set_wptr(struct amdgpu_ring *ring)
486 {
487 	struct amdgpu_device *adev = ring->adev;
488 
489 	if (ring->use_doorbell) {
490 		adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
491 		WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
492 	} else {
493 		WREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me),
494 				    regUVD_JRBC_RB_WPTR,
495 				    (ring->pipe ? jpeg_v5_0_2_core_reg_offset(ring->pipe) : 0),
496 				    lower_32_bits(ring->wptr));
497 	}
498 }
499 
500 static bool jpeg_v5_0_2_is_idle(struct amdgpu_ip_block *ip_block)
501 {
502 	struct amdgpu_device *adev = ip_block->adev;
503 	bool ret = false;
504 	int i, j;
505 
506 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
507 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
508 			int reg_offset = (j ? jpeg_v5_0_2_core_reg_offset(j) : 0);
509 
510 			ret &= ((RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, i),
511 				regUVD_JRBC_STATUS, reg_offset) &
512 				UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
513 				UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
514 		}
515 	}
516 
517 	return ret;
518 }
519 
520 static int jpeg_v5_0_2_wait_for_idle(struct amdgpu_ip_block *ip_block)
521 {
522 	struct amdgpu_device *adev = ip_block->adev;
523 	int ret = 0;
524 	int i, j;
525 
526 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
527 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
528 			int reg_offset = (j ? jpeg_v5_0_2_core_reg_offset(j) : 0);
529 
530 			ret &= SOC15_WAIT_ON_RREG_OFFSET(JPEG, GET_INST(JPEG, i),
531 							 regUVD_JRBC_STATUS, reg_offset,
532 							 UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
533 							 UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
534 		}
535 	}
536 	return ret;
537 }
538 
539 static int jpeg_v5_0_2_set_clockgating_state(struct amdgpu_ip_block *ip_block,
540 					     enum amd_clockgating_state state)
541 {
542 	struct amdgpu_device *adev = ip_block->adev;
543 	bool enable = state == AMD_CG_STATE_GATE;
544 
545 	int i;
546 
547 	if (!enable)
548 		return 0;
549 
550 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
551 		if (!jpeg_v5_0_2_is_idle(ip_block))
552 			return -EBUSY;
553 	}
554 
555 	return 0;
556 }
557 
558 static int jpeg_v5_0_2_set_powergating_state(struct amdgpu_ip_block *ip_block,
559 					     enum amd_powergating_state state)
560 {
561 	struct amdgpu_device *adev = ip_block->adev;
562 	int ret;
563 
564 	if (state == adev->jpeg.cur_state)
565 		return 0;
566 
567 	if (state == AMD_PG_STATE_GATE)
568 		ret = jpeg_v5_0_2_stop(adev);
569 	else
570 		ret = jpeg_v5_0_2_start(adev);
571 
572 	if (!ret)
573 		adev->jpeg.cur_state = state;
574 
575 	return ret;
576 }
577 
578 static int jpeg_v5_0_2_set_interrupt_state(struct amdgpu_device *adev,
579 					   struct amdgpu_irq_src *source,
580 					   unsigned int type,
581 					   enum amdgpu_interrupt_state state)
582 {
583 	return 0;
584 }
585 
586 static int jpeg_v5_0_2_process_interrupt(struct amdgpu_device *adev,
587 					 struct amdgpu_irq_src *source,
588 					 struct amdgpu_iv_entry *entry)
589 {
590 	u32 i, inst;
591 
592 	i = node_id_to_phys_map[entry->node_id];
593 	DRM_DEV_DEBUG(adev->dev, "IH: JPEG TRAP\n");
594 
595 	for (inst = 0; inst < adev->jpeg.num_jpeg_inst; ++inst)
596 		if (adev->jpeg.inst[inst].aid_id == i)
597 			break;
598 
599 	if (inst >= adev->jpeg.num_jpeg_inst) {
600 		dev_WARN_ONCE(adev->dev, 1,
601 			      "Interrupt received for unknown JPEG instance %d",
602 			      entry->node_id);
603 		return 0;
604 	}
605 
606 	switch (entry->src_id) {
607 	case VCN_5_0__SRCID__JPEG_DECODE:
608 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[0]);
609 		break;
610 	case VCN_5_0__SRCID__JPEG1_DECODE:
611 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[1]);
612 		break;
613 	case VCN_5_0__SRCID__JPEG2_DECODE:
614 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[2]);
615 		break;
616 	case VCN_5_0__SRCID__JPEG3_DECODE:
617 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[3]);
618 		break;
619 	case VCN_5_0__SRCID__JPEG4_DECODE:
620 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[4]);
621 		break;
622 	case VCN_5_0__SRCID__JPEG5_DECODE:
623 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[5]);
624 		break;
625 	case VCN_5_0__SRCID__JPEG6_DECODE:
626 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[6]);
627 		break;
628 	case VCN_5_0__SRCID__JPEG7_DECODE:
629 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[7]);
630 		break;
631 	case VCN_5_0__SRCID__JPEG8_DECODE:
632 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[8]);
633 		break;
634 	case VCN_5_0__SRCID__JPEG9_DECODE:
635 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[9]);
636 		break;
637 	default:
638 		DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n",
639 			      entry->src_id, entry->src_data[0]);
640 		break;
641 	}
642 
643 	return 0;
644 }
645 
646 static void jpeg_v5_0_2_core_stall_reset(struct amdgpu_ring *ring)
647 {
648 	struct amdgpu_device *adev = ring->adev;
649 	int jpeg_inst = GET_INST(JPEG, ring->me);
650 	int reg_offset = ring->pipe ? jpeg_v5_0_2_core_reg_offset(ring->pipe) : 0;
651 
652 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
653 			    regUVD_JMI0_UVD_JMI_CLIENT_STALL,
654 			    reg_offset, 0x1F);
655 	SOC15_WAIT_ON_RREG_OFFSET(JPEG, jpeg_inst,
656 				  regUVD_JMI0_UVD_JMI_CLIENT_CLEAN_STATUS,
657 				  reg_offset, 0x1F, 0x1F);
658 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
659 			    regUVD_JMI0_JPEG_LMI_DROP,
660 			    reg_offset, 0x1F);
661 	WREG32_SOC15(JPEG, jpeg_inst, regJPEG_CORE_RST_CTRL, 1 << ring->pipe);
662 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
663 			    regUVD_JMI0_UVD_JMI_CLIENT_STALL,
664 			    reg_offset, 0x00);
665 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
666 			    regUVD_JMI0_JPEG_LMI_DROP,
667 			    reg_offset, 0x00);
668 	WREG32_SOC15(JPEG, jpeg_inst, regJPEG_CORE_RST_CTRL, 0x00);
669 }
670 
671 static int jpeg_v5_0_2_ring_reset(struct amdgpu_ring *ring,
672 				  unsigned int vmid,
673 				  struct amdgpu_fence *timedout_fence)
674 {
675 	amdgpu_ring_reset_helper_begin(ring, timedout_fence);
676 	jpeg_v5_0_2_core_stall_reset(ring);
677 	jpeg_v5_0_2_init_jrbc(ring);
678 	return amdgpu_ring_reset_helper_end(ring, timedout_fence);
679 }
680 
681 static const struct amd_ip_funcs jpeg_v5_0_2_ip_funcs = {
682 	.name = "jpeg_v5_0_2",
683 	.early_init = jpeg_v5_0_2_early_init,
684 	.late_init = NULL,
685 	.sw_init = jpeg_v5_0_2_sw_init,
686 	.sw_fini = jpeg_v5_0_2_sw_fini,
687 	.hw_init = jpeg_v5_0_2_hw_init,
688 	.hw_fini = jpeg_v5_0_2_hw_fini,
689 	.suspend = jpeg_v5_0_2_suspend,
690 	.resume = jpeg_v5_0_2_resume,
691 	.is_idle = jpeg_v5_0_2_is_idle,
692 	.wait_for_idle = jpeg_v5_0_2_wait_for_idle,
693 	.check_soft_reset = NULL,
694 	.pre_soft_reset = NULL,
695 	.soft_reset = NULL,
696 	.post_soft_reset = NULL,
697 	.set_clockgating_state = jpeg_v5_0_2_set_clockgating_state,
698 	.set_powergating_state = jpeg_v5_0_2_set_powergating_state,
699 	.dump_ip_state = amdgpu_jpeg_dump_ip_state,
700 	.print_ip_state = amdgpu_jpeg_print_ip_state,
701 };
702 
703 static const struct amdgpu_ring_funcs jpeg_v5_0_2_dec_ring_vm_funcs = {
704 	.type = AMDGPU_RING_TYPE_VCN_JPEG,
705 	.align_mask = 0xf,
706 	.get_rptr = jpeg_v5_0_2_dec_ring_get_rptr,
707 	.get_wptr = jpeg_v5_0_2_dec_ring_get_wptr,
708 	.set_wptr = jpeg_v5_0_2_dec_ring_set_wptr,
709 	.emit_frame_size =
710 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
711 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
712 		8 + /* jpeg_v5_0_2_dec_ring_emit_vm_flush */
713 		22 + 22 + /* jpeg_v5_0_2_dec_ring_emit_fence x2 vm fence */
714 		8 + 16,
715 	.emit_ib_size = 22, /* jpeg_v5_0_2_dec_ring_emit_ib */
716 	.emit_ib = jpeg_v4_0_3_dec_ring_emit_ib,
717 	.emit_fence = jpeg_v4_0_3_dec_ring_emit_fence,
718 	.emit_vm_flush = jpeg_v4_0_3_dec_ring_emit_vm_flush,
719 	.emit_hdp_flush = jpeg_v4_0_3_ring_emit_hdp_flush,
720 	.test_ring = amdgpu_jpeg_dec_ring_test_ring,
721 	.test_ib = amdgpu_jpeg_dec_ring_test_ib,
722 	.insert_nop = jpeg_v4_0_3_dec_ring_nop,
723 	.insert_start = jpeg_v4_0_3_dec_ring_insert_start,
724 	.insert_end = jpeg_v4_0_3_dec_ring_insert_end,
725 	.pad_ib = amdgpu_ring_generic_pad_ib,
726 	.begin_use = amdgpu_jpeg_ring_begin_use,
727 	.end_use = amdgpu_jpeg_ring_end_use,
728 	.emit_wreg = jpeg_v4_0_3_dec_ring_emit_wreg,
729 	.emit_reg_wait = jpeg_v4_0_3_dec_ring_emit_reg_wait,
730 	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
731 	.reset = jpeg_v5_0_2_ring_reset,
732 };
733 
734 static void jpeg_v5_0_2_set_dec_ring_funcs(struct amdgpu_device *adev)
735 {
736 	int i, j, jpeg_inst;
737 
738 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
739 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
740 			adev->jpeg.inst[i].ring_dec[j].funcs = &jpeg_v5_0_2_dec_ring_vm_funcs;
741 			adev->jpeg.inst[i].ring_dec[j].me = i;
742 			adev->jpeg.inst[i].ring_dec[j].pipe = j;
743 		}
744 		jpeg_inst = GET_INST(JPEG, i);
745 		adev->jpeg.inst[i].aid_id =
746 			jpeg_inst / adev->jpeg.num_inst_per_aid;
747 	}
748 }
749 
750 static const struct amdgpu_irq_src_funcs jpeg_v5_0_2_irq_funcs = {
751 	.set = jpeg_v5_0_2_set_interrupt_state,
752 	.process = jpeg_v5_0_2_process_interrupt,
753 };
754 
755 static void jpeg_v5_0_2_set_irq_funcs(struct amdgpu_device *adev)
756 {
757 	int i;
758 
759 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i)
760 		adev->jpeg.inst->irq.num_types += adev->jpeg.num_jpeg_rings;
761 
762 	adev->jpeg.inst->irq.funcs = &jpeg_v5_0_2_irq_funcs;
763 }
764 
765 const struct amdgpu_ip_block_version jpeg_v5_0_2_ip_block = {
766 	.type = AMD_IP_BLOCK_TYPE_JPEG,
767 	.major = 5,
768 	.minor = 0,
769 	.rev = 2,
770 	.funcs = &jpeg_v5_0_2_ip_funcs,
771 };
772 
773 #if 0
774 static int jpeg_v5_0_2_aca_bank_parser(struct aca_handle *handle, struct aca_bank *bank,
775 					enum aca_smu_type type, void *data)
776 {
777 	struct aca_bank_info info;
778 	u64 misc0;
779 	int ret;
780 
781 	ret = aca_bank_info_decode(bank, &info);
782 	if (ret)
783 		return ret;
784 
785 	misc0 = bank->regs[ACA_REG_IDX_MISC0];
786 	switch (type) {
787 	case ACA_SMU_TYPE_UE:
788 		bank->aca_err_type = ACA_ERROR_TYPE_UE;
789 		ret = aca_error_cache_log_bank_error(handle, &info, ACA_ERROR_TYPE_UE,
790 						1ULL);
791 		break;
792 	case ACA_SMU_TYPE_CE:
793 		bank->aca_err_type = ACA_ERROR_TYPE_CE;
794 		ret = aca_error_cache_log_bank_error(handle, &info, bank->aca_err_type,
795 						ACA_REG__MISC0__ERRCNT(misc0));
796 		break;
797 	default:
798 		return -EINVAL;
799 	}
800 
801 	return ret;
802 }
803 
804 /* reference to smu driver if header file */
805 static int jpeg_v5_0_2_err_codes[] = {
806 	16, 17, 18, 19, 20, 21, 22, 23, /* JPEG[0-9][S|D] */
807 	24, 25, 26, 27, 28, 29, 30, 31,
808 	48, 49, 50, 51,
809 };
810 
811 static bool jpeg_v5_0_2_aca_bank_is_valid(struct aca_handle *handle, struct aca_bank *bank,
812 					enum aca_smu_type type, void *data)
813 {
814 	u32 instlo;
815 
816 	instlo = ACA_REG__IPID__INSTANCEIDLO(bank->regs[ACA_REG_IDX_IPID]);
817 	instlo &= GENMASK(31, 1);
818 
819 	if (instlo != mmSMNAID_AID0_MCA_SMU)
820 		return false;
821 
822 	if (aca_bank_check_error_codes(handle->adev, bank,
823 					jpeg_v5_0_2_err_codes,
824 					ARRAY_SIZE(jpeg_v5_0_2_err_codes)))
825 		return false;
826 
827 	return true;
828 }
829 
830 static const struct aca_bank_ops jpeg_v5_0_2_aca_bank_ops = {
831 	.aca_bank_parser = jpeg_v5_0_2_aca_bank_parser,
832 	.aca_bank_is_valid = jpeg_v5_0_2_aca_bank_is_valid,
833 };
834 
835 static const struct aca_info jpeg_v5_0_2_aca_info = {
836 	.hwip = ACA_HWIP_TYPE_SMU,
837 	.mask = ACA_ERROR_UE_MASK,
838 	.bank_ops = &jpeg_v5_0_2_aca_bank_ops,
839 };
840 #endif
841