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 
jpeg_v5_0_1_core_reg_offset(u32 pipe)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  */
jpeg_v5_0_1_early_init(struct amdgpu_ip_block * ip_block)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  */
jpeg_v5_0_1_sw_init(struct amdgpu_ip_block * ip_block)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 	if (!amdgpu_sriov_vf(adev)) {
194 		adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
195 		r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
196 		if (r)
197 			return r;
198 	}
199 
200 	return 0;
201 }
202 
203 /**
204  * jpeg_v5_0_1_sw_fini - sw fini for JPEG block
205  *
206  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
207  *
208  * JPEG suspend and free up sw allocation
209  */
jpeg_v5_0_1_sw_fini(struct amdgpu_ip_block * ip_block)210 static int jpeg_v5_0_1_sw_fini(struct amdgpu_ip_block *ip_block)
211 {
212 	struct amdgpu_device *adev = ip_block->adev;
213 	int r;
214 
215 	r = amdgpu_jpeg_suspend(adev);
216 	if (r)
217 		return r;
218 
219 	if (!amdgpu_sriov_vf(adev))
220 		amdgpu_jpeg_sysfs_reset_mask_fini(adev);
221 
222 	r = amdgpu_jpeg_sw_fini(adev);
223 
224 	return r;
225 }
226 
227 /**
228  * jpeg_v5_0_1_hw_init - start and test JPEG block
229  *
230  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
231  *
232  */
jpeg_v5_0_1_hw_init(struct amdgpu_ip_block * ip_block)233 static int jpeg_v5_0_1_hw_init(struct amdgpu_ip_block *ip_block)
234 {
235 	struct amdgpu_device *adev = ip_block->adev;
236 	struct amdgpu_ring *ring;
237 	int i, j, r, jpeg_inst;
238 
239 	if (amdgpu_sriov_vf(adev)) {
240 		/* jpeg_v5_0_1_start_sriov(adev); */
241 		for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
242 			for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
243 				ring = &adev->jpeg.inst[i].ring_dec[j];
244 				ring->wptr = 0;
245 				ring->wptr_old = 0;
246 				jpeg_v5_0_1_dec_ring_set_wptr(ring);
247 				ring->sched.ready = true;
248 			}
249 		}
250 		return 0;
251 	}
252 	if (RREG32_SOC15(VCN, GET_INST(VCN, 0), regVCN_RRMT_CNTL) & 0x100)
253 		adev->jpeg.caps |= AMDGPU_JPEG_CAPS(RRMT_ENABLED);
254 
255 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
256 		jpeg_inst = GET_INST(JPEG, i);
257 		ring = adev->jpeg.inst[i].ring_dec;
258 		if (ring->use_doorbell)
259 			adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
260 				 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 11 * jpeg_inst,
261 				 adev->jpeg.inst[i].aid_id);
262 
263 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
264 			ring = &adev->jpeg.inst[i].ring_dec[j];
265 			if (ring->use_doorbell)
266 				WREG32_SOC15_OFFSET(VCN, GET_INST(VCN, i), regVCN_JPEG_DB_CTRL,
267 						    (ring->pipe ? (ring->pipe - 0x15) : 0),
268 						    ring->doorbell_index <<
269 						    VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
270 						    VCN_JPEG_DB_CTRL__EN_MASK);
271 			r = amdgpu_ring_test_helper(ring);
272 			if (r)
273 				return r;
274 		}
275 	}
276 
277 	return 0;
278 }
279 
280 /**
281  * jpeg_v5_0_1_hw_fini - stop the hardware block
282  *
283  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
284  *
285  * Stop the JPEG block, mark ring as not ready any more
286  */
jpeg_v5_0_1_hw_fini(struct amdgpu_ip_block * ip_block)287 static int jpeg_v5_0_1_hw_fini(struct amdgpu_ip_block *ip_block)
288 {
289 	struct amdgpu_device *adev = ip_block->adev;
290 	int ret = 0;
291 
292 	cancel_delayed_work_sync(&adev->jpeg.idle_work);
293 
294 	if (adev->jpeg.cur_state != AMD_PG_STATE_GATE)
295 		ret = jpeg_v5_0_1_set_powergating_state(ip_block, AMD_PG_STATE_GATE);
296 
297 	return ret;
298 }
299 
300 /**
301  * jpeg_v5_0_1_suspend - suspend JPEG block
302  *
303  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
304  *
305  * HW fini and suspend JPEG block
306  */
jpeg_v5_0_1_suspend(struct amdgpu_ip_block * ip_block)307 static int jpeg_v5_0_1_suspend(struct amdgpu_ip_block *ip_block)
308 {
309 	struct amdgpu_device *adev = ip_block->adev;
310 	int r;
311 
312 	r = jpeg_v5_0_1_hw_fini(ip_block);
313 	if (r)
314 		return r;
315 
316 	r = amdgpu_jpeg_suspend(adev);
317 
318 	return r;
319 }
320 
321 /**
322  * jpeg_v5_0_1_resume - resume JPEG block
323  *
324  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
325  *
326  * Resume firmware and hw init JPEG block
327  */
jpeg_v5_0_1_resume(struct amdgpu_ip_block * ip_block)328 static int jpeg_v5_0_1_resume(struct amdgpu_ip_block *ip_block)
329 {
330 	struct amdgpu_device *adev = ip_block->adev;
331 	int r;
332 
333 	r = amdgpu_jpeg_resume(adev);
334 	if (r)
335 		return r;
336 
337 	r = jpeg_v5_0_1_hw_init(ip_block);
338 
339 	return r;
340 }
341 
jpeg_v5_0_1_init_inst(struct amdgpu_device * adev,int i)342 static void jpeg_v5_0_1_init_inst(struct amdgpu_device *adev, int i)
343 {
344 	int jpeg_inst = GET_INST(JPEG, i);
345 
346 	/* disable anti hang mechanism */
347 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS), 0,
348 		 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
349 
350 	/* keep the JPEG in static PG mode */
351 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS), 0,
352 		 ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK);
353 
354 	/* MJPEG global tiling registers */
355 	WREG32_SOC15(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG,
356 		     adev->gfx.config.gb_addr_config);
357 
358 	/* enable JMI channel */
359 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL), 0,
360 		 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
361 }
362 
jpeg_v5_0_1_deinit_inst(struct amdgpu_device * adev,int i)363 static void jpeg_v5_0_1_deinit_inst(struct amdgpu_device *adev, int i)
364 {
365 	int jpeg_inst = GET_INST(JPEG, i);
366 	/* reset JMI */
367 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL),
368 		 UVD_JMI_CNTL__SOFT_RESET_MASK,
369 		 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
370 
371 	/* enable anti hang mechanism */
372 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS),
373 		 UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
374 		 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
375 }
376 
jpeg_v5_0_1_init_jrbc(struct amdgpu_ring * ring)377 static void jpeg_v5_0_1_init_jrbc(struct amdgpu_ring *ring)
378 {
379 	struct amdgpu_device *adev = ring->adev;
380 	u32 reg, data, mask;
381 	int jpeg_inst = GET_INST(JPEG, ring->me);
382 	int reg_offset = ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0;
383 
384 	/* enable System Interrupt for JRBC */
385 	reg = SOC15_REG_OFFSET(JPEG, jpeg_inst, regJPEG_SYS_INT_EN);
386 	if (ring->pipe < AMDGPU_MAX_JPEG_RINGS_4_0_3) {
387 		data = JPEG_SYS_INT_EN__DJRBC0_MASK << ring->pipe;
388 		mask = ~(JPEG_SYS_INT_EN__DJRBC0_MASK << ring->pipe);
389 		WREG32_P(reg, data, mask);
390 	} else {
391 		data = JPEG_SYS_INT_EN__DJRBC0_MASK << (ring->pipe+12);
392 		mask = ~(JPEG_SYS_INT_EN__DJRBC0_MASK << (ring->pipe+12));
393 		WREG32_P(reg, data, mask);
394 	}
395 
396 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
397 			    regUVD_LMI_JRBC_RB_VMID,
398 			    reg_offset, 0);
399 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
400 			    regUVD_JRBC_RB_CNTL,
401 			    reg_offset,
402 			    (0x00000001L | 0x00000002L));
403 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
404 			    regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
405 			    reg_offset, lower_32_bits(ring->gpu_addr));
406 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
407 			    regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
408 			    reg_offset, upper_32_bits(ring->gpu_addr));
409 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
410 			    regUVD_JRBC_RB_RPTR,
411 			    reg_offset, 0);
412 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
413 			    regUVD_JRBC_RB_WPTR,
414 			    reg_offset, 0);
415 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
416 			    regUVD_JRBC_RB_CNTL,
417 			    reg_offset, 0x00000002L);
418 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
419 			    regUVD_JRBC_RB_SIZE,
420 			    reg_offset, ring->ring_size / 4);
421 	ring->wptr = RREG32_SOC15_OFFSET(JPEG, jpeg_inst, regUVD_JRBC_RB_WPTR,
422 					 reg_offset);
423 }
424 
425 /**
426  * jpeg_v5_0_1_start - start JPEG block
427  *
428  * @adev: amdgpu_device pointer
429  *
430  * Setup and start the JPEG block
431  */
jpeg_v5_0_1_start(struct amdgpu_device * adev)432 static int jpeg_v5_0_1_start(struct amdgpu_device *adev)
433 {
434 	struct amdgpu_ring *ring;
435 	int i, j;
436 
437 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
438 		jpeg_v5_0_1_init_inst(adev, i);
439 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
440 			ring = &adev->jpeg.inst[i].ring_dec[j];
441 			jpeg_v5_0_1_init_jrbc(ring);
442 		}
443 	}
444 
445 	return 0;
446 }
447 
448 /**
449  * jpeg_v5_0_1_stop - stop JPEG block
450  *
451  * @adev: amdgpu_device pointer
452  *
453  * stop the JPEG block
454  */
jpeg_v5_0_1_stop(struct amdgpu_device * adev)455 static int jpeg_v5_0_1_stop(struct amdgpu_device *adev)
456 {
457 	int i;
458 
459 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i)
460 		jpeg_v5_0_1_deinit_inst(adev, i);
461 
462 	return 0;
463 }
464 
465 /**
466  * jpeg_v5_0_1_dec_ring_get_rptr - get read pointer
467  *
468  * @ring: amdgpu_ring pointer
469  *
470  * Returns the current hardware read pointer
471  */
jpeg_v5_0_1_dec_ring_get_rptr(struct amdgpu_ring * ring)472 static uint64_t jpeg_v5_0_1_dec_ring_get_rptr(struct amdgpu_ring *ring)
473 {
474 	struct amdgpu_device *adev = ring->adev;
475 
476 	return RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC_RB_RPTR,
477 				   ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0);
478 }
479 
480 /**
481  * jpeg_v5_0_1_dec_ring_get_wptr - get write pointer
482  *
483  * @ring: amdgpu_ring pointer
484  *
485  * Returns the current hardware write pointer
486  */
jpeg_v5_0_1_dec_ring_get_wptr(struct amdgpu_ring * ring)487 static uint64_t jpeg_v5_0_1_dec_ring_get_wptr(struct amdgpu_ring *ring)
488 {
489 	struct amdgpu_device *adev = ring->adev;
490 
491 	if (ring->use_doorbell)
492 		return adev->wb.wb[ring->wptr_offs];
493 
494 	return RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC_RB_WPTR,
495 				   ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0);
496 }
497 
498 /**
499  * jpeg_v5_0_1_dec_ring_set_wptr - set write pointer
500  *
501  * @ring: amdgpu_ring pointer
502  *
503  * Commits the write pointer to the hardware
504  */
jpeg_v5_0_1_dec_ring_set_wptr(struct amdgpu_ring * ring)505 static void jpeg_v5_0_1_dec_ring_set_wptr(struct amdgpu_ring *ring)
506 {
507 	struct amdgpu_device *adev = ring->adev;
508 
509 	if (ring->use_doorbell) {
510 		adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
511 		WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
512 	} else {
513 		WREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me),
514 				    regUVD_JRBC_RB_WPTR,
515 				    (ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0),
516 				    lower_32_bits(ring->wptr));
517 	}
518 }
519 
jpeg_v5_0_1_is_idle(struct amdgpu_ip_block * ip_block)520 static bool jpeg_v5_0_1_is_idle(struct amdgpu_ip_block *ip_block)
521 {
522 	struct amdgpu_device *adev = ip_block->adev;
523 	bool ret = false;
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_1_core_reg_offset(j) : 0);
529 
530 			ret &= ((RREG32_SOC15_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 
537 	return ret;
538 }
539 
jpeg_v5_0_1_wait_for_idle(struct amdgpu_ip_block * ip_block)540 static int jpeg_v5_0_1_wait_for_idle(struct amdgpu_ip_block *ip_block)
541 {
542 	struct amdgpu_device *adev = ip_block->adev;
543 	int ret = 0;
544 	int i, j;
545 
546 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
547 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
548 			int reg_offset = (j ? jpeg_v5_0_1_core_reg_offset(j) : 0);
549 
550 			ret &= SOC15_WAIT_ON_RREG_OFFSET(JPEG, GET_INST(JPEG, i),
551 							 regUVD_JRBC_STATUS, reg_offset,
552 							 UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
553 							 UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
554 		}
555 	}
556 	return ret;
557 }
558 
jpeg_v5_0_1_set_clockgating_state(struct amdgpu_ip_block * ip_block,enum amd_clockgating_state state)559 static int jpeg_v5_0_1_set_clockgating_state(struct amdgpu_ip_block *ip_block,
560 					     enum amd_clockgating_state state)
561 {
562 	struct amdgpu_device *adev = ip_block->adev;
563 	bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
564 
565 	int i;
566 
567 	if (!enable)
568 		return 0;
569 
570 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
571 		if (!jpeg_v5_0_1_is_idle(ip_block))
572 			return -EBUSY;
573 	}
574 
575 	return 0;
576 }
577 
jpeg_v5_0_1_set_powergating_state(struct amdgpu_ip_block * ip_block,enum amd_powergating_state state)578 static int jpeg_v5_0_1_set_powergating_state(struct amdgpu_ip_block *ip_block,
579 					     enum amd_powergating_state state)
580 {
581 	struct amdgpu_device *adev = ip_block->adev;
582 	int ret;
583 
584 	if (state == adev->jpeg.cur_state)
585 		return 0;
586 
587 	if (state == AMD_PG_STATE_GATE)
588 		ret = jpeg_v5_0_1_stop(adev);
589 	else
590 		ret = jpeg_v5_0_1_start(adev);
591 
592 	if (!ret)
593 		adev->jpeg.cur_state = state;
594 
595 	return ret;
596 }
597 
jpeg_v5_0_1_set_interrupt_state(struct amdgpu_device * adev,struct amdgpu_irq_src * source,unsigned int type,enum amdgpu_interrupt_state state)598 static int jpeg_v5_0_1_set_interrupt_state(struct amdgpu_device *adev,
599 					   struct amdgpu_irq_src *source,
600 					   unsigned int type,
601 					   enum amdgpu_interrupt_state state)
602 {
603 	return 0;
604 }
605 
jpeg_v5_0_1_process_interrupt(struct amdgpu_device * adev,struct amdgpu_irq_src * source,struct amdgpu_iv_entry * entry)606 static int jpeg_v5_0_1_process_interrupt(struct amdgpu_device *adev,
607 					 struct amdgpu_irq_src *source,
608 					 struct amdgpu_iv_entry *entry)
609 {
610 	u32 i, inst;
611 
612 	i = node_id_to_phys_map[entry->node_id];
613 	DRM_DEV_DEBUG(adev->dev, "IH: JPEG TRAP\n");
614 
615 	for (inst = 0; inst < adev->jpeg.num_jpeg_inst; ++inst)
616 		if (adev->jpeg.inst[inst].aid_id == i)
617 			break;
618 
619 	if (inst >= adev->jpeg.num_jpeg_inst) {
620 		dev_WARN_ONCE(adev->dev, 1,
621 			      "Interrupt received for unknown JPEG instance %d",
622 			      entry->node_id);
623 		return 0;
624 	}
625 
626 	switch (entry->src_id) {
627 	case VCN_5_0__SRCID__JPEG_DECODE:
628 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[0]);
629 		break;
630 	case VCN_5_0__SRCID__JPEG1_DECODE:
631 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[1]);
632 		break;
633 	case VCN_5_0__SRCID__JPEG2_DECODE:
634 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[2]);
635 		break;
636 	case VCN_5_0__SRCID__JPEG3_DECODE:
637 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[3]);
638 		break;
639 	case VCN_5_0__SRCID__JPEG4_DECODE:
640 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[4]);
641 		break;
642 	case VCN_5_0__SRCID__JPEG5_DECODE:
643 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[5]);
644 		break;
645 	case VCN_5_0__SRCID__JPEG6_DECODE:
646 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[6]);
647 		break;
648 	case VCN_5_0__SRCID__JPEG7_DECODE:
649 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[7]);
650 		break;
651 	case VCN_5_0__SRCID__JPEG8_DECODE:
652 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[8]);
653 		break;
654 	case VCN_5_0__SRCID__JPEG9_DECODE:
655 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[9]);
656 		break;
657 	default:
658 		DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n",
659 			      entry->src_id, entry->src_data[0]);
660 		break;
661 	}
662 
663 	return 0;
664 }
665 
jpeg_v5_0_1_core_stall_reset(struct amdgpu_ring * ring)666 static void jpeg_v5_0_1_core_stall_reset(struct amdgpu_ring *ring)
667 {
668 	struct amdgpu_device *adev = ring->adev;
669 	int jpeg_inst = GET_INST(JPEG, ring->me);
670 	int reg_offset = ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0;
671 
672 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
673 			    regUVD_JMI0_UVD_JMI_CLIENT_STALL,
674 			    reg_offset, 0x1F);
675 	SOC15_WAIT_ON_RREG_OFFSET(JPEG, jpeg_inst,
676 				  regUVD_JMI0_UVD_JMI_CLIENT_CLEAN_STATUS,
677 				  reg_offset, 0x1F, 0x1F);
678 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
679 			    regUVD_JMI0_JPEG_LMI_DROP,
680 			    reg_offset, 0x1F);
681 	WREG32_SOC15(JPEG, jpeg_inst, regJPEG_CORE_RST_CTRL, 1 << ring->pipe);
682 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
683 			    regUVD_JMI0_UVD_JMI_CLIENT_STALL,
684 			    reg_offset, 0x00);
685 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
686 			    regUVD_JMI0_JPEG_LMI_DROP,
687 			    reg_offset, 0x00);
688 	WREG32_SOC15(JPEG, jpeg_inst, regJPEG_CORE_RST_CTRL, 0x00);
689 }
690 
jpeg_v5_0_1_ring_reset(struct amdgpu_ring * ring,unsigned int vmid)691 static int jpeg_v5_0_1_ring_reset(struct amdgpu_ring *ring, unsigned int vmid)
692 {
693 	if (amdgpu_sriov_vf(ring->adev))
694 		return -EOPNOTSUPP;
695 
696 	jpeg_v5_0_1_core_stall_reset(ring);
697 	jpeg_v5_0_1_init_jrbc(ring);
698 	return amdgpu_ring_test_helper(ring);
699 }
700 
701 static const struct amd_ip_funcs jpeg_v5_0_1_ip_funcs = {
702 	.name = "jpeg_v5_0_1",
703 	.early_init = jpeg_v5_0_1_early_init,
704 	.late_init = NULL,
705 	.sw_init = jpeg_v5_0_1_sw_init,
706 	.sw_fini = jpeg_v5_0_1_sw_fini,
707 	.hw_init = jpeg_v5_0_1_hw_init,
708 	.hw_fini = jpeg_v5_0_1_hw_fini,
709 	.suspend = jpeg_v5_0_1_suspend,
710 	.resume = jpeg_v5_0_1_resume,
711 	.is_idle = jpeg_v5_0_1_is_idle,
712 	.wait_for_idle = jpeg_v5_0_1_wait_for_idle,
713 	.check_soft_reset = NULL,
714 	.pre_soft_reset = NULL,
715 	.soft_reset = NULL,
716 	.post_soft_reset = NULL,
717 	.set_clockgating_state = jpeg_v5_0_1_set_clockgating_state,
718 	.set_powergating_state = jpeg_v5_0_1_set_powergating_state,
719 	.dump_ip_state = amdgpu_jpeg_dump_ip_state,
720 	.print_ip_state = amdgpu_jpeg_print_ip_state,
721 };
722 
723 static const struct amdgpu_ring_funcs jpeg_v5_0_1_dec_ring_vm_funcs = {
724 	.type = AMDGPU_RING_TYPE_VCN_JPEG,
725 	.align_mask = 0xf,
726 	.get_rptr = jpeg_v5_0_1_dec_ring_get_rptr,
727 	.get_wptr = jpeg_v5_0_1_dec_ring_get_wptr,
728 	.set_wptr = jpeg_v5_0_1_dec_ring_set_wptr,
729 	.emit_frame_size =
730 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
731 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
732 		8 + /* jpeg_v5_0_1_dec_ring_emit_vm_flush */
733 		22 + 22 + /* jpeg_v5_0_1_dec_ring_emit_fence x2 vm fence */
734 		8 + 16,
735 	.emit_ib_size = 22, /* jpeg_v5_0_1_dec_ring_emit_ib */
736 	.emit_ib = jpeg_v4_0_3_dec_ring_emit_ib,
737 	.emit_fence = jpeg_v4_0_3_dec_ring_emit_fence,
738 	.emit_vm_flush = jpeg_v4_0_3_dec_ring_emit_vm_flush,
739 	.emit_hdp_flush = jpeg_v4_0_3_ring_emit_hdp_flush,
740 	.test_ring = amdgpu_jpeg_dec_ring_test_ring,
741 	.test_ib = amdgpu_jpeg_dec_ring_test_ib,
742 	.insert_nop = jpeg_v4_0_3_dec_ring_nop,
743 	.insert_start = jpeg_v4_0_3_dec_ring_insert_start,
744 	.insert_end = jpeg_v4_0_3_dec_ring_insert_end,
745 	.pad_ib = amdgpu_ring_generic_pad_ib,
746 	.begin_use = amdgpu_jpeg_ring_begin_use,
747 	.end_use = amdgpu_jpeg_ring_end_use,
748 	.emit_wreg = jpeg_v4_0_3_dec_ring_emit_wreg,
749 	.emit_reg_wait = jpeg_v4_0_3_dec_ring_emit_reg_wait,
750 	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
751 	.reset = jpeg_v5_0_1_ring_reset,
752 };
753 
jpeg_v5_0_1_set_dec_ring_funcs(struct amdgpu_device * adev)754 static void jpeg_v5_0_1_set_dec_ring_funcs(struct amdgpu_device *adev)
755 {
756 	int i, j, jpeg_inst;
757 
758 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
759 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
760 			adev->jpeg.inst[i].ring_dec[j].funcs = &jpeg_v5_0_1_dec_ring_vm_funcs;
761 			adev->jpeg.inst[i].ring_dec[j].me = i;
762 			adev->jpeg.inst[i].ring_dec[j].pipe = j;
763 		}
764 		jpeg_inst = GET_INST(JPEG, i);
765 		adev->jpeg.inst[i].aid_id =
766 			jpeg_inst / adev->jpeg.num_inst_per_aid;
767 	}
768 }
769 
770 static const struct amdgpu_irq_src_funcs jpeg_v5_0_1_irq_funcs = {
771 	.set = jpeg_v5_0_1_set_interrupt_state,
772 	.process = jpeg_v5_0_1_process_interrupt,
773 };
774 
jpeg_v5_0_1_set_irq_funcs(struct amdgpu_device * adev)775 static void jpeg_v5_0_1_set_irq_funcs(struct amdgpu_device *adev)
776 {
777 	int i;
778 
779 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i)
780 		adev->jpeg.inst->irq.num_types += adev->jpeg.num_jpeg_rings;
781 
782 	adev->jpeg.inst->irq.funcs = &jpeg_v5_0_1_irq_funcs;
783 }
784 
785 const struct amdgpu_ip_block_version jpeg_v5_0_1_ip_block = {
786 	.type = AMD_IP_BLOCK_TYPE_JPEG,
787 	.major = 5,
788 	.minor = 0,
789 	.rev = 1,
790 	.funcs = &jpeg_v5_0_1_ip_funcs,
791 };
792