xref: /linux/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c (revision 76e3b62db9bf2dbedc5f41070684fdec64cd71a6)
1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /*
3  * Copyright 2014-2024 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_1.h"
31 
32 #include "vcn/vcn_5_0_0_offset.h"
33 #include "vcn/vcn_5_0_0_sh_mask.h"
34 #include "ivsrcid/vcn/irqsrcs_vcn_5_0.h"
35 
36 static void jpeg_v5_0_1_set_dec_ring_funcs(struct amdgpu_device *adev);
37 static void jpeg_v5_0_1_set_irq_funcs(struct amdgpu_device *adev);
38 static int jpeg_v5_0_1_set_powergating_state(struct amdgpu_ip_block *ip_block,
39 					     enum amd_powergating_state state);
40 static void jpeg_v5_0_1_dec_ring_set_wptr(struct amdgpu_ring *ring);
41 
42 static int amdgpu_ih_srcid_jpeg[] = {
43 	VCN_5_0__SRCID__JPEG_DECODE,
44 	VCN_5_0__SRCID__JPEG1_DECODE,
45 	VCN_5_0__SRCID__JPEG2_DECODE,
46 	VCN_5_0__SRCID__JPEG3_DECODE,
47 	VCN_5_0__SRCID__JPEG4_DECODE,
48 	VCN_5_0__SRCID__JPEG5_DECODE,
49 	VCN_5_0__SRCID__JPEG6_DECODE,
50 	VCN_5_0__SRCID__JPEG7_DECODE,
51 	VCN_5_0__SRCID__JPEG8_DECODE,
52 	VCN_5_0__SRCID__JPEG9_DECODE,
53 };
54 
55 static const struct amdgpu_hwip_reg_entry jpeg_reg_list_5_0_1[] = {
56 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_POWER_STATUS),
57 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_INT_STAT),
58 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_RPTR),
59 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_WPTR),
60 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_STATUS),
61 	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_ADDR_MODE),
62 	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG),
63 	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_Y_GFX10_TILING_SURFACE),
64 	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_UV_GFX10_TILING_SURFACE),
65 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_PITCH),
66 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_UV_PITCH),
67 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_RB_RPTR),
68 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_RB_WPTR),
69 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_STATUS),
70 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_RB_RPTR),
71 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_RB_WPTR),
72 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_STATUS),
73 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_RB_RPTR),
74 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_RB_WPTR),
75 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_STATUS),
76 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_RB_RPTR),
77 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_RB_WPTR),
78 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_STATUS),
79 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_RB_RPTR),
80 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_RB_WPTR),
81 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_STATUS),
82 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_RB_RPTR),
83 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_RB_WPTR),
84 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_STATUS),
85 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_RB_RPTR),
86 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_RB_WPTR),
87 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_STATUS),
88 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC8_UVD_JRBC_RB_RPTR),
89 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC8_UVD_JRBC_RB_WPTR),
90 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC8_UVD_JRBC_STATUS),
91 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC9_UVD_JRBC_RB_RPTR),
92 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC9_UVD_JRBC_RB_WPTR),
93 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC9_UVD_JRBC_STATUS),
94 };
95 
96 static int jpeg_v5_0_1_core_reg_offset(u32 pipe)
97 {
98 	if (pipe <= AMDGPU_MAX_JPEG_RINGS_4_0_3)
99 		return ((0x40 * pipe) - 0xc80);
100 	else
101 		return ((0x40 * pipe) - 0x440);
102 }
103 
104 /**
105  * jpeg_v5_0_1_early_init - set function pointers
106  *
107  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
108  *
109  * Set ring and irq function pointers
110  */
111 static int jpeg_v5_0_1_early_init(struct amdgpu_ip_block *ip_block)
112 {
113 	struct amdgpu_device *adev = ip_block->adev;
114 
115 	if (!adev->jpeg.num_jpeg_inst || adev->jpeg.num_jpeg_inst > AMDGPU_MAX_JPEG_INSTANCES)
116 		return -ENOENT;
117 
118 	adev->jpeg.num_jpeg_rings = AMDGPU_MAX_JPEG_RINGS;
119 	jpeg_v5_0_1_set_dec_ring_funcs(adev);
120 	jpeg_v5_0_1_set_irq_funcs(adev);
121 
122 	return 0;
123 }
124 
125 /**
126  * jpeg_v5_0_1_sw_init - sw init for JPEG block
127  *
128  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
129  *
130  * Load firmware and sw initialization
131  */
132 static int jpeg_v5_0_1_sw_init(struct amdgpu_ip_block *ip_block)
133 {
134 	struct amdgpu_device *adev = ip_block->adev;
135 	struct amdgpu_ring *ring;
136 	int i, j, r, jpeg_inst;
137 
138 	for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
139 		/* JPEG TRAP */
140 		r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
141 				      amdgpu_ih_srcid_jpeg[j], &adev->jpeg.inst->irq);
142 		if (r)
143 			return r;
144 	}
145 
146 	r = amdgpu_jpeg_sw_init(adev);
147 	if (r)
148 		return r;
149 
150 	r = amdgpu_jpeg_resume(adev);
151 	if (r)
152 		return r;
153 
154 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
155 		jpeg_inst = GET_INST(JPEG, i);
156 
157 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
158 			ring = &adev->jpeg.inst[i].ring_dec[j];
159 			ring->use_doorbell = false;
160 			ring->vm_hub = AMDGPU_MMHUB0(adev->jpeg.inst[i].aid_id);
161 			if (!amdgpu_sriov_vf(adev)) {
162 				ring->doorbell_index =
163 					(adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
164 					1 + j + 11 * jpeg_inst;
165 			} else {
166 				if (j < 4)
167 					ring->doorbell_index =
168 						(adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
169 						4 + j + 32 * jpeg_inst;
170 				else
171 					ring->doorbell_index =
172 						(adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
173 						8 + j + 32 * jpeg_inst;
174 			}
175 			sprintf(ring->name, "jpeg_dec_%d.%d", adev->jpeg.inst[i].aid_id, j);
176 			r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0,
177 					     AMDGPU_RING_PRIO_DEFAULT, NULL);
178 			if (r)
179 				return r;
180 
181 			adev->jpeg.internal.jpeg_pitch[j] =
182 				regUVD_JRBC0_UVD_JRBC_SCRATCH0_INTERNAL_OFFSET;
183 			adev->jpeg.inst[i].external.jpeg_pitch[j] =
184 				SOC15_REG_OFFSET1(JPEG, jpeg_inst, regUVD_JRBC_SCRATCH0,
185 						  (j ? jpeg_v5_0_1_core_reg_offset(j) : 0));
186 		}
187 	}
188 
189 	r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_5_0_1, ARRAY_SIZE(jpeg_reg_list_5_0_1));
190 	if (r)
191 		return r;
192 
193 	return 0;
194 }
195 
196 /**
197  * jpeg_v5_0_1_sw_fini - sw fini for JPEG block
198  *
199  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
200  *
201  * JPEG suspend and free up sw allocation
202  */
203 static int jpeg_v5_0_1_sw_fini(struct amdgpu_ip_block *ip_block)
204 {
205 	struct amdgpu_device *adev = ip_block->adev;
206 	int r;
207 
208 	r = amdgpu_jpeg_suspend(adev);
209 	if (r)
210 		return r;
211 
212 	r = amdgpu_jpeg_sw_fini(adev);
213 
214 	return r;
215 }
216 
217 /**
218  * jpeg_v5_0_1_hw_init - start and test JPEG block
219  *
220  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
221  *
222  */
223 static int jpeg_v5_0_1_hw_init(struct amdgpu_ip_block *ip_block)
224 {
225 	struct amdgpu_device *adev = ip_block->adev;
226 	struct amdgpu_ring *ring;
227 	int i, j, r, jpeg_inst;
228 
229 	if (amdgpu_sriov_vf(adev)) {
230 		/* jpeg_v5_0_1_start_sriov(adev); */
231 		for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
232 			for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
233 				ring = &adev->jpeg.inst[i].ring_dec[j];
234 				ring->wptr = 0;
235 				ring->wptr_old = 0;
236 				jpeg_v5_0_1_dec_ring_set_wptr(ring);
237 				ring->sched.ready = true;
238 			}
239 		}
240 		return 0;
241 	}
242 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
243 		jpeg_inst = GET_INST(JPEG, i);
244 		ring = adev->jpeg.inst[i].ring_dec;
245 		if (ring->use_doorbell)
246 			adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
247 				 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 11 * jpeg_inst,
248 				 adev->jpeg.inst[i].aid_id);
249 
250 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
251 			ring = &adev->jpeg.inst[i].ring_dec[j];
252 			if (ring->use_doorbell)
253 				WREG32_SOC15_OFFSET(VCN, GET_INST(VCN, i), regVCN_JPEG_DB_CTRL,
254 						    (ring->pipe ? (ring->pipe - 0x15) : 0),
255 						    ring->doorbell_index <<
256 						    VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
257 						    VCN_JPEG_DB_CTRL__EN_MASK);
258 			r = amdgpu_ring_test_helper(ring);
259 			if (r)
260 				return r;
261 		}
262 	}
263 
264 	return 0;
265 }
266 
267 /**
268  * jpeg_v5_0_1_hw_fini - stop the hardware block
269  *
270  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
271  *
272  * Stop the JPEG block, mark ring as not ready any more
273  */
274 static int jpeg_v5_0_1_hw_fini(struct amdgpu_ip_block *ip_block)
275 {
276 	struct amdgpu_device *adev = ip_block->adev;
277 	int ret = 0;
278 
279 	cancel_delayed_work_sync(&adev->jpeg.idle_work);
280 
281 	if (adev->jpeg.cur_state != AMD_PG_STATE_GATE)
282 		ret = jpeg_v5_0_1_set_powergating_state(ip_block, AMD_PG_STATE_GATE);
283 
284 	return ret;
285 }
286 
287 /**
288  * jpeg_v5_0_1_suspend - suspend JPEG block
289  *
290  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
291  *
292  * HW fini and suspend JPEG block
293  */
294 static int jpeg_v5_0_1_suspend(struct amdgpu_ip_block *ip_block)
295 {
296 	struct amdgpu_device *adev = ip_block->adev;
297 	int r;
298 
299 	r = jpeg_v5_0_1_hw_fini(ip_block);
300 	if (r)
301 		return r;
302 
303 	r = amdgpu_jpeg_suspend(adev);
304 
305 	return r;
306 }
307 
308 /**
309  * jpeg_v5_0_1_resume - resume JPEG block
310  *
311  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
312  *
313  * Resume firmware and hw init JPEG block
314  */
315 static int jpeg_v5_0_1_resume(struct amdgpu_ip_block *ip_block)
316 {
317 	struct amdgpu_device *adev = ip_block->adev;
318 	int r;
319 
320 	r = amdgpu_jpeg_resume(adev);
321 	if (r)
322 		return r;
323 
324 	r = jpeg_v5_0_1_hw_init(ip_block);
325 
326 	return r;
327 }
328 
329 static int jpeg_v5_0_1_disable_antihang(struct amdgpu_device *adev, int inst_idx)
330 {
331 	int jpeg_inst;
332 
333 	jpeg_inst = GET_INST(JPEG, inst_idx);
334 	/* disable anti hang mechanism */
335 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS), 0,
336 		 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
337 
338 	/* keep the JPEG in static PG mode */
339 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS), 0,
340 		 ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK);
341 
342 	return 0;
343 }
344 
345 static int jpeg_v5_0_1_enable_antihang(struct amdgpu_device *adev, int inst_idx)
346 {
347 	int jpeg_inst;
348 
349 	jpeg_inst = GET_INST(JPEG, inst_idx);
350 	/* enable anti hang mechanism */
351 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS),
352 		 UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
353 		~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
354 
355 	return 0;
356 }
357 
358 /**
359  * jpeg_v5_0_1_start - start JPEG block
360  *
361  * @adev: amdgpu_device pointer
362  *
363  * Setup and start the JPEG block
364  */
365 static int jpeg_v5_0_1_start(struct amdgpu_device *adev)
366 {
367 	struct amdgpu_ring *ring;
368 	int i, j, jpeg_inst, r;
369 
370 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
371 		jpeg_inst = GET_INST(JPEG, i);
372 
373 		/* disable antihang */
374 		r = jpeg_v5_0_1_disable_antihang(adev, i);
375 		if (r)
376 			return r;
377 
378 		/* MJPEG global tiling registers */
379 		WREG32_SOC15(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG,
380 			     adev->gfx.config.gb_addr_config);
381 
382 		/* enable JMI channel */
383 		WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL), 0,
384 			 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
385 
386 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
387 			int reg_offset = (j ? jpeg_v5_0_1_core_reg_offset(j) : 0);
388 			u32 reg, data, mask;
389 
390 			ring = &adev->jpeg.inst[i].ring_dec[j];
391 
392 			/* enable System Interrupt for JRBC */
393 			reg = SOC15_REG_OFFSET(JPEG, jpeg_inst, regJPEG_SYS_INT_EN);
394 			if (j < AMDGPU_MAX_JPEG_RINGS_4_0_3) {
395 				data = JPEG_SYS_INT_EN__DJRBC0_MASK << j;
396 				mask = ~(JPEG_SYS_INT_EN__DJRBC0_MASK << j);
397 				WREG32_P(reg, data, mask);
398 			} else {
399 				data = JPEG_SYS_INT_EN__DJRBC0_MASK << (j+12);
400 				mask = ~(JPEG_SYS_INT_EN__DJRBC0_MASK << (j+12));
401 				WREG32_P(reg, data, mask);
402 			}
403 
404 			WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
405 					    regUVD_LMI_JRBC_RB_VMID,
406 					    reg_offset, 0);
407 			WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
408 					    regUVD_JRBC_RB_CNTL,
409 					    reg_offset,
410 					    (0x00000001L | 0x00000002L));
411 			WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
412 					    regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
413 					    reg_offset, lower_32_bits(ring->gpu_addr));
414 			WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
415 					    regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
416 					    reg_offset, upper_32_bits(ring->gpu_addr));
417 			WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
418 					    regUVD_JRBC_RB_RPTR,
419 					    reg_offset, 0);
420 			WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
421 					    regUVD_JRBC_RB_WPTR,
422 					    reg_offset, 0);
423 			WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
424 					    regUVD_JRBC_RB_CNTL,
425 					    reg_offset, 0x00000002L);
426 			WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
427 					    regUVD_JRBC_RB_SIZE,
428 					    reg_offset, ring->ring_size / 4);
429 			ring->wptr = RREG32_SOC15_OFFSET(JPEG, jpeg_inst, regUVD_JRBC_RB_WPTR,
430 							 reg_offset);
431 		}
432 	}
433 
434 	return 0;
435 }
436 
437 /**
438  * jpeg_v5_0_1_stop - stop JPEG block
439  *
440  * @adev: amdgpu_device pointer
441  *
442  * stop the JPEG block
443  */
444 static int jpeg_v5_0_1_stop(struct amdgpu_device *adev)
445 {
446 	int i, jpeg_inst, r;
447 
448 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
449 		jpeg_inst = GET_INST(JPEG, i);
450 		/* reset JMI */
451 		WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL),
452 			 UVD_JMI_CNTL__SOFT_RESET_MASK,
453 			 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
454 
455 		/* enable antihang */
456 		r = jpeg_v5_0_1_enable_antihang(adev, i);
457 		if (r)
458 			return r;
459 	}
460 
461 	return 0;
462 }
463 
464 /**
465  * jpeg_v5_0_1_dec_ring_get_rptr - get read pointer
466  *
467  * @ring: amdgpu_ring pointer
468  *
469  * Returns the current hardware read pointer
470  */
471 static uint64_t jpeg_v5_0_1_dec_ring_get_rptr(struct amdgpu_ring *ring)
472 {
473 	struct amdgpu_device *adev = ring->adev;
474 
475 	return RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC_RB_RPTR,
476 				   ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0);
477 }
478 
479 /**
480  * jpeg_v5_0_1_dec_ring_get_wptr - get write pointer
481  *
482  * @ring: amdgpu_ring pointer
483  *
484  * Returns the current hardware write pointer
485  */
486 static uint64_t jpeg_v5_0_1_dec_ring_get_wptr(struct amdgpu_ring *ring)
487 {
488 	struct amdgpu_device *adev = ring->adev;
489 
490 	if (ring->use_doorbell)
491 		return adev->wb.wb[ring->wptr_offs];
492 
493 	return RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC_RB_WPTR,
494 				   ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0);
495 }
496 
497 /**
498  * jpeg_v5_0_1_dec_ring_set_wptr - set write pointer
499  *
500  * @ring: amdgpu_ring pointer
501  *
502  * Commits the write pointer to the hardware
503  */
504 static void jpeg_v5_0_1_dec_ring_set_wptr(struct amdgpu_ring *ring)
505 {
506 	struct amdgpu_device *adev = ring->adev;
507 
508 	if (ring->use_doorbell) {
509 		adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
510 		WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
511 	} else {
512 		WREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me),
513 				    regUVD_JRBC_RB_WPTR,
514 				    (ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0),
515 				    lower_32_bits(ring->wptr));
516 	}
517 }
518 
519 static bool jpeg_v5_0_1_is_idle(void *handle)
520 {
521 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
522 	bool ret = false;
523 	int i, j;
524 
525 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
526 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
527 			int reg_offset = (j ? jpeg_v5_0_1_core_reg_offset(j) : 0);
528 
529 			ret &= ((RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, i),
530 				regUVD_JRBC_STATUS, reg_offset) &
531 				UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
532 				UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
533 		}
534 	}
535 
536 	return ret;
537 }
538 
539 static int jpeg_v5_0_1_wait_for_idle(struct amdgpu_ip_block *ip_block)
540 {
541 	struct amdgpu_device *adev = ip_block->adev;
542 	int ret = 0;
543 	int i, j;
544 
545 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
546 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
547 			int reg_offset = (j ? jpeg_v5_0_1_core_reg_offset(j) : 0);
548 
549 			ret &= SOC15_WAIT_ON_RREG_OFFSET(JPEG, GET_INST(JPEG, i),
550 							 regUVD_JRBC_STATUS, reg_offset,
551 							 UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
552 							 UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
553 		}
554 	}
555 	return ret;
556 }
557 
558 static int jpeg_v5_0_1_set_clockgating_state(struct amdgpu_ip_block *ip_block,
559 					     enum amd_clockgating_state state)
560 {
561 	struct amdgpu_device *adev = ip_block->adev;
562 	bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
563 
564 	int i;
565 
566 	if (!enable)
567 		return 0;
568 
569 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
570 		if (!jpeg_v5_0_1_is_idle(adev))
571 			return -EBUSY;
572 	}
573 
574 	return 0;
575 }
576 
577 static int jpeg_v5_0_1_set_powergating_state(struct amdgpu_ip_block *ip_block,
578 					     enum amd_powergating_state state)
579 {
580 	struct amdgpu_device *adev = ip_block->adev;
581 	int ret;
582 
583 	if (state == adev->jpeg.cur_state)
584 		return 0;
585 
586 	if (state == AMD_PG_STATE_GATE)
587 		ret = jpeg_v5_0_1_stop(adev);
588 	else
589 		ret = jpeg_v5_0_1_start(adev);
590 
591 	if (!ret)
592 		adev->jpeg.cur_state = state;
593 
594 	return ret;
595 }
596 
597 static int jpeg_v5_0_1_set_interrupt_state(struct amdgpu_device *adev,
598 					   struct amdgpu_irq_src *source,
599 					   unsigned int type,
600 					   enum amdgpu_interrupt_state state)
601 {
602 	return 0;
603 }
604 
605 static int jpeg_v5_0_1_process_interrupt(struct amdgpu_device *adev,
606 					 struct amdgpu_irq_src *source,
607 					 struct amdgpu_iv_entry *entry)
608 {
609 	u32 i, inst;
610 
611 	i = node_id_to_phys_map[entry->node_id];
612 	DRM_DEV_DEBUG(adev->dev, "IH: JPEG TRAP\n");
613 
614 	for (inst = 0; inst < adev->jpeg.num_jpeg_inst; ++inst)
615 		if (adev->jpeg.inst[inst].aid_id == i)
616 			break;
617 
618 	if (inst >= adev->jpeg.num_jpeg_inst) {
619 		dev_WARN_ONCE(adev->dev, 1,
620 			      "Interrupt received for unknown JPEG instance %d",
621 			      entry->node_id);
622 		return 0;
623 	}
624 
625 	switch (entry->src_id) {
626 	case VCN_5_0__SRCID__JPEG_DECODE:
627 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[0]);
628 		break;
629 	case VCN_5_0__SRCID__JPEG1_DECODE:
630 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[1]);
631 		break;
632 	case VCN_5_0__SRCID__JPEG2_DECODE:
633 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[2]);
634 		break;
635 	case VCN_5_0__SRCID__JPEG3_DECODE:
636 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[3]);
637 		break;
638 	case VCN_5_0__SRCID__JPEG4_DECODE:
639 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[4]);
640 		break;
641 	case VCN_5_0__SRCID__JPEG5_DECODE:
642 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[5]);
643 		break;
644 	case VCN_5_0__SRCID__JPEG6_DECODE:
645 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[6]);
646 		break;
647 	case VCN_5_0__SRCID__JPEG7_DECODE:
648 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[7]);
649 		break;
650 	case VCN_5_0__SRCID__JPEG8_DECODE:
651 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[8]);
652 		break;
653 	case VCN_5_0__SRCID__JPEG9_DECODE:
654 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[9]);
655 		break;
656 	default:
657 		DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n",
658 			      entry->src_id, entry->src_data[0]);
659 		break;
660 	}
661 
662 	return 0;
663 }
664 
665 static const struct amd_ip_funcs jpeg_v5_0_1_ip_funcs = {
666 	.name = "jpeg_v5_0_1",
667 	.early_init = jpeg_v5_0_1_early_init,
668 	.late_init = NULL,
669 	.sw_init = jpeg_v5_0_1_sw_init,
670 	.sw_fini = jpeg_v5_0_1_sw_fini,
671 	.hw_init = jpeg_v5_0_1_hw_init,
672 	.hw_fini = jpeg_v5_0_1_hw_fini,
673 	.suspend = jpeg_v5_0_1_suspend,
674 	.resume = jpeg_v5_0_1_resume,
675 	.is_idle = jpeg_v5_0_1_is_idle,
676 	.wait_for_idle = jpeg_v5_0_1_wait_for_idle,
677 	.check_soft_reset = NULL,
678 	.pre_soft_reset = NULL,
679 	.soft_reset = NULL,
680 	.post_soft_reset = NULL,
681 	.set_clockgating_state = jpeg_v5_0_1_set_clockgating_state,
682 	.set_powergating_state = jpeg_v5_0_1_set_powergating_state,
683 	.dump_ip_state = amdgpu_jpeg_dump_ip_state,
684 	.print_ip_state = amdgpu_jpeg_print_ip_state,
685 };
686 
687 static const struct amdgpu_ring_funcs jpeg_v5_0_1_dec_ring_vm_funcs = {
688 	.type = AMDGPU_RING_TYPE_VCN_JPEG,
689 	.align_mask = 0xf,
690 	.get_rptr = jpeg_v5_0_1_dec_ring_get_rptr,
691 	.get_wptr = jpeg_v5_0_1_dec_ring_get_wptr,
692 	.set_wptr = jpeg_v5_0_1_dec_ring_set_wptr,
693 	.emit_frame_size =
694 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
695 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
696 		8 + /* jpeg_v5_0_1_dec_ring_emit_vm_flush */
697 		22 + 22 + /* jpeg_v5_0_1_dec_ring_emit_fence x2 vm fence */
698 		8 + 16,
699 	.emit_ib_size = 22, /* jpeg_v5_0_1_dec_ring_emit_ib */
700 	.emit_ib = jpeg_v4_0_3_dec_ring_emit_ib,
701 	.emit_fence = jpeg_v4_0_3_dec_ring_emit_fence,
702 	.emit_vm_flush = jpeg_v4_0_3_dec_ring_emit_vm_flush,
703 	.test_ring = amdgpu_jpeg_dec_ring_test_ring,
704 	.test_ib = amdgpu_jpeg_dec_ring_test_ib,
705 	.insert_nop = jpeg_v4_0_3_dec_ring_nop,
706 	.insert_start = jpeg_v4_0_3_dec_ring_insert_start,
707 	.insert_end = jpeg_v4_0_3_dec_ring_insert_end,
708 	.pad_ib = amdgpu_ring_generic_pad_ib,
709 	.begin_use = amdgpu_jpeg_ring_begin_use,
710 	.end_use = amdgpu_jpeg_ring_end_use,
711 	.emit_wreg = jpeg_v4_0_3_dec_ring_emit_wreg,
712 	.emit_reg_wait = jpeg_v4_0_3_dec_ring_emit_reg_wait,
713 	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
714 };
715 
716 static void jpeg_v5_0_1_set_dec_ring_funcs(struct amdgpu_device *adev)
717 {
718 	int i, j, jpeg_inst;
719 
720 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
721 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
722 			adev->jpeg.inst[i].ring_dec[j].funcs = &jpeg_v5_0_1_dec_ring_vm_funcs;
723 			adev->jpeg.inst[i].ring_dec[j].me = i;
724 			adev->jpeg.inst[i].ring_dec[j].pipe = j;
725 		}
726 		jpeg_inst = GET_INST(JPEG, i);
727 		adev->jpeg.inst[i].aid_id =
728 			jpeg_inst / adev->jpeg.num_inst_per_aid;
729 	}
730 }
731 
732 static const struct amdgpu_irq_src_funcs jpeg_v5_0_1_irq_funcs = {
733 	.set = jpeg_v5_0_1_set_interrupt_state,
734 	.process = jpeg_v5_0_1_process_interrupt,
735 };
736 
737 static void jpeg_v5_0_1_set_irq_funcs(struct amdgpu_device *adev)
738 {
739 	int i;
740 
741 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i)
742 		adev->jpeg.inst->irq.num_types += adev->jpeg.num_jpeg_rings;
743 
744 	adev->jpeg.inst->irq.funcs = &jpeg_v5_0_1_irq_funcs;
745 }
746 
747 const struct amdgpu_ip_block_version jpeg_v5_0_1_ip_block = {
748 	.type = AMD_IP_BLOCK_TYPE_JPEG,
749 	.major = 5,
750 	.minor = 0,
751 	.rev = 1,
752 	.funcs = &jpeg_v5_0_1_ip_funcs,
753 };
754