xref: /openbsd/sys/dev/pci/drm/amd/amdgpu/jpeg_v2_5.c (revision f005ef32)
1c349dbc7Sjsg /*
2c349dbc7Sjsg  * Copyright 2019 Advanced Micro Devices, Inc.
3c349dbc7Sjsg  *
4c349dbc7Sjsg  * Permission is hereby granted, free of charge, to any person obtaining a
5c349dbc7Sjsg  * copy of this software and associated documentation files (the "Software"),
6c349dbc7Sjsg  * to deal in the Software without restriction, including without limitation
7c349dbc7Sjsg  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8c349dbc7Sjsg  * and/or sell copies of the Software, and to permit persons to whom the
9c349dbc7Sjsg  * Software is furnished to do so, subject to the following conditions:
10c349dbc7Sjsg  *
11c349dbc7Sjsg  * The above copyright notice and this permission notice shall be included in
12c349dbc7Sjsg  * all copies or substantial portions of the Software.
13c349dbc7Sjsg  *
14c349dbc7Sjsg  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15c349dbc7Sjsg  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16c349dbc7Sjsg  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17c349dbc7Sjsg  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18c349dbc7Sjsg  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19c349dbc7Sjsg  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20c349dbc7Sjsg  * OTHER DEALINGS IN THE SOFTWARE.
21c349dbc7Sjsg  *
22c349dbc7Sjsg  */
23c349dbc7Sjsg 
24c349dbc7Sjsg #include "amdgpu.h"
25c349dbc7Sjsg #include "amdgpu_jpeg.h"
26c349dbc7Sjsg #include "soc15.h"
27c349dbc7Sjsg #include "soc15d.h"
28c349dbc7Sjsg #include "jpeg_v2_0.h"
291bb76ff1Sjsg #include "jpeg_v2_5.h"
30c349dbc7Sjsg 
31c349dbc7Sjsg #include "vcn/vcn_2_5_offset.h"
32c349dbc7Sjsg #include "vcn/vcn_2_5_sh_mask.h"
33c349dbc7Sjsg #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
34c349dbc7Sjsg 
35c349dbc7Sjsg #define mmUVD_JPEG_PITCH_INTERNAL_OFFSET			0x401f
36c349dbc7Sjsg 
37c349dbc7Sjsg #define JPEG25_MAX_HW_INSTANCES_ARCTURUS			2
38c349dbc7Sjsg 
39c349dbc7Sjsg static void jpeg_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev);
40c349dbc7Sjsg static void jpeg_v2_5_set_irq_funcs(struct amdgpu_device *adev);
41c349dbc7Sjsg static int jpeg_v2_5_set_powergating_state(void *handle,
42c349dbc7Sjsg 				enum amd_powergating_state state);
431bb76ff1Sjsg static void jpeg_v2_5_set_ras_funcs(struct amdgpu_device *adev);
44c349dbc7Sjsg 
45c349dbc7Sjsg static int amdgpu_ih_clientid_jpeg[] = {
46c349dbc7Sjsg 	SOC15_IH_CLIENTID_VCN,
47c349dbc7Sjsg 	SOC15_IH_CLIENTID_VCN1
48c349dbc7Sjsg };
49c349dbc7Sjsg 
50c349dbc7Sjsg /**
51c349dbc7Sjsg  * jpeg_v2_5_early_init - set function pointers
52c349dbc7Sjsg  *
53c349dbc7Sjsg  * @handle: amdgpu_device pointer
54c349dbc7Sjsg  *
55c349dbc7Sjsg  * Set ring and irq function pointers
56c349dbc7Sjsg  */
jpeg_v2_5_early_init(void * handle)57c349dbc7Sjsg static int jpeg_v2_5_early_init(void *handle)
58c349dbc7Sjsg {
59c349dbc7Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
60c349dbc7Sjsg 	u32 harvest;
61c349dbc7Sjsg 	int i;
62c349dbc7Sjsg 
63*f005ef32Sjsg 	adev->jpeg.num_jpeg_rings = 1;
64c349dbc7Sjsg 	adev->jpeg.num_jpeg_inst = JPEG25_MAX_HW_INSTANCES_ARCTURUS;
65c349dbc7Sjsg 	for (i = 0; i < adev->jpeg.num_jpeg_inst; i++) {
66c349dbc7Sjsg 		harvest = RREG32_SOC15(JPEG, i, mmCC_UVD_HARVESTING);
67c349dbc7Sjsg 		if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK)
68c349dbc7Sjsg 			adev->jpeg.harvest_config |= 1 << i;
69c349dbc7Sjsg 	}
70c349dbc7Sjsg 	if (adev->jpeg.harvest_config == (AMDGPU_JPEG_HARVEST_JPEG0 |
71c349dbc7Sjsg 					 AMDGPU_JPEG_HARVEST_JPEG1))
72c349dbc7Sjsg 		return -ENOENT;
73c349dbc7Sjsg 
74c349dbc7Sjsg 	jpeg_v2_5_set_dec_ring_funcs(adev);
75c349dbc7Sjsg 	jpeg_v2_5_set_irq_funcs(adev);
761bb76ff1Sjsg 	jpeg_v2_5_set_ras_funcs(adev);
77c349dbc7Sjsg 
78c349dbc7Sjsg 	return 0;
79c349dbc7Sjsg }
80c349dbc7Sjsg 
81c349dbc7Sjsg /**
82c349dbc7Sjsg  * jpeg_v2_5_sw_init - sw init for JPEG block
83c349dbc7Sjsg  *
84c349dbc7Sjsg  * @handle: amdgpu_device pointer
85c349dbc7Sjsg  *
86c349dbc7Sjsg  * Load firmware and sw initialization
87c349dbc7Sjsg  */
jpeg_v2_5_sw_init(void * handle)88c349dbc7Sjsg static int jpeg_v2_5_sw_init(void *handle)
89c349dbc7Sjsg {
90c349dbc7Sjsg 	struct amdgpu_ring *ring;
91c349dbc7Sjsg 	int i, r;
92c349dbc7Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
93c349dbc7Sjsg 
94c349dbc7Sjsg 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
95c349dbc7Sjsg 		if (adev->jpeg.harvest_config & (1 << i))
96c349dbc7Sjsg 			continue;
97c349dbc7Sjsg 
98c349dbc7Sjsg 		/* JPEG TRAP */
99c349dbc7Sjsg 		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
100c349dbc7Sjsg 				VCN_2_0__SRCID__JPEG_DECODE, &adev->jpeg.inst[i].irq);
101c349dbc7Sjsg 		if (r)
102c349dbc7Sjsg 			return r;
1031bb76ff1Sjsg 
1041bb76ff1Sjsg 		/* JPEG DJPEG POISON EVENT */
1051bb76ff1Sjsg 		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
106*f005ef32Sjsg 			VCN_2_6__SRCID_DJPEG0_POISON, &adev->jpeg.inst[i].ras_poison_irq);
1071bb76ff1Sjsg 		if (r)
1081bb76ff1Sjsg 			return r;
1091bb76ff1Sjsg 
1101bb76ff1Sjsg 		/* JPEG EJPEG POISON EVENT */
1111bb76ff1Sjsg 		r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
112*f005ef32Sjsg 			VCN_2_6__SRCID_EJPEG0_POISON, &adev->jpeg.inst[i].ras_poison_irq);
1131bb76ff1Sjsg 		if (r)
1141bb76ff1Sjsg 			return r;
115c349dbc7Sjsg 	}
116c349dbc7Sjsg 
117c349dbc7Sjsg 	r = amdgpu_jpeg_sw_init(adev);
118c349dbc7Sjsg 	if (r)
119c349dbc7Sjsg 		return r;
120c349dbc7Sjsg 
121c349dbc7Sjsg 	r = amdgpu_jpeg_resume(adev);
122c349dbc7Sjsg 	if (r)
123c349dbc7Sjsg 		return r;
124c349dbc7Sjsg 
125c349dbc7Sjsg 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
126c349dbc7Sjsg 		if (adev->jpeg.harvest_config & (1 << i))
127c349dbc7Sjsg 			continue;
128c349dbc7Sjsg 
129*f005ef32Sjsg 		ring = adev->jpeg.inst[i].ring_dec;
130c349dbc7Sjsg 		ring->use_doorbell = true;
131*f005ef32Sjsg 		if (adev->ip_versions[UVD_HWIP][0] == IP_VERSION(2, 5, 0))
132*f005ef32Sjsg 			ring->vm_hub = AMDGPU_MMHUB1(0);
133*f005ef32Sjsg 		else
134*f005ef32Sjsg 			ring->vm_hub = AMDGPU_MMHUB0(0);
135c349dbc7Sjsg 		ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + 8 * i;
136c349dbc7Sjsg 		snprintf(ring->name, sizeof(ring->name), "jpeg_dec_%d", i);
137ad8b1aafSjsg 		r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst[i].irq,
1385ca02815Sjsg 				     0, AMDGPU_RING_PRIO_DEFAULT, NULL);
139c349dbc7Sjsg 		if (r)
140c349dbc7Sjsg 			return r;
141c349dbc7Sjsg 
142*f005ef32Sjsg 		adev->jpeg.internal.jpeg_pitch[0] = mmUVD_JPEG_PITCH_INTERNAL_OFFSET;
143*f005ef32Sjsg 		adev->jpeg.inst[i].external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_PITCH);
144c349dbc7Sjsg 	}
145c349dbc7Sjsg 
146*f005ef32Sjsg 	r = amdgpu_jpeg_ras_sw_init(adev);
147*f005ef32Sjsg 	if (r)
148*f005ef32Sjsg 		return r;
149*f005ef32Sjsg 
150c349dbc7Sjsg 	return 0;
151c349dbc7Sjsg }
152c349dbc7Sjsg 
153c349dbc7Sjsg /**
154c349dbc7Sjsg  * jpeg_v2_5_sw_fini - sw fini for JPEG block
155c349dbc7Sjsg  *
156c349dbc7Sjsg  * @handle: amdgpu_device pointer
157c349dbc7Sjsg  *
158c349dbc7Sjsg  * JPEG suspend and free up sw allocation
159c349dbc7Sjsg  */
jpeg_v2_5_sw_fini(void * handle)160c349dbc7Sjsg static int jpeg_v2_5_sw_fini(void *handle)
161c349dbc7Sjsg {
162c349dbc7Sjsg 	int r;
163c349dbc7Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
164c349dbc7Sjsg 
165c349dbc7Sjsg 	r = amdgpu_jpeg_suspend(adev);
166c349dbc7Sjsg 	if (r)
167c349dbc7Sjsg 		return r;
168c349dbc7Sjsg 
169c349dbc7Sjsg 	r = amdgpu_jpeg_sw_fini(adev);
170c349dbc7Sjsg 
171c349dbc7Sjsg 	return r;
172c349dbc7Sjsg }
173c349dbc7Sjsg 
174c349dbc7Sjsg /**
175c349dbc7Sjsg  * jpeg_v2_5_hw_init - start and test JPEG block
176c349dbc7Sjsg  *
177c349dbc7Sjsg  * @handle: amdgpu_device pointer
178c349dbc7Sjsg  *
179c349dbc7Sjsg  */
jpeg_v2_5_hw_init(void * handle)180c349dbc7Sjsg static int jpeg_v2_5_hw_init(void *handle)
181c349dbc7Sjsg {
182c349dbc7Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
183c349dbc7Sjsg 	struct amdgpu_ring *ring;
184c349dbc7Sjsg 	int i, r;
185c349dbc7Sjsg 
186c349dbc7Sjsg 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
187c349dbc7Sjsg 		if (adev->jpeg.harvest_config & (1 << i))
188c349dbc7Sjsg 			continue;
189c349dbc7Sjsg 
190*f005ef32Sjsg 		ring = adev->jpeg.inst[i].ring_dec;
191c349dbc7Sjsg 		adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
192c349dbc7Sjsg 			(adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i, i);
193c349dbc7Sjsg 
194c349dbc7Sjsg 		r = amdgpu_ring_test_helper(ring);
195c349dbc7Sjsg 		if (r)
196c349dbc7Sjsg 			return r;
197c349dbc7Sjsg 	}
198c349dbc7Sjsg 
199c349dbc7Sjsg 	DRM_INFO("JPEG decode initialized successfully.\n");
200c349dbc7Sjsg 
201c349dbc7Sjsg 	return 0;
202c349dbc7Sjsg }
203c349dbc7Sjsg 
204c349dbc7Sjsg /**
205c349dbc7Sjsg  * jpeg_v2_5_hw_fini - stop the hardware block
206c349dbc7Sjsg  *
207c349dbc7Sjsg  * @handle: amdgpu_device pointer
208c349dbc7Sjsg  *
209c349dbc7Sjsg  * Stop the JPEG block, mark ring as not ready any more
210c349dbc7Sjsg  */
jpeg_v2_5_hw_fini(void * handle)211c349dbc7Sjsg static int jpeg_v2_5_hw_fini(void *handle)
212c349dbc7Sjsg {
213c349dbc7Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
214c349dbc7Sjsg 	int i;
215c349dbc7Sjsg 
216ad8b1aafSjsg 	cancel_delayed_work_sync(&adev->vcn.idle_work);
217ad8b1aafSjsg 
218c349dbc7Sjsg 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
219c349dbc7Sjsg 		if (adev->jpeg.harvest_config & (1 << i))
220c349dbc7Sjsg 			continue;
221c349dbc7Sjsg 
222c349dbc7Sjsg 		if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
223c349dbc7Sjsg 		      RREG32_SOC15(JPEG, i, mmUVD_JRBC_STATUS))
224c349dbc7Sjsg 			jpeg_v2_5_set_powergating_state(adev, AMD_PG_STATE_GATE);
225*f005ef32Sjsg 
226*f005ef32Sjsg 		if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__JPEG))
227*f005ef32Sjsg 			amdgpu_irq_put(adev, &adev->jpeg.inst[i].ras_poison_irq, 0);
228c349dbc7Sjsg 	}
229c349dbc7Sjsg 
230c349dbc7Sjsg 	return 0;
231c349dbc7Sjsg }
232c349dbc7Sjsg 
233c349dbc7Sjsg /**
234c349dbc7Sjsg  * jpeg_v2_5_suspend - suspend JPEG block
235c349dbc7Sjsg  *
236c349dbc7Sjsg  * @handle: amdgpu_device pointer
237c349dbc7Sjsg  *
238c349dbc7Sjsg  * HW fini and suspend JPEG block
239c349dbc7Sjsg  */
jpeg_v2_5_suspend(void * handle)240c349dbc7Sjsg static int jpeg_v2_5_suspend(void *handle)
241c349dbc7Sjsg {
242c349dbc7Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
243c349dbc7Sjsg 	int r;
244c349dbc7Sjsg 
245c349dbc7Sjsg 	r = jpeg_v2_5_hw_fini(adev);
246c349dbc7Sjsg 	if (r)
247c349dbc7Sjsg 		return r;
248c349dbc7Sjsg 
249c349dbc7Sjsg 	r = amdgpu_jpeg_suspend(adev);
250c349dbc7Sjsg 
251c349dbc7Sjsg 	return r;
252c349dbc7Sjsg }
253c349dbc7Sjsg 
254c349dbc7Sjsg /**
255c349dbc7Sjsg  * jpeg_v2_5_resume - resume JPEG block
256c349dbc7Sjsg  *
257c349dbc7Sjsg  * @handle: amdgpu_device pointer
258c349dbc7Sjsg  *
259c349dbc7Sjsg  * Resume firmware and hw init JPEG block
260c349dbc7Sjsg  */
jpeg_v2_5_resume(void * handle)261c349dbc7Sjsg static int jpeg_v2_5_resume(void *handle)
262c349dbc7Sjsg {
263c349dbc7Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
264c349dbc7Sjsg 	int r;
265c349dbc7Sjsg 
266c349dbc7Sjsg 	r = amdgpu_jpeg_resume(adev);
267c349dbc7Sjsg 	if (r)
268c349dbc7Sjsg 		return r;
269c349dbc7Sjsg 
270c349dbc7Sjsg 	r = jpeg_v2_5_hw_init(adev);
271c349dbc7Sjsg 
272c349dbc7Sjsg 	return r;
273c349dbc7Sjsg }
274c349dbc7Sjsg 
jpeg_v2_5_disable_clock_gating(struct amdgpu_device * adev,int inst)275c349dbc7Sjsg static void jpeg_v2_5_disable_clock_gating(struct amdgpu_device *adev, int inst)
276c349dbc7Sjsg {
277c349dbc7Sjsg 	uint32_t data;
278c349dbc7Sjsg 
279c349dbc7Sjsg 	data = RREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL);
280c349dbc7Sjsg 	if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG)
281c349dbc7Sjsg 		data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
282c349dbc7Sjsg 	else
283c349dbc7Sjsg 		data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
284c349dbc7Sjsg 
285c349dbc7Sjsg 	data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
286c349dbc7Sjsg 	data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
287c349dbc7Sjsg 	WREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL, data);
288c349dbc7Sjsg 
289c349dbc7Sjsg 	data = RREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE);
290c349dbc7Sjsg 	data &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK
291c349dbc7Sjsg 		| JPEG_CGC_GATE__JPEG2_DEC_MASK
292c349dbc7Sjsg 		| JPEG_CGC_GATE__JMCIF_MASK
293c349dbc7Sjsg 		| JPEG_CGC_GATE__JRBBM_MASK);
294c349dbc7Sjsg 	WREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE, data);
295c349dbc7Sjsg 
296c349dbc7Sjsg 	data = RREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL);
297c349dbc7Sjsg 	data &= ~(JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK
298c349dbc7Sjsg 		| JPEG_CGC_CTRL__JPEG2_DEC_MODE_MASK
299c349dbc7Sjsg 		| JPEG_CGC_CTRL__JMCIF_MODE_MASK
300c349dbc7Sjsg 		| JPEG_CGC_CTRL__JRBBM_MODE_MASK);
301c349dbc7Sjsg 	WREG32_SOC15(JPEG, inst, mmJPEG_CGC_CTRL, data);
302c349dbc7Sjsg }
303c349dbc7Sjsg 
jpeg_v2_5_enable_clock_gating(struct amdgpu_device * adev,int inst)304c349dbc7Sjsg static void jpeg_v2_5_enable_clock_gating(struct amdgpu_device *adev, int inst)
305c349dbc7Sjsg {
306c349dbc7Sjsg 	uint32_t data;
307c349dbc7Sjsg 
308c349dbc7Sjsg 	data = RREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE);
309c349dbc7Sjsg 	data |= (JPEG_CGC_GATE__JPEG_DEC_MASK
310c349dbc7Sjsg 		|JPEG_CGC_GATE__JPEG2_DEC_MASK
311c349dbc7Sjsg 		|JPEG_CGC_GATE__JPEG_ENC_MASK
312c349dbc7Sjsg 		|JPEG_CGC_GATE__JMCIF_MASK
313c349dbc7Sjsg 		|JPEG_CGC_GATE__JRBBM_MASK);
314c349dbc7Sjsg 	WREG32_SOC15(JPEG, inst, mmJPEG_CGC_GATE, data);
315c349dbc7Sjsg }
316c349dbc7Sjsg 
317c349dbc7Sjsg /**
318c349dbc7Sjsg  * jpeg_v2_5_start - start JPEG block
319c349dbc7Sjsg  *
320c349dbc7Sjsg  * @adev: amdgpu_device pointer
321c349dbc7Sjsg  *
322c349dbc7Sjsg  * Setup and start the JPEG block
323c349dbc7Sjsg  */
jpeg_v2_5_start(struct amdgpu_device * adev)324c349dbc7Sjsg static int jpeg_v2_5_start(struct amdgpu_device *adev)
325c349dbc7Sjsg {
326c349dbc7Sjsg 	struct amdgpu_ring *ring;
327c349dbc7Sjsg 	int i;
328c349dbc7Sjsg 
329c349dbc7Sjsg 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
330c349dbc7Sjsg 		if (adev->jpeg.harvest_config & (1 << i))
331c349dbc7Sjsg 			continue;
332c349dbc7Sjsg 
333*f005ef32Sjsg 		ring = adev->jpeg.inst[i].ring_dec;
334c349dbc7Sjsg 		/* disable anti hang mechanism */
335c349dbc7Sjsg 		WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_POWER_STATUS), 0,
336c349dbc7Sjsg 			~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
337c349dbc7Sjsg 
338c349dbc7Sjsg 		/* JPEG disable CGC */
339c349dbc7Sjsg 		jpeg_v2_5_disable_clock_gating(adev, i);
340c349dbc7Sjsg 
341c349dbc7Sjsg 		/* MJPEG global tiling registers */
342c349dbc7Sjsg 		WREG32_SOC15(JPEG, i, mmJPEG_DEC_GFX8_ADDR_CONFIG,
343c349dbc7Sjsg 			adev->gfx.config.gb_addr_config);
344c349dbc7Sjsg 		WREG32_SOC15(JPEG, i, mmJPEG_DEC_GFX10_ADDR_CONFIG,
345c349dbc7Sjsg 			adev->gfx.config.gb_addr_config);
346c349dbc7Sjsg 
347c349dbc7Sjsg 		/* enable JMI channel */
348c349dbc7Sjsg 		WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JMI_CNTL), 0,
349c349dbc7Sjsg 			~UVD_JMI_CNTL__SOFT_RESET_MASK);
350c349dbc7Sjsg 
351c349dbc7Sjsg 		/* enable System Interrupt for JRBC */
352c349dbc7Sjsg 		WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmJPEG_SYS_INT_EN),
353c349dbc7Sjsg 			JPEG_SYS_INT_EN__DJRBC_MASK,
354c349dbc7Sjsg 			~JPEG_SYS_INT_EN__DJRBC_MASK);
355c349dbc7Sjsg 
356c349dbc7Sjsg 		WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_VMID, 0);
357c349dbc7Sjsg 		WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
358c349dbc7Sjsg 		WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
359c349dbc7Sjsg 			lower_32_bits(ring->gpu_addr));
360c349dbc7Sjsg 		WREG32_SOC15(JPEG, i, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
361c349dbc7Sjsg 			upper_32_bits(ring->gpu_addr));
362c349dbc7Sjsg 		WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_RPTR, 0);
363c349dbc7Sjsg 		WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_WPTR, 0);
364c349dbc7Sjsg 		WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_CNTL, 0x00000002L);
365c349dbc7Sjsg 		WREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_SIZE, ring->ring_size / 4);
366c349dbc7Sjsg 		ring->wptr = RREG32_SOC15(JPEG, i, mmUVD_JRBC_RB_WPTR);
367c349dbc7Sjsg 	}
368c349dbc7Sjsg 
369c349dbc7Sjsg 	return 0;
370c349dbc7Sjsg }
371c349dbc7Sjsg 
372c349dbc7Sjsg /**
373c349dbc7Sjsg  * jpeg_v2_5_stop - stop JPEG block
374c349dbc7Sjsg  *
375c349dbc7Sjsg  * @adev: amdgpu_device pointer
376c349dbc7Sjsg  *
377c349dbc7Sjsg  * stop the JPEG block
378c349dbc7Sjsg  */
jpeg_v2_5_stop(struct amdgpu_device * adev)379c349dbc7Sjsg static int jpeg_v2_5_stop(struct amdgpu_device *adev)
380c349dbc7Sjsg {
381c349dbc7Sjsg 	int i;
382c349dbc7Sjsg 
383c349dbc7Sjsg 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
384c349dbc7Sjsg 		if (adev->jpeg.harvest_config & (1 << i))
385c349dbc7Sjsg 			continue;
386c349dbc7Sjsg 
387c349dbc7Sjsg 		/* reset JMI */
388c349dbc7Sjsg 		WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JMI_CNTL),
389c349dbc7Sjsg 			UVD_JMI_CNTL__SOFT_RESET_MASK,
390c349dbc7Sjsg 			~UVD_JMI_CNTL__SOFT_RESET_MASK);
391c349dbc7Sjsg 
392c349dbc7Sjsg 		jpeg_v2_5_enable_clock_gating(adev, i);
393c349dbc7Sjsg 
394c349dbc7Sjsg 		/* enable anti hang mechanism */
395c349dbc7Sjsg 		WREG32_P(SOC15_REG_OFFSET(JPEG, i, mmUVD_JPEG_POWER_STATUS),
396c349dbc7Sjsg 			UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
397c349dbc7Sjsg 			~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
398c349dbc7Sjsg 	}
399c349dbc7Sjsg 
400c349dbc7Sjsg 	return 0;
401c349dbc7Sjsg }
402c349dbc7Sjsg 
403c349dbc7Sjsg /**
404c349dbc7Sjsg  * jpeg_v2_5_dec_ring_get_rptr - get read pointer
405c349dbc7Sjsg  *
406c349dbc7Sjsg  * @ring: amdgpu_ring pointer
407c349dbc7Sjsg  *
408c349dbc7Sjsg  * Returns the current hardware read pointer
409c349dbc7Sjsg  */
jpeg_v2_5_dec_ring_get_rptr(struct amdgpu_ring * ring)410c349dbc7Sjsg static uint64_t jpeg_v2_5_dec_ring_get_rptr(struct amdgpu_ring *ring)
411c349dbc7Sjsg {
412c349dbc7Sjsg 	struct amdgpu_device *adev = ring->adev;
413c349dbc7Sjsg 
414c349dbc7Sjsg 	return RREG32_SOC15(JPEG, ring->me, mmUVD_JRBC_RB_RPTR);
415c349dbc7Sjsg }
416c349dbc7Sjsg 
417c349dbc7Sjsg /**
418c349dbc7Sjsg  * jpeg_v2_5_dec_ring_get_wptr - get write pointer
419c349dbc7Sjsg  *
420c349dbc7Sjsg  * @ring: amdgpu_ring pointer
421c349dbc7Sjsg  *
422c349dbc7Sjsg  * Returns the current hardware write pointer
423c349dbc7Sjsg  */
jpeg_v2_5_dec_ring_get_wptr(struct amdgpu_ring * ring)424c349dbc7Sjsg static uint64_t jpeg_v2_5_dec_ring_get_wptr(struct amdgpu_ring *ring)
425c349dbc7Sjsg {
426c349dbc7Sjsg 	struct amdgpu_device *adev = ring->adev;
427c349dbc7Sjsg 
428c349dbc7Sjsg 	if (ring->use_doorbell)
4291bb76ff1Sjsg 		return *ring->wptr_cpu_addr;
430c349dbc7Sjsg 	else
431c349dbc7Sjsg 		return RREG32_SOC15(JPEG, ring->me, mmUVD_JRBC_RB_WPTR);
432c349dbc7Sjsg }
433c349dbc7Sjsg 
434c349dbc7Sjsg /**
435c349dbc7Sjsg  * jpeg_v2_5_dec_ring_set_wptr - set write pointer
436c349dbc7Sjsg  *
437c349dbc7Sjsg  * @ring: amdgpu_ring pointer
438c349dbc7Sjsg  *
439c349dbc7Sjsg  * Commits the write pointer to the hardware
440c349dbc7Sjsg  */
jpeg_v2_5_dec_ring_set_wptr(struct amdgpu_ring * ring)441c349dbc7Sjsg static void jpeg_v2_5_dec_ring_set_wptr(struct amdgpu_ring *ring)
442c349dbc7Sjsg {
443c349dbc7Sjsg 	struct amdgpu_device *adev = ring->adev;
444c349dbc7Sjsg 
445c349dbc7Sjsg 	if (ring->use_doorbell) {
4461bb76ff1Sjsg 		*ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
447c349dbc7Sjsg 		WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
448c349dbc7Sjsg 	} else {
449c349dbc7Sjsg 		WREG32_SOC15(JPEG, ring->me, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
450c349dbc7Sjsg 	}
451c349dbc7Sjsg }
452c349dbc7Sjsg 
4531bb76ff1Sjsg /**
4541bb76ff1Sjsg  * jpeg_v2_6_dec_ring_insert_start - insert a start command
4551bb76ff1Sjsg  *
4561bb76ff1Sjsg  * @ring: amdgpu_ring pointer
4571bb76ff1Sjsg  *
4581bb76ff1Sjsg  * Write a start command to the ring.
4591bb76ff1Sjsg  */
jpeg_v2_6_dec_ring_insert_start(struct amdgpu_ring * ring)4601bb76ff1Sjsg static void jpeg_v2_6_dec_ring_insert_start(struct amdgpu_ring *ring)
4611bb76ff1Sjsg {
4621bb76ff1Sjsg 	amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
4631bb76ff1Sjsg 		0, 0, PACKETJ_TYPE0));
4641bb76ff1Sjsg 	amdgpu_ring_write(ring, 0x6aa04); /* PCTL0_MMHUB_DEEPSLEEP_IB */
4651bb76ff1Sjsg 
4661bb76ff1Sjsg 	amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
4671bb76ff1Sjsg 		0, 0, PACKETJ_TYPE0));
4681bb76ff1Sjsg 	amdgpu_ring_write(ring, 0x80000000 | (1 << (ring->me * 2 + 14)));
4691bb76ff1Sjsg }
4701bb76ff1Sjsg 
4711bb76ff1Sjsg /**
4721bb76ff1Sjsg  * jpeg_v2_6_dec_ring_insert_end - insert a end command
4731bb76ff1Sjsg  *
4741bb76ff1Sjsg  * @ring: amdgpu_ring pointer
4751bb76ff1Sjsg  *
4761bb76ff1Sjsg  * Write a end command to the ring.
4771bb76ff1Sjsg  */
jpeg_v2_6_dec_ring_insert_end(struct amdgpu_ring * ring)4781bb76ff1Sjsg static void jpeg_v2_6_dec_ring_insert_end(struct amdgpu_ring *ring)
4791bb76ff1Sjsg {
4801bb76ff1Sjsg 	amdgpu_ring_write(ring, PACKETJ(mmUVD_JRBC_EXTERNAL_REG_INTERNAL_OFFSET,
4811bb76ff1Sjsg 		0, 0, PACKETJ_TYPE0));
4821bb76ff1Sjsg 	amdgpu_ring_write(ring, 0x6aa04); /* PCTL0_MMHUB_DEEPSLEEP_IB */
4831bb76ff1Sjsg 
4841bb76ff1Sjsg 	amdgpu_ring_write(ring, PACKETJ(JRBC_DEC_EXTERNAL_REG_WRITE_ADDR,
4851bb76ff1Sjsg 		0, 0, PACKETJ_TYPE0));
4861bb76ff1Sjsg 	amdgpu_ring_write(ring, (1 << (ring->me * 2 + 14)));
4871bb76ff1Sjsg }
4881bb76ff1Sjsg 
jpeg_v2_5_is_idle(void * handle)489c349dbc7Sjsg static bool jpeg_v2_5_is_idle(void *handle)
490c349dbc7Sjsg {
491c349dbc7Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
492c349dbc7Sjsg 	int i, ret = 1;
493c349dbc7Sjsg 
494c349dbc7Sjsg 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
495c349dbc7Sjsg 		if (adev->jpeg.harvest_config & (1 << i))
496c349dbc7Sjsg 			continue;
497c349dbc7Sjsg 
498c349dbc7Sjsg 		ret &= (((RREG32_SOC15(JPEG, i, mmUVD_JRBC_STATUS) &
499c349dbc7Sjsg 			UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
500c349dbc7Sjsg 			UVD_JRBC_STATUS__RB_JOB_DONE_MASK));
501c349dbc7Sjsg 	}
502c349dbc7Sjsg 
503c349dbc7Sjsg 	return ret;
504c349dbc7Sjsg }
505c349dbc7Sjsg 
jpeg_v2_5_wait_for_idle(void * handle)506c349dbc7Sjsg static int jpeg_v2_5_wait_for_idle(void *handle)
507c349dbc7Sjsg {
508c349dbc7Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
509ad8b1aafSjsg 	int i, ret;
510c349dbc7Sjsg 
511c349dbc7Sjsg 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
512c349dbc7Sjsg 		if (adev->jpeg.harvest_config & (1 << i))
513c349dbc7Sjsg 			continue;
514c349dbc7Sjsg 
515ad8b1aafSjsg 		ret = SOC15_WAIT_ON_RREG(JPEG, i, mmUVD_JRBC_STATUS,
516c349dbc7Sjsg 			UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
517ad8b1aafSjsg 			UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
518c349dbc7Sjsg 		if (ret)
519c349dbc7Sjsg 			return ret;
520c349dbc7Sjsg 	}
521c349dbc7Sjsg 
52202cc048fSjsg 	return 0;
523c349dbc7Sjsg }
524c349dbc7Sjsg 
jpeg_v2_5_set_clockgating_state(void * handle,enum amd_clockgating_state state)525c349dbc7Sjsg static int jpeg_v2_5_set_clockgating_state(void *handle,
526c349dbc7Sjsg 					  enum amd_clockgating_state state)
527c349dbc7Sjsg {
528c349dbc7Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
529c349dbc7Sjsg 	bool enable = (state == AMD_CG_STATE_GATE);
530c349dbc7Sjsg 	int i;
531c349dbc7Sjsg 
532c349dbc7Sjsg 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
533c349dbc7Sjsg 		if (adev->jpeg.harvest_config & (1 << i))
534c349dbc7Sjsg 			continue;
535c349dbc7Sjsg 
536c349dbc7Sjsg 		if (enable) {
537c349dbc7Sjsg 			if (!jpeg_v2_5_is_idle(handle))
538c349dbc7Sjsg 				return -EBUSY;
539c349dbc7Sjsg 			jpeg_v2_5_enable_clock_gating(adev, i);
540c349dbc7Sjsg 		} else {
541c349dbc7Sjsg 			jpeg_v2_5_disable_clock_gating(adev, i);
542c349dbc7Sjsg 		}
543c349dbc7Sjsg 	}
544c349dbc7Sjsg 
545c349dbc7Sjsg 	return 0;
546c349dbc7Sjsg }
547c349dbc7Sjsg 
jpeg_v2_5_set_powergating_state(void * handle,enum amd_powergating_state state)548c349dbc7Sjsg static int jpeg_v2_5_set_powergating_state(void *handle,
549c349dbc7Sjsg 					  enum amd_powergating_state state)
550c349dbc7Sjsg {
551c349dbc7Sjsg 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
552c349dbc7Sjsg 	int ret;
553c349dbc7Sjsg 
554c349dbc7Sjsg 	if(state == adev->jpeg.cur_state)
555c349dbc7Sjsg 		return 0;
556c349dbc7Sjsg 
557c349dbc7Sjsg 	if (state == AMD_PG_STATE_GATE)
558c349dbc7Sjsg 		ret = jpeg_v2_5_stop(adev);
559c349dbc7Sjsg 	else
560c349dbc7Sjsg 		ret = jpeg_v2_5_start(adev);
561c349dbc7Sjsg 
562c349dbc7Sjsg 	if(!ret)
563c349dbc7Sjsg 		adev->jpeg.cur_state = state;
564c349dbc7Sjsg 
565c349dbc7Sjsg 	return ret;
566c349dbc7Sjsg }
567c349dbc7Sjsg 
jpeg_v2_5_set_interrupt_state(struct amdgpu_device * adev,struct amdgpu_irq_src * source,unsigned type,enum amdgpu_interrupt_state state)568c349dbc7Sjsg static int jpeg_v2_5_set_interrupt_state(struct amdgpu_device *adev,
569c349dbc7Sjsg 					struct amdgpu_irq_src *source,
570c349dbc7Sjsg 					unsigned type,
571c349dbc7Sjsg 					enum amdgpu_interrupt_state state)
572c349dbc7Sjsg {
573c349dbc7Sjsg 	return 0;
574c349dbc7Sjsg }
575c349dbc7Sjsg 
jpeg_v2_6_set_ras_interrupt_state(struct amdgpu_device * adev,struct amdgpu_irq_src * source,unsigned int type,enum amdgpu_interrupt_state state)576*f005ef32Sjsg static int jpeg_v2_6_set_ras_interrupt_state(struct amdgpu_device *adev,
577*f005ef32Sjsg 					struct amdgpu_irq_src *source,
578*f005ef32Sjsg 					unsigned int type,
579*f005ef32Sjsg 					enum amdgpu_interrupt_state state)
580*f005ef32Sjsg {
581*f005ef32Sjsg 	return 0;
582*f005ef32Sjsg }
583*f005ef32Sjsg 
jpeg_v2_5_process_interrupt(struct amdgpu_device * adev,struct amdgpu_irq_src * source,struct amdgpu_iv_entry * entry)584c349dbc7Sjsg static int jpeg_v2_5_process_interrupt(struct amdgpu_device *adev,
585c349dbc7Sjsg 				      struct amdgpu_irq_src *source,
586c349dbc7Sjsg 				      struct amdgpu_iv_entry *entry)
587c349dbc7Sjsg {
588c349dbc7Sjsg 	uint32_t ip_instance;
589c349dbc7Sjsg 
590c349dbc7Sjsg 	switch (entry->client_id) {
591c349dbc7Sjsg 	case SOC15_IH_CLIENTID_VCN:
592c349dbc7Sjsg 		ip_instance = 0;
593c349dbc7Sjsg 		break;
594c349dbc7Sjsg 	case SOC15_IH_CLIENTID_VCN1:
595c349dbc7Sjsg 		ip_instance = 1;
596c349dbc7Sjsg 		break;
597c349dbc7Sjsg 	default:
598c349dbc7Sjsg 		DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
599c349dbc7Sjsg 		return 0;
600c349dbc7Sjsg 	}
601c349dbc7Sjsg 
602c349dbc7Sjsg 	DRM_DEBUG("IH: JPEG TRAP\n");
603c349dbc7Sjsg 
604c349dbc7Sjsg 	switch (entry->src_id) {
605c349dbc7Sjsg 	case VCN_2_0__SRCID__JPEG_DECODE:
606*f005ef32Sjsg 		amdgpu_fence_process(adev->jpeg.inst[ip_instance].ring_dec);
6071bb76ff1Sjsg 		break;
608c349dbc7Sjsg 	default:
609c349dbc7Sjsg 		DRM_ERROR("Unhandled interrupt: %d %d\n",
610c349dbc7Sjsg 			  entry->src_id, entry->src_data[0]);
611c349dbc7Sjsg 		break;
612c349dbc7Sjsg 	}
613c349dbc7Sjsg 
614c349dbc7Sjsg 	return 0;
615c349dbc7Sjsg }
616c349dbc7Sjsg 
617c349dbc7Sjsg static const struct amd_ip_funcs jpeg_v2_5_ip_funcs = {
618c349dbc7Sjsg 	.name = "jpeg_v2_5",
619c349dbc7Sjsg 	.early_init = jpeg_v2_5_early_init,
620c349dbc7Sjsg 	.late_init = NULL,
621c349dbc7Sjsg 	.sw_init = jpeg_v2_5_sw_init,
622c349dbc7Sjsg 	.sw_fini = jpeg_v2_5_sw_fini,
623c349dbc7Sjsg 	.hw_init = jpeg_v2_5_hw_init,
624c349dbc7Sjsg 	.hw_fini = jpeg_v2_5_hw_fini,
625c349dbc7Sjsg 	.suspend = jpeg_v2_5_suspend,
626c349dbc7Sjsg 	.resume = jpeg_v2_5_resume,
627c349dbc7Sjsg 	.is_idle = jpeg_v2_5_is_idle,
628c349dbc7Sjsg 	.wait_for_idle = jpeg_v2_5_wait_for_idle,
629c349dbc7Sjsg 	.check_soft_reset = NULL,
630c349dbc7Sjsg 	.pre_soft_reset = NULL,
631c349dbc7Sjsg 	.soft_reset = NULL,
632c349dbc7Sjsg 	.post_soft_reset = NULL,
633c349dbc7Sjsg 	.set_clockgating_state = jpeg_v2_5_set_clockgating_state,
634c349dbc7Sjsg 	.set_powergating_state = jpeg_v2_5_set_powergating_state,
635c349dbc7Sjsg };
636c349dbc7Sjsg 
6375ca02815Sjsg static const struct amd_ip_funcs jpeg_v2_6_ip_funcs = {
6385ca02815Sjsg 	.name = "jpeg_v2_6",
6395ca02815Sjsg 	.early_init = jpeg_v2_5_early_init,
6405ca02815Sjsg 	.late_init = NULL,
6415ca02815Sjsg 	.sw_init = jpeg_v2_5_sw_init,
6425ca02815Sjsg 	.sw_fini = jpeg_v2_5_sw_fini,
6435ca02815Sjsg 	.hw_init = jpeg_v2_5_hw_init,
6445ca02815Sjsg 	.hw_fini = jpeg_v2_5_hw_fini,
6455ca02815Sjsg 	.suspend = jpeg_v2_5_suspend,
6465ca02815Sjsg 	.resume = jpeg_v2_5_resume,
6475ca02815Sjsg 	.is_idle = jpeg_v2_5_is_idle,
6485ca02815Sjsg 	.wait_for_idle = jpeg_v2_5_wait_for_idle,
6495ca02815Sjsg 	.check_soft_reset = NULL,
6505ca02815Sjsg 	.pre_soft_reset = NULL,
6515ca02815Sjsg 	.soft_reset = NULL,
6525ca02815Sjsg 	.post_soft_reset = NULL,
6535ca02815Sjsg 	.set_clockgating_state = jpeg_v2_5_set_clockgating_state,
6545ca02815Sjsg 	.set_powergating_state = jpeg_v2_5_set_powergating_state,
6555ca02815Sjsg };
6565ca02815Sjsg 
657c349dbc7Sjsg static const struct amdgpu_ring_funcs jpeg_v2_5_dec_ring_vm_funcs = {
658c349dbc7Sjsg 	.type = AMDGPU_RING_TYPE_VCN_JPEG,
659c349dbc7Sjsg 	.align_mask = 0xf,
660c349dbc7Sjsg 	.get_rptr = jpeg_v2_5_dec_ring_get_rptr,
661c349dbc7Sjsg 	.get_wptr = jpeg_v2_5_dec_ring_get_wptr,
662c349dbc7Sjsg 	.set_wptr = jpeg_v2_5_dec_ring_set_wptr,
663c349dbc7Sjsg 	.emit_frame_size =
664c349dbc7Sjsg 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
665c349dbc7Sjsg 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
666c349dbc7Sjsg 		8 + /* jpeg_v2_5_dec_ring_emit_vm_flush */
667c349dbc7Sjsg 		18 + 18 + /* jpeg_v2_5_dec_ring_emit_fence x2 vm fence */
668c349dbc7Sjsg 		8 + 16,
669c349dbc7Sjsg 	.emit_ib_size = 22, /* jpeg_v2_5_dec_ring_emit_ib */
670c349dbc7Sjsg 	.emit_ib = jpeg_v2_0_dec_ring_emit_ib,
671c349dbc7Sjsg 	.emit_fence = jpeg_v2_0_dec_ring_emit_fence,
672c349dbc7Sjsg 	.emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush,
673c349dbc7Sjsg 	.test_ring = amdgpu_jpeg_dec_ring_test_ring,
674c349dbc7Sjsg 	.test_ib = amdgpu_jpeg_dec_ring_test_ib,
675c349dbc7Sjsg 	.insert_nop = jpeg_v2_0_dec_ring_nop,
676c349dbc7Sjsg 	.insert_start = jpeg_v2_0_dec_ring_insert_start,
677c349dbc7Sjsg 	.insert_end = jpeg_v2_0_dec_ring_insert_end,
678c349dbc7Sjsg 	.pad_ib = amdgpu_ring_generic_pad_ib,
679c349dbc7Sjsg 	.begin_use = amdgpu_jpeg_ring_begin_use,
680c349dbc7Sjsg 	.end_use = amdgpu_jpeg_ring_end_use,
681c349dbc7Sjsg 	.emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
682c349dbc7Sjsg 	.emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
683c349dbc7Sjsg 	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
684c349dbc7Sjsg };
685c349dbc7Sjsg 
6865ca02815Sjsg static const struct amdgpu_ring_funcs jpeg_v2_6_dec_ring_vm_funcs = {
6875ca02815Sjsg 	.type = AMDGPU_RING_TYPE_VCN_JPEG,
6885ca02815Sjsg 	.align_mask = 0xf,
6895ca02815Sjsg 	.get_rptr = jpeg_v2_5_dec_ring_get_rptr,
6905ca02815Sjsg 	.get_wptr = jpeg_v2_5_dec_ring_get_wptr,
6915ca02815Sjsg 	.set_wptr = jpeg_v2_5_dec_ring_set_wptr,
6925ca02815Sjsg 	.emit_frame_size =
6935ca02815Sjsg 		SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
6945ca02815Sjsg 		SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
6955ca02815Sjsg 		8 + /* jpeg_v2_5_dec_ring_emit_vm_flush */
6965ca02815Sjsg 		18 + 18 + /* jpeg_v2_5_dec_ring_emit_fence x2 vm fence */
6975ca02815Sjsg 		8 + 16,
6985ca02815Sjsg 	.emit_ib_size = 22, /* jpeg_v2_5_dec_ring_emit_ib */
6995ca02815Sjsg 	.emit_ib = jpeg_v2_0_dec_ring_emit_ib,
7005ca02815Sjsg 	.emit_fence = jpeg_v2_0_dec_ring_emit_fence,
7015ca02815Sjsg 	.emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush,
7025ca02815Sjsg 	.test_ring = amdgpu_jpeg_dec_ring_test_ring,
7035ca02815Sjsg 	.test_ib = amdgpu_jpeg_dec_ring_test_ib,
7045ca02815Sjsg 	.insert_nop = jpeg_v2_0_dec_ring_nop,
7051bb76ff1Sjsg 	.insert_start = jpeg_v2_6_dec_ring_insert_start,
7061bb76ff1Sjsg 	.insert_end = jpeg_v2_6_dec_ring_insert_end,
7075ca02815Sjsg 	.pad_ib = amdgpu_ring_generic_pad_ib,
7085ca02815Sjsg 	.begin_use = amdgpu_jpeg_ring_begin_use,
7095ca02815Sjsg 	.end_use = amdgpu_jpeg_ring_end_use,
7105ca02815Sjsg 	.emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
7115ca02815Sjsg 	.emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
7125ca02815Sjsg 	.emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
7135ca02815Sjsg };
7145ca02815Sjsg 
jpeg_v2_5_set_dec_ring_funcs(struct amdgpu_device * adev)715c349dbc7Sjsg static void jpeg_v2_5_set_dec_ring_funcs(struct amdgpu_device *adev)
716c349dbc7Sjsg {
717c349dbc7Sjsg 	int i;
718c349dbc7Sjsg 
719c349dbc7Sjsg 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
720c349dbc7Sjsg 		if (adev->jpeg.harvest_config & (1 << i))
721c349dbc7Sjsg 			continue;
7225ca02815Sjsg 		if (adev->asic_type == CHIP_ARCTURUS)
723*f005ef32Sjsg 			adev->jpeg.inst[i].ring_dec->funcs = &jpeg_v2_5_dec_ring_vm_funcs;
7245ca02815Sjsg 		else  /* CHIP_ALDEBARAN */
725*f005ef32Sjsg 			adev->jpeg.inst[i].ring_dec->funcs = &jpeg_v2_6_dec_ring_vm_funcs;
726*f005ef32Sjsg 		adev->jpeg.inst[i].ring_dec->me = i;
727c349dbc7Sjsg 		DRM_INFO("JPEG(%d) JPEG decode is enabled in VM mode\n", i);
728c349dbc7Sjsg 	}
729c349dbc7Sjsg }
730c349dbc7Sjsg 
731c349dbc7Sjsg static const struct amdgpu_irq_src_funcs jpeg_v2_5_irq_funcs = {
732c349dbc7Sjsg 	.set = jpeg_v2_5_set_interrupt_state,
733c349dbc7Sjsg 	.process = jpeg_v2_5_process_interrupt,
734c349dbc7Sjsg };
735c349dbc7Sjsg 
736*f005ef32Sjsg static const struct amdgpu_irq_src_funcs jpeg_v2_6_ras_irq_funcs = {
737*f005ef32Sjsg 	.set = jpeg_v2_6_set_ras_interrupt_state,
738*f005ef32Sjsg 	.process = amdgpu_jpeg_process_poison_irq,
739*f005ef32Sjsg };
740*f005ef32Sjsg 
jpeg_v2_5_set_irq_funcs(struct amdgpu_device * adev)741c349dbc7Sjsg static void jpeg_v2_5_set_irq_funcs(struct amdgpu_device *adev)
742c349dbc7Sjsg {
743c349dbc7Sjsg 	int i;
744c349dbc7Sjsg 
745c349dbc7Sjsg 	for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
746c349dbc7Sjsg 		if (adev->jpeg.harvest_config & (1 << i))
747c349dbc7Sjsg 			continue;
748c349dbc7Sjsg 
749c349dbc7Sjsg 		adev->jpeg.inst[i].irq.num_types = 1;
750c349dbc7Sjsg 		adev->jpeg.inst[i].irq.funcs = &jpeg_v2_5_irq_funcs;
751*f005ef32Sjsg 
752*f005ef32Sjsg 		adev->jpeg.inst[i].ras_poison_irq.num_types = 1;
753*f005ef32Sjsg 		adev->jpeg.inst[i].ras_poison_irq.funcs = &jpeg_v2_6_ras_irq_funcs;
754c349dbc7Sjsg 	}
755c349dbc7Sjsg }
756c349dbc7Sjsg 
757c349dbc7Sjsg const struct amdgpu_ip_block_version jpeg_v2_5_ip_block =
758c349dbc7Sjsg {
759c349dbc7Sjsg 		.type = AMD_IP_BLOCK_TYPE_JPEG,
760c349dbc7Sjsg 		.major = 2,
761c349dbc7Sjsg 		.minor = 5,
762c349dbc7Sjsg 		.rev = 0,
763c349dbc7Sjsg 		.funcs = &jpeg_v2_5_ip_funcs,
764c349dbc7Sjsg };
7655ca02815Sjsg 
7665ca02815Sjsg const struct amdgpu_ip_block_version jpeg_v2_6_ip_block =
7675ca02815Sjsg {
7685ca02815Sjsg 		.type = AMD_IP_BLOCK_TYPE_JPEG,
7695ca02815Sjsg 		.major = 2,
7705ca02815Sjsg 		.minor = 6,
7715ca02815Sjsg 		.rev = 0,
7725ca02815Sjsg 		.funcs = &jpeg_v2_6_ip_funcs,
7735ca02815Sjsg };
7741bb76ff1Sjsg 
jpeg_v2_6_query_poison_by_instance(struct amdgpu_device * adev,uint32_t instance,uint32_t sub_block)7751bb76ff1Sjsg static uint32_t jpeg_v2_6_query_poison_by_instance(struct amdgpu_device *adev,
7761bb76ff1Sjsg 		uint32_t instance, uint32_t sub_block)
7771bb76ff1Sjsg {
7781bb76ff1Sjsg 	uint32_t poison_stat = 0, reg_value = 0;
7791bb76ff1Sjsg 
7801bb76ff1Sjsg 	switch (sub_block) {
7811bb76ff1Sjsg 	case AMDGPU_JPEG_V2_6_JPEG0:
7821bb76ff1Sjsg 		reg_value = RREG32_SOC15(JPEG, instance, mmUVD_RAS_JPEG0_STATUS);
7831bb76ff1Sjsg 		poison_stat = REG_GET_FIELD(reg_value, UVD_RAS_JPEG0_STATUS, POISONED_PF);
7841bb76ff1Sjsg 		break;
7851bb76ff1Sjsg 	case AMDGPU_JPEG_V2_6_JPEG1:
7861bb76ff1Sjsg 		reg_value = RREG32_SOC15(JPEG, instance, mmUVD_RAS_JPEG1_STATUS);
7871bb76ff1Sjsg 		poison_stat = REG_GET_FIELD(reg_value, UVD_RAS_JPEG1_STATUS, POISONED_PF);
7881bb76ff1Sjsg 		break;
7891bb76ff1Sjsg 	default:
7901bb76ff1Sjsg 		break;
7911bb76ff1Sjsg 	}
7921bb76ff1Sjsg 
7931bb76ff1Sjsg 	if (poison_stat)
7941bb76ff1Sjsg 		dev_info(adev->dev, "Poison detected in JPEG%d sub_block%d\n",
7951bb76ff1Sjsg 			instance, sub_block);
7961bb76ff1Sjsg 
7971bb76ff1Sjsg 	return poison_stat;
7981bb76ff1Sjsg }
7991bb76ff1Sjsg 
jpeg_v2_6_query_ras_poison_status(struct amdgpu_device * adev)8001bb76ff1Sjsg static bool jpeg_v2_6_query_ras_poison_status(struct amdgpu_device *adev)
8011bb76ff1Sjsg {
8021bb76ff1Sjsg 	uint32_t inst = 0, sub = 0, poison_stat = 0;
8031bb76ff1Sjsg 
8041bb76ff1Sjsg 	for (inst = 0; inst < adev->jpeg.num_jpeg_inst; inst++)
8051bb76ff1Sjsg 		for (sub = 0; sub < AMDGPU_JPEG_V2_6_MAX_SUB_BLOCK; sub++)
8061bb76ff1Sjsg 			poison_stat +=
8071bb76ff1Sjsg 			jpeg_v2_6_query_poison_by_instance(adev, inst, sub);
8081bb76ff1Sjsg 
8091bb76ff1Sjsg 	return !!poison_stat;
8101bb76ff1Sjsg }
8111bb76ff1Sjsg 
8121bb76ff1Sjsg const struct amdgpu_ras_block_hw_ops jpeg_v2_6_ras_hw_ops = {
8131bb76ff1Sjsg 	.query_poison_status = jpeg_v2_6_query_ras_poison_status,
8141bb76ff1Sjsg };
8151bb76ff1Sjsg 
8161bb76ff1Sjsg static struct amdgpu_jpeg_ras jpeg_v2_6_ras = {
8171bb76ff1Sjsg 	.ras_block = {
8181bb76ff1Sjsg 		.hw_ops = &jpeg_v2_6_ras_hw_ops,
819*f005ef32Sjsg 		.ras_late_init = amdgpu_jpeg_ras_late_init,
8201bb76ff1Sjsg 	},
8211bb76ff1Sjsg };
8221bb76ff1Sjsg 
jpeg_v2_5_set_ras_funcs(struct amdgpu_device * adev)8231bb76ff1Sjsg static void jpeg_v2_5_set_ras_funcs(struct amdgpu_device *adev)
8241bb76ff1Sjsg {
8251bb76ff1Sjsg 	switch (adev->ip_versions[JPEG_HWIP][0]) {
8261bb76ff1Sjsg 	case IP_VERSION(2, 6, 0):
8271bb76ff1Sjsg 		adev->jpeg.ras = &jpeg_v2_6_ras;
8281bb76ff1Sjsg 		break;
8291bb76ff1Sjsg 	default:
8301bb76ff1Sjsg 		break;
8311bb76ff1Sjsg 	}
8321bb76ff1Sjsg }
833