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
;
55 else if (target
->buffer_format
== PIPE_FORMAT_YUYV
)
56 dec
->jpg
.dt_pitch
= luma
->surface
.u
.gfx9
.surf_pitch
;
57 dec
->jpg
.dt_uv_pitch
= dec
->jpg
.dt_pitch
/ 2;
59 return luma
->buffer
.buf
;
62 /* add a new set register command to the IB */
63 static void set_reg_jpeg(struct radeon_decoder
*dec
, unsigned reg
,
64 unsigned cond
, unsigned type
, uint32_t val
)
66 radeon_emit(dec
->cs
, RDECODE_PKTJ(SOC15_REG_ADDR(reg
), cond
, type
));
67 radeon_emit(dec
->cs
, val
);
70 /* send a bitstream buffer command */
71 static void send_cmd_bitstream(struct radeon_decoder
*dec
,
72 struct pb_buffer
* buf
, uint32_t off
,
73 enum radeon_bo_usage usage
, enum radeon_bo_domain domain
)
78 set_reg_jpeg(dec
, mmUVD_JPEG_CNTL
, COND0
, TYPE0
, 1);
80 // ensuring the Reset is asserted in SCLK domain
81 set_reg_jpeg(dec
, mmUVD_CTX_INDEX
, COND0
, TYPE0
, 0x01C2);
82 set_reg_jpeg(dec
, mmUVD_CTX_DATA
, COND0
, TYPE0
, 0x01400200);
83 set_reg_jpeg(dec
, mmUVD_CTX_INDEX
, COND0
, TYPE0
, 0x01C3);
84 set_reg_jpeg(dec
, mmUVD_CTX_DATA
, COND0
, TYPE0
, (1 << 9));
85 set_reg_jpeg(dec
, mmUVD_SOFT_RESET
, COND0
, TYPE3
, (1 << 9));
88 set_reg_jpeg(dec
, mmUVD_JPEG_CNTL
, COND0
, TYPE0
, 0);
90 // ensuring the Reset is de-asserted in SCLK domain
91 set_reg_jpeg(dec
, mmUVD_CTX_INDEX
, COND0
, TYPE0
, 0x01C3);
92 set_reg_jpeg(dec
, mmUVD_CTX_DATA
, COND0
, TYPE0
, (0 << 9));
93 set_reg_jpeg(dec
, mmUVD_SOFT_RESET
, COND0
, TYPE3
, (1 << 9));
95 dec
->ws
->cs_add_buffer(dec
->cs
, buf
, usage
| RADEON_USAGE_SYNCHRONIZED
,
97 addr
= dec
->ws
->buffer_get_virtual_address(buf
);
100 // set UVD_LMI_JPEG_READ_64BIT_BAR_LOW/HIGH based on bitstream buffer address
101 set_reg_jpeg(dec
, mmUVD_LMI_JPEG_READ_64BIT_BAR_HIGH
, COND0
, TYPE0
, (addr
>> 32));
102 set_reg_jpeg(dec
, mmUVD_LMI_JPEG_READ_64BIT_BAR_LOW
, COND0
, TYPE0
, addr
);
105 set_reg_jpeg(dec
, mmUVD_JPEG_RB_BASE
, COND0
, TYPE0
, 0);
108 set_reg_jpeg(dec
, mmUVD_JPEG_RB_SIZE
, COND0
, TYPE0
, 0xFFFFFFF0);
111 set_reg_jpeg(dec
, mmUVD_JPEG_RB_WPTR
, COND0
, TYPE0
, (dec
->jpg
.bsd_size
>> 2));
114 /* send a target buffer command */
115 static void send_cmd_target(struct radeon_decoder
*dec
,
116 struct pb_buffer
* buf
, uint32_t off
,
117 enum radeon_bo_usage usage
, enum radeon_bo_domain domain
)
121 set_reg_jpeg(dec
, mmUVD_JPEG_PITCH
, COND0
, TYPE0
, (dec
->jpg
.dt_pitch
>> 4));
122 set_reg_jpeg(dec
, mmUVD_JPEG_UV_PITCH
, COND0
, TYPE0
, ((dec
->jpg
.dt_uv_pitch
* 2) >> 4));
124 set_reg_jpeg(dec
, mmUVD_JPEG_TILING_CTRL
, COND0
, TYPE0
, 0);
125 set_reg_jpeg(dec
, mmUVD_JPEG_UV_TILING_CTRL
, COND0
, TYPE0
, 0);
127 dec
->ws
->cs_add_buffer(dec
->cs
, buf
, usage
| RADEON_USAGE_SYNCHRONIZED
,
129 addr
= dec
->ws
->buffer_get_virtual_address(buf
);
132 // set UVD_LMI_JPEG_WRITE_64BIT_BAR_LOW/HIGH based on target buffer address
133 set_reg_jpeg(dec
, mmUVD_LMI_JPEG_WRITE_64BIT_BAR_HIGH
, COND0
, TYPE0
, (addr
>> 32));
134 set_reg_jpeg(dec
, mmUVD_LMI_JPEG_WRITE_64BIT_BAR_LOW
, COND0
, TYPE0
, addr
);
136 // set output buffer data address
137 set_reg_jpeg(dec
, mmUVD_JPEG_INDEX
, COND0
, TYPE0
, 0);
138 set_reg_jpeg(dec
, mmUVD_JPEG_DATA
, COND0
, TYPE0
, dec
->jpg
.dt_luma_top_offset
);
139 set_reg_jpeg(dec
, mmUVD_JPEG_INDEX
, COND0
, TYPE0
, 1);
140 set_reg_jpeg(dec
, mmUVD_JPEG_DATA
, COND0
, TYPE0
, dec
->jpg
.dt_chroma_top_offset
);
141 set_reg_jpeg(dec
, mmUVD_JPEG_TIER_CNTL2
, COND0
, TYPE3
, 0);
143 // set output buffer read pointer
144 set_reg_jpeg(dec
, mmUVD_JPEG_OUTBUF_RPTR
, COND0
, TYPE0
, 0);
146 // enable error interrupts
147 set_reg_jpeg(dec
, mmUVD_JPEG_INT_EN
, COND0
, TYPE0
, 0xFFFFFFFE);
149 // start engine command
150 set_reg_jpeg(dec
, mmUVD_JPEG_CNTL
, COND0
, TYPE0
, 0x6);
152 // wait for job completion, wait for job JBSI fetch done
153 set_reg_jpeg(dec
, mmUVD_CTX_INDEX
, COND0
, TYPE0
, 0x01C3);
154 set_reg_jpeg(dec
, mmUVD_CTX_DATA
, COND0
, TYPE0
, (dec
->jpg
.bsd_size
>> 2));
155 set_reg_jpeg(dec
, mmUVD_CTX_INDEX
, COND0
, TYPE0
, 0x01C2);
156 set_reg_jpeg(dec
, mmUVD_CTX_DATA
, COND0
, TYPE0
, 0x01400200);
157 set_reg_jpeg(dec
, mmUVD_JPEG_RB_RPTR
, COND0
, TYPE3
, 0xFFFFFFFF);
159 // wait for job jpeg outbuf idle
160 set_reg_jpeg(dec
, mmUVD_CTX_INDEX
, COND0
, TYPE0
, 0x01C3);
161 set_reg_jpeg(dec
, mmUVD_CTX_DATA
, COND0
, TYPE0
, 0xFFFFFFFF);
162 set_reg_jpeg(dec
, mmUVD_JPEG_OUTBUF_WPTR
, COND0
, TYPE3
, 0x00000001);
165 set_reg_jpeg(dec
, mmUVD_JPEG_CNTL
, COND0
, TYPE0
, 0x4);
167 // asserting jpeg lmi drop
168 set_reg_jpeg(dec
, mmUVD_CTX_INDEX
, COND0
, TYPE0
, 0x0005);
169 set_reg_jpeg(dec
, mmUVD_CTX_DATA
, COND0
, TYPE0
, (1 << 23 | 1 << 0));
170 set_reg_jpeg(dec
, mmUVD_CTX_DATA
, COND0
, TYPE1
, 0);
172 // asserting jpeg reset
173 set_reg_jpeg(dec
, mmUVD_JPEG_CNTL
, COND0
, TYPE0
, 1);
175 // ensure reset is asserted in sclk domain
176 set_reg_jpeg(dec
, mmUVD_CTX_INDEX
, COND0
, TYPE0
, 0x01C3);
177 set_reg_jpeg(dec
, mmUVD_CTX_DATA
, COND0
, TYPE0
, (1 << 9));
178 set_reg_jpeg(dec
, mmUVD_SOFT_RESET
, COND0
, TYPE3
, (1 << 9));
180 // de-assert jpeg reset
181 set_reg_jpeg(dec
, mmUVD_JPEG_CNTL
, COND0
, TYPE0
, 0);
183 // ensure reset is de-asserted in sclk domain
184 set_reg_jpeg(dec
, mmUVD_CTX_INDEX
, COND0
, TYPE0
, 0x01C3);
185 set_reg_jpeg(dec
, mmUVD_CTX_DATA
, COND0
, TYPE0
, (0 << 9));
186 set_reg_jpeg(dec
, mmUVD_SOFT_RESET
, COND0
, TYPE3
, (1 << 9));
188 // de-asserting jpeg lmi drop
189 set_reg_jpeg(dec
, mmUVD_CTX_INDEX
, COND0
, TYPE0
, 0x0005);
190 set_reg_jpeg(dec
, mmUVD_CTX_DATA
, COND0
, TYPE0
, 0);
194 * send cmd for vcn jpeg
196 void send_cmd_jpeg(struct radeon_decoder
*dec
,
197 struct pipe_video_buffer
*target
,
198 struct pipe_picture_desc
*picture
)
200 struct pb_buffer
*dt
;
201 struct rvid_buffer
*bs_buf
;
203 bs_buf
= &dec
->bs_buffers
[dec
->cur_buffer
];
205 memset(dec
->bs_ptr
, 0, align(dec
->bs_size
, 128) - dec
->bs_size
);
206 dec
->ws
->buffer_unmap(bs_buf
->res
->buf
);
208 dt
= radeon_jpeg_get_decode_param(dec
, target
, picture
);
210 send_cmd_bitstream(dec
, bs_buf
->res
->buf
,
211 0, RADEON_USAGE_READ
, RADEON_DOMAIN_GTT
);
212 send_cmd_target(dec
, dt
, 0,
213 RADEON_USAGE_WRITE
, RADEON_DOMAIN_VRAM
);