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