xref: /rockchip-linux_mpp/mpp/hal/rkdec/h264d/hal_h264d_vdpu1.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /*
2  *
3  * Copyright 2015 Rockchip Electronics Co. LTD
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #define MODULE_TAG "hal_h264d_vdpu1_reg"
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "rk_type.h"
25 #include "mpp_err.h"
26 #include "mpp_mem.h"
27 #include "mpp_common.h"
28 
29 #include "hal_h264d_global.h"
30 #include "hal_h264d_api.h"
31 #include "hal_h264d_vdpu_com.h"
32 #include "hal_h264d_vdpu1.h"
33 #include "hal_h264d_vdpu1_reg.h"
34 #include "mpp_dec_cb_param.h"
35 
36 const RK_U32 vdpu1_ref_idx[16] = {
37     14, 15, 16, 17, 18, 19, 20, 21,
38     22, 23, 24, 25, 26, 27, 28, 29
39 };
40 
41 MPP_RET vdpu1_h264d_deinit(void *hal);
vdpu1_set_refer_pic_idx(H264dVdpu1Regs_t * p_regs,RK_U32 i,RK_U16 val)42 static MPP_RET vdpu1_set_refer_pic_idx(H264dVdpu1Regs_t *p_regs, RK_U32 i,
43                                        RK_U16 val)
44 {
45     switch (i) {
46     case 0:
47         p_regs->SwReg30.sw_refer0_nbr = val;
48         break;
49     case 1:
50         p_regs->SwReg30.sw_refer1_nbr = val;
51         break;
52     case 2:
53         p_regs->SwReg31.sw_refer2_nbr = val;
54         break;
55     case 3:
56         p_regs->SwReg31.sw_refer3_nbr = val;
57         break;
58     case 4:
59         p_regs->SwReg32.sw_refer4_nbr = val;
60         break;
61     case 5:
62         p_regs->SwReg32.sw_refer5_nbr = val;
63         break;
64     case 6:
65         p_regs->SwReg33.sw_refer6_nbr = val;
66         break;
67     case 7:
68         p_regs->SwReg33.sw_refer7_nbr = val;
69         break;
70     case 8:
71         p_regs->SwReg34.sw_refer8_nbr = val;
72         break;
73     case 9:
74         p_regs->SwReg34.sw_refer9_nbr = val;
75         break;
76     case 10:
77         p_regs->SwReg35.sw_refer10_nbr = val;
78         break;
79     case 11:
80         p_regs->SwReg35.sw_refer11_nbr = val;
81         break;
82     case 12:
83         p_regs->SwReg36.sw_refer12_nbr = val;
84         break;
85     case 13:
86         p_regs->SwReg36.sw_refer13_nbr = val;
87         break;
88     case 14:
89         p_regs->SwReg37.sw_refer14_nbr = val;
90         break;
91     case 15:
92         p_regs->SwReg37.sw_refer15_nbr = val;
93         break;
94     default:
95         break;
96     }
97 
98     return MPP_OK;
99 }
100 
vdpu1_set_refer_pic_list_p(H264dVdpu1Regs_t * p_regs,RK_U32 i,RK_U16 val)101 static MPP_RET vdpu1_set_refer_pic_list_p(H264dVdpu1Regs_t *p_regs, RK_U32 i,
102                                           RK_U16 val)
103 {
104     switch (i) {
105     case 0:
106         p_regs->SwReg47.sw_pinit_rlist_f0 = val;
107         break;
108     case 1:
109         p_regs->SwReg47.sw_pinit_rlist_f1 = val;
110         break;
111     case 2:
112         p_regs->SwReg47.sw_pinit_rlist_f2 = val;
113         break;
114     case 3:
115         p_regs->SwReg47.sw_pinit_rlist_f3 = val;
116         break;
117     case 4:
118         p_regs->SwReg10.sw_pinit_rlist_f4 = val;
119         break;
120     case 5:
121         p_regs->SwReg10.sw_pinit_rlist_f5 = val;
122         break;
123     case 6:
124         p_regs->SwReg10.sw_pinit_rlist_f6 = val;
125         break;
126     case 7:
127         p_regs->SwReg10.sw_pinit_rlist_f7 = val;
128         break;
129     case 8:
130         p_regs->SwReg10.sw_pinit_rlist_f8 = val;
131         break;
132     case 9:
133         p_regs->SwReg10.sw_pinit_rlist_f9 = val;
134         break;
135     case 10:
136         p_regs->SwReg11.sw_pinit_rlist_f10 = val;
137         break;
138     case 11:
139         p_regs->SwReg11.sw_pinit_rlist_f11 = val;
140         break;
141     case 12:
142         p_regs->SwReg11.sw_pinit_rlist_f12 = val;
143         break;
144     case 13:
145         p_regs->SwReg11.sw_pinit_rlist_f13 = val;
146         break;
147     case 14:
148         p_regs->SwReg11.sw_pinit_rlist_f14 = val;
149         break;
150     case 15:
151         p_regs->SwReg11.sw_pinit_rlist_f15 = val;
152         break;
153     default:
154         break;
155     }
156 
157     return MPP_OK;
158 }
159 
vdpu1_set_refer_pic_list_b0(H264dVdpu1Regs_t * p_regs,RK_U32 i,RK_U16 val)160 static MPP_RET vdpu1_set_refer_pic_list_b0(H264dVdpu1Regs_t *p_regs, RK_U32 i,
161                                            RK_U16 val)
162 {
163     switch (i) {
164     case 0:
165         p_regs->SwReg42.sw_binit_rlist_f0 = val;
166         break;
167     case 1:
168         p_regs->SwReg42.sw_binit_rlist_f1 = val;
169         break;
170     case 2:
171         p_regs->SwReg42.sw_binit_rlist_f2 = val;
172         break;
173     case 3:
174         p_regs->SwReg43.sw_binit_rlist_f3 = val;
175         break;
176     case 4:
177         p_regs->SwReg43.sw_binit_rlist_f4 = val;
178         break;
179     case 5:
180         p_regs->SwReg43.sw_binit_rlist_f5 = val;
181         break;
182     case 6:
183         p_regs->SwReg44.sw_binit_rlist_f6 = val;
184         break;
185     case 7:
186         p_regs->SwReg44.sw_binit_rlist_f7 = val;
187         break;
188     case 8:
189         p_regs->SwReg44.sw_binit_rlist_f8 = val;
190         break;
191     case 9:
192         p_regs->SwReg45.sw_binit_rlist_f9 = val;
193         break;
194     case 10:
195         p_regs->SwReg45.sw_binit_rlist_f10 = val;
196         break;
197     case 11:
198         p_regs->SwReg45.sw_binit_rlist_f11 = val;
199         break;
200     case 12:
201         p_regs->SwReg46.sw_binit_rlist_f12 = val;
202         break;
203     case 13:
204         p_regs->SwReg46.sw_binit_rlist_f13 = val;
205         break;
206     case 14:
207         p_regs->SwReg46.sw_binit_rlist_f14 = val;
208         break;
209     case 15:
210         p_regs->SwReg47.sw_binit_rlist_f15 = val;
211         break;
212     default:
213         break;
214     }
215 
216     return MPP_OK;
217 }
218 
vdpu1_set_refer_pic_list_b1(H264dVdpu1Regs_t * p_regs,RK_U32 i,RK_U16 val)219 static MPP_RET vdpu1_set_refer_pic_list_b1(H264dVdpu1Regs_t *p_regs, RK_U32 i,
220                                            RK_U16 val)
221 {
222     switch (i) {
223     case 0:
224         p_regs->SwReg42.sw_binit_rlist_b0 = val;
225         break;
226     case 1:
227         p_regs->SwReg42.sw_binit_rlist_b1 = val;
228         break;
229     case 2:
230         p_regs->SwReg42.sw_binit_rlist_b2 = val;
231         break;
232     case 3:
233         p_regs->SwReg43.sw_binit_rlist_b3 = val;
234         break;
235     case 4:
236         p_regs->SwReg43.sw_binit_rlist_b4 = val;
237         break;
238     case 5:
239         p_regs->SwReg43.sw_binit_rlist_b5 = val;
240         break;
241     case 6:
242         p_regs->SwReg44.sw_binit_rlist_b6 = val;
243         break;
244     case 7:
245         p_regs->SwReg44.sw_binit_rlist_b7 = val;
246         break;
247     case 8:
248         p_regs->SwReg44.sw_binit_rlist_b8 = val;
249         break;
250     case 9:
251         p_regs->SwReg45.sw_binit_rlist_b9 = val;
252         break;
253     case 10:
254         p_regs->SwReg45.sw_binit_rlist_b10 = val;
255         break;
256     case 11:
257         p_regs->SwReg45.sw_binit_rlist_b11 = val;
258         break;
259     case 12:
260         p_regs->SwReg46.sw_binit_rlist_b12 = val;
261         break;
262     case 13:
263         p_regs->SwReg46.sw_binit_rlist_b13 = val;
264         break;
265     case 14:
266         p_regs->SwReg46.sw_binit_rlist_b14 = val;
267         break;
268     case 15:
269         p_regs->SwReg47.sw_binit_rlist_b15 = val;
270         break;
271     default:
272         break;
273     }
274 
275     return MPP_OK;
276 }
277 
vdpu1_set_refer_pic_base_addr(H264dVdpu1Regs_t * p_regs,RK_U32 i,RK_U32 val)278 static MPP_RET vdpu1_set_refer_pic_base_addr(H264dVdpu1Regs_t *p_regs, RK_U32 i,
279                                              RK_U32 val)
280 {
281     switch (i) {
282     case 0:
283         p_regs->SwReg14.sw_refer0_base = val;
284         break;
285     case 1:
286         p_regs->SwReg15.sw_refer1_base = val;
287         break;
288     case 2:
289         p_regs->SwReg16.sw_refer2_base = val;
290         break;
291     case 3:
292         p_regs->SwReg17.sw_refer3_base = val;
293         break;
294     case 4:
295         p_regs->SwReg18.sw_refer4_base = val;
296         break;
297     case 5:
298         p_regs->SwReg19.sw_refer5_base = val;
299         break;
300     case 6:
301         p_regs->SwReg20.sw_refer6_base = val;
302         break;
303     case 7:
304         p_regs->SwReg21.sw_refer7_base = val;
305         break;
306     case 8:
307         p_regs->SwReg22.sw_refer8_base = val;
308         break;
309     case 9:
310         p_regs->SwReg23.sw_refer9_base = val;
311         break;
312     case 10:
313         p_regs->SwReg24.sw_refer10_base = val;
314         break;
315     case 11:
316         p_regs->SwReg25.sw_refer11_base = val;
317         break;
318     case 12:
319         p_regs->SwReg26.sw_refer12_base = val;
320         break;
321     case 13:
322         p_regs->SwReg27.sw_refer13_base = val;
323         break;
324     case 14:
325         p_regs->SwReg28.sw_refer14_base = val;
326         break;
327     case 15:
328         p_regs->SwReg29.sw_refer15_base = val;
329         break;
330     default:
331         break;
332     }
333     return MPP_OK;
334 }
335 
vdpu1_set_pic_regs(H264dHalCtx_t * p_hal,H264dVdpu1Regs_t * p_regs)336 static MPP_RET vdpu1_set_pic_regs(H264dHalCtx_t *p_hal,
337                                   H264dVdpu1Regs_t *p_regs)
338 {
339     MPP_RET ret = MPP_ERR_UNKNOW;
340 
341     p_regs->SwReg04.sw_pic_mb_width = p_hal->pp->wFrameWidthInMbsMinus1 + 1;
342     p_regs->SwReg04.sw_pic_mb_height_p = (2 - p_hal->pp->frame_mbs_only_flag)
343                                          * (p_hal->pp->wFrameHeightInMbsMinus1 + 1);
344 
345     return ret = MPP_OK;
346 }
347 
vdpu1_set_vlc_regs(H264dHalCtx_t * p_hal,H264dVdpu1Regs_t * p_regs)348 static MPP_RET vdpu1_set_vlc_regs(H264dHalCtx_t *p_hal,
349                                   H264dVdpu1Regs_t *p_regs)
350 {
351     RK_U32 i = 0;
352     MPP_RET ret = MPP_ERR_UNKNOW;
353     DXVA_PicParams_H264_MVC *pp = p_hal->pp;
354 
355     p_regs->SwReg03.sw_dec_out_dis = 0;
356     p_regs->SwReg03.sw_rlc_mode_e = 0;
357     p_regs->SwReg06.sw_init_qp = pp->pic_init_qp_minus26 + 26;
358     p_regs->SwReg09.sw_refidx0_active = pp->num_ref_idx_l0_active_minus1 + 1;
359     p_regs->SwReg04.sw_ref_frames = pp->num_ref_frames;
360 
361     p_regs->SwReg07.sw_framenum_len = pp->log2_max_frame_num_minus4 + 4;
362     p_regs->SwReg07.sw_framenum = pp->frame_num;
363 
364     p_regs->SwReg08.sw_const_intra_e = pp->constrained_intra_pred_flag;
365     p_regs->SwReg08.sw_filt_ctrl_pres =
366         pp->deblocking_filter_control_present_flag;
367     p_regs->SwReg08.sw_rdpic_cnt_pres = pp->redundant_pic_cnt_present_flag;
368     p_regs->SwReg08.sw_refpic_mk_len = p_hal->slice_long[0].drpm_used_bitlen;
369     p_regs->SwReg08.sw_idr_pic_e = p_hal->slice_long[0].idr_flag;
370     p_regs->SwReg08.sw_idr_pic_id = p_hal->slice_long[0].idr_pic_id;
371 
372     p_regs->SwReg09.sw_pps_id = p_hal->slice_long[0].active_pps_id;
373     p_regs->SwReg09.sw_poc_length = p_hal->slice_long[0].poc_used_bitlen;
374 
375     /* reference picture flags, TODO separate fields */
376     if (pp->field_pic_flag) {
377         RK_U32 validTmp = 0, validFlags = 0;
378         RK_U32 longTermTmp = 0, longTermflags = 0;
379         for (i = 0; i < 32; i++) {
380             if (pp->RefFrameList[i / 2].bPicEntry == 0xff) { //!< invalid
381                 longTermflags <<= 1;
382                 validFlags <<= 1;
383             } else {
384                 longTermTmp = pp->RefFrameList[i / 2].AssociatedFlag; //!< get long term flag
385                 longTermflags = (longTermflags << 1) | longTermTmp;
386 
387                 validTmp = ((pp->UsedForReferenceFlags >> i) & 0x01);
388                 validFlags = (validFlags << 1) | validTmp;
389             }
390         }
391         p_regs->SwReg38.refpic_term_flag = longTermflags;
392         p_regs->SwReg39.refpic_valid_flag = validFlags;
393     } else {
394         RK_U32 validTmp = 0, validFlags = 0;
395         RK_U32 longTermTmp = 0, longTermflags = 0;
396         for (i = 0; i < 16; i++) {
397             if (pp->RefFrameList[i].bPicEntry == 0xff) {  //!< invalid
398                 longTermflags <<= 1;
399                 validFlags <<= 1;
400             } else {
401                 longTermTmp = pp->RefFrameList[i].AssociatedFlag;
402                 longTermflags = (longTermflags << 1) | longTermTmp;
403                 validTmp = ((pp->UsedForReferenceFlags >> (2 * i)) & 0x03) > 0;
404                 validFlags = (validFlags << 1) | validTmp;
405             }
406         }
407         p_regs->SwReg38.refpic_term_flag = (longTermflags << 16);
408         p_regs->SwReg39.refpic_valid_flag = (validFlags << 16);
409     }
410 
411     for (i = 0; i < 16; i++) {
412         if (pp->RefFrameList[i].bPicEntry != 0xff) { //!< valid
413             if (pp->RefFrameList[i].AssociatedFlag) { //!< longterm flag
414                 vdpu1_set_refer_pic_idx(p_regs, i, pp->LongTermPicNumList[i]); //!< pic_num
415             } else {
416                 vdpu1_set_refer_pic_idx(p_regs, i, pp->FrameNumList[i]); //< frame_num
417             }
418         }
419     }
420     p_regs->SwReg03.sw_picord_count_e = 1;
421     //!< set poc to buffer
422     {
423         H264dVdpuRegCtx_t *reg_ctx = (H264dVdpuRegCtx_t *)p_hal->reg_ctx;
424         RK_U32 *pocBase = (RK_U32 *)reg_ctx->poc_ptr;
425 
426         //!< set reference reorder poc
427         for (i = 0; i < 32; i++) {
428             if (pp->RefFrameList[i / 2].bPicEntry != 0xff) {
429                 *pocBase++ = pp->FieldOrderCntList[i / 2][i & 0x1];
430             } else {
431                 *pocBase++ = 0;
432             }
433         }
434 
435         //!< set current poc
436         if (pp->field_pic_flag || !pp->MbaffFrameFlag) {
437             if (pp->field_pic_flag)
438                 *pocBase++ = pp->CurrFieldOrderCnt[pp->CurrPic.AssociatedFlag ? 1 : 0];
439             else
440                 *pocBase++ = MPP_MIN(pp->CurrFieldOrderCnt[0], pp->CurrFieldOrderCnt[1]);
441         } else {
442             *pocBase++ = pp->CurrFieldOrderCnt[0];
443             *pocBase++ = pp->CurrFieldOrderCnt[1];
444         }
445     }
446 
447     p_regs->SwReg07.sw_cabac_e = pp->entropy_coding_mode_flag;
448 
449     //!< stream position update
450     {
451         MppBuffer bitstream_buf = NULL;
452         p_regs->SwReg06.sw_start_code_e = 1;
453 
454         mpp_buf_slot_get_prop(p_hal->packet_slots, p_hal->in_task->input,
455                               SLOT_BUFFER, &bitstream_buf);
456 
457         p_regs->SwReg05.sw_strm_start_bit = 0; /* sodb stream start bit */
458         p_regs->SwReg12.rlc_vlc_st_adr = mpp_buffer_get_fd(bitstream_buf);
459 
460         p_regs->SwReg06.sw_stream_len = p_hal->strm_len;
461     }
462 
463     return ret = MPP_OK;
464 }
465 
vdpu1_set_ref_regs(H264dHalCtx_t * p_hal,H264dVdpu1Regs_t * p_regs)466 static MPP_RET vdpu1_set_ref_regs(H264dHalCtx_t *p_hal,
467                                   H264dVdpu1Regs_t *p_regs)
468 {
469     MPP_RET ret = MPP_ERR_UNKNOW;
470     RK_U32 i = 0;
471     RK_U32 num_refs = 0;
472     RK_U32 num_reorder = 0;
473     H264dRefsList_t m_lists[3][16];
474     DXVA_PicParams_H264_MVC  *pp = p_hal->pp;
475     RK_U32 max_frame_num = 1 << (pp->log2_max_frame_num_minus4 + 4);
476 
477     // init list
478     memset(m_lists, 0, sizeof(m_lists));
479     for (i = 0; i < 16; i++) {
480         RK_U32 ref_flag = pp->UsedForReferenceFlags >> (2 * i) & 0x3;
481 
482         m_lists[0][i].idx = i;
483         if (ref_flag) {
484             num_refs++;
485             m_lists[0][i].cur_poc = pp->CurrPic.AssociatedFlag
486                                     ? pp->CurrFieldOrderCnt[1] : pp->CurrFieldOrderCnt[0];
487             m_lists[0][i].ref_flag = ref_flag;
488             m_lists[0][i].lt_flag = pp->RefFrameList[i].AssociatedFlag;
489             if (m_lists[0][i].lt_flag) {
490                 m_lists[0][i].ref_picnum = pp->LongTermPicNumList[i];
491             } else {
492                 m_lists[0][i].ref_picnum = pp->FrameNumList[i] > pp->frame_num ?
493                                            (pp->FrameNumList[i] - max_frame_num) :
494                                            pp->FrameNumList[i];
495             }
496 
497             if (ref_flag == 3) {
498                 m_lists[0][i].ref_poc = MPP_MIN(pp->FieldOrderCntList[i][0], pp->FieldOrderCntList[i][1]);
499             } else if (ref_flag & 0x1) {
500                 m_lists[0][i].ref_poc = pp->FieldOrderCntList[i][0];
501             } else if (ref_flag & 0x2) {
502                 m_lists[0][i].ref_poc = pp->FieldOrderCntList[i][1];
503             }
504             num_reorder = i + 1;
505         }
506     }
507     /*
508      * the value of num_reorder may be greater than num_refs,
509      * e.g. v: valid  x: invalid
510      *      num_refs = 3, num_reorder = 4
511      *      the index 1 will be reorder to the end
512      *   ┌─┬─┬─┬─┬─┬─┬─┐
513      *   │0│1│2│3│.│.│F│
514      *   ├─┼─┼─┼─┼─┼─┼─┤
515      *   │v│x│v│v│x│x│x│
516      *   └─┴─┴─┴─┴─┴─┴─┘
517      */
518     memcpy(m_lists[1], m_lists[0], sizeof(m_lists[0]));
519     memcpy(m_lists[2], m_lists[0], sizeof(m_lists[0]));
520     qsort(m_lists[0], num_reorder, sizeof(m_lists[0][0]), compare_p);
521     qsort(m_lists[1], num_reorder, sizeof(m_lists[1][0]), compare_b0);
522     qsort(m_lists[2], num_reorder, sizeof(m_lists[2][0]), compare_b1);
523     if (num_refs > 1 && !p_hal->pp->field_pic_flag) {
524         if (!memcmp(m_lists[1], m_lists[2], sizeof(m_lists[1]))) {
525             MPP_SWAP(H264dRefsList_t, m_lists[2][0], m_lists[2][1]);
526         }
527     }
528     //!< list0 list1 listP
529     for (i = 0; i < 16; i++) {
530         vdpu1_set_refer_pic_list_p(p_regs, i, m_lists[0][i].idx);
531         vdpu1_set_refer_pic_list_b0(p_regs, i, m_lists[1][i].idx);
532         vdpu1_set_refer_pic_list_b1(p_regs, i, m_lists[2][i].idx);
533     }
534 
535     return ret = MPP_OK;
536 }
537 
vdpu1_set_asic_regs(H264dHalCtx_t * p_hal,H264dVdpu1Regs_t * p_regs)538 static MPP_RET vdpu1_set_asic_regs(H264dHalCtx_t *p_hal,
539                                    H264dVdpu1Regs_t *p_regs)
540 {
541     RK_U32 i = 0, j = 0;
542     RK_U32 outPhyAddr = 0;
543     MppBuffer frame_buf = NULL;
544     MPP_RET ret = MPP_ERR_UNKNOW;
545     DXVA_PicParams_H264_MVC *pp = p_hal->pp;
546     DXVA_Slice_H264_Long *p_long = &p_hal->slice_long[0];
547 
548     /* reference picture physic address */
549     for (i = 0, j = 0xff; i < MPP_ARRAY_ELEMS(pp->RefFrameList); i++) {
550         RK_U32 val = 0;
551         RK_U32 top_closer = 0;
552         RK_U32 field_flag = 0;
553         RK_S32 cur_poc = 0;
554         RK_U32 used_flag = 0;
555 
556         if (pp->RefFrameList[i].bPicEntry != 0xff) {
557             mpp_buf_slot_get_prop(p_hal->frame_slots,
558                                   pp->RefFrameList[i].Index7Bits,
559                                   SLOT_BUFFER, &frame_buf); //!< reference phy addr
560             j = i;
561         } else {
562             mpp_buf_slot_get_prop(p_hal->frame_slots,
563                                   pp->CurrPic.Index7Bits,
564                                   SLOT_BUFFER, &frame_buf); //!< current out phy addr
565         }
566 
567         field_flag = ((pp->RefPicFiledFlags >> i) & 0x1) ? 0x2 : 0;
568         cur_poc = pp->CurrPic.AssociatedFlag
569                   ? pp->CurrFieldOrderCnt[1] : pp->CurrFieldOrderCnt[0];
570         used_flag = ((pp->UsedForReferenceFlags >> (2 * i)) & 0x3);
571         if (used_flag & 0x3) {
572             top_closer = MPP_ABS(pp->FieldOrderCntList[i][0] - cur_poc) <
573                          MPP_ABS(pp->FieldOrderCntList[i][1] - cur_poc) ? 0x1 : 0;
574         } else if (used_flag & 0x2) {
575             top_closer = 0;
576         } else if (used_flag & 0x1) {
577             top_closer = 1;
578         }
579         val = top_closer | field_flag;
580         if (val)
581             mpp_dev_set_reg_offset(p_hal->dev, vdpu1_ref_idx[i], val);
582         vdpu1_set_refer_pic_base_addr(p_regs, i, mpp_buffer_get_fd(frame_buf));
583     }
584 
585     /* inter-view reference picture */
586     {
587         H264dVdpuPriv_t *priv = (H264dVdpuPriv_t *)p_hal->priv;
588         if (pp->curr_layer_id && priv->ilt_dpb && priv->ilt_dpb->valid /*pp->inter_view_flag*/) {
589             mpp_buf_slot_get_prop(p_hal->frame_slots,
590                                   priv->ilt_dpb->slot_index,
591                                   SLOT_BUFFER, &frame_buf);
592             p_regs->SwReg29.sw_refer15_base = mpp_buffer_get_fd(frame_buf); //!< inter-view base, ref15
593             p_regs->SwReg39.refpic_valid_flag |=
594                 (pp->field_pic_flag ? 0x3 : 0x10000);
595         }
596     }
597 
598     p_regs->SwReg03.sw_pic_fixed_quant = pp->curr_layer_id; //!< VDPU_MVC_E
599     p_regs->SwReg03.sw_filtering_dis = 0;
600 
601     mpp_buf_slot_get_prop(p_hal->frame_slots,
602                           pp->CurrPic.Index7Bits,
603                           SLOT_BUFFER, &frame_buf); //!< current out phy addr
604     outPhyAddr = mpp_buffer_get_fd(frame_buf);
605     if (pp->field_pic_flag && pp->CurrPic.AssociatedFlag) {
606         mpp_dev_set_reg_offset(p_hal->dev, 13, ((pp->wFrameWidthInMbsMinus1 + 1) * 16));
607     }
608     p_regs->SwReg13.dec_out_st_adr = outPhyAddr; //!< outPhyAddr, pp->CurrPic.Index7Bits
609 
610     p_regs->SwReg05.sw_ch_qp_offset = pp->chroma_qp_index_offset;
611     p_regs->SwReg05.sw_ch_qp_offset2 = pp->second_chroma_qp_index_offset;
612 
613     /* set default value for register[41] to avoid illegal translation fd */
614     {
615         RK_U32 dirMvOffset = 0;
616         RK_U32 picSizeInMbs = 0;
617 
618         picSizeInMbs = p_hal->pp->wFrameWidthInMbsMinus1 + 1;
619         picSizeInMbs = picSizeInMbs * (2 - pp->frame_mbs_only_flag)
620                        * (pp->wFrameHeightInMbsMinus1 + 1);
621         dirMvOffset = picSizeInMbs
622                       * ((p_hal->pp->chroma_format_idc == 0) ? 256 : 384);
623         dirMvOffset += (pp->field_pic_flag && pp->CurrPic.AssociatedFlag)
624                        ? (picSizeInMbs * 32) : 0;
625         if (dirMvOffset) {
626             RK_U32 offset = mpp_get_ioctl_version() ? dirMvOffset : dirMvOffset >> 4;
627             mpp_dev_set_reg_offset(p_hal->dev, 41, offset);
628         }
629         p_regs->SwReg41.dmmv_st_adr = mpp_buffer_get_fd(frame_buf);
630     }
631 
632     p_regs->SwReg03.sw_write_mvs_e = (p_long->nal_ref_idc != 0) ? 1 : 0; /* defalut set 1 */
633     p_regs->SwReg07.sw_dir_8x8_infer_e = pp->direct_8x8_inference_flag;
634     p_regs->SwReg07.sw_weight_pred_e = pp->weighted_pred_flag;
635     p_regs->SwReg07.sw_weight_bipr_idc = pp->weighted_bipred_idc;
636     p_regs->SwReg09.sw_refidx1_active = (pp->num_ref_idx_l1_active_minus1 + 1);
637     p_regs->SwReg05.sw_fieldpic_flag_e = (!pp->frame_mbs_only_flag) ? 1 : 0;
638 
639     p_regs->SwReg03.sw_pic_interlace_e =
640         (!pp->frame_mbs_only_flag
641          && (pp->MbaffFrameFlag || pp->field_pic_flag)) ? 1 : 0;
642     p_regs->SwReg03.sw_pic_fieldmode_e = pp->field_pic_flag;
643     p_regs->SwReg03.sw_pic_topfield_e = (!pp->CurrPic.AssociatedFlag) ? 1 : 0; /* bottomFieldFlag */
644     p_regs->SwReg03.sw_seq_mbaff_e = pp->MbaffFrameFlag;
645     p_regs->SwReg08.sw_8x8trans_flag_e = pp->transform_8x8_mode_flag;
646     p_regs->SwReg07.sw_blackwhite_e = (p_long->profileIdc >= 100
647                                        && pp->chroma_format_idc == 0) ? 1 : 0;
648     p_regs->SwReg05.sw_type1_quant_e = pp->scaleing_list_enable_flag;
649 
650     {
651         H264dVdpuRegCtx_t *reg_ctx = (H264dVdpuRegCtx_t *)p_hal->reg_ctx;
652         if (p_hal->pp->scaleing_list_enable_flag) {
653             RK_U32 temp = 0;
654             RK_U32 *ptr = (RK_U32 *)reg_ctx->sclst_ptr;
655 
656             for (i = 0; i < 6; i++) {
657                 for (j = 0; j < 4; j++) {
658                     temp = (p_hal->qm->bScalingLists4x4[i][4 * j + 0] << 24) |
659                            (p_hal->qm->bScalingLists4x4[i][4 * j + 1] << 16) |
660                            (p_hal->qm->bScalingLists4x4[i][4 * j + 2] << 8) |
661                            (p_hal->qm->bScalingLists4x4[i][4 * j + 3]);
662                     *ptr++ = temp;
663                 }
664             }
665 
666             for (i = 0; i < 2; i++) {
667                 for (j = 0; j < 16; j++) {
668                     temp = (p_hal->qm->bScalingLists8x8[i][4 * j + 0] << 24) |
669                            (p_hal->qm->bScalingLists8x8[i][4 * j + 1] << 16) |
670                            (p_hal->qm->bScalingLists8x8[i][4 * j + 2] << 8) |
671                            (p_hal->qm->bScalingLists8x8[i][4 * j + 3]);
672                     *ptr++ = temp;
673                 }
674             }
675         }
676         p_regs->SwReg40.qtable_st_adr = mpp_buffer_get_fd(reg_ctx->buf);
677     }
678 
679     p_regs->SwReg03.sw_dec_out_dis = 0; /* set defalut 0 */
680     p_regs->SwReg06.sw_ch_8pix_ileav_e = 0;
681     p_regs->SwReg01.sw_dec_en = 1;
682 
683     return ret = MPP_OK;
684 }
685 
vdpu1_set_device_regs(H264dHalCtx_t * p_hal,H264dVdpu1Regs_t * p_reg)686 static MPP_RET vdpu1_set_device_regs(H264dHalCtx_t *p_hal,
687                                      H264dVdpu1Regs_t *p_reg)
688 {
689     MPP_RET ret = MPP_ERR_UNKNOW;
690 
691     p_reg->SwReg03.sw_dec_mode = 0; /* set H264 mode */
692     p_reg->SwReg02.sw_dec_out_endian = 1;  /* little endian */
693     p_reg->SwReg02.sw_dec_in_endian = 0;  /* big endian */
694     p_reg->SwReg02.sw_dec_strendian_e = 1; //!< little endian
695     p_reg->SwReg02.sw_tiled_mode_msb = 0; /* 0: raster scan  1: tiled */
696 
697     /* bus_burst_length = 16, bus burst */
698     p_reg->SwReg02.sw_dec_max_burst = 16; /* (0, 4, 8, 16) choice one */
699     p_reg->SwReg02.sw_dec_scmd_dis = 0; /* disable */
700     p_reg->SwReg02.sw_dec_adv_pre_dis = 0; /* disable */
701     p_reg->SwReg55.sw_apf_threshold = 8;
702     p_reg->SwReg02.sw_dec_latency = 0; /* compensation for bus latency; values up to 63 */
703     p_reg->SwReg02.sw_dec_data_disc_e = 0;
704     p_reg->SwReg02.sw_dec_out_endian = 1; /* little endian */
705     p_reg->SwReg02.sw_dec_inswap32_e = 1; /* little endian */
706     p_reg->SwReg02.sw_dec_outswap32_e = 1;
707     p_reg->SwReg02.sw_dec_strswap32_e = 1;
708     p_reg->SwReg02.sw_dec_strendian_e = 1; /* little endian */
709     p_reg->SwReg02.sw_dec_timeout_e = 1;
710 
711     /* clock_gating  0:clock always on, 1: clock gating module control the key(turn off when decoder free) */
712     p_reg->SwReg02.sw_dec_clk_gate_e = 1;
713     p_reg->SwReg01.sw_dec_irq_dis_cfg = 0;
714 
715     //!< set AXI RW IDs
716     p_reg->SwReg02.sw_dec_axi_rd_id = (0xFF & 0xFFU); /* 0-255 */
717     p_reg->SwReg03.sw_dec_axi_wr_id = (0x00 & 0xFFU); /* 0-255 */
718 
719     ///!< Set prediction filter taps
720     {
721         RK_U32 val = 0;
722         p_reg->SwReg49.sw_pred_bc_tap_0_0 = 1;
723 
724         val = (RK_U32)(-5);
725         p_reg->SwReg49.sw_pred_bc_tap_0_1 = val;
726         p_reg->SwReg49.sw_pred_bc_tap_0_2 = 20;
727     }
728 
729     (void)p_hal;
730 
731     return ret = MPP_OK;
732 }
733 
734 /*!
735 ***********************************************************************
736 * \brief
737 *    init  VDPU granite decoder
738 ***********************************************************************
739 */
740 //extern "C"
vdpu1_h264d_init(void * hal,MppHalCfg * cfg)741 MPP_RET vdpu1_h264d_init(void *hal, MppHalCfg *cfg)
742 {
743     MPP_RET ret = MPP_ERR_UNKNOW;
744     H264dHalCtx_t  *p_hal = (H264dHalCtx_t *)hal;
745     INP_CHECK(ret, NULL == hal);
746     (void) cfg;
747 
748     //!< malloc init registers
749     MEM_CHECK(ret, p_hal->priv =
750                   mpp_calloc_size(void, sizeof(H264dVdpuPriv_t)));
751 
752     MEM_CHECK(ret, p_hal->reg_ctx = mpp_calloc_size(void, sizeof(H264dVdpuRegCtx_t)));
753     H264dVdpuRegCtx_t *reg_ctx = (H264dVdpuRegCtx_t *)p_hal->reg_ctx;
754     //!< malloc buffers
755     {
756         RK_U32 i = 0;
757         RK_U32 loop = p_hal->fast_mode ? MPP_ARRAY_ELEMS(reg_ctx->reg_buf) : 1;
758 
759         RK_U32 buf_size = VDPU_CABAC_TAB_SIZE +  VDPU_POC_BUF_SIZE + VDPU_SCALING_LIST_SIZE;
760         for (i = 0; i < loop; i++) {
761             FUN_CHECK(ret = mpp_buffer_get(p_hal->buf_group, &reg_ctx->reg_buf[i].buf,  buf_size));
762             reg_ctx->reg_buf[i].cabac_ptr = mpp_buffer_get_ptr(reg_ctx->reg_buf[i].buf);
763             reg_ctx->reg_buf[i].poc_ptr = reg_ctx->reg_buf[i].cabac_ptr + VDPU_CABAC_TAB_SIZE;
764             reg_ctx->reg_buf[i].sclst_ptr = reg_ctx->reg_buf[i].poc_ptr + VDPU_POC_BUF_SIZE;
765             reg_ctx->reg_buf[i].regs = mpp_calloc_size(void, sizeof(H264dVdpu1Regs_t));
766             //!< copy cabac table bytes
767             memcpy(reg_ctx->reg_buf[i].cabac_ptr, (void *)vdpu_cabac_table,  sizeof(vdpu_cabac_table));
768         }
769     }
770     if (!p_hal->fast_mode) {
771         reg_ctx->buf = reg_ctx->reg_buf[0].buf;
772         reg_ctx->cabac_ptr = reg_ctx->reg_buf[0].cabac_ptr;
773         reg_ctx->poc_ptr = reg_ctx->reg_buf[0].poc_ptr;
774         reg_ctx->sclst_ptr = reg_ctx->reg_buf[0].sclst_ptr;
775         reg_ctx->regs = reg_ctx->reg_buf[0].regs;
776     }
777 
778     mpp_slots_set_prop(p_hal->frame_slots, SLOTS_HOR_ALIGN, vdpu_hor_align);
779     mpp_slots_set_prop(p_hal->frame_slots, SLOTS_VER_ALIGN, vdpu_ver_align);
780 
781 __RETURN:
782     return MPP_OK;
783 __FAILED:
784     vdpu1_h264d_deinit(hal);
785 
786     return ret;
787 }
788 
789 /*!
790 ***********************************************************************
791 * \brief
792 *    deinit
793 ***********************************************************************
794 */
795 //extern "C"
vdpu1_h264d_deinit(void * hal)796 MPP_RET vdpu1_h264d_deinit(void *hal)
797 {
798     H264dHalCtx_t  *p_hal = (H264dHalCtx_t *)hal;
799     H264dVdpuRegCtx_t *reg_ctx = (H264dVdpuRegCtx_t *)p_hal->reg_ctx;
800 
801     RK_U32 i = 0;
802     RK_U32 loop = p_hal->fast_mode ? MPP_ARRAY_ELEMS(reg_ctx->reg_buf) : 1;
803     for (i = 0; i < loop; i++) {
804         MPP_FREE(reg_ctx->reg_buf[i].regs);
805         mpp_buffer_put(reg_ctx->reg_buf[i].buf);
806     }
807     MPP_FREE(p_hal->reg_ctx);
808     MPP_FREE(p_hal->priv);
809 
810     return MPP_OK;
811 }
812 
813 /*!
814 ***********************************************************************
815 * \brief
816 *    generate register
817 ***********************************************************************
818 */
819 //extern "C"
vdpu1_h264d_gen_regs(void * hal,HalTaskInfo * task)820 MPP_RET vdpu1_h264d_gen_regs(void *hal, HalTaskInfo *task)
821 {
822     MPP_RET ret = MPP_ERR_UNKNOW;
823 
824     H264dVdpuPriv_t *priv = NULL;
825     H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
826     INP_CHECK(ret, NULL == p_hal);
827     p_hal->in_task = &task->dec;
828     if (task->dec.flags.parse_err ||
829         (task->dec.flags.ref_err && !p_hal->cfg->base.disable_error)) {
830         goto __RETURN;
831     }
832     priv = p_hal->priv;
833     priv->layed_id = p_hal->pp->curr_layer_id;
834 
835     H264dVdpuRegCtx_t *reg_ctx = (H264dVdpuRegCtx_t *)p_hal->reg_ctx;
836     if (p_hal->fast_mode) {
837         RK_U32 i = 0;
838         for (i = 0; i <  MPP_ARRAY_ELEMS(reg_ctx->reg_buf); i++) {
839             if (!reg_ctx->reg_buf[i].valid) {
840                 task->dec.reg_index = i;
841                 reg_ctx->buf = reg_ctx->reg_buf[i].buf;
842                 reg_ctx->cabac_ptr = reg_ctx->reg_buf[i].cabac_ptr;
843                 reg_ctx->poc_ptr = reg_ctx->reg_buf[i].poc_ptr;
844                 reg_ctx->sclst_ptr = reg_ctx->reg_buf[i].sclst_ptr;
845                 reg_ctx->regs = reg_ctx->reg_buf[i].regs;
846                 reg_ctx->reg_buf[i].valid = 1;
847                 break;
848             }
849         }
850     }
851 
852     FUN_CHECK(ret = adjust_input(priv, &p_hal->slice_long[0], p_hal->pp));
853     FUN_CHECK(ret = vdpu1_set_device_regs(p_hal, (H264dVdpu1Regs_t *)reg_ctx->regs));
854     FUN_CHECK(ret = vdpu1_set_pic_regs(p_hal, (H264dVdpu1Regs_t *)reg_ctx->regs));
855     FUN_CHECK(ret = vdpu1_set_vlc_regs(p_hal, (H264dVdpu1Regs_t *)reg_ctx->regs));
856     FUN_CHECK(ret = vdpu1_set_ref_regs(p_hal, (H264dVdpu1Regs_t *)reg_ctx->regs));
857     FUN_CHECK(ret = vdpu1_set_asic_regs(p_hal, (H264dVdpu1Regs_t *)reg_ctx->regs));
858     mpp_buffer_sync_end(reg_ctx->buf);
859 
860 __RETURN:
861     return ret = MPP_OK;
862 __FAILED:
863     return ret;
864 }
865 
866 /*!
867 ***********************************************************************
868 * \brief h
869 *    start hard
870 ***********************************************************************
871 */
872 //extern "C"
vdpu1_h264d_start(void * hal,HalTaskInfo * task)873 MPP_RET vdpu1_h264d_start(void *hal, HalTaskInfo *task)
874 {
875     MPP_RET ret = MPP_ERR_UNKNOW;
876     H264dHalCtx_t *p_hal  = (H264dHalCtx_t *)hal;
877     H264dVdpuRegCtx_t *reg_ctx = (H264dVdpuRegCtx_t *)p_hal->reg_ctx;
878     H264dVdpu1Regs_t *p_regs = (H264dVdpu1Regs_t *)(p_hal->fast_mode ?
879                                                     reg_ctx->reg_buf[task->dec.reg_index].regs :
880                                                     reg_ctx->regs);
881 
882     if (task->dec.flags.parse_err ||
883         (task->dec.flags.ref_err && !p_hal->cfg->base.disable_error)) {
884         goto __RETURN;
885     }
886 
887     p_regs->SwReg57.sw_cache_en = 1;
888     p_regs->SwReg57.sw_pref_sigchan = 1;
889     p_regs->SwReg57.sw_intra_dbl3t = 1;
890     p_regs->SwReg57.sw_inter_dblspeed = 1;
891     p_regs->SwReg57.sw_intra_dblspeed = 1;
892     p_regs->SwReg57.sw_paral_bus = 1;
893 
894     do {
895         MppDevRegWrCfg wr_cfg;
896         MppDevRegRdCfg rd_cfg;
897         RK_U32 reg_size = DEC_VDPU1_REGISTERS * sizeof(RK_U32);
898 
899         wr_cfg.reg = reg_ctx->regs;
900         wr_cfg.size = reg_size;
901         wr_cfg.offset = 0;
902 
903         ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_REG_WR, &wr_cfg);
904         if (ret) {
905             mpp_err_f("set register write failed %d\n", ret);
906             break;
907         }
908 
909         rd_cfg.reg = reg_ctx->regs;
910         rd_cfg.size = reg_size;
911         rd_cfg.offset = 0;
912 
913         ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_REG_RD, &rd_cfg);
914         if (ret) {
915             mpp_err_f("set register read failed %d\n", ret);
916             break;
917         }
918 
919         ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_CMD_SEND, NULL);
920         if (ret) {
921             mpp_err_f("send cmd failed %d\n", ret);
922             break;
923         }
924     } while (0);
925 
926 __RETURN:
927     (void)task;
928     return ret = MPP_OK;
929 }
930 
931 /*!
932 ***********************************************************************
933 * \brief
934 *    wait hard
935 ***********************************************************************
936 */
937 //extern "C"
vdpu1_h264d_wait(void * hal,HalTaskInfo * task)938 MPP_RET vdpu1_h264d_wait(void *hal, HalTaskInfo *task)
939 {
940     MPP_RET ret = MPP_ERR_UNKNOW;
941     H264dHalCtx_t  *p_hal = (H264dHalCtx_t *)hal;
942     H264dVdpuRegCtx_t *reg_ctx = (H264dVdpuRegCtx_t *)p_hal->reg_ctx;
943     H264dVdpu1Regs_t *p_regs = (H264dVdpu1Regs_t *)(p_hal->fast_mode ?
944                                                     reg_ctx->reg_buf[task->dec.reg_index].regs :
945                                                     reg_ctx->regs);
946 
947     if (task->dec.flags.parse_err ||
948         (task->dec.flags.ref_err && !p_hal->cfg->base.disable_error)) {
949         goto __SKIP_HARD;
950     }
951 
952     ret = mpp_dev_ioctl(p_hal->dev, MPP_DEV_CMD_POLL, NULL);
953     if (ret)
954         mpp_err_f("poll cmd failed %d\n", ret);
955 
956 __SKIP_HARD:
957     if (p_hal->dec_cb) {
958         DecCbHalDone param;
959 
960         param.task = (void *)&task->dec;
961         param.regs = (RK_U32 *)reg_ctx->regs;
962         param.hard_err = !p_regs->SwReg01.sw_dec_rdy_int;
963 
964         mpp_callback(p_hal->dec_cb, &param);
965     }
966     memset(&p_regs->SwReg01, 0, sizeof(RK_U32));
967     if (p_hal->fast_mode) {
968         reg_ctx->reg_buf[task->dec.reg_index].valid = 0;
969     }
970     (void)task;
971 
972     return ret = MPP_OK;
973 }
974 
975 /*!
976 ***********************************************************************
977 * \brief
978 *    reset
979 ***********************************************************************
980 */
981 //extern "C"
vdpu1_h264d_reset(void * hal)982 MPP_RET vdpu1_h264d_reset(void *hal)
983 {
984     MPP_RET ret = MPP_ERR_UNKNOW;
985     H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
986 
987     INP_CHECK(ret, NULL == p_hal);
988     memset(p_hal->priv, 0, sizeof(H264dVdpuPriv_t));
989 
990 __RETURN:
991     return ret = MPP_OK;
992 }
993 
994 /*!
995 ***********************************************************************
996 * \brief
997 *    flush
998 ***********************************************************************
999 */
1000 //extern "C"
vdpu1_h264d_flush(void * hal)1001 MPP_RET vdpu1_h264d_flush(void *hal)
1002 {
1003     MPP_RET ret = MPP_ERR_UNKNOW;
1004     H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
1005 
1006     INP_CHECK(ret, NULL == p_hal);
1007 
1008 
1009 
1010 __RETURN:
1011     return ret = MPP_OK;
1012 }
1013 
1014 /*!
1015 ***********************************************************************
1016 * \brief
1017 *    control
1018 ***********************************************************************
1019 */
1020 //extern "C"
vdpu1_h264d_control(void * hal,MpiCmd cmd_type,void * param)1021 MPP_RET vdpu1_h264d_control(void *hal, MpiCmd cmd_type, void *param)
1022 {
1023     MPP_RET ret = MPP_ERR_UNKNOW;
1024     H264dHalCtx_t *p_hal = (H264dHalCtx_t *)hal;
1025 
1026     INP_CHECK(ret, NULL == p_hal);
1027 
1028     (void)hal;
1029     (void)cmd_type;
1030     (void)param;
1031 __RETURN:
1032     return ret = MPP_OK;
1033 }
1034 
1035 const MppHalApi hal_h264d_vdpu1 = {
1036     .name     = "h264d_vdpu1",
1037     .type     = MPP_CTX_DEC,
1038     .coding   = MPP_VIDEO_CodingAVC,
1039     .ctx_size = sizeof(H264dVdpuRegCtx_t),
1040     .flag     = 0,
1041     .init     = vdpu1_h264d_init,
1042     .deinit   = vdpu1_h264d_deinit,
1043     .reg_gen  = vdpu1_h264d_gen_regs,
1044     .start    = vdpu1_h264d_start,
1045     .wait     = vdpu1_h264d_wait,
1046     .reset    = vdpu1_h264d_reset,
1047     .flush    = vdpu1_h264d_flush,
1048     .control  = vdpu1_h264d_control,
1049 };
1050