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_3.h"
31
32 #include "vcn/vcn_5_0_0_offset.h"
33 #include "vcn/vcn_5_0_0_sh_mask.h"
34 #include "ivsrcid/vcn/irqsrcs_vcn_5_0.h"
35 #include "jpeg_v5_0_0.h"
36
37 static const struct amdgpu_hwip_reg_entry jpeg_reg_list_5_0[] = {
38 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_POWER_STATUS),
39 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_INT_STAT),
40 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_RPTR),
41 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_WPTR),
42 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_CNTL),
43 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_RB_SIZE),
44 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JRBC_STATUS),
45 SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_ADDR_MODE),
46 SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG),
47 SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_Y_GFX10_TILING_SURFACE),
48 SOC15_REG_ENTRY_STR(JPEG, 0, regJPEG_DEC_UV_GFX10_TILING_SURFACE),
49 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_PITCH),
50 SOC15_REG_ENTRY_STR(JPEG, 0, regUVD_JPEG_UV_PITCH),
51 };
52
53 static void jpeg_v5_0_0_set_dec_ring_funcs(struct amdgpu_device *adev);
54 static void jpeg_v5_0_0_set_irq_funcs(struct amdgpu_device *adev);
55 static int jpeg_v5_0_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
56 enum amd_powergating_state state);
57
58 /**
59 * jpeg_v5_0_0_early_init - set function pointers
60 *
61 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
62 *
63 * Set ring and irq function pointers
64 */
jpeg_v5_0_0_early_init(struct amdgpu_ip_block * ip_block)65 static int jpeg_v5_0_0_early_init(struct amdgpu_ip_block *ip_block)
66 {
67 struct amdgpu_device *adev = ip_block->adev;
68
69 adev->jpeg.num_jpeg_inst = 1;
70 adev->jpeg.num_jpeg_rings = 1;
71
72 jpeg_v5_0_0_set_dec_ring_funcs(adev);
73 jpeg_v5_0_0_set_irq_funcs(adev);
74
75 return 0;
76 }
77
78 /**
79 * jpeg_v5_0_0_sw_init - sw init for JPEG block
80 *
81 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
82 *
83 * Load firmware and sw initialization
84 */
jpeg_v5_0_0_sw_init(struct amdgpu_ip_block * ip_block)85 static int jpeg_v5_0_0_sw_init(struct amdgpu_ip_block *ip_block)
86 {
87 struct amdgpu_device *adev = ip_block->adev;
88 struct amdgpu_ring *ring;
89 int r;
90
91 /* JPEG TRAP */
92 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
93 VCN_5_0__SRCID__JPEG_DECODE, &adev->jpeg.inst->irq);
94 if (r)
95 return r;
96
97 r = amdgpu_jpeg_sw_init(adev);
98 if (r)
99 return r;
100
101 r = amdgpu_jpeg_resume(adev);
102 if (r)
103 return r;
104
105 ring = adev->jpeg.inst->ring_dec;
106 ring->use_doorbell = true;
107 ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1;
108 ring->vm_hub = AMDGPU_MMHUB0(0);
109
110 sprintf(ring->name, "jpeg_dec");
111 r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0,
112 AMDGPU_RING_PRIO_DEFAULT, NULL);
113 if (r)
114 return r;
115
116 adev->jpeg.internal.jpeg_pitch[0] = regUVD_JPEG_PITCH_INTERNAL_OFFSET;
117 adev->jpeg.inst->external.jpeg_pitch[0] = SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_PITCH);
118
119 r = amdgpu_jpeg_reg_dump_init(adev, jpeg_reg_list_5_0, ARRAY_SIZE(jpeg_reg_list_5_0));
120 if (r)
121 return r;
122
123 /* TODO: Add queue reset mask when FW fully supports it */
124 adev->jpeg.supported_reset =
125 amdgpu_get_soft_full_reset_mask(&adev->jpeg.inst[0].ring_dec[0]);
126 r = amdgpu_jpeg_sysfs_reset_mask_init(adev);
127 if (r)
128 return r;
129 return 0;
130 }
131
132 /**
133 * jpeg_v5_0_0_sw_fini - sw fini for JPEG block
134 *
135 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
136 *
137 * JPEG suspend and free up sw allocation
138 */
jpeg_v5_0_0_sw_fini(struct amdgpu_ip_block * ip_block)139 static int jpeg_v5_0_0_sw_fini(struct amdgpu_ip_block *ip_block)
140 {
141 struct amdgpu_device *adev = ip_block->adev;
142 int r;
143
144 r = amdgpu_jpeg_suspend(adev);
145 if (r)
146 return r;
147
148 amdgpu_jpeg_sysfs_reset_mask_fini(adev);
149 r = amdgpu_jpeg_sw_fini(adev);
150
151 return r;
152 }
153
154 /**
155 * jpeg_v5_0_0_hw_init - start and test JPEG block
156 *
157 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
158 *
159 */
jpeg_v5_0_0_hw_init(struct amdgpu_ip_block * ip_block)160 static int jpeg_v5_0_0_hw_init(struct amdgpu_ip_block *ip_block)
161 {
162 struct amdgpu_device *adev = ip_block->adev;
163 struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec;
164 int r;
165
166 adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
167 (adev->doorbell_index.vcn.vcn_ring0_1 << 1), 0);
168
169 /* Skip ring test because pause DPG is not implemented. */
170 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG)
171 return 0;
172
173 r = amdgpu_ring_test_helper(ring);
174 if (r)
175 return r;
176
177 return 0;
178 }
179
180 /**
181 * jpeg_v5_0_0_hw_fini - stop the hardware block
182 *
183 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
184 *
185 * Stop the JPEG block, mark ring as not ready any more
186 */
jpeg_v5_0_0_hw_fini(struct amdgpu_ip_block * ip_block)187 static int jpeg_v5_0_0_hw_fini(struct amdgpu_ip_block *ip_block)
188 {
189 struct amdgpu_device *adev = ip_block->adev;
190
191 cancel_delayed_work_sync(&adev->jpeg.idle_work);
192
193 if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
194 RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS))
195 jpeg_v5_0_0_set_powergating_state(ip_block, AMD_PG_STATE_GATE);
196
197 return 0;
198 }
199
200 /**
201 * jpeg_v5_0_0_suspend - suspend JPEG block
202 *
203 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
204 *
205 * HW fini and suspend JPEG block
206 */
jpeg_v5_0_0_suspend(struct amdgpu_ip_block * ip_block)207 static int jpeg_v5_0_0_suspend(struct amdgpu_ip_block *ip_block)
208 {
209 int r;
210
211 r = jpeg_v5_0_0_hw_fini(ip_block);
212 if (r)
213 return r;
214
215 r = amdgpu_jpeg_suspend(ip_block->adev);
216
217 return r;
218 }
219
220 /**
221 * jpeg_v5_0_0_resume - resume JPEG block
222 *
223 * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
224 *
225 * Resume firmware and hw init JPEG block
226 */
jpeg_v5_0_0_resume(struct amdgpu_ip_block * ip_block)227 static int jpeg_v5_0_0_resume(struct amdgpu_ip_block *ip_block)
228 {
229 int r;
230
231 r = amdgpu_jpeg_resume(ip_block->adev);
232 if (r)
233 return r;
234
235 r = jpeg_v5_0_0_hw_init(ip_block);
236
237 return r;
238 }
239
jpeg_v5_0_0_disable_clock_gating(struct amdgpu_device * adev)240 static void jpeg_v5_0_0_disable_clock_gating(struct amdgpu_device *adev)
241 {
242 uint32_t data = 0;
243
244 WREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE, data);
245
246 data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL);
247 data &= ~(JPEG_CGC_CTRL__JPEG0_DEC_MODE_MASK
248 | JPEG_CGC_CTRL__JPEG_ENC_MODE_MASK);
249 WREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL, data);
250 }
251
jpeg_v5_0_0_enable_clock_gating(struct amdgpu_device * adev)252 static void jpeg_v5_0_0_enable_clock_gating(struct amdgpu_device *adev)
253 {
254 uint32_t data = 0;
255
256 data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL);
257
258 data |= 1 << JPEG_CGC_CTRL__JPEG0_DEC_MODE__SHIFT;
259 WREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL, data);
260
261 data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE);
262 data |= (JPEG_CGC_GATE__JPEG0_DEC_MASK
263 |JPEG_CGC_GATE__JPEG_ENC_MASK
264 |JPEG_CGC_GATE__JMCIF_MASK
265 |JPEG_CGC_GATE__JRBBM_MASK);
266 WREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE, data);
267 }
268
jpeg_v5_0_0_disable_power_gating(struct amdgpu_device * adev)269 static int jpeg_v5_0_0_disable_power_gating(struct amdgpu_device *adev)
270 {
271 uint32_t data = 0;
272
273 data = 1 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT;
274 WREG32_SOC15(JPEG, 0, regUVD_IPX_DLDO_CONFIG, data);
275 SOC15_WAIT_ON_RREG(JPEG, 0, regUVD_IPX_DLDO_STATUS, 0,
276 UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK);
277
278 /* disable anti hang mechanism */
279 WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_POWER_STATUS), 0,
280 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
281
282 return 0;
283 }
284
jpeg_v5_0_0_enable_power_gating(struct amdgpu_device * adev)285 static int jpeg_v5_0_0_enable_power_gating(struct amdgpu_device *adev)
286 {
287 /* enable anti hang mechanism */
288 WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_POWER_STATUS),
289 UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
290 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
291
292 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
293 WREG32(SOC15_REG_OFFSET(JPEG, 0, regUVD_IPX_DLDO_CONFIG),
294 2 << UVD_IPX_DLDO_CONFIG__ONO1_PWR_CONFIG__SHIFT);
295 SOC15_WAIT_ON_RREG(JPEG, 0, regUVD_IPX_DLDO_STATUS,
296 1 << UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS__SHIFT,
297 UVD_IPX_DLDO_STATUS__ONO1_PWR_STATUS_MASK);
298 }
299
300 return 0;
301 }
302
jpeg_engine_5_0_0_dpg_clock_gating_mode(struct amdgpu_device * adev,int inst_idx,uint8_t indirect)303 static void jpeg_engine_5_0_0_dpg_clock_gating_mode(struct amdgpu_device *adev,
304 int inst_idx, uint8_t indirect)
305 {
306 uint32_t data = 0;
307
308 // JPEG disable CGC
309 if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG)
310 data = 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
311 else
312 data = 0 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
313
314 data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
315 data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
316
317 if (indirect) {
318 ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipJPEG_CGC_CTRL, data, indirect);
319
320 // Turn on All JPEG clocks
321 data = 0;
322 ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipJPEG_CGC_GATE, data, indirect);
323 } else {
324 WREG32_SOC24_JPEG_DPG_MODE(inst_idx, vcnipJPEG_CGC_CTRL, data, indirect);
325
326 // Turn on All JPEG clocks
327 data = 0;
328 WREG32_SOC24_JPEG_DPG_MODE(inst_idx, vcnipJPEG_CGC_GATE, data, indirect);
329 }
330 }
331
332 /**
333 * jpeg_v5_0_0_start_dpg_mode - Jpeg start with dpg mode
334 *
335 * @adev: amdgpu_device pointer
336 * @inst_idx: instance number index
337 * @indirect: indirectly write sram
338 *
339 * Start JPEG block with dpg mode
340 */
jpeg_v5_0_0_start_dpg_mode(struct amdgpu_device * adev,int inst_idx,bool indirect)341 static int jpeg_v5_0_0_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, bool indirect)
342 {
343 struct amdgpu_ring *ring = adev->jpeg.inst[inst_idx].ring_dec;
344 uint32_t reg_data = 0;
345
346 jpeg_v5_0_0_enable_power_gating(adev);
347
348 // enable dynamic power gating mode
349 reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS);
350 reg_data |= UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK;
351 WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
352
353 if (indirect)
354 adev->jpeg.inst[inst_idx].dpg_sram_curr_addr =
355 (uint32_t *)adev->jpeg.inst[inst_idx].dpg_sram_cpu_addr;
356
357 jpeg_engine_5_0_0_dpg_clock_gating_mode(adev, inst_idx, indirect);
358
359 /* MJPEG global tiling registers */
360 if (indirect)
361 ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipJPEG_DEC_GFX10_ADDR_CONFIG,
362 adev->gfx.config.gb_addr_config, indirect);
363 else
364 WREG32_SOC24_JPEG_DPG_MODE(inst_idx, vcnipJPEG_DEC_GFX10_ADDR_CONFIG,
365 adev->gfx.config.gb_addr_config, 1);
366
367 /* enable System Interrupt for JRBC */
368 if (indirect)
369 ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipJPEG_SYS_INT_EN,
370 JPEG_SYS_INT_EN__DJRBC0_MASK, indirect);
371 else
372 WREG32_SOC24_JPEG_DPG_MODE(inst_idx, vcnipJPEG_SYS_INT_EN,
373 JPEG_SYS_INT_EN__DJRBC0_MASK, 1);
374
375 if (indirect) {
376 /* add nop to workaround PSP size check */
377 ADD_SOC24_JPEG_TO_DPG_SRAM(inst_idx, vcnipUVD_NO_OP, 0, indirect);
378
379 amdgpu_jpeg_psp_update_sram(adev, inst_idx, 0);
380 }
381
382 WREG32_SOC15(VCN, 0, regVCN_JPEG_DB_CTRL,
383 ring->doorbell_index << VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
384 VCN_JPEG_DB_CTRL__EN_MASK);
385
386 WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_VMID, 0);
387 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
388 WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
389 lower_32_bits(ring->gpu_addr));
390 WREG32_SOC15(JPEG, inst_idx, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
391 upper_32_bits(ring->gpu_addr));
392 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_RPTR, 0);
393 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_WPTR, 0);
394 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_CNTL, 0x00000002L);
395 WREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_SIZE, ring->ring_size / 4);
396 ring->wptr = RREG32_SOC15(JPEG, inst_idx, regUVD_JRBC_RB_WPTR);
397
398 return 0;
399 }
400
401 /**
402 * jpeg_v5_0_0_stop_dpg_mode - Jpeg stop with dpg mode
403 *
404 * @adev: amdgpu_device pointer
405 * @inst_idx: instance number index
406 *
407 * Stop JPEG block with dpg mode
408 */
jpeg_v5_0_0_stop_dpg_mode(struct amdgpu_device * adev,int inst_idx)409 static void jpeg_v5_0_0_stop_dpg_mode(struct amdgpu_device *adev, int inst_idx)
410 {
411 uint32_t reg_data = 0;
412
413 reg_data = RREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS);
414 reg_data &= ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK;
415 WREG32_SOC15(JPEG, inst_idx, regUVD_JPEG_POWER_STATUS, reg_data);
416 }
417
418 /**
419 * jpeg_v5_0_0_start - start JPEG block
420 *
421 * @adev: amdgpu_device pointer
422 *
423 * Setup and start the JPEG block
424 */
jpeg_v5_0_0_start(struct amdgpu_device * adev)425 static int jpeg_v5_0_0_start(struct amdgpu_device *adev)
426 {
427 struct amdgpu_ring *ring = adev->jpeg.inst->ring_dec;
428 int r;
429
430 if (adev->pm.dpm_enabled)
431 amdgpu_dpm_enable_jpeg(adev, true);
432
433 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
434 r = jpeg_v5_0_0_start_dpg_mode(adev, 0, adev->jpeg.indirect_sram);
435 return r;
436 }
437
438 /* disable power gating */
439 r = jpeg_v5_0_0_disable_power_gating(adev);
440 if (r)
441 return r;
442
443 /* JPEG disable CGC */
444 jpeg_v5_0_0_disable_clock_gating(adev);
445
446 /* MJPEG global tiling registers */
447 WREG32_SOC15(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG,
448 adev->gfx.config.gb_addr_config);
449
450 /* enable JMI channel */
451 WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI_CNTL), 0,
452 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
453
454 /* enable System Interrupt for JRBC */
455 WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regJPEG_SYS_INT_EN),
456 JPEG_SYS_INT_EN__DJRBC0_MASK,
457 ~JPEG_SYS_INT_EN__DJRBC0_MASK);
458
459 WREG32_SOC15(VCN, 0, regVCN_JPEG_DB_CTRL,
460 ring->doorbell_index << VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
461 VCN_JPEG_DB_CTRL__EN_MASK);
462
463 WREG32_SOC15(JPEG, 0, regUVD_LMI_JRBC_RB_VMID, 0);
464 WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
465 WREG32_SOC15(JPEG, 0, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
466 lower_32_bits(ring->gpu_addr));
467 WREG32_SOC15(JPEG, 0, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
468 upper_32_bits(ring->gpu_addr));
469 WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_RPTR, 0);
470 WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR, 0);
471 WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_CNTL, 0x00000002L);
472 WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_SIZE, ring->ring_size / 4);
473 ring->wptr = RREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR);
474
475 return 0;
476 }
477
478 /**
479 * jpeg_v5_0_0_stop - stop JPEG block
480 *
481 * @adev: amdgpu_device pointer
482 *
483 * stop the JPEG block
484 */
jpeg_v5_0_0_stop(struct amdgpu_device * adev)485 static int jpeg_v5_0_0_stop(struct amdgpu_device *adev)
486 {
487 int r;
488
489 if (adev->pg_flags & AMD_PG_SUPPORT_JPEG_DPG) {
490 jpeg_v5_0_0_stop_dpg_mode(adev, 0);
491 } else {
492
493 /* reset JMI */
494 WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI_CNTL),
495 UVD_JMI_CNTL__SOFT_RESET_MASK,
496 ~UVD_JMI_CNTL__SOFT_RESET_MASK);
497
498 jpeg_v5_0_0_enable_clock_gating(adev);
499
500 /* enable power gating */
501 r = jpeg_v5_0_0_enable_power_gating(adev);
502 if (r)
503 return r;
504 }
505
506 if (adev->pm.dpm_enabled)
507 amdgpu_dpm_enable_jpeg(adev, false);
508
509 return 0;
510 }
511
512 /**
513 * jpeg_v5_0_0_dec_ring_get_rptr - get read pointer
514 *
515 * @ring: amdgpu_ring pointer
516 *
517 * Returns the current hardware read pointer
518 */
jpeg_v5_0_0_dec_ring_get_rptr(struct amdgpu_ring * ring)519 static uint64_t jpeg_v5_0_0_dec_ring_get_rptr(struct amdgpu_ring *ring)
520 {
521 struct amdgpu_device *adev = ring->adev;
522
523 return RREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_RPTR);
524 }
525
526 /**
527 * jpeg_v5_0_0_dec_ring_get_wptr - get write pointer
528 *
529 * @ring: amdgpu_ring pointer
530 *
531 * Returns the current hardware write pointer
532 */
jpeg_v5_0_0_dec_ring_get_wptr(struct amdgpu_ring * ring)533 static uint64_t jpeg_v5_0_0_dec_ring_get_wptr(struct amdgpu_ring *ring)
534 {
535 struct amdgpu_device *adev = ring->adev;
536
537 if (ring->use_doorbell)
538 return *ring->wptr_cpu_addr;
539 else
540 return RREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR);
541 }
542
543 /**
544 * jpeg_v5_0_0_dec_ring_set_wptr - set write pointer
545 *
546 * @ring: amdgpu_ring pointer
547 *
548 * Commits the write pointer to the hardware
549 */
jpeg_v5_0_0_dec_ring_set_wptr(struct amdgpu_ring * ring)550 static void jpeg_v5_0_0_dec_ring_set_wptr(struct amdgpu_ring *ring)
551 {
552 struct amdgpu_device *adev = ring->adev;
553
554 if (ring->use_doorbell) {
555 *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
556 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
557 } else {
558 WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
559 }
560 }
561
jpeg_v5_0_0_is_idle(struct amdgpu_ip_block * ip_block)562 static bool jpeg_v5_0_0_is_idle(struct amdgpu_ip_block *ip_block)
563 {
564 struct amdgpu_device *adev = ip_block->adev;
565 int ret = 1;
566
567 ret &= (((RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS) &
568 UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
569 UVD_JRBC_STATUS__RB_JOB_DONE_MASK));
570
571 return ret;
572 }
573
jpeg_v5_0_0_wait_for_idle(struct amdgpu_ip_block * ip_block)574 static int jpeg_v5_0_0_wait_for_idle(struct amdgpu_ip_block *ip_block)
575 {
576 struct amdgpu_device *adev = ip_block->adev;
577
578 return SOC15_WAIT_ON_RREG(JPEG, 0, regUVD_JRBC_STATUS,
579 UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
580 UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
581 }
582
jpeg_v5_0_0_set_clockgating_state(struct amdgpu_ip_block * ip_block,enum amd_clockgating_state state)583 static int jpeg_v5_0_0_set_clockgating_state(struct amdgpu_ip_block *ip_block,
584 enum amd_clockgating_state state)
585 {
586 struct amdgpu_device *adev = ip_block->adev;
587 bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
588
589 if (enable) {
590 if (!jpeg_v5_0_0_is_idle(ip_block))
591 return -EBUSY;
592 jpeg_v5_0_0_enable_clock_gating(adev);
593 } else {
594 jpeg_v5_0_0_disable_clock_gating(adev);
595 }
596
597 return 0;
598 }
599
jpeg_v5_0_0_set_powergating_state(struct amdgpu_ip_block * ip_block,enum amd_powergating_state state)600 static int jpeg_v5_0_0_set_powergating_state(struct amdgpu_ip_block *ip_block,
601 enum amd_powergating_state state)
602 {
603 struct amdgpu_device *adev = ip_block->adev;
604 int ret;
605
606 if (state == adev->jpeg.cur_state)
607 return 0;
608
609 if (state == AMD_PG_STATE_GATE)
610 ret = jpeg_v5_0_0_stop(adev);
611 else
612 ret = jpeg_v5_0_0_start(adev);
613
614 if (!ret)
615 adev->jpeg.cur_state = state;
616
617 return ret;
618 }
619
jpeg_v5_0_0_set_interrupt_state(struct amdgpu_device * adev,struct amdgpu_irq_src * source,unsigned int type,enum amdgpu_interrupt_state state)620 static int jpeg_v5_0_0_set_interrupt_state(struct amdgpu_device *adev,
621 struct amdgpu_irq_src *source,
622 unsigned int type,
623 enum amdgpu_interrupt_state state)
624 {
625 return 0;
626 }
627
jpeg_v5_0_0_process_interrupt(struct amdgpu_device * adev,struct amdgpu_irq_src * source,struct amdgpu_iv_entry * entry)628 static int jpeg_v5_0_0_process_interrupt(struct amdgpu_device *adev,
629 struct amdgpu_irq_src *source,
630 struct amdgpu_iv_entry *entry)
631 {
632 DRM_DEBUG("IH: JPEG TRAP\n");
633
634 switch (entry->src_id) {
635 case VCN_5_0__SRCID__JPEG_DECODE:
636 amdgpu_fence_process(adev->jpeg.inst->ring_dec);
637 break;
638 default:
639 DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n",
640 entry->src_id, entry->src_data[0]);
641 break;
642 }
643
644 return 0;
645 }
646
647 static const struct amd_ip_funcs jpeg_v5_0_0_ip_funcs = {
648 .name = "jpeg_v5_0_0",
649 .early_init = jpeg_v5_0_0_early_init,
650 .sw_init = jpeg_v5_0_0_sw_init,
651 .sw_fini = jpeg_v5_0_0_sw_fini,
652 .hw_init = jpeg_v5_0_0_hw_init,
653 .hw_fini = jpeg_v5_0_0_hw_fini,
654 .suspend = jpeg_v5_0_0_suspend,
655 .resume = jpeg_v5_0_0_resume,
656 .is_idle = jpeg_v5_0_0_is_idle,
657 .wait_for_idle = jpeg_v5_0_0_wait_for_idle,
658 .set_clockgating_state = jpeg_v5_0_0_set_clockgating_state,
659 .set_powergating_state = jpeg_v5_0_0_set_powergating_state,
660 .dump_ip_state = amdgpu_jpeg_dump_ip_state,
661 .print_ip_state = amdgpu_jpeg_print_ip_state,
662 };
663
664 static const struct amdgpu_ring_funcs jpeg_v5_0_0_dec_ring_vm_funcs = {
665 .type = AMDGPU_RING_TYPE_VCN_JPEG,
666 .align_mask = 0xf,
667 .get_rptr = jpeg_v5_0_0_dec_ring_get_rptr,
668 .get_wptr = jpeg_v5_0_0_dec_ring_get_wptr,
669 .set_wptr = jpeg_v5_0_0_dec_ring_set_wptr,
670 .parse_cs = jpeg_v2_dec_ring_parse_cs,
671 .emit_frame_size =
672 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
673 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
674 8 + /* jpeg_v5_0_0_dec_ring_emit_vm_flush */
675 22 + 22 + /* jpeg_v5_0_0_dec_ring_emit_fence x2 vm fence */
676 8 + 16,
677 .emit_ib_size = 22, /* jpeg_v5_0_0_dec_ring_emit_ib */
678 .emit_ib = jpeg_v4_0_3_dec_ring_emit_ib,
679 .emit_fence = jpeg_v4_0_3_dec_ring_emit_fence,
680 .emit_vm_flush = jpeg_v4_0_3_dec_ring_emit_vm_flush,
681 .test_ring = amdgpu_jpeg_dec_ring_test_ring,
682 .test_ib = amdgpu_jpeg_dec_ring_test_ib,
683 .insert_nop = jpeg_v4_0_3_dec_ring_nop,
684 .insert_start = jpeg_v4_0_3_dec_ring_insert_start,
685 .insert_end = jpeg_v4_0_3_dec_ring_insert_end,
686 .pad_ib = amdgpu_ring_generic_pad_ib,
687 .begin_use = amdgpu_jpeg_ring_begin_use,
688 .end_use = amdgpu_jpeg_ring_end_use,
689 .emit_wreg = jpeg_v4_0_3_dec_ring_emit_wreg,
690 .emit_reg_wait = jpeg_v4_0_3_dec_ring_emit_reg_wait,
691 .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
692 };
693
jpeg_v5_0_0_set_dec_ring_funcs(struct amdgpu_device * adev)694 static void jpeg_v5_0_0_set_dec_ring_funcs(struct amdgpu_device *adev)
695 {
696 adev->jpeg.inst->ring_dec->funcs = &jpeg_v5_0_0_dec_ring_vm_funcs;
697 }
698
699 static const struct amdgpu_irq_src_funcs jpeg_v5_0_0_irq_funcs = {
700 .set = jpeg_v5_0_0_set_interrupt_state,
701 .process = jpeg_v5_0_0_process_interrupt,
702 };
703
jpeg_v5_0_0_set_irq_funcs(struct amdgpu_device * adev)704 static void jpeg_v5_0_0_set_irq_funcs(struct amdgpu_device *adev)
705 {
706 adev->jpeg.inst->irq.num_types = 1;
707 adev->jpeg.inst->irq.funcs = &jpeg_v5_0_0_irq_funcs;
708 }
709
710 const struct amdgpu_ip_block_version jpeg_v5_0_0_ip_block = {
711 .type = AMD_IP_BLOCK_TYPE_JPEG,
712 .major = 5,
713 .minor = 0,
714 .rev = 0,
715 .funcs = &jpeg_v5_0_0_ip_funcs,
716 };
717