• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**************************************************************************
2  *
3  * Copyright 2018 Advanced Micro Devices, Inc.
4  *
5  * SPDX-License-Identifier: MIT
6  *
7  **************************************************************************/
8 
9 #include "pipe/p_video_codec.h"
10 #include "radeon_vcn_dec.h"
11 #include "radeon_video.h"
12 #include "radeonsi/si_pipe.h"
13 #include "util/u_memory.h"
14 #include "util/u_video.h"
15 
16 #include <assert.h>
17 #include <stdio.h>
18 
radeon_jpeg_get_decode_param(struct radeon_decoder * dec,struct pipe_video_buffer * target,struct pipe_picture_desc * picture)19 static struct pb_buffer_lean *radeon_jpeg_get_decode_param(struct radeon_decoder *dec,
20                                                            struct pipe_video_buffer *target,
21                                                            struct pipe_picture_desc *picture)
22 {
23    struct si_texture *luma = (struct si_texture *)((struct vl_video_buffer *)target)->resources[0];
24    struct si_texture *chroma, *chromav;
25 
26    dec->jpg.bsd_size = align(dec->bs_size, 128);
27    dec->jpg.dt_luma_top_offset = luma->surface.u.gfx9.surf_offset;
28    dec->jpg.dt_chroma_top_offset = 0;
29    dec->jpg.dt_chromav_top_offset = 0;
30 
31    switch (target->buffer_format) {
32       case PIPE_FORMAT_IYUV:
33       case PIPE_FORMAT_YV12:
34       case PIPE_FORMAT_Y8_U8_V8_444_UNORM:
35       case PIPE_FORMAT_R8_G8_B8_UNORM:
36          chromav = (struct si_texture *)((struct vl_video_buffer *)target)->resources[2];
37          dec->jpg.dt_chromav_top_offset = chromav->surface.u.gfx9.surf_offset;
38          chroma = (struct si_texture *)((struct vl_video_buffer*)target)->resources[1];
39          dec->jpg.dt_chroma_top_offset = chroma->surface.u.gfx9.surf_offset;
40          break;
41       case PIPE_FORMAT_NV12:
42       case PIPE_FORMAT_P010:
43       case PIPE_FORMAT_P016:
44          chroma = (struct si_texture *)((struct vl_video_buffer*)target)->resources[1];
45          dec->jpg.dt_chroma_top_offset = chroma->surface.u.gfx9.surf_offset;
46          break;
47       default:
48          break;
49    }
50    dec->jpg.dt_pitch = luma->surface.u.gfx9.surf_pitch * luma->surface.blk_w;
51    dec->jpg.dt_uv_pitch = dec->jpg.dt_pitch / 2;
52 
53    return luma->buffer.buf;
54 }
55 
56 /* add a new set register command to the IB */
set_reg_jpeg(struct radeon_decoder * dec,unsigned reg,unsigned cond,unsigned type,uint32_t val)57 static void set_reg_jpeg(struct radeon_decoder *dec, unsigned reg, unsigned cond, unsigned type,
58                          uint32_t val)
59 {
60    radeon_emit(&dec->jcs[dec->cb_idx], RDECODE_PKTJ(reg, cond, type));
61    radeon_emit(&dec->jcs[dec->cb_idx], val);
62 }
63 
64 /* send a bitstream buffer command */
send_cmd_bitstream(struct radeon_decoder * dec,struct pb_buffer_lean * buf,uint32_t off,unsigned usage,enum radeon_bo_domain domain)65 static void send_cmd_bitstream(struct radeon_decoder *dec, struct pb_buffer_lean *buf, uint32_t off,
66                                unsigned usage, enum radeon_bo_domain domain)
67 {
68    uint64_t addr;
69 
70    // jpeg soft reset
71    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 1);
72 
73    // ensuring the Reset is asserted in SCLK domain
74    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C2);
75    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0x01400200);
76    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
77    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (1 << 9));
78    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_SOFT_RESET), COND0, TYPE3, (1 << 9));
79 
80    // wait mem
81    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 0);
82 
83    // ensuring the Reset is de-asserted in SCLK domain
84    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
85    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (0 << 9));
86    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_SOFT_RESET), COND0, TYPE3, (1 << 9));
87 
88    dec->ws->cs_add_buffer(&dec->jcs[dec->cb_idx], buf, usage | RADEON_USAGE_SYNCHRONIZED, domain);
89    addr = dec->ws->buffer_get_virtual_address(buf);
90    addr = addr + off;
91 
92    // set UVD_LMI_JPEG_READ_64BIT_BAR_LOW/HIGH based on bitstream buffer address
93    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_LMI_JPEG_READ_64BIT_BAR_HIGH), COND0, TYPE0,
94                 (addr >> 32));
95    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_LMI_JPEG_READ_64BIT_BAR_LOW), COND0, TYPE0, addr);
96 
97    // set jpeg_rb_base
98    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_RB_BASE), COND0, TYPE0, 0);
99 
100    // set jpeg_rb_base
101    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_RB_SIZE), COND0, TYPE0, 0xFFFFFFF0);
102 
103    // set jpeg_rb_wptr
104    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_RB_WPTR), COND0, TYPE0, (dec->jpg.bsd_size >> 2));
105 }
106 
107 /* send a target buffer command */
send_cmd_target(struct radeon_decoder * dec,struct pb_buffer_lean * buf,uint32_t off,unsigned usage,enum radeon_bo_domain domain)108 static void send_cmd_target(struct radeon_decoder *dec, struct pb_buffer_lean *buf, uint32_t off,
109                             unsigned usage, enum radeon_bo_domain domain)
110 {
111    uint64_t addr;
112 
113    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_PITCH), COND0, TYPE0, (dec->jpg.dt_pitch >> 4));
114    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_UV_PITCH), COND0, TYPE0,
115                 ((dec->jpg.dt_uv_pitch * 2) >> 4));
116 
117    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_TILING_CTRL), COND0, TYPE0, 0);
118    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_UV_TILING_CTRL), COND0, TYPE0, 0);
119 
120    dec->ws->cs_add_buffer(&dec->jcs[dec->cb_idx], buf, usage | RADEON_USAGE_SYNCHRONIZED, domain);
121    addr = dec->ws->buffer_get_virtual_address(buf);
122    addr = addr + off;
123 
124    // set UVD_LMI_JPEG_WRITE_64BIT_BAR_LOW/HIGH based on target buffer address
125    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_LMI_JPEG_WRITE_64BIT_BAR_HIGH), COND0, TYPE0,
126                 (addr >> 32));
127    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_LMI_JPEG_WRITE_64BIT_BAR_LOW), COND0, TYPE0, addr);
128 
129    // set output buffer data address
130    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_INDEX), COND0, TYPE0, 0);
131    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_DATA), COND0, TYPE0, dec->jpg.dt_luma_top_offset);
132    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_INDEX), COND0, TYPE0, 1);
133    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_DATA), COND0, TYPE0, dec->jpg.dt_chroma_top_offset);
134    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_TIER_CNTL2), COND0, TYPE3, 0);
135 
136    // set output buffer read pointer
137    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_OUTBUF_RPTR), COND0, TYPE0, 0);
138 
139    // enable error interrupts
140    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_INT_EN), COND0, TYPE0, 0xFFFFFFFE);
141 
142    // start engine command
143    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 0x6);
144 
145    // wait for job completion, wait for job JBSI fetch done
146    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
147    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (dec->jpg.bsd_size >> 2));
148    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C2);
149    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0x01400200);
150    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_RB_RPTR), COND0, TYPE3, 0xFFFFFFFF);
151 
152    // wait for job jpeg outbuf idle
153    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
154    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0xFFFFFFFF);
155    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_OUTBUF_WPTR), COND0, TYPE3, 0x00000001);
156 
157    // stop engine
158    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 0x4);
159 
160    // asserting jpeg lmi drop
161    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x0005);
162    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (1 << 23 | 1 << 0));
163    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE1, 0);
164 
165    // asserting jpeg reset
166    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 1);
167 
168    // ensure reset is asserted in sclk domain
169    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
170    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (1 << 9));
171    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_SOFT_RESET), COND0, TYPE3, (1 << 9));
172 
173    // de-assert jpeg reset
174    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 0);
175 
176    // ensure reset is de-asserted in sclk domain
177    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
178    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (0 << 9));
179    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_SOFT_RESET), COND0, TYPE3, (1 << 9));
180 
181    // de-asserting jpeg lmi drop
182    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x0005);
183    set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0);
184 }
185 
186 /* send a bitstream buffer command */
send_cmd_bitstream_direct(struct radeon_decoder * dec,struct pb_buffer_lean * buf,uint32_t off,unsigned usage,enum radeon_bo_domain domain)187 static void send_cmd_bitstream_direct(struct radeon_decoder *dec, struct pb_buffer_lean *buf,
188                                       uint32_t off, unsigned usage,
189                                       enum radeon_bo_domain domain)
190 {
191    uint64_t addr;
192 
193    // jpeg soft reset
194    set_reg_jpeg(dec, dec->jpg_reg.jpeg_dec_soft_rst, COND0, TYPE0, 1);
195 
196    // ensuring the Reset is asserted in SCLK domain
197    set_reg_jpeg(dec, dec->jpg_reg.jrbc_ib_cond_rd_timer, COND0, TYPE0, 0x01400200);
198    set_reg_jpeg(dec, dec->jpg_reg.jrbc_ib_ref_data, COND0, TYPE0, (0x1 << 0x10));
199    set_reg_jpeg(dec, dec->jpg_reg.jpeg_dec_soft_rst, COND3, TYPE3, (0x1 << 0x10));
200 
201    // wait mem
202    set_reg_jpeg(dec, dec->jpg_reg.jpeg_dec_soft_rst, COND0, TYPE0, 0);
203 
204    // ensuring the Reset is de-asserted in SCLK domain
205    set_reg_jpeg(dec, dec->jpg_reg.jrbc_ib_ref_data, COND0, TYPE0, (0 << 0x10));
206    set_reg_jpeg(dec, dec->jpg_reg.jpeg_dec_soft_rst, COND3, TYPE3, (0x1 << 0x10));
207 
208    dec->ws->cs_add_buffer(&dec->jcs[dec->cb_idx], buf, usage | RADEON_USAGE_SYNCHRONIZED, domain);
209    addr = dec->ws->buffer_get_virtual_address(buf);
210    addr = addr + off;
211 
212    // set UVD_LMI_JPEG_READ_64BIT_BAR_LOW/HIGH based on bitstream buffer address
213    set_reg_jpeg(dec, dec->jpg_reg.lmi_jpeg_read_64bit_bar_high, COND0, TYPE0, (addr >> 32));
214    set_reg_jpeg(dec, dec->jpg_reg.lmi_jpeg_read_64bit_bar_low, COND0, TYPE0, addr);
215 
216    // set jpeg_rb_base
217    set_reg_jpeg(dec, dec->jpg_reg.jpeg_rb_base, COND0, TYPE0, 0);
218 
219    // set jpeg_rb_base
220    set_reg_jpeg(dec, dec->jpg_reg.jpeg_rb_size, COND0, TYPE0, 0xFFFFFFF0);
221 
222    // set jpeg_rb_wptr
223    set_reg_jpeg(dec, dec->jpg_reg.jpeg_rb_wptr, COND0, TYPE0, (dec->jpg.bsd_size >> 2));
224 }
225 
226 /* send a target buffer command */
send_cmd_target_direct(struct radeon_decoder * dec,struct pb_buffer_lean * buf,uint32_t off,unsigned usage,enum radeon_bo_domain domain,enum pipe_format buffer_format)227 static void send_cmd_target_direct(struct radeon_decoder *dec, struct pb_buffer_lean *buf, uint32_t off,
228                                    unsigned usage, enum radeon_bo_domain domain,
229                                    enum pipe_format buffer_format)
230 {
231    uint64_t addr;
232    uint32_t val;
233    bool format_convert = false;
234    uint32_t fc_sps_info_val = 0;
235 
236    switch (buffer_format) {
237       case PIPE_FORMAT_R8G8B8A8_UNORM:
238          format_convert = true;
239          fc_sps_info_val = 1 | (1 << 4) | (0xff << 8);
240          break;
241       case PIPE_FORMAT_A8R8G8B8_UNORM:
242          format_convert = true;
243          fc_sps_info_val = 1 | (1 << 4) | (1 << 5) | (0xff << 8);
244          break;
245       case PIPE_FORMAT_R8_G8_B8_UNORM:
246          format_convert = true;
247          fc_sps_info_val = 1 | (1 << 5) | (0xff << 8);
248          break;
249       default:
250          break;
251    }
252 
253    if (dec->jpg_reg.version == RDECODE_JPEG_REG_VER_V3 && format_convert) {
254       set_reg_jpeg(dec, dec->jpg_reg.jpeg_pitch, COND0, TYPE0, dec->jpg.dt_pitch);
255       set_reg_jpeg(dec, dec->jpg_reg.jpeg_uv_pitch, COND0, TYPE0, (dec->jpg.dt_uv_pitch * 2));
256    } else {
257       set_reg_jpeg(dec, dec->jpg_reg.jpeg_pitch, COND0, TYPE0, (dec->jpg.dt_pitch >> 4));
258       set_reg_jpeg(dec, dec->jpg_reg.jpeg_uv_pitch, COND0, TYPE0, ((dec->jpg.dt_uv_pitch * 2) >> 4));
259    }
260 
261    set_reg_jpeg(dec, dec->jpg_reg.dec_addr_mode, COND0, TYPE0, 0);
262    set_reg_jpeg(dec, dec->jpg_reg.dec_y_gfx10_tiling_surface, COND0, TYPE0, 0);
263    set_reg_jpeg(dec, dec->jpg_reg.dec_uv_gfx10_tiling_surface, COND0, TYPE0, 0);
264 
265    dec->ws->cs_add_buffer(&dec->jcs[dec->cb_idx], buf, usage | RADEON_USAGE_SYNCHRONIZED, domain);
266    addr = dec->ws->buffer_get_virtual_address(buf);
267    addr = addr + off;
268 
269    // set UVD_LMI_JPEG_WRITE_64BIT_BAR_LOW/HIGH based on target buffer address
270    set_reg_jpeg(dec, dec->jpg_reg.lmi_jpeg_write_64bit_bar_high, COND0, TYPE0, (addr >> 32));
271    set_reg_jpeg(dec, dec->jpg_reg.lmi_jpeg_write_64bit_bar_low, COND0, TYPE0, addr);
272 
273    // set output buffer data address
274    if (dec->jpg_reg.version == RDECODE_JPEG_REG_VER_V2) {
275       set_reg_jpeg(dec, dec->jpg_reg.jpeg_index, COND0, TYPE0, 0);
276       set_reg_jpeg(dec, dec->jpg_reg.jpeg_data, COND0, TYPE0, dec->jpg.dt_luma_top_offset);
277       set_reg_jpeg(dec, dec->jpg_reg.jpeg_index, COND0, TYPE0, 1);
278       set_reg_jpeg(dec, dec->jpg_reg.jpeg_data, COND0, TYPE0, dec->jpg.dt_chroma_top_offset);
279       if (dec->jpg.dt_chromav_top_offset) {
280          set_reg_jpeg(dec, dec->jpg_reg.jpeg_index, COND0, TYPE0, 2);
281          set_reg_jpeg(dec, dec->jpg_reg.jpeg_data, COND0, TYPE0, dec->jpg.dt_chromav_top_offset);
282       }
283    } else {
284       set_reg_jpeg(dec, dec->jpg_reg.jpeg_luma_base0_0, COND0, TYPE0, dec->jpg.dt_luma_top_offset);
285       set_reg_jpeg(dec, dec->jpg_reg.jpeg_chroma_base0_0, COND0, TYPE0, dec->jpg.dt_chroma_top_offset);
286       set_reg_jpeg(dec, dec->jpg_reg.jpeg_chromav_base0_0, COND0, TYPE0, dec->jpg.dt_chromav_top_offset);
287       if (dec->jpg.crop_width && dec->jpg.crop_height) {
288          set_reg_jpeg(dec, vcnipUVD_JPEG_ROI_CROP_POS_START, COND0, TYPE0,
289                       ((dec->jpg.crop_y << 16) | dec->jpg.crop_x));
290          set_reg_jpeg(dec, vcnipUVD_JPEG_ROI_CROP_POS_STRIDE, COND0, TYPE0,
291                       ((dec->jpg.crop_height << 16) | dec->jpg.crop_width));
292       } else {
293          set_reg_jpeg(dec, vcnipUVD_JPEG_ROI_CROP_POS_START, COND0, TYPE0,
294                       ((0 << 16) | 0));
295          set_reg_jpeg(dec, vcnipUVD_JPEG_ROI_CROP_POS_STRIDE, COND0, TYPE0,
296                       ((1 << 16) | 1));
297       }
298       if (format_convert) {
299          /* set fc timeout control */
300          set_reg_jpeg(dec, vcnipUVD_JPEG_FC_TMEOUT_CNT, COND0, TYPE0,(4244373504));
301          /* set alpha position and packed format */
302          set_reg_jpeg(dec, vcnipUVD_JPEG_FC_SPS_INFO, COND0, TYPE0, fc_sps_info_val);
303          /* coefs */
304          set_reg_jpeg(dec, vcnipUVD_JPEG_FC_R_COEF, COND0, TYPE0, 256 | (0 << 10) | (403 << 20));
305          set_reg_jpeg(dec, vcnipUVD_JPEG_FC_G_COEF, COND0, TYPE0, 256 | (976 << 10) | (904 << 20));
306          set_reg_jpeg(dec, vcnipUVD_JPEG_FC_B_COEF, COND0, TYPE0, 256 | (475 << 10) | (0 << 20));
307          set_reg_jpeg(dec, vcnipUVD_JPEG_FC_VUP_COEF_CNTL0, COND0, TYPE0, 128 | (384 << 16));
308          set_reg_jpeg(dec, vcnipUVD_JPEG_FC_VUP_COEF_CNTL1, COND0, TYPE0, 384 | (128 << 16));
309          set_reg_jpeg(dec, vcnipUVD_JPEG_FC_VUP_COEF_CNTL2, COND0, TYPE0, 128 | (384 << 16));
310          set_reg_jpeg(dec, vcnipUVD_JPEG_FC_VUP_COEF_CNTL3, COND0, TYPE0, 384 | (128 << 16));
311          set_reg_jpeg(dec, vcnipUVD_JPEG_FC_HUP_COEF_CNTL0, COND0, TYPE0, 128 | (384 << 16));
312          set_reg_jpeg(dec, vcnipUVD_JPEG_FC_HUP_COEF_CNTL1, COND0, TYPE0, 384 | (128 << 16));
313          set_reg_jpeg(dec, vcnipUVD_JPEG_FC_HUP_COEF_CNTL2, COND0, TYPE0, 128 | (384 << 16));
314          set_reg_jpeg(dec, vcnipUVD_JPEG_FC_HUP_COEF_CNTL3, COND0, TYPE0, 384 | (128 << 16));
315       } else
316          set_reg_jpeg(dec, vcnipUVD_JPEG_FC_SPS_INFO, COND0, TYPE0, 1 | (1 << 5) | (255 << 8));
317    }
318    set_reg_jpeg(dec, dec->jpg_reg.jpeg_tier_cntl2, COND0, 0, 0);
319 
320    // set output buffer read pointer
321    set_reg_jpeg(dec, dec->jpg_reg.jpeg_outbuf_rptr, COND0, TYPE0, 0);
322    set_reg_jpeg(dec, dec->jpg_reg.jpeg_outbuf_cntl, COND0, TYPE0,
323                 ((0x00001587 & (~0x00000180L)) | (0x1 << 0x7) | (0x1 << 0x6)));
324 
325    // enable error interrupts
326    set_reg_jpeg(dec, dec->jpg_reg.jpeg_int_en, COND0, TYPE0, 0xFFFFFFFE);
327 
328    // start engine command
329    val = 0x6;
330    if (dec->jpg_reg.version == RDECODE_JPEG_REG_VER_V3) {
331       if (dec->jpg.crop_width && dec->jpg.crop_height)
332          val = val | (0x1 << 24);
333       if (format_convert)
334          val = val |  (1 << 16) | (1 << 18);
335    }
336    set_reg_jpeg(dec, dec->jpg_reg.jpeg_cntl, COND0, TYPE0, val);
337 
338    // wait for job completion, wait for job JBSI fetch done
339    set_reg_jpeg(dec, dec->jpg_reg.jrbc_ib_ref_data, COND0, TYPE0, (dec->jpg.bsd_size >> 2));
340    set_reg_jpeg(dec, dec->jpg_reg.jrbc_ib_cond_rd_timer, COND0, TYPE0, 0x01400200);
341    set_reg_jpeg(dec, dec->jpg_reg.jpeg_rb_rptr, COND3, TYPE3, 0xFFFFFFFF);
342 
343    // wait for job jpeg outbuf idle
344    set_reg_jpeg(dec, dec->jpg_reg.jrbc_ib_ref_data, COND0, TYPE0, 0xFFFFFFFF);
345    set_reg_jpeg(dec, dec->jpg_reg.jpeg_outbuf_wptr, COND3, TYPE3, 0x00000001);
346 
347    if (dec->jpg_reg.version == RDECODE_JPEG_REG_VER_V3 && format_convert) {
348       val = val | (0x7 << 16);
349       set_reg_jpeg(dec, dec->jpg_reg.jrbc_ib_ref_data, COND0, TYPE0, 0);
350       set_reg_jpeg(dec, vcnipUVD_JPEG_INT_STAT, COND3, TYPE3, val);
351    }
352 
353    // stop engine
354    set_reg_jpeg(dec, dec->jpg_reg.jpeg_cntl, COND0, TYPE0, 0x4);
355 }
356 
357 /**
358  * send cmd for vcn jpeg
359  */
send_cmd_jpeg(struct radeon_decoder * dec,struct pipe_video_buffer * target,struct pipe_picture_desc * picture)360 void send_cmd_jpeg(struct radeon_decoder *dec, struct pipe_video_buffer *target,
361                    struct pipe_picture_desc *picture)
362 {
363    struct pb_buffer_lean *dt;
364    struct rvid_buffer *bs_buf;
365 
366    bs_buf = &dec->bs_buffers[dec->cur_buffer];
367 
368    memset(dec->bs_ptr, 0, align(dec->bs_size, 128) - dec->bs_size);
369    dec->ws->buffer_unmap(dec->ws, bs_buf->res->buf);
370    dec->bs_ptr = NULL;
371 
372    dt = radeon_jpeg_get_decode_param(dec, target, picture);
373 
374    if (dec->jpg_reg.version == RDECODE_JPEG_REG_VER_V1) {
375       send_cmd_bitstream(dec, bs_buf->res->buf, 0, RADEON_USAGE_READ, RADEON_DOMAIN_GTT);
376       send_cmd_target(dec, dt, 0, RADEON_USAGE_WRITE, RADEON_DOMAIN_VRAM);
377    } else {
378       send_cmd_bitstream_direct(dec, bs_buf->res->buf, 0, RADEON_USAGE_READ, RADEON_DOMAIN_GTT);
379       send_cmd_target_direct(dec, dt, 0, RADEON_USAGE_WRITE, RADEON_DOMAIN_VRAM, target->buffer_format);
380    }
381 }
382