1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka * Copyright 2017 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_vdpu1"
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_vdpu1.h"
32*437bfbebSnyanmisaka #include "hal_m4vd_vdpu1_reg.h"
33*437bfbebSnyanmisaka #include "mpp_dec_cb_param.h"
34*437bfbebSnyanmisaka
vdpu1_mpg4d_setup_regs_by_syntax(hal_mpg4_ctx * ctx,MppSyntax syntax)35*437bfbebSnyanmisaka static void vdpu1_mpg4d_setup_regs_by_syntax(hal_mpg4_ctx *ctx, MppSyntax syntax)
36*437bfbebSnyanmisaka {
37*437bfbebSnyanmisaka M4vdVdpu1Regs_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->SwReg04.sw_pic_mb_width = (pp->vop_width + 15) >> 4;
84*437bfbebSnyanmisaka regs->SwReg04.sw_pic_mb_hight_p = (pp->vop_height + 15) >> 4;
85*437bfbebSnyanmisaka
86*437bfbebSnyanmisaka if (pp->custorm_version == 4) {
87*437bfbebSnyanmisaka regs->SwReg04.sw_mb_width_off = pp->vop_width & 0xf;
88*437bfbebSnyanmisaka regs->SwReg04.sw_mb_height_off = pp->vop_height & 0xf;
89*437bfbebSnyanmisaka } else {
90*437bfbebSnyanmisaka regs->SwReg04.sw_mb_width_off = 0;
91*437bfbebSnyanmisaka regs->SwReg04.sw_mb_height_off = 0;
92*437bfbebSnyanmisaka }
93*437bfbebSnyanmisaka
94*437bfbebSnyanmisaka regs->SwReg03.sw_dec_mode = 1;
95*437bfbebSnyanmisaka
96*437bfbebSnyanmisaka /* note: When comparing bit 19 of reg136(that is sw_alt_scan_flag_e) with bit 6 of
97*437bfbebSnyanmisaka ** reg120(that is sw_alt_scan_e), we may be confused about the function of
98*437bfbebSnyanmisaka ** these two bits. According to C Model, just sw_alt_scan_flag_e is set,
99*437bfbebSnyanmisaka ** but not sw_alt_scan_e.
100*437bfbebSnyanmisaka */
101*437bfbebSnyanmisaka regs->SwReg18.sw_alt_scan_flag_e = pp->alternate_vertical_scan_flag;
102*437bfbebSnyanmisaka regs->SwReg48.sw_startmb_x = 0;
103*437bfbebSnyanmisaka regs->SwReg48.sw_startmb_y = 0;
104*437bfbebSnyanmisaka regs->SwReg03.sw_filtering_dis = 1;
105*437bfbebSnyanmisaka regs->SwReg18.sw_mpeg4_vc1_rc = pp->vop_rounding_type;
106*437bfbebSnyanmisaka regs->SwReg05.sw_intradc_vlc_thr = pp->intra_dc_vlc_thr;
107*437bfbebSnyanmisaka regs->SwReg06.sw_init_qp = pp->vop_quant;
108*437bfbebSnyanmisaka regs->SwReg05.sw_sync_markers_e = 1;
109*437bfbebSnyanmisaka
110*437bfbebSnyanmisaka {
111*437bfbebSnyanmisaka /*
112*437bfbebSnyanmisaka * update stream base address here according to consumed bit length
113*437bfbebSnyanmisaka * 1. hardware start address has to be 64 bit align
114*437bfbebSnyanmisaka * 2. hardware need to know which is the start bit in
115*437bfbebSnyanmisaka * 2. pass (10bit fd + (offset << 10)) register value to kernel
116*437bfbebSnyanmisaka */
117*437bfbebSnyanmisaka RK_U32 val = regs->SwReg12.sw_rlc_vlc_base;
118*437bfbebSnyanmisaka RK_U32 consumed_bytes = stream_used >> 3;
119*437bfbebSnyanmisaka RK_U32 consumed_bytes_align = consumed_bytes & (~0x7);
120*437bfbebSnyanmisaka RK_U32 start_bit_offset = stream_used & 0x3F;
121*437bfbebSnyanmisaka RK_U32 left_bytes = stream_length - consumed_bytes_align;
122*437bfbebSnyanmisaka
123*437bfbebSnyanmisaka regs->SwReg12.sw_rlc_vlc_base = val;
124*437bfbebSnyanmisaka if (consumed_bytes_align)
125*437bfbebSnyanmisaka mpp_dev_set_reg_offset(ctx->dev, 12, consumed_bytes_align);
126*437bfbebSnyanmisaka regs->SwReg05.sw_strm_start_bit = start_bit_offset;
127*437bfbebSnyanmisaka regs->SwReg06.sw_stream_len = left_bytes;
128*437bfbebSnyanmisaka }
129*437bfbebSnyanmisaka regs->SwReg05.sw_vop_time_incr = pp->vop_time_increment_resolution;
130*437bfbebSnyanmisaka
131*437bfbebSnyanmisaka switch (pp->vop_coding_type) {
132*437bfbebSnyanmisaka case MPEG4_B_VOP : {
133*437bfbebSnyanmisaka RK_U32 time_bp = pp->time_bp;
134*437bfbebSnyanmisaka RK_U32 time_pp = pp->time_pp;
135*437bfbebSnyanmisaka
136*437bfbebSnyanmisaka RK_U32 trb_per_trd_d0 = MPP_DIV((((RK_S64)(1 * time_bp + 0)) << 27) + 1 * (time_pp - 1), time_pp);
137*437bfbebSnyanmisaka RK_U32 trb_per_trd_d1 = MPP_DIV((((RK_S64)(2 * time_bp + 1)) << 27) + 2 * (time_pp - 0), 2 * time_pp + 1);
138*437bfbebSnyanmisaka RK_U32 trb_per_trd_dm1 = MPP_DIV((((RK_S64)(2 * time_bp - 1)) << 27) + 2 * (time_pp - 1), 2 * time_pp - 1);
139*437bfbebSnyanmisaka
140*437bfbebSnyanmisaka regs->SwReg03.sw_pic_b_e = 1;
141*437bfbebSnyanmisaka regs->SwReg03.sw_pic_inter_e = 1;
142*437bfbebSnyanmisaka regs->SwReg18.sw_mpeg4_vc1_rc = 0;
143*437bfbebSnyanmisaka regs->SwReg14.sw_refer0_base = 1;
144*437bfbebSnyanmisaka
145*437bfbebSnyanmisaka mpp_assert(ctx->fd_ref1 >= 0);
146*437bfbebSnyanmisaka if (ctx->fd_ref1 >= 0) {
147*437bfbebSnyanmisaka regs->SwReg14.sw_refer0_base = (RK_U32)ctx->fd_ref1;
148*437bfbebSnyanmisaka regs->SwReg15.sw_refer1_base = (RK_U32)ctx->fd_ref1;
149*437bfbebSnyanmisaka } else {
150*437bfbebSnyanmisaka regs->SwReg14.sw_refer0_base = (RK_U32)ctx->fd_curr;
151*437bfbebSnyanmisaka regs->SwReg15.sw_refer1_base = (RK_U32)ctx->fd_curr;
152*437bfbebSnyanmisaka }
153*437bfbebSnyanmisaka
154*437bfbebSnyanmisaka mpp_assert(ctx->fd_ref0 >= 0);
155*437bfbebSnyanmisaka if (ctx->fd_ref0 >= 0) {
156*437bfbebSnyanmisaka regs->SwReg16.sw_refer2_base = (RK_U32)ctx->fd_ref0;
157*437bfbebSnyanmisaka regs->SwReg17.sw_refer3_base = (RK_U32)ctx->fd_ref0;
158*437bfbebSnyanmisaka } else {
159*437bfbebSnyanmisaka regs->SwReg16.sw_refer2_base = (RK_U32)ctx->fd_curr;
160*437bfbebSnyanmisaka regs->SwReg17.sw_refer3_base = (RK_U32)ctx->fd_curr;
161*437bfbebSnyanmisaka }
162*437bfbebSnyanmisaka
163*437bfbebSnyanmisaka regs->SwReg18.sw_fcode_fwd_hor = pp->vop_fcode_forward;
164*437bfbebSnyanmisaka regs->SwReg18.sw_fcode_fwd_ver = pp->vop_fcode_forward;
165*437bfbebSnyanmisaka regs->SwReg18.sw_fcode_bwd_hor = pp->vop_fcode_backward;
166*437bfbebSnyanmisaka regs->SwReg18.sw_fcode_bwd_ver = pp->vop_fcode_backward;
167*437bfbebSnyanmisaka regs->SwReg03.sw_write_mvs_e = 0;
168*437bfbebSnyanmisaka regs->SwReg41.sw_dir_mv_base = mv_buf_fd;
169*437bfbebSnyanmisaka regs->SwReg19.sw_refer5_base = trb_per_trd_d0;
170*437bfbebSnyanmisaka regs->SwReg21.sw_refer7_base = trb_per_trd_d1;
171*437bfbebSnyanmisaka regs->SwReg20.sw_refer6_base = trb_per_trd_dm1;
172*437bfbebSnyanmisaka } break;
173*437bfbebSnyanmisaka case MPEG4_P_VOP : {
174*437bfbebSnyanmisaka regs->SwReg03.sw_pic_b_e = 0;
175*437bfbebSnyanmisaka regs->SwReg03.sw_pic_inter_e = 1;
176*437bfbebSnyanmisaka
177*437bfbebSnyanmisaka if (ctx->fd_ref0 >= 0) {
178*437bfbebSnyanmisaka regs->SwReg14.sw_refer0_base = (RK_U32)ctx->fd_ref0;
179*437bfbebSnyanmisaka regs->SwReg15.sw_refer1_base = (RK_U32)ctx->fd_ref0;
180*437bfbebSnyanmisaka } else {
181*437bfbebSnyanmisaka regs->SwReg14.sw_refer0_base = (RK_U32)ctx->fd_curr;
182*437bfbebSnyanmisaka regs->SwReg15.sw_refer1_base = (RK_U32)ctx->fd_curr;
183*437bfbebSnyanmisaka }
184*437bfbebSnyanmisaka regs->SwReg16.sw_refer2_base = (RK_U32)ctx->fd_curr;
185*437bfbebSnyanmisaka regs->SwReg17.sw_refer3_base = (RK_U32)ctx->fd_curr;
186*437bfbebSnyanmisaka
187*437bfbebSnyanmisaka regs->SwReg18.sw_fcode_fwd_hor = pp->vop_fcode_forward;
188*437bfbebSnyanmisaka regs->SwReg18.sw_fcode_fwd_ver = pp->vop_fcode_forward;
189*437bfbebSnyanmisaka regs->SwReg03.sw_write_mvs_e = 1;
190*437bfbebSnyanmisaka regs->SwReg41.sw_dir_mv_base = mv_buf_fd;
191*437bfbebSnyanmisaka } break;
192*437bfbebSnyanmisaka case MPEG4_I_VOP : {
193*437bfbebSnyanmisaka regs->SwReg03.sw_pic_b_e = 0;
194*437bfbebSnyanmisaka regs->SwReg03.sw_pic_inter_e = 0;
195*437bfbebSnyanmisaka
196*437bfbebSnyanmisaka regs->SwReg14.sw_refer0_base = (RK_U32)ctx->fd_curr;
197*437bfbebSnyanmisaka regs->SwReg15.sw_refer1_base = (RK_U32)ctx->fd_curr;
198*437bfbebSnyanmisaka regs->SwReg16.sw_refer2_base = (RK_U32)ctx->fd_curr;
199*437bfbebSnyanmisaka regs->SwReg17.sw_refer3_base = (RK_U32)ctx->fd_curr;
200*437bfbebSnyanmisaka
201*437bfbebSnyanmisaka regs->SwReg03.sw_write_mvs_e = 0;
202*437bfbebSnyanmisaka regs->SwReg41.sw_dir_mv_base = mv_buf_fd;
203*437bfbebSnyanmisaka
204*437bfbebSnyanmisaka regs->SwReg18.sw_fcode_fwd_hor = 1;
205*437bfbebSnyanmisaka regs->SwReg18.sw_fcode_fwd_ver = 1;
206*437bfbebSnyanmisaka } break;
207*437bfbebSnyanmisaka default : {
208*437bfbebSnyanmisaka /* no nothing */
209*437bfbebSnyanmisaka } break;
210*437bfbebSnyanmisaka }
211*437bfbebSnyanmisaka
212*437bfbebSnyanmisaka if (pp->interlaced) {
213*437bfbebSnyanmisaka regs->SwReg03.sw_pic_interlace_e = 1;
214*437bfbebSnyanmisaka regs->SwReg03.sw_pic_fieldmode_e = 0;
215*437bfbebSnyanmisaka regs->SwReg04.sw_topfieldfirst_e = pp->top_field_first;
216*437bfbebSnyanmisaka }
217*437bfbebSnyanmisaka
218*437bfbebSnyanmisaka regs->SwReg18.sw_prev_anc_type = pp->prev_coding_type;
219*437bfbebSnyanmisaka regs->SwReg05.sw_type1_quant_e = pp->quant_type;
220*437bfbebSnyanmisaka regs->SwReg40.sw_qtable_base = mpp_buffer_get_fd(ctx->qp_table);
221*437bfbebSnyanmisaka regs->SwReg18.sw_mv_accuracy_fwd = pp->quarter_sample;
222*437bfbebSnyanmisaka
223*437bfbebSnyanmisaka }
224*437bfbebSnyanmisaka
vdpu1_mpg4d_init(void * hal,MppHalCfg * cfg)225*437bfbebSnyanmisaka MPP_RET vdpu1_mpg4d_init(void *hal, MppHalCfg *cfg)
226*437bfbebSnyanmisaka {
227*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
228*437bfbebSnyanmisaka M4vdVdpu1Regs_t *regs = NULL;
229*437bfbebSnyanmisaka MppBufferGroup group = NULL;
230*437bfbebSnyanmisaka MppBuffer mv_buf = NULL;
231*437bfbebSnyanmisaka MppBuffer qp_table = NULL;
232*437bfbebSnyanmisaka hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal;
233*437bfbebSnyanmisaka
234*437bfbebSnyanmisaka mpp_assert(hal);
235*437bfbebSnyanmisaka
236*437bfbebSnyanmisaka ret = mpp_buffer_group_get_internal(&group, MPP_BUFFER_TYPE_ION);
237*437bfbebSnyanmisaka if (ret) {
238*437bfbebSnyanmisaka mpp_err_f("failed to get buffer group ret %d\n", ret);
239*437bfbebSnyanmisaka goto ERR_RET;
240*437bfbebSnyanmisaka }
241*437bfbebSnyanmisaka
242*437bfbebSnyanmisaka ret = mpp_buffer_get(group, &mv_buf, MPEG4_MAX_MV_BUF_SIZE);
243*437bfbebSnyanmisaka if (ret) {
244*437bfbebSnyanmisaka mpp_err_f("failed to get mv buffer ret %d\n", ret);
245*437bfbebSnyanmisaka goto ERR_RET;
246*437bfbebSnyanmisaka }
247*437bfbebSnyanmisaka
248*437bfbebSnyanmisaka ret = mpp_buffer_get(group, &qp_table, 64 * 2 * sizeof(RK_U8));
249*437bfbebSnyanmisaka if (ret) {
250*437bfbebSnyanmisaka mpp_err_f("failed to get qp talbe buffer ret %d\n", ret);
251*437bfbebSnyanmisaka goto ERR_RET;
252*437bfbebSnyanmisaka }
253*437bfbebSnyanmisaka
254*437bfbebSnyanmisaka regs = mpp_calloc(M4vdVdpu1Regs_t, 1);
255*437bfbebSnyanmisaka if (NULL == regs) {
256*437bfbebSnyanmisaka mpp_err_f("failed to malloc register ret\n");
257*437bfbebSnyanmisaka ret = MPP_ERR_MALLOC;
258*437bfbebSnyanmisaka goto ERR_RET;
259*437bfbebSnyanmisaka }
260*437bfbebSnyanmisaka
261*437bfbebSnyanmisaka ret = mpp_dev_init(&ctx->dev, VPU_CLIENT_VDPU1);
262*437bfbebSnyanmisaka if (ret) {
263*437bfbebSnyanmisaka mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
264*437bfbebSnyanmisaka goto ERR_RET;
265*437bfbebSnyanmisaka }
266*437bfbebSnyanmisaka
267*437bfbebSnyanmisaka ctx->frm_slots = cfg->frame_slots;
268*437bfbebSnyanmisaka ctx->pkt_slots = cfg->packet_slots;
269*437bfbebSnyanmisaka ctx->dec_cb = cfg->dec_cb;
270*437bfbebSnyanmisaka ctx->group = group;
271*437bfbebSnyanmisaka ctx->mv_buf = mv_buf;
272*437bfbebSnyanmisaka ctx->qp_table = qp_table;
273*437bfbebSnyanmisaka ctx->regs = regs;
274*437bfbebSnyanmisaka cfg->dev = ctx->dev;
275*437bfbebSnyanmisaka
276*437bfbebSnyanmisaka mpp_env_get_u32("hal_mpg4d_debug", &hal_mpg4d_debug, 0);
277*437bfbebSnyanmisaka
278*437bfbebSnyanmisaka return ret;
279*437bfbebSnyanmisaka ERR_RET:
280*437bfbebSnyanmisaka if (regs) {
281*437bfbebSnyanmisaka mpp_free(regs);
282*437bfbebSnyanmisaka regs = NULL;
283*437bfbebSnyanmisaka }
284*437bfbebSnyanmisaka
285*437bfbebSnyanmisaka if (qp_table) {
286*437bfbebSnyanmisaka mpp_buffer_put(qp_table);
287*437bfbebSnyanmisaka qp_table = NULL;
288*437bfbebSnyanmisaka }
289*437bfbebSnyanmisaka
290*437bfbebSnyanmisaka if (mv_buf) {
291*437bfbebSnyanmisaka mpp_buffer_put(mv_buf);
292*437bfbebSnyanmisaka mv_buf = NULL;
293*437bfbebSnyanmisaka }
294*437bfbebSnyanmisaka
295*437bfbebSnyanmisaka if (group) {
296*437bfbebSnyanmisaka mpp_buffer_group_put(group);
297*437bfbebSnyanmisaka group = NULL;
298*437bfbebSnyanmisaka }
299*437bfbebSnyanmisaka
300*437bfbebSnyanmisaka return ret;
301*437bfbebSnyanmisaka }
302*437bfbebSnyanmisaka
vdpu1_mpg4d_deinit(void * hal)303*437bfbebSnyanmisaka MPP_RET vdpu1_mpg4d_deinit(void *hal)
304*437bfbebSnyanmisaka {
305*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
306*437bfbebSnyanmisaka hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal;
307*437bfbebSnyanmisaka
308*437bfbebSnyanmisaka mpp_assert(hal);
309*437bfbebSnyanmisaka
310*437bfbebSnyanmisaka if (ctx->regs) {
311*437bfbebSnyanmisaka mpp_free(ctx->regs);
312*437bfbebSnyanmisaka ctx->regs = NULL;
313*437bfbebSnyanmisaka }
314*437bfbebSnyanmisaka
315*437bfbebSnyanmisaka if (ctx->qp_table) {
316*437bfbebSnyanmisaka mpp_buffer_put(ctx->qp_table);
317*437bfbebSnyanmisaka ctx->qp_table = NULL;
318*437bfbebSnyanmisaka }
319*437bfbebSnyanmisaka
320*437bfbebSnyanmisaka if (ctx->mv_buf) {
321*437bfbebSnyanmisaka mpp_buffer_put(ctx->mv_buf);
322*437bfbebSnyanmisaka ctx->mv_buf = NULL;
323*437bfbebSnyanmisaka }
324*437bfbebSnyanmisaka
325*437bfbebSnyanmisaka if (ctx->group) {
326*437bfbebSnyanmisaka mpp_buffer_group_put(ctx->group);
327*437bfbebSnyanmisaka ctx->group = NULL;
328*437bfbebSnyanmisaka }
329*437bfbebSnyanmisaka
330*437bfbebSnyanmisaka if (ctx->dev) {
331*437bfbebSnyanmisaka mpp_dev_deinit(ctx->dev);
332*437bfbebSnyanmisaka ctx->dev = NULL;
333*437bfbebSnyanmisaka }
334*437bfbebSnyanmisaka
335*437bfbebSnyanmisaka return ret;
336*437bfbebSnyanmisaka }
337*437bfbebSnyanmisaka
vdpu1_mpg4d_gen_regs(void * hal,HalTaskInfo * syn)338*437bfbebSnyanmisaka MPP_RET vdpu1_mpg4d_gen_regs(void *hal, HalTaskInfo *syn)
339*437bfbebSnyanmisaka {
340*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
341*437bfbebSnyanmisaka hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal;
342*437bfbebSnyanmisaka HalDecTask *task = &syn->dec;
343*437bfbebSnyanmisaka MppBuffer buf_frm_curr = NULL;
344*437bfbebSnyanmisaka MppBuffer buf_frm_ref0 = NULL;
345*437bfbebSnyanmisaka MppBuffer buf_frm_ref1 = NULL;
346*437bfbebSnyanmisaka MppBuffer buf_pkt = NULL;
347*437bfbebSnyanmisaka M4vdVdpu1Regs_t *regs = ctx->regs;
348*437bfbebSnyanmisaka
349*437bfbebSnyanmisaka mpp_assert(task->valid);
350*437bfbebSnyanmisaka mpp_assert(task->input >= 0);
351*437bfbebSnyanmisaka mpp_assert(task->output >= 0);
352*437bfbebSnyanmisaka
353*437bfbebSnyanmisaka memset(regs, 0, sizeof(M4vdVdpu1Regs_t));
354*437bfbebSnyanmisaka
355*437bfbebSnyanmisaka /*
356*437bfbebSnyanmisaka * basic register configuration setup here
357*437bfbebSnyanmisaka */
358*437bfbebSnyanmisaka regs->SwReg02.sw_dec_out_endian = 1;
359*437bfbebSnyanmisaka regs->SwReg02.sw_dec_in_endian = 1;
360*437bfbebSnyanmisaka regs->SwReg02.sw_dec_inswap32_e = 1;
361*437bfbebSnyanmisaka regs->SwReg02.sw_dec_outswap32_e = 1;
362*437bfbebSnyanmisaka regs->SwReg02.sw_dec_strswap32_e = 1;
363*437bfbebSnyanmisaka regs->SwReg02.sw_dec_strendian_e = 1;
364*437bfbebSnyanmisaka regs->SwReg02.sw_dec_max_burst = 16;
365*437bfbebSnyanmisaka regs->SwReg55.sw_apf_threshold = 1;
366*437bfbebSnyanmisaka regs->SwReg02.sw_dec_timeout_e = 1;
367*437bfbebSnyanmisaka regs->SwReg02.sw_dec_clk_gate_e = 1;
368*437bfbebSnyanmisaka regs->SwReg01.sw_dec_en = 1;
369*437bfbebSnyanmisaka regs->SwReg49.sw_pred_bc_tap_0_0 = -1;
370*437bfbebSnyanmisaka regs->SwReg49.sw_pred_bc_tap_0_1 = 3;
371*437bfbebSnyanmisaka regs->SwReg49.sw_pred_bc_tap_0_2 = -6;
372*437bfbebSnyanmisaka regs->SwReg34.sw_pred_bc_tap_0_3 = 20;
373*437bfbebSnyanmisaka
374*437bfbebSnyanmisaka /* setup buffer for input / output / reference */
375*437bfbebSnyanmisaka mpp_buf_slot_get_prop(ctx->pkt_slots, task->input, SLOT_BUFFER, &buf_pkt);
376*437bfbebSnyanmisaka mpp_assert(buf_pkt);
377*437bfbebSnyanmisaka vpu_mpg4d_get_buffer_by_index(ctx, task->output, &buf_frm_curr);
378*437bfbebSnyanmisaka vpu_mpg4d_get_buffer_by_index(ctx, task->refer[0], &buf_frm_ref0);
379*437bfbebSnyanmisaka vpu_mpg4d_get_buffer_by_index(ctx, task->refer[1], &buf_frm_ref1);
380*437bfbebSnyanmisaka
381*437bfbebSnyanmisaka /* address registers setup first */
382*437bfbebSnyanmisaka ctx->fd_curr = mpp_buffer_get_fd(buf_frm_curr);
383*437bfbebSnyanmisaka ctx->fd_ref0 = (buf_frm_ref0) ? (mpp_buffer_get_fd(buf_frm_ref0)) : (-1);
384*437bfbebSnyanmisaka ctx->fd_ref1 = (buf_frm_ref1) ? (mpp_buffer_get_fd(buf_frm_ref1)) : (-1);
385*437bfbebSnyanmisaka regs->SwReg13.dec_out_st_adr = (RK_U32)ctx->fd_curr;
386*437bfbebSnyanmisaka regs->SwReg12.sw_rlc_vlc_base = mpp_buffer_get_fd(buf_pkt);
387*437bfbebSnyanmisaka
388*437bfbebSnyanmisaka /* setup other registers, here will update packet address */
389*437bfbebSnyanmisaka vdpu1_mpg4d_setup_regs_by_syntax(ctx, task->syntax);
390*437bfbebSnyanmisaka /* memset tails to zero for stream buffer */
391*437bfbebSnyanmisaka {
392*437bfbebSnyanmisaka RK_U8 *ptr = (RK_U8 *)mpp_buffer_get_ptr(buf_pkt);
393*437bfbebSnyanmisaka RK_U32 strm_len = MPP_ALIGN(ctx->bitstrm_len, 16) + 64;
394*437bfbebSnyanmisaka memset(ptr + ctx->bitstrm_len, 0, strm_len - ctx->bitstrm_len);
395*437bfbebSnyanmisaka }
396*437bfbebSnyanmisaka
397*437bfbebSnyanmisaka return ret;
398*437bfbebSnyanmisaka }
399*437bfbebSnyanmisaka
vdpu1_mpg4d_start(void * hal,HalTaskInfo * task)400*437bfbebSnyanmisaka MPP_RET vdpu1_mpg4d_start(void *hal, HalTaskInfo *task)
401*437bfbebSnyanmisaka {
402*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
403*437bfbebSnyanmisaka hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal;
404*437bfbebSnyanmisaka RK_U32* regs = (RK_U32 *)ctx->regs;
405*437bfbebSnyanmisaka
406*437bfbebSnyanmisaka if (hal_mpg4d_debug & MPG4D_HAL_DBG_REG_PUT) {
407*437bfbebSnyanmisaka RK_U32 reg_count = (sizeof(M4vdVdpu1Regs_t) / sizeof(RK_U32));
408*437bfbebSnyanmisaka RK_U32 i = 0;
409*437bfbebSnyanmisaka
410*437bfbebSnyanmisaka for (i = 2; i < reg_count; i++) {
411*437bfbebSnyanmisaka mpp_log("reg[%03d]: %08x\n", i, regs[i]);
412*437bfbebSnyanmisaka }
413*437bfbebSnyanmisaka }
414*437bfbebSnyanmisaka
415*437bfbebSnyanmisaka do {
416*437bfbebSnyanmisaka MppDevRegWrCfg wr_cfg;
417*437bfbebSnyanmisaka MppDevRegRdCfg rd_cfg;
418*437bfbebSnyanmisaka RK_U32 reg_size = sizeof(M4vdVdpu1Regs_t);
419*437bfbebSnyanmisaka
420*437bfbebSnyanmisaka wr_cfg.reg = regs;
421*437bfbebSnyanmisaka wr_cfg.size = reg_size;
422*437bfbebSnyanmisaka wr_cfg.offset = 0;
423*437bfbebSnyanmisaka
424*437bfbebSnyanmisaka ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
425*437bfbebSnyanmisaka if (ret) {
426*437bfbebSnyanmisaka mpp_err_f("set register write failed %d\n", ret);
427*437bfbebSnyanmisaka break;
428*437bfbebSnyanmisaka }
429*437bfbebSnyanmisaka
430*437bfbebSnyanmisaka rd_cfg.reg = regs;
431*437bfbebSnyanmisaka rd_cfg.size = reg_size;
432*437bfbebSnyanmisaka rd_cfg.offset = 0;
433*437bfbebSnyanmisaka
434*437bfbebSnyanmisaka ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
435*437bfbebSnyanmisaka if (ret) {
436*437bfbebSnyanmisaka mpp_err_f("set register read failed %d\n", ret);
437*437bfbebSnyanmisaka break;
438*437bfbebSnyanmisaka }
439*437bfbebSnyanmisaka
440*437bfbebSnyanmisaka ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
441*437bfbebSnyanmisaka if (ret) {
442*437bfbebSnyanmisaka mpp_err_f("send cmd failed %d\n", ret);
443*437bfbebSnyanmisaka break;
444*437bfbebSnyanmisaka }
445*437bfbebSnyanmisaka } while (0);
446*437bfbebSnyanmisaka
447*437bfbebSnyanmisaka (void)task;
448*437bfbebSnyanmisaka return ret;
449*437bfbebSnyanmisaka }
450*437bfbebSnyanmisaka
vdpu1_mpg4d_wait(void * hal,HalTaskInfo * task)451*437bfbebSnyanmisaka MPP_RET vdpu1_mpg4d_wait(void *hal, HalTaskInfo *task)
452*437bfbebSnyanmisaka {
453*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
454*437bfbebSnyanmisaka hal_mpg4_ctx *ctx = (hal_mpg4_ctx *)hal;
455*437bfbebSnyanmisaka M4vdVdpu1Regs_t *regs = (M4vdVdpu1Regs_t *)ctx->regs;
456*437bfbebSnyanmisaka
457*437bfbebSnyanmisaka ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
458*437bfbebSnyanmisaka if (ret)
459*437bfbebSnyanmisaka mpp_err_f("poll cmd failed %d\n", ret);
460*437bfbebSnyanmisaka
461*437bfbebSnyanmisaka if (hal_mpg4d_debug & MPG4D_HAL_DBG_REG_GET) {
462*437bfbebSnyanmisaka RK_U32 reg_count = (sizeof(M4vdVdpu1Regs_t) / sizeof(RK_U32));
463*437bfbebSnyanmisaka RK_U32 i = 0;
464*437bfbebSnyanmisaka
465*437bfbebSnyanmisaka for (i = 0; i < reg_count; i++) {
466*437bfbebSnyanmisaka mpp_log("reg[%03d]: %08x\n", i, ((RK_U32 *)regs)[i]);
467*437bfbebSnyanmisaka }
468*437bfbebSnyanmisaka }
469*437bfbebSnyanmisaka if (ctx->dec_cb) {
470*437bfbebSnyanmisaka DecCbHalDone param;
471*437bfbebSnyanmisaka
472*437bfbebSnyanmisaka param.task = (void *)&task->dec;
473*437bfbebSnyanmisaka param.regs = (RK_U32 *)ctx->regs;
474*437bfbebSnyanmisaka param.hard_err = !regs->SwReg01.sw_dec_rdy_int;
475*437bfbebSnyanmisaka
476*437bfbebSnyanmisaka mpp_callback(ctx->dec_cb, ¶m);
477*437bfbebSnyanmisaka }
478*437bfbebSnyanmisaka
479*437bfbebSnyanmisaka memset(®s->SwReg01, 0, sizeof(RK_U32));
480*437bfbebSnyanmisaka
481*437bfbebSnyanmisaka (void)task;
482*437bfbebSnyanmisaka return ret;
483*437bfbebSnyanmisaka }
484