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 "soc15.h"
0027 #include "soc15d.h"
0028 #include "vcn_v1_0.h"
0029 #include "jpeg_v1_0.h"
0030 
0031 #include "vcn/vcn_1_0_offset.h"
0032 #include "vcn/vcn_1_0_sh_mask.h"
0033 
0034 static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev);
0035 static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev);
0036 static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring);
0037 
0038 static void jpeg_v1_0_decode_ring_patch_wreg(struct amdgpu_ring *ring, uint32_t *ptr, uint32_t reg_offset, uint32_t val)
0039 {
0040     struct amdgpu_device *adev = ring->adev;
0041     ring->ring[(*ptr)++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0);
0042     if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) ||
0043         ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) {
0044         ring->ring[(*ptr)++] = 0;
0045         ring->ring[(*ptr)++] = PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0);
0046     } else {
0047         ring->ring[(*ptr)++] = reg_offset;
0048         ring->ring[(*ptr)++] = PACKETJ(0, 0, 0, PACKETJ_TYPE0);
0049     }
0050     ring->ring[(*ptr)++] = val;
0051 }
0052 
0053 static void jpeg_v1_0_decode_ring_set_patch_ring(struct amdgpu_ring *ring, uint32_t ptr)
0054 {
0055     struct amdgpu_device *adev = ring->adev;
0056 
0057     uint32_t reg, reg_offset, val, mask, i;
0058 
0059     // 1st: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW
0060     reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW);
0061     reg_offset = (reg << 2);
0062     val = lower_32_bits(ring->gpu_addr);
0063     jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
0064 
0065     // 2nd: program mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH
0066     reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH);
0067     reg_offset = (reg << 2);
0068     val = upper_32_bits(ring->gpu_addr);
0069     jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
0070 
0071     // 3rd to 5th: issue MEM_READ commands
0072     for (i = 0; i <= 2; i++) {
0073         ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE2);
0074         ring->ring[ptr++] = 0;
0075     }
0076 
0077     // 6th: program mmUVD_JRBC_RB_CNTL register to enable NO_FETCH and RPTR write ability
0078     reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL);
0079     reg_offset = (reg << 2);
0080     val = 0x13;
0081     jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
0082 
0083     // 7th: program mmUVD_JRBC_RB_REF_DATA
0084     reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA);
0085     reg_offset = (reg << 2);
0086     val = 0x1;
0087     jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
0088 
0089     // 8th: issue conditional register read mmUVD_JRBC_RB_CNTL
0090     reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL);
0091     reg_offset = (reg << 2);
0092     val = 0x1;
0093     mask = 0x1;
0094 
0095     ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0);
0096     ring->ring[ptr++] = 0x01400200;
0097     ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0);
0098     ring->ring[ptr++] = val;
0099     ring->ring[ptr++] = PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0);
0100     if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) ||
0101         ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) {
0102         ring->ring[ptr++] = 0;
0103         ring->ring[ptr++] = PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3);
0104     } else {
0105         ring->ring[ptr++] = reg_offset;
0106         ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE3);
0107     }
0108     ring->ring[ptr++] = mask;
0109 
0110     //9th to 21st: insert no-op
0111     for (i = 0; i <= 12; i++) {
0112         ring->ring[ptr++] = PACKETJ(0, 0, 0, PACKETJ_TYPE6);
0113         ring->ring[ptr++] = 0;
0114     }
0115 
0116     //22nd: reset mmUVD_JRBC_RB_RPTR
0117     reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_RPTR);
0118     reg_offset = (reg << 2);
0119     val = 0;
0120     jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
0121 
0122     //23rd: program mmUVD_JRBC_RB_CNTL to disable no_fetch
0123     reg = SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_CNTL);
0124     reg_offset = (reg << 2);
0125     val = 0x12;
0126     jpeg_v1_0_decode_ring_patch_wreg(ring, &ptr, reg_offset, val);
0127 }
0128 
0129 /**
0130  * jpeg_v1_0_decode_ring_get_rptr - get read pointer
0131  *
0132  * @ring: amdgpu_ring pointer
0133  *
0134  * Returns the current hardware read pointer
0135  */
0136 static uint64_t jpeg_v1_0_decode_ring_get_rptr(struct amdgpu_ring *ring)
0137 {
0138     struct amdgpu_device *adev = ring->adev;
0139 
0140     return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR);
0141 }
0142 
0143 /**
0144  * jpeg_v1_0_decode_ring_get_wptr - get write pointer
0145  *
0146  * @ring: amdgpu_ring pointer
0147  *
0148  * Returns the current hardware write pointer
0149  */
0150 static uint64_t jpeg_v1_0_decode_ring_get_wptr(struct amdgpu_ring *ring)
0151 {
0152     struct amdgpu_device *adev = ring->adev;
0153 
0154     return RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR);
0155 }
0156 
0157 /**
0158  * jpeg_v1_0_decode_ring_set_wptr - set write pointer
0159  *
0160  * @ring: amdgpu_ring pointer
0161  *
0162  * Commits the write pointer to the hardware
0163  */
0164 static void jpeg_v1_0_decode_ring_set_wptr(struct amdgpu_ring *ring)
0165 {
0166     struct amdgpu_device *adev = ring->adev;
0167 
0168     WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, lower_32_bits(ring->wptr));
0169 }
0170 
0171 /**
0172  * jpeg_v1_0_decode_ring_insert_start - insert a start command
0173  *
0174  * @ring: amdgpu_ring pointer
0175  *
0176  * Write a start command to the ring.
0177  */
0178 static void jpeg_v1_0_decode_ring_insert_start(struct amdgpu_ring *ring)
0179 {
0180     struct amdgpu_device *adev = ring->adev;
0181 
0182     amdgpu_ring_write(ring,
0183         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0));
0184     amdgpu_ring_write(ring, 0x68e04);
0185 
0186     amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0));
0187     amdgpu_ring_write(ring, 0x80010000);
0188 }
0189 
0190 /**
0191  * jpeg_v1_0_decode_ring_insert_end - insert a end command
0192  *
0193  * @ring: amdgpu_ring pointer
0194  *
0195  * Write a end command to the ring.
0196  */
0197 static void jpeg_v1_0_decode_ring_insert_end(struct amdgpu_ring *ring)
0198 {
0199     struct amdgpu_device *adev = ring->adev;
0200 
0201     amdgpu_ring_write(ring,
0202         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0));
0203     amdgpu_ring_write(ring, 0x68e04);
0204 
0205     amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE0));
0206     amdgpu_ring_write(ring, 0x00010000);
0207 }
0208 
0209 /**
0210  * jpeg_v1_0_decode_ring_emit_fence - emit an fence & trap command
0211  *
0212  * @ring: amdgpu_ring pointer
0213  * @addr: address
0214  * @seq: sequence number
0215  * @flags: fence related flags
0216  *
0217  * Write a fence and a trap command to the ring.
0218  */
0219 static void jpeg_v1_0_decode_ring_emit_fence(struct amdgpu_ring *ring, u64 addr, u64 seq,
0220                      unsigned flags)
0221 {
0222     struct amdgpu_device *adev = ring->adev;
0223 
0224     WARN_ON(flags & AMDGPU_FENCE_FLAG_64BIT);
0225 
0226     amdgpu_ring_write(ring,
0227         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_DATA0), 0, 0, PACKETJ_TYPE0));
0228     amdgpu_ring_write(ring, seq);
0229 
0230     amdgpu_ring_write(ring,
0231         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_DATA1), 0, 0, PACKETJ_TYPE0));
0232     amdgpu_ring_write(ring, seq);
0233 
0234     amdgpu_ring_write(ring,
0235         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0));
0236     amdgpu_ring_write(ring, lower_32_bits(addr));
0237 
0238     amdgpu_ring_write(ring,
0239         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_WR_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0));
0240     amdgpu_ring_write(ring, upper_32_bits(addr));
0241 
0242     amdgpu_ring_write(ring,
0243         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_CMD), 0, 0, PACKETJ_TYPE0));
0244     amdgpu_ring_write(ring, 0x8);
0245 
0246     amdgpu_ring_write(ring,
0247         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_GPCOM_CMD), 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE4));
0248     amdgpu_ring_write(ring, 0);
0249 
0250     amdgpu_ring_write(ring,
0251         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0));
0252     amdgpu_ring_write(ring, 0x01400200);
0253 
0254     amdgpu_ring_write(ring,
0255         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0));
0256     amdgpu_ring_write(ring, seq);
0257 
0258     amdgpu_ring_write(ring,
0259         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0));
0260     amdgpu_ring_write(ring, lower_32_bits(addr));
0261 
0262     amdgpu_ring_write(ring,
0263         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0));
0264     amdgpu_ring_write(ring, upper_32_bits(addr));
0265 
0266     amdgpu_ring_write(ring,
0267         PACKETJ(0, 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE2));
0268     amdgpu_ring_write(ring, 0xffffffff);
0269 
0270     amdgpu_ring_write(ring,
0271         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0));
0272     amdgpu_ring_write(ring, 0x3fbc);
0273 
0274     amdgpu_ring_write(ring,
0275         PACKETJ(0, 0, 0, PACKETJ_TYPE0));
0276     amdgpu_ring_write(ring, 0x1);
0277 
0278     /* emit trap */
0279     amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE7));
0280     amdgpu_ring_write(ring, 0);
0281 }
0282 
0283 /**
0284  * jpeg_v1_0_decode_ring_emit_ib - execute indirect buffer
0285  *
0286  * @ring: amdgpu_ring pointer
0287  * @job: job to retrieve vmid from
0288  * @ib: indirect buffer to execute
0289  * @flags: unused
0290  *
0291  * Write ring commands to execute the indirect buffer.
0292  */
0293 static void jpeg_v1_0_decode_ring_emit_ib(struct amdgpu_ring *ring,
0294                     struct amdgpu_job *job,
0295                     struct amdgpu_ib *ib,
0296                     uint32_t flags)
0297 {
0298     struct amdgpu_device *adev = ring->adev;
0299     unsigned vmid = AMDGPU_JOB_GET_VMID(job);
0300 
0301     amdgpu_ring_write(ring,
0302         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_VMID), 0, 0, PACKETJ_TYPE0));
0303     amdgpu_ring_write(ring, (vmid | (vmid << 4)));
0304 
0305     amdgpu_ring_write(ring,
0306         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JPEG_VMID), 0, 0, PACKETJ_TYPE0));
0307     amdgpu_ring_write(ring, (vmid | (vmid << 4)));
0308 
0309     amdgpu_ring_write(ring,
0310         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0));
0311     amdgpu_ring_write(ring, lower_32_bits(ib->gpu_addr));
0312 
0313     amdgpu_ring_write(ring,
0314         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_IB_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0));
0315     amdgpu_ring_write(ring, upper_32_bits(ib->gpu_addr));
0316 
0317     amdgpu_ring_write(ring,
0318         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_IB_SIZE), 0, 0, PACKETJ_TYPE0));
0319     amdgpu_ring_write(ring, ib->length_dw);
0320 
0321     amdgpu_ring_write(ring,
0322         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_LOW), 0, 0, PACKETJ_TYPE0));
0323     amdgpu_ring_write(ring, lower_32_bits(ring->gpu_addr));
0324 
0325     amdgpu_ring_write(ring,
0326         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_LMI_JRBC_RB_MEM_RD_64BIT_BAR_HIGH), 0, 0, PACKETJ_TYPE0));
0327     amdgpu_ring_write(ring, upper_32_bits(ring->gpu_addr));
0328 
0329     amdgpu_ring_write(ring,
0330         PACKETJ(0, 0, PACKETJ_CONDITION_CHECK0, PACKETJ_TYPE2));
0331     amdgpu_ring_write(ring, 0);
0332 
0333     amdgpu_ring_write(ring,
0334         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0));
0335     amdgpu_ring_write(ring, 0x01400200);
0336 
0337     amdgpu_ring_write(ring,
0338         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0));
0339     amdgpu_ring_write(ring, 0x2);
0340 
0341     amdgpu_ring_write(ring,
0342         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_STATUS), 0, PACKETJ_CONDITION_CHECK3, PACKETJ_TYPE3));
0343     amdgpu_ring_write(ring, 0x2);
0344 }
0345 
0346 static void jpeg_v1_0_decode_ring_emit_reg_wait(struct amdgpu_ring *ring,
0347                         uint32_t reg, uint32_t val,
0348                         uint32_t mask)
0349 {
0350     struct amdgpu_device *adev = ring->adev;
0351     uint32_t reg_offset = (reg << 2);
0352 
0353     amdgpu_ring_write(ring,
0354         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_COND_RD_TIMER), 0, 0, PACKETJ_TYPE0));
0355     amdgpu_ring_write(ring, 0x01400200);
0356 
0357     amdgpu_ring_write(ring,
0358         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_RB_REF_DATA), 0, 0, PACKETJ_TYPE0));
0359     amdgpu_ring_write(ring, val);
0360 
0361     amdgpu_ring_write(ring,
0362         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0));
0363     if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) ||
0364         ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) {
0365         amdgpu_ring_write(ring, 0);
0366         amdgpu_ring_write(ring,
0367             PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE3));
0368     } else {
0369         amdgpu_ring_write(ring, reg_offset);
0370         amdgpu_ring_write(ring,
0371             PACKETJ(0, 0, 0, PACKETJ_TYPE3));
0372     }
0373     amdgpu_ring_write(ring, mask);
0374 }
0375 
0376 static void jpeg_v1_0_decode_ring_emit_vm_flush(struct amdgpu_ring *ring,
0377         unsigned vmid, uint64_t pd_addr)
0378 {
0379     struct amdgpu_vmhub *hub = &ring->adev->vmhub[ring->funcs->vmhub];
0380     uint32_t data0, data1, mask;
0381 
0382     pd_addr = amdgpu_gmc_emit_flush_gpu_tlb(ring, vmid, pd_addr);
0383 
0384     /* wait for register write */
0385     data0 = hub->ctx0_ptb_addr_lo32 + vmid * hub->ctx_addr_distance;
0386     data1 = lower_32_bits(pd_addr);
0387     mask = 0xffffffff;
0388     jpeg_v1_0_decode_ring_emit_reg_wait(ring, data0, data1, mask);
0389 }
0390 
0391 static void jpeg_v1_0_decode_ring_emit_wreg(struct amdgpu_ring *ring,
0392                     uint32_t reg, uint32_t val)
0393 {
0394     struct amdgpu_device *adev = ring->adev;
0395     uint32_t reg_offset = (reg << 2);
0396 
0397     amdgpu_ring_write(ring,
0398         PACKETJ(SOC15_REG_OFFSET(JPEG, 0, mmUVD_JRBC_EXTERNAL_REG_BASE), 0, 0, PACKETJ_TYPE0));
0399     if (((reg_offset >= 0x1f800) && (reg_offset <= 0x21fff)) ||
0400             ((reg_offset >= 0x1e000) && (reg_offset <= 0x1e1ff))) {
0401         amdgpu_ring_write(ring, 0);
0402         amdgpu_ring_write(ring,
0403             PACKETJ((reg_offset >> 2), 0, 0, PACKETJ_TYPE0));
0404     } else {
0405         amdgpu_ring_write(ring, reg_offset);
0406         amdgpu_ring_write(ring,
0407             PACKETJ(0, 0, 0, PACKETJ_TYPE0));
0408     }
0409     amdgpu_ring_write(ring, val);
0410 }
0411 
0412 static void jpeg_v1_0_decode_ring_nop(struct amdgpu_ring *ring, uint32_t count)
0413 {
0414     int i;
0415 
0416     WARN_ON(ring->wptr % 2 || count % 2);
0417 
0418     for (i = 0; i < count / 2; i++) {
0419         amdgpu_ring_write(ring, PACKETJ(0, 0, 0, PACKETJ_TYPE6));
0420         amdgpu_ring_write(ring, 0);
0421     }
0422 }
0423 
0424 static int jpeg_v1_0_set_interrupt_state(struct amdgpu_device *adev,
0425                     struct amdgpu_irq_src *source,
0426                     unsigned type,
0427                     enum amdgpu_interrupt_state state)
0428 {
0429     return 0;
0430 }
0431 
0432 static int jpeg_v1_0_process_interrupt(struct amdgpu_device *adev,
0433                       struct amdgpu_irq_src *source,
0434                       struct amdgpu_iv_entry *entry)
0435 {
0436     DRM_DEBUG("IH: JPEG decode TRAP\n");
0437 
0438     switch (entry->src_id) {
0439     case 126:
0440         amdgpu_fence_process(&adev->jpeg.inst->ring_dec);
0441         break;
0442     default:
0443         DRM_ERROR("Unhandled interrupt: %d %d\n",
0444               entry->src_id, entry->src_data[0]);
0445         break;
0446     }
0447 
0448     return 0;
0449 }
0450 
0451 /**
0452  * jpeg_v1_0_early_init - set function pointers
0453  *
0454  * @handle: amdgpu_device pointer
0455  *
0456  * Set ring and irq function pointers
0457  */
0458 int jpeg_v1_0_early_init(void *handle)
0459 {
0460     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0461 
0462     adev->jpeg.num_jpeg_inst = 1;
0463 
0464     jpeg_v1_0_set_dec_ring_funcs(adev);
0465     jpeg_v1_0_set_irq_funcs(adev);
0466 
0467     return 0;
0468 }
0469 
0470 /**
0471  * jpeg_v1_0_sw_init - sw init for JPEG block
0472  *
0473  * @handle: amdgpu_device pointer
0474  *
0475  */
0476 int jpeg_v1_0_sw_init(void *handle)
0477 {
0478     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0479     struct amdgpu_ring *ring;
0480     int r;
0481 
0482     /* JPEG TRAP */
0483     r = amdgpu_irq_add_id(adev, SOC15_IH_CLIENTID_VCN, 126, &adev->jpeg.inst->irq);
0484     if (r)
0485         return r;
0486 
0487     ring = &adev->jpeg.inst->ring_dec;
0488     sprintf(ring->name, "jpeg_dec");
0489     r = amdgpu_ring_init(adev, ring, 512, &adev->jpeg.inst->irq,
0490                  0, AMDGPU_RING_PRIO_DEFAULT, NULL);
0491     if (r)
0492         return r;
0493 
0494     adev->jpeg.internal.jpeg_pitch = adev->jpeg.inst->external.jpeg_pitch =
0495         SOC15_REG_OFFSET(JPEG, 0, mmUVD_JPEG_PITCH);
0496 
0497     return 0;
0498 }
0499 
0500 /**
0501  * jpeg_v1_0_sw_fini - sw fini for JPEG block
0502  *
0503  * @handle: amdgpu_device pointer
0504  *
0505  * JPEG free up sw allocation
0506  */
0507 void jpeg_v1_0_sw_fini(void *handle)
0508 {
0509     struct amdgpu_device *adev = (struct amdgpu_device *)handle;
0510 
0511     amdgpu_ring_fini(&adev->jpeg.inst[0].ring_dec);
0512 }
0513 
0514 /**
0515  * jpeg_v1_0_start - start JPEG block
0516  *
0517  * @adev: amdgpu_device pointer
0518  * @mode: SPG or DPG mode
0519  *
0520  * Setup and start the JPEG block
0521  */
0522 void jpeg_v1_0_start(struct amdgpu_device *adev, int mode)
0523 {
0524     struct amdgpu_ring *ring = &adev->jpeg.inst->ring_dec;
0525 
0526     if (mode == 0) {
0527         WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_VMID, 0);
0528         WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, UVD_JRBC_RB_CNTL__RB_NO_FETCH_MASK |
0529                 UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
0530         WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_LOW, lower_32_bits(ring->gpu_addr));
0531         WREG32_SOC15(JPEG, 0, mmUVD_LMI_JRBC_RB_64BIT_BAR_HIGH, upper_32_bits(ring->gpu_addr));
0532         WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_RPTR, 0);
0533         WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR, 0);
0534         WREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_CNTL, UVD_JRBC_RB_CNTL__RB_RPTR_WR_EN_MASK);
0535     }
0536 
0537     /* initialize wptr */
0538     ring->wptr = RREG32_SOC15(JPEG, 0, mmUVD_JRBC_RB_WPTR);
0539 
0540     /* copy patch commands to the jpeg ring */
0541     jpeg_v1_0_decode_ring_set_patch_ring(ring,
0542         (ring->wptr + ring->max_dw * amdgpu_sched_hw_submission));
0543 }
0544 
0545 static const struct amdgpu_ring_funcs jpeg_v1_0_decode_ring_vm_funcs = {
0546     .type = AMDGPU_RING_TYPE_VCN_JPEG,
0547     .align_mask = 0xf,
0548     .nop = PACKET0(0x81ff, 0),
0549     .support_64bit_ptrs = false,
0550     .no_user_fence = true,
0551     .vmhub = AMDGPU_MMHUB_0,
0552     .extra_dw = 64,
0553     .get_rptr = jpeg_v1_0_decode_ring_get_rptr,
0554     .get_wptr = jpeg_v1_0_decode_ring_get_wptr,
0555     .set_wptr = jpeg_v1_0_decode_ring_set_wptr,
0556     .emit_frame_size =
0557         6 + 6 + /* hdp invalidate / flush */
0558         SOC15_FLUSH_GPU_TLB_NUM_WREG * 6 +
0559         SOC15_FLUSH_GPU_TLB_NUM_REG_WAIT * 8 +
0560         8 + /* jpeg_v1_0_decode_ring_emit_vm_flush */
0561         26 + 26 + /* jpeg_v1_0_decode_ring_emit_fence x2 vm fence */
0562         6,
0563     .emit_ib_size = 22, /* jpeg_v1_0_decode_ring_emit_ib */
0564     .emit_ib = jpeg_v1_0_decode_ring_emit_ib,
0565     .emit_fence = jpeg_v1_0_decode_ring_emit_fence,
0566     .emit_vm_flush = jpeg_v1_0_decode_ring_emit_vm_flush,
0567     .test_ring = amdgpu_jpeg_dec_ring_test_ring,
0568     .test_ib = amdgpu_jpeg_dec_ring_test_ib,
0569     .insert_nop = jpeg_v1_0_decode_ring_nop,
0570     .insert_start = jpeg_v1_0_decode_ring_insert_start,
0571     .insert_end = jpeg_v1_0_decode_ring_insert_end,
0572     .pad_ib = amdgpu_ring_generic_pad_ib,
0573     .begin_use = jpeg_v1_0_ring_begin_use,
0574     .end_use = vcn_v1_0_ring_end_use,
0575     .emit_wreg = jpeg_v1_0_decode_ring_emit_wreg,
0576     .emit_reg_wait = jpeg_v1_0_decode_ring_emit_reg_wait,
0577     .emit_reg_write_reg_wait = amdgpu_ring_emit_reg_write_reg_wait_helper,
0578 };
0579 
0580 static void jpeg_v1_0_set_dec_ring_funcs(struct amdgpu_device *adev)
0581 {
0582     adev->jpeg.inst->ring_dec.funcs = &jpeg_v1_0_decode_ring_vm_funcs;
0583     DRM_INFO("JPEG decode is enabled in VM mode\n");
0584 }
0585 
0586 static const struct amdgpu_irq_src_funcs jpeg_v1_0_irq_funcs = {
0587     .set = jpeg_v1_0_set_interrupt_state,
0588     .process = jpeg_v1_0_process_interrupt,
0589 };
0590 
0591 static void jpeg_v1_0_set_irq_funcs(struct amdgpu_device *adev)
0592 {
0593     adev->jpeg.inst->irq.funcs = &jpeg_v1_0_irq_funcs;
0594 }
0595 
0596 static void jpeg_v1_0_ring_begin_use(struct amdgpu_ring *ring)
0597 {
0598     struct  amdgpu_device *adev = ring->adev;
0599     bool    set_clocks = !cancel_delayed_work_sync(&adev->vcn.idle_work);
0600     int     cnt = 0;
0601 
0602     mutex_lock(&adev->vcn.vcn1_jpeg1_workaround);
0603 
0604     if (amdgpu_fence_wait_empty(&adev->vcn.inst->ring_dec))
0605         DRM_ERROR("JPEG dec: vcn dec ring may not be empty\n");
0606 
0607     for (cnt = 0; cnt < adev->vcn.num_enc_rings; cnt++) {
0608         if (amdgpu_fence_wait_empty(&adev->vcn.inst->ring_enc[cnt]))
0609             DRM_ERROR("JPEG dec: vcn enc ring[%d] may not be empty\n", cnt);
0610     }
0611 
0612     vcn_v1_0_set_pg_for_begin_use(ring, set_clocks);
0613 }