1 /*
2 * Copyright 2023 Advanced Micro Devices, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
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_v2_0.h"
30 #include "jpeg_v4_0_5.h"
31 #include "mmsch_v4_0.h"
32
33 #include "vcn/vcn_4_0_5_offset.h"
34 #include "vcn/vcn_4_0_5_sh_mask.h"
35 #include "ivsrcid/vcn/irqsrcs_vcn_4_0.h"
36
37 #define mmUVD_DPG_LMA_CTL regUVD_DPG_LMA_CTL
38 #define mmUVD_DPG_LMA_CTL_BASE_IDX regUVD_DPG_LMA_CTL_BASE_IDX
39 #define mmUVD_DPG_LMA_DATA regUVD_DPG_LMA_DATA
40 #define mmUVD_DPG_LMA_DATA_BASE_IDX regUVD_DPG_LMA_DATA_BASE_IDX
41
42 #define regUVD_JPEG_PITCH_INTERNAL_OFFSET 0x401f
43 #define regJPEG_DEC_GFX10_ADDR_CONFIG_INTERNAL_OFFSET 0x4026
44 #define regJPEG_SYS_INT_EN_INTERNAL_OFFSET 0x4141
45 #define regJPEG_CGC_CTRL_INTERNAL_OFFSET 0x4161
46 #define regJPEG_CGC_GATE_INTERNAL_OFFSET 0x4160
47 #define regUVD_NO_OP_INTERNAL_OFFSET 0x0029
48
49 static const struct amdgpu_hwip_reg_entry jpeg_reg_list_4_0_5[] = {
50 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_POWER_STATUS),
51 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_INT_STAT),
52 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_RPTR),
53 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_WPTR),
54 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_CNTL),
55 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_SIZE),
56 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_STATUS),
57 SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_ADDR_MODE),
58 SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG),
59 SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_Y_GFX10_TILING_SURFACE),
60 SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_UV_GFX10_TILING_SURFACE),
61 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_PITCH),
62 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_UV_PITCH),
63 };
64
65 static void jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device *adev);
66 static void jpeg_v4_0_5_set_irq_funcs(struct amdgpu_device *adev);
67 static int jpeg_v4_0_5_set_powergating_state(struct amdgpu_ip_block *ip_block,
68 enum amd_powergating_state state);
69 static void jpeg_v4_0_5_dec_ring_set_wptr(struct amdgpu_ring *ring);
70
71 static int amdgpu_ih_clientid_jpeg[] = {
72 SOC15_IH_CLIENTID_VCN,
73 SOC15_IH_CLIENTID_VCN1
74 };
75
76
77
78 /**
79 * jpeg_v4_0_5_early_init - set function pointers
80 *
81 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
82 *
83 * Set ring and irq function pointers
84 */
jpeg_v4_0_5_early_init(struct amdgpu_ip_block * ip_block)85 static int jpeg_v4_0_5_early_init(struct amdgpu_ip_block *ip_block)
86 {
87 struct amdgpu_device *adev = ip_block->adev;
88
89 switch (amdgpu_ip_version(adev, UVD_HWIP, 0)) {
90 case IP_VERSION(4, 0, 5):
91 adev->jpeg.num_jpeg_inst = 1;
92 break;
93 case IP_VERSION(4, 0, 6):
94 adev->jpeg.num_jpeg_inst = 2;
95 break;
96 default:
97 DRM_DEV_ERROR(adev->dev,
98 "Failed to init vcn ip block(UVD_HWIP:0x%x)\n",
99 amdgpu_ip_version(adev, UVD_HWIP, 0));
100 return -EINVAL;
101 }
102
103 adev->jpeg.num_jpeg_rings = 1;
104
105 jpeg_v4_0_5_set_dec_ring_funcs(adev);
106 jpeg_v4_0_5_set_irq_funcs(adev);
107
108 return 0;
109 }
110
111 /**
112 * jpeg_v4_0_5_sw_init - sw init for JPEG block
113 *
114 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
115 *
116 * Load firmware and sw initialization
117 */
jpeg_v4_0_5_sw_init(struct amdgpu_ip_block * ip_block)118 static int jpeg_v4_0_5_sw_init(struct amdgpu_ip_block *ip_block)
119 {
120 struct amdgpu_device *adev = ip_block->adev;
121 struct amdgpu_ring *ring;
122 int r, i;
123
124 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
125 if (adev->jpeg.harvest_config & (1 << i))
126 continue;
127
128 /* JPEG TRAP */
129 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
130 VCN_4_0__SRCID__JPEG_DECODE, &adev->jpeg.inst[i].irq);
131 if (r)
132 return r;
133
134 /* JPEG DJPEG POISON EVENT */
135 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
136 VCN_4_0__SRCID_DJPEG0_POISON, &adev->jpeg.inst[i].irq);
137 if (r)
138 return r;
139
140 /* JPEG EJPEG POISON EVENT */
141 r = amdgpu_irq_add_id(adev, amdgpu_ih_clientid_jpeg[i],
142 VCN_4_0__SRCID_EJPEG0_POISON, &adev->jpeg.inst[i].irq);
143 if (r)
144 return r;
145 }
146
147 r = amdgpu_jpeg_sw_init(adev);
148 if (r)
149 return r;
150
151 r = amdgpu_jpeg_resume(adev);
152 if (r)
153 return r;
154
155 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
156 if (adev->jpeg.harvest_config & (1 << i))
157 continue;
158
159 ring = adev->jpeg.inst[i].ring_dec;
160 ring->use_doorbell = true;
161 ring->vm_hub = AMDGPU_MMHUB0(0);
162 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1 + 8 * i;
163 sprintf(ring->name, "jpeg_dec_%d", i);
164 r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst[i].irq,
165 0, AMDGPU_RING_PRIO_DEFAULT, NULL);
166 if (r)
167 return r;
168
169 adev->jpeg.internal.jpeg_pitch[0] = regUVD_JPEG_PITCH_INTERNAL_OFFSET;
170 adev->jpeg.inst[i].external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, i, regUVD_JPEG_PITCH);
171 }
172
173 r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_4_0_5, ARRAY_SIZE(jpeg_reg_list_4_0_5));
174 if (r)
175 return r;
176
177 adev->jpeg.supported_reset =
178 amdgpu_get_soft_full_reset_mask(&adev->jpeg.inst[0].ring_dec[0]);
179 if (!amdgpu_sriov_vf(adev))
180 adev->jpeg.supported_reset |= AMDGPU_RESET_TYPE_PER_QUEUE;
181 r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
182 if (r)
183 return r;
184
185 return 0;
186 }
187
188 /**
189 * jpeg_v4_0_5_sw_fini - sw fini for JPEG block
190 *
191 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
192 *
193 * JPEG suspend and free up sw allocation
194 */
jpeg_v4_0_5_sw_fini(struct amdgpu_ip_block * ip_block)195 static int jpeg_v4_0_5_sw_fini(struct amdgpu_ip_block *ip_block)
196 {
197 struct amdgpu_device *adev = ip_block->adev;
198 int r;
199
200 r = amdgpu_jpeg_suspend(adev);
201 if (r)
202 return r;
203
204 amdgpu_jpeg_sysfs_reset_mask_fini(adev);
205 r = amdgpu_jpeg_sw_fini(adev);
206
207 return r;
208 }
209
210 /**
211 * jpeg_v4_0_5_hw_init - start and test JPEG block
212 *
213 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
214 *
215 */
jpeg_v4_0_5_hw_init(struct amdgpu_ip_block * ip_block)216 static int jpeg_v4_0_5_hw_init(struct amdgpu_ip_block *ip_block)
217 {
218 struct amdgpu_device *adev = ip_block->adev;
219 struct amdgpu_ring *ring;
220 int i, r = 0;
221
222 // TODO: Enable ring test with DPG support
223 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
224 return 0;
225 }
226
227 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
228 if (adev->jpeg.harvest_config & (1 << i))
229 continue;
230
231 ring = adev->jpeg.inst[i].ring_dec;
232 r = amdgpu_ring_test_helper(ring);
233 if (r)
234 return r;
235 }
236
237 return 0;
238 }
239
240 /**
241 * jpeg_v4_0_5_hw_fini - stop the hardware block
242 *
243 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
244 *
245 * Stop the JPEG block, mark ring as not ready any more
246 */
jpeg_v4_0_5_hw_fini(struct amdgpu_ip_block * ip_block)247 static int jpeg_v4_0_5_hw_fini(struct amdgpu_ip_block *ip_block)
248 {
249 struct amdgpu_device *adev = ip_block->adev;
250 int i;
251
252 cancel_delayed_work_sync(&adev->jpeg.idle_work);
253
254 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
255 if (adev->jpeg.harvest_config & (1 << i))
256 continue;
257
258 if (!amdgpu_sriov_vf(adev)) {
259 if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
260 RREG32_SOC15(JPEG, i, regUVD_JRBC_STATUS))
261 jpeg_v4_0_5_set_powergating_state(ip_block, AMD_PG_STATE_GATE);
262 }
263 }
264 return 0;
265 }
266
267 /**
268 * jpeg_v4_0_5_suspend - suspend JPEG block
269 *
270 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
271 *
272 * HW fini and suspend JPEG block
273 */
jpeg_v4_0_5_suspend(struct amdgpu_ip_block * ip_block)274 static int jpeg_v4_0_5_suspend(struct amdgpu_ip_block *ip_block)
275 {
276 int r;
277
278 r = jpeg_v4_0_5_hw_fini(ip_block);
279 if (r)
280 return r;
281
282 r = amdgpu_jpeg_suspend(ip_block->adev);
283
284 return r;
285 }
286
287 /**
288 * jpeg_v4_0_5_resume - resume JPEG block
289 *
290 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
291 *
292 * Resume firmware and hw init JPEG block
293 */
jpeg_v4_0_5_resume(struct amdgpu_ip_block * ip_block)294 static int jpeg_v4_0_5_resume(struct amdgpu_ip_block *ip_block)
295 {
296 int r;
297
298 r = amdgpu_jpeg_resume(ip_block->adev);
299 if (r)
300 return r;
301
302 r = jpeg_v4_0_5_hw_init(ip_block);
303
304 return r;
305 }
306
jpeg_v4_0_5_disable_clock_gating(struct amdgpu_device * adev,int inst)307 static void jpeg_v4_0_5_disable_clock_gating(struct amdgpu_device *adev, int inst)
308 {
309 uint32_t data = 0;
310
311 data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL);
312 if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) {
313 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
314 data &= (~JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK);
315 } else {
316 data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
317 }
318
319 data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
320 data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
321 WREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL, data);
322
323 data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE);
324 data &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK
325 | JPEG_CGC_GATE__JPEG2_DEC_MASK
326 | JPEG_CGC_GATE__JMCIF_MASK
327 | JPEG_CGC_GATE__JRBBM_MASK);
328 WREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE, data);
329 }
330
jpeg_v4_0_5_enable_clock_gating(struct amdgpu_device * adev,int inst)331 static void jpeg_v4_0_5_enable_clock_gating(struct amdgpu_device *adev, int inst)
332 {
333 uint32_t data = 0;
334
335 data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL);
336 if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) {
337 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
338 data |= JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK;
339 } else {
340 data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
341 }
342
343 data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
344 data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
345 WREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL, data);
346
347 data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE);
348 data |= (JPEG_CGC_GATE__JPEG_DEC_MASK
349 |JPEG_CGC_GATE__JPEG2_DEC_MASK
350 |JPEG_CGC_GATE__JMCIF_MASK
351 |JPEG_CGC_GATE__JRBBM_MASK);
352 WREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE, data);
353 }
354
jpeg_engine_4_0_5_dpg_clock_gating_mode(struct amdgpu_device * adev,int inst_idx,uint8_t indirect)355 static void jpeg_engine_4_0_5_dpg_clock_gating_mode(struct amdgpu_device *adev,
356 int inst_idx, uint8_t indirect)
357 {
358 uint32_t data = 0;
359
360 if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG)
361 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
362 else
363 data |= 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
364
365 data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
366 data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
367 WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_CGC_CTRL_INTERNAL_OFFSET, data, indirect);
368
369 data = 0;
370 WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_CGC_GATE_INTERNAL_OFFSET,
371 data, indirect);
372 }
373
jpeg_v4_0_5_disable_static_power_gating(struct amdgpu_device * adev,int inst)374 static int jpeg_v4_0_5_disable_static_power_gating(struct amdgpu_device *adev, int inst)
375 {
376 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
377 WREG32(SOC15_REG_OFFSET(JPEG, inst, regUVD_IPX_DLDO_CONFIG),
378 1 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT);
379 SOC15_WAIT_ON_RREG(JPEG, inst, regUVD_IPX_DLDO_STATUS,
380 0, UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK);
381 }
382
383 /* disable anti hang mechanism */
384 WREG32_P(SOC15_REG_OFFSET(JPEG, inst, regUVD_JPEG_POWER_STATUS), 0,
385 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
386
387 /* keep the JPEG in static PG mode */
388 WREG32_P(SOC15_REG_OFFSET(JPEG, inst, regUVD_JPEG_POWER_STATUS), 0,
389 ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK);
390
391 return 0;
392 }
393
jpeg_v4_0_5_enable_static_power_gating(struct amdgpu_device * adev,int inst)394 static int jpeg_v4_0_5_enable_static_power_gating(struct amdgpu_device *adev, int inst)
395 {
396 /* enable anti hang mechanism */
397 WREG32_P(SOC15_REG_OFFSET(JPEG, inst, regUVD_JPEG_POWER_STATUS),
398 UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
399 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
400
401 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
402 WREG32(SOC15_REG_OFFSET(JPEG, inst, regUVD_IPX_DLDO_CONFIG),
403 2 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT);
404 SOC15_WAIT_ON_RREG(JPEG, inst, regUVD_IPX_DLDO_STATUS,
405 1 << UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS__SHIFT,
406 UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK);
407 }
408
409 return 0;
410 }
411
412 /**
413 * jpeg_v4_0_5_start_dpg_mode - Jpeg start with dpg mode
414 *
415 * @adev: amdgpu_device pointer
416 * @inst_idx: instance number index
417 * @indirect: indirectly write sram
418 *
419 * Start JPEG block with dpg mode
420 */
jpeg_v4_0_5_start_dpg_mode(struct amdgpu_device * adev,int inst_idx,bool indirect)421 static void jpeg_v4_0_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
422 {
423 struct amdgpu_ring *ring = adev->jpeg.inst[inst_idx].ring_dec;
424 uint32_t reg_data = 0;
425
426 /* enable anti hang mechanism */
427 reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS);
428 reg_data &= ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK;
429 reg_data |= 0x1;
430 WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
431
432 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
433 WREG32(SOC15_REG_OFFSET(JPEG, inst_idx, regUVD_IPX_DLDO_CONFIG),
434 2 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT);
435 SOC15_WAIT_ON_RREG(JPEG, inst_idx, regUVD_IPX_DLDO_STATUS,
436 1 << UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS__SHIFT,
437 UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK);
438 }
439
440 reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS);
441 reg_data |= UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK;
442 WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
443
444 if (indirect)
445 adev->jpeg.inst[inst_idx].dpg_sram_curr_addr =
446 (uint32_t *)adev->jpeg.inst[inst_idx].dpg_sram_cpu_addr;
447
448 jpeg_engine_4_0_5_dpg_clock_gating_mode(adev, inst_idx, indirect);
449
450 /* MJPEG global tiling registers */
451 WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_DEC_GFX10_ADDR_CONFIG_INTERNAL_OFFSET,
452 adev->gfx.config.gb_addr_config, indirect);
453 /* enable System Interrupt for JRBC */
454 WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_SYS_INT_EN_INTERNAL_OFFSET,
455 JPEG_SYS_INT_EN__DJRBC_MASK, indirect);
456
457 /* add nop to workaround PSP size check */
458 WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regUVD_NO_OP_INTERNAL_OFFSET, 0, indirect);
459
460 if (indirect)
461 amdgpu_jpeg_psp_update_sram(adev, inst_idx, 0);
462
463 WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_VMID, 0);
464 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
465 WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
466 lower_32_bits(ring->gpu_addr));
467 WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
468 upper_32_bits(ring->gpu_addr));
469 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_RPTR, 0);
470 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_WPTR, 0);
471 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_CNTL, 0x00000002L);
472 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_SIZE, ring->ring_size / 4);
473 ring->wptr = RREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_WPTR);
474 }
475
476 /**
477 * jpeg_v4_0_5_stop_dpg_mode - Jpeg stop with dpg mode
478 *
479 * @adev: amdgpu_device pointer
480 * @inst_idx: instance number index
481 *
482 * Stop JPEG block with dpg mode
483 */
jpeg_v4_0_5_stop_dpg_mode(struct amdgpu_device * adev,int inst_idx)484 static void jpeg_v4_0_5_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
485 {
486 uint32_t reg_data = 0;
487
488 reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS);
489 reg_data &= ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK;
490 WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
491
492 }
493
494 /**
495 * jpeg_v4_0_5_start - start JPEG block
496 *
497 * @adev: amdgpu_device pointer
498 *
499 * Setup and start the JPEG block
500 */
jpeg_v4_0_5_start(struct amdgpu_device * adev)501 static int jpeg_v4_0_5_start(struct amdgpu_device *adev)
502 {
503 struct amdgpu_ring *ring;
504 int r, i;
505
506 if (adev->pm.dpm_enabled)
507 amdgpu_dpm_enable_jpeg(adev, true);
508
509 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
510 if (adev->jpeg.harvest_config & (1 << i))
511 continue;
512
513 ring = adev->jpeg.inst[i].ring_dec;
514 /* doorbell programming is done for every playback */
515 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
516 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i, i);
517
518 WREG32_SOC15(VCN, i, regVCN_JPEG_DB_CTRL,
519 ring->doorbell_index << VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
520 VCN_JPEG_DB_CTRL__EN_MASK);
521
522 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
523 jpeg_v4_0_5_start_dpg_mode(adev, i, adev->jpeg.indirect_sram);
524 continue;
525 }
526
527 /* disable power gating */
528 r = jpeg_v4_0_5_disable_static_power_gating(adev, i);
529 if (r)
530 return r;
531
532 /* JPEG disable CGC */
533 jpeg_v4_0_5_disable_clock_gating(adev, i);
534
535 /* MJPEG global tiling registers */
536 WREG32_SOC15(JPEG, i, regJPEG_DEC_GFX10_ADDR_CONFIG,
537 adev->gfx.config.gb_addr_config);
538
539 /* enable JMI channel */
540 WREG32_P(SOC15_REG_OFFSET(JPEG, i, regUVD_JMI_CNTL), 0,
541 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
542
543 /* enable System Interrupt for JRBC */
544 WREG32_P(SOC15_REG_OFFSET(JPEG, i, regJPEG_SYS_INT_EN),
545 JPEG_SYS_INT_EN__DJRBC_MASK,
546 ~JPEG_SYS_INT_EN__DJRBC_MASK);
547
548 WREG32_SOC15(JPEG, i, regUVD_LMI_JRBC_RB_VMID, 0);
549 WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
550 WREG32_SOC15(JPEG, i, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
551 lower_32_bits(ring->gpu_addr));
552 WREG32_SOC15(JPEG, i, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
553 upper_32_bits(ring->gpu_addr));
554 WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_RPTR, 0);
555 WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_WPTR, 0);
556 WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_CNTL, 0x00000002L);
557 WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_SIZE, ring->ring_size / 4);
558 ring->wptr = RREG32_SOC15(JPEG, i, regUVD_JRBC_RB_WPTR);
559 }
560
561 return 0;
562 }
563
564 /**
565 * jpeg_v4_0_5_stop - stop JPEG block
566 *
567 * @adev: amdgpu_device pointer
568 *
569 * stop the JPEG block
570 */
jpeg_v4_0_5_stop(struct amdgpu_device * adev)571 static int jpeg_v4_0_5_stop(struct amdgpu_device *adev)
572 {
573 int r, i;
574
575 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
576 if (adev->jpeg.harvest_config & (1 << i))
577 continue;
578
579 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
580 jpeg_v4_0_5_stop_dpg_mode(adev, i);
581 continue;
582 }
583
584 /* reset JMI */
585 WREG32_P(SOC15_REG_OFFSET(JPEG, i, regUVD_JMI_CNTL),
586 UVD_JMI_CNTL__SOFT_RESET_MASK,
587 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
588
589 jpeg_v4_0_5_enable_clock_gating(adev, i);
590
591 /* enable power gating */
592 r = jpeg_v4_0_5_enable_static_power_gating(adev, i);
593 if (r)
594 return r;
595 }
596 if (adev->pm.dpm_enabled)
597 amdgpu_dpm_enable_jpeg(adev, false);
598
599 return 0;
600 }
601
602 /**
603 * jpeg_v4_0_5_dec_ring_get_rptr - get read pointer
604 *
605 * @ring: amdgpu_ring pointer
606 *
607 * Returns the current hardware read pointer
608 */
jpeg_v4_0_5_dec_ring_get_rptr(struct amdgpu_ring * ring)609 static uint64_t jpeg_v4_0_5_dec_ring_get_rptr(struct amdgpu_ring *ring)
610 {
611 struct amdgpu_device *adev = ring->adev;
612
613 return RREG32_SOC15(JPEG, ring->me, regUVD_JRBC_RB_RPTR);
614 }
615
616 /**
617 * jpeg_v4_0_5_dec_ring_get_wptr - get write pointer
618 *
619 * @ring: amdgpu_ring pointer
620 *
621 * Returns the current hardware write pointer
622 */
jpeg_v4_0_5_dec_ring_get_wptr(struct amdgpu_ring * ring)623 static uint64_t jpeg_v4_0_5_dec_ring_get_wptr(struct amdgpu_ring *ring)
624 {
625 struct amdgpu_device *adev = ring->adev;
626
627 if (ring->use_doorbell)
628 return *ring->wptr_cpu_addr;
629 else
630 return RREG32_SOC15(JPEG, ring->me, regUVD_JRBC_RB_WPTR);
631 }
632
633 /**
634 * jpeg_v4_0_5_dec_ring_set_wptr - set write pointer
635 *
636 * @ring: amdgpu_ring pointer
637 *
638 * Commits the write pointer to the hardware
639 */
jpeg_v4_0_5_dec_ring_set_wptr(struct amdgpu_ring * ring)640 static void jpeg_v4_0_5_dec_ring_set_wptr(struct amdgpu_ring *ring)
641 {
642 struct amdgpu_device *adev = ring->adev;
643
644 if (ring->use_doorbell) {
645 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
646 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
647 } else {
648 WREG32_SOC15(JPEG, ring->me, regUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
649 }
650 }
651
jpeg_v4_0_5_is_idle(struct amdgpu_ip_block * ip_block)652 static bool jpeg_v4_0_5_is_idle(struct amdgpu_ip_block *ip_block)
653 {
654 struct amdgpu_device *adev = ip_block->adev;
655 int i, ret = 1;
656
657 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
658 if (adev->jpeg.harvest_config & (1 << i))
659 continue;
660
661 ret &= (((RREG32_SOC15(JPEG, i, regUVD_JRBC_STATUS) &
662 UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
663 UVD_JRBC_STATUS__RB_JOB_DONE_MASK));
664 }
665 return ret;
666 }
667
jpeg_v4_0_5_wait_for_idle(struct amdgpu_ip_block * ip_block)668 static int jpeg_v4_0_5_wait_for_idle(struct amdgpu_ip_block *ip_block)
669 {
670 struct amdgpu_device *adev = ip_block->adev;
671 int i;
672
673 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
674 if (adev->jpeg.harvest_config & (1 << i))
675 continue;
676
677 return SOC15_WAIT_ON_RREG(JPEG, i, regUVD_JRBC_STATUS,
678 UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
679 UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
680 }
681
682 return 0;
683 }
684
jpeg_v4_0_5_set_clockgating_state(struct amdgpu_ip_block * ip_block,enum amd_clockgating_state state)685 static int jpeg_v4_0_5_set_clockgating_state(struct amdgpu_ip_block *ip_block,
686 enum amd_clockgating_state state)
687 {
688 struct amdgpu_device *adev = ip_block->adev;
689 bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
690 int i;
691
692 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
693 if (adev->jpeg.harvest_config & (1 << i))
694 continue;
695
696 if (enable) {
697 if (!jpeg_v4_0_5_is_idle(ip_block))
698 return -EBUSY;
699
700 jpeg_v4_0_5_enable_clock_gating(adev, i);
701 } else {
702 jpeg_v4_0_5_disable_clock_gating(adev, i);
703 }
704 }
705
706 return 0;
707 }
708
jpeg_v4_0_5_set_powergating_state(struct amdgpu_ip_block * ip_block,enum amd_powergating_state state)709 static int jpeg_v4_0_5_set_powergating_state(struct amdgpu_ip_block *ip_block,
710 enum amd_powergating_state state)
711 {
712 struct amdgpu_device *adev = ip_block->adev;
713 int ret;
714
715 if (amdgpu_sriov_vf(adev)) {
716 adev->jpeg.cur_state = AMD_PG_STATE_UNGATE;
717 return 0;
718 }
719
720 if (state == adev->jpeg.cur_state)
721 return 0;
722
723 if (state == AMD_PG_STATE_GATE)
724 ret = jpeg_v4_0_5_stop(adev);
725 else
726 ret = jpeg_v4_0_5_start(adev);
727
728 if (!ret)
729 adev->jpeg.cur_state = state;
730
731 return ret;
732 }
733
jpeg_v4_0_5_process_interrupt(struct amdgpu_device * adev,struct amdgpu_irq_src * source,struct amdgpu_iv_entry * entry)734 static int jpeg_v4_0_5_process_interrupt(struct amdgpu_device *adev,
735 struct amdgpu_irq_src *source,
736 struct amdgpu_iv_entry *entry)
737 {
738 uint32_t ip_instance;
739
740 DRM_DEBUG("IH: JPEG TRAP\n");
741
742 switch (entry->client_id) {
743 case SOC15_IH_CLIENTID_VCN:
744 ip_instance = 0;
745 break;
746 case SOC15_IH_CLIENTID_VCN1:
747 ip_instance = 1;
748 break;
749 default:
750 DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
751 return 0;
752 }
753
754 switch (entry->src_id) {
755 case VCN_4_0__SRCID__JPEG_DECODE:
756 amdgpu_fence_process(adev->jpeg.inst[ip_instance].ring_dec);
757 break;
758 case VCN_4_0__SRCID_DJPEG0_POISON:
759 case VCN_4_0__SRCID_EJPEG0_POISON:
760 amdgpu_jpeg_process_poison_irq(adev, source, entry);
761 break;
762 default:
763 DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n",
764 entry->src_id, entry->src_data[0]);
765 break;
766 }
767
768 return 0;
769 }
770
jpeg_v4_0_5_ring_reset(struct amdgpu_ring * ring,unsigned int vmid,struct amdgpu_fence * timedout_fence)771 static int jpeg_v4_0_5_ring_reset(struct amdgpu_ring *ring,
772 unsigned int vmid,
773 struct amdgpu_fence *timedout_fence)
774 {
775 int r;
776
777 amdgpu_ring_reset_helper_begin(ring, timedout_fence);
778 r = jpeg_v4_0_5_stop(ring->adev);
779 if (r)
780 return r;
781 r = jpeg_v4_0_5_start(ring->adev);
782 if (r)
783 return r;
784 return amdgpu_ring_reset_helper_end(ring, timedout_fence);
785 }
786
787 static const struct amd_ip_funcs jpeg_v4_0_5_ip_funcs = {
788 .name = "jpeg_v4_0_5",
789 .early_init = jpeg_v4_0_5_early_init,
790 .sw_init = jpeg_v4_0_5_sw_init,
791 .sw_fini = jpeg_v4_0_5_sw_fini,
792 .hw_init = jpeg_v4_0_5_hw_init,
793 .hw_fini = jpeg_v4_0_5_hw_fini,
794 .suspend = jpeg_v4_0_5_suspend,
795 .resume = jpeg_v4_0_5_resume,
796 .is_idle = jpeg_v4_0_5_is_idle,
797 .wait_for_idle = jpeg_v4_0_5_wait_for_idle,
798 .set_clockgating_state = jpeg_v4_0_5_set_clockgating_state,
799 .set_powergating_state = jpeg_v4_0_5_set_powergating_state,
800 .dump_ip_state = amdgpu_jpeg_dump_ip_state,
801 .print_ip_state = amdgpu_jpeg_print_ip_state,
802 };
803
804 static const struct amdgpu_ring_funcs jpeg_v4_0_5_dec_ring_vm_funcs = {
805 .type = AMDGPU_RING_TYPE_VCN_JPEG,
806 .align_mask = 0xf,
807 .get_rptr = jpeg_v4_0_5_dec_ring_get_rptr,
808 .get_wptr = jpeg_v4_0_5_dec_ring_get_wptr,
809 .set_wptr = jpeg_v4_0_5_dec_ring_set_wptr,
810 .parse_cs = jpeg_v2_dec_ring_parse_cs,
811 .emit_frame_size =
812 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
813 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
814 8 + /* jpeg_v4_0_5_dec_ring_emit_vm_flush */
815 18 + 18 + /* jpeg_v4_0_5_dec_ring_emit_fence x2 vm fence */
816 8 + 16,
817 .emit_ib_size = 22, /* jpeg_v4_0_5_dec_ring_emit_ib */
818 .emit_ib = jpeg_v2_0_dec_ring_emit_ib,
819 .emit_fence = jpeg_v2_0_dec_ring_emit_fence,
820 .emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush,
821 .test_ring = amdgpu_jpeg_dec_ring_test_ring,
822 .test_ib = amdgpu_jpeg_dec_ring_test_ib,
823 .insert_nop = jpeg_v2_0_dec_ring_nop,
824 .insert_start = jpeg_v2_0_dec_ring_insert_start,
825 .insert_end = jpeg_v2_0_dec_ring_insert_end,
826 .pad_ib = amdgpu_ring_generic_pad_ib,
827 .begin_use = amdgpu_jpeg_ring_begin_use,
828 .end_use = amdgpu_jpeg_ring_end_use,
829 .emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
830 .emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
831 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
832 .reset = jpeg_v4_0_5_ring_reset,
833 };
834
jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device * adev)835 static void jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device *adev)
836 {
837 int i;
838
839 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
840 if (adev->jpeg.harvest_config & (1 << i))
841 continue;
842
843 adev->jpeg.inst[i].ring_dec->funcs = &jpeg_v4_0_5_dec_ring_vm_funcs;
844 adev->jpeg.inst[i].ring_dec->me = i;
845 }
846 }
847
848 static const struct amdgpu_irq_src_funcs jpeg_v4_0_5_irq_funcs = {
849 .process = jpeg_v4_0_5_process_interrupt,
850 };
851
jpeg_v4_0_5_set_irq_funcs(struct amdgpu_device * adev)852 static void jpeg_v4_0_5_set_irq_funcs(struct amdgpu_device *adev)
853 {
854 int i;
855
856 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
857 if (adev->jpeg.harvest_config & (1 << i))
858 continue;
859
860 adev->jpeg.inst[i].irq.num_types = 1;
861 adev->jpeg.inst[i].irq.funcs = &jpeg_v4_0_5_irq_funcs;
862 }
863 }
864
865 const struct amdgpu_ip_block_version jpeg_v4_0_5_ip_block = {
866 .type = AMD_IP_BLOCK_TYPE_JPEG,
867 .major = 4,
868 .minor = 0,
869 .rev = 5,
870 .funcs = &jpeg_v4_0_5_ip_funcs,
871 };
872
873