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