xref: /rockchip-linux_mpp/mpp/hal/vpu/mpg4d/hal_m4vd_vdpu2.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka  * Copyright 2016 Rockchip Electronics Co. LTD
3*437bfbebSnyanmisaka  *
4*437bfbebSnyanmisaka  * Licensed under the Apache License, Version 2.0 (the "License");
5*437bfbebSnyanmisaka  * you may not use this file except in compliance with the License.
6*437bfbebSnyanmisaka  * You may obtain a copy of the License at
7*437bfbebSnyanmisaka  *
8*437bfbebSnyanmisaka  *      http://www.apache.org/licenses/LICENSE-2.0
9*437bfbebSnyanmisaka  *
10*437bfbebSnyanmisaka  * Unless required by applicable law or agreed to in writing, software
11*437bfbebSnyanmisaka  * distributed under the License is distributed on an "AS IS" BASIS,
12*437bfbebSnyanmisaka  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*437bfbebSnyanmisaka  * See the License for the specific language governing permissions and
14*437bfbebSnyanmisaka  * limitations under the License.
15*437bfbebSnyanmisaka  */
16*437bfbebSnyanmisaka 
17*437bfbebSnyanmisaka #define MODULE_TAG "hal_m4vd_vdpu2"
18*437bfbebSnyanmisaka 
19*437bfbebSnyanmisaka #include <stdio.h>
20*437bfbebSnyanmisaka #include <string.h>
21*437bfbebSnyanmisaka 
22*437bfbebSnyanmisaka #include "mpp_mem.h"
23*437bfbebSnyanmisaka #include "mpp_env.h"
24*437bfbebSnyanmisaka #include "mpp_debug.h"
25*437bfbebSnyanmisaka #include "mpp_buffer.h"
26*437bfbebSnyanmisaka #include "mpp_common.h"
27*437bfbebSnyanmisaka 
28*437bfbebSnyanmisaka #include "mpg4d_syntax.h"
29*437bfbebSnyanmisaka #include "hal_mpg4d_api.h"
30*437bfbebSnyanmisaka #include "hal_m4vd_com.h"
31*437bfbebSnyanmisaka #include "hal_m4vd_vdpu2.h"
32*437bfbebSnyanmisaka #include "hal_m4vd_vdpu2_reg.h"
33*437bfbebSnyanmisaka #include "mpp_dec_cb_param.h"
34*437bfbebSnyanmisaka 
vdpu2_mpg4d_setup_regs_by_syntax(hal_mpg4_ctx * ctx,MppSyntax syntax)35*437bfbebSnyanmisaka static void vdpu2_mpg4d_setup_regs_by_syntax(hal_mpg4_ctx *ctx, MppSyntax syntax)
36*437bfbebSnyanmisaka {
37*437bfbebSnyanmisaka     M4vdVdpu2Regs_t *regs = ctx->regs;
38*437bfbebSnyanmisaka     DXVA2_DecodeBufferDesc **data = syntax.data;
39*437bfbebSnyanmisaka     DXVA_PicParams_MPEG4_PART2 *pp = NULL;
40*437bfbebSnyanmisaka     DXVA_QmatrixData *qm = NULL;
41*437bfbebSnyanmisaka     RK_S32 mv_buf_fd = mpp_buffer_get_fd(ctx->mv_buf);
42*437bfbebSnyanmisaka     RK_U32 stream_length = 0;
43*437bfbebSnyanmisaka     RK_U32 stream_used = 0;
44*437bfbebSnyanmisaka     RK_U32 i;
45*437bfbebSnyanmisaka 
46*437bfbebSnyanmisaka     for (i = 0; i < syntax.number; i++) {
47*437bfbebSnyanmisaka         DXVA2_DecodeBufferDesc *desc = data[i];
48*437bfbebSnyanmisaka         switch (desc->CompressedBufferType) {
49*437bfbebSnyanmisaka         case DXVA2_PictureParametersBufferType : {
50*437bfbebSnyanmisaka             pp = (DXVA_PicParams_MPEG4_PART2 *)desc->pvPVPState;
51*437bfbebSnyanmisaka         } break;
52*437bfbebSnyanmisaka         case DXVA2_InverseQuantizationMatrixBufferType : {
53*437bfbebSnyanmisaka             qm = (DXVA_QmatrixData *)desc->pvPVPState;
54*437bfbebSnyanmisaka         } break;
55*437bfbebSnyanmisaka         case DXVA2_BitStreamDateBufferType : {
56*437bfbebSnyanmisaka             stream_length = desc->DataSize;
57*437bfbebSnyanmisaka             stream_used = desc->DataOffset;
58*437bfbebSnyanmisaka             ctx->bitstrm_len = stream_length;
59*437bfbebSnyanmisaka         } break;
60*437bfbebSnyanmisaka         default : {
61*437bfbebSnyanmisaka             mpp_err_f("found invalid buffer descriptor type %d\n", desc->CompressedBufferType);
62*437bfbebSnyanmisaka         } break;
63*437bfbebSnyanmisaka         }
64*437bfbebSnyanmisaka     }
65*437bfbebSnyanmisaka 
66*437bfbebSnyanmisaka     mpp_assert(pp);
67*437bfbebSnyanmisaka     mpp_assert(qm);
68*437bfbebSnyanmisaka     mpp_assert(stream_length);
69*437bfbebSnyanmisaka     mpp_assert(stream_used);
70*437bfbebSnyanmisaka 
71*437bfbebSnyanmisaka     // copy qp table to buffer
72*437bfbebSnyanmisaka     {
73*437bfbebSnyanmisaka         RK_U8 *dst = (RK_U8 *)mpp_buffer_get_ptr(ctx->qp_table);
74*437bfbebSnyanmisaka         RK_U8 *src = (qm->bNewQmatrix[0]) ? (qm->Qmatrix[0]) : (default_intra_matrix);
75*437bfbebSnyanmisaka 
76*437bfbebSnyanmisaka         memcpy(dst, src, 64);
77*437bfbebSnyanmisaka         dst += 64;
78*437bfbebSnyanmisaka 
79*437bfbebSnyanmisaka         src = (qm->bNewQmatrix[1]) ? (qm->Qmatrix[1]) : (default_inter_matrix);
80*437bfbebSnyanmisaka         memcpy(dst, src, 64);
81*437bfbebSnyanmisaka     }
82*437bfbebSnyanmisaka 
83*437bfbebSnyanmisaka     regs->reg120.sw_pic_mb_width = (pp->vop_width  + 15) >> 4;
84*437bfbebSnyanmisaka     regs->reg120.sw_pic_mb_hight_p = (pp->vop_height + 15) >> 4;
85*437bfbebSnyanmisaka     if (pp->custorm_version == 4) {
86*437bfbebSnyanmisaka         regs->reg120.sw_mb_width_off = pp->vop_width & 0xf;
87*437bfbebSnyanmisaka         regs->reg120.sw_mb_height_off = pp->vop_height & 0xf;
88*437bfbebSnyanmisaka     } else {
89*437bfbebSnyanmisaka         regs->reg120.sw_mb_width_off = 0;
90*437bfbebSnyanmisaka         regs->reg120.sw_mb_height_off = 0;
91*437bfbebSnyanmisaka     }
92*437bfbebSnyanmisaka     regs->reg53_dec_mode = 1;
93*437bfbebSnyanmisaka 
94*437bfbebSnyanmisaka     /* note: When comparing bit 19 of reg136(that is sw_alt_scan_flag_e) with bit 6 of
95*437bfbebSnyanmisaka     **       reg120(that is sw_alt_scan_e), we may be confused about the function of
96*437bfbebSnyanmisaka     **       these two bits. According to C Model, just sw_alt_scan_flag_e is set,
97*437bfbebSnyanmisaka     **       but not sw_alt_scan_e.
98*437bfbebSnyanmisaka     */
99*437bfbebSnyanmisaka     regs->reg136.sw_alt_scan_flag_e = pp->alternate_vertical_scan_flag;
100*437bfbebSnyanmisaka     regs->reg52_error_concealment.sw_xdim_mbst = 0;
101*437bfbebSnyanmisaka     regs->reg52_error_concealment.sw_ydim_mbst = 0;
102*437bfbebSnyanmisaka     regs->reg50_dec_ctrl.sw_dblk_flt_dis = 1;
103*437bfbebSnyanmisaka     regs->reg136.sw_rounding = pp->vop_rounding_type;
104*437bfbebSnyanmisaka     regs->reg122.sw_intradc_vlc_thr = pp->intra_dc_vlc_thr;
105*437bfbebSnyanmisaka     regs->reg51_stream_info.sw_qp_init_val = pp->vop_quant;
106*437bfbebSnyanmisaka     regs->reg122.sw_sync_markers_en = 1;
107*437bfbebSnyanmisaka 
108*437bfbebSnyanmisaka     {
109*437bfbebSnyanmisaka         /*
110*437bfbebSnyanmisaka          * update stream base address here according to consumed bit length
111*437bfbebSnyanmisaka          * 1. hardware start address has to be 64 bit align
112*437bfbebSnyanmisaka          * 2. hardware need to know which is the start bit in
113*437bfbebSnyanmisaka          * 2. pass (10bit fd + (offset << 10)) register value to kernel
114*437bfbebSnyanmisaka          */
115*437bfbebSnyanmisaka         RK_U32 val = regs->reg64_input_stream_base;
116*437bfbebSnyanmisaka         RK_U32 consumed_bytes = stream_used >> 3;
117*437bfbebSnyanmisaka         RK_U32 consumed_bytes_align = consumed_bytes & (~0x7);
118*437bfbebSnyanmisaka         RK_U32 start_bit_offset = stream_used & 0x3F;
119*437bfbebSnyanmisaka         RK_U32 left_bytes = stream_length - consumed_bytes_align;
120*437bfbebSnyanmisaka 
121*437bfbebSnyanmisaka         regs->reg64_input_stream_base = val;
122*437bfbebSnyanmisaka         if (consumed_bytes_align)
123*437bfbebSnyanmisaka             mpp_dev_set_reg_offset(ctx->dev, 64, consumed_bytes_align);
124*437bfbebSnyanmisaka         regs->reg122.sw_stream_start_word = start_bit_offset;
125*437bfbebSnyanmisaka         regs->reg51_stream_info.sw_stream_len = left_bytes;
126*437bfbebSnyanmisaka     }
127*437bfbebSnyanmisaka     regs->reg122.sw_vop_time_incr = pp->vop_time_increment_resolution;
128*437bfbebSnyanmisaka 
129*437bfbebSnyanmisaka     switch (pp->vop_coding_type) {
130*437bfbebSnyanmisaka     case MPEG4_B_VOP : {
131*437bfbebSnyanmisaka         RK_U32 time_bp = pp->time_bp;
132*437bfbebSnyanmisaka         RK_U32 time_pp = pp->time_pp;
133*437bfbebSnyanmisaka 
134*437bfbebSnyanmisaka         RK_U32 trb_per_trd_d0  = MPP_DIV((((RK_S64)(1 * time_bp + 0)) << 27) + 1 * (time_pp - 1), time_pp);
135*437bfbebSnyanmisaka         RK_U32 trb_per_trd_d1  = MPP_DIV((((RK_S64)(2 * time_bp + 1)) << 27) + 2 * (time_pp - 0), 2 * time_pp + 1);
136*437bfbebSnyanmisaka         RK_U32 trb_per_trd_dm1 = MPP_DIV((((RK_S64)(2 * time_bp - 1)) << 27) + 2 * (time_pp - 1), 2 * time_pp - 1);
137*437bfbebSnyanmisaka 
138*437bfbebSnyanmisaka         regs->reg57_enable_ctrl.sw_pic_type_sel1 = 1;
139*437bfbebSnyanmisaka         regs->reg57_enable_ctrl.sw_pic_type_sel0 = 1;
140*437bfbebSnyanmisaka         regs->reg136.sw_rounding = 0;
141*437bfbebSnyanmisaka         regs->reg131_ref0_base = 1;
142*437bfbebSnyanmisaka 
143*437bfbebSnyanmisaka         mpp_assert(ctx->fd_ref1 >= 0);
144*437bfbebSnyanmisaka         if (ctx->fd_ref1 >= 0) {
145*437bfbebSnyanmisaka             regs->reg131_ref0_base = (RK_U32)ctx->fd_ref1;
146*437bfbebSnyanmisaka             regs->reg148_ref1_base = (RK_U32)ctx->fd_ref1;
147*437bfbebSnyanmisaka         } else {
148*437bfbebSnyanmisaka             regs->reg131_ref0_base = (RK_U32)ctx->fd_curr;
149*437bfbebSnyanmisaka             regs->reg148_ref1_base = (RK_U32)ctx->fd_curr;
150*437bfbebSnyanmisaka         }
151*437bfbebSnyanmisaka 
152*437bfbebSnyanmisaka         mpp_assert(ctx->fd_ref0 >= 0);
153*437bfbebSnyanmisaka         if (ctx->fd_ref0 >= 0) {
154*437bfbebSnyanmisaka             regs->reg134_ref2_base = (RK_U32)ctx->fd_ref0;
155*437bfbebSnyanmisaka             regs->reg135_ref3_base = (RK_U32)ctx->fd_ref0;
156*437bfbebSnyanmisaka         } else {
157*437bfbebSnyanmisaka             regs->reg134_ref2_base = (RK_U32)ctx->fd_curr;
158*437bfbebSnyanmisaka             regs->reg135_ref3_base = (RK_U32)ctx->fd_curr;
159*437bfbebSnyanmisaka         }
160*437bfbebSnyanmisaka 
161*437bfbebSnyanmisaka         regs->reg136.sw_hrz_bit_of_fwd_mv = pp->vop_fcode_forward;
162*437bfbebSnyanmisaka         regs->reg136.sw_vrz_bit_of_fwd_mv = pp->vop_fcode_forward;
163*437bfbebSnyanmisaka         regs->reg136.sw_hrz_bit_of_bwd_mv = pp->vop_fcode_backward;
164*437bfbebSnyanmisaka         regs->reg136.sw_vrz_bit_of_bwd_mv = pp->vop_fcode_backward;
165*437bfbebSnyanmisaka         regs->reg57_enable_ctrl.sw_dmmv_wr_en = 0;
166*437bfbebSnyanmisaka         regs->reg62_directmv_base = mv_buf_fd;
167*437bfbebSnyanmisaka         regs->reg137.sw_trb_per_trd_d0 = trb_per_trd_d0;
168*437bfbebSnyanmisaka         regs->reg139.sw_trb_per_trd_d1 = trb_per_trd_d1;
169*437bfbebSnyanmisaka         regs->reg138.sw_trb_per_trd_dm1 = trb_per_trd_dm1;
170*437bfbebSnyanmisaka     } break;
171*437bfbebSnyanmisaka     case MPEG4_P_VOP : {
172*437bfbebSnyanmisaka         regs->reg57_enable_ctrl.sw_pic_type_sel1 = 0;
173*437bfbebSnyanmisaka         regs->reg57_enable_ctrl.sw_pic_type_sel0 = 1;
174*437bfbebSnyanmisaka 
175*437bfbebSnyanmisaka         if (ctx->fd_ref0 >= 0) {
176*437bfbebSnyanmisaka             regs->reg131_ref0_base = (RK_U32)ctx->fd_ref0;
177*437bfbebSnyanmisaka             regs->reg148_ref1_base = (RK_U32)ctx->fd_ref0;
178*437bfbebSnyanmisaka         } else {
179*437bfbebSnyanmisaka             regs->reg131_ref0_base = (RK_U32)ctx->fd_curr;
180*437bfbebSnyanmisaka             regs->reg148_ref1_base = (RK_U32)ctx->fd_curr;
181*437bfbebSnyanmisaka         }
182*437bfbebSnyanmisaka         regs->reg134_ref2_base = (RK_U32)ctx->fd_curr;
183*437bfbebSnyanmisaka         regs->reg135_ref3_base = (RK_U32)ctx->fd_curr;
184*437bfbebSnyanmisaka 
185*437bfbebSnyanmisaka         regs->reg136.sw_hrz_bit_of_fwd_mv = pp->vop_fcode_forward;
186*437bfbebSnyanmisaka         regs->reg136.sw_vrz_bit_of_fwd_mv = pp->vop_fcode_forward;
187*437bfbebSnyanmisaka         regs->reg57_enable_ctrl.sw_dmmv_wr_en = 1;
188*437bfbebSnyanmisaka         regs->reg62_directmv_base = mv_buf_fd;
189*437bfbebSnyanmisaka     } break;
190*437bfbebSnyanmisaka     case MPEG4_I_VOP : {
191*437bfbebSnyanmisaka         regs->reg57_enable_ctrl.sw_pic_type_sel1 = 0;
192*437bfbebSnyanmisaka         regs->reg57_enable_ctrl.sw_pic_type_sel0 = 0;
193*437bfbebSnyanmisaka 
194*437bfbebSnyanmisaka         regs->reg131_ref0_base = (RK_U32)ctx->fd_curr;
195*437bfbebSnyanmisaka         regs->reg148_ref1_base = (RK_U32)ctx->fd_curr;
196*437bfbebSnyanmisaka         regs->reg134_ref2_base = (RK_U32)ctx->fd_curr;
197*437bfbebSnyanmisaka         regs->reg135_ref3_base = (RK_U32)ctx->fd_curr;
198*437bfbebSnyanmisaka 
199*437bfbebSnyanmisaka         regs->reg57_enable_ctrl.sw_dmmv_wr_en = 0;
200*437bfbebSnyanmisaka         regs->reg62_directmv_base = mv_buf_fd;
201*437bfbebSnyanmisaka 
202*437bfbebSnyanmisaka         regs->reg136.sw_hrz_bit_of_fwd_mv = 1;
203*437bfbebSnyanmisaka         regs->reg136.sw_vrz_bit_of_fwd_mv = 1;
204*437bfbebSnyanmisaka     } break;
205*437bfbebSnyanmisaka     default : {
206*437bfbebSnyanmisaka         /* no nothing */
207*437bfbebSnyanmisaka     } break;
208*437bfbebSnyanmisaka     }
209*437bfbebSnyanmisaka 
210*437bfbebSnyanmisaka     if (pp->interlaced) {
211*437bfbebSnyanmisaka         regs->reg57_enable_ctrl.sw_curpic_code_sel = 1;
212*437bfbebSnyanmisaka         regs->reg57_enable_ctrl.sw_curpic_stru_sel = 0;
213*437bfbebSnyanmisaka         regs->reg120.sw_topfieldfirst_e = pp->top_field_first;
214*437bfbebSnyanmisaka     }
215*437bfbebSnyanmisaka 
216*437bfbebSnyanmisaka     regs->reg136.sw_prev_pic_type = pp->prev_coding_type;
217*437bfbebSnyanmisaka     regs->reg122.sw_quant_type_1_en = pp->quant_type;
218*437bfbebSnyanmisaka     regs->reg61_qtable_base = mpp_buffer_get_fd(ctx->qp_table);
219*437bfbebSnyanmisaka     regs->reg136.sw_fwd_mv_y_resolution = pp->quarter_sample;
220*437bfbebSnyanmisaka 
221*437bfbebSnyanmisaka }
222*437bfbebSnyanmisaka 
vdpu2_mpg4d_init(void * hal,MppHalCfg * cfg)223*437bfbebSnyanmisaka MPP_RET vdpu2_mpg4d_init(void *hal, MppHalCfg *cfg)
224*437bfbebSnyanmisaka {
225*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
226*437bfbebSnyanmisaka     M4vdVdpu2Regs_t *regs = NULL;
227*437bfbebSnyanmisaka     MppBufferGroup group = NULL;
228*437bfbebSnyanmisaka     MppBuffer mv_buf = NULL;
229*437bfbebSnyanmisaka     MppBuffer qp_table = NULL;
230*437bfbebSnyanmisaka     hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal;
231*437bfbebSnyanmisaka 
232*437bfbebSnyanmisaka     mpp_assert(hal);
233*437bfbebSnyanmisaka 
234*437bfbebSnyanmisaka     ret = mpp_buffer_group_get_internal(&group, MPP_BUFFER_TYPE_ION);
235*437bfbebSnyanmisaka     if (ret) {
236*437bfbebSnyanmisaka         mpp_err_f("failed to get buffer group ret %d\n", ret);
237*437bfbebSnyanmisaka         goto ERR_RET;
238*437bfbebSnyanmisaka     }
239*437bfbebSnyanmisaka 
240*437bfbebSnyanmisaka     ret = mpp_buffer_get(group, &mv_buf, MPEG4_MAX_MV_BUF_SIZE);
241*437bfbebSnyanmisaka     if (ret) {
242*437bfbebSnyanmisaka         mpp_err_f("failed to get mv buffer ret %d\n", ret);
243*437bfbebSnyanmisaka         goto ERR_RET;
244*437bfbebSnyanmisaka     }
245*437bfbebSnyanmisaka 
246*437bfbebSnyanmisaka     ret = mpp_buffer_get(group, &qp_table, 64 * 2 * sizeof(RK_U8));
247*437bfbebSnyanmisaka     if (ret) {
248*437bfbebSnyanmisaka         mpp_err_f("failed to get qp talbe buffer ret %d\n", ret);
249*437bfbebSnyanmisaka         goto ERR_RET;
250*437bfbebSnyanmisaka     }
251*437bfbebSnyanmisaka 
252*437bfbebSnyanmisaka     regs = mpp_calloc(M4vdVdpu2Regs_t, 1);
253*437bfbebSnyanmisaka     if (NULL == regs) {
254*437bfbebSnyanmisaka         mpp_err_f("failed to malloc register ret\n");
255*437bfbebSnyanmisaka         ret = MPP_ERR_MALLOC;
256*437bfbebSnyanmisaka         goto ERR_RET;
257*437bfbebSnyanmisaka     }
258*437bfbebSnyanmisaka 
259*437bfbebSnyanmisaka     ret = mpp_dev_init(&ctx->dev, VPU_CLIENT_VDPU2);
260*437bfbebSnyanmisaka     if (ret) {
261*437bfbebSnyanmisaka         mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
262*437bfbebSnyanmisaka         goto ERR_RET;
263*437bfbebSnyanmisaka     }
264*437bfbebSnyanmisaka 
265*437bfbebSnyanmisaka     ctx->frm_slots  = cfg->frame_slots;
266*437bfbebSnyanmisaka     ctx->pkt_slots  = cfg->packet_slots;
267*437bfbebSnyanmisaka     ctx->dec_cb     = cfg->dec_cb;
268*437bfbebSnyanmisaka     ctx->group      = group;
269*437bfbebSnyanmisaka     ctx->mv_buf     = mv_buf;
270*437bfbebSnyanmisaka     ctx->qp_table   = qp_table;
271*437bfbebSnyanmisaka     ctx->regs       = regs;
272*437bfbebSnyanmisaka     cfg->dev        = ctx->dev;
273*437bfbebSnyanmisaka 
274*437bfbebSnyanmisaka     mpp_env_get_u32("hal_mpg4d_debug", &hal_mpg4d_debug, 0);
275*437bfbebSnyanmisaka 
276*437bfbebSnyanmisaka     return ret;
277*437bfbebSnyanmisaka ERR_RET:
278*437bfbebSnyanmisaka     if (regs) {
279*437bfbebSnyanmisaka         mpp_free(regs);
280*437bfbebSnyanmisaka         regs = NULL;
281*437bfbebSnyanmisaka     }
282*437bfbebSnyanmisaka 
283*437bfbebSnyanmisaka     if (qp_table) {
284*437bfbebSnyanmisaka         mpp_buffer_put(qp_table);
285*437bfbebSnyanmisaka         qp_table = NULL;
286*437bfbebSnyanmisaka     }
287*437bfbebSnyanmisaka 
288*437bfbebSnyanmisaka     if (mv_buf) {
289*437bfbebSnyanmisaka         mpp_buffer_put(mv_buf);
290*437bfbebSnyanmisaka         mv_buf = NULL;
291*437bfbebSnyanmisaka     }
292*437bfbebSnyanmisaka 
293*437bfbebSnyanmisaka     if (group) {
294*437bfbebSnyanmisaka         mpp_buffer_group_put(group);
295*437bfbebSnyanmisaka         group = NULL;
296*437bfbebSnyanmisaka     }
297*437bfbebSnyanmisaka 
298*437bfbebSnyanmisaka     return ret;
299*437bfbebSnyanmisaka }
300*437bfbebSnyanmisaka 
vdpu2_mpg4d_deinit(void * hal)301*437bfbebSnyanmisaka MPP_RET vdpu2_mpg4d_deinit(void *hal)
302*437bfbebSnyanmisaka {
303*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
304*437bfbebSnyanmisaka     hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal;
305*437bfbebSnyanmisaka 
306*437bfbebSnyanmisaka     mpp_assert(hal);
307*437bfbebSnyanmisaka 
308*437bfbebSnyanmisaka     if (ctx->regs) {
309*437bfbebSnyanmisaka         mpp_free(ctx->regs);
310*437bfbebSnyanmisaka         ctx->regs = NULL;
311*437bfbebSnyanmisaka     }
312*437bfbebSnyanmisaka 
313*437bfbebSnyanmisaka     if (ctx->qp_table) {
314*437bfbebSnyanmisaka         mpp_buffer_put(ctx->qp_table);
315*437bfbebSnyanmisaka         ctx->qp_table = NULL;
316*437bfbebSnyanmisaka     }
317*437bfbebSnyanmisaka 
318*437bfbebSnyanmisaka     if (ctx->mv_buf) {
319*437bfbebSnyanmisaka         mpp_buffer_put(ctx->mv_buf);
320*437bfbebSnyanmisaka         ctx->mv_buf = NULL;
321*437bfbebSnyanmisaka     }
322*437bfbebSnyanmisaka 
323*437bfbebSnyanmisaka     if (ctx->group) {
324*437bfbebSnyanmisaka         mpp_buffer_group_put(ctx->group);
325*437bfbebSnyanmisaka         ctx->group = NULL;
326*437bfbebSnyanmisaka     }
327*437bfbebSnyanmisaka 
328*437bfbebSnyanmisaka     if (ctx->dev) {
329*437bfbebSnyanmisaka         mpp_dev_deinit(ctx->dev);
330*437bfbebSnyanmisaka         ctx->dev = NULL;
331*437bfbebSnyanmisaka     }
332*437bfbebSnyanmisaka 
333*437bfbebSnyanmisaka     return ret;
334*437bfbebSnyanmisaka }
335*437bfbebSnyanmisaka 
vdpu2_mpg4d_gen_regs(void * hal,HalTaskInfo * syn)336*437bfbebSnyanmisaka MPP_RET vdpu2_mpg4d_gen_regs(void *hal,  HalTaskInfo *syn)
337*437bfbebSnyanmisaka {
338*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
339*437bfbebSnyanmisaka     hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal;
340*437bfbebSnyanmisaka     HalDecTask *task = &syn->dec;
341*437bfbebSnyanmisaka     MppBuffer buf_frm_curr = NULL;
342*437bfbebSnyanmisaka     MppBuffer buf_frm_ref0 = NULL;
343*437bfbebSnyanmisaka     MppBuffer buf_frm_ref1 = NULL;
344*437bfbebSnyanmisaka     MppBuffer buf_pkt = NULL;
345*437bfbebSnyanmisaka     M4vdVdpu2Regs_t *regs = ctx->regs;
346*437bfbebSnyanmisaka 
347*437bfbebSnyanmisaka     mpp_assert(task->valid);
348*437bfbebSnyanmisaka     mpp_assert(task->input >= 0);
349*437bfbebSnyanmisaka     mpp_assert(task->output >= 0);
350*437bfbebSnyanmisaka 
351*437bfbebSnyanmisaka     memset(regs, 0, sizeof(M4vdVdpu2Regs_t));
352*437bfbebSnyanmisaka 
353*437bfbebSnyanmisaka     /*
354*437bfbebSnyanmisaka      * basic register configuration setup here
355*437bfbebSnyanmisaka      */
356*437bfbebSnyanmisaka     regs->reg54_endian.sw_dec_out_endian = 1;
357*437bfbebSnyanmisaka     regs->reg54_endian.sw_dec_in_endian = 1;
358*437bfbebSnyanmisaka     regs->reg54_endian.sw_dec_in_wordsp = 1;
359*437bfbebSnyanmisaka     regs->reg54_endian.sw_dec_out_wordsp = 1;
360*437bfbebSnyanmisaka     regs->reg54_endian.sw_dec_strswap32_e = 1;
361*437bfbebSnyanmisaka     regs->reg54_endian.sw_dec_strendian_e = 1;
362*437bfbebSnyanmisaka     regs->reg56_axi_ctrl.sw_dec_max_burlen = 16;
363*437bfbebSnyanmisaka     regs->reg52_error_concealment.sw_adv_pref_thrd = 1;
364*437bfbebSnyanmisaka     regs->reg57_enable_ctrl.sw_timeout_sts_en = 1;
365*437bfbebSnyanmisaka     regs->reg57_enable_ctrl.sw_dec_clkgate_en = 1;
366*437bfbebSnyanmisaka     regs->reg57_enable_ctrl.sw_dec_st_work = 1;
367*437bfbebSnyanmisaka     regs->reg59.sw_pflt_set0_tap0 = -1;
368*437bfbebSnyanmisaka     regs->reg59.sw_pflt_set0_tap1    = 3;
369*437bfbebSnyanmisaka     regs->reg59.sw_pflt_set0_tap2 = -6;
370*437bfbebSnyanmisaka     regs->reg153.sw_pred_bc_tap_0_3 = 20;
371*437bfbebSnyanmisaka 
372*437bfbebSnyanmisaka     /* setup buffer for input / output / reference */
373*437bfbebSnyanmisaka     mpp_buf_slot_get_prop(ctx->pkt_slots, task->input, SLOT_BUFFER, &buf_pkt);
374*437bfbebSnyanmisaka     mpp_assert(buf_pkt);
375*437bfbebSnyanmisaka     vpu_mpg4d_get_buffer_by_index(ctx, task->output, &buf_frm_curr);
376*437bfbebSnyanmisaka     vpu_mpg4d_get_buffer_by_index(ctx, task->refer[0], &buf_frm_ref0);
377*437bfbebSnyanmisaka     vpu_mpg4d_get_buffer_by_index(ctx, task->refer[1], &buf_frm_ref1);
378*437bfbebSnyanmisaka 
379*437bfbebSnyanmisaka     /* address registers setup first */
380*437bfbebSnyanmisaka     ctx->fd_curr = mpp_buffer_get_fd(buf_frm_curr);
381*437bfbebSnyanmisaka     ctx->fd_ref0 = (buf_frm_ref0) ? (mpp_buffer_get_fd(buf_frm_ref0)) : (-1);
382*437bfbebSnyanmisaka     ctx->fd_ref1 = (buf_frm_ref1) ? (mpp_buffer_get_fd(buf_frm_ref1)) : (-1);
383*437bfbebSnyanmisaka     regs->reg63_cur_pic_base = (RK_U32)ctx->fd_curr;
384*437bfbebSnyanmisaka     regs->reg64_input_stream_base = mpp_buffer_get_fd(buf_pkt);
385*437bfbebSnyanmisaka 
386*437bfbebSnyanmisaka     /* setup other registers, here will update packet address */
387*437bfbebSnyanmisaka     vdpu2_mpg4d_setup_regs_by_syntax(ctx, task->syntax);
388*437bfbebSnyanmisaka     /* memset tails to zero for stream buffer */
389*437bfbebSnyanmisaka     {
390*437bfbebSnyanmisaka         RK_U8 *ptr = (RK_U8 *)mpp_buffer_get_ptr(buf_pkt);
391*437bfbebSnyanmisaka         RK_U32 strm_len = MPP_ALIGN(ctx->bitstrm_len, 16) + 64;
392*437bfbebSnyanmisaka         memset(ptr + ctx->bitstrm_len, 0, strm_len - ctx->bitstrm_len);
393*437bfbebSnyanmisaka     }
394*437bfbebSnyanmisaka 
395*437bfbebSnyanmisaka     return ret;
396*437bfbebSnyanmisaka }
397*437bfbebSnyanmisaka 
vdpu2_mpg4d_start(void * hal,HalTaskInfo * task)398*437bfbebSnyanmisaka MPP_RET vdpu2_mpg4d_start(void *hal, HalTaskInfo *task)
399*437bfbebSnyanmisaka {
400*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
401*437bfbebSnyanmisaka     hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal;
402*437bfbebSnyanmisaka     RK_U32* regs = (RK_U32 *)ctx->regs;
403*437bfbebSnyanmisaka 
404*437bfbebSnyanmisaka     if (hal_mpg4d_debug & MPG4D_HAL_DBG_REG_PUT) {
405*437bfbebSnyanmisaka         RK_U32 reg_count = (sizeof(M4vdVdpu2Regs_t) / sizeof(RK_U32));
406*437bfbebSnyanmisaka         RK_U32 i = 0;
407*437bfbebSnyanmisaka 
408*437bfbebSnyanmisaka         for (i = 0; i < reg_count; i++) {
409*437bfbebSnyanmisaka             mpp_log("reg[%03d]: %08x\n", i, regs[i]);
410*437bfbebSnyanmisaka         }
411*437bfbebSnyanmisaka     }
412*437bfbebSnyanmisaka 
413*437bfbebSnyanmisaka     do {
414*437bfbebSnyanmisaka         MppDevRegWrCfg wr_cfg;
415*437bfbebSnyanmisaka         MppDevRegRdCfg rd_cfg;
416*437bfbebSnyanmisaka         RK_U32 reg_size = sizeof(M4vdVdpu2Regs_t);
417*437bfbebSnyanmisaka 
418*437bfbebSnyanmisaka         wr_cfg.reg = regs;
419*437bfbebSnyanmisaka         wr_cfg.size = reg_size;
420*437bfbebSnyanmisaka         wr_cfg.offset = 0;
421*437bfbebSnyanmisaka 
422*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
423*437bfbebSnyanmisaka         if (ret) {
424*437bfbebSnyanmisaka             mpp_err_f("set register write failed %d\n", ret);
425*437bfbebSnyanmisaka             break;
426*437bfbebSnyanmisaka         }
427*437bfbebSnyanmisaka 
428*437bfbebSnyanmisaka         rd_cfg.reg = regs;
429*437bfbebSnyanmisaka         rd_cfg.size = reg_size;
430*437bfbebSnyanmisaka         rd_cfg.offset = 0;
431*437bfbebSnyanmisaka 
432*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
433*437bfbebSnyanmisaka         if (ret) {
434*437bfbebSnyanmisaka             mpp_err_f("set register read failed %d\n", ret);
435*437bfbebSnyanmisaka             break;
436*437bfbebSnyanmisaka         }
437*437bfbebSnyanmisaka 
438*437bfbebSnyanmisaka         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
439*437bfbebSnyanmisaka         if (ret) {
440*437bfbebSnyanmisaka             mpp_err_f("send cmd failed %d\n", ret);
441*437bfbebSnyanmisaka             break;
442*437bfbebSnyanmisaka         }
443*437bfbebSnyanmisaka     } while (0);
444*437bfbebSnyanmisaka 
445*437bfbebSnyanmisaka     (void)task;
446*437bfbebSnyanmisaka     return ret;
447*437bfbebSnyanmisaka }
448*437bfbebSnyanmisaka 
vdpu2_mpg4d_wait(void * hal,HalTaskInfo * task)449*437bfbebSnyanmisaka MPP_RET vdpu2_mpg4d_wait(void *hal, HalTaskInfo *task)
450*437bfbebSnyanmisaka {
451*437bfbebSnyanmisaka     MPP_RET ret = MPP_OK;
452*437bfbebSnyanmisaka     hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal;
453*437bfbebSnyanmisaka     M4vdVdpu2Regs_t *regs = (M4vdVdpu2Regs_t *)ctx->regs;
454*437bfbebSnyanmisaka 
455*437bfbebSnyanmisaka     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
456*437bfbebSnyanmisaka     if (ret)
457*437bfbebSnyanmisaka         mpp_err_f("poll cmd failed %d\n", ret);
458*437bfbebSnyanmisaka 
459*437bfbebSnyanmisaka     if (hal_mpg4d_debug & MPG4D_HAL_DBG_REG_GET) {
460*437bfbebSnyanmisaka         RK_U32 reg_count = (sizeof(M4vdVdpu2Regs_t) / sizeof(RK_U32));
461*437bfbebSnyanmisaka         RK_U32 i = 0;
462*437bfbebSnyanmisaka 
463*437bfbebSnyanmisaka         for (i = 0; i < reg_count; i++) {
464*437bfbebSnyanmisaka             mpp_log("reg[%03d]: %08x\n", i, ((RK_U32 *)regs)[i]);
465*437bfbebSnyanmisaka         }
466*437bfbebSnyanmisaka     }
467*437bfbebSnyanmisaka 
468*437bfbebSnyanmisaka     if (ctx->dec_cb) {
469*437bfbebSnyanmisaka         DecCbHalDone param = { 0 };
470*437bfbebSnyanmisaka 
471*437bfbebSnyanmisaka         if (!regs->reg55_Interrupt.sw_dec_rdy_int)
472*437bfbebSnyanmisaka             param.hard_err = 1;
473*437bfbebSnyanmisaka 
474*437bfbebSnyanmisaka         param.task = (void *)&task->dec;
475*437bfbebSnyanmisaka         param.regs = (RK_U32 *)ctx->regs;
476*437bfbebSnyanmisaka 
477*437bfbebSnyanmisaka         mpp_callback(ctx->dec_cb, &param);
478*437bfbebSnyanmisaka     }
479*437bfbebSnyanmisaka 
480*437bfbebSnyanmisaka     (void)task;
481*437bfbebSnyanmisaka     return ret;
482*437bfbebSnyanmisaka }
483