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 /* TODO: Add queue reset mask when FW fully supports it */
178 adev->jpeg.supported_reset =
179 amdgpu_get_soft_full_reset_mask(&adev->jpeg.inst[0].ring_dec[0]);
180 r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
181 if (r)
182 return r;
183
184 return 0;
185 }
186
187 /**
188 * jpeg_v4_0_5_sw_fini - sw fini for JPEG block
189 *
190 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
191 *
192 * JPEG suspend and free up sw allocation
193 */
jpeg_v4_0_5_sw_fini(struct amdgpu_ip_block * ip_block)194 static int jpeg_v4_0_5_sw_fini(struct amdgpu_ip_block *ip_block)
195 {
196 struct amdgpu_device *adev = ip_block->adev;
197 int r;
198
199 r = amdgpu_jpeg_suspend(adev);
200 if (r)
201 return r;
202
203 amdgpu_jpeg_sysfs_reset_mask_fini(adev);
204 r = amdgpu_jpeg_sw_fini(adev);
205
206 return r;
207 }
208
209 /**
210 * jpeg_v4_0_5_hw_init - start and test JPEG block
211 *
212 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
213 *
214 */
jpeg_v4_0_5_hw_init(struct amdgpu_ip_block * ip_block)215 static int jpeg_v4_0_5_hw_init(struct amdgpu_ip_block *ip_block)
216 {
217 struct amdgpu_device *adev = ip_block->adev;
218 struct amdgpu_ring *ring;
219 int i, r = 0;
220
221 // TODO: Enable ring test with DPG support
222 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
223 return 0;
224 }
225
226 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
227 if (adev->jpeg.harvest_config & (1 << i))
228 continue;
229
230 ring = adev->jpeg.inst[i].ring_dec;
231 r = amdgpu_ring_test_helper(ring);
232 if (r)
233 return r;
234 }
235
236 return 0;
237 }
238
239 /**
240 * jpeg_v4_0_5_hw_fini - stop the hardware block
241 *
242 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
243 *
244 * Stop the JPEG block, mark ring as not ready any more
245 */
jpeg_v4_0_5_hw_fini(struct amdgpu_ip_block * ip_block)246 static int jpeg_v4_0_5_hw_fini(struct amdgpu_ip_block *ip_block)
247 {
248 struct amdgpu_device *adev = ip_block->adev;
249 int i;
250
251 cancel_delayed_work_sync(&adev->jpeg.idle_work);
252
253 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
254 if (adev->jpeg.harvest_config & (1 << i))
255 continue;
256
257 if (!amdgpu_sriov_vf(adev)) {
258 if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
259 RREG32_SOC15(JPEG, i, regUVD_JRBC_STATUS))
260 jpeg_v4_0_5_set_powergating_state(ip_block, AMD_PG_STATE_GATE);
261 }
262 }
263 return 0;
264 }
265
266 /**
267 * jpeg_v4_0_5_suspend - suspend JPEG block
268 *
269 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
270 *
271 * HW fini and suspend JPEG block
272 */
jpeg_v4_0_5_suspend(struct amdgpu_ip_block * ip_block)273 static int jpeg_v4_0_5_suspend(struct amdgpu_ip_block *ip_block)
274 {
275 int r;
276
277 r = jpeg_v4_0_5_hw_fini(ip_block);
278 if (r)
279 return r;
280
281 r = amdgpu_jpeg_suspend(ip_block->adev);
282
283 return r;
284 }
285
286 /**
287 * jpeg_v4_0_5_resume - resume JPEG block
288 *
289 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
290 *
291 * Resume firmware and hw init JPEG block
292 */
jpeg_v4_0_5_resume(struct amdgpu_ip_block * ip_block)293 static int jpeg_v4_0_5_resume(struct amdgpu_ip_block *ip_block)
294 {
295 int r;
296
297 r = amdgpu_jpeg_resume(ip_block->adev);
298 if (r)
299 return r;
300
301 r = jpeg_v4_0_5_hw_init(ip_block);
302
303 return r;
304 }
305
jpeg_v4_0_5_disable_clock_gating(struct amdgpu_device * adev,int inst)306 static void jpeg_v4_0_5_disable_clock_gating(struct amdgpu_device *adev, int inst)
307 {
308 uint32_t data = 0;
309
310 data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL);
311 if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) {
312 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
313 data &= (~JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK);
314 } else {
315 data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
316 }
317
318 data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
319 data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
320 WREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL, data);
321
322 data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE);
323 data &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK
324 | JPEG_CGC_GATE__JPEG2_DEC_MASK
325 | JPEG_CGC_GATE__JMCIF_MASK
326 | JPEG_CGC_GATE__JRBBM_MASK);
327 WREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE, data);
328 }
329
jpeg_v4_0_5_enable_clock_gating(struct amdgpu_device * adev,int inst)330 static void jpeg_v4_0_5_enable_clock_gating(struct amdgpu_device *adev, int inst)
331 {
332 uint32_t data = 0;
333
334 data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL);
335 if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) {
336 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
337 data |= JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK;
338 } else {
339 data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
340 }
341
342 data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
343 data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
344 WREG32_SOC15(JPEG, inst, regJPEG_CGC_CTRL, data);
345
346 data = RREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE);
347 data |= (JPEG_CGC_GATE__JPEG_DEC_MASK
348 |JPEG_CGC_GATE__JPEG2_DEC_MASK
349 |JPEG_CGC_GATE__JMCIF_MASK
350 |JPEG_CGC_GATE__JRBBM_MASK);
351 WREG32_SOC15(JPEG, inst, regJPEG_CGC_GATE, data);
352 }
353
jpeg_engine_4_0_5_dpg_clock_gating_mode(struct amdgpu_device * adev,int inst_idx,uint8_t indirect)354 static void jpeg_engine_4_0_5_dpg_clock_gating_mode(struct amdgpu_device *adev,
355 int inst_idx, uint8_t indirect)
356 {
357 uint32_t data = 0;
358
359 if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG)
360 data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
361 else
362 data |= 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
363
364 data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
365 data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
366 WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_CGC_CTRL_INTERNAL_OFFSET, data, indirect);
367
368 data = 0;
369 WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_CGC_GATE_INTERNAL_OFFSET,
370 data, indirect);
371 }
372
jpeg_v4_0_5_disable_static_power_gating(struct amdgpu_device * adev,int inst)373 static int jpeg_v4_0_5_disable_static_power_gating(struct amdgpu_device *adev, int inst)
374 {
375 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
376 WREG32(SOC15_REG_OFFSET(JPEG, inst, regUVD_IPX_DLDO_CONFIG),
377 1 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT);
378 SOC15_WAIT_ON_RREG(JPEG, inst, regUVD_IPX_DLDO_STATUS,
379 0, UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK);
380 }
381
382 /* disable anti hang mechanism */
383 WREG32_P(SOC15_REG_OFFSET(JPEG, inst, regUVD_JPEG_POWER_STATUS), 0,
384 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
385
386 /* keep the JPEG in static PG mode */
387 WREG32_P(SOC15_REG_OFFSET(JPEG, inst, regUVD_JPEG_POWER_STATUS), 0,
388 ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK);
389
390 return 0;
391 }
392
jpeg_v4_0_5_enable_static_power_gating(struct amdgpu_device * adev,int inst)393 static int jpeg_v4_0_5_enable_static_power_gating(struct amdgpu_device *adev, int inst)
394 {
395 /* enable anti hang mechanism */
396 WREG32_P(SOC15_REG_OFFSET(JPEG, inst, regUVD_JPEG_POWER_STATUS),
397 UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
398 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
399
400 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
401 WREG32(SOC15_REG_OFFSET(JPEG, inst, regUVD_IPX_DLDO_CONFIG),
402 2 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT);
403 SOC15_WAIT_ON_RREG(JPEG, inst, regUVD_IPX_DLDO_STATUS,
404 1 << UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS__SHIFT,
405 UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK);
406 }
407
408 return 0;
409 }
410
411 /**
412 * jpeg_v4_0_5_start_dpg_mode - Jpeg start with dpg mode
413 *
414 * @adev: amdgpu_device pointer
415 * @inst_idx: instance number index
416 * @indirect: indirectly write sram
417 *
418 * Start JPEG block with dpg mode
419 */
jpeg_v4_0_5_start_dpg_mode(struct amdgpu_device * adev,int inst_idx,bool indirect)420 static void jpeg_v4_0_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
421 {
422 struct amdgpu_ring *ring = adev->jpeg.inst[inst_idx].ring_dec;
423 uint32_t reg_data = 0;
424
425 /* enable anti hang mechanism */
426 reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS);
427 reg_data &= ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK;
428 reg_data |= 0x1;
429 WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
430
431 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
432 WREG32(SOC15_REG_OFFSET(JPEG, inst_idx, regUVD_IPX_DLDO_CONFIG),
433 2 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT);
434 SOC15_WAIT_ON_RREG(JPEG, inst_idx, regUVD_IPX_DLDO_STATUS,
435 1 << UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS__SHIFT,
436 UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK);
437 }
438
439 reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS);
440 reg_data |= UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK;
441 WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
442
443 if (indirect)
444 adev->jpeg.inst[inst_idx].dpg_sram_curr_addr =
445 (uint32_t *)adev->jpeg.inst[inst_idx].dpg_sram_cpu_addr;
446
447 jpeg_engine_4_0_5_dpg_clock_gating_mode(adev, inst_idx, indirect);
448
449 /* MJPEG global tiling registers */
450 WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_DEC_GFX10_ADDR_CONFIG_INTERNAL_OFFSET,
451 adev->gfx.config.gb_addr_config, indirect);
452 /* enable System Interrupt for JRBC */
453 WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regJPEG_SYS_INT_EN_INTERNAL_OFFSET,
454 JPEG_SYS_INT_EN__DJRBC_MASK, indirect);
455
456 /* add nop to workaround PSP size check */
457 WREG32_SOC15_JPEG_DPG_MODE(inst_idx, regUVD_NO_OP_INTERNAL_OFFSET, 0, indirect);
458
459 if (indirect)
460 amdgpu_jpeg_psp_update_sram(adev, inst_idx, 0);
461
462 WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_VMID, 0);
463 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
464 WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
465 lower_32_bits(ring->gpu_addr));
466 WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
467 upper_32_bits(ring->gpu_addr));
468 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_RPTR, 0);
469 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_WPTR, 0);
470 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_CNTL, 0x00000002L);
471 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_SIZE, ring->ring_size / 4);
472 ring->wptr = RREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_WPTR);
473 }
474
475 /**
476 * jpeg_v4_0_5_stop_dpg_mode - Jpeg stop with dpg mode
477 *
478 * @adev: amdgpu_device pointer
479 * @inst_idx: instance number index
480 *
481 * Stop JPEG block with dpg mode
482 */
jpeg_v4_0_5_stop_dpg_mode(struct amdgpu_device * adev,int inst_idx)483 static void jpeg_v4_0_5_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
484 {
485 uint32_t reg_data = 0;
486
487 reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS);
488 reg_data &= ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK;
489 WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
490
491 }
492
493 /**
494 * jpeg_v4_0_5_start - start JPEG block
495 *
496 * @adev: amdgpu_device pointer
497 *
498 * Setup and start the JPEG block
499 */
jpeg_v4_0_5_start(struct amdgpu_device * adev)500 static int jpeg_v4_0_5_start(struct amdgpu_device *adev)
501 {
502 struct amdgpu_ring *ring;
503 int r, i;
504
505 if (adev->pm.dpm_enabled)
506 amdgpu_dpm_enable_jpeg(adev, true);
507
508 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
509 if (adev->jpeg.harvest_config & (1 << i))
510 continue;
511
512 ring = adev->jpeg.inst[i].ring_dec;
513 /* doorbell programming is done for every playback */
514 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
515 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 8 * i, i);
516
517 WREG32_SOC15(VCN, i, regVCN_JPEG_DB_CTRL,
518 ring->doorbell_index << VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
519 VCN_JPEG_DB_CTRL__EN_MASK);
520
521 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
522 jpeg_v4_0_5_start_dpg_mode(adev, i, adev->jpeg.indirect_sram);
523 continue;
524 }
525
526 /* disable power gating */
527 r = jpeg_v4_0_5_disable_static_power_gating(adev, i);
528 if (r)
529 return r;
530
531 /* JPEG disable CGC */
532 jpeg_v4_0_5_disable_clock_gating(adev, i);
533
534 /* MJPEG global tiling registers */
535 WREG32_SOC15(JPEG, i, regJPEG_DEC_GFX10_ADDR_CONFIG,
536 adev->gfx.config.gb_addr_config);
537
538 /* enable JMI channel */
539 WREG32_P(SOC15_REG_OFFSET(JPEG, i, regUVD_JMI_CNTL), 0,
540 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
541
542 /* enable System Interrupt for JRBC */
543 WREG32_P(SOC15_REG_OFFSET(JPEG, i, regJPEG_SYS_INT_EN),
544 JPEG_SYS_INT_EN__DJRBC_MASK,
545 ~JPEG_SYS_INT_EN__DJRBC_MASK);
546
547 WREG32_SOC15(JPEG, i, regUVD_LMI_JRBC_RB_VMID, 0);
548 WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
549 WREG32_SOC15(JPEG, i, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
550 lower_32_bits(ring->gpu_addr));
551 WREG32_SOC15(JPEG, i, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
552 upper_32_bits(ring->gpu_addr));
553 WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_RPTR, 0);
554 WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_WPTR, 0);
555 WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_CNTL, 0x00000002L);
556 WREG32_SOC15(JPEG, i, regUVD_JRBC_RB_SIZE, ring->ring_size / 4);
557 ring->wptr = RREG32_SOC15(JPEG, i, regUVD_JRBC_RB_WPTR);
558 }
559
560 return 0;
561 }
562
563 /**
564 * jpeg_v4_0_5_stop - stop JPEG block
565 *
566 * @adev: amdgpu_device pointer
567 *
568 * stop the JPEG block
569 */
jpeg_v4_0_5_stop(struct amdgpu_device * adev)570 static int jpeg_v4_0_5_stop(struct amdgpu_device *adev)
571 {
572 int r, i;
573
574 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
575 if (adev->jpeg.harvest_config & (1 << i))
576 continue;
577
578 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
579 jpeg_v4_0_5_stop_dpg_mode(adev, i);
580 continue;
581 }
582
583 /* reset JMI */
584 WREG32_P(SOC15_REG_OFFSET(JPEG, i, regUVD_JMI_CNTL),
585 UVD_JMI_CNTL__SOFT_RESET_MASK,
586 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
587
588 jpeg_v4_0_5_enable_clock_gating(adev, i);
589
590 /* enable power gating */
591 r = jpeg_v4_0_5_enable_static_power_gating(adev, i);
592 if (r)
593 return r;
594 }
595 if (adev->pm.dpm_enabled)
596 amdgpu_dpm_enable_jpeg(adev, false);
597
598 return 0;
599 }
600
601 /**
602 * jpeg_v4_0_5_dec_ring_get_rptr - get read pointer
603 *
604 * @ring: amdgpu_ring pointer
605 *
606 * Returns the current hardware read pointer
607 */
jpeg_v4_0_5_dec_ring_get_rptr(struct amdgpu_ring * ring)608 static uint64_t jpeg_v4_0_5_dec_ring_get_rptr(struct amdgpu_ring *ring)
609 {
610 struct amdgpu_device *adev = ring->adev;
611
612 return RREG32_SOC15(JPEG, ring->me, regUVD_JRBC_RB_RPTR);
613 }
614
615 /**
616 * jpeg_v4_0_5_dec_ring_get_wptr - get write pointer
617 *
618 * @ring: amdgpu_ring pointer
619 *
620 * Returns the current hardware write pointer
621 */
jpeg_v4_0_5_dec_ring_get_wptr(struct amdgpu_ring * ring)622 static uint64_t jpeg_v4_0_5_dec_ring_get_wptr(struct amdgpu_ring *ring)
623 {
624 struct amdgpu_device *adev = ring->adev;
625
626 if (ring->use_doorbell)
627 return *ring->wptr_cpu_addr;
628 else
629 return RREG32_SOC15(JPEG, ring->me, regUVD_JRBC_RB_WPTR);
630 }
631
632 /**
633 * jpeg_v4_0_5_dec_ring_set_wptr - set write pointer
634 *
635 * @ring: amdgpu_ring pointer
636 *
637 * Commits the write pointer to the hardware
638 */
jpeg_v4_0_5_dec_ring_set_wptr(struct amdgpu_ring * ring)639 static void jpeg_v4_0_5_dec_ring_set_wptr(struct amdgpu_ring *ring)
640 {
641 struct amdgpu_device *adev = ring->adev;
642
643 if (ring->use_doorbell) {
644 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
645 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
646 } else {
647 WREG32_SOC15(JPEG, ring->me, regUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
648 }
649 }
650
jpeg_v4_0_5_is_idle(struct amdgpu_ip_block * ip_block)651 static bool jpeg_v4_0_5_is_idle(struct amdgpu_ip_block *ip_block)
652 {
653 struct amdgpu_device *adev = ip_block->adev;
654 int i, ret = 1;
655
656 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
657 if (adev->jpeg.harvest_config & (1 << i))
658 continue;
659
660 ret &= (((RREG32_SOC15(JPEG, i, regUVD_JRBC_STATUS) &
661 UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
662 UVD_JRBC_STATUS__RB_JOB_DONE_MASK));
663 }
664 return ret;
665 }
666
jpeg_v4_0_5_wait_for_idle(struct amdgpu_ip_block * ip_block)667 static int jpeg_v4_0_5_wait_for_idle(struct amdgpu_ip_block *ip_block)
668 {
669 struct amdgpu_device *adev = ip_block->adev;
670 int i;
671
672 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
673 if (adev->jpeg.harvest_config & (1 << i))
674 continue;
675
676 return SOC15_WAIT_ON_RREG(JPEG, i, regUVD_JRBC_STATUS,
677 UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
678 UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
679 }
680
681 return 0;
682 }
683
jpeg_v4_0_5_set_clockgating_state(struct amdgpu_ip_block * ip_block,enum amd_clockgating_state state)684 static int jpeg_v4_0_5_set_clockgating_state(struct amdgpu_ip_block *ip_block,
685 enum amd_clockgating_state state)
686 {
687 struct amdgpu_device *adev = ip_block->adev;
688 bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
689 int i;
690
691 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
692 if (adev->jpeg.harvest_config & (1 << i))
693 continue;
694
695 if (enable) {
696 if (!jpeg_v4_0_5_is_idle(ip_block))
697 return -EBUSY;
698
699 jpeg_v4_0_5_enable_clock_gating(adev, i);
700 } else {
701 jpeg_v4_0_5_disable_clock_gating(adev, i);
702 }
703 }
704
705 return 0;
706 }
707
jpeg_v4_0_5_set_powergating_state(struct amdgpu_ip_block * ip_block,enum amd_powergating_state state)708 static int jpeg_v4_0_5_set_powergating_state(struct amdgpu_ip_block *ip_block,
709 enum amd_powergating_state state)
710 {
711 struct amdgpu_device *adev = ip_block->adev;
712 int ret;
713
714 if (amdgpu_sriov_vf(adev)) {
715 adev->jpeg.cur_state = AMD_PG_STATE_UNGATE;
716 return 0;
717 }
718
719 if (state == adev->jpeg.cur_state)
720 return 0;
721
722 if (state == AMD_PG_STATE_GATE)
723 ret = jpeg_v4_0_5_stop(adev);
724 else
725 ret = jpeg_v4_0_5_start(adev);
726
727 if (!ret)
728 adev->jpeg.cur_state = state;
729
730 return ret;
731 }
732
jpeg_v4_0_5_process_interrupt(struct amdgpu_device * adev,struct amdgpu_irq_src * source,struct amdgpu_iv_entry * entry)733 static int jpeg_v4_0_5_process_interrupt(struct amdgpu_device *adev,
734 struct amdgpu_irq_src *source,
735 struct amdgpu_iv_entry *entry)
736 {
737 uint32_t ip_instance;
738
739 DRM_DEBUG("IH: JPEG TRAP\n");
740
741 switch (entry->client_id) {
742 case SOC15_IH_CLIENTID_VCN:
743 ip_instance = 0;
744 break;
745 case SOC15_IH_CLIENTID_VCN1:
746 ip_instance = 1;
747 break;
748 default:
749 DRM_ERROR("Unhandled client id: %d\n", entry->client_id);
750 return 0;
751 }
752
753 switch (entry->src_id) {
754 case VCN_4_0__SRCID__JPEG_DECODE:
755 amdgpu_fence_process(adev->jpeg.inst[ip_instance].ring_dec);
756 break;
757 case VCN_4_0__SRCID_DJPEG0_POISON:
758 case VCN_4_0__SRCID_EJPEG0_POISON:
759 amdgpu_jpeg_process_poison_irq(adev, source, entry);
760 break;
761 default:
762 DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n",
763 entry->src_id, entry->src_data[0]);
764 break;
765 }
766
767 return 0;
768 }
769
770 static const struct amd_ip_funcs jpeg_v4_0_5_ip_funcs = {
771 .name = "jpeg_v4_0_5",
772 .early_init = jpeg_v4_0_5_early_init,
773 .sw_init = jpeg_v4_0_5_sw_init,
774 .sw_fini = jpeg_v4_0_5_sw_fini,
775 .hw_init = jpeg_v4_0_5_hw_init,
776 .hw_fini = jpeg_v4_0_5_hw_fini,
777 .suspend = jpeg_v4_0_5_suspend,
778 .resume = jpeg_v4_0_5_resume,
779 .is_idle = jpeg_v4_0_5_is_idle,
780 .wait_for_idle = jpeg_v4_0_5_wait_for_idle,
781 .set_clockgating_state = jpeg_v4_0_5_set_clockgating_state,
782 .set_powergating_state = jpeg_v4_0_5_set_powergating_state,
783 .dump_ip_state = amdgpu_jpeg_dump_ip_state,
784 .print_ip_state = amdgpu_jpeg_print_ip_state,
785 };
786
787 static const struct amdgpu_ring_funcs jpeg_v4_0_5_dec_ring_vm_funcs = {
788 .type = AMDGPU_RING_TYPE_VCN_JPEG,
789 .align_mask = 0xf,
790 .get_rptr = jpeg_v4_0_5_dec_ring_get_rptr,
791 .get_wptr = jpeg_v4_0_5_dec_ring_get_wptr,
792 .set_wptr = jpeg_v4_0_5_dec_ring_set_wptr,
793 .parse_cs = jpeg_v2_dec_ring_parse_cs,
794 .emit_frame_size =
795 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
796 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
797 8 + /* jpeg_v4_0_5_dec_ring_emit_vm_flush */
798 18 + 18 + /* jpeg_v4_0_5_dec_ring_emit_fence x2 vm fence */
799 8 + 16,
800 .emit_ib_size = 22, /* jpeg_v4_0_5_dec_ring_emit_ib */
801 .emit_ib = jpeg_v2_0_dec_ring_emit_ib,
802 .emit_fence = jpeg_v2_0_dec_ring_emit_fence,
803 .emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush,
804 .test_ring = amdgpu_jpeg_dec_ring_test_ring,
805 .test_ib = amdgpu_jpeg_dec_ring_test_ib,
806 .insert_nop = jpeg_v2_0_dec_ring_nop,
807 .insert_start = jpeg_v2_0_dec_ring_insert_start,
808 .insert_end = jpeg_v2_0_dec_ring_insert_end,
809 .pad_ib = amdgpu_ring_generic_pad_ib,
810 .begin_use = amdgpu_jpeg_ring_begin_use,
811 .end_use = amdgpu_jpeg_ring_end_use,
812 .emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
813 .emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
814 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
815 };
816
jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device * adev)817 static void jpeg_v4_0_5_set_dec_ring_funcs(struct amdgpu_device *adev)
818 {
819 int i;
820
821 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
822 if (adev->jpeg.harvest_config & (1 << i))
823 continue;
824
825 adev->jpeg.inst[i].ring_dec->funcs = &jpeg_v4_0_5_dec_ring_vm_funcs;
826 adev->jpeg.inst[i].ring_dec->me = i;
827 }
828 }
829
830 static const struct amdgpu_irq_src_funcs jpeg_v4_0_5_irq_funcs = {
831 .process = jpeg_v4_0_5_process_interrupt,
832 };
833
jpeg_v4_0_5_set_irq_funcs(struct amdgpu_device * adev)834 static void jpeg_v4_0_5_set_irq_funcs(struct amdgpu_device *adev)
835 {
836 int i;
837
838 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
839 if (adev->jpeg.harvest_config & (1 << i))
840 continue;
841
842 adev->jpeg.inst[i].irq.num_types = 1;
843 adev->jpeg.inst[i].irq.funcs = &jpeg_v4_0_5_irq_funcs;
844 }
845 }
846
847 const struct amdgpu_ip_block_version jpeg_v4_0_5_ip_block = {
848 .type = AMD_IP_BLOCK_TYPE_JPEG,
849 .major = 4,
850 .minor = 0,
851 .rev = 5,
852 .funcs = &jpeg_v4_0_5_ip_funcs,
853 };
854
855