Line data Source code
1 : /*
2 : * Copyright 2021 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 :
31 : #include "vcn/vcn_4_0_0_offset.h"
32 : #include "vcn/vcn_4_0_0_sh_mask.h"
33 : #include "ivsrcid/vcn/irqsrcs_vcn_4_0.h"
34 :
35 : #define regUVD_JPEG_PITCH_INTERNAL_OFFSET 0x401f
36 :
37 : static void jpeg_v4_0_set_dec_ring_funcs(struct amdgpu_device *adev);
38 : static void jpeg_v4_0_set_irq_funcs(struct amdgpu_device *adev);
39 : static int jpeg_v4_0_set_powergating_state(void *handle,
40 : enum amd_powergating_state state);
41 :
42 : /**
43 : * jpeg_v4_0_early_init - set function pointers
44 : *
45 : * @handle: amdgpu_device pointer
46 : *
47 : * Set ring and irq function pointers
48 : */
49 0 : static int jpeg_v4_0_early_init(void *handle)
50 : {
51 0 : struct amdgpu_device *adev = (struct amdgpu_device *)handle;
52 :
53 :
54 0 : adev->jpeg.num_jpeg_inst = 1;
55 :
56 0 : jpeg_v4_0_set_dec_ring_funcs(adev);
57 0 : jpeg_v4_0_set_irq_funcs(adev);
58 :
59 0 : return 0;
60 : }
61 :
62 : /**
63 : * jpeg_v4_0_sw_init - sw init for JPEG block
64 : *
65 : * @handle: amdgpu_device pointer
66 : *
67 : * Load firmware and sw initialization
68 : */
69 0 : static int jpeg_v4_0_sw_init(void *handle)
70 : {
71 0 : struct amdgpu_device *adev = (struct amdgpu_device *)handle;
72 : struct amdgpu_ring *ring;
73 : int r;
74 :
75 : /* JPEG TRAP */
76 0 : r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
77 : VCN_4_0__SRCID__JPEG_DECODE, &adev->jpeg.inst->irq);
78 0 : if (r)
79 : return r;
80 :
81 0 : r = amdgpu_jpeg_sw_init(adev);
82 0 : if (r)
83 : return r;
84 :
85 0 : r = amdgpu_jpeg_resume(adev);
86 0 : if (r)
87 : return r;
88 :
89 0 : ring = &adev->jpeg.inst->ring_dec;
90 0 : ring->use_doorbell = true;
91 0 : ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1;
92 0 : sprintf(ring->name, "jpeg_dec");
93 0 : r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0,
94 : AMDGPU_RING_PRIO_DEFAULT, NULL);
95 0 : if (r)
96 : return r;
97 :
98 0 : adev->jpeg.internal.jpeg_pitch = regUVD_JPEG_PITCH_INTERNAL_OFFSET;
99 0 : adev->jpeg.inst->external.jpeg_pitch = SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_PITCH);
100 :
101 0 : return 0;
102 : }
103 :
104 : /**
105 : * jpeg_v4_0_sw_fini - sw fini for JPEG block
106 : *
107 : * @handle: amdgpu_device pointer
108 : *
109 : * JPEG suspend and free up sw allocation
110 : */
111 0 : static int jpeg_v4_0_sw_fini(void *handle)
112 : {
113 0 : struct amdgpu_device *adev = (struct amdgpu_device *)handle;
114 : int r;
115 :
116 0 : r = amdgpu_jpeg_suspend(adev);
117 0 : if (r)
118 : return r;
119 :
120 0 : r = amdgpu_jpeg_sw_fini(adev);
121 :
122 0 : return r;
123 : }
124 :
125 : /**
126 : * jpeg_v4_0_hw_init - start and test JPEG block
127 : *
128 : * @handle: amdgpu_device pointer
129 : *
130 : */
131 0 : static int jpeg_v4_0_hw_init(void *handle)
132 : {
133 0 : struct amdgpu_device *adev = (struct amdgpu_device *)handle;
134 0 : struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
135 : int r;
136 :
137 0 : adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
138 0 : (adev->doorbell_index.vcn.vcn_ring0_1 << 1), 0);
139 :
140 0 : WREG32_SOC15(VCN, 0, regVCN_JPEG_DB_CTRL,
141 : ring->doorbell_index << VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
142 : VCN_JPEG_DB_CTRL__EN_MASK);
143 :
144 0 : r = amdgpu_ring_test_helper(ring);
145 0 : if (r)
146 : return r;
147 :
148 0 : DRM_DEV_INFO(adev->dev, "JPEG decode initialized successfully.\n");
149 :
150 0 : return 0;
151 : }
152 :
153 : /**
154 : * jpeg_v4_0_hw_fini - stop the hardware block
155 : *
156 : * @handle: amdgpu_device pointer
157 : *
158 : * Stop the JPEG block, mark ring as not ready any more
159 : */
160 0 : static int jpeg_v4_0_hw_fini(void *handle)
161 : {
162 0 : struct amdgpu_device *adev = (struct amdgpu_device *)handle;
163 :
164 0 : cancel_delayed_work_sync(&adev->vcn.idle_work);
165 :
166 0 : if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
167 0 : RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS))
168 0 : jpeg_v4_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
169 :
170 0 : return 0;
171 : }
172 :
173 : /**
174 : * jpeg_v4_0_suspend - suspend JPEG block
175 : *
176 : * @handle: amdgpu_device pointer
177 : *
178 : * HW fini and suspend JPEG block
179 : */
180 0 : static int jpeg_v4_0_suspend(void *handle)
181 : {
182 0 : struct amdgpu_device *adev = (struct amdgpu_device *)handle;
183 : int r;
184 :
185 0 : r = jpeg_v4_0_hw_fini(adev);
186 0 : if (r)
187 : return r;
188 :
189 0 : r = amdgpu_jpeg_suspend(adev);
190 :
191 0 : return r;
192 : }
193 :
194 : /**
195 : * jpeg_v4_0_resume - resume JPEG block
196 : *
197 : * @handle: amdgpu_device pointer
198 : *
199 : * Resume firmware and hw init JPEG block
200 : */
201 0 : static int jpeg_v4_0_resume(void *handle)
202 : {
203 0 : struct amdgpu_device *adev = (struct amdgpu_device *)handle;
204 : int r;
205 :
206 0 : r = amdgpu_jpeg_resume(adev);
207 0 : if (r)
208 : return r;
209 :
210 0 : r = jpeg_v4_0_hw_init(adev);
211 :
212 0 : return r;
213 : }
214 :
215 0 : static void jpeg_v4_0_disable_clock_gating(struct amdgpu_device *adev)
216 : {
217 0 : uint32_t data = 0;
218 :
219 0 : data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL);
220 0 : if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) {
221 0 : data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
222 0 : data &= (~JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK);
223 : } else {
224 : data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
225 : }
226 :
227 0 : data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
228 0 : data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
229 0 : WREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL, data);
230 :
231 0 : data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE);
232 0 : data &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK
233 : | JPEG_CGC_GATE__JPEG2_DEC_MASK
234 : | JPEG_CGC_GATE__JMCIF_MASK
235 : | JPEG_CGC_GATE__JRBBM_MASK);
236 0 : WREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE, data);
237 0 : }
238 :
239 0 : static void jpeg_v4_0_enable_clock_gating(struct amdgpu_device *adev)
240 : {
241 0 : uint32_t data = 0;
242 :
243 0 : data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL);
244 0 : if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) {
245 0 : data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
246 0 : data |= JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK;
247 : } else {
248 : data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
249 : }
250 :
251 0 : data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
252 0 : data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
253 0 : WREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL, data);
254 :
255 0 : data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE);
256 0 : data |= (JPEG_CGC_GATE__JPEG_DEC_MASK
257 : |JPEG_CGC_GATE__JPEG2_DEC_MASK
258 : |JPEG_CGC_GATE__JMCIF_MASK
259 : |JPEG_CGC_GATE__JRBBM_MASK);
260 0 : WREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE, data);
261 0 : }
262 :
263 0 : static int jpeg_v4_0_disable_static_power_gating(struct amdgpu_device *adev)
264 : {
265 0 : if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
266 0 : uint32_t data = 0;
267 0 : int r = 0;
268 :
269 0 : data = 1 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT;
270 0 : WREG32(SOC15_REG_OFFSET(JPEG, 0, regUVD_PGFSM_CONFIG), data);
271 :
272 0 : r = SOC15_WAIT_ON_RREG(JPEG, 0,
273 : regUVD_PGFSM_STATUS, UVD_PGFSM_STATUS_UVDJ_PWR_ON,
274 : UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK);
275 :
276 0 : if (r) {
277 0 : DRM_DEV_ERROR(adev->dev, "amdgpu: JPEG disable power gating failed\n");
278 0 : return r;
279 : }
280 : }
281 :
282 : /* disable anti hang mechanism */
283 0 : WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_POWER_STATUS), 0,
284 : ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
285 :
286 : /* keep the JPEG in static PG mode */
287 0 : WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_POWER_STATUS), 0,
288 : ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK);
289 :
290 0 : return 0;
291 : }
292 :
293 0 : static int jpeg_v4_0_enable_static_power_gating(struct amdgpu_device *adev)
294 : {
295 : /* enable anti hang mechanism */
296 0 : WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_POWER_STATUS),
297 : UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
298 : ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
299 :
300 0 : if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
301 0 : uint32_t data = 0;
302 0 : int r = 0;
303 :
304 0 : data = 2 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT;
305 0 : WREG32(SOC15_REG_OFFSET(JPEG, 0, regUVD_PGFSM_CONFIG), data);
306 :
307 0 : r = SOC15_WAIT_ON_RREG(JPEG, 0, regUVD_PGFSM_STATUS,
308 : (2 << UVD_PGFSM_STATUS__UVDJ_PWR_STATUS__SHIFT),
309 : UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK);
310 :
311 0 : if (r) {
312 0 : DRM_DEV_ERROR(adev->dev, "amdgpu: JPEG enable power gating failed\n");
313 0 : return r;
314 : }
315 : }
316 :
317 : return 0;
318 : }
319 :
320 : /**
321 : * jpeg_v4_0_start - start JPEG block
322 : *
323 : * @adev: amdgpu_device pointer
324 : *
325 : * Setup and start the JPEG block
326 : */
327 0 : static int jpeg_v4_0_start(struct amdgpu_device *adev)
328 : {
329 0 : struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
330 : int r;
331 :
332 0 : if (adev->pm.dpm_enabled)
333 0 : amdgpu_dpm_enable_jpeg(adev, true);
334 :
335 : /* disable power gating */
336 0 : r = jpeg_v4_0_disable_static_power_gating(adev);
337 0 : if (r)
338 : return r;
339 :
340 : /* JPEG disable CGC */
341 0 : jpeg_v4_0_disable_clock_gating(adev);
342 :
343 : /* MJPEG global tiling registers */
344 0 : WREG32_SOC15(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG,
345 : adev->gfx.config.gb_addr_config);
346 :
347 :
348 : /* enable JMI channel */
349 0 : WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI_CNTL), 0,
350 : ~UVD_JMI_CNTL__SOFT_RESET_MASK);
351 :
352 : /* enable System Interrupt for JRBC */
353 0 : WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regJPEG_SYS_INT_EN),
354 : JPEG_SYS_INT_EN__DJRBC_MASK,
355 : ~JPEG_SYS_INT_EN__DJRBC_MASK);
356 :
357 0 : WREG32_SOC15(JPEG, 0, regUVD_LMI_JRBC_RB_VMID, 0);
358 0 : WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
359 0 : WREG32_SOC15(JPEG, 0, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
360 : lower_32_bits(ring->gpu_addr));
361 0 : WREG32_SOC15(JPEG, 0, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
362 : upper_32_bits(ring->gpu_addr));
363 0 : WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_RPTR, 0);
364 0 : WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR, 0);
365 0 : WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_CNTL, 0x00000002L);
366 0 : WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_SIZE, ring->ring_size / 4);
367 0 : ring->wptr = RREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR);
368 :
369 0 : return 0;
370 : }
371 :
372 : /**
373 : * jpeg_v4_0_stop - stop JPEG block
374 : *
375 : * @adev: amdgpu_device pointer
376 : *
377 : * stop the JPEG block
378 : */
379 0 : static int jpeg_v4_0_stop(struct amdgpu_device *adev)
380 : {
381 : int r;
382 :
383 : /* reset JMI */
384 0 : WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI_CNTL),
385 : UVD_JMI_CNTL__SOFT_RESET_MASK,
386 : ~UVD_JMI_CNTL__SOFT_RESET_MASK);
387 :
388 0 : jpeg_v4_0_enable_clock_gating(adev);
389 :
390 : /* enable power gating */
391 0 : r = jpeg_v4_0_enable_static_power_gating(adev);
392 0 : if (r)
393 : return r;
394 :
395 0 : if (adev->pm.dpm_enabled)
396 0 : amdgpu_dpm_enable_jpeg(adev, false);
397 :
398 : return 0;
399 : }
400 :
401 : /**
402 : * jpeg_v4_0_dec_ring_get_rptr - get read pointer
403 : *
404 : * @ring: amdgpu_ring pointer
405 : *
406 : * Returns the current hardware read pointer
407 : */
408 0 : static uint64_t jpeg_v4_0_dec_ring_get_rptr(struct amdgpu_ring *ring)
409 : {
410 0 : struct amdgpu_device *adev = ring->adev;
411 :
412 0 : return RREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_RPTR);
413 : }
414 :
415 : /**
416 : * jpeg_v4_0_dec_ring_get_wptr - get write pointer
417 : *
418 : * @ring: amdgpu_ring pointer
419 : *
420 : * Returns the current hardware write pointer
421 : */
422 0 : static uint64_t jpeg_v4_0_dec_ring_get_wptr(struct amdgpu_ring *ring)
423 : {
424 0 : struct amdgpu_device *adev = ring->adev;
425 :
426 0 : if (ring->use_doorbell)
427 0 : return *ring->wptr_cpu_addr;
428 : else
429 0 : return RREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR);
430 : }
431 :
432 : /**
433 : * jpeg_v4_0_dec_ring_set_wptr - set write pointer
434 : *
435 : * @ring: amdgpu_ring pointer
436 : *
437 : * Commits the write pointer to the hardware
438 : */
439 0 : static void jpeg_v4_0_dec_ring_set_wptr(struct amdgpu_ring *ring)
440 : {
441 0 : struct amdgpu_device *adev = ring->adev;
442 :
443 0 : if (ring->use_doorbell) {
444 0 : *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
445 0 : WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
446 : } else {
447 0 : WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
448 : }
449 0 : }
450 :
451 0 : static bool jpeg_v4_0_is_idle(void *handle)
452 : {
453 0 : struct amdgpu_device *adev = (struct amdgpu_device *)handle;
454 0 : int ret = 1;
455 :
456 0 : ret &= (((RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS) &
457 0 : UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
458 : UVD_JRBC_STATUS__RB_JOB_DONE_MASK));
459 :
460 0 : return ret;
461 : }
462 :
463 0 : static int jpeg_v4_0_wait_for_idle(void *handle)
464 : {
465 0 : struct amdgpu_device *adev = (struct amdgpu_device *)handle;
466 :
467 0 : return SOC15_WAIT_ON_RREG(JPEG, 0, regUVD_JRBC_STATUS,
468 : UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
469 : UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
470 : }
471 :
472 0 : static int jpeg_v4_0_set_clockgating_state(void *handle,
473 : enum amd_clockgating_state state)
474 : {
475 0 : struct amdgpu_device *adev = (struct amdgpu_device *)handle;
476 0 : bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
477 :
478 0 : if (enable) {
479 0 : if (!jpeg_v4_0_is_idle(handle))
480 : return -EBUSY;
481 0 : jpeg_v4_0_enable_clock_gating(adev);
482 : } else {
483 0 : jpeg_v4_0_disable_clock_gating(adev);
484 : }
485 :
486 : return 0;
487 : }
488 :
489 0 : static int jpeg_v4_0_set_powergating_state(void *handle,
490 : enum amd_powergating_state state)
491 : {
492 0 : struct amdgpu_device *adev = (struct amdgpu_device *)handle;
493 : int ret;
494 :
495 0 : if (state == adev->jpeg.cur_state)
496 : return 0;
497 :
498 0 : if (state == AMD_PG_STATE_GATE)
499 0 : ret = jpeg_v4_0_stop(adev);
500 : else
501 0 : ret = jpeg_v4_0_start(adev);
502 :
503 0 : if (!ret)
504 0 : adev->jpeg.cur_state = state;
505 :
506 : return ret;
507 : }
508 :
509 0 : static int jpeg_v4_0_set_interrupt_state(struct amdgpu_device *adev,
510 : struct amdgpu_irq_src *source,
511 : unsigned type,
512 : enum amdgpu_interrupt_state state)
513 : {
514 0 : return 0;
515 : }
516 :
517 0 : static int jpeg_v4_0_process_interrupt(struct amdgpu_device *adev,
518 : struct amdgpu_irq_src *source,
519 : struct amdgpu_iv_entry *entry)
520 : {
521 0 : DRM_DEBUG("IH: JPEG TRAP\n");
522 :
523 0 : switch (entry->src_id) {
524 : case VCN_4_0__SRCID__JPEG_DECODE:
525 0 : amdgpu_fence_process(&adev->jpeg.inst->ring_dec);
526 0 : break;
527 : default:
528 0 : DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n",
529 : entry->src_id, entry->src_data[0]);
530 0 : break;
531 : }
532 :
533 0 : return 0;
534 : }
535 :
536 : static const struct amd_ip_funcs jpeg_v4_0_ip_funcs = {
537 : .name = "jpeg_v4_0",
538 : .early_init = jpeg_v4_0_early_init,
539 : .late_init = NULL,
540 : .sw_init = jpeg_v4_0_sw_init,
541 : .sw_fini = jpeg_v4_0_sw_fini,
542 : .hw_init = jpeg_v4_0_hw_init,
543 : .hw_fini = jpeg_v4_0_hw_fini,
544 : .suspend = jpeg_v4_0_suspend,
545 : .resume = jpeg_v4_0_resume,
546 : .is_idle = jpeg_v4_0_is_idle,
547 : .wait_for_idle = jpeg_v4_0_wait_for_idle,
548 : .check_soft_reset = NULL,
549 : .pre_soft_reset = NULL,
550 : .soft_reset = NULL,
551 : .post_soft_reset = NULL,
552 : .set_clockgating_state = jpeg_v4_0_set_clockgating_state,
553 : .set_powergating_state = jpeg_v4_0_set_powergating_state,
554 : };
555 :
556 : static const struct amdgpu_ring_funcs jpeg_v4_0_dec_ring_vm_funcs = {
557 : .type = AMDGPU_RING_TYPE_VCN_JPEG,
558 : .align_mask = 0xf,
559 : .vmhub = AMDGPU_MMHUB_0,
560 : .get_rptr = jpeg_v4_0_dec_ring_get_rptr,
561 : .get_wptr = jpeg_v4_0_dec_ring_get_wptr,
562 : .set_wptr = jpeg_v4_0_dec_ring_set_wptr,
563 : .emit_frame_size =
564 : SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
565 : SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
566 : 8 + /* jpeg_v4_0_dec_ring_emit_vm_flush */
567 : 18 + 18 + /* jpeg_v4_0_dec_ring_emit_fence x2 vm fence */
568 : 8 + 16,
569 : .emit_ib_size = 22, /* jpeg_v4_0_dec_ring_emit_ib */
570 : .emit_ib = jpeg_v2_0_dec_ring_emit_ib,
571 : .emit_fence = jpeg_v2_0_dec_ring_emit_fence,
572 : .emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush,
573 : .test_ring = amdgpu_jpeg_dec_ring_test_ring,
574 : .test_ib = amdgpu_jpeg_dec_ring_test_ib,
575 : .insert_nop = jpeg_v2_0_dec_ring_nop,
576 : .insert_start = jpeg_v2_0_dec_ring_insert_start,
577 : .insert_end = jpeg_v2_0_dec_ring_insert_end,
578 : .pad_ib = amdgpu_ring_generic_pad_ib,
579 : .begin_use = amdgpu_jpeg_ring_begin_use,
580 : .end_use = amdgpu_jpeg_ring_end_use,
581 : .emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
582 : .emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
583 : .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
584 : };
585 :
586 : static void jpeg_v4_0_set_dec_ring_funcs(struct amdgpu_device *adev)
587 : {
588 0 : adev->jpeg.inst->ring_dec.funcs = &jpeg_v4_0_dec_ring_vm_funcs;
589 0 : DRM_DEV_INFO(adev->dev, "JPEG decode is enabled in VM mode\n");
590 : }
591 :
592 : static const struct amdgpu_irq_src_funcs jpeg_v4_0_irq_funcs = {
593 : .set = jpeg_v4_0_set_interrupt_state,
594 : .process = jpeg_v4_0_process_interrupt,
595 : };
596 :
597 : static void jpeg_v4_0_set_irq_funcs(struct amdgpu_device *adev)
598 : {
599 0 : adev->jpeg.inst->irq.num_types = 1;
600 0 : adev->jpeg.inst->irq.funcs = &jpeg_v4_0_irq_funcs;
601 : }
602 :
603 : const struct amdgpu_ip_block_version jpeg_v4_0_ip_block = {
604 : .type = AMD_IP_BLOCK_TYPE_JPEG,
605 : .major = 4,
606 : .minor = 0,
607 : .rev = 0,
608 : .funcs = &jpeg_v4_0_ip_funcs,
609 : };
|