1 /*
2 * Copyright 2015 Rockchip Electronics Co. LTD
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define MODULE_TAG "hal_m2vd_vdpu1"
18
19 #include <string.h>
20
21 #include "mpp_mem.h"
22 #include "mpp_common.h"
23
24 #include "hal_m2vd_base.h"
25 #include "hal_m2vd_vdpu1_reg.h"
26 #include "hal_m2vd_vpu1.h"
27
hal_m2vd_vdpu1_init(void * hal,MppHalCfg * cfg)28 MPP_RET hal_m2vd_vdpu1_init(void *hal, MppHalCfg *cfg)
29 {
30 MPP_RET ret = MPP_OK;
31 M2vdHalCtx *ctx = (M2vdHalCtx *)hal;
32 M2vdVdpu1Reg_t *regs = NULL;
33
34 regs = mpp_calloc(M2vdVdpu1Reg_t, 1);
35 if (NULL == regs) {
36 mpp_err_f("failed to malloc register ret\n");
37 ret = MPP_ERR_MALLOC;
38 goto __ERR_RET;
39 }
40
41 ctx->reg_len = M2VD_VDPU1_REG_NUM;
42
43 ret = mpp_dev_init(&ctx->dev, VPU_CLIENT_VDPU1);
44 if (ret) {
45 mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
46 ret = MPP_ERR_UNKNOW;
47 goto __ERR_RET;
48 }
49 if (ctx->group == NULL) {
50 ret = mpp_buffer_group_get_internal(&ctx->group, MPP_BUFFER_TYPE_ION);
51 if (ret) {
52 mpp_err("m2v_hal mpp_buffer_group_get failed\n");
53 goto __ERR_RET;
54 }
55 }
56 ret = mpp_buffer_get(ctx->group, &ctx->qp_table, M2VD_BUF_SIZE_QPTAB);
57 if (ret) {
58 mpp_err("m2v_hal_qtable_base get buffer failed\n");
59 goto __ERR_RET;
60 }
61
62 ctx->packet_slots = cfg->packet_slots;
63 ctx->frame_slots = cfg->frame_slots;
64 ctx->dec_cb = cfg->dec_cb;
65 ctx->regs = (void*)regs;
66 cfg->dev = ctx->dev;
67
68 return ret;
69
70 __ERR_RET:
71 if (regs) {
72 mpp_free(regs);
73 regs = NULL;
74 }
75
76 if (ctx) {
77 hal_m2vd_vdpu1_deinit(ctx);
78 }
79
80 return ret;
81 }
82
hal_m2vd_vdpu1_deinit(void * hal)83 MPP_RET hal_m2vd_vdpu1_deinit(void *hal)
84 {
85 MPP_RET ret = MPP_OK;
86 M2vdHalCtx *p = (M2vdHalCtx *)hal;
87
88 if (p->dev) {
89 mpp_dev_deinit(p->dev);
90 p->dev = NULL;
91 }
92
93 if (p->qp_table) {
94 ret = mpp_buffer_put(p->qp_table);
95 p->qp_table = NULL;
96 if (MPP_OK != ret) {
97 mpp_err("m2v_hal qp_table put buffer failed\n");
98 return ret;
99 }
100 }
101
102 if (p->group) {
103 ret = mpp_buffer_group_put(p->group);
104 p->group = NULL;
105 if (ret) {
106 mpp_err("m2v_hal group free buffer failed\n");
107 return ret;
108 }
109 }
110
111 return ret;
112 }
113
hal_m2vd_vdpu1_init_hwcfg(M2vdHalCtx * ctx)114 static MPP_RET hal_m2vd_vdpu1_init_hwcfg(M2vdHalCtx *ctx)
115 {
116 M2vdVdpu1Reg_t *p_regs = (M2vdVdpu1Reg_t *)ctx->regs;
117
118 memset(p_regs, 0, sizeof(M2vdVdpu1Reg_t));
119 p_regs->sw02.dec_axi_rn_id = 0;
120 p_regs->sw02.dec_timeout_e = 1;
121 p_regs->sw02.dec_strswap32_e = 1;
122 p_regs->sw02.dec_strendian_e = 1;
123 p_regs->sw02.dec_inswap32_e = 1;
124 p_regs->sw02.dec_outswap32_e = 1;
125
126 p_regs->sw02.dec_clk_gate_e = 1;
127 p_regs->sw02.dec_in_endian = 1;
128 p_regs->sw02.dec_out_endian = 1;
129
130 p_regs->sw02.dec_out_tiled_e = 0;
131 p_regs->sw02.dec_max_burst = DEC_BUS_BURST_LENGTH_16;
132 p_regs->sw02.dec_scmd_dis = 0;
133 p_regs->sw02.dec_adv_pre_dis = 0;
134 p_regs->sw55.apf_threshold = 8;
135 p_regs->sw02.dec_latency = 0;
136 p_regs->sw02.dec_data_disc_e = 0;
137 p_regs->sw01.dec_irq = 0;
138 p_regs->sw02.dec_axi_rn_id = 0;
139 p_regs->sw03.dec_axi_wr_id = 0;
140 p_regs->sw03.dec_mode = 8;
141
142 return MPP_OK;
143 }
144
hal_m2vd_vdpu1_gen_regs(void * hal,HalTaskInfo * task)145 MPP_RET hal_m2vd_vdpu1_gen_regs(void *hal, HalTaskInfo *task)
146 {
147 MPP_RET ret = MPP_OK;
148
149 if (task->dec.valid) {
150 void *q_table = NULL;
151 MppBuffer streambuf = NULL;
152 MppBuffer framebuf = NULL;
153 M2vdHalCtx *ctx = (M2vdHalCtx *)hal;
154 M2VDDxvaParam *dx = (M2VDDxvaParam *)task->dec.syntax.data;
155 M2vdVdpu1Reg_t *p_regs = (M2vdVdpu1Reg_t*) ctx->regs;
156
157 task->dec.valid = 0;
158 q_table = mpp_buffer_get_ptr(ctx->qp_table);
159 memcpy(q_table, dx->qp_tab, M2VD_BUF_SIZE_QPTAB);
160 mpp_buffer_sync_end(ctx->qp_table);
161
162 hal_m2vd_vdpu1_init_hwcfg(ctx);
163
164 p_regs->sw18.mv_accuracy_fwd = 1;
165 p_regs->sw18.mv_accuracy_bwd = 1;
166 if (dx->seq_ext_head_dec_flag) {
167 p_regs->sw03.dec_mode = 5;
168 p_regs->sw18.fcode_fwd_hor = dx->pic.full_pel_forward_vector;
169 p_regs->sw18.fcode_fwd_ver = dx->pic.forward_f_code;
170 p_regs->sw18.fcode_bwd_hor = dx->pic.full_pel_backward_vector;
171 p_regs->sw18.fcode_bwd_ver = dx->pic.backward_f_code;
172 } else {
173 p_regs->sw03.dec_mode = 6;
174 p_regs->sw18.fcode_fwd_hor = dx->pic.forward_f_code;
175 p_regs->sw18.fcode_fwd_ver = dx->pic.forward_f_code;
176 p_regs->sw18.fcode_bwd_hor = dx->pic.backward_f_code;
177 p_regs->sw18.fcode_bwd_ver = dx->pic.backward_f_code;
178 if (dx->pic.full_pel_forward_vector)
179 p_regs->sw18.mv_accuracy_fwd = 0;
180 if (dx->pic.full_pel_backward_vector)
181 p_regs->sw18.mv_accuracy_bwd = 0;
182 }
183
184 p_regs->sw04.pic_mb_width = (dx->seq.decode_width + 15) >> 4;
185 p_regs->sw04.pic_mb_height_p = (dx->seq.decode_height + 15) >> 4;
186 p_regs->sw03.pic_interlace_e = 1 - dx->seq_ext.progressive_sequence;
187 if (dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_FRAME)
188 p_regs->sw03.pic_fieldmode_e = 0;
189 else {
190 p_regs->sw03.pic_fieldmode_e = 1;
191 p_regs->sw03.pic_topfield_e = dx->pic_code_ext.picture_structure == 1;
192 }
193 if (dx->pic.picture_coding_type == M2VD_CODING_TYPE_B)
194 p_regs->sw03.pic_b_e = 1;
195 else
196 p_regs->sw03.pic_b_e = 0;
197 if (dx->pic.picture_coding_type == M2VD_CODING_TYPE_I)
198 p_regs->sw03.pic_inter_e = 0;
199 else
200 p_regs->sw03.pic_inter_e = 1;
201
202 p_regs->sw04.topfieldfirst_e = dx->pic_code_ext.top_field_first;
203 p_regs->sw03.fwd_interlace_e = 0;
204 p_regs->sw03.write_mvs_e = 0;
205 p_regs->sw04.alt_scan_e = dx->pic_code_ext.alternate_scan;
206 p_regs->sw18.alt_scan_flag_e = dx->pic_code_ext.alternate_scan;
207
208 p_regs->sw05.qscale_type = dx->pic_code_ext.q_scale_type;
209 p_regs->sw05.intra_dc_prec = dx->pic_code_ext.intra_dc_precision;
210 p_regs->sw05.con_mv_e = dx->pic_code_ext.concealment_motion_vectors;
211 p_regs->sw05.intra_vlc_tab = dx->pic_code_ext.intra_vlc_format;
212 p_regs->sw05.frame_pred_dct = dx->pic_code_ext.frame_pred_frame_dct;
213 p_regs->sw06.init_qp = 1;
214
215 mpp_buf_slot_get_prop(ctx->packet_slots, task->dec.input, SLOT_BUFFER, &streambuf);
216 p_regs->sw12.rlc_vlc_base = mpp_buffer_get_fd(streambuf);
217 if (dx->bitstream_offset) {
218 mpp_dev_set_reg_offset(ctx->dev, 12, dx->bitstream_offset);
219 }
220
221 mpp_buf_slot_get_prop(ctx->frame_slots, dx->CurrPic.Index7Bits, SLOT_BUFFER, &framebuf);
222
223 if ((dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) ||
224 (dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_FRAME)) {
225 p_regs->sw13.dec_out_base = mpp_buffer_get_fd(framebuf);
226 } else {
227 p_regs->sw13.dec_out_base = mpp_buffer_get_fd(framebuf);
228 mpp_dev_set_reg_offset(ctx->dev, 13, MPP_ALIGN(dx->seq.decode_width, 16));
229 }
230
231 mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[0].Index7Bits, SLOT_BUFFER, &framebuf);
232 p_regs->sw14.refer0_base = mpp_buffer_get_fd(framebuf);
233
234 mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[1].Index7Bits, SLOT_BUFFER, &framebuf);
235 p_regs->sw15.refer1_base = mpp_buffer_get_fd(framebuf);
236
237 mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[2].Index7Bits, SLOT_BUFFER, &framebuf);
238 p_regs->sw16.refer2_base = mpp_buffer_get_fd(framebuf);
239
240 mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[3].Index7Bits, SLOT_BUFFER, &framebuf);
241 p_regs->sw17.refer3_base = mpp_buffer_get_fd(framebuf);
242
243 p_regs->sw40.qtable_base = mpp_buffer_get_fd(ctx->qp_table);
244
245 p_regs->sw48.startmb_x = 0;
246 p_regs->sw48.startmb_y = 0;
247 p_regs->sw03.dec_out_dis = 0;
248 p_regs->sw03.filtering_dis = 1;
249 p_regs->sw06.stream_len = dx->bitstream_length;
250 p_regs->sw05.stream_start_bit = dx->bitstream_start_bit;
251 p_regs->sw01.dec_e = 1;
252
253 task->dec.valid = 1;
254 ctx->dec_frame_cnt++;
255 }
256
257 return ret;
258 }
259
hal_m2vd_vdpu1_start(void * hal,HalTaskInfo * task)260 MPP_RET hal_m2vd_vdpu1_start(void *hal, HalTaskInfo *task)
261 {
262 MPP_RET ret = MPP_OK;
263 M2vdHalCtx *ctx = (M2vdHalCtx *)hal;
264
265 do {
266 MppDevRegWrCfg wr_cfg;
267 MppDevRegRdCfg rd_cfg;
268 RK_U32 *regs = (RK_U32 *)ctx->regs;
269 RK_U32 reg_size = sizeof(M2vdVdpu1Reg_t);
270
271 wr_cfg.reg = regs;
272 wr_cfg.size = reg_size;
273 wr_cfg.offset = 0;
274
275 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
276 if (ret) {
277 mpp_err_f("set register write failed %d\n", ret);
278 break;
279 }
280
281 rd_cfg.reg = regs;
282 rd_cfg.size = reg_size;
283 rd_cfg.offset = 0;
284
285 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
286 if (ret) {
287 mpp_err_f("set register read failed %d\n", ret);
288 break;
289 }
290
291 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
292 if (ret) {
293 mpp_err_f("send cmd failed %d\n", ret);
294 break;
295 }
296 } while (0);
297
298 (void)task;
299 return ret;
300 }
301
hal_m2vd_vdpu1_wait(void * hal,HalTaskInfo * task)302 MPP_RET hal_m2vd_vdpu1_wait(void *hal, HalTaskInfo *task)
303 {
304 MPP_RET ret = MPP_OK;
305 M2vdHalCtx *ctx = (M2vdHalCtx *)hal;
306 M2vdVdpu1Reg_t* reg_out = (M2vdVdpu1Reg_t * )ctx->regs;
307
308 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
309 if (ret)
310 mpp_err_f("poll cmd failed %d\n", ret);
311
312 if (reg_out->sw01.dec_error_int | reg_out->sw01.dec_buffer_int) {
313 if (ctx->dec_cb)
314 mpp_callback(ctx->dec_cb, NULL);
315 }
316
317 (void)task;
318
319 return ret;
320 }
321