Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2021 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_4_0_0_offset.h"
0032 #include "vcn/vcn_4_0_0_sh_mask.h"
0033 #include "ivsrcid/vcn/irqsrcs_vcn_4_0.h"
0034 
0035 #define regUVD_JPEG_PITCH_INTERNAL_OFFSET                  0x401f
0036 
0037 static void jpeg_v4_0_set_dec_ring_funcs(struct amdgpu_device *adev);
0038 static void jpeg_v4_0_set_irq_funcs(struct amdgpu_device *adev);
0039 static int jpeg_v4_0_set_powergating_state(void *handle,
0040                 enum amd_powergating_state state);
0041 
0042 /**
0043  * jpeg_v4_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_v4_0_early_init(void *handle)
0050 {
0051     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0052 
0053 
0054     adev->jpeg.num_jpeg_inst = 1;
0055 
0056     jpeg_v4_0_set_dec_ring_funcs(adev);
0057     jpeg_v4_0_set_irq_funcs(adev);
0058 
0059     return 0;
0060 }
0061 
0062 /**
0063  * jpeg_v4_0_sw_init - sw init for JPEG block
0064  *
0065  * @handle: amdgpu_device pointer
0066  *
0067  * Load firmware and sw initialization
0068  */
0069 static int jpeg_v4_0_sw_init(void *handle)
0070 {
0071     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0072     struct amdgpu_ring *ring;
0073     int r;
0074 
0075     /* JPEG TRAP */
0076     r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN,
0077         VCN_4_0__SRCID__JPEG_DECODE, &adev->jpeg.inst->irq);
0078     if (r)
0079         return r;
0080 
0081     r = amdgpu_jpeg_sw_init(adev);
0082     if (r)
0083         return r;
0084 
0085     r = amdgpu_jpeg_resume(adev);
0086     if (r)
0087         return r;
0088 
0089     ring = &adev->jpeg.inst->ring_dec;
0090     ring->use_doorbell = true;
0091     ring->doorbell_index = (adev->doorbell_index.vcn.vcn_ring0_1 << 1) + 1;
0092     sprintf(ring->name, "jpeg_dec");
0093     r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq, 0,
0094                  AMDGPU_RING_PRIO_DEFAULT, NULL);
0095     if (r)
0096         return r;
0097 
0098     adev->jpeg.internal.jpeg_pitch = regUVD_JPEG_PITCH_INTERNAL_OFFSET;
0099     adev->jpeg.inst->external.jpeg_pitch = SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_PITCH);
0100 
0101     return 0;
0102 }
0103 
0104 /**
0105  * jpeg_v4_0_sw_fini - sw fini for JPEG block
0106  *
0107  * @handle: amdgpu_device pointer
0108  *
0109  * JPEG suspend and free up sw allocation
0110  */
0111 static int jpeg_v4_0_sw_fini(void *handle)
0112 {
0113     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0114     int r;
0115 
0116     r = amdgpu_jpeg_suspend(adev);
0117     if (r)
0118         return r;
0119 
0120     r = amdgpu_jpeg_sw_fini(adev);
0121 
0122     return r;
0123 }
0124 
0125 /**
0126  * jpeg_v4_0_hw_init - start and test JPEG block
0127  *
0128  * @handle: amdgpu_device pointer
0129  *
0130  */
0131 static int jpeg_v4_0_hw_init(void *handle)
0132 {
0133     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0134     struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
0135     int r;
0136 
0137     adev->nbio.funcs->vcn_doorbell_range(adev, ring->use_doorbell,
0138                     (adev->doorbell_index.vcn.vcn_ring0_1 << 1), 0);
0139 
0140     WREG32_SOC15(VCN, 0, regVCN_JPEG_DB_CTRL,
0141         ring->doorbell_index << VCN_JPEG_DB_CTRL__OFFSET__SHIFT |
0142         VCN_JPEG_DB_CTRL__EN_MASK);
0143 
0144     r = amdgpu_ring_test_helper(ring);
0145     if (r)
0146         return r;
0147 
0148     DRM_DEV_INFO(adev->dev, "JPEG decode initialized successfully.\n");
0149 
0150     return 0;
0151 }
0152 
0153 /**
0154  * jpeg_v4_0_hw_fini - stop the hardware block
0155  *
0156  * @handle: amdgpu_device pointer
0157  *
0158  * Stop the JPEG block, mark ring as not ready any more
0159  */
0160 static int jpeg_v4_0_hw_fini(void *handle)
0161 {
0162     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0163 
0164     cancel_delayed_work_sync(&adev->vcn.idle_work);
0165 
0166     if (adev->jpeg.cur_state != AMD_PG_STATE_GATE &&
0167           RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS))
0168         jpeg_v4_0_set_powergating_state(adev, AMD_PG_STATE_GATE);
0169 
0170     return 0;
0171 }
0172 
0173 /**
0174  * jpeg_v4_0_suspend - suspend JPEG block
0175  *
0176  * @handle: amdgpu_device pointer
0177  *
0178  * HW fini and suspend JPEG block
0179  */
0180 static int jpeg_v4_0_suspend(void *handle)
0181 {
0182     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0183     int r;
0184 
0185     r = jpeg_v4_0_hw_fini(adev);
0186     if (r)
0187         return r;
0188 
0189     r = amdgpu_jpeg_suspend(adev);
0190 
0191     return r;
0192 }
0193 
0194 /**
0195  * jpeg_v4_0_resume - resume JPEG block
0196  *
0197  * @handle: amdgpu_device pointer
0198  *
0199  * Resume firmware and hw init JPEG block
0200  */
0201 static int jpeg_v4_0_resume(void *handle)
0202 {
0203     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0204     int r;
0205 
0206     r = amdgpu_jpeg_resume(adev);
0207     if (r)
0208         return r;
0209 
0210     r = jpeg_v4_0_hw_init(adev);
0211 
0212     return r;
0213 }
0214 
0215 static void jpeg_v4_0_disable_clock_gating(struct amdgpu_device *adev)
0216 {
0217     uint32_t data = 0;
0218 
0219     data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL);
0220     if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) {
0221         data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
0222         data &= (~JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK);
0223     } else {
0224         data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
0225     }
0226 
0227     data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
0228     data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
0229     WREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL, data);
0230 
0231     data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE);
0232     data &= ~(JPEG_CGC_GATE__JPEG_DEC_MASK
0233         | JPEG_CGC_GATE__JPEG2_DEC_MASK
0234         | JPEG_CGC_GATE__JMCIF_MASK
0235         | JPEG_CGC_GATE__JRBBM_MASK);
0236     WREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE, data);
0237 }
0238 
0239 static void jpeg_v4_0_enable_clock_gating(struct amdgpu_device *adev)
0240 {
0241     uint32_t data = 0;
0242 
0243     data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL);
0244     if (adev->cg_flags & AMD_CG_SUPPORT_JPEG_MGCG) {
0245         data |= 1 << JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
0246         data |= JPEG_CGC_CTRL__JPEG_DEC_MODE_MASK;
0247     } else {
0248         data &= ~JPEG_CGC_CTRL__DYN_CLOCK_MODE__SHIFT;
0249     }
0250 
0251     data |= 1 << JPEG_CGC_CTRL__CLK_GATE_DLY_TIMER__SHIFT;
0252     data |= 4 << JPEG_CGC_CTRL__CLK_OFF_DELAY__SHIFT;
0253     WREG32_SOC15(JPEG, 0, regJPEG_CGC_CTRL, data);
0254 
0255     data = RREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE);
0256     data |= (JPEG_CGC_GATE__JPEG_DEC_MASK
0257         |JPEG_CGC_GATE__JPEG2_DEC_MASK
0258         |JPEG_CGC_GATE__JMCIF_MASK
0259         |JPEG_CGC_GATE__JRBBM_MASK);
0260     WREG32_SOC15(JPEG, 0, regJPEG_CGC_GATE, data);
0261 }
0262 
0263 static int jpeg_v4_0_disable_static_power_gating(struct amdgpu_device *adev)
0264 {
0265     if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
0266         uint32_t data = 0;
0267         int r = 0;
0268 
0269         data = 1 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT;
0270         WREG32(SOC15_REG_OFFSET(JPEG, 0, regUVD_PGFSM_CONFIG), data);
0271 
0272         r = SOC15_WAIT_ON_RREG(JPEG, 0,
0273             regUVD_PGFSM_STATUS, UVD_PGFSM_STATUS_UVDJ_PWR_ON,
0274             UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK);
0275 
0276         if (r) {
0277             DRM_DEV_ERROR(adev->dev, "amdgpu: JPEG disable power gating failed\n");
0278             return r;
0279         }
0280     }
0281 
0282     /* disable anti hang mechanism */
0283     WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_POWER_STATUS), 0,
0284         ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
0285 
0286     /* keep the JPEG in static PG mode */
0287     WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_POWER_STATUS), 0,
0288         ~UVD_JPEG_POWER_STATUS__JPEG_PG_MODE_MASK);
0289 
0290     return 0;
0291 }
0292 
0293 static int jpeg_v4_0_enable_static_power_gating(struct amdgpu_device *adev)
0294 {
0295     /* enable anti hang mechanism */
0296     WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JPEG_POWER_STATUS),
0297         UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK,
0298         ~UVD_JPEG_POWER_STATUS__JPEG_POWER_STATUS_MASK);
0299 
0300     if (adev->pg_flags & AMD_PG_SUPPORT_JPEG) {
0301         uint32_t data = 0;
0302         int r = 0;
0303 
0304         data = 2 << UVD_PGFSM_CONFIG__UVDJ_PWR_CONFIG__SHIFT;
0305         WREG32(SOC15_REG_OFFSET(JPEG, 0, regUVD_PGFSM_CONFIG), data);
0306 
0307         r = SOC15_WAIT_ON_RREG(JPEG, 0, regUVD_PGFSM_STATUS,
0308             (2 << UVD_PGFSM_STATUS__UVDJ_PWR_STATUS__SHIFT),
0309             UVD_PGFSM_STATUS__UVDJ_PWR_STATUS_MASK);
0310 
0311         if (r) {
0312             DRM_DEV_ERROR(adev->dev, "amdgpu: JPEG enable power gating failed\n");
0313             return r;
0314         }
0315     }
0316 
0317     return 0;
0318 }
0319 
0320 /**
0321  * jpeg_v4_0_start - start JPEG block
0322  *
0323  * @adev: amdgpu_device pointer
0324  *
0325  * Setup and start the JPEG block
0326  */
0327 static int jpeg_v4_0_start(struct amdgpu_device *adev)
0328 {
0329     struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
0330     int r;
0331 
0332     if (adev->pm.dpm_enabled)
0333         amdgpu_dpm_enable_jpeg(adev, true);
0334 
0335     /* disable power gating */
0336     r = jpeg_v4_0_disable_static_power_gating(adev);
0337     if (r)
0338         return r;
0339 
0340     /* JPEG disable CGC */
0341     jpeg_v4_0_disable_clock_gating(adev);
0342 
0343     /* MJPEG global tiling registers */
0344     WREG32_SOC15(JPEG, 0, regJPEG_DEC_GFX10_ADDR_CONFIG,
0345         adev->gfx.config.gb_addr_config);
0346 
0347 
0348     /* enable JMI channel */
0349     WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI_CNTL), 0,
0350         ~UVD_JMI_CNTL__SOFT_RESET_MASK);
0351 
0352     /* enable System Interrupt for JRBC */
0353     WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regJPEG_SYS_INT_EN),
0354         JPEG_SYS_INT_EN__DJRBC_MASK,
0355         ~JPEG_SYS_INT_EN__DJRBC_MASK);
0356 
0357     WREG32_SOC15(JPEG, 0, regUVD_LMI_JRBC_RB_VMID, 0);
0358     WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_CNTL, (0x00000001L | 0x00000002L));
0359     WREG32_SOC15(JPEG, 0, regUVD_LMI_JRBC_RB_64BIT_BAR_LOW,
0360         lower_32_bits(ring->gpu_addr));
0361     WREG32_SOC15(JPEG, 0, regUVD_LMI_JRBC_RB_64BIT_BAR_HIGH,
0362         upper_32_bits(ring->gpu_addr));
0363     WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_RPTR, 0);
0364     WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR, 0);
0365     WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_CNTL, 0x00000002L);
0366     WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_SIZE, ring->ring_size / 4);
0367     ring->wptr = RREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR);
0368 
0369     return 0;
0370 }
0371 
0372 /**
0373  * jpeg_v4_0_stop - stop JPEG block
0374  *
0375  * @adev: amdgpu_device pointer
0376  *
0377  * stop the JPEG block
0378  */
0379 static int jpeg_v4_0_stop(struct amdgpu_device *adev)
0380 {
0381     int r;
0382 
0383     /* reset JMI */
0384     WREG32_P(SOC15_REG_OFFSET(JPEG, 0, regUVD_JMI_CNTL),
0385         UVD_JMI_CNTL__SOFT_RESET_MASK,
0386         ~UVD_JMI_CNTL__SOFT_RESET_MASK);
0387 
0388     jpeg_v4_0_enable_clock_gating(adev);
0389 
0390     /* enable power gating */
0391     r = jpeg_v4_0_enable_static_power_gating(adev);
0392     if (r)
0393         return r;
0394 
0395     if (adev->pm.dpm_enabled)
0396         amdgpu_dpm_enable_jpeg(adev, false);
0397 
0398     return 0;
0399 }
0400 
0401 /**
0402  * jpeg_v4_0_dec_ring_get_rptr - get read pointer
0403  *
0404  * @ring: amdgpu_ring pointer
0405  *
0406  * Returns the current hardware read pointer
0407  */
0408 static uint64_t jpeg_v4_0_dec_ring_get_rptr(struct amdgpu_ring *ring)
0409 {
0410     struct amdgpu_device *adev = ring->adev;
0411 
0412     return RREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_RPTR);
0413 }
0414 
0415 /**
0416  * jpeg_v4_0_dec_ring_get_wptr - get write pointer
0417  *
0418  * @ring: amdgpu_ring pointer
0419  *
0420  * Returns the current hardware write pointer
0421  */
0422 static uint64_t jpeg_v4_0_dec_ring_get_wptr(struct amdgpu_ring *ring)
0423 {
0424     struct amdgpu_device *adev = ring->adev;
0425 
0426     if (ring->use_doorbell)
0427         return *ring->wptr_cpu_addr;
0428     else
0429         return RREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR);
0430 }
0431 
0432 /**
0433  * jpeg_v4_0_dec_ring_set_wptr - set write pointer
0434  *
0435  * @ring: amdgpu_ring pointer
0436  *
0437  * Commits the write pointer to the hardware
0438  */
0439 static void jpeg_v4_0_dec_ring_set_wptr(struct amdgpu_ring *ring)
0440 {
0441     struct amdgpu_device *adev = ring->adev;
0442 
0443     if (ring->use_doorbell) {
0444         *ring->wptr_cpu_addr = lower_32_bits(ring->wptr);
0445         WDOORBELL32(ring->doorbell_index, lower_32_bits(ring->wptr));
0446     } else {
0447         WREG32_SOC15(JPEG, 0, regUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
0448     }
0449 }
0450 
0451 static bool jpeg_v4_0_is_idle(void *handle)
0452 {
0453     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0454     int ret = 1;
0455 
0456     ret &= (((RREG32_SOC15(JPEG, 0, regUVD_JRBC_STATUS) &
0457         UVD_JRBC_STATUS__RB_JOB_DONE_MASK) ==
0458         UVD_JRBC_STATUS__RB_JOB_DONE_MASK));
0459 
0460     return ret;
0461 }
0462 
0463 static int jpeg_v4_0_wait_for_idle(void *handle)
0464 {
0465     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0466 
0467     return SOC15_WAIT_ON_RREG(JPEG, 0, regUVD_JRBC_STATUS,
0468         UVD_JRBC_STATUS__RB_JOB_DONE_MASK,
0469         UVD_JRBC_STATUS__RB_JOB_DONE_MASK);
0470 }
0471 
0472 static int jpeg_v4_0_set_clockgating_state(void *handle,
0473                       enum amd_clockgating_state state)
0474 {
0475     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0476     bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
0477 
0478     if (enable) {
0479         if (!jpeg_v4_0_is_idle(handle))
0480             return -EBUSY;
0481         jpeg_v4_0_enable_clock_gating(adev);
0482     } else {
0483         jpeg_v4_0_disable_clock_gating(adev);
0484     }
0485 
0486     return 0;
0487 }
0488 
0489 static int jpeg_v4_0_set_powergating_state(void *handle,
0490                       enum amd_powergating_state state)
0491 {
0492     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0493     int ret;
0494 
0495     if (state == adev->jpeg.cur_state)
0496         return 0;
0497 
0498     if (state == AMD_PG_STATE_GATE)
0499         ret = jpeg_v4_0_stop(adev);
0500     else
0501         ret = jpeg_v4_0_start(adev);
0502 
0503     if (!ret)
0504         adev->jpeg.cur_state = state;
0505 
0506     return ret;
0507 }
0508 
0509 static int jpeg_v4_0_set_interrupt_state(struct amdgpu_device *adev,
0510                     struct amdgpu_irq_src *source,
0511                     unsigned type,
0512                     enum amdgpu_interrupt_state state)
0513 {
0514     return 0;
0515 }
0516 
0517 static int jpeg_v4_0_process_interrupt(struct amdgpu_device *adev,
0518                       struct amdgpu_irq_src *source,
0519                       struct amdgpu_iv_entry *entry)
0520 {
0521     DRM_DEBUG("IH: JPEG TRAP\n");
0522 
0523     switch (entry->src_id) {
0524     case VCN_4_0__SRCID__JPEG_DECODE:
0525         amdgpu_fence_process(&adev->jpeg.inst->ring_dec);
0526         break;
0527     default:
0528         DRM_DEV_ERROR(adev->dev, "Unhandled interrupt: %d %d\n",
0529               entry->src_id, entry->src_data[0]);
0530         break;
0531     }
0532 
0533     return 0;
0534 }
0535 
0536 static const struct amd_ip_funcs jpeg_v4_0_ip_funcs = {
0537     .name = "jpeg_v4_0",
0538     .early_init = jpeg_v4_0_early_init,
0539     .late_init = NULL,
0540     .sw_init = jpeg_v4_0_sw_init,
0541     .sw_fini = jpeg_v4_0_sw_fini,
0542     .hw_init = jpeg_v4_0_hw_init,
0543     .hw_fini = jpeg_v4_0_hw_fini,
0544     .suspend = jpeg_v4_0_suspend,
0545     .resume = jpeg_v4_0_resume,
0546     .is_idle = jpeg_v4_0_is_idle,
0547     .wait_for_idle = jpeg_v4_0_wait_for_idle,
0548     .check_soft_reset = NULL,
0549     .pre_soft_reset = NULL,
0550     .soft_reset = NULL,
0551     .post_soft_reset = NULL,
0552     .set_clockgating_state = jpeg_v4_0_set_clockgating_state,
0553     .set_powergating_state = jpeg_v4_0_set_powergating_state,
0554 };
0555 
0556 static const struct amdgpu_ring_funcs jpeg_v4_0_dec_ring_vm_funcs = {
0557     .type = AMDGPU_RING_TYPE_VCN_JPEG,
0558     .align_mask = 0xf,
0559     .vmhub = AMDGPU_MMHUB_0,
0560     .get_rptr = jpeg_v4_0_dec_ring_get_rptr,
0561     .get_wptr = jpeg_v4_0_dec_ring_get_wptr,
0562     .set_wptr = jpeg_v4_0_dec_ring_set_wptr,
0563     .emit_frame_size =
0564         SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
0565         SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
0566         8 + /* jpeg_v4_0_dec_ring_emit_vm_flush */
0567         18 + 18 + /* jpeg_v4_0_dec_ring_emit_fence x2 vm fence */
0568         8 + 16,
0569     .emit_ib_size = 22, /* jpeg_v4_0_dec_ring_emit_ib */
0570     .emit_ib = jpeg_v2_0_dec_ring_emit_ib,
0571     .emit_fence = jpeg_v2_0_dec_ring_emit_fence,
0572     .emit_vm_flush = jpeg_v2_0_dec_ring_emit_vm_flush,
0573     .test_ring = amdgpu_jpeg_dec_ring_test_ring,
0574     .test_ib = amdgpu_jpeg_dec_ring_test_ib,
0575     .insert_nop = jpeg_v2_0_dec_ring_nop,
0576     .insert_start = jpeg_v2_0_dec_ring_insert_start,
0577     .insert_end = jpeg_v2_0_dec_ring_insert_end,
0578     .pad_ib = amdgpu_ring_generic_pad_ib,
0579     .begin_use = amdgpu_jpeg_ring_begin_use,
0580     .end_use = amdgpu_jpeg_ring_end_use,
0581     .emit_wreg = jpeg_v2_0_dec_ring_emit_wreg,
0582     .emit_reg_wait = jpeg_v2_0_dec_ring_emit_reg_wait,
0583     .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
0584 };
0585 
0586 static void jpeg_v4_0_set_dec_ring_funcs(struct amdgpu_device *adev)
0587 {
0588     adev->jpeg.inst->ring_dec.funcs = &jpeg_v4_0_dec_ring_vm_funcs;
0589     DRM_DEV_INFO(adev->dev, "JPEG decode is enabled in VM mode\n");
0590 }
0591 
0592 static const struct amdgpu_irq_src_funcs jpeg_v4_0_irq_funcs = {
0593     .set = jpeg_v4_0_set_interrupt_state,
0594     .process = jpeg_v4_0_process_interrupt,
0595 };
0596 
0597 static void jpeg_v4_0_set_irq_funcs(struct amdgpu_device *adev)
0598 {
0599     adev->jpeg.inst->irq.num_types = 1;
0600     adev->jpeg.inst->irq.funcs = &jpeg_v4_0_irq_funcs;
0601 }
0602 
0603 const struct amdgpu_ip_block_version jpeg_v4_0_ip_block = {
0604     .type = AMD_IP_BLOCK_TYPE_JPEG,
0605     .major = 4,
0606     .minor = 0,
0607     .rev = 0,
0608     .funcs = &jpeg_v4_0_ip_funcs,
0609 };