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