1 /**************************************************************************
3 * Copyright 2018 Advanced Micro Devices, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
31 #include "pipe/p_video_codec.h"
33 #include "util/u_memory.h"
34 #include "util/u_video.h"
36 #include "radeonsi/si_pipe.h"
37 #include "radeon_video.h"
38 #include "radeon_vcn_dec.h"
40 static struct pb_buffer
*radeon_jpeg_get_decode_param(struct radeon_decoder
*dec
,
41 struct pipe_video_buffer
*target
,
42 struct pipe_picture_desc
*picture
)
44 struct si_texture
*luma
= (struct si_texture
*)
45 ((struct vl_video_buffer
*)target
)->resources
[0];
46 struct si_texture
*chroma
= (struct si_texture
*)
47 ((struct vl_video_buffer
*)target
)->resources
[1];
49 dec
->jpg
.bsd_size
= align(dec
->bs_size
, 128);
50 dec
->jpg
.dt_luma_top_offset
= luma
->surface
.u
.gfx9
.surf_offset
;
51 if (target
->buffer_format
== PIPE_FORMAT_NV12
)
52 dec
->jpg
.dt_chroma_top_offset
= chroma
->surface
.u
.gfx9
.surf_offset
;
53 dec
->jpg
.dt_pitch
= luma
->surface
.u
.gfx9
.surf_pitch
* luma
->surface
.blk_w
;
54 dec
->jpg
.dt_uv_pitch
= dec
->jpg
.dt_pitch
/ 2;
56 return luma
->buffer
.buf
;
59 /* add a new set register command to the IB */
60 static void set_reg_jpeg(struct radeon_decoder
*dec
, unsigned reg
,
61 unsigned cond
, unsigned type
, uint32_t val
)
63 radeon_emit(dec
->cs
, RDECODE_PKTJ(reg
, cond
, type
));
64 radeon_emit(dec
->cs
, val
);
67 /* send a bitstream buffer command */
68 static void send_cmd_bitstream(struct radeon_decoder
*dec
,
69 struct pb_buffer
* buf
, uint32_t off
,
70 enum radeon_bo_usage usage
, enum radeon_bo_domain domain
)
75 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_CNTL
), COND0
, TYPE0
, 1);
77 // ensuring the Reset is asserted in SCLK domain
78 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_INDEX
), COND0
, TYPE0
, 0x01C2);
79 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_DATA
), COND0
, TYPE0
, 0x01400200);
80 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_INDEX
), COND0
, TYPE0
, 0x01C3);
81 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_DATA
), COND0
, TYPE0
, (1 << 9));
82 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_SOFT_RESET
), COND0
, TYPE3
, (1 << 9));
85 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_CNTL
), COND0
, TYPE0
, 0);
87 // ensuring the Reset is de-asserted in SCLK domain
88 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_INDEX
), COND0
, TYPE0
, 0x01C3);
89 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_DATA
), COND0
, TYPE0
, (0 << 9));
90 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_SOFT_RESET
), COND0
, TYPE3
, (1 << 9));
92 dec
->ws
->cs_add_buffer(dec
->cs
, buf
, usage
| RADEON_USAGE_SYNCHRONIZED
,
94 addr
= dec
->ws
->buffer_get_virtual_address(buf
);
97 // set UVD_LMI_JPEG_READ_64BIT_BAR_LOW/HIGH based on bitstream buffer address
98 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_LMI_JPEG_READ_64BIT_BAR_HIGH
), COND0
, TYPE0
, (addr
>> 32));
99 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_LMI_JPEG_READ_64BIT_BAR_LOW
), COND0
, TYPE0
, addr
);
102 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_RB_BASE
), COND0
, TYPE0
, 0);
105 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_RB_SIZE
), COND0
, TYPE0
, 0xFFFFFFF0);
108 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_RB_WPTR
), COND0
, TYPE0
, (dec
->jpg
.bsd_size
>> 2));
111 /* send a target buffer command */
112 static void send_cmd_target(struct radeon_decoder
*dec
,
113 struct pb_buffer
* buf
, uint32_t off
,
114 enum radeon_bo_usage usage
, enum radeon_bo_domain domain
)
118 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_PITCH
), COND0
, TYPE0
, (dec
->jpg
.dt_pitch
>> 4));
119 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_UV_PITCH
), COND0
, TYPE0
, ((dec
->jpg
.dt_uv_pitch
* 2) >> 4));
121 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_TILING_CTRL
), COND0
, TYPE0
, 0);
122 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_UV_TILING_CTRL
), COND0
, TYPE0
, 0);
124 dec
->ws
->cs_add_buffer(dec
->cs
, buf
, usage
| RADEON_USAGE_SYNCHRONIZED
,
126 addr
= dec
->ws
->buffer_get_virtual_address(buf
);
129 // set UVD_LMI_JPEG_WRITE_64BIT_BAR_LOW/HIGH based on target buffer address
130 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_LMI_JPEG_WRITE_64BIT_BAR_HIGH
), COND0
, TYPE0
, (addr
>> 32));
131 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_LMI_JPEG_WRITE_64BIT_BAR_LOW
), COND0
, TYPE0
, addr
);
133 // set output buffer data address
134 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_INDEX
), COND0
, TYPE0
, 0);
135 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_DATA
), COND0
, TYPE0
, dec
->jpg
.dt_luma_top_offset
);
136 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_INDEX
), COND0
, TYPE0
, 1);
137 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_DATA
), COND0
, TYPE0
, dec
->jpg
.dt_chroma_top_offset
);
138 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_TIER_CNTL2
), COND0
, TYPE3
, 0);
140 // set output buffer read pointer
141 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_OUTBUF_RPTR
), COND0
, TYPE0
, 0);
143 // enable error interrupts
144 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_INT_EN
), COND0
, TYPE0
, 0xFFFFFFFE);
146 // start engine command
147 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_CNTL
), COND0
, TYPE0
, 0x6);
149 // wait for job completion, wait for job JBSI fetch done
150 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_INDEX
), COND0
, TYPE0
, 0x01C3);
151 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_DATA
), COND0
, TYPE0
, (dec
->jpg
.bsd_size
>> 2));
152 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_INDEX
), COND0
, TYPE0
, 0x01C2);
153 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_DATA
), COND0
, TYPE0
, 0x01400200);
154 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_RB_RPTR
), COND0
, TYPE3
, 0xFFFFFFFF);
156 // wait for job jpeg outbuf idle
157 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_INDEX
), COND0
, TYPE0
, 0x01C3);
158 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_DATA
), COND0
, TYPE0
, 0xFFFFFFFF);
159 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_OUTBUF_WPTR
), COND0
, TYPE3
, 0x00000001);
162 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_CNTL
), COND0
, TYPE0
, 0x4);
164 // asserting jpeg lmi drop
165 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_INDEX
), COND0
, TYPE0
, 0x0005);
166 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_DATA
), COND0
, TYPE0
, (1 << 23 | 1 << 0));
167 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_DATA
), COND0
, TYPE1
, 0);
169 // asserting jpeg reset
170 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_CNTL
), COND0
, TYPE0
, 1);
172 // ensure reset is asserted in sclk domain
173 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_INDEX
), COND0
, TYPE0
, 0x01C3);
174 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_DATA
), COND0
, TYPE0
, (1 << 9));
175 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_SOFT_RESET
), COND0
, TYPE3
, (1 << 9));
177 // de-assert jpeg reset
178 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_JPEG_CNTL
), COND0
, TYPE0
, 0);
180 // ensure reset is de-asserted in sclk domain
181 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_INDEX
), COND0
, TYPE0
, 0x01C3);
182 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_DATA
), COND0
, TYPE0
, (0 << 9));
183 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_SOFT_RESET
), COND0
, TYPE3
, (1 << 9));
185 // de-asserting jpeg lmi drop
186 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_INDEX
), COND0
, TYPE0
, 0x0005);
187 set_reg_jpeg(dec
, SOC15_REG_ADDR(mmUVD_CTX_DATA
), COND0
, TYPE0
, 0);
190 /* send a bitstream buffer command */
191 static void send_cmd_bitstream_direct(struct radeon_decoder
*dec
,
192 struct pb_buffer
* buf
, uint32_t off
,
193 enum radeon_bo_usage usage
, enum radeon_bo_domain domain
)
198 set_reg_jpeg(dec
, vcnipUVD_JPEG_DEC_SOFT_RST
, COND0
, TYPE0
, 1);
200 // ensuring the Reset is asserted in SCLK domain
201 set_reg_jpeg(dec
, vcnipUVD_JRBC_IB_COND_RD_TIMER
, COND0
, TYPE0
, 0x01400200);
202 set_reg_jpeg(dec
, vcnipUVD_JRBC_IB_REF_DATA
, COND0
, TYPE0
, (0x1 << 0x10));
203 set_reg_jpeg(dec
, vcnipUVD_JPEG_DEC_SOFT_RST
, COND3
, TYPE3
, (0x1 << 0x10));
206 set_reg_jpeg(dec
, vcnipUVD_JPEG_DEC_SOFT_RST
, COND0
, TYPE0
, 0);
208 // ensuring the Reset is de-asserted in SCLK domain
209 set_reg_jpeg(dec
, vcnipUVD_JRBC_IB_REF_DATA
, COND0
, TYPE0
, (0 << 0x10));
210 set_reg_jpeg(dec
, vcnipUVD_JPEG_DEC_SOFT_RST
, COND3
, TYPE3
, (0x1 << 0x10));
212 dec
->ws
->cs_add_buffer(dec
->cs
, buf
, usage
| RADEON_USAGE_SYNCHRONIZED
,
214 addr
= dec
->ws
->buffer_get_virtual_address(buf
);
217 // set UVD_LMI_JPEG_READ_64BIT_BAR_LOW/HIGH based on bitstream buffer address
218 set_reg_jpeg(dec
, vcnipUVD_LMI_JPEG_READ_64BIT_BAR_HIGH
, COND0
, TYPE0
, (addr
>> 32));
219 set_reg_jpeg(dec
, vcnipUVD_LMI_JPEG_READ_64BIT_BAR_LOW
, COND0
, TYPE0
, addr
);
222 set_reg_jpeg(dec
, vcnipUVD_JPEG_RB_BASE
, COND0
, TYPE0
, 0);
225 set_reg_jpeg(dec
, vcnipUVD_JPEG_RB_SIZE
, COND0
, TYPE0
, 0xFFFFFFF0);
228 set_reg_jpeg(dec
, vcnipUVD_JPEG_RB_WPTR
, COND0
, TYPE0
, (dec
->jpg
.bsd_size
>> 2));
231 /* send a target buffer command */
232 static void send_cmd_target_direct(struct radeon_decoder
*dec
,
233 struct pb_buffer
* buf
, uint32_t off
,
234 enum radeon_bo_usage usage
, enum radeon_bo_domain domain
)
238 set_reg_jpeg(dec
, vcnipUVD_JPEG_PITCH
, COND0
, TYPE0
, (dec
->jpg
.dt_pitch
>> 4));
239 set_reg_jpeg(dec
, vcnipUVD_JPEG_UV_PITCH
, COND0
, TYPE0
, ((dec
->jpg
.dt_uv_pitch
* 2) >> 4));
241 set_reg_jpeg(dec
, vcnipJPEG_DEC_ADDR_MODE
, COND0
, TYPE0
, 0);
242 set_reg_jpeg(dec
, vcnipJPEG_DEC_Y_GFX10_TILING_SURFACE
, COND0
, TYPE0
, 0);
243 set_reg_jpeg(dec
, vcnipJPEG_DEC_UV_GFX10_TILING_SURFACE
, COND0
, TYPE0
, 0);
245 dec
->ws
->cs_add_buffer(dec
->cs
, buf
, usage
| RADEON_USAGE_SYNCHRONIZED
,
247 addr
= dec
->ws
->buffer_get_virtual_address(buf
);
250 // set UVD_LMI_JPEG_WRITE_64BIT_BAR_LOW/HIGH based on target buffer address
251 set_reg_jpeg(dec
, vcnipUVD_LMI_JPEG_WRITE_64BIT_BAR_HIGH
, COND0
, TYPE0
, (addr
>> 32));
252 set_reg_jpeg(dec
, vcnipUVD_LMI_JPEG_WRITE_64BIT_BAR_LOW
, COND0
, TYPE0
, addr
);
254 // set output buffer data address
255 set_reg_jpeg(dec
, vcnipUVD_JPEG_INDEX
, COND0
, TYPE0
, 0);
256 set_reg_jpeg(dec
, vcnipUVD_JPEG_DATA
, COND0
, TYPE0
, dec
->jpg
.dt_luma_top_offset
);
257 set_reg_jpeg(dec
, vcnipUVD_JPEG_INDEX
, COND0
, TYPE0
, 1);
258 set_reg_jpeg(dec
, vcnipUVD_JPEG_DATA
, COND0
, TYPE0
, dec
->jpg
.dt_chroma_top_offset
);
259 set_reg_jpeg(dec
, vcnipUVD_JPEG_TIER_CNTL2
, COND0
, 0, 0);
261 // set output buffer read pointer
262 set_reg_jpeg(dec
, vcnipUVD_JPEG_OUTBUF_RPTR
, COND0
, TYPE0
, 0);
263 set_reg_jpeg(dec
, vcnipUVD_JPEG_OUTBUF_CNTL
, COND0
, TYPE0
, ((0x00001587 & (~0x00000180L
)) | (0x1 << 0x7) | (0x1 << 0x6)));
265 // enable error interrupts
266 set_reg_jpeg(dec
, vcnipUVD_JPEG_INT_EN
, COND0
, TYPE0
, 0xFFFFFFFE);
268 // start engine command
269 set_reg_jpeg(dec
, vcnipUVD_JPEG_CNTL
, COND0
, TYPE0
, 0xE);
271 // wait for job completion, wait for job JBSI fetch done
272 set_reg_jpeg(dec
, vcnipUVD_JRBC_IB_REF_DATA
, COND0
, TYPE0
, (dec
->jpg
.bsd_size
>> 2));
273 set_reg_jpeg(dec
, vcnipUVD_JRBC_IB_COND_RD_TIMER
, COND0
, TYPE0
, 0x01400200);
274 set_reg_jpeg(dec
, vcnipUVD_JPEG_RB_RPTR
, COND3
, TYPE3
, 0xFFFFFFFF);
276 // wait for job jpeg outbuf idle
277 set_reg_jpeg(dec
, vcnipUVD_JRBC_IB_REF_DATA
, COND0
, TYPE0
, 0xFFFFFFFF);
278 set_reg_jpeg(dec
, vcnipUVD_JPEG_OUTBUF_WPTR
, COND3
, TYPE3
, 0x00000001);
281 set_reg_jpeg(dec
, vcnipUVD_JPEG_CNTL
, COND0
, TYPE0
, 0x4);
285 * send cmd for vcn jpeg
287 void send_cmd_jpeg(struct radeon_decoder
*dec
,
288 struct pipe_video_buffer
*target
,
289 struct pipe_picture_desc
*picture
)
291 struct pb_buffer
*dt
;
292 struct rvid_buffer
*bs_buf
;
294 bs_buf
= &dec
->bs_buffers
[dec
->cur_buffer
];
296 memset(dec
->bs_ptr
, 0, align(dec
->bs_size
, 128) - dec
->bs_size
);
297 dec
->ws
->buffer_unmap(bs_buf
->res
->buf
);
299 dt
= radeon_jpeg_get_decode_param(dec
, target
, picture
);
301 if (dec
->jpg
.direct_reg
== true) {
302 send_cmd_bitstream_direct(dec
, bs_buf
->res
->buf
,
303 0, RADEON_USAGE_READ
, RADEON_DOMAIN_GTT
);
304 send_cmd_target_direct(dec
, dt
, 0,
305 RADEON_USAGE_WRITE
, RADEON_DOMAIN_VRAM
);
307 send_cmd_bitstream(dec
, bs_buf
->res
->buf
,
308 0, RADEON_USAGE_READ
, RADEON_DOMAIN_GTT
);
309 send_cmd_target(dec
, dt
, 0,
310 RADEON_USAGE_WRITE
, RADEON_DOMAIN_VRAM
);