xref: /rockchip-linux_mpp/mpp/hal/rkdec/avsd/hal_avsd_vdpu1.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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_avsd_vdpu1"
18 
19 #include <string.h>
20 
21 #include "mpp_debug.h"
22 #include "mpp_common.h"
23 #include "mpp_mem.h"
24 #include "mpp_device.h"
25 #include "mpp_dec_cb_param.h"
26 
27 #include "hal_avsd_base.h"
28 #include "hal_avsd_vdpu1.h"
29 #include "hal_avsd_vdpu1_reg.h"
30 
set_defalut_parameters(AvsdHalCtx_t * p_hal)31 static MPP_RET set_defalut_parameters(AvsdHalCtx_t *p_hal)
32 {
33     AvsdVdpu1Regs_t *p_regs = (AvsdVdpu1Regs_t *)p_hal->p_regs;
34 
35     p_regs->sw02.dec_out_endian = 1;
36     p_regs->sw02.dec_in_endian = 0;
37     p_regs->sw02.dec_strendian_e = 1;
38     p_regs->sw02.dec_max_burst = 16;
39     p_regs->sw02.dec_scmd_dis = 0;
40 
41     p_regs->sw02.dec_adv_pre_dis = 0;
42     p_regs->sw55.apf_threshold = 8;
43     p_regs->sw02.dec_latency = 0;
44 
45     p_regs->sw02.dec_data_disc_e = 0;
46     p_regs->sw02.dec_outswap32_e = 1;
47     p_regs->sw02.dec_inswap32_e = 1;
48     p_regs->sw02.dec_strswap32_e = 1;
49 
50     p_regs->sw02.dec_timeout_e = 0;
51     p_regs->sw02.dec_clk_gate_e = 1;
52     p_regs->sw01.dec_irq_dis = 0;
53 
54     p_regs->sw02.dec_axi_rd_id = 0xFF;
55     p_regs->sw03.dec_axi_wr_id = 0;
56 
57     p_regs->sw49.pred_bc_tap_0_0 = 0x3FF;
58     p_regs->sw49.pred_bc_tap_0_1 = 5;
59     p_regs->sw49.pred_bc_tap_0_2 = 5;
60     p_regs->sw34.pred_bc_tap_0_3 = 0x3FF;
61     p_regs->sw34.pred_bc_tap_1_0 = 1;
62     p_regs->sw34.pred_bc_tap_1_1 = 7;
63     p_regs->sw35.pred_bc_tap_1_2 = 7;
64     p_regs->sw35.pred_bc_tap_1_3 = 1;
65 
66     p_regs->sw02.tiled_mode_lsb = 0;
67 
68     return MPP_OK;
69 }
70 
set_regs_parameters(AvsdHalCtx_t * p_hal,HalDecTask * task)71 static MPP_RET set_regs_parameters(AvsdHalCtx_t *p_hal, HalDecTask *task)
72 {
73     MPP_RET ret = MPP_ERR_UNKNOW;
74 
75     AvsdSyntax_t *p_syn = &p_hal->syn;
76     AvsdVdpu1Regs_t *p_regs = (AvsdVdpu1Regs_t *)p_hal->p_regs;
77 
78     set_defalut_parameters(p_hal);
79 
80     p_regs->sw02.dec_timeout_e = 1;
81     p_regs->sw02.dec_clk_gate_e = 1;
82     p_regs->sw01.dec_irq_dis = 0;
83     p_regs->sw03.rlc_mode_e = 0;
84 
85     //!< set wrok_out pic info
86     if (p_hal->work_out < 0) {
87         p_hal->work_out = get_queue_pic(p_hal);
88         if (p_hal->work_out < 0) {
89             ret = MPP_NOK;
90             mpp_err_f("cannot get a pic_info buffer.\n");
91             goto __FAILED;
92         }
93     }
94     {
95         AvsdHalPic_t *p_work_out = &p_hal->pic[p_hal->work_out];
96 
97         p_work_out->slot_idx = task->output;
98         p_work_out->pic_code_type = p_syn->pp.picCodingType;
99         p_work_out->picture_distance = p_syn->pp.pictureDistance;
100     }
101     //!< set register
102     p_regs->sw04.pic_mb_width = (p_syn->pp.horizontalSize + 15) >> 4;
103     p_regs->sw03.dec_mode = 11; //!< DEC_MODE_AVS
104 
105     if (p_syn->pp.pictureStructure == FRAMEPICTURE) {
106         p_regs->sw03.pic_interlace_e = 0;
107         p_regs->sw03.pic_fieldmode_e = 0;
108         p_regs->sw03.pic_topfiled_e = 0;
109     } else {
110         p_regs->sw03.pic_interlace_e = 1;
111         p_regs->sw03.pic_fieldmode_e = 1;
112         p_regs->sw03.pic_topfiled_e = p_hal->first_field;
113     }
114 
115     p_regs->sw04.pic_mb_height_p = (p_syn->pp.verticalSize + 15) >> 4;
116     //p_regs->sw07.avs_h_ext = (p_syn->pp.verticalSize + 15) >> 12;
117 
118     if (p_syn->pp.picCodingType == BFRAME) {
119         p_regs->sw03.pic_b_e = 1;
120     } else {
121         p_regs->sw03.pic_b_e = 0;
122     }
123     p_regs->sw03.pic_inter_e = (p_syn->pp.picCodingType != IFRAME) ? 1 : 0;
124 
125     mpp_log("data_offset %x\n", p_hal->data_offset);
126     p_regs->sw05.strm_start_bit = 8 * (p_hal->data_offset & 0x7);
127     p_hal->data_offset = (p_hal->data_offset & ~0x7);
128     p_regs->sw12.rlc_vlc_base = get_packet_fd(p_hal, task->input);
129     mpp_dev_set_reg_offset(p_hal->dev, 12, p_hal->data_offset);
130     p_regs->sw06.stream_len = p_syn->bitstream_size - p_hal->data_offset;
131     p_regs->sw03.pic_fixed_quant = p_syn->pp.fixedPictureQp;
132     p_regs->sw06.init_qp = p_syn->pp.pictureQp;
133 
134     p_regs->sw13.dec_out_base = get_frame_fd(p_hal, task->output);
135     if (p_syn->pp.pictureStructure == FIELDPICTURE && !p_hal->first_field) {
136         //!< start of bottom field line
137         mpp_dev_set_reg_offset(p_hal->dev, 13, p_syn->pp.horizontalSize);
138     }
139     {
140         RK_S32 tmp_fwd = -1;
141         RK_S32 refer0 = -1;
142         RK_S32 refer1 = -1;
143 
144         tmp_fwd = (p_hal->work1 < 0) ? p_hal->work0 : p_hal->work1;
145         tmp_fwd = (tmp_fwd < 0) ? p_hal->work_out : tmp_fwd;
146 
147         refer0 = (task->refer[0] < 0) ? task->output : task->refer[0];
148         refer1 = (task->refer[1] < 0) ? refer0 : task->refer[1];
149         if (!p_hal->first_field
150             && p_syn->pp.pictureStructure == FIELDPICTURE
151             && p_syn->pp.picCodingType != BFRAME) {
152             p_regs->sw14.refer0_base = get_frame_fd(p_hal, task->output);
153             p_regs->sw15.refer1_base = get_frame_fd(p_hal, refer0);
154             p_regs->sw16.refer2_base = get_frame_fd(p_hal, refer0);
155             p_regs->sw17.refer3_base = get_frame_fd(p_hal, refer1);
156         } else {
157             p_regs->sw14.refer0_base = get_frame_fd(p_hal, refer0);
158             p_regs->sw15.refer1_base = get_frame_fd(p_hal, refer0);
159             p_regs->sw16.refer2_base = get_frame_fd(p_hal, refer1);
160             p_regs->sw17.refer3_base = get_frame_fd(p_hal, refer1);
161         }
162     }
163     //!< block distances
164     if (p_syn->pp.pictureStructure == FRAMEPICTURE) {
165         if (p_syn->pp.picCodingType == BFRAME) {
166             RK_S32 tmp = 0;
167             //!< current to future anchor
168             if (p_hal->work0 >= 0) {
169                 tmp = (2 * p_hal->pic[p_hal->work0].picture_distance -
170                        2 * p_syn->pp.pictureDistance + 512) & 0x1FF;
171             }
172             //!< prevent division by zero
173             if (!tmp) tmp = 2;
174             p_regs->sw31.ref_dist_cur_2 = tmp;
175             p_regs->sw31.ref_dist_cur_3 = tmp;
176             p_regs->sw29.ref_invd_cur_2 = 512 / tmp;
177             p_regs->sw29.ref_invd_cur_3 = 512 / tmp;
178 
179             //!< current to past anchor
180             if (p_hal->work1 >= 0) {
181                 tmp = (2 * p_syn->pp.pictureDistance -
182                        2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
183                 if (!tmp) tmp = 2;
184             }
185             p_regs->sw30.ref_dist_cur_0 = tmp;
186             p_regs->sw30.ref_dist_cur_1 = tmp;
187             p_regs->sw28.ref_invd_cur_0 = 512 / tmp;
188             p_regs->sw28.ref_invd_cur_1 = 512 / tmp;
189             //!< future anchor to past anchor
190             if (p_hal->work0 >= 0 && p_hal->work1 >= 0) {
191                 tmp = (2 * p_hal->pic[p_hal->work0].picture_distance -
192                        2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
193                 if (!tmp) tmp = 2;
194             }
195             tmp = 16384 / tmp;
196             p_regs->sw32.ref_invd_col_0 = tmp;
197             p_regs->sw32.ref_invd_col_1 = tmp;
198             //!< future anchor to previous past anchor
199             tmp = p_hal->future2prev_past_dist;
200             tmp = 16384 / tmp;
201             p_regs->sw33.ref_invd_col_2 = tmp;
202             p_regs->sw33.ref_invd_col_3 = tmp;
203         } else {
204             RK_S32 tmp = 0;
205             //!< current to past anchor
206             if (p_hal->work0 >= 0) {
207                 tmp = (2 * p_syn->pp.pictureDistance -
208                        2 * p_hal->pic[p_hal->work0].picture_distance - 512) & 0x1FF;
209             }
210             if (!tmp) tmp = 2;
211             p_regs->sw30.ref_dist_cur_0 = tmp;
212             p_regs->sw30.ref_dist_cur_1 = tmp;
213             p_regs->sw28.ref_invd_cur_0 = 512 / tmp;
214             p_regs->sw28.ref_invd_cur_1 = 512 / tmp;
215             //!< current to previous past anchor
216             if (p_hal->work1 >= 0) {
217                 tmp = (2 * p_syn->pp.pictureDistance -
218                        2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
219                 if (!tmp) tmp = 2;
220             }
221             //!< this will become "future to previous past" for next B
222             p_hal->future2prev_past_dist = tmp;
223 
224             p_regs->sw31.ref_dist_cur_2 = tmp;
225             p_regs->sw31.ref_dist_cur_3 = tmp;
226             p_regs->sw29.ref_invd_cur_2 = 512 / tmp;
227             p_regs->sw29.ref_invd_cur_3 = 512 / tmp;
228 
229             p_regs->sw32.ref_invd_col_0 = 0;
230             p_regs->sw32.ref_invd_col_1 = 0;
231             p_regs->sw33.ref_invd_col_2 = 0;
232             p_regs->sw33.ref_invd_col_3 = 0;
233         }
234     } else {
235         //!< field interlaced
236         if (p_syn->pp.picCodingType == BFRAME) {
237             RK_S32 tmp = 0;
238             //!< block distances
239             if (p_hal->work0 >= 0) {
240                 tmp = (2 * p_hal->pic[p_hal->work0].picture_distance -
241                        2 * p_syn->pp.pictureDistance + 512) & 0x1FF;
242             }
243             //!< prevent division by zero
244             if (!tmp) tmp = 2;
245 
246             if (p_hal->first_field) {
247                 p_regs->sw31.ref_dist_cur_2 = tmp;
248                 p_regs->sw31.ref_dist_cur_3 = tmp + 1;
249                 p_regs->sw29.ref_invd_cur_2 = 512 / tmp;
250                 p_regs->sw29.ref_invd_cur_3 = 512 / (tmp + 1);
251             } else {
252                 p_regs->sw31.ref_dist_cur_2 = tmp - 1;
253                 p_regs->sw31.ref_dist_cur_3 = tmp;
254                 p_regs->sw29.ref_invd_cur_2 = 512 / (tmp - 1);
255                 p_regs->sw29.ref_invd_cur_3 = 512 / tmp;
256             }
257 
258             if (p_hal->work1 >= 0) {
259                 tmp = (2 * p_syn->pp.pictureDistance -
260                        2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
261                 if (!tmp) tmp = 2;
262             }
263             if (p_hal->first_field) {
264                 p_regs->sw30.ref_dist_cur_0 = (tmp - 1);
265                 p_regs->sw30.ref_dist_cur_1 = tmp;
266                 p_regs->sw28.ref_invd_cur_0 = 512 / (tmp - 1);
267                 p_regs->sw28.ref_invd_cur_1 = 512 / tmp;
268             } else {
269                 p_regs->sw30.ref_dist_cur_0 = tmp;
270                 p_regs->sw30.ref_dist_cur_1 = tmp + 1;
271                 p_regs->sw28.ref_invd_cur_0 = 512 / tmp;
272                 p_regs->sw28.ref_invd_cur_1 = 512 / (tmp + 1);
273             }
274 
275             if (p_hal->work0 >= 0 && p_hal->work1 >= 0) {
276                 tmp = (2 * p_hal->pic[p_hal->work0].picture_distance -
277                        2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
278                 if (!tmp) tmp = 2;
279             }
280 
281             if (p_syn->pp.pbFieldEnhancedFlag && !p_hal->first_field) {
282                 //!< in this case, BlockDistanceRef is different with before, the mvRef points to top field
283                 p_regs->sw32.ref_invd_col_0 = 16384 / (tmp - 1);
284                 p_regs->sw32.ref_invd_col_1 = 16384 / tmp;
285 
286                 //!< future anchor to previous past anchor
287                 tmp = p_hal->future2prev_past_dist;
288 
289                 p_regs->sw33.ref_invd_col_2 = 16384 / (tmp - 1);
290                 p_regs->sw33.ref_invd_col_3 = 16384 / tmp;
291             } else {
292                 if (p_hal->first_field) {
293                     p_regs->sw32.ref_invd_col_0 = 16384 / (tmp - 1);
294                     p_regs->sw32.ref_invd_col_1 = 16384 / tmp;
295                 } else {
296                     p_regs->sw32.ref_invd_col_0 = 16384;
297                     p_regs->sw32.ref_invd_col_1 = 16384 / tmp;
298                     p_regs->sw33.ref_invd_col_2 = 16384 / (tmp + 1);
299                 }
300 
301                 //!< future anchor to previous past anchor
302                 tmp = p_hal->future2prev_past_dist;
303 
304                 if (p_hal->first_field) {
305                     p_regs->sw33.ref_invd_col_2 = 16384 / (tmp - 1);
306                     p_regs->sw33.ref_invd_col_3 = 16384 / tmp;
307                 } else {
308                     p_regs->sw33.ref_invd_col_3 = 16384 / tmp;
309                 }
310             }
311         } else {
312             RK_S32 tmp = 0;
313             if (p_hal->work0 >= 0) {
314                 tmp = (2 * p_syn->pp.pictureDistance -
315                        2 * p_hal->pic[p_hal->work0].picture_distance - 512) & 0x1FF;
316             }
317             if (!tmp) tmp = 2;
318 
319             if (!p_hal->first_field) {
320                 p_regs->sw30.ref_dist_cur_0 = 1;
321                 p_regs->sw31.ref_dist_cur_2 = tmp + 1;
322 
323                 p_regs->sw28.ref_invd_cur_0 = 512;
324                 p_regs->sw29.ref_invd_cur_2 = 512 / (tmp + 1);
325             } else {
326                 p_regs->sw30.ref_dist_cur_0 = tmp - 1;
327                 p_regs->sw28.ref_invd_cur_0 = 512 / (tmp - 1);
328             }
329             p_regs->sw30.ref_dist_cur_1 = tmp;
330             p_regs->sw28.ref_invd_cur_1 = 512 / tmp;
331 
332             if (p_hal->work1 >= 0) {
333                 tmp = (2 * p_syn->pp.pictureDistance -
334                        2 * p_hal->pic[p_hal->work1].picture_distance - 512) & 0x1FF;
335                 if (!tmp) tmp = 2;
336             }
337             //!< this will become "future to previous past" for next B
338             p_hal->future2prev_past_dist = tmp;
339             if (p_hal->first_field) {
340                 p_regs->sw31.ref_dist_cur_2 = tmp - 1;
341                 p_regs->sw31.ref_dist_cur_3 = tmp;
342 
343                 p_regs->sw29.ref_invd_cur_2 = 512 / (tmp - 1);
344                 p_regs->sw29.ref_invd_cur_3 = 512 / tmp;
345             } else {
346                 p_regs->sw31.ref_dist_cur_3 = tmp;
347                 p_regs->sw29.ref_invd_cur_3 = 512 / tmp;
348             }
349 
350             p_regs->sw32.ref_invd_col_0 = 0;
351             p_regs->sw32.ref_invd_col_1 = 0;
352             p_regs->sw33.ref_invd_col_2 = 0;
353             p_regs->sw33.ref_invd_col_3 = 0;
354         }
355     }
356 
357     p_regs->sw48.startmb_x = 0;
358     p_regs->sw48.startmb_y = 0;
359 
360     p_regs->sw03.filtering_dis = p_syn->pp.loopFilterDisable;
361     p_regs->sw05.alpha_offset = p_syn->pp.alphaOffset;
362     p_regs->sw05.beta_offset = p_syn->pp.betaOffset;
363     p_regs->sw03.skip_mode = p_syn->pp.skipModeFlag;
364     p_regs->sw04.pic_refer_flag = p_syn->pp.pictureReferenceFlag;
365 
366     if (p_syn->pp.picCodingType == PFRAME
367         || (p_syn->pp.picCodingType == IFRAME && !p_hal->first_field)) {
368         p_regs->sw03.write_mvs_e = 1;
369     } else {
370         p_regs->sw03.write_mvs_e = 0;
371     }
372     //!< set mv base
373     p_regs->sw41.dir_mv_base = mpp_buffer_get_fd(p_hal->mv_buf);
374     if (p_hal->first_field ||
375         (p_syn->pp.picCodingType == BFRAME && p_hal->prev_pic_structure)) {
376     } else {
377         RK_U32 frame_width = 0, frame_height = 0, offset = 0;
378         frame_width = (p_syn->pp.horizontalSize + 15) >> 4;
379         if (p_syn->pp.progressiveFrame)
380             frame_height = (p_syn->pp.verticalSize + 15) >> 4;
381         else
382             frame_height = 2 * ((p_syn->pp.verticalSize + 31) >> 5);
383         offset = MPP_ALIGN(frame_width * frame_height / 2, 2) * 16;
384         mpp_dev_set_reg_offset(p_hal->dev, 41, offset);
385     }
386     {
387         RK_U32 pic_type = 0;
388         RK_U32 prev_anc_type = 0;
389         if (p_hal->work0 >= 0) {
390             pic_type = p_hal->pic[p_hal->work0].pic_type;
391         }
392         prev_anc_type = !pic_type || (!p_hal->first_field && !p_hal->prev_pic_structure);
393         p_regs->sw18.prev_anc_type = prev_anc_type;
394     }
395     //!< b-picture needs to know if future reference is field or frame coded
396     // p_regs->sw16.refer2_field_e = (!p_hal->prev_pic_structure) ? 1 : 0;
397     // p_regs->sw17.refer3_field_e = (!p_hal->prev_pic_structure) ? 1 : 0;
398     if (!p_hal->prev_pic_structure) {
399         mpp_dev_set_reg_offset(p_hal->dev, 16, 2);
400         mpp_dev_set_reg_offset(p_hal->dev, 17, 3);
401     }
402 
403     p_regs->sw03.dec_out_dis = 0;
404     p_regs->sw01.dec_e = 1;
405 
406     return MPP_OK;
407 __FAILED:
408     return ret;
409 }
410 
update_parameters(AvsdHalCtx_t * p_hal)411 static MPP_RET update_parameters(AvsdHalCtx_t *p_hal)
412 {
413     AvsdSyntax_t *p_syn = &p_hal->syn;
414 
415     if (p_syn->pp.pictureStructure == FRAMEPICTURE || !p_hal->first_field) {
416         p_hal->first_field = 1;
417         if (p_syn->pp.picCodingType != BFRAME) {
418             RK_S32 temp = p_hal->work1;
419 
420             p_hal->work1 =  p_hal->work0;
421             p_hal->work0 =  p_hal->work_out;
422 
423             if (p_hal->work_out >= 0)
424                 p_hal->pic[p_hal->work_out].pic_type = p_syn->pp.picCodingType == IFRAME;
425             p_hal->work_out = temp;
426             p_hal->prev_pic_structure = p_syn->pp.pictureStructure;
427         }
428         p_hal->prev_pic_code_type = p_syn->pp.picCodingType;
429     } else {
430         p_hal->first_field = 0;
431     }
432 
433     return MPP_OK;
434 }
435 
repeat_other_field(AvsdHalCtx_t * p_hal,HalTaskInfo * task)436 static MPP_RET repeat_other_field(AvsdHalCtx_t *p_hal, HalTaskInfo *task)
437 {
438     RK_U8 i = 0;
439     RK_U8 *pdata = NULL;
440     MppBuffer mbuffer = NULL;
441     MPP_RET ret = MPP_ERR_UNKNOW;
442     AvsdVdpu1Regs_t *p_regs = (AvsdVdpu1Regs_t *)p_hal->p_regs;
443 
444     //!< re-find start code and calculate offset
445     p_hal->data_offset = p_regs->sw12.rlc_vlc_base >> 10;
446     p_hal->data_offset += p_hal->syn.bitstream_offset;
447     p_hal->data_offset -= MPP_MIN(p_hal->data_offset, 8);
448 
449     mpp_buf_slot_get_prop(p_hal->packet_slots, task->dec.input, SLOT_BUFFER, &mbuffer);
450     pdata = (RK_U8 *)mpp_buffer_get_ptr(mbuffer) + p_hal->data_offset;
451 
452     while (i < 16) {
453         if (pdata[i] == 0 && pdata[i + 1] == 0 && pdata[i + 2] == 1) {
454             p_hal->data_offset += i;
455             break;
456         }
457         i++;
458     }
459     AVSD_HAL_DBG(AVSD_HAL_DBG_OFFSET, "frame_no=%d, i=%d, offset=%d\n",
460                  p_hal->frame_no, i, p_hal->data_offset);
461     //!< re-generate register
462     FUN_CHECK(ret = set_regs_parameters(p_hal, &task->dec));
463     hal_avsd_vdpu1_start((void *)p_hal, task);
464     hal_avsd_vdpu1_wait((void *)p_hal, task);
465 
466     return ret = MPP_OK;
467 __FAILED:
468     return ret;
469 }
470 
471 /*!
472 ***********************************************************************
473 * \brief
474 *    init
475 ***********************************************************************
476 */
477 //extern "C"
hal_avsd_vdpu1_init(void * decoder,MppHalCfg * cfg)478 MPP_RET hal_avsd_vdpu1_init(void *decoder, MppHalCfg *cfg)
479 {
480     MPP_RET ret = MPP_ERR_UNKNOW;
481     RK_U32 buf_size = 0;
482     AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
483 
484     AVSD_HAL_TRACE("AVS_vdpu1 In.");
485 
486     buf_size = (1920 * 1088) * 2;
487     FUN_CHECK(ret = mpp_buffer_get(p_hal->buf_group, &p_hal->mv_buf, buf_size));
488 
489     p_hal->p_regs = mpp_calloc_size(RK_U32, sizeof(AvsdVdpu1Regs_t));
490     MEM_CHECK(ret, p_hal->p_regs);
491 
492     mpp_slots_set_prop(p_hal->frame_slots, SLOTS_HOR_ALIGN, avsd_hor_align);
493     mpp_slots_set_prop(p_hal->frame_slots, SLOTS_VER_ALIGN, avsd_ver_align);
494     mpp_slots_set_prop(p_hal->frame_slots, SLOTS_LEN_ALIGN, avsd_len_align);
495 
496     p_hal->regs_num = 60;
497     //!< initial for control
498     p_hal->first_field = 1;
499     p_hal->prev_pic_structure = 0; //!< field
500 
501     memset(p_hal->pic, 0, sizeof(p_hal->pic));
502     p_hal->work_out = -1;
503     p_hal->work0 = -1;
504     p_hal->work1 = -1;
505 
506     AVSD_HAL_TRACE("Out.");
507     (void)cfg;
508     return ret = MPP_OK;
509 __FAILED:
510     return ret;
511 }
512 /*!
513 ***********************************************************************
514 * \brief
515 *    deinit
516 ***********************************************************************
517 */
518 //extern "C"
hal_avsd_vdpu1_deinit(void * decoder)519 MPP_RET hal_avsd_vdpu1_deinit(void *decoder)
520 {
521     AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
522 
523     AVSD_HAL_TRACE("In.");
524 
525     if (p_hal->mv_buf) {
526         mpp_buffer_put(p_hal->mv_buf);
527         p_hal->mv_buf = NULL;
528     }
529     MPP_FREE(p_hal->p_regs);
530 
531     AVSD_HAL_TRACE("Out.");
532 
533     return MPP_OK;
534 }
535 /*!
536 ***********************************************************************
537 * \brief
538 *    generate register
539 ***********************************************************************
540 */
541 //extern "C"
hal_avsd_vdpu1_gen_regs(void * decoder,HalTaskInfo * task)542 MPP_RET hal_avsd_vdpu1_gen_regs(void *decoder, HalTaskInfo *task)
543 {
544     MPP_RET ret = MPP_ERR_UNKNOW;
545     AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
546 
547     AVSD_HAL_TRACE("In.");
548     if ((task->dec.flags.parse_err || task->dec.flags.ref_err) &&
549         !p_hal->dec_cfg->base.disable_error) {
550         goto __RETURN;
551     }
552     p_hal->data_offset = p_hal->syn.bitstream_offset;
553 
554     FUN_CHECK(ret = set_regs_parameters(p_hal, &task->dec));
555 __RETURN:
556     AVSD_HAL_TRACE("Out.");
557 
558     return ret = MPP_OK;
559 __FAILED:
560     return ret;
561 }
562 /*!
563 ***********************************************************************
564 * \brief h
565 *    start hard
566 ***********************************************************************
567 */
568 //extern "C"
hal_avsd_vdpu1_start(void * decoder,HalTaskInfo * task)569 MPP_RET hal_avsd_vdpu1_start(void *decoder, HalTaskInfo *task)
570 {
571     MPP_RET ret = MPP_ERR_UNKNOW;
572     AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
573 
574     AVSD_HAL_TRACE("In.");
575 
576     if ((task->dec.flags.parse_err || task->dec.flags.ref_err) &&
577         !p_hal->dec_cfg->base.disable_error) {
578         goto __RETURN;
579     }
580 
581     do {
582         MppDevRegWrCfg wr_cfg;
583         MppDevRegRdCfg rd_cfg;
584         RK_U32 reg_size = 101 * sizeof(RK_U32);
585 
586         wr_cfg.reg = p_hal->p_regs;
587         wr_cfg.size = reg_size;
588         wr_cfg.offset = 0;
589 
590         ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_REG_WR, &wr_cfg);
591         if (ret) {
592             mpp_err_f("set register write failed %d\n", ret);
593             break;
594         }
595 
596         rd_cfg.reg = p_hal->p_regs;
597         rd_cfg.size = reg_size;
598         rd_cfg.offset = 0;
599 
600         ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_REG_RD, &rd_cfg);
601         if (ret) {
602             mpp_err_f("set register read failed %d\n", ret);
603             break;
604         }
605 
606         ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_CMD_SEND, NULL);
607         if (ret) {
608             mpp_err_f("send cmd failed %d\n", ret);
609             break;
610         }
611     } while (0);
612 
613 __RETURN:
614     AVSD_HAL_TRACE("Out.");
615     return ret = MPP_OK;
616 }
617 /*!
618 ***********************************************************************
619 * \brief
620 *    wait hard
621 ***********************************************************************
622 */
623 //extern "C"
hal_avsd_vdpu1_wait(void * decoder,HalTaskInfo * task)624 MPP_RET hal_avsd_vdpu1_wait(void *decoder, HalTaskInfo *task)
625 {
626     MPP_RET ret = MPP_ERR_UNKNOW;
627     AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
628 
629     AVSD_HAL_TRACE("In.");
630 
631     if ((task->dec.flags.parse_err || task->dec.flags.ref_err) &&
632         !p_hal->dec_cfg->base.disable_error) {
633         goto __SKIP_HARD;
634     }
635 
636     ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_CMD_POLL, NULL);
637     if (ret)
638         mpp_err_f("poll cmd failed %d\n", ret);
639 
640 __SKIP_HARD:
641     if (p_hal->dec_cb) {
642         DecCbHalDone param;
643 
644         param.task = (void *)&task->dec;
645         param.regs = (RK_U32 *)p_hal->p_regs;
646 
647         if (!((AvsdVdpu1Regs_t *)p_hal->p_regs)->sw01.dec_rdy_int) {
648             param.hard_err = 1;
649         } else
650             param.hard_err = 0;
651 
652         mpp_callback(p_hal->dec_cb, &param);
653         AVSD_HAL_DBG(AVSD_HAL_DBG_WAIT, "reg[1]=%08x, ref=%d, dpberr=%d, harderr=%d\n",
654                      p_hal->p_regs[1], task->dec.flags.used_for_ref, task->dec.flags.ref_err, param.hard_err);
655     }
656     update_parameters(p_hal);
657     memset(&p_hal->p_regs[1], 0, sizeof(RK_U32));
658     if (!p_hal->first_field && p_hal->syn.pp.pictureStructure == FIELDPICTURE &&
659         ((!task->dec.flags.parse_err && !task->dec.flags.ref_err) ||
660          p_hal->dec_cfg->base.disable_error)) {
661         repeat_other_field(p_hal, task);
662     }
663     p_hal->frame_no++;
664 
665     AVSD_HAL_TRACE("Out.");
666     return ret = MPP_OK;
667 }
668 /*!
669 ***********************************************************************
670 * \brief
671 *    reset
672 ***********************************************************************
673 */
674 //extern "C"
hal_avsd_vdpu1_reset(void * decoder)675 MPP_RET hal_avsd_vdpu1_reset(void *decoder)
676 {
677     MPP_RET ret = MPP_ERR_UNKNOW;
678     AvsdHalCtx_t *p_hal = (AvsdHalCtx_t *)decoder;
679 
680     AVSD_HAL_TRACE("In.");
681 
682     p_hal->first_field = 1;
683     p_hal->prev_pic_structure = 0; //!< field
684 
685     memset(p_hal->pic, 0, sizeof(p_hal->pic));
686     p_hal->work_out = -1;
687     p_hal->work0 = -1;
688     p_hal->work1 = -1;
689 
690     AVSD_HAL_TRACE("Out.");
691 
692     return ret = MPP_OK;
693 }
694 /*!
695 ***********************************************************************
696 * \brief
697 *    flush
698 ***********************************************************************
699 */
700 //extern "C"
hal_avsd_vdpu1_flush(void * decoder)701 MPP_RET hal_avsd_vdpu1_flush(void *decoder)
702 {
703     MPP_RET ret = MPP_ERR_UNKNOW;
704 
705     AVSD_HAL_TRACE("In.");
706 
707     (void)decoder;
708 
709     AVSD_HAL_TRACE("Out.");
710 
711     return ret = MPP_OK;
712 }
713 /*!
714 ***********************************************************************
715 * \brief
716 *    control
717 ***********************************************************************
718 */
719 //extern "C"
hal_avsd_vdpu1_control(void * decoder,MpiCmd cmd_type,void * param)720 MPP_RET hal_avsd_vdpu1_control(void *decoder, MpiCmd cmd_type, void *param)
721 {
722     MPP_RET ret = MPP_ERR_UNKNOW;
723 
724     AVSD_HAL_TRACE("In.");
725 
726     (void)decoder;
727     (void)cmd_type;
728     (void)param;
729 
730     AVSD_HAL_TRACE("Out.");
731 
732     return ret = MPP_OK;
733 }
734