xref: /rockchip-linux_mpp/mpp/hal/vpu/m2vd/hal_m2vd_vdpu2.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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         mpp_buffer_sync_end(ctx->qp_table);
210 
211         hal_m2vd_vdpu2_init_hwcfg(ctx);
212 
213         p_regs->sw136.mv_accuracy_fwd = 1;
214         p_regs->sw136.mv_accuracy_bwd = 1;
215         if (dx->seq_ext_head_dec_flag) {
216             p_regs->sw53.sw_dec_mode = 5;
217             p_regs->sw136.fcode_fwd_hor = dx->pic.full_pel_forward_vector;
218             p_regs->sw136.fcode_fwd_ver = dx->pic.forward_f_code;
219             p_regs->sw136.fcode_bwd_hor = dx->pic.full_pel_backward_vector;
220             p_regs->sw136.fcode_bwd_ver = dx->pic.backward_f_code;
221 
222         } else {
223             p_regs->sw53.sw_dec_mode = 6;
224             p_regs->sw136.fcode_fwd_hor = dx->pic.forward_f_code;
225             p_regs->sw136.fcode_fwd_ver = dx->pic.forward_f_code;
226             p_regs->sw136.fcode_bwd_hor = dx->pic.backward_f_code;
227             p_regs->sw136.fcode_bwd_ver = dx->pic.backward_f_code;
228             if (dx->pic.full_pel_forward_vector)
229                 p_regs->sw136.mv_accuracy_fwd = 0;
230             if (dx->pic.full_pel_backward_vector)
231                 p_regs->sw136.mv_accuracy_bwd = 0;
232         }
233 
234         p_regs->sw120.pic_mb_width = (dx->seq.decode_width + 15) >> 4;
235         p_regs->sw120.pic_mb_height_p = (dx->seq.decode_height + 15) >> 4;
236         p_regs->sw57.pic_interlace_e = 1 - dx->seq_ext.progressive_sequence;
237         if (dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_FRAME)
238             p_regs->sw57.pic_fieldmode_e = 0;
239         else {
240             p_regs->sw57.pic_fieldmode_e = 1;
241             p_regs->sw57.pic_topfield_e = dx->pic_code_ext.picture_structure == 1;
242         }
243         if (dx->pic.picture_coding_type == M2VD_CODING_TYPE_B)
244             p_regs->sw57.pic_b_e = 1;
245         else
246             p_regs->sw57.pic_b_e = 0;
247         if (dx->pic.picture_coding_type == M2VD_CODING_TYPE_I)
248             p_regs->sw57.pic_inter_e = 0;
249         else
250             p_regs->sw57.pic_inter_e = 1;
251 
252         p_regs->sw120.topfieldfirst_e = dx->pic_code_ext.top_field_first;
253         p_regs->sw57.fwd_interlace_e = 0;
254         p_regs->sw57.write_mvs_e = 0;//concealment_motion_vectors;
255         p_regs->sw120.alt_scan_e = dx->pic_code_ext.alternate_scan;
256         p_regs->sw136.alt_scan_flag_e = dx->pic_code_ext.alternate_scan;
257 
258         p_regs->sw122.qscale_type = dx->pic_code_ext.q_scale_type;
259         p_regs->sw122.intra_dc_prec = dx->pic_code_ext.intra_dc_precision;
260         p_regs->sw122.con_mv_e = dx->pic_code_ext.concealment_motion_vectors;
261         p_regs->sw122.intra_vlc_tab = dx->pic_code_ext.intra_vlc_format;
262         p_regs->sw122.frame_pred_dct = dx->pic_code_ext.frame_pred_frame_dct;
263         p_regs->sw51.init_qp = 1;
264 
265         mpp_buf_slot_get_prop(ctx->packet_slots, task->dec.input, SLOT_BUFFER, &streambuf);
266         p_regs->sw64.VLC_base = mpp_buffer_get_fd(streambuf);
267         if (dx->bitstream_offset) {
268             mpp_dev_set_reg_offset(ctx->dev, 64, dx->bitstream_offset);
269         }
270 
271         mpp_buf_slot_get_prop(ctx->frame_slots, dx->CurrPic.Index7Bits, SLOT_BUFFER, &framebuf);
272 
273 
274         if ((dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) ||
275             (dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_FRAME)) {
276             p_regs->sw63.cur_pic_base = mpp_buffer_get_fd(framebuf); //just index need map
277         } else {
278             p_regs->sw63.cur_pic_base = mpp_buffer_get_fd(framebuf);
279             mpp_dev_set_reg_offset(ctx->dev, 63, MPP_ALIGN(dx->seq.decode_width, 16));
280         }
281 
282         //ref & qtable config
283         mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[0].Index7Bits, SLOT_BUFFER, &framebuf);
284         p_regs->sw131.ref0  = mpp_buffer_get_fd(framebuf); //just index need map
285 
286         mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[1].Index7Bits, SLOT_BUFFER, &framebuf);
287         p_regs->sw148.ref1  = mpp_buffer_get_fd(framebuf); //just index need map
288 
289         mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[2].Index7Bits, SLOT_BUFFER, &framebuf);
290         p_regs->sw134.ref2  = mpp_buffer_get_fd(framebuf); //just index need map
291 
292         mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[3].Index7Bits, SLOT_BUFFER, &framebuf);
293         p_regs->sw135.ref3  = mpp_buffer_get_fd(framebuf); //just index need map
294 
295         p_regs->sw61.slice_table = mpp_buffer_get_fd(ctx->qp_table);
296 
297         p_regs->sw52.startmb_x = 0;
298         p_regs->sw52.startmb_y = 0;
299         p_regs->sw57.dec_out_dis = 0;
300         p_regs->sw50.filtering_dis = 1;
301 
302         p_regs->sw51.stream_len = dx->bitstream_length;
303         p_regs->sw122.stream_start_bit = dx->bitstream_start_bit;
304         p_regs->sw57.dec_e = 1;
305 
306         if (M2VH_DBG_REG & m2vh_debug) {
307             RK_U32 j = 0;
308             RK_U32 *p_reg = (RK_U32 *)p_regs;
309             for (j = 50; j < 159; j++) {
310                 mpp_log("reg[%d] = 0x%08x", j, p_reg[j]);
311             }
312         }
313         if (ctx->fp_reg_in) {
314             int k = 0;
315             RK_U32 *p_reg = (RK_U32*)p_regs;
316             mpp_log("fwrite regs start");
317             fprintf(ctx->fp_reg_in, "Frame #%d\n", ctx->dec_frame_cnt);
318             for (k = 0; k < M2VD_VDPU2_REG_NUM; k++)
319                 fprintf(ctx->fp_reg_in, "[(D)%03d, (X)%03x]  %08x\n", k, k, p_reg[k]);
320             fflush(ctx->fp_reg_in);
321         }
322 
323         task->dec.valid = 1;
324         ctx->dec_frame_cnt++;
325     }
326     return ret;
327 
328 }
329 
hal_m2vd_vdpu2_start(void * hal,HalTaskInfo * task)330 MPP_RET hal_m2vd_vdpu2_start(void *hal, HalTaskInfo *task)
331 {
332     MPP_RET ret = MPP_OK;
333     M2vdHalCtx *ctx = (M2vdHalCtx *)hal;
334 
335     m2vh_dbg_func("enter\n");
336 
337     do {
338         MppDevRegWrCfg wr_cfg;
339         MppDevRegRdCfg rd_cfg;
340         RK_U32 *regs = (RK_U32 *)ctx->regs;
341         RK_U32 reg_size = sizeof(M2vdVdpu2Reg);
342 
343         wr_cfg.reg = regs;
344         wr_cfg.size = reg_size;
345         wr_cfg.offset = 0;
346 
347         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
348         if (ret) {
349             mpp_err_f("set register write failed %d\n", ret);
350             break;
351         }
352 
353         rd_cfg.reg = regs;
354         rd_cfg.size = reg_size;
355         rd_cfg.offset = 0;
356 
357         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
358         if (ret) {
359             mpp_err_f("set register read failed %d\n", ret);
360             break;
361         }
362 
363         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
364         if (ret) {
365             mpp_err_f("send cmd failed %d\n", ret);
366             break;
367         }
368     } while (0);
369 
370     (void)task;
371     m2vh_dbg_func("leave\n");
372     return ret;
373 }
374 
hal_m2vd_vdpu2_wait(void * hal,HalTaskInfo * task)375 MPP_RET hal_m2vd_vdpu2_wait(void *hal, HalTaskInfo *task)
376 {
377     MPP_RET ret = MPP_OK;
378     M2vdHalCtx *ctx = (M2vdHalCtx *)hal;
379     M2vdVdpu2Reg* reg_out = (M2vdVdpu2Reg * )ctx->regs;
380 
381     m2vh_dbg_func("enter\n");
382 
383     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
384     if (ret)
385         mpp_err_f("poll cmd failed %d\n", ret);
386 
387     if (ctx->fp_reg_out) {
388         int k = 0;
389         RK_U32 *p_reg = (RK_U32*)&reg_out;
390         fprintf(ctx->fp_reg_out, "Frame #%d\n", ctx->dec_frame_cnt);
391         for (k = 0; k < M2VD_VDPU2_REG_NUM; k++)
392             fprintf(ctx->fp_reg_out, "[(D)%03d, (X)%03x]  %08x\n", k, k, p_reg[k]);
393         fflush(ctx->fp_reg_out);
394     }
395     if (reg_out->sw55.dec_error_int | reg_out->sw55.dec_buffer_int) {
396         if (ctx->dec_cb)
397             mpp_callback(ctx->dec_cb, NULL);
398     }
399 
400     if (M2VH_DBG_IRQ & m2vh_debug)
401         mpp_log("mpp_device_wait_reg return interrupt:%08x", reg_out->sw55);
402 
403     (void)task;
404     m2vh_dbg_func("leave\n");
405     return ret;
406 }
407