1 /*
2 * Copyright 2016 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_vdpu2"
18
19 #include <string.h>
20
21 #include "mpp_env.h"
22 #include "mpp_mem.h"
23 #include "mpp_common.h"
24
25 #include "hal_m2vd_base.h"
26 #include "hal_m2vd_vdpu2_reg.h"
27 #include "hal_m2vd_vpu2.h"
28 #include "hal_m2vd_api.h"
29
hal_m2vd_vdpu2_init(void * hal,MppHalCfg * cfg)30 MPP_RET hal_m2vd_vdpu2_init(void *hal, MppHalCfg *cfg)
31 {
32 MPP_RET ret = MPP_OK;
33 M2vdHalCtx *p = (M2vdHalCtx *)hal;
34 M2vdVdpu2Reg *reg = NULL;
35
36 m2vh_dbg_func("enter\n");
37
38 reg = mpp_calloc(M2vdVdpu2Reg, 1);
39 if (NULL == reg) {
40 mpp_err_f("failed to malloc register ret\n");
41 ret = MPP_ERR_MALLOC;
42 goto __ERR_RET;
43 }
44
45 p->reg_len = M2VD_VDPU2_REG_NUM;
46
47 ret = mpp_dev_init(&p->dev, VPU_CLIENT_VDPU2);
48 if (ret) {
49 mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
50 goto __ERR_RET;
51 }
52
53 if (p->group == NULL) {
54 ret = mpp_buffer_group_get_internal(&p->group, MPP_BUFFER_TYPE_ION);
55 if (ret) {
56 mpp_err("m2v_hal mpp_buffer_group_get failed\n");
57 goto __ERR_RET;
58 }
59 }
60
61 ret = mpp_buffer_get(p->group, &p->qp_table, M2VD_BUF_SIZE_QPTAB);
62 if (ret) {
63 mpp_err("m2v_hal qtable_base get buffer failed\n");
64 goto __ERR_RET;
65 }
66
67 if (M2VH_DBG_DUMP_REG & m2vh_debug) {
68 p->fp_reg_in = fopen("/sdcard/m2vd_dbg_reg_in.txt", "wb");
69 if (p->fp_reg_in == NULL) {
70 mpp_log("file open error: %s", "/sdcard/m2vd_dbg_reg_in.txt");
71 }
72 p->fp_reg_out = fopen("/sdcard/m2vd_dbg_reg_out.txt", "wb");
73 if (p->fp_reg_out == NULL) {
74 mpp_log("file open error: %s", "/sdcard/m2vd_dbg_reg_out.txt");
75 }
76 } else {
77 p->fp_reg_in = NULL;
78 p->fp_reg_out = NULL;
79 }
80
81 //configure
82 p->packet_slots = cfg->packet_slots;
83 p->frame_slots = cfg->frame_slots;
84 p->dec_cb = cfg->dec_cb;
85 p->regs = (void*)reg;
86 cfg->dev = p->dev;
87
88 m2vh_dbg_func("leave\n");
89
90 return ret;
91
92 __ERR_RET:
93 if (reg) {
94 mpp_free(reg);
95 reg = NULL;
96 }
97
98 if (p) {
99 hal_m2vd_vdpu2_deinit(p);
100 }
101
102 return ret;
103 }
104
hal_m2vd_vdpu2_deinit(void * hal)105 MPP_RET hal_m2vd_vdpu2_deinit(void *hal)
106 {
107 MPP_RET ret = MPP_OK;
108 M2vdHalCtx *p = (M2vdHalCtx *)hal;
109
110 m2vh_dbg_func("enter\n");
111
112 if (p->dev) {
113 mpp_dev_deinit(p->dev);
114 p->dev = NULL;
115 }
116
117 if (p->qp_table) {
118 ret = mpp_buffer_put(p->qp_table);
119 p->qp_table = NULL;
120 if (ret) {
121 mpp_err("m2v_hal qp_table put buffer failed\n");
122 return ret;
123 }
124 }
125
126 if (p->group) {
127 ret = mpp_buffer_group_put(p->group);
128 p->group = NULL;
129 if (ret) {
130 mpp_err("m2v_hal group free buffer failed\n");
131 return ret;
132 }
133 }
134
135 if (p->regs) {
136 mpp_free(p->regs);
137 p->regs = NULL;
138 }
139
140 if (p->fp_reg_in) {
141 fclose(p->fp_reg_in);
142 p->fp_reg_in = NULL;
143 }
144 if (p->fp_reg_out) {
145 fclose(p->fp_reg_out);
146 p->fp_reg_out = NULL;
147 }
148
149 m2vh_dbg_func("leave\n");
150 return ret;
151 }
152
hal_m2vd_vdpu2_init_hwcfg(M2vdHalCtx * ctx)153 static MPP_RET hal_m2vd_vdpu2_init_hwcfg(M2vdHalCtx *ctx)
154 {
155
156 M2vdVdpu2Reg *p_regs = (M2vdVdpu2Reg *)ctx->regs;
157
158 memset(p_regs, 0, sizeof(M2vdVdpu2Reg));
159
160 p_regs->sw56.dec_axi_rn_id = 0;
161 p_regs->sw57.dec_timeout_e = 1;
162 p_regs->sw54.dec_strswap32_e = 1; //change
163 p_regs->sw54.dec_strendian_e = DEC_LITTLE_ENDIAN;
164 p_regs->sw54.dec_inswap32_e = 1; //change
165 p_regs->sw54.dec_outswap32_e = 1; //change
166
167
168 p_regs->sw57.dec_clk_gate_e = 1; //change
169 p_regs->sw54.dec_in_endian = DEC_LITTLE_ENDIAN; //change
170 p_regs->sw54.dec_out_endian = DEC_LITTLE_ENDIAN;
171
172 p_regs->sw50.dec_out_tiled_e = 0;
173 p_regs->sw56.dec_max_burst = DEC_BUS_BURST_LENGTH_16;
174 p_regs->sw50.dec_scmd_dis = 0;
175 p_regs->sw50.dec_adv_pre_dis = 0;
176 p_regs->sw52.apf_threshold = 8;
177
178 p_regs->sw50.dec_latency = 0;
179 p_regs->sw56.dec_data_disc_e = 0;
180
181 p_regs->sw55.dec_irq = 0;
182 p_regs->sw56.dec_axi_rn_id = 0;
183 p_regs->sw56.dec_axi_wr_id = 0;
184
185 p_regs->sw53.sw_dec_mode = 8;
186
187 p_regs->ppReg[0] = 0;
188 p_regs->sw136.mv_accuracy_fwd = 1;
189 p_regs->sw136.mv_accuracy_bwd = 1;
190
191 return MPP_OK;
192 }
193
hal_m2vd_vdpu2_gen_regs(void * hal,HalTaskInfo * task)194 MPP_RET hal_m2vd_vdpu2_gen_regs(void *hal, HalTaskInfo *task)
195 {
196 MPP_RET ret = MPP_OK;
197
198 if (task->dec.valid) {
199 void *q_table = NULL;
200 MppBuffer streambuf = NULL;
201 MppBuffer framebuf = NULL;
202 M2vdHalCtx *ctx = (M2vdHalCtx *)hal;
203 M2VDDxvaParam *dx = (M2VDDxvaParam *)task->dec.syntax.data;
204 M2vdVdpu2Reg *p_regs = ctx->regs;
205
206 task->dec.valid = 0;
207 q_table = mpp_buffer_get_ptr(ctx->qp_table);
208 memcpy(q_table, dx->qp_tab, M2VD_BUF_SIZE_QPTAB);
209
210 hal_m2vd_vdpu2_init_hwcfg(ctx);
211
212 p_regs->sw136.mv_accuracy_fwd = 1;
213 p_regs->sw136.mv_accuracy_bwd = 1;
214 if (dx->seq_ext_head_dec_flag) {
215 p_regs->sw53.sw_dec_mode = 5;
216 p_regs->sw136.fcode_fwd_hor = dx->pic.full_pel_forward_vector;
217 p_regs->sw136.fcode_fwd_ver = dx->pic.forward_f_code;
218 p_regs->sw136.fcode_bwd_hor = dx->pic.full_pel_backward_vector;
219 p_regs->sw136.fcode_bwd_ver = dx->pic.backward_f_code;
220
221 } else {
222 p_regs->sw53.sw_dec_mode = 6;
223 p_regs->sw136.fcode_fwd_hor = dx->pic.forward_f_code;
224 p_regs->sw136.fcode_fwd_ver = dx->pic.forward_f_code;
225 p_regs->sw136.fcode_bwd_hor = dx->pic.backward_f_code;
226 p_regs->sw136.fcode_bwd_ver = dx->pic.backward_f_code;
227 if (dx->pic.full_pel_forward_vector)
228 p_regs->sw136.mv_accuracy_fwd = 0;
229 if (dx->pic.full_pel_backward_vector)
230 p_regs->sw136.mv_accuracy_bwd = 0;
231 }
232
233 p_regs->sw120.pic_mb_width = (dx->seq.decode_width + 15) >> 4;
234 p_regs->sw120.pic_mb_height_p = (dx->seq.decode_height + 15) >> 4;
235 p_regs->sw57.pic_interlace_e = 1 - dx->seq_ext.progressive_sequence;
236 if (dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_FRAME)
237 p_regs->sw57.pic_fieldmode_e = 0;
238 else {
239 p_regs->sw57.pic_fieldmode_e = 1;
240 p_regs->sw57.pic_topfield_e = dx->pic_code_ext.picture_structure == 1;
241 }
242 if (dx->pic.picture_coding_type == M2VD_CODING_TYPE_B)
243 p_regs->sw57.pic_b_e = 1;
244 else
245 p_regs->sw57.pic_b_e = 0;
246 if (dx->pic.picture_coding_type == M2VD_CODING_TYPE_I)
247 p_regs->sw57.pic_inter_e = 0;
248 else
249 p_regs->sw57.pic_inter_e = 1;
250
251 p_regs->sw120.topfieldfirst_e = dx->pic_code_ext.top_field_first;
252 p_regs->sw57.fwd_interlace_e = 0;
253 p_regs->sw57.write_mvs_e = 0;//concealment_motion_vectors;
254 p_regs->sw120.alt_scan_e = dx->pic_code_ext.alternate_scan;
255 p_regs->sw136.alt_scan_flag_e = dx->pic_code_ext.alternate_scan;
256
257 p_regs->sw122.qscale_type = dx->pic_code_ext.q_scale_type;
258 p_regs->sw122.intra_dc_prec = dx->pic_code_ext.intra_dc_precision;
259 p_regs->sw122.con_mv_e = dx->pic_code_ext.concealment_motion_vectors;
260 p_regs->sw122.intra_vlc_tab = dx->pic_code_ext.intra_vlc_format;
261 p_regs->sw122.frame_pred_dct = dx->pic_code_ext.frame_pred_frame_dct;
262 p_regs->sw51.init_qp = 1;
263
264 mpp_buf_slot_get_prop(ctx->packet_slots, task->dec.input, SLOT_BUFFER, &streambuf);
265 p_regs->sw64.VLC_base = mpp_buffer_get_fd(streambuf);
266 if (dx->bitstream_offset) {
267 mpp_dev_set_reg_offset(ctx->dev, 64, dx->bitstream_offset);
268 }
269
270 mpp_buf_slot_get_prop(ctx->frame_slots, dx->CurrPic.Index7Bits, SLOT_BUFFER, &framebuf);
271
272
273 if ((dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) ||
274 (dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_FRAME)) {
275 p_regs->sw63.cur_pic_base = mpp_buffer_get_fd(framebuf); //just index need map
276 } else {
277 p_regs->sw63.cur_pic_base = mpp_buffer_get_fd(framebuf);
278 mpp_dev_set_reg_offset(ctx->dev, 63, MPP_ALIGN(dx->seq.decode_width, 16));
279 }
280
281 //ref & qtable config
282 mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[0].Index7Bits, SLOT_BUFFER, &framebuf);
283 p_regs->sw131.ref0 = mpp_buffer_get_fd(framebuf); //just index need map
284
285 mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[1].Index7Bits, SLOT_BUFFER, &framebuf);
286 p_regs->sw148.ref1 = mpp_buffer_get_fd(framebuf); //just index need map
287
288 mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[2].Index7Bits, SLOT_BUFFER, &framebuf);
289 p_regs->sw134.ref2 = mpp_buffer_get_fd(framebuf); //just index need map
290
291 mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[3].Index7Bits, SLOT_BUFFER, &framebuf);
292 p_regs->sw135.ref3 = mpp_buffer_get_fd(framebuf); //just index need map
293
294 p_regs->sw61.slice_table = mpp_buffer_get_fd(ctx->qp_table);
295
296 p_regs->sw52.startmb_x = 0;
297 p_regs->sw52.startmb_y = 0;
298 p_regs->sw57.dec_out_dis = 0;
299 p_regs->sw50.filtering_dis = 1;
300
301 p_regs->sw51.stream_len = dx->bitstream_length;
302 p_regs->sw122.stream_start_bit = dx->bitstream_start_bit;
303 p_regs->sw57.dec_e = 1;
304
305 if (M2VH_DBG_REG & m2vh_debug) {
306 RK_U32 j = 0;
307 RK_U32 *p_reg = (RK_U32 *)p_regs;
308 for (j = 50; j < 159; j++) {
309 mpp_log("reg[%d] = 0x%08x", j, p_reg[j]);
310 }
311 }
312 if (ctx->fp_reg_in) {
313 int k = 0;
314 RK_U32 *p_reg = (RK_U32*)p_regs;
315 mpp_log("fwrite regs start");
316 fprintf(ctx->fp_reg_in, "Frame #%d\n", ctx->dec_frame_cnt);
317 for (k = 0; k < M2VD_VDPU2_REG_NUM; k++)
318 fprintf(ctx->fp_reg_in, "[(D)%03d, (X)%03x] %08x\n", k, k, p_reg[k]);
319 fflush(ctx->fp_reg_in);
320 }
321
322 task->dec.valid = 1;
323 ctx->dec_frame_cnt++;
324 }
325 return ret;
326
327 }
328
hal_m2vd_vdpu2_start(void * hal,HalTaskInfo * task)329 MPP_RET hal_m2vd_vdpu2_start(void *hal, HalTaskInfo *task)
330 {
331 MPP_RET ret = MPP_OK;
332 M2vdHalCtx *ctx = (M2vdHalCtx *)hal;
333
334 m2vh_dbg_func("enter\n");
335
336 do {
337 MppDevRegWrCfg wr_cfg;
338 MppDevRegRdCfg rd_cfg;
339 RK_U32 *regs = (RK_U32 *)ctx->regs;
340 RK_U32 reg_size = sizeof(M2vdVdpu2Reg);
341
342 wr_cfg.reg = regs;
343 wr_cfg.size = reg_size;
344 wr_cfg.offset = 0;
345
346 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
347 if (ret) {
348 mpp_err_f("set register write failed %d\n", ret);
349 break;
350 }
351
352 rd_cfg.reg = regs;
353 rd_cfg.size = reg_size;
354 rd_cfg.offset = 0;
355
356 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
357 if (ret) {
358 mpp_err_f("set register read failed %d\n", ret);
359 break;
360 }
361
362 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
363 if (ret) {
364 mpp_err_f("send cmd failed %d\n", ret);
365 break;
366 }
367 } while (0);
368
369 (void)task;
370 m2vh_dbg_func("leave\n");
371 return ret;
372 }
373
hal_m2vd_vdpu2_wait(void * hal,HalTaskInfo * task)374 MPP_RET hal_m2vd_vdpu2_wait(void *hal, HalTaskInfo *task)
375 {
376 MPP_RET ret = MPP_OK;
377 M2vdHalCtx *ctx = (M2vdHalCtx *)hal;
378 M2vdVdpu2Reg* reg_out = (M2vdVdpu2Reg * )ctx->regs;
379
380 m2vh_dbg_func("enter\n");
381
382 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
383 if (ret)
384 mpp_err_f("poll cmd failed %d\n", ret);
385
386 if (ctx->fp_reg_out) {
387 int k = 0;
388 RK_U32 *p_reg = (RK_U32*)®_out;
389 fprintf(ctx->fp_reg_out, "Frame #%d\n", ctx->dec_frame_cnt);
390 for (k = 0; k < M2VD_VDPU2_REG_NUM; k++)
391 fprintf(ctx->fp_reg_out, "[(D)%03d, (X)%03x] %08x\n", k, k, p_reg[k]);
392 fflush(ctx->fp_reg_out);
393 }
394 if (reg_out->sw55.dec_error_int | reg_out->sw55.dec_buffer_int) {
395 if (ctx->dec_cb)
396 mpp_callback(ctx->dec_cb, NULL);
397 }
398
399 if (M2VH_DBG_IRQ & m2vh_debug)
400 mpp_log("mpp_device_wait_reg return interrupt:%08x", reg_out->sw55);
401
402 (void)task;
403 m2vh_dbg_func("leave\n");
404 return ret;
405 }
406