xref: /OK3568_Linux_fs/external/mpp/mpp/hal/vpu/m2vd/hal_m2vd_vdpu1.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 
161         hal_m2vd_vdpu1_init_hwcfg(ctx);
162 
163         p_regs->sw18.mv_accuracy_fwd = 1;
164         p_regs->sw18.mv_accuracy_bwd = 1;
165         if (dx->seq_ext_head_dec_flag) {
166             p_regs->sw03.dec_mode = 5;
167             p_regs->sw18.fcode_fwd_hor = dx->pic.full_pel_forward_vector;
168             p_regs->sw18.fcode_fwd_ver = dx->pic.forward_f_code;
169             p_regs->sw18.fcode_bwd_hor = dx->pic.full_pel_backward_vector;
170             p_regs->sw18.fcode_bwd_ver = dx->pic.backward_f_code;
171         } else {
172             p_regs->sw03.dec_mode = 6;
173             p_regs->sw18.fcode_fwd_hor = dx->pic.forward_f_code;
174             p_regs->sw18.fcode_fwd_ver = dx->pic.forward_f_code;
175             p_regs->sw18.fcode_bwd_hor = dx->pic.backward_f_code;
176             p_regs->sw18.fcode_bwd_ver = dx->pic.backward_f_code;
177             if (dx->pic.full_pel_forward_vector)
178                 p_regs->sw18.mv_accuracy_fwd = 0;
179             if (dx->pic.full_pel_backward_vector)
180                 p_regs->sw18.mv_accuracy_bwd = 0;
181         }
182 
183         p_regs->sw04.pic_mb_width = (dx->seq.decode_width + 15) >> 4;
184         p_regs->sw04.pic_mb_height_p = (dx->seq.decode_height + 15) >> 4;
185         p_regs->sw03.pic_interlace_e = 1 - dx->seq_ext.progressive_sequence;
186         if (dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_FRAME)
187             p_regs->sw03.pic_fieldmode_e = 0;
188         else {
189             p_regs->sw03.pic_fieldmode_e = 1;
190             p_regs->sw03.pic_topfield_e = dx->pic_code_ext.picture_structure == 1;
191         }
192         if (dx->pic.picture_coding_type == M2VD_CODING_TYPE_B)
193             p_regs->sw03.pic_b_e = 1;
194         else
195             p_regs->sw03.pic_b_e = 0;
196         if (dx->pic.picture_coding_type == M2VD_CODING_TYPE_I)
197             p_regs->sw03.pic_inter_e = 0;
198         else
199             p_regs->sw03.pic_inter_e = 1;
200 
201         p_regs->sw04.topfieldfirst_e = dx->pic_code_ext.top_field_first;
202         p_regs->sw03.fwd_interlace_e = 0;
203         p_regs->sw03.write_mvs_e = 0;
204         p_regs->sw04.alt_scan_e = dx->pic_code_ext.alternate_scan;
205         p_regs->sw18.alt_scan_flag_e = dx->pic_code_ext.alternate_scan;
206 
207         p_regs->sw05.qscale_type = dx->pic_code_ext.q_scale_type;
208         p_regs->sw05.intra_dc_prec = dx->pic_code_ext.intra_dc_precision;
209         p_regs->sw05.con_mv_e = dx->pic_code_ext.concealment_motion_vectors;
210         p_regs->sw05.intra_vlc_tab = dx->pic_code_ext.intra_vlc_format;
211         p_regs->sw05.frame_pred_dct = dx->pic_code_ext.frame_pred_frame_dct;
212         p_regs->sw06.init_qp = 1;
213 
214         mpp_buf_slot_get_prop(ctx->packet_slots, task->dec.input, SLOT_BUFFER, &streambuf);
215         p_regs->sw12.rlc_vlc_base = mpp_buffer_get_fd(streambuf);
216         if (dx->bitstream_offset) {
217             mpp_dev_set_reg_offset(ctx->dev, 12, dx->bitstream_offset);
218         }
219 
220         mpp_buf_slot_get_prop(ctx->frame_slots, dx->CurrPic.Index7Bits, SLOT_BUFFER, &framebuf);
221 
222         if ((dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_TOP_FIELD) ||
223             (dx->pic_code_ext.picture_structure == M2VD_PIC_STRUCT_FRAME)) {
224             p_regs->sw13.dec_out_base = mpp_buffer_get_fd(framebuf);
225         } else {
226             p_regs->sw13.dec_out_base = mpp_buffer_get_fd(framebuf);
227             mpp_dev_set_reg_offset(ctx->dev, 13, MPP_ALIGN(dx->seq.decode_width, 16));
228         }
229 
230         mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[0].Index7Bits, SLOT_BUFFER, &framebuf);
231         p_regs->sw14.refer0_base = mpp_buffer_get_fd(framebuf);
232 
233         mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[1].Index7Bits, SLOT_BUFFER, &framebuf);
234         p_regs->sw15.refer1_base = mpp_buffer_get_fd(framebuf);
235 
236         mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[2].Index7Bits, SLOT_BUFFER, &framebuf);
237         p_regs->sw16.refer2_base = mpp_buffer_get_fd(framebuf);
238 
239         mpp_buf_slot_get_prop(ctx->frame_slots, dx->frame_refs[3].Index7Bits, SLOT_BUFFER, &framebuf);
240         p_regs->sw17.refer3_base = mpp_buffer_get_fd(framebuf);
241 
242         p_regs->sw40.qtable_base = mpp_buffer_get_fd(ctx->qp_table);
243 
244         p_regs->sw48.startmb_x = 0;
245         p_regs->sw48.startmb_y = 0;
246         p_regs->sw03.dec_out_dis = 0;
247         p_regs->sw03.filtering_dis = 1;
248         p_regs->sw06.stream_len = dx->bitstream_length;
249         p_regs->sw05.stream_start_bit = dx->bitstream_start_bit;
250         p_regs->sw01.dec_e = 1;
251 
252         task->dec.valid = 1;
253         ctx->dec_frame_cnt++;
254     }
255 
256     return ret;
257 }
258 
hal_m2vd_vdpu1_start(void * hal,HalTaskInfo * task)259 MPP_RET hal_m2vd_vdpu1_start(void *hal, HalTaskInfo *task)
260 {
261     MPP_RET ret = MPP_OK;
262     M2vdHalCtx *ctx = (M2vdHalCtx *)hal;
263 
264     do {
265         MppDevRegWrCfg wr_cfg;
266         MppDevRegRdCfg rd_cfg;
267         RK_U32 *regs = (RK_U32 *)ctx->regs;
268         RK_U32 reg_size = sizeof(M2vdVdpu1Reg_t);
269 
270         wr_cfg.reg = regs;
271         wr_cfg.size = reg_size;
272         wr_cfg.offset = 0;
273 
274         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
275         if (ret) {
276             mpp_err_f("set register write failed %d\n", ret);
277             break;
278         }
279 
280         rd_cfg.reg = regs;
281         rd_cfg.size = reg_size;
282         rd_cfg.offset = 0;
283 
284         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
285         if (ret) {
286             mpp_err_f("set register read failed %d\n", ret);
287             break;
288         }
289 
290         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
291         if (ret) {
292             mpp_err_f("send cmd failed %d\n", ret);
293             break;
294         }
295     } while (0);
296 
297     (void)task;
298     return ret;
299 }
300 
hal_m2vd_vdpu1_wait(void * hal,HalTaskInfo * task)301 MPP_RET hal_m2vd_vdpu1_wait(void *hal, HalTaskInfo *task)
302 {
303     MPP_RET ret = MPP_OK;
304     M2vdHalCtx *ctx = (M2vdHalCtx *)hal;
305     M2vdVdpu1Reg_t* reg_out = (M2vdVdpu1Reg_t * )ctx->regs;
306 
307     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
308     if (ret)
309         mpp_err_f("poll cmd failed %d\n", ret);
310 
311     if (reg_out->sw01.dec_error_int | reg_out->sw01.dec_buffer_int) {
312         if (ctx->dec_cb)
313             mpp_callback(ctx->dec_cb, NULL);
314     }
315 
316     (void)task;
317 
318     return ret;
319 }
320