Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2019 Advanced Micro Devices, Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  *
0022  */
0023 
0024 #include "amdgpu.h"
0025 #include "amdgpu_jpeg.h"
0026 #include "amdgpu_pm.h"
0027 #include "soc15.h"
0028 #include "soc15d.h"
0029 #include "jpeg_v2_0.h"
0030 
0031 #include "vcn/vcn_3_0_0_offset.h"
0032 #include "vcn/vcn_3_0_0_sh_mask.h"
0033 #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h"
0034 
0035 #define mmUVD_JPEG_PITCH_INTERNAL_OFFSET    0x401f
0036 
0037 static void jpeg_v3_0_set_dec_ring_funcs(struct amdgpu_device *adev);
0038 static void jpeg_v3_0_set_irq_funcs(struct amdgpu_device *adev);
0039 static int jpeg_v3_0_set_powergating_state(void *handle,
0040                 enum amd_powergating_state state);
0041 
0042 /**
0043  * jpeg_v3_0_early_init - set function pointers
0044  *
0045  * @handle: amdgpu_device pointer
0046  *
0047  * Set ring and irq function pointers
0048  */
0049 static int jpeg_v3_0_early_init(void *handle)
0050 {
0051     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0052 
0053     u32 harvest;
0054 
0055     switch (adev->ip_versions[UVD_HWIP][0]) {
0056     case IP_VERSION(3, 1, 1):
0057         break;
0058     default:
0059         harvest = RREG32_SOC15(JPEG, 0, mmCC_UVD_HARVESTING);
0060         if (harvest & CC_UVD_HARVESTING__UVD_DISABLE_MASK)
0061             return -ENOENT;
0062         break;
0063     }
0064 
0065     adev->jpeg.num_jpeg_inst = 1;
0066 
0067     jpeg_v3_0_set_dec_ring_funcs(adev);
0068     jpeg_v3_0_set_irq_funcs(adev);
0069 
0070     return 0;
0071 }
0072 
0073 /**
0074  * jpeg_v3_0_sw_init - sw init for JPEG block
0075  *
0076  * @handle: amdgpu_device pointer
0077  *
0078  * Load firmware and sw initialization
0079  */
0080 static int jpeg_v3_0_sw_init(void *handle)
0081 {
0082     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0083     struct amdgpu_ring *ring;
0084     int r;
0085 
0086     /* JPEG TRAP */
0087     r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
0088         VCN_2_0__SRCID__JPEG_DECODE, &adev->jpeg.inst->irq);
0089     if (r)
0090         return r;
0091 
0092     r = amdgpu_jpeg_sw_init(adev);
0093     if (r)
0094         return r;
0095 
0096     r = amdgpu_jpeg_resume(adev);
0097     if (r)
0098         return r;
0099 
0100     ring = &adev->jpeg.inst->ring_dec;
0101     ring->use_doorbell = true;
0102     ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1;
0103     sprintf(ring->name, "jpeg_dec");
0104     r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0,
0105                  AMDGPU_RING_PRIO_DEFAULT, NULL);
0106     if (r)
0107         return r;
0108 
0109     adev->jpeg.internal.jpeg_pitch = mmUVD_JPEG_PITCH_INTERNAL_OFFSET;
0110     adev->jpeg.inst->external.jpeg_pitch = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_PITCH);
0111 
0112     return 0;
0113 }
0114 
0115 /**
0116  * jpeg_v3_0_sw_fini - sw fini for JPEG block
0117  *
0118  * @handle: amdgpu_device pointer
0119  *
0120  * JPEG suspend and free up sw allocation
0121  */
0122 static int jpeg_v3_0_sw_fini(void *handle)
0123 {
0124     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0125     int r;
0126 
0127     r = amdgpu_jpeg_suspend(adev);
0128     if (r)
0129         return r;
0130 
0131     r = amdgpu_jpeg_sw_fini(adev);
0132 
0133     return r;
0134 }
0135 
0136 /**
0137  * jpeg_v3_0_hw_init - start and test JPEG block
0138  *
0139  * @handle: amdgpu_device pointer
0140  *
0141  */
0142 static int jpeg_v3_0_hw_init(void *handle)
0143 {
0144     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0145     struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
0146     int r;
0147 
0148     adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
0149         (adev->doorbell_index.vcn.vcn_ring0_1 << 1), 0);
0150 
0151     r = amdgpu_ring_test_helper(ring);
0152     if (r)
0153         return r;
0154 
0155     DRM_INFO("JPEG decode initialized successfully.\n");
0156 
0157     return 0;
0158 }
0159 
0160 /**
0161  * jpeg_v3_0_hw_fini - stop the hardware block
0162  *
0163  * @handle: amdgpu_device pointer
0164  *
0165  * Stop the JPEG block, mark ring as not ready any more
0166  */
0167 static int jpeg_v3_0_hw_fini(void *handle)
0168 {
0169     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0170 
0171     cancel_delayed_work_sync(&adev->vcn.idle_work);
0172 
0173     if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
0174           RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS))
0175         jpeg_v3_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
0176 
0177     return 0;
0178 }
0179 
0180 /**
0181  * jpeg_v3_0_suspend - suspend JPEG block
0182  *
0183  * @handle: amdgpu_device pointer
0184  *
0185  * HW fini and suspend JPEG block
0186  */
0187 static int jpeg_v3_0_suspend(void *handle)
0188 {
0189     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0190     int r;
0191 
0192     r = jpeg_v3_0_hw_fini(adev);
0193     if (r)
0194         return r;
0195 
0196     r = amdgpu_jpeg_suspend(adev);
0197 
0198     return r;
0199 }
0200 
0201 /**
0202  * jpeg_v3_0_resume - resume JPEG block
0203  *
0204  * @handle: amdgpu_device pointer
0205  *
0206  * Resume firmware and hw init JPEG block
0207  */
0208 static int jpeg_v3_0_resume(void *handle)
0209 {
0210     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0211     int r;
0212 
0213     r = amdgpu_jpeg_resume(adev);
0214     if (r)
0215         return r;
0216 
0217     r = jpeg_v3_0_hw_init(adev);
0218 
0219     return r;
0220 }
0221 
0222 static void jpeg_v3_0_disable_clock_gating(struct amdgpu_device *adev)
0223 {
0224     uint32_t data = 0;
0225 
0226     data = RREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL);
0227     if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG)
0228         data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
0229     else
0230         data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
0231 
0232     data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
0233     data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
0234     WREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL, data);
0235 
0236     data = RREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE);
0237     data &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK
0238         | JPEG_CGC_GATE__JPEG2_DEC_MASK
0239         | JPEG_CGC_GATE__JPEG_ENC_MASK
0240         | JPEG_CGC_GATE__JMCIF_MASK
0241         | JPEG_CGC_GATE__JRBBM_MASK);
0242     WREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE, data);
0243 
0244     data = RREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL);
0245     data &= ~(JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK
0246         | JPEG_CGC_CTRL__JPEG2_DEC_MODE_MASK
0247         | JPEG_CGC_CTRL__JMCIF_MODE_MASK
0248         | JPEG_CGC_CTRL__JRBBM_MODE_MASK);
0249     WREG32_SOC15(JPEG, 0, mmJPEG_CGC_CTRL, data);
0250 }
0251 
0252 static void jpeg_v3_0_enable_clock_gating(struct amdgpu_device *adev)
0253 {
0254     uint32_t data = 0;
0255 
0256     data = RREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE);
0257     data |= (JPEG_CGC_GATE__JPEG_DEC_MASK
0258         |JPEG_CGC_GATE__JPEG2_DEC_MASK
0259         |JPEG_CGC_GATE__JPEG_ENC_MASK
0260         |JPEG_CGC_GATE__JMCIF_MASK
0261         |JPEG_CGC_GATE__JRBBM_MASK);
0262     WREG32_SOC15(JPEG, 0, mmJPEG_CGC_GATE, data);
0263 }
0264 
0265 static int jpeg_v3_0_disable_static_power_gating(struct amdgpu_device *adev)
0266 {
0267     if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
0268         uint32_t data = 0;
0269         int r = 0;
0270 
0271         data = 1 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT;
0272         WREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_PGFSM_CONFIG), data);
0273 
0274         r = SOC15_WAIT_ON_RREG(JPEG, 0,
0275             mmUVD_PGFSM_STATUS, UVD_PGFSM_STATUS_UVDJ_PWR_ON,
0276             UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK);
0277 
0278         if (r) {
0279             DRM_ERROR("amdgpu: JPEG disable power gating failed\n");
0280             return r;
0281         }
0282     }
0283 
0284     /* disable anti hang mechanism */
0285     WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS), 0,
0286         ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
0287 
0288     /* keep the JPEG in static PG mode */
0289     WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS), 0,
0290         ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK);
0291 
0292     return 0;
0293 }
0294 
0295 static int jpeg_v3_0_enable_static_power_gating(struct amdgpu_device *adev)
0296 {
0297     /* enable anti hang mechanism */
0298     WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_POWER_STATUS),
0299         UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
0300         ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
0301 
0302     if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
0303         uint32_t data = 0;
0304         int r = 0;
0305 
0306         data = 2 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT;
0307         WREG32(SOC15_REG_OFFSET(JPEG, 0, mmUVD_PGFSM_CONFIG), data);
0308 
0309         r = SOC15_WAIT_ON_RREG(JPEG, 0, mmUVD_PGFSM_STATUS,
0310             (2 << UVD_PGFSM_STATUS__UVDJ_PWR_STATUS__SHIFT),
0311             UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK);
0312 
0313         if (r) {
0314             DRM_ERROR("amdgpu: JPEG enable power gating failed\n");
0315             return r;
0316         }
0317     }
0318 
0319     return 0;
0320 }
0321 
0322 /**
0323  * jpeg_v3_0_start - start JPEG block
0324  *
0325  * @adev: amdgpu_device pointer
0326  *
0327  * Setup and start the JPEG block
0328  */
0329 static int jpeg_v3_0_start(struct amdgpu_device *adev)
0330 {
0331     struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
0332     int r;
0333 
0334     if (adev->pm.dpm_enabled)
0335         amdgpu_dpm_enable_jpeg(adev, true);
0336 
0337     /* disable power gating */
0338     r = jpeg_v3_0_disable_static_power_gating(adev);
0339     if (r)
0340         return r;
0341 
0342     /* JPEG disable CGC */
0343     jpeg_v3_0_disable_clock_gating(adev);
0344 
0345     /* MJPEG global tiling registers */
0346     WREG32_SOC15(JPEG, 0, mmJPEG_DEC_GFX10_ADDR_CONFIG,
0347         adev->gfx.config.gb_addr_config);
0348     WREG32_SOC15(JPEG, 0, mmJPEG_ENC_GFX10_ADDR_CONFIG,
0349         adev->gfx.config.gb_addr_config);
0350 
0351     /* enable JMI channel */
0352     WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JMI_CNTL), 0,
0353         ~UVD_JMI_CNTL__SOFT_RESET_MASK);
0354 
0355     /* enable System Interrupt for JRBC */
0356     WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmJPEG_SYS_INT_EN),
0357         JPEG_SYS_INT_EN__DJRBC_MASK,
0358         ~JPEG_SYS_INT_EN__DJRBC_MASK);
0359 
0360     WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_VMID, 0);
0361     WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
0362     WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
0363         lower_32_bits(ring->gpu_addr));
0364     WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
0365         upper_32_bits(ring->gpu_addr));
0366     WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR, 0);
0367     WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, 0);
0368     WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, 0x00000002L);
0369     WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_SIZE, ring->ring_size / 4);
0370     ring->wptr = RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR);
0371 
0372     return 0;
0373 }
0374 
0375 /**
0376  * jpeg_v3_0_stop - stop JPEG block
0377  *
0378  * @adev: amdgpu_device pointer
0379  *
0380  * stop the JPEG block
0381  */
0382 static int jpeg_v3_0_stop(struct amdgpu_device *adev)
0383 {
0384     int r;
0385 
0386     /* reset JMI */
0387     WREG32_P(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JMI_CNTL),
0388         UVD_JMI_CNTL__SOFT_RESET_MASK,
0389         ~UVD_JMI_CNTL__SOFT_RESET_MASK);
0390 
0391     jpeg_v3_0_enable_clock_gating(adev);
0392 
0393     /* enable power gating */
0394     r = jpeg_v3_0_enable_static_power_gating(adev);
0395     if (r)
0396         return r;
0397 
0398     if (adev->pm.dpm_enabled)
0399         amdgpu_dpm_enable_jpeg(adev, false);
0400 
0401     return 0;
0402 }
0403 
0404 /**
0405  * jpeg_v3_0_dec_ring_get_rptr - get read pointer
0406  *
0407  * @ring: amdgpu_ring pointer
0408  *
0409  * Returns the current hardware read pointer
0410  */
0411 static uint64_t jpeg_v3_0_dec_ring_get_rptr(struct amdgpu_ring *ring)
0412 {
0413     struct amdgpu_device *adev = ring->adev;
0414 
0415     return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR);
0416 }
0417 
0418 /**
0419  * jpeg_v3_0_dec_ring_get_wptr - get write pointer
0420  *
0421  * @ring: amdgpu_ring pointer
0422  *
0423  * Returns the current hardware write pointer
0424  */
0425 static uint64_t jpeg_v3_0_dec_ring_get_wptr(struct amdgpu_ring *ring)
0426 {
0427     struct amdgpu_device *adev = ring->adev;
0428 
0429     if (ring->use_doorbell)
0430         return *ring->wptr_cpu_addr;
0431     else
0432         return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR);
0433 }
0434 
0435 /**
0436  * jpeg_v3_0_dec_ring_set_wptr - set write pointer
0437  *
0438  * @ring: amdgpu_ring pointer
0439  *
0440  * Commits the write pointer to the hardware
0441  */
0442 static void jpeg_v3_0_dec_ring_set_wptr(struct amdgpu_ring *ring)
0443 {
0444     struct amdgpu_device *adev = ring->adev;
0445 
0446     if (ring->use_doorbell) {
0447         *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
0448         WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
0449     } else {
0450         WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
0451     }
0452 }
0453 
0454 static bool jpeg_v3_0_is_idle(void *handle)
0455 {
0456     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0457     int ret = 1;
0458 
0459     ret &= (((RREG32_SOC15(JPEG, 0, mmUVD_JRBC_STATUS) &
0460         UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
0461         UVD_JRBC_STATUS__RB_JOB_DONE_MASK));
0462 
0463     return ret;
0464 }
0465 
0466 static int jpeg_v3_0_wait_for_idle(void *handle)
0467 {
0468     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0469 
0470     return SOC15_WAIT_ON_RREG(JPEG, 0, mmUVD_JRBC_STATUS,
0471         UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
0472         UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
0473 }
0474 
0475 static int jpeg_v3_0_set_clockgating_state(void *handle,
0476                       enum amd_clockgating_state state)
0477 {
0478     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0479     bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
0480 
0481     if (enable) {
0482         if (!jpeg_v3_0_is_idle(handle))
0483             return -EBUSY;
0484         jpeg_v3_0_enable_clock_gating(adev);
0485     } else {
0486         jpeg_v3_0_disable_clock_gating(adev);
0487     }
0488 
0489     return 0;
0490 }
0491 
0492 static int jpeg_v3_0_set_powergating_state(void *handle,
0493                       enum amd_powergating_state state)
0494 {
0495     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0496     int ret;
0497 
0498     if(state == adev->jpeg.cur_state)
0499         return 0;
0500 
0501     if (state == AMD_PG_STATE_GATE)
0502         ret = jpeg_v3_0_stop(adev);
0503     else
0504         ret = jpeg_v3_0_start(adev);
0505 
0506     if(!ret)
0507         adev->jpeg.cur_state = state;
0508 
0509     return ret;
0510 }
0511 
0512 static int jpeg_v3_0_set_interrupt_state(struct amdgpu_device *adev,
0513                     struct amdgpu_irq_src *source,
0514                     unsigned type,
0515                     enum amdgpu_interrupt_state state)
0516 {
0517     return 0;
0518 }
0519 
0520 static int jpeg_v3_0_process_interrupt(struct amdgpu_device *adev,
0521                       struct amdgpu_irq_src *source,
0522                       struct amdgpu_iv_entry *entry)
0523 {
0524     DRM_DEBUG("IH: JPEG TRAP\n");
0525 
0526     switch (entry->src_id) {
0527     case VCN_2_0__SRCID__JPEG_DECODE:
0528         amdgpu_fence_process(&adev->jpeg.inst->ring_dec);
0529         break;
0530     default:
0531         DRM_ERROR("Unhandled interrupt: %d %d\n",
0532               entry->src_id, entry->src_data[0]);
0533         break;
0534     }
0535 
0536     return 0;
0537 }
0538 
0539 static const struct amd_ip_funcs jpeg_v3_0_ip_funcs = {
0540     .name = "jpeg_v3_0",
0541     .early_init = jpeg_v3_0_early_init,
0542     .late_init = NULL,
0543     .sw_init = jpeg_v3_0_sw_init,
0544     .sw_fini = jpeg_v3_0_sw_fini,
0545     .hw_init = jpeg_v3_0_hw_init,
0546     .hw_fini = jpeg_v3_0_hw_fini,
0547     .suspend = jpeg_v3_0_suspend,
0548     .resume = jpeg_v3_0_resume,
0549     .is_idle = jpeg_v3_0_is_idle,
0550     .wait_for_idle = jpeg_v3_0_wait_for_idle,
0551     .check_soft_reset = NULL,
0552     .pre_soft_reset = NULL,
0553     .soft_reset = NULL,
0554     .post_soft_reset = NULL,
0555     .set_clockgating_state = jpeg_v3_0_set_clockgating_state,
0556     .set_powergating_state = jpeg_v3_0_set_powergating_state,
0557 };
0558 
0559 static const struct amdgpu_ring_funcs jpeg_v3_0_dec_ring_vm_funcs = {
0560     .type = AMDGPU_RING_TYPE_VCN_JPEG,
0561     .align_mask = 0xf,
0562     .vmhub = AMDGPU_MMHUB_0,
0563     .get_rptr = jpeg_v3_0_dec_ring_get_rptr,
0564     .get_wptr = jpeg_v3_0_dec_ring_get_wptr,
0565     .set_wptr = jpeg_v3_0_dec_ring_set_wptr,
0566     .emit_frame_size =
0567         SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
0568         SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
0569         8 + /* jpeg_v3_0_dec_ring_emit_vm_flush */
0570         18 + 18 + /* jpeg_v3_0_dec_ring_emit_fence x2 vm fence */
0571         8 + 16,
0572     .emit_ib_size = 22, /* jpeg_v3_0_dec_ring_emit_ib */
0573     .emit_ib = jpeg_v2_0_dec_ring_emit_ib,
0574     .emit_fence = jpeg_v2_0_dec_ring_emit_fence,
0575     .emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush,
0576     .test_ring = amdgpu_jpeg_dec_ring_test_ring,
0577     .test_ib = amdgpu_jpeg_dec_ring_test_ib,
0578     .insert_nop = jpeg_v2_0_dec_ring_nop,
0579     .insert_start = jpeg_v2_0_dec_ring_insert_start,
0580     .insert_end = jpeg_v2_0_dec_ring_insert_end,
0581     .pad_ib = amdgpu_ring_generic_pad_ib,
0582     .begin_use = amdgpu_jpeg_ring_begin_use,
0583     .end_use = amdgpu_jpeg_ring_end_use,
0584     .emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
0585     .emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
0586     .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
0587 };
0588 
0589 static void jpeg_v3_0_set_dec_ring_funcs(struct amdgpu_device *adev)
0590 {
0591     adev->jpeg.inst->ring_dec.funcs = &jpeg_v3_0_dec_ring_vm_funcs;
0592     DRM_INFO("JPEG decode is enabled in VM mode\n");
0593 }
0594 
0595 static const struct amdgpu_irq_src_funcs jpeg_v3_0_irq_funcs = {
0596     .set = jpeg_v3_0_set_interrupt_state,
0597     .process = jpeg_v3_0_process_interrupt,
0598 };
0599 
0600 static void jpeg_v3_0_set_irq_funcs(struct amdgpu_device *adev)
0601 {
0602     adev->jpeg.inst->irq.num_types = 1;
0603     adev->jpeg.inst->irq.funcs = &jpeg_v3_0_irq_funcs;
0604 }
0605 
0606 const struct amdgpu_ip_block_version jpeg_v3_0_ip_block =
0607 {
0608     .type = AMD_IP_BLOCK_TYPE_JPEG,
0609     .major = 3,
0610     .minor = 0,
0611     .rev = 0,
0612     .funcs = &jpeg_v3_0_ip_funcs,
0613 };