xref: /linux/drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c (revision cfc4ca8986bb1f6182da6cd7bb57f228590b4643)
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 #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 int jpeg_v5_0_1_start_sriov(struct amdgpu_device *adev);
38 static void jpeg_v5_0_1_set_dec_ring_funcs(struct amdgpu_device *adev);
39 static void jpeg_v5_0_1_set_irq_funcs(struct amdgpu_device *adev);
40 static int jpeg_v5_0_1_set_powergating_state(struct amdgpu_ip_block *ip_block,
41 					     enum amd_powergating_state state);
42 static void jpeg_v5_0_1_dec_ring_set_wptr(struct amdgpu_ring *ring);
43 
44 static int amdgpu_ih_srcid_jpeg[] = {
45 	VCN_5_0__SRCID__JPEG_DECODE,
46 	VCN_5_0__SRCID__JPEG1_DECODE,
47 	VCN_5_0__SRCID__JPEG2_DECODE,
48 	VCN_5_0__SRCID__JPEG3_DECODE,
49 	VCN_5_0__SRCID__JPEG4_DECODE,
50 	VCN_5_0__SRCID__JPEG5_DECODE,
51 	VCN_5_0__SRCID__JPEG6_DECODE,
52 	VCN_5_0__SRCID__JPEG7_DECODE,
53 	VCN_5_0__SRCID__JPEG8_DECODE,
54 	VCN_5_0__SRCID__JPEG9_DECODE,
55 };
56 
57 static const struct amdgpu_hwip_reg_entry jpeg_reg_list_5_0_1[] = {
58 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_POWER_STATUS),
59 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_INT_STAT),
60 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_RPTR),
61 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_RB_WPTR),
62 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC0_UVD_JRBC_STATUS),
63 	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_ADDR_MODE),
64 	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG),
65 	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_Y_GFX10_TILING_SURFACE),
66 	SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_UV_GFX10_TILING_SURFACE),
67 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_PITCH),
68 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_UV_PITCH),
69 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_RB_RPTR),
70 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_RB_WPTR),
71 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC1_UVD_JRBC_STATUS),
72 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_RB_RPTR),
73 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_RB_WPTR),
74 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC2_UVD_JRBC_STATUS),
75 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_RB_RPTR),
76 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_RB_WPTR),
77 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC3_UVD_JRBC_STATUS),
78 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_RB_RPTR),
79 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_RB_WPTR),
80 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC4_UVD_JRBC_STATUS),
81 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_RB_RPTR),
82 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_RB_WPTR),
83 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC5_UVD_JRBC_STATUS),
84 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_RB_RPTR),
85 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_RB_WPTR),
86 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC6_UVD_JRBC_STATUS),
87 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_RB_RPTR),
88 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_RB_WPTR),
89 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC7_UVD_JRBC_STATUS),
90 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC8_UVD_JRBC_RB_RPTR),
91 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC8_UVD_JRBC_RB_WPTR),
92 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC8_UVD_JRBC_STATUS),
93 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC9_UVD_JRBC_RB_RPTR),
94 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC9_UVD_JRBC_RB_WPTR),
95 	SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC9_UVD_JRBC_STATUS),
96 };
97 
98 static int jpeg_v5_0_1_core_reg_offset(u32 pipe)
99 {
100 	if (pipe <= AMDGPU_MAX_JPEG_RINGS_4_0_3)
101 		return ((0x40 * pipe) - 0xc80);
102 	else
103 		return ((0x40 * pipe) - 0x440);
104 }
105 
106 /**
107  * jpeg_v5_0_1_early_init - set function pointers
108  *
109  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
110  *
111  * Set ring and irq function pointers
112  */
113 static int jpeg_v5_0_1_early_init(struct amdgpu_ip_block *ip_block)
114 {
115 	struct amdgpu_device *adev = ip_block->adev;
116 
117 	if (!adev->jpeg.num_jpeg_inst || adev->jpeg.num_jpeg_inst > AMDGPU_MAX_JPEG_INSTANCES)
118 		return -ENOENT;
119 
120 	adev->jpeg.num_jpeg_rings = AMDGPU_MAX_JPEG_RINGS;
121 	jpeg_v5_0_1_set_dec_ring_funcs(adev);
122 	jpeg_v5_0_1_set_irq_funcs(adev);
123 
124 	return 0;
125 }
126 
127 /**
128  * jpeg_v5_0_1_sw_init - sw init for JPEG block
129  *
130  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
131  *
132  * Load firmware and sw initialization
133  */
134 static int jpeg_v5_0_1_sw_init(struct amdgpu_ip_block *ip_block)
135 {
136 	struct amdgpu_device *adev = ip_block->adev;
137 	struct amdgpu_ring *ring;
138 	int i, j, r, jpeg_inst;
139 
140 	for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
141 		/* JPEG TRAP */
142 		r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
143 				      amdgpu_ih_srcid_jpeg[j], &adev->jpeg.inst->irq);
144 		if (r)
145 			return r;
146 	}
147 
148 	r = amdgpu_jpeg_sw_init(adev);
149 	if (r)
150 		return r;
151 
152 	r = amdgpu_jpeg_resume(adev);
153 	if (r)
154 		return r;
155 
156 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
157 		jpeg_inst = GET_INST(JPEG, i);
158 
159 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
160 			ring = &adev->jpeg.inst[i].ring_dec[j];
161 			ring->use_doorbell = true;
162 			ring->vm_hub = AMDGPU_MMHUB0(adev->jpeg.inst[i].aid_id);
163 			if (!amdgpu_sriov_vf(adev)) {
164 				ring->doorbell_index =
165 					(adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
166 					1 + j + 11 * jpeg_inst;
167 			} else {
168 				ring->doorbell_index =
169 					(adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
170 					2 + j + 32 * jpeg_inst;
171 			}
172 			sprintf(ring->name, "jpeg_dec_%d.%d", adev->jpeg.inst[i].aid_id, j);
173 			r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0,
174 					     AMDGPU_RING_PRIO_DEFAULT, NULL);
175 			if (r)
176 				return r;
177 
178 			adev->jpeg.internal.jpeg_pitch[j] =
179 				regUVD_JRBC0_UVD_JRBC_SCRATCH0_INTERNAL_OFFSET;
180 			adev->jpeg.inst[i].external.jpeg_pitch[j] =
181 				SOC15_REG_OFFSET1(JPEG, jpeg_inst, regUVD_JRBC_SCRATCH0,
182 						  (j ? jpeg_v5_0_1_core_reg_offset(j) : 0));
183 		}
184 	}
185 
186 	r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_5_0_1, ARRAY_SIZE(jpeg_reg_list_5_0_1));
187 	if (r)
188 		return r;
189 
190 	if (!amdgpu_sriov_vf(adev)) {
191 		adev->jpeg.supported_reset = AMDGPU_RESET_TYPE_PER_QUEUE;
192 		r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
193 		if (r)
194 			return r;
195 	}
196 
197 	return 0;
198 }
199 
200 /**
201  * jpeg_v5_0_1_sw_fini - sw fini for JPEG block
202  *
203  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
204  *
205  * JPEG suspend and free up sw allocation
206  */
207 static int jpeg_v5_0_1_sw_fini(struct amdgpu_ip_block *ip_block)
208 {
209 	struct amdgpu_device *adev = ip_block->adev;
210 	int r;
211 
212 	r = amdgpu_jpeg_suspend(adev);
213 	if (r)
214 		return r;
215 
216 	if (!amdgpu_sriov_vf(adev))
217 		amdgpu_jpeg_sysfs_reset_mask_fini(adev);
218 
219 	r = amdgpu_jpeg_sw_fini(adev);
220 
221 	return r;
222 }
223 
224 /**
225  * jpeg_v5_0_1_hw_init - start and test JPEG block
226  *
227  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
228  *
229  */
230 static int jpeg_v5_0_1_hw_init(struct amdgpu_ip_block *ip_block)
231 {
232 	struct amdgpu_device *adev = ip_block->adev;
233 	struct amdgpu_ring *ring;
234 	int i, j, r, jpeg_inst;
235 
236 	if (amdgpu_sriov_vf(adev)) {
237 		r = jpeg_v5_0_1_start_sriov(adev);
238 		if (r)
239 			return r;
240 
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,
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  */
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 (!amdgpu_sriov_vf(adev)) {
295 		if (adev->jpeg.cur_state != AMD_PG_STATE_GATE)
296 			ret = jpeg_v5_0_1_set_powergating_state(ip_block, AMD_PG_STATE_GATE);
297 	}
298 
299 	return ret;
300 }
301 
302 /**
303  * jpeg_v5_0_1_suspend - suspend JPEG block
304  *
305  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
306  *
307  * HW fini and suspend JPEG block
308  */
309 static int jpeg_v5_0_1_suspend(struct amdgpu_ip_block *ip_block)
310 {
311 	struct amdgpu_device *adev = ip_block->adev;
312 	int r;
313 
314 	r = jpeg_v5_0_1_hw_fini(ip_block);
315 	if (r)
316 		return r;
317 
318 	r = amdgpu_jpeg_suspend(adev);
319 
320 	return r;
321 }
322 
323 /**
324  * jpeg_v5_0_1_resume - resume JPEG block
325  *
326  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
327  *
328  * Resume firmware and hw init JPEG block
329  */
330 static int jpeg_v5_0_1_resume(struct amdgpu_ip_block *ip_block)
331 {
332 	struct amdgpu_device *adev = ip_block->adev;
333 	int r;
334 
335 	r = amdgpu_jpeg_resume(adev);
336 	if (r)
337 		return r;
338 
339 	r = jpeg_v5_0_1_hw_init(ip_block);
340 
341 	return r;
342 }
343 
344 static void jpeg_v5_0_1_init_inst(struct amdgpu_device *adev, int i)
345 {
346 	int jpeg_inst = GET_INST(JPEG, i);
347 
348 	/* disable anti hang mechanism */
349 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS), 0,
350 		 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
351 
352 	/* keep the JPEG in static PG mode */
353 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS), 0,
354 		 ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK);
355 
356 	/* MJPEG global tiling registers */
357 	WREG32_SOC15(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG,
358 		     adev->gfx.config.gb_addr_config);
359 
360 	/* enable JMI channel */
361 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL), 0,
362 		 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
363 }
364 
365 static void jpeg_v5_0_1_deinit_inst(struct amdgpu_device *adev, int i)
366 {
367 	int jpeg_inst = GET_INST(JPEG, i);
368 	/* reset JMI */
369 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL),
370 		 UVD_JMI_CNTL__SOFT_RESET_MASK,
371 		 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
372 
373 	/* enable anti hang mechanism */
374 	WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS),
375 		 UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
376 		 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
377 }
378 
379 static void jpeg_v5_0_1_init_jrbc(struct amdgpu_ring *ring)
380 {
381 	struct amdgpu_device *adev = ring->adev;
382 	u32 reg, data, mask;
383 	int jpeg_inst = GET_INST(JPEG, ring->me);
384 	int reg_offset = ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0;
385 
386 	/* enable System Interrupt for JRBC */
387 	reg = SOC15_REG_OFFSET(JPEG, jpeg_inst, regJPEG_SYS_INT_EN);
388 	if (ring->pipe < AMDGPU_MAX_JPEG_RINGS_4_0_3) {
389 		data = JPEG_SYS_INT_EN__DJRBC0_MASK << ring->pipe;
390 		mask = ~(JPEG_SYS_INT_EN__DJRBC0_MASK << ring->pipe);
391 		WREG32_P(reg, data, mask);
392 	} else {
393 		data = JPEG_SYS_INT_EN__DJRBC0_MASK << (ring->pipe+12);
394 		mask = ~(JPEG_SYS_INT_EN__DJRBC0_MASK << (ring->pipe+12));
395 		WREG32_P(reg, data, mask);
396 	}
397 
398 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
399 			    regUVD_LMI_JRBC_RB_VMID,
400 			    reg_offset, 0);
401 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
402 			    regUVD_JRBC_RB_CNTL,
403 			    reg_offset,
404 			    (0x00000001L | 0x00000002L));
405 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
406 			    regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
407 			    reg_offset, lower_32_bits(ring->gpu_addr));
408 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
409 			    regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
410 			    reg_offset, upper_32_bits(ring->gpu_addr));
411 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
412 			    regUVD_JRBC_RB_RPTR,
413 			    reg_offset, 0);
414 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
415 			    regUVD_JRBC_RB_WPTR,
416 			    reg_offset, 0);
417 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
418 			    regUVD_JRBC_RB_CNTL,
419 			    reg_offset, 0x00000002L);
420 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
421 			    regUVD_JRBC_RB_SIZE,
422 			    reg_offset, ring->ring_size / 4);
423 	ring->wptr = RREG32_SOC15_OFFSET(JPEG, jpeg_inst, regUVD_JRBC_RB_WPTR,
424 					 reg_offset);
425 }
426 
427 static int jpeg_v5_0_1_start_sriov(struct amdgpu_device *adev)
428 {
429 	struct amdgpu_ring *ring;
430 	uint64_t ctx_addr;
431 	uint32_t param, resp, expected;
432 	uint32_t tmp, timeout;
433 
434 	struct amdgpu_mm_table *table = &adev->virt.mm_table;
435 	uint32_t *table_loc;
436 	uint32_t table_size;
437 	uint32_t size, size_dw, item_offset;
438 	uint32_t init_status;
439 	int i, j, jpeg_inst;
440 
441 	struct mmsch_v5_0_cmd_direct_write
442 		direct_wt = { {0} };
443 	struct mmsch_v5_0_cmd_end end = { {0} };
444 	struct mmsch_v5_0_init_header header;
445 
446 	direct_wt.cmd_header.command_type =
447 		MMSCH_COMMAND__DIRECT_REG_WRITE;
448 	end.cmd_header.command_type =
449 		MMSCH_COMMAND__END;
450 
451 	for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) {
452 		jpeg_inst = GET_INST(JPEG, i);
453 
454 		memset(&header, 0, sizeof(struct mmsch_v5_0_init_header));
455 		header.version = MMSCH_VERSION;
456 		header.total_size = sizeof(struct mmsch_v5_0_init_header) >> 2;
457 
458 		table_loc = (uint32_t *)table->cpu_addr;
459 		table_loc += header.total_size;
460 
461 		item_offset = header.total_size;
462 
463 		for (j = 0; j < adev->jpeg.num_jpeg_rings; j++) {
464 			ring = &adev->jpeg.inst[i].ring_dec[j];
465 			table_size = 0;
466 
467 			tmp = SOC15_REG_OFFSET(JPEG, 0, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW);
468 			MMSCH_V5_0_INSERT_DIRECT_WT(tmp, lower_32_bits(ring->gpu_addr));
469 			tmp = SOC15_REG_OFFSET(JPEG, 0, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH);
470 			MMSCH_V5_0_INSERT_DIRECT_WT(tmp, upper_32_bits(ring->gpu_addr));
471 			tmp = SOC15_REG_OFFSET(JPEG, 0, regUVD_JRBC_RB_SIZE);
472 			MMSCH_V5_0_INSERT_DIRECT_WT(tmp, ring->ring_size / 4);
473 
474 			if (j < 5) {
475 				header.mjpegdec0[j].table_offset = item_offset;
476 				header.mjpegdec0[j].init_status = 0;
477 				header.mjpegdec0[j].table_size = table_size;
478 			} else {
479 				header.mjpegdec1[j - 5].table_offset = item_offset;
480 				header.mjpegdec1[j - 5].init_status = 0;
481 				header.mjpegdec1[j - 5].table_size = table_size;
482 			}
483 			header.total_size += table_size;
484 			item_offset += table_size;
485 		}
486 
487 		MMSCH_V5_0_INSERT_END();
488 
489 		/* send init table to MMSCH */
490 		size = sizeof(struct mmsch_v5_0_init_header);
491 		table_loc = (uint32_t *)table->cpu_addr;
492 		memcpy((void *)table_loc, &header, size);
493 
494 		ctx_addr = table->gpu_addr;
495 		WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_CTX_ADDR_LO, lower_32_bits(ctx_addr));
496 		WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_CTX_ADDR_HI, upper_32_bits(ctx_addr));
497 
498 		tmp = RREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_VMID);
499 		tmp &= ~MMSCH_VF_VMID__VF_CTX_VMID_MASK;
500 		tmp |= (0 << MMSCH_VF_VMID__VF_CTX_VMID__SHIFT);
501 		WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_VMID, tmp);
502 
503 		size = header.total_size;
504 		WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_CTX_SIZE, size);
505 
506 		WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_MAILBOX_RESP, 0);
507 
508 		param = 0x00000001;
509 		WREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_MAILBOX_HOST, param);
510 		tmp = 0;
511 		timeout = 1000;
512 		resp = 0;
513 		expected = MMSCH_VF_MAILBOX_RESP__OK;
514 		init_status =
515 			((struct mmsch_v5_0_init_header *)(table_loc))->mjpegdec0[i].init_status;
516 		while (resp != expected) {
517 			resp = RREG32_SOC15(VCN, jpeg_inst, regMMSCH_VF_MAILBOX_RESP);
518 
519 			if (resp != 0)
520 				break;
521 			udelay(10);
522 			tmp = tmp + 10;
523 			if (tmp >= timeout) {
524 				DRM_ERROR("failed to init MMSCH. TIME-OUT after %d usec"\
525 					" waiting for regMMSCH_VF_MAILBOX_RESP "\
526 					"(expected=0x%08x, readback=0x%08x)\n",
527 					tmp, expected, resp);
528 				return -EBUSY;
529 			}
530 		}
531 		if (resp != expected && resp != MMSCH_VF_MAILBOX_RESP__INCOMPLETE &&
532 				init_status != MMSCH_VF_ENGINE_STATUS__PASS)
533 			DRM_ERROR("MMSCH init status is incorrect! readback=0x%08x, header init status for jpeg: %x\n",
534 					resp, init_status);
535 
536 	}
537 	return 0;
538 }
539 
540 /**
541  * jpeg_v5_0_1_start - start JPEG block
542  *
543  * @adev: amdgpu_device pointer
544  *
545  * Setup and start the JPEG block
546  */
547 static int jpeg_v5_0_1_start(struct amdgpu_device *adev)
548 {
549 	struct amdgpu_ring *ring;
550 	int i, j;
551 
552 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
553 		jpeg_v5_0_1_init_inst(adev, i);
554 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
555 			ring = &adev->jpeg.inst[i].ring_dec[j];
556 			jpeg_v5_0_1_init_jrbc(ring);
557 		}
558 	}
559 
560 	return 0;
561 }
562 
563 /**
564  * jpeg_v5_0_1_stop - stop JPEG block
565  *
566  * @adev: amdgpu_device pointer
567  *
568  * stop the JPEG block
569  */
570 static int jpeg_v5_0_1_stop(struct amdgpu_device *adev)
571 {
572 	int i;
573 
574 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i)
575 		jpeg_v5_0_1_deinit_inst(adev, i);
576 
577 	return 0;
578 }
579 
580 /**
581  * jpeg_v5_0_1_dec_ring_get_rptr - get read pointer
582  *
583  * @ring: amdgpu_ring pointer
584  *
585  * Returns the current hardware read pointer
586  */
587 static uint64_t jpeg_v5_0_1_dec_ring_get_rptr(struct amdgpu_ring *ring)
588 {
589 	struct amdgpu_device *adev = ring->adev;
590 
591 	return RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC_RB_RPTR,
592 				   ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0);
593 }
594 
595 /**
596  * jpeg_v5_0_1_dec_ring_get_wptr - get write pointer
597  *
598  * @ring: amdgpu_ring pointer
599  *
600  * Returns the current hardware write pointer
601  */
602 static uint64_t jpeg_v5_0_1_dec_ring_get_wptr(struct amdgpu_ring *ring)
603 {
604 	struct amdgpu_device *adev = ring->adev;
605 
606 	if (ring->use_doorbell)
607 		return adev->wb.wb[ring->wptr_offs];
608 
609 	return RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC_RB_WPTR,
610 				   ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0);
611 }
612 
613 /**
614  * jpeg_v5_0_1_dec_ring_set_wptr - set write pointer
615  *
616  * @ring: amdgpu_ring pointer
617  *
618  * Commits the write pointer to the hardware
619  */
620 static void jpeg_v5_0_1_dec_ring_set_wptr(struct amdgpu_ring *ring)
621 {
622 	struct amdgpu_device *adev = ring->adev;
623 
624 	if (ring->use_doorbell) {
625 		adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
626 		WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
627 	} else {
628 		WREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me),
629 				    regUVD_JRBC_RB_WPTR,
630 				    (ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0),
631 				    lower_32_bits(ring->wptr));
632 	}
633 }
634 
635 static bool jpeg_v5_0_1_is_idle(struct amdgpu_ip_block *ip_block)
636 {
637 	struct amdgpu_device *adev = ip_block->adev;
638 	bool ret = false;
639 	int i, j;
640 
641 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
642 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
643 			int reg_offset = (j ? jpeg_v5_0_1_core_reg_offset(j) : 0);
644 
645 			ret &= ((RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, i),
646 				regUVD_JRBC_STATUS, reg_offset) &
647 				UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
648 				UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
649 		}
650 	}
651 
652 	return ret;
653 }
654 
655 static int jpeg_v5_0_1_wait_for_idle(struct amdgpu_ip_block *ip_block)
656 {
657 	struct amdgpu_device *adev = ip_block->adev;
658 	int ret = 0;
659 	int i, j;
660 
661 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
662 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
663 			int reg_offset = (j ? jpeg_v5_0_1_core_reg_offset(j) : 0);
664 
665 			ret &= SOC15_WAIT_ON_RREG_OFFSET(JPEG, GET_INST(JPEG, i),
666 							 regUVD_JRBC_STATUS, reg_offset,
667 							 UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
668 							 UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
669 		}
670 	}
671 	return ret;
672 }
673 
674 static int jpeg_v5_0_1_set_clockgating_state(struct amdgpu_ip_block *ip_block,
675 					     enum amd_clockgating_state state)
676 {
677 	struct amdgpu_device *adev = ip_block->adev;
678 	bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
679 
680 	int i;
681 
682 	if (!enable)
683 		return 0;
684 
685 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
686 		if (!jpeg_v5_0_1_is_idle(ip_block))
687 			return -EBUSY;
688 	}
689 
690 	return 0;
691 }
692 
693 static int jpeg_v5_0_1_set_powergating_state(struct amdgpu_ip_block *ip_block,
694 					     enum amd_powergating_state state)
695 {
696 	struct amdgpu_device *adev = ip_block->adev;
697 	int ret;
698 
699 	if (amdgpu_sriov_vf(adev)) {
700 		adev->jpeg.cur_state = AMD_PG_STATE_UNGATE;
701 		return 0;
702 	}
703 
704 	if (state == adev->jpeg.cur_state)
705 		return 0;
706 
707 	if (state == AMD_PG_STATE_GATE)
708 		ret = jpeg_v5_0_1_stop(adev);
709 	else
710 		ret = jpeg_v5_0_1_start(adev);
711 
712 	if (!ret)
713 		adev->jpeg.cur_state = state;
714 
715 	return ret;
716 }
717 
718 static int jpeg_v5_0_1_set_interrupt_state(struct amdgpu_device *adev,
719 					   struct amdgpu_irq_src *source,
720 					   unsigned int type,
721 					   enum amdgpu_interrupt_state state)
722 {
723 	return 0;
724 }
725 
726 static int jpeg_v5_0_1_process_interrupt(struct amdgpu_device *adev,
727 					 struct amdgpu_irq_src *source,
728 					 struct amdgpu_iv_entry *entry)
729 {
730 	u32 i, inst;
731 
732 	i = node_id_to_phys_map[entry->node_id];
733 	DRM_DEV_DEBUG(adev->dev, "IH: JPEG TRAP\n");
734 
735 	for (inst = 0; inst < adev->jpeg.num_jpeg_inst; ++inst)
736 		if (adev->jpeg.inst[inst].aid_id == i)
737 			break;
738 
739 	if (inst >= adev->jpeg.num_jpeg_inst) {
740 		dev_WARN_ONCE(adev->dev, 1,
741 			      "Interrupt received for unknown JPEG instance %d",
742 			      entry->node_id);
743 		return 0;
744 	}
745 
746 	switch (entry->src_id) {
747 	case VCN_5_0__SRCID__JPEG_DECODE:
748 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[0]);
749 		break;
750 	case VCN_5_0__SRCID__JPEG1_DECODE:
751 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[1]);
752 		break;
753 	case VCN_5_0__SRCID__JPEG2_DECODE:
754 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[2]);
755 		break;
756 	case VCN_5_0__SRCID__JPEG3_DECODE:
757 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[3]);
758 		break;
759 	case VCN_5_0__SRCID__JPEG4_DECODE:
760 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[4]);
761 		break;
762 	case VCN_5_0__SRCID__JPEG5_DECODE:
763 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[5]);
764 		break;
765 	case VCN_5_0__SRCID__JPEG6_DECODE:
766 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[6]);
767 		break;
768 	case VCN_5_0__SRCID__JPEG7_DECODE:
769 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[7]);
770 		break;
771 	case VCN_5_0__SRCID__JPEG8_DECODE:
772 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[8]);
773 		break;
774 	case VCN_5_0__SRCID__JPEG9_DECODE:
775 		amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[9]);
776 		break;
777 	default:
778 		DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n",
779 			      entry->src_id, entry->src_data[0]);
780 		break;
781 	}
782 
783 	return 0;
784 }
785 
786 static void jpeg_v5_0_1_core_stall_reset(struct amdgpu_ring *ring)
787 {
788 	struct amdgpu_device *adev = ring->adev;
789 	int jpeg_inst = GET_INST(JPEG, ring->me);
790 	int reg_offset = ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0;
791 
792 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
793 			    regUVD_JMI0_UVD_JMI_CLIENT_STALL,
794 			    reg_offset, 0x1F);
795 	SOC15_WAIT_ON_RREG_OFFSET(JPEG, jpeg_inst,
796 				  regUVD_JMI0_UVD_JMI_CLIENT_CLEAN_STATUS,
797 				  reg_offset, 0x1F, 0x1F);
798 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
799 			    regUVD_JMI0_JPEG_LMI_DROP,
800 			    reg_offset, 0x1F);
801 	WREG32_SOC15(JPEG, jpeg_inst, regJPEG_CORE_RST_CTRL, 1 << ring->pipe);
802 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
803 			    regUVD_JMI0_UVD_JMI_CLIENT_STALL,
804 			    reg_offset, 0x00);
805 	WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
806 			    regUVD_JMI0_JPEG_LMI_DROP,
807 			    reg_offset, 0x00);
808 	WREG32_SOC15(JPEG, jpeg_inst, regJPEG_CORE_RST_CTRL, 0x00);
809 }
810 
811 static int jpeg_v5_0_1_ring_reset(struct amdgpu_ring *ring, unsigned int vmid)
812 {
813 	if (amdgpu_sriov_vf(ring->adev))
814 		return -EOPNOTSUPP;
815 
816 	jpeg_v5_0_1_core_stall_reset(ring);
817 	jpeg_v5_0_1_init_jrbc(ring);
818 	return amdgpu_ring_test_helper(ring);
819 }
820 
821 static const struct amd_ip_funcs jpeg_v5_0_1_ip_funcs = {
822 	.name = "jpeg_v5_0_1",
823 	.early_init = jpeg_v5_0_1_early_init,
824 	.late_init = NULL,
825 	.sw_init = jpeg_v5_0_1_sw_init,
826 	.sw_fini = jpeg_v5_0_1_sw_fini,
827 	.hw_init = jpeg_v5_0_1_hw_init,
828 	.hw_fini = jpeg_v5_0_1_hw_fini,
829 	.suspend = jpeg_v5_0_1_suspend,
830 	.resume = jpeg_v5_0_1_resume,
831 	.is_idle = jpeg_v5_0_1_is_idle,
832 	.wait_for_idle = jpeg_v5_0_1_wait_for_idle,
833 	.check_soft_reset = NULL,
834 	.pre_soft_reset = NULL,
835 	.soft_reset = NULL,
836 	.post_soft_reset = NULL,
837 	.set_clockgating_state = jpeg_v5_0_1_set_clockgating_state,
838 	.set_powergating_state = jpeg_v5_0_1_set_powergating_state,
839 	.dump_ip_state = amdgpu_jpeg_dump_ip_state,
840 	.print_ip_state = amdgpu_jpeg_print_ip_state,
841 };
842 
843 static const struct amdgpu_ring_funcs jpeg_v5_0_1_dec_ring_vm_funcs = {
844 	.type = AMDGPU_RING_TYPE_VCN_JPEG,
845 	.align_mask = 0xf,
846 	.get_rptr = jpeg_v5_0_1_dec_ring_get_rptr,
847 	.get_wptr = jpeg_v5_0_1_dec_ring_get_wptr,
848 	.set_wptr = jpeg_v5_0_1_dec_ring_set_wptr,
849 	.emit_frame_size =
850 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
851 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
852 		8 + /* jpeg_v5_0_1_dec_ring_emit_vm_flush */
853 		22 + 22 + /* jpeg_v5_0_1_dec_ring_emit_fence x2 vm fence */
854 		8 + 16,
855 	.emit_ib_size = 22, /* jpeg_v5_0_1_dec_ring_emit_ib */
856 	.emit_ib = jpeg_v4_0_3_dec_ring_emit_ib,
857 	.emit_fence = jpeg_v4_0_3_dec_ring_emit_fence,
858 	.emit_vm_flush = jpeg_v4_0_3_dec_ring_emit_vm_flush,
859 	.emit_hdp_flush = jpeg_v4_0_3_ring_emit_hdp_flush,
860 	.test_ring = amdgpu_jpeg_dec_ring_test_ring,
861 	.test_ib = amdgpu_jpeg_dec_ring_test_ib,
862 	.insert_nop = jpeg_v4_0_3_dec_ring_nop,
863 	.insert_start = jpeg_v4_0_3_dec_ring_insert_start,
864 	.insert_end = jpeg_v4_0_3_dec_ring_insert_end,
865 	.pad_ib = amdgpu_ring_generic_pad_ib,
866 	.begin_use = amdgpu_jpeg_ring_begin_use,
867 	.end_use = amdgpu_jpeg_ring_end_use,
868 	.emit_wreg = jpeg_v4_0_3_dec_ring_emit_wreg,
869 	.emit_reg_wait = jpeg_v4_0_3_dec_ring_emit_reg_wait,
870 	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
871 	.reset = jpeg_v5_0_1_ring_reset,
872 };
873 
874 static void jpeg_v5_0_1_set_dec_ring_funcs(struct amdgpu_device *adev)
875 {
876 	int i, j, jpeg_inst;
877 
878 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
879 		for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
880 			adev->jpeg.inst[i].ring_dec[j].funcs = &jpeg_v5_0_1_dec_ring_vm_funcs;
881 			adev->jpeg.inst[i].ring_dec[j].me = i;
882 			adev->jpeg.inst[i].ring_dec[j].pipe = j;
883 		}
884 		jpeg_inst = GET_INST(JPEG, i);
885 		adev->jpeg.inst[i].aid_id =
886 			jpeg_inst / adev->jpeg.num_inst_per_aid;
887 	}
888 }
889 
890 static const struct amdgpu_irq_src_funcs jpeg_v5_0_1_irq_funcs = {
891 	.set = jpeg_v5_0_1_set_interrupt_state,
892 	.process = jpeg_v5_0_1_process_interrupt,
893 };
894 
895 static void jpeg_v5_0_1_set_irq_funcs(struct amdgpu_device *adev)
896 {
897 	int i;
898 
899 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i)
900 		adev->jpeg.inst->irq.num_types += adev->jpeg.num_jpeg_rings;
901 
902 	adev->jpeg.inst->irq.funcs = &jpeg_v5_0_1_irq_funcs;
903 }
904 
905 const struct amdgpu_ip_block_version jpeg_v5_0_1_ip_block = {
906 	.type = AMD_IP_BLOCK_TYPE_JPEG,
907 	.major = 5,
908 	.minor = 0,
909 	.rev = 1,
910 	.funcs = &jpeg_v5_0_1_ip_funcs,
911 };
912