]> Git Repo - linux.git/blob - drivers/gpu/drm/amd/amdgpu/jpeg_v5_0_1.c
Linux 6.14-rc3
[linux.git] / drivers / gpu / drm / amd / amdgpu / jpeg_v5_0_1.c
1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /*
3  * Copyright 2014-2024 Advanced Micro Devices, Inc. All rights reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21  * OTHER DEALINGS IN THE SOFTWARE.
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_v4_0_3.h"
30 #include "jpeg_v5_0_1.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
36 static void jpeg_v5_0_1_set_dec_ring_funcs(struct amdgpu_device *adev);
37 static void jpeg_v5_0_1_set_irq_funcs(struct amdgpu_device *adev);
38 static int jpeg_v5_0_1_set_powergating_state(struct amdgpu_ip_block *ip_block,
39                                              enum amd_powergating_state state);
40 static void jpeg_v5_0_1_dec_ring_set_wptr(struct amdgpu_ring *ring);
41
42 static int amdgpu_ih_srcid_jpeg[] = {
43         VCN_5_0__SRCID__JPEG_DECODE,
44         VCN_5_0__SRCID__JPEG1_DECODE,
45         VCN_5_0__SRCID__JPEG2_DECODE,
46         VCN_5_0__SRCID__JPEG3_DECODE,
47         VCN_5_0__SRCID__JPEG4_DECODE,
48         VCN_5_0__SRCID__JPEG5_DECODE,
49         VCN_5_0__SRCID__JPEG6_DECODE,
50         VCN_5_0__SRCID__JPEG7_DECODE,
51         VCN_5_0__SRCID__JPEG8_DECODE,
52         VCN_5_0__SRCID__JPEG9_DECODE,
53 };
54
55 static int jpeg_v5_0_1_core_reg_offset(u32 pipe)
56 {
57         if (pipe <= AMDGPU_MAX_JPEG_RINGS_4_0_3)
58                 return ((0x40 * pipe) - 0xc80);
59         else
60                 return ((0x40 * pipe) - 0x440);
61 }
62
63 /**
64  * jpeg_v5_0_1_early_init - set function pointers
65  *
66  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
67  *
68  * Set ring and irq function pointers
69  */
70 static int jpeg_v5_0_1_early_init(struct amdgpu_ip_block *ip_block)
71 {
72         struct amdgpu_device *adev = ip_block->adev;
73
74         if (!adev->jpeg.num_jpeg_inst || adev->jpeg.num_jpeg_inst > AMDGPU_MAX_JPEG_INSTANCES)
75                 return -ENOENT;
76
77         adev->jpeg.num_jpeg_rings = AMDGPU_MAX_JPEG_RINGS;
78         jpeg_v5_0_1_set_dec_ring_funcs(adev);
79         jpeg_v5_0_1_set_irq_funcs(adev);
80
81         return 0;
82 }
83
84 /**
85  * jpeg_v5_0_1_sw_init - sw init for JPEG block
86  *
87  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
88  *
89  * Load firmware and sw initialization
90  */
91 static int jpeg_v5_0_1_sw_init(struct amdgpu_ip_block *ip_block)
92 {
93         struct amdgpu_device *adev = ip_block->adev;
94         struct amdgpu_ring *ring;
95         int i, j, r, jpeg_inst;
96
97         for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
98                 /* JPEG TRAP */
99                 r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
100                                       amdgpu_ih_srcid_jpeg[j], &adev->jpeg.inst->irq);
101                 if (r)
102                         return r;
103         }
104
105         r = amdgpu_jpeg_sw_init(adev);
106         if (r)
107                 return r;
108
109         r = amdgpu_jpeg_resume(adev);
110         if (r)
111                 return r;
112
113         for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
114                 jpeg_inst = GET_INST(JPEG, i);
115
116                 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
117                         ring = &adev->jpeg.inst[i].ring_dec[j];
118                         ring->use_doorbell = false;
119                         ring->vm_hub = AMDGPU_MMHUB0(adev->jpeg.inst[i].aid_id);
120                         if (!amdgpu_sriov_vf(adev)) {
121                                 ring->doorbell_index =
122                                         (adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
123                                         1 + j + 11 * jpeg_inst;
124                         } else {
125                                 if (j < 4)
126                                         ring->doorbell_index =
127                                                 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
128                                                 4 + j + 32 * jpeg_inst;
129                                 else
130                                         ring->doorbell_index =
131                                                 (adev->doorbell_index.vcn.vcn_ring0_1 << 1) +
132                                                 8 + j + 32 * jpeg_inst;
133                         }
134                         sprintf(ring->name, "jpeg_dec_%d.%d", adev->jpeg.inst[i].aid_id, j);
135                         r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0,
136                                              AMDGPU_RING_PRIO_DEFAULT, NULL);
137                         if (r)
138                                 return r;
139
140                         adev->jpeg.internal.jpeg_pitch[j] =
141                                 regUVD_JRBC0_UVD_JRBC_SCRATCH0_INTERNAL_OFFSET;
142                         adev->jpeg.inst[i].external.jpeg_pitch[j] =
143                                 SOC15_REG_OFFSET1(JPEG, jpeg_inst, regUVD_JRBC_SCRATCH0,
144                                                   (j ? jpeg_v5_0_1_core_reg_offset(j) : 0));
145                 }
146         }
147
148         return 0;
149 }
150
151 /**
152  * jpeg_v5_0_1_sw_fini - sw fini for JPEG block
153  *
154  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
155  *
156  * JPEG suspend and free up sw allocation
157  */
158 static int jpeg_v5_0_1_sw_fini(struct amdgpu_ip_block *ip_block)
159 {
160         struct amdgpu_device *adev = ip_block->adev;
161         int r;
162
163         r = amdgpu_jpeg_suspend(adev);
164         if (r)
165                 return r;
166
167         r = amdgpu_jpeg_sw_fini(adev);
168
169         return r;
170 }
171
172 /**
173  * jpeg_v5_0_1_hw_init - start and test JPEG block
174  *
175  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
176  *
177  */
178 static int jpeg_v5_0_1_hw_init(struct amdgpu_ip_block *ip_block)
179 {
180         struct amdgpu_device *adev = ip_block->adev;
181         struct amdgpu_ring *ring;
182         int i, j, r, jpeg_inst;
183
184         if (amdgpu_sriov_vf(adev)) {
185                 /* jpeg_v5_0_1_start_sriov(adev); */
186                 for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
187                         for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
188                                 ring = &adev->jpeg.inst[i].ring_dec[j];
189                                 ring->wptr = 0;
190                                 ring->wptr_old = 0;
191                                 jpeg_v5_0_1_dec_ring_set_wptr(ring);
192                                 ring->sched.ready = true;
193                         }
194                 }
195                 return 0;
196         }
197         for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
198                 jpeg_inst = GET_INST(JPEG, i);
199                 ring = adev->jpeg.inst[i].ring_dec;
200                 if (ring->use_doorbell)
201                         adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
202                                  (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 11 * jpeg_inst,
203                                  adev->jpeg.inst[i].aid_id);
204
205                 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
206                         ring = &adev->jpeg.inst[i].ring_dec[j];
207                         if (ring->use_doorbell)
208                                 WREG32_SOC15_OFFSET(VCN, GET_INST(VCN, i), regVCN_JPEG_DB_CTRL,
209                                                     (ring->pipe ? (ring->pipe - 0x15) : 0),
210                                                     ring->doorbell_index <<
211                                                     VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
212                                                     VCN_JPEG_DB_CTRL__EN_MASK);
213                         r = amdgpu_ring_test_helper(ring);
214                         if (r)
215                                 return r;
216                 }
217         }
218
219         return 0;
220 }
221
222 /**
223  * jpeg_v5_0_1_hw_fini - stop the hardware block
224  *
225  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
226  *
227  * Stop the JPEG block, mark ring as not ready any more
228  */
229 static int jpeg_v5_0_1_hw_fini(struct amdgpu_ip_block *ip_block)
230 {
231         struct amdgpu_device *adev = ip_block->adev;
232         int ret = 0;
233
234         cancel_delayed_work_sync(&adev->jpeg.idle_work);
235
236         if (adev->jpeg.cur_state != AMD_PG_STATE_GATE)
237                 ret = jpeg_v5_0_1_set_powergating_state(ip_block, AMD_PG_STATE_GATE);
238
239         return ret;
240 }
241
242 /**
243  * jpeg_v5_0_1_suspend - suspend JPEG block
244  *
245  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
246  *
247  * HW fini and suspend JPEG block
248  */
249 static int jpeg_v5_0_1_suspend(struct amdgpu_ip_block *ip_block)
250 {
251         struct amdgpu_device *adev = ip_block->adev;
252         int r;
253
254         r = jpeg_v5_0_1_hw_fini(ip_block);
255         if (r)
256                 return r;
257
258         r = amdgpu_jpeg_suspend(adev);
259
260         return r;
261 }
262
263 /**
264  * jpeg_v5_0_1_resume - resume JPEG block
265  *
266  * @ip_block: Pointer to the amdgpu_ip_block for this hw instance.
267  *
268  * Resume firmware and hw init JPEG block
269  */
270 static int jpeg_v5_0_1_resume(struct amdgpu_ip_block *ip_block)
271 {
272         struct amdgpu_device *adev = ip_block->adev;
273         int r;
274
275         r = amdgpu_jpeg_resume(adev);
276         if (r)
277                 return r;
278
279         r = jpeg_v5_0_1_hw_init(ip_block);
280
281         return r;
282 }
283
284 static int jpeg_v5_0_1_disable_antihang(struct amdgpu_device *adev, int inst_idx)
285 {
286         int jpeg_inst;
287
288         jpeg_inst = GET_INST(JPEG, inst_idx);
289         /* disable anti hang mechanism */
290         WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS), 0,
291                  ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
292
293         /* keep the JPEG in static PG mode */
294         WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS), 0,
295                  ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK);
296
297         return 0;
298 }
299
300 static int jpeg_v5_0_1_enable_antihang(struct amdgpu_device *adev, int inst_idx)
301 {
302         int jpeg_inst;
303
304         jpeg_inst = GET_INST(JPEG, inst_idx);
305         /* enable anti hang mechanism */
306         WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JPEG_POWER_STATUS),
307                  UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
308                 ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
309
310         return 0;
311 }
312
313 /**
314  * jpeg_v5_0_1_start - start JPEG block
315  *
316  * @adev: amdgpu_device pointer
317  *
318  * Setup and start the JPEG block
319  */
320 static int jpeg_v5_0_1_start(struct amdgpu_device *adev)
321 {
322         struct amdgpu_ring *ring;
323         int i, j, jpeg_inst, r;
324
325         for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
326                 jpeg_inst = GET_INST(JPEG, i);
327
328                 /* disable antihang */
329                 r = jpeg_v5_0_1_disable_antihang(adev, i);
330                 if (r)
331                         return r;
332
333                 /* MJPEG global tiling registers */
334                 WREG32_SOC15(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG,
335                              adev->gfx.config.gb_addr_config);
336
337                 /* enable JMI channel */
338                 WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL), 0,
339                          ~UVD_JMI_CNTL__SOFT_RESET_MASK);
340
341                 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
342                         int reg_offset = (j ? jpeg_v5_0_1_core_reg_offset(j) : 0);
343                         u32 reg, data, mask;
344
345                         ring = &adev->jpeg.inst[i].ring_dec[j];
346
347                         /* enable System Interrupt for JRBC */
348                         reg = SOC15_REG_OFFSET(JPEG, jpeg_inst, regJPEG_SYS_INT_EN);
349                         if (j < AMDGPU_MAX_JPEG_RINGS_4_0_3) {
350                                 data = JPEG_SYS_INT_EN__DJRBC0_MASK << j;
351                                 mask = ~(JPEG_SYS_INT_EN__DJRBC0_MASK << j);
352                                 WREG32_P(reg, data, mask);
353                         } else {
354                                 data = JPEG_SYS_INT_EN__DJRBC0_MASK << (j+12);
355                                 mask = ~(JPEG_SYS_INT_EN__DJRBC0_MASK << (j+12));
356                                 WREG32_P(reg, data, mask);
357                         }
358
359                         WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
360                                             regUVD_LMI_JRBC_RB_VMID,
361                                             reg_offset, 0);
362                         WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
363                                             regUVD_JRBC_RB_CNTL,
364                                             reg_offset,
365                                             (0x00000001L | 0x00000002L));
366                         WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
367                                             regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
368                                             reg_offset, lower_32_bits(ring->gpu_addr));
369                         WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
370                                             regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
371                                             reg_offset, upper_32_bits(ring->gpu_addr));
372                         WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
373                                             regUVD_JRBC_RB_RPTR,
374                                             reg_offset, 0);
375                         WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
376                                             regUVD_JRBC_RB_WPTR,
377                                             reg_offset, 0);
378                         WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
379                                             regUVD_JRBC_RB_CNTL,
380                                             reg_offset, 0x00000002L);
381                         WREG32_SOC15_OFFSET(JPEG, jpeg_inst,
382                                             regUVD_JRBC_RB_SIZE,
383                                             reg_offset, ring->ring_size / 4);
384                         ring->wptr = RREG32_SOC15_OFFSET(JPEG, jpeg_inst, regUVD_JRBC_RB_WPTR,
385                                                          reg_offset);
386                 }
387         }
388
389         return 0;
390 }
391
392 /**
393  * jpeg_v5_0_1_stop - stop JPEG block
394  *
395  * @adev: amdgpu_device pointer
396  *
397  * stop the JPEG block
398  */
399 static int jpeg_v5_0_1_stop(struct amdgpu_device *adev)
400 {
401         int i, jpeg_inst, r;
402
403         for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
404                 jpeg_inst = GET_INST(JPEG, i);
405                 /* reset JMI */
406                 WREG32_P(SOC15_REG_OFFSET(JPEG, jpeg_inst, regUVD_JMI_CNTL),
407                          UVD_JMI_CNTL__SOFT_RESET_MASK,
408                          ~UVD_JMI_CNTL__SOFT_RESET_MASK);
409
410                 /* enable antihang */
411                 r = jpeg_v5_0_1_enable_antihang(adev, i);
412                 if (r)
413                         return r;
414         }
415
416         return 0;
417 }
418
419 /**
420  * jpeg_v5_0_1_dec_ring_get_rptr - get read pointer
421  *
422  * @ring: amdgpu_ring pointer
423  *
424  * Returns the current hardware read pointer
425  */
426 static uint64_t jpeg_v5_0_1_dec_ring_get_rptr(struct amdgpu_ring *ring)
427 {
428         struct amdgpu_device *adev = ring->adev;
429
430         return RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC_RB_RPTR,
431                                    ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0);
432 }
433
434 /**
435  * jpeg_v5_0_1_dec_ring_get_wptr - get write pointer
436  *
437  * @ring: amdgpu_ring pointer
438  *
439  * Returns the current hardware write pointer
440  */
441 static uint64_t jpeg_v5_0_1_dec_ring_get_wptr(struct amdgpu_ring *ring)
442 {
443         struct amdgpu_device *adev = ring->adev;
444
445         if (ring->use_doorbell)
446                 return adev->wb.wb[ring->wptr_offs];
447
448         return RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me), regUVD_JRBC_RB_WPTR,
449                                    ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0);
450 }
451
452 /**
453  * jpeg_v5_0_1_dec_ring_set_wptr - set write pointer
454  *
455  * @ring: amdgpu_ring pointer
456  *
457  * Commits the write pointer to the hardware
458  */
459 static void jpeg_v5_0_1_dec_ring_set_wptr(struct amdgpu_ring *ring)
460 {
461         struct amdgpu_device *adev = ring->adev;
462
463         if (ring->use_doorbell) {
464                 adev->wb.wb[ring->wptr_offs] = lower_32_bits(ring->wptr);
465                 WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
466         } else {
467                 WREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, ring->me),
468                                     regUVD_JRBC_RB_WPTR,
469                                     (ring->pipe ? jpeg_v5_0_1_core_reg_offset(ring->pipe) : 0),
470                                     lower_32_bits(ring->wptr));
471         }
472 }
473
474 static bool jpeg_v5_0_1_is_idle(void *handle)
475 {
476         struct amdgpu_device *adev = (struct amdgpu_device *)handle;
477         bool ret = false;
478         int i, j;
479
480         for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
481                 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
482                         int reg_offset = (j ? jpeg_v5_0_1_core_reg_offset(j) : 0);
483
484                         ret &= ((RREG32_SOC15_OFFSET(JPEG, GET_INST(JPEG, i),
485                                 regUVD_JRBC_STATUS, reg_offset) &
486                                 UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
487                                 UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
488                 }
489         }
490
491         return ret;
492 }
493
494 static int jpeg_v5_0_1_wait_for_idle(struct amdgpu_ip_block *ip_block)
495 {
496         struct amdgpu_device *adev = ip_block->adev;
497         int ret = 0;
498         int i, j;
499
500         for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
501                 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
502                         int reg_offset = (j ? jpeg_v5_0_1_core_reg_offset(j) : 0);
503
504                         ret &= SOC15_WAIT_ON_RREG_OFFSET(JPEG, GET_INST(JPEG, i),
505                                                          regUVD_JRBC_STATUS, reg_offset,
506                                                          UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
507                                                          UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
508                 }
509         }
510         return ret;
511 }
512
513 static int jpeg_v5_0_1_set_clockgating_state(struct amdgpu_ip_block *ip_block,
514                                              enum amd_clockgating_state state)
515 {
516         struct amdgpu_device *adev = ip_block->adev;
517         bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
518
519         int i;
520
521         if (!enable)
522                 return 0;
523
524         for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
525                 if (!jpeg_v5_0_1_is_idle(adev))
526                         return -EBUSY;
527         }
528
529         return 0;
530 }
531
532 static int jpeg_v5_0_1_set_powergating_state(struct amdgpu_ip_block *ip_block,
533                                              enum amd_powergating_state state)
534 {
535         struct amdgpu_device *adev = ip_block->adev;
536         int ret;
537
538         if (state == adev->jpeg.cur_state)
539                 return 0;
540
541         if (state == AMD_PG_STATE_GATE)
542                 ret = jpeg_v5_0_1_stop(adev);
543         else
544                 ret = jpeg_v5_0_1_start(adev);
545
546         if (!ret)
547                 adev->jpeg.cur_state = state;
548
549         return ret;
550 }
551
552 static int jpeg_v5_0_1_set_interrupt_state(struct amdgpu_device *adev,
553                                            struct amdgpu_irq_src *source,
554                                            unsigned int type,
555                                            enum amdgpu_interrupt_state state)
556 {
557         return 0;
558 }
559
560 static int jpeg_v5_0_1_process_interrupt(struct amdgpu_device *adev,
561                                          struct amdgpu_irq_src *source,
562                                          struct amdgpu_iv_entry *entry)
563 {
564         u32 i, inst;
565
566         i = node_id_to_phys_map[entry->node_id];
567         DRM_DEV_DEBUG(adev->dev, "IH: JPEG TRAP\n");
568
569         for (inst = 0; inst < adev->jpeg.num_jpeg_inst; ++inst)
570                 if (adev->jpeg.inst[inst].aid_id == i)
571                         break;
572
573         if (inst >= adev->jpeg.num_jpeg_inst) {
574                 dev_WARN_ONCE(adev->dev, 1,
575                               "Interrupt received for unknown JPEG instance %d",
576                               entry->node_id);
577                 return 0;
578         }
579
580         switch (entry->src_id) {
581         case VCN_5_0__SRCID__JPEG_DECODE:
582                 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[0]);
583                 break;
584         case VCN_5_0__SRCID__JPEG1_DECODE:
585                 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[1]);
586                 break;
587         case VCN_5_0__SRCID__JPEG2_DECODE:
588                 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[2]);
589                 break;
590         case VCN_5_0__SRCID__JPEG3_DECODE:
591                 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[3]);
592                 break;
593         case VCN_5_0__SRCID__JPEG4_DECODE:
594                 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[4]);
595                 break;
596         case VCN_5_0__SRCID__JPEG5_DECODE:
597                 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[5]);
598                 break;
599         case VCN_5_0__SRCID__JPEG6_DECODE:
600                 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[6]);
601                 break;
602         case VCN_5_0__SRCID__JPEG7_DECODE:
603                 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[7]);
604                 break;
605         case VCN_5_0__SRCID__JPEG8_DECODE:
606                 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[8]);
607                 break;
608         case VCN_5_0__SRCID__JPEG9_DECODE:
609                 amdgpu_fence_process(&adev->jpeg.inst[inst].ring_dec[9]);
610                 break;
611         default:
612                 DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n",
613                               entry->src_id, entry->src_data[0]);
614                 break;
615         }
616
617         return 0;
618 }
619
620 static const struct amd_ip_funcs jpeg_v5_0_1_ip_funcs = {
621         .name = "jpeg_v5_0_1",
622         .early_init = jpeg_v5_0_1_early_init,
623         .late_init = NULL,
624         .sw_init = jpeg_v5_0_1_sw_init,
625         .sw_fini = jpeg_v5_0_1_sw_fini,
626         .hw_init = jpeg_v5_0_1_hw_init,
627         .hw_fini = jpeg_v5_0_1_hw_fini,
628         .suspend = jpeg_v5_0_1_suspend,
629         .resume = jpeg_v5_0_1_resume,
630         .is_idle = jpeg_v5_0_1_is_idle,
631         .wait_for_idle = jpeg_v5_0_1_wait_for_idle,
632         .check_soft_reset = NULL,
633         .pre_soft_reset = NULL,
634         .soft_reset = NULL,
635         .post_soft_reset = NULL,
636         .set_clockgating_state = jpeg_v5_0_1_set_clockgating_state,
637         .set_powergating_state = jpeg_v5_0_1_set_powergating_state,
638         .dump_ip_state = NULL,
639         .print_ip_state = NULL,
640 };
641
642 static const struct amdgpu_ring_funcs jpeg_v5_0_1_dec_ring_vm_funcs = {
643         .type = AMDGPU_RING_TYPE_VCN_JPEG,
644         .align_mask = 0xf,
645         .get_rptr = jpeg_v5_0_1_dec_ring_get_rptr,
646         .get_wptr = jpeg_v5_0_1_dec_ring_get_wptr,
647         .set_wptr = jpeg_v5_0_1_dec_ring_set_wptr,
648         .emit_frame_size =
649                 SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
650                 SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
651                 8 + /* jpeg_v5_0_1_dec_ring_emit_vm_flush */
652                 22 + 22 + /* jpeg_v5_0_1_dec_ring_emit_fence x2 vm fence */
653                 8 + 16,
654         .emit_ib_size = 22, /* jpeg_v5_0_1_dec_ring_emit_ib */
655         .emit_ib = jpeg_v4_0_3_dec_ring_emit_ib,
656         .emit_fence = jpeg_v4_0_3_dec_ring_emit_fence,
657         .emit_vm_flush = jpeg_v4_0_3_dec_ring_emit_vm_flush,
658         .test_ring = amdgpu_jpeg_dec_ring_test_ring,
659         .test_ib = amdgpu_jpeg_dec_ring_test_ib,
660         .insert_nop = jpeg_v4_0_3_dec_ring_nop,
661         .insert_start = jpeg_v4_0_3_dec_ring_insert_start,
662         .insert_end = jpeg_v4_0_3_dec_ring_insert_end,
663         .pad_ib = amdgpu_ring_generic_pad_ib,
664         .begin_use = amdgpu_jpeg_ring_begin_use,
665         .end_use = amdgpu_jpeg_ring_end_use,
666         .emit_wreg = jpeg_v4_0_3_dec_ring_emit_wreg,
667         .emit_reg_wait = jpeg_v4_0_3_dec_ring_emit_reg_wait,
668         .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
669 };
670
671 static void jpeg_v5_0_1_set_dec_ring_funcs(struct amdgpu_device *adev)
672 {
673         int i, j, jpeg_inst;
674
675         for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
676                 for (j = 0; j < adev->jpeg.num_jpeg_rings; ++j) {
677                         adev->jpeg.inst[i].ring_dec[j].funcs = &jpeg_v5_0_1_dec_ring_vm_funcs;
678                         adev->jpeg.inst[i].ring_dec[j].me = i;
679                         adev->jpeg.inst[i].ring_dec[j].pipe = j;
680                 }
681                 jpeg_inst = GET_INST(JPEG, i);
682                 adev->jpeg.inst[i].aid_id =
683                         jpeg_inst / adev->jpeg.num_inst_per_aid;
684         }
685 }
686
687 static const struct amdgpu_irq_src_funcs jpeg_v5_0_1_irq_funcs = {
688         .set = jpeg_v5_0_1_set_interrupt_state,
689         .process = jpeg_v5_0_1_process_interrupt,
690 };
691
692 static void jpeg_v5_0_1_set_irq_funcs(struct amdgpu_device *adev)
693 {
694         int i;
695
696         for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i)
697                 adev->jpeg.inst->irq.num_types += adev->jpeg.num_jpeg_rings;
698
699         adev->jpeg.inst->irq.funcs = &jpeg_v5_0_1_irq_funcs;
700 }
701
702 const struct amdgpu_ip_block_version jpeg_v5_0_1_ip_block = {
703         .type = AMD_IP_BLOCK_TYPE_JPEG,
704         .major = 5,
705         .minor = 0,
706         .rev = 1,
707         .funcs = &jpeg_v5_0_1_ip_funcs,
708 };
This page took 0.10802 seconds and 4 git commands to generate.