1*437bfbebSnyanmisaka /*
2*437bfbebSnyanmisaka * Copyright 2015 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_h264e_vepu2_v2"
18*437bfbebSnyanmisaka
19*437bfbebSnyanmisaka #include <string.h>
20*437bfbebSnyanmisaka
21*437bfbebSnyanmisaka #include "mpp_env.h"
22*437bfbebSnyanmisaka #include "mpp_mem.h"
23*437bfbebSnyanmisaka #include "mpp_frame.h"
24*437bfbebSnyanmisaka #include "mpp_common.h"
25*437bfbebSnyanmisaka #include "mpp_device.h"
26*437bfbebSnyanmisaka #include "mpp_rc.h"
27*437bfbebSnyanmisaka #include "mpp_packet_impl.h"
28*437bfbebSnyanmisaka
29*437bfbebSnyanmisaka #include "mpp_enc_hal.h"
30*437bfbebSnyanmisaka #include "h264e_debug.h"
31*437bfbebSnyanmisaka #include "h264e_sps.h"
32*437bfbebSnyanmisaka #include "h264e_pps.h"
33*437bfbebSnyanmisaka #include "h264e_slice.h"
34*437bfbebSnyanmisaka
35*437bfbebSnyanmisaka #include "hal_h264e_debug.h"
36*437bfbebSnyanmisaka #include "hal_h264e_vpu_tbl.h"
37*437bfbebSnyanmisaka #include "hal_h264e_vepu_v2.h"
38*437bfbebSnyanmisaka #include "hal_h264e_stream_amend.h"
39*437bfbebSnyanmisaka
40*437bfbebSnyanmisaka #include "hal_h264e_vepu2_reg_tbl.h"
41*437bfbebSnyanmisaka
42*437bfbebSnyanmisaka typedef struct HalH264eVepu2Ctx_t {
43*437bfbebSnyanmisaka MppEncCfgSet *cfg;
44*437bfbebSnyanmisaka
45*437bfbebSnyanmisaka MppDev dev;
46*437bfbebSnyanmisaka RK_S32 frame_cnt;
47*437bfbebSnyanmisaka
48*437bfbebSnyanmisaka /* buffers management */
49*437bfbebSnyanmisaka HalH264eVepuBufs hw_bufs;
50*437bfbebSnyanmisaka
51*437bfbebSnyanmisaka /* preprocess config */
52*437bfbebSnyanmisaka HalH264eVepuPrep hw_prep;
53*437bfbebSnyanmisaka
54*437bfbebSnyanmisaka /* input / recon / refer address config */
55*437bfbebSnyanmisaka HalH264eVepuAddr hw_addr;
56*437bfbebSnyanmisaka VepuOffsetCfg hw_offset;
57*437bfbebSnyanmisaka
58*437bfbebSnyanmisaka /* macroblock ratecontrol config */
59*437bfbebSnyanmisaka HalH264eVepuMbRc hw_mbrc;
60*437bfbebSnyanmisaka
61*437bfbebSnyanmisaka /* syntax for input from enc_impl */
62*437bfbebSnyanmisaka RK_U32 updated;
63*437bfbebSnyanmisaka H264eSps *sps;
64*437bfbebSnyanmisaka H264ePps *pps;
65*437bfbebSnyanmisaka H264eSlice *slice;
66*437bfbebSnyanmisaka H264eFrmInfo *frms;
67*437bfbebSnyanmisaka H264eReorderInfo *reorder;
68*437bfbebSnyanmisaka H264eMarkingInfo *marking;
69*437bfbebSnyanmisaka H264ePrefixNal *prefix;
70*437bfbebSnyanmisaka
71*437bfbebSnyanmisaka /* special TSVC stream header fixup */
72*437bfbebSnyanmisaka HalH264eVepuStreamAmend amend;
73*437bfbebSnyanmisaka
74*437bfbebSnyanmisaka /* vepu2 macroblock ratecontrol context */
75*437bfbebSnyanmisaka HalH264eVepuMbRcCtx rc_ctx;
76*437bfbebSnyanmisaka
77*437bfbebSnyanmisaka H264eVpu2RegSet regs_set;
78*437bfbebSnyanmisaka H264eVpu2RegSet regs_get;
79*437bfbebSnyanmisaka } HalH264eVepu2Ctx;
80*437bfbebSnyanmisaka
hal_h264e_vepu2_deinit_v2(void * hal)81*437bfbebSnyanmisaka static MPP_RET hal_h264e_vepu2_deinit_v2(void *hal)
82*437bfbebSnyanmisaka {
83*437bfbebSnyanmisaka HalH264eVepu2Ctx *p = (HalH264eVepu2Ctx *)hal;
84*437bfbebSnyanmisaka
85*437bfbebSnyanmisaka hal_h264e_dbg_func("enter %p\n", p);
86*437bfbebSnyanmisaka
87*437bfbebSnyanmisaka if (p->dev) {
88*437bfbebSnyanmisaka mpp_dev_deinit(p->dev);
89*437bfbebSnyanmisaka p->dev = NULL;
90*437bfbebSnyanmisaka }
91*437bfbebSnyanmisaka
92*437bfbebSnyanmisaka h264e_vepu_buf_deinit(&p->hw_bufs);
93*437bfbebSnyanmisaka
94*437bfbebSnyanmisaka if (p->rc_ctx) {
95*437bfbebSnyanmisaka h264e_vepu_mbrc_deinit(p->rc_ctx);
96*437bfbebSnyanmisaka p->rc_ctx = NULL;
97*437bfbebSnyanmisaka }
98*437bfbebSnyanmisaka
99*437bfbebSnyanmisaka h264e_vepu_stream_amend_deinit(&p->amend);
100*437bfbebSnyanmisaka
101*437bfbebSnyanmisaka hal_h264e_dbg_func("leave %p\n", p);
102*437bfbebSnyanmisaka
103*437bfbebSnyanmisaka return MPP_OK;
104*437bfbebSnyanmisaka }
105*437bfbebSnyanmisaka
hal_h264e_vepu2_init_v2(void * hal,MppEncHalCfg * cfg)106*437bfbebSnyanmisaka static MPP_RET hal_h264e_vepu2_init_v2(void *hal, MppEncHalCfg *cfg)
107*437bfbebSnyanmisaka {
108*437bfbebSnyanmisaka HalH264eVepu2Ctx *p = (HalH264eVepu2Ctx *)hal;
109*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
110*437bfbebSnyanmisaka
111*437bfbebSnyanmisaka hal_h264e_dbg_func("enter %p\n", p);
112*437bfbebSnyanmisaka
113*437bfbebSnyanmisaka p->cfg = cfg->cfg;
114*437bfbebSnyanmisaka
115*437bfbebSnyanmisaka /* update output to MppEnc */
116*437bfbebSnyanmisaka cfg->type = VPU_CLIENT_VEPU2;
117*437bfbebSnyanmisaka
118*437bfbebSnyanmisaka ret = mpp_dev_init(&cfg->dev, cfg->type);
119*437bfbebSnyanmisaka if (ret) {
120*437bfbebSnyanmisaka mpp_err_f("mpp_dev_init failed ret: %d\n", ret);
121*437bfbebSnyanmisaka goto DONE;
122*437bfbebSnyanmisaka }
123*437bfbebSnyanmisaka p->dev = cfg->dev;
124*437bfbebSnyanmisaka
125*437bfbebSnyanmisaka ret = h264e_vepu_buf_init(&p->hw_bufs);
126*437bfbebSnyanmisaka if (ret) {
127*437bfbebSnyanmisaka mpp_err_f("init vepu buffer failed ret: %d\n", ret);
128*437bfbebSnyanmisaka goto DONE;
129*437bfbebSnyanmisaka }
130*437bfbebSnyanmisaka
131*437bfbebSnyanmisaka ret = h264e_vepu_mbrc_init(&p->rc_ctx, &p->hw_mbrc);
132*437bfbebSnyanmisaka if (ret) {
133*437bfbebSnyanmisaka mpp_err_f("init mb rate control failed ret: %d\n", ret);
134*437bfbebSnyanmisaka goto DONE;
135*437bfbebSnyanmisaka }
136*437bfbebSnyanmisaka
137*437bfbebSnyanmisaka /* create buffer to TSVC stream */
138*437bfbebSnyanmisaka h264e_vepu_stream_amend_init(&p->amend);
139*437bfbebSnyanmisaka
140*437bfbebSnyanmisaka DONE:
141*437bfbebSnyanmisaka if (ret)
142*437bfbebSnyanmisaka hal_h264e_vepu2_deinit_v2(hal);
143*437bfbebSnyanmisaka
144*437bfbebSnyanmisaka hal_h264e_dbg_func("leave %p\n", p);
145*437bfbebSnyanmisaka return ret;
146*437bfbebSnyanmisaka }
147*437bfbebSnyanmisaka
update_vepu2_syntax(HalH264eVepu2Ctx * ctx,MppSyntax * syntax)148*437bfbebSnyanmisaka static RK_U32 update_vepu2_syntax(HalH264eVepu2Ctx *ctx, MppSyntax *syntax)
149*437bfbebSnyanmisaka {
150*437bfbebSnyanmisaka H264eSyntaxDesc *desc = syntax->data;
151*437bfbebSnyanmisaka RK_S32 syn_num = syntax->number;
152*437bfbebSnyanmisaka RK_U32 updated = 0;
153*437bfbebSnyanmisaka RK_S32 i;
154*437bfbebSnyanmisaka
155*437bfbebSnyanmisaka for (i = 0; i < syn_num; i++, desc++) {
156*437bfbebSnyanmisaka switch (desc->type) {
157*437bfbebSnyanmisaka case H264E_SYN_CFG : {
158*437bfbebSnyanmisaka hal_h264e_dbg_detail("update cfg");
159*437bfbebSnyanmisaka ctx->cfg = desc->p;
160*437bfbebSnyanmisaka } break;
161*437bfbebSnyanmisaka case H264E_SYN_SPS : {
162*437bfbebSnyanmisaka hal_h264e_dbg_detail("update sps");
163*437bfbebSnyanmisaka ctx->sps = desc->p;
164*437bfbebSnyanmisaka } break;
165*437bfbebSnyanmisaka case H264E_SYN_PPS : {
166*437bfbebSnyanmisaka hal_h264e_dbg_detail("update pps");
167*437bfbebSnyanmisaka ctx->pps = desc->p;
168*437bfbebSnyanmisaka } break;
169*437bfbebSnyanmisaka case H264E_SYN_DPB : {
170*437bfbebSnyanmisaka hal_h264e_dbg_detail("update dpb");
171*437bfbebSnyanmisaka } break;
172*437bfbebSnyanmisaka case H264E_SYN_SLICE : {
173*437bfbebSnyanmisaka hal_h264e_dbg_detail("update slice");
174*437bfbebSnyanmisaka ctx->slice = desc->p;
175*437bfbebSnyanmisaka } break;
176*437bfbebSnyanmisaka case H264E_SYN_FRAME : {
177*437bfbebSnyanmisaka hal_h264e_dbg_detail("update frames");
178*437bfbebSnyanmisaka ctx->frms = desc->p;
179*437bfbebSnyanmisaka } break;
180*437bfbebSnyanmisaka case H264E_SYN_PREFIX : {
181*437bfbebSnyanmisaka hal_h264e_dbg_detail("update prefix nal");
182*437bfbebSnyanmisaka ctx->prefix = desc->p;
183*437bfbebSnyanmisaka } break;
184*437bfbebSnyanmisaka default : {
185*437bfbebSnyanmisaka mpp_log_f("invalid syntax type %d\n", desc->type);
186*437bfbebSnyanmisaka } break;
187*437bfbebSnyanmisaka }
188*437bfbebSnyanmisaka
189*437bfbebSnyanmisaka updated |= SYN_TYPE_FLAG(desc->type);
190*437bfbebSnyanmisaka }
191*437bfbebSnyanmisaka
192*437bfbebSnyanmisaka return updated;
193*437bfbebSnyanmisaka }
194*437bfbebSnyanmisaka
hal_h264e_vepu2_get_task_v2(void * hal,HalEncTask * task)195*437bfbebSnyanmisaka static MPP_RET hal_h264e_vepu2_get_task_v2(void *hal, HalEncTask *task)
196*437bfbebSnyanmisaka {
197*437bfbebSnyanmisaka HalH264eVepu2Ctx *ctx = (HalH264eVepu2Ctx *)hal;
198*437bfbebSnyanmisaka RK_U32 updated = update_vepu2_syntax(ctx, &task->syntax);
199*437bfbebSnyanmisaka MppEncPrepCfg *prep = &ctx->cfg->prep;
200*437bfbebSnyanmisaka HalH264eVepuPrep *hw_prep = &ctx->hw_prep;
201*437bfbebSnyanmisaka HalH264eVepuAddr *hw_addr = &ctx->hw_addr;
202*437bfbebSnyanmisaka HalH264eVepuBufs *hw_bufs = &ctx->hw_bufs;
203*437bfbebSnyanmisaka VepuOffsetCfg *hw_offset = &ctx->hw_offset;
204*437bfbebSnyanmisaka H264eFrmInfo *frms = ctx->frms;
205*437bfbebSnyanmisaka
206*437bfbebSnyanmisaka hal_h264e_dbg_func("enter %p\n", hal);
207*437bfbebSnyanmisaka
208*437bfbebSnyanmisaka if (updated & SYN_TYPE_FLAG(H264E_SYN_CFG)) {
209*437bfbebSnyanmisaka h264e_vepu_buf_set_frame_size(hw_bufs, prep->width, prep->height);
210*437bfbebSnyanmisaka
211*437bfbebSnyanmisaka /* preprocess setup */
212*437bfbebSnyanmisaka if (h264e_vepu_prep_setup(hw_prep, prep))
213*437bfbebSnyanmisaka return MPP_NOK;
214*437bfbebSnyanmisaka
215*437bfbebSnyanmisaka h264e_vepu_mbrc_setup(ctx->rc_ctx, ctx->cfg);
216*437bfbebSnyanmisaka }
217*437bfbebSnyanmisaka
218*437bfbebSnyanmisaka if (updated & SYN_TYPE_FLAG(H264E_SYN_SLICE)) {
219*437bfbebSnyanmisaka H264eSlice *slice = ctx->slice;
220*437bfbebSnyanmisaka
221*437bfbebSnyanmisaka h264e_vepu_buf_set_cabac_idc(hw_bufs, slice->cabac_init_idc);
222*437bfbebSnyanmisaka }
223*437bfbebSnyanmisaka
224*437bfbebSnyanmisaka h264e_vepu_prep_get_addr(hw_prep, task->input, &hw_addr->orig);
225*437bfbebSnyanmisaka
226*437bfbebSnyanmisaka MppBuffer recn = h264e_vepu_buf_get_frame_buffer(hw_bufs, frms->curr_idx);
227*437bfbebSnyanmisaka MppBuffer refr = h264e_vepu_buf_get_frame_buffer(hw_bufs, frms->refr_idx);
228*437bfbebSnyanmisaka
229*437bfbebSnyanmisaka hw_addr->recn[0] = mpp_buffer_get_fd(recn);
230*437bfbebSnyanmisaka hw_addr->refr[0] = mpp_buffer_get_fd(refr);
231*437bfbebSnyanmisaka hw_addr->recn[1] = hw_addr->recn[0];
232*437bfbebSnyanmisaka hw_addr->refr[1] = hw_addr->refr[0];
233*437bfbebSnyanmisaka
234*437bfbebSnyanmisaka hw_offset->fmt = prep->format;
235*437bfbebSnyanmisaka hw_offset->width = prep->width;
236*437bfbebSnyanmisaka hw_offset->height = prep->height;
237*437bfbebSnyanmisaka hw_offset->hor_stride = prep->hor_stride;
238*437bfbebSnyanmisaka hw_offset->ver_stride = prep->ver_stride;
239*437bfbebSnyanmisaka hw_offset->offset_x = mpp_frame_get_offset_x(task->frame);
240*437bfbebSnyanmisaka hw_offset->offset_y = mpp_frame_get_offset_y(task->frame);
241*437bfbebSnyanmisaka
242*437bfbebSnyanmisaka get_vepu_offset_cfg(hw_offset);
243*437bfbebSnyanmisaka
244*437bfbebSnyanmisaka h264e_vepu_stream_amend_config(&ctx->amend, task->packet, ctx->cfg,
245*437bfbebSnyanmisaka ctx->slice, ctx->prefix);
246*437bfbebSnyanmisaka
247*437bfbebSnyanmisaka hal_h264e_dbg_func("leave %p\n", hal);
248*437bfbebSnyanmisaka
249*437bfbebSnyanmisaka return MPP_OK;
250*437bfbebSnyanmisaka }
251*437bfbebSnyanmisaka
setup_output_packet(HalH264eVepu2Ctx * ctx,RK_U32 * reg,MppBuffer buf,RK_U32 offset)252*437bfbebSnyanmisaka static RK_S32 setup_output_packet(HalH264eVepu2Ctx *ctx, RK_U32 *reg, MppBuffer buf, RK_U32 offset)
253*437bfbebSnyanmisaka {
254*437bfbebSnyanmisaka RK_U32 offset8 = offset & (~0x7);
255*437bfbebSnyanmisaka RK_S32 fd = mpp_buffer_get_fd(buf);
256*437bfbebSnyanmisaka RK_U32 hdr_rem_msb = 0;
257*437bfbebSnyanmisaka RK_U32 hdr_rem_lsb = 0;
258*437bfbebSnyanmisaka RK_U32 limit = 0;
259*437bfbebSnyanmisaka
260*437bfbebSnyanmisaka if (offset) {
261*437bfbebSnyanmisaka RK_U8 *buf32 = (RK_U8 *)mpp_buffer_get_ptr(buf) + offset8;
262*437bfbebSnyanmisaka
263*437bfbebSnyanmisaka hdr_rem_msb = MPP_RB32(buf32);
264*437bfbebSnyanmisaka hdr_rem_lsb = MPP_RB32(buf32 + 4);
265*437bfbebSnyanmisaka }
266*437bfbebSnyanmisaka
267*437bfbebSnyanmisaka hal_h264e_dbg_detail("offset %d offset8 %d\n", offset, offset8);
268*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_OUTPUT_STREAM, fd);
269*437bfbebSnyanmisaka mpp_dev_set_reg_offset(ctx->dev, VEPU_REG_ADDR_OUTPUT_STREAM >> 2, offset8);
270*437bfbebSnyanmisaka
271*437bfbebSnyanmisaka /* output buffer size is 64 bit address then 8 multiple size */
272*437bfbebSnyanmisaka limit = mpp_buffer_get_size(buf);
273*437bfbebSnyanmisaka limit -= offset8;
274*437bfbebSnyanmisaka limit >>= 3;
275*437bfbebSnyanmisaka limit &= ~7;
276*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_STR_BUF_LIMIT, limit);
277*437bfbebSnyanmisaka
278*437bfbebSnyanmisaka hal_h264e_dbg_detail("msb %08x lsb %08x", hdr_rem_msb, hdr_rem_lsb);
279*437bfbebSnyanmisaka
280*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_STR_HDR_REM_MSB, hdr_rem_msb);
281*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_STR_HDR_REM_LSB, hdr_rem_lsb);
282*437bfbebSnyanmisaka
283*437bfbebSnyanmisaka return (offset - offset8) * 8;
284*437bfbebSnyanmisaka }
285*437bfbebSnyanmisaka
setup_intra_refresh(HalH264eVepu2Ctx * ctx,EncFrmStatus * frm)286*437bfbebSnyanmisaka static MPP_RET setup_intra_refresh(HalH264eVepu2Ctx *ctx, EncFrmStatus *frm)
287*437bfbebSnyanmisaka {
288*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
289*437bfbebSnyanmisaka RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
290*437bfbebSnyanmisaka RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
291*437bfbebSnyanmisaka RK_U32 refresh_num = ctx->cfg->rc.refresh_num;
292*437bfbebSnyanmisaka MppEncCfgSet *cfg = ctx->cfg;
293*437bfbebSnyanmisaka RK_U32 *reg = ctx->regs_set.val;
294*437bfbebSnyanmisaka RK_U32 val = 0;
295*437bfbebSnyanmisaka RK_S32 top = 0;
296*437bfbebSnyanmisaka RK_S32 left = 0;
297*437bfbebSnyanmisaka RK_S32 right = 0;
298*437bfbebSnyanmisaka RK_S32 bottom = 0;
299*437bfbebSnyanmisaka RK_U32 refresh_idx = frm->seq_idx % cfg->rc.gop;
300*437bfbebSnyanmisaka
301*437bfbebSnyanmisaka hal_h264e_dbg_func("enter\n");
302*437bfbebSnyanmisaka
303*437bfbebSnyanmisaka if (!ctx->cfg->rc.refresh_en || !frm->is_i_refresh) {
304*437bfbebSnyanmisaka goto RET;
305*437bfbebSnyanmisaka }
306*437bfbebSnyanmisaka
307*437bfbebSnyanmisaka if (ctx->cfg->rc.refresh_mode == MPP_ENC_RC_INTRA_REFRESH_ROW) {
308*437bfbebSnyanmisaka left = 0;
309*437bfbebSnyanmisaka right = mb_w;
310*437bfbebSnyanmisaka top = refresh_idx * refresh_num - 2;
311*437bfbebSnyanmisaka bottom = (refresh_idx + 1) * refresh_num - 1;
312*437bfbebSnyanmisaka top = mpp_clip(top, 0, mb_h);
313*437bfbebSnyanmisaka bottom = mpp_clip(bottom, 0, mb_h);
314*437bfbebSnyanmisaka } else if (ctx->cfg->rc.refresh_mode == MPP_ENC_RC_INTRA_REFRESH_COL) {
315*437bfbebSnyanmisaka top = 0;
316*437bfbebSnyanmisaka bottom = mb_h;
317*437bfbebSnyanmisaka left = refresh_idx * refresh_num - 2;
318*437bfbebSnyanmisaka right = (refresh_idx + 1) * refresh_num - 1;
319*437bfbebSnyanmisaka left = mpp_clip(left, 0, mb_w);
320*437bfbebSnyanmisaka right = mpp_clip(right, 0, mb_w);
321*437bfbebSnyanmisaka }
322*437bfbebSnyanmisaka
323*437bfbebSnyanmisaka RET:
324*437bfbebSnyanmisaka val = VEPU_REG_INTRA_AREA_TOP(top)
325*437bfbebSnyanmisaka | VEPU_REG_INTRA_AREA_BOTTOM(bottom)
326*437bfbebSnyanmisaka | VEPU_REG_INTRA_AREA_LEFT(left)
327*437bfbebSnyanmisaka | VEPU_REG_INTRA_AREA_RIGHT(right);
328*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_INTRA_AREA_CTRL, val);
329*437bfbebSnyanmisaka
330*437bfbebSnyanmisaka hal_h264e_dbg_func("leave, ret %d\n", ret);
331*437bfbebSnyanmisaka
332*437bfbebSnyanmisaka return ret;
333*437bfbebSnyanmisaka }
334*437bfbebSnyanmisaka
hal_h264e_vepu2_gen_regs_v2(void * hal,HalEncTask * task)335*437bfbebSnyanmisaka static MPP_RET hal_h264e_vepu2_gen_regs_v2(void *hal, HalEncTask *task)
336*437bfbebSnyanmisaka {
337*437bfbebSnyanmisaka //MPP_RET ret = MPP_OK;
338*437bfbebSnyanmisaka HalH264eVepu2Ctx *ctx = (HalH264eVepu2Ctx *)hal;
339*437bfbebSnyanmisaka HalH264eVepuBufs *hw_bufs = &ctx->hw_bufs;
340*437bfbebSnyanmisaka HalH264eVepuPrep *hw_prep = &ctx->hw_prep;
341*437bfbebSnyanmisaka HalH264eVepuAddr *hw_addr = &ctx->hw_addr;
342*437bfbebSnyanmisaka HalH264eVepuMbRc *hw_mbrc = &ctx->hw_mbrc;
343*437bfbebSnyanmisaka VepuOffsetCfg *hw_offset = &ctx->hw_offset;
344*437bfbebSnyanmisaka EncRcTaskInfo *rc_info = &task->rc_task->info;
345*437bfbebSnyanmisaka EncFrmStatus *frm = &task->rc_task->frm;
346*437bfbebSnyanmisaka H264eSps *sps = ctx->sps;
347*437bfbebSnyanmisaka H264ePps *pps = ctx->pps;
348*437bfbebSnyanmisaka H264eSlice *slice = ctx->slice;
349*437bfbebSnyanmisaka RK_U32 *reg = ctx->regs_set.val;
350*437bfbebSnyanmisaka RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
351*437bfbebSnyanmisaka RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
352*437bfbebSnyanmisaka RK_U32 offset = mpp_packet_get_length(task->packet);
353*437bfbebSnyanmisaka RK_U32 first_free_bit = 0;
354*437bfbebSnyanmisaka RK_U32 val = 0;
355*437bfbebSnyanmisaka RK_S32 i = 0;
356*437bfbebSnyanmisaka
357*437bfbebSnyanmisaka if (hw_prep->rotation) {
358*437bfbebSnyanmisaka mb_w = ctx->sps->pic_height_in_mbs;
359*437bfbebSnyanmisaka mb_h = ctx->sps->pic_width_in_mbs;
360*437bfbebSnyanmisaka }
361*437bfbebSnyanmisaka
362*437bfbebSnyanmisaka hw_mbrc->qp_init = rc_info->quality_target;
363*437bfbebSnyanmisaka hw_mbrc->qp_max = rc_info->quality_max;
364*437bfbebSnyanmisaka hw_mbrc->qp_min = rc_info->quality_min;
365*437bfbebSnyanmisaka
366*437bfbebSnyanmisaka hal_h264e_dbg_func("enter %p\n", hal);
367*437bfbebSnyanmisaka
368*437bfbebSnyanmisaka hal_h264e_dbg_detail("frame %d generate regs now", frm->seq_idx);
369*437bfbebSnyanmisaka
370*437bfbebSnyanmisaka // prepare mb rc config
371*437bfbebSnyanmisaka h264e_vepu_mbrc_prepare(ctx->rc_ctx, &ctx->hw_mbrc, task->rc_task);
372*437bfbebSnyanmisaka h264e_vepu_slice_split_cfg(ctx->slice, &ctx->hw_mbrc, task->rc_task, ctx->cfg);
373*437bfbebSnyanmisaka
374*437bfbebSnyanmisaka /* setup output address with offset */
375*437bfbebSnyanmisaka first_free_bit = setup_output_packet(ctx, reg, task->output, offset);
376*437bfbebSnyanmisaka
377*437bfbebSnyanmisaka /* set extra byte for header */
378*437bfbebSnyanmisaka hw_mbrc->hdr_strm_size = offset;
379*437bfbebSnyanmisaka hw_mbrc->hdr_free_size = first_free_bit / 8;
380*437bfbebSnyanmisaka hw_mbrc->out_strm_size = 0;
381*437bfbebSnyanmisaka
382*437bfbebSnyanmisaka /*
383*437bfbebSnyanmisaka * The hardware needs only the value for luma plane, because
384*437bfbebSnyanmisaka * values of other planes are calculated internally based on
385*437bfbebSnyanmisaka * format setting.
386*437bfbebSnyanmisaka */
387*437bfbebSnyanmisaka setup_intra_refresh(ctx, frm);
388*437bfbebSnyanmisaka
389*437bfbebSnyanmisaka val = VEPU_REG_AXI_CTRL_READ_ID(0);
390*437bfbebSnyanmisaka val |= VEPU_REG_AXI_CTRL_WRITE_ID(0);
391*437bfbebSnyanmisaka val |= VEPU_REG_AXI_CTRL_BURST_LEN(16);
392*437bfbebSnyanmisaka val |= VEPU_REG_AXI_CTRL_INCREMENT_MODE(0);
393*437bfbebSnyanmisaka val |= VEPU_REG_AXI_CTRL_BIRST_DISCARD(0);
394*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_AXI_CTRL, val);
395*437bfbebSnyanmisaka
396*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_QP_ADJUST_MAD_DELTA_ROI,
397*437bfbebSnyanmisaka hw_mbrc->mad_qp_change);
398*437bfbebSnyanmisaka
399*437bfbebSnyanmisaka val = 0;
400*437bfbebSnyanmisaka if (mb_w * mb_h > 3600)
401*437bfbebSnyanmisaka val = VEPU_REG_DISABLE_QUARTER_PIXEL_MV;
402*437bfbebSnyanmisaka val |= VEPU_REG_CABAC_INIT_IDC(slice->cabac_init_idc);
403*437bfbebSnyanmisaka if (pps->entropy_coding_mode)
404*437bfbebSnyanmisaka val |= VEPU_REG_ENTROPY_CODING_MODE;
405*437bfbebSnyanmisaka if (pps->transform_8x8_mode)
406*437bfbebSnyanmisaka val |= VEPU_REG_H264_TRANS8X8_MODE;
407*437bfbebSnyanmisaka if (sps->profile_idc > 31)
408*437bfbebSnyanmisaka val |= VEPU_REG_H264_INTER4X4_MODE;
409*437bfbebSnyanmisaka /*reg |= VEPU_REG_H264_STREAM_MODE;*/
410*437bfbebSnyanmisaka val |= VEPU_REG_H264_SLICE_SIZE(hw_mbrc->slice_size_mb_rows);
411*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL0, val);
412*437bfbebSnyanmisaka
413*437bfbebSnyanmisaka RK_U32 scaler = MPP_MAX(1, 200 / (mb_w + mb_h));
414*437bfbebSnyanmisaka
415*437bfbebSnyanmisaka RK_U32 skip_penalty = MPP_MIN(255, h264_skip_sad_penalty[hw_mbrc->qp_init] * scaler);
416*437bfbebSnyanmisaka
417*437bfbebSnyanmisaka RK_U32 overfill_r = (hw_prep->src_w & 0x0f) ?
418*437bfbebSnyanmisaka ((16 - (hw_prep->src_w & 0x0f)) / 4) : 0;
419*437bfbebSnyanmisaka
420*437bfbebSnyanmisaka RK_U32 overfill_b = (hw_prep->src_h & 0x0f) ?
421*437bfbebSnyanmisaka (16 - (hw_prep->src_h & 0x0f)) : 0;
422*437bfbebSnyanmisaka
423*437bfbebSnyanmisaka val = VEPU_REG_STREAM_START_OFFSET(first_free_bit) |
424*437bfbebSnyanmisaka VEPU_REG_SKIP_MACROBLOCK_PENALTY(skip_penalty) |
425*437bfbebSnyanmisaka VEPU_REG_IN_IMG_CTRL_OVRFLR_D4(overfill_r) |
426*437bfbebSnyanmisaka VEPU_REG_IN_IMG_CTRL_OVRFLB(overfill_b);
427*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ENC_OVER_FILL_STRM_OFFSET, val);
428*437bfbebSnyanmisaka
429*437bfbebSnyanmisaka // When offset is zero row length should be total 16 aligned width
430*437bfbebSnyanmisaka val = VEPU_REG_IN_IMG_CHROMA_OFFSET(0)
431*437bfbebSnyanmisaka | VEPU_REG_IN_IMG_LUMA_OFFSET(0)
432*437bfbebSnyanmisaka | VEPU_REG_IN_IMG_CTRL_ROW_LEN(hw_prep->pixel_stride);
433*437bfbebSnyanmisaka
434*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_INPUT_LUMA_INFO, val);
435*437bfbebSnyanmisaka
436*437bfbebSnyanmisaka val = VEPU_REG_CHECKPOINT_CHECK1(hw_mbrc->cp_target[0])
437*437bfbebSnyanmisaka | VEPU_REG_CHECKPOINT_CHECK0(hw_mbrc->cp_target[1]);
438*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(0), val);
439*437bfbebSnyanmisaka
440*437bfbebSnyanmisaka val = VEPU_REG_CHECKPOINT_CHECK1(hw_mbrc->cp_target[2])
441*437bfbebSnyanmisaka | VEPU_REG_CHECKPOINT_CHECK0(hw_mbrc->cp_target[3]);
442*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(1), val);
443*437bfbebSnyanmisaka
444*437bfbebSnyanmisaka val = VEPU_REG_CHECKPOINT_CHECK1(hw_mbrc->cp_target[4])
445*437bfbebSnyanmisaka | VEPU_REG_CHECKPOINT_CHECK0(hw_mbrc->cp_target[5]);
446*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(2), val);
447*437bfbebSnyanmisaka
448*437bfbebSnyanmisaka val = VEPU_REG_CHECKPOINT_CHECK1(hw_mbrc->cp_target[6])
449*437bfbebSnyanmisaka | VEPU_REG_CHECKPOINT_CHECK0(hw_mbrc->cp_target[7]);
450*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(3), val);
451*437bfbebSnyanmisaka
452*437bfbebSnyanmisaka val = VEPU_REG_CHECKPOINT_CHECK1(hw_mbrc->cp_target[8])
453*437bfbebSnyanmisaka | VEPU_REG_CHECKPOINT_CHECK0(hw_mbrc->cp_target[9]);
454*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_CHECKPOINT(4), val);
455*437bfbebSnyanmisaka
456*437bfbebSnyanmisaka val = VEPU_REG_CHKPT_WORD_ERR_CHK1(hw_mbrc->cp_error[0])
457*437bfbebSnyanmisaka | VEPU_REG_CHKPT_WORD_ERR_CHK0(hw_mbrc->cp_error[1]);
458*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(0), val);
459*437bfbebSnyanmisaka
460*437bfbebSnyanmisaka val = VEPU_REG_CHKPT_WORD_ERR_CHK1(hw_mbrc->cp_error[2])
461*437bfbebSnyanmisaka | VEPU_REG_CHKPT_WORD_ERR_CHK0(hw_mbrc->cp_error[3]);
462*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(1), val);
463*437bfbebSnyanmisaka
464*437bfbebSnyanmisaka val = VEPU_REG_CHKPT_WORD_ERR_CHK1(hw_mbrc->cp_error[4])
465*437bfbebSnyanmisaka | VEPU_REG_CHKPT_WORD_ERR_CHK0(hw_mbrc->cp_error[5]);
466*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_WORD_ERR(2), val);
467*437bfbebSnyanmisaka
468*437bfbebSnyanmisaka val = VEPU_REG_CHKPT_DELTA_QP_CHK6(hw_mbrc->cp_delta_qp[6])
469*437bfbebSnyanmisaka | VEPU_REG_CHKPT_DELTA_QP_CHK5(hw_mbrc->cp_delta_qp[5])
470*437bfbebSnyanmisaka | VEPU_REG_CHKPT_DELTA_QP_CHK4(hw_mbrc->cp_delta_qp[4])
471*437bfbebSnyanmisaka | VEPU_REG_CHKPT_DELTA_QP_CHK3(hw_mbrc->cp_delta_qp[3])
472*437bfbebSnyanmisaka | VEPU_REG_CHKPT_DELTA_QP_CHK2(hw_mbrc->cp_delta_qp[2])
473*437bfbebSnyanmisaka | VEPU_REG_CHKPT_DELTA_QP_CHK1(hw_mbrc->cp_delta_qp[1])
474*437bfbebSnyanmisaka | VEPU_REG_CHKPT_DELTA_QP_CHK0(hw_mbrc->cp_delta_qp[0]);
475*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_CHKPT_DELTA_QP, val);
476*437bfbebSnyanmisaka
477*437bfbebSnyanmisaka val = VEPU_REG_MAD_THRESHOLD(hw_mbrc->mad_threshold)
478*437bfbebSnyanmisaka | VEPU_REG_IN_IMG_CTRL_FMT(hw_prep->src_fmt)
479*437bfbebSnyanmisaka | VEPU_REG_IN_IMG_ROTATE_MODE(hw_prep->rotation)
480*437bfbebSnyanmisaka | VEPU_REG_SIZE_TABLE_PRESENT; //FIXED
481*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL1, val);
482*437bfbebSnyanmisaka
483*437bfbebSnyanmisaka val = VEPU_REG_INTRA16X16_MODE(h264_intra16_favor[hw_mbrc->qp_init])
484*437bfbebSnyanmisaka | VEPU_REG_INTER_MODE(h264_inter_favor[hw_mbrc->qp_init]);
485*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_INTRA_INTER_MODE, val);
486*437bfbebSnyanmisaka
487*437bfbebSnyanmisaka val = VEPU_REG_PPS_INIT_QP(pps->pic_init_qp)
488*437bfbebSnyanmisaka | VEPU_REG_SLICE_FILTER_ALPHA(slice->slice_alpha_c0_offset_div2)
489*437bfbebSnyanmisaka | VEPU_REG_SLICE_FILTER_BETA(slice->slice_beta_offset_div2)
490*437bfbebSnyanmisaka | VEPU_REG_CHROMA_QP_OFFSET(pps->chroma_qp_index_offset)
491*437bfbebSnyanmisaka | VEPU_REG_IDR_PIC_ID(slice->idr_pic_id);
492*437bfbebSnyanmisaka
493*437bfbebSnyanmisaka if (slice->disable_deblocking_filter_idc)
494*437bfbebSnyanmisaka val |= VEPU_REG_FILTER_DISABLE;
495*437bfbebSnyanmisaka
496*437bfbebSnyanmisaka if (pps->constrained_intra_pred)
497*437bfbebSnyanmisaka val |= VEPU_REG_CONSTRAINED_INTRA_PREDICTION;
498*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL2, val);
499*437bfbebSnyanmisaka
500*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_NEXT_PIC, 0);
501*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_MV_OUT, 0);
502*437bfbebSnyanmisaka
503*437bfbebSnyanmisaka MppBuffer cabac_table = hw_bufs->cabac_table;
504*437bfbebSnyanmisaka RK_S32 cabac_table_fd = cabac_table ? mpp_buffer_get_fd(cabac_table) : 0;
505*437bfbebSnyanmisaka
506*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_CABAC_TBL, cabac_table_fd);
507*437bfbebSnyanmisaka
508*437bfbebSnyanmisaka val = VEPU_REG_ROI1_TOP_MB(mb_h)
509*437bfbebSnyanmisaka | VEPU_REG_ROI1_BOTTOM_MB(mb_h)
510*437bfbebSnyanmisaka | VEPU_REG_ROI1_LEFT_MB(mb_w)
511*437bfbebSnyanmisaka | VEPU_REG_ROI1_RIGHT_MB(mb_w);
512*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ROI1, val);
513*437bfbebSnyanmisaka
514*437bfbebSnyanmisaka val = VEPU_REG_ROI2_TOP_MB(mb_h)
515*437bfbebSnyanmisaka | VEPU_REG_ROI2_BOTTOM_MB(mb_h)
516*437bfbebSnyanmisaka | VEPU_REG_ROI2_LEFT_MB(mb_w)
517*437bfbebSnyanmisaka | VEPU_REG_ROI2_RIGHT_MB(mb_w);
518*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ROI2, val);
519*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_STABLILIZATION_OUTPUT, 0);
520*437bfbebSnyanmisaka
521*437bfbebSnyanmisaka val = VEPU_REG_RGB2YUV_CONVERSION_COEFB(hw_prep->color_conversion_coeff_b)
522*437bfbebSnyanmisaka | VEPU_REG_RGB2YUV_CONVERSION_COEFA(hw_prep->color_conversion_coeff_a);
523*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF1, val);
524*437bfbebSnyanmisaka
525*437bfbebSnyanmisaka val = VEPU_REG_RGB2YUV_CONVERSION_COEFE(hw_prep->color_conversion_coeff_e)
526*437bfbebSnyanmisaka | VEPU_REG_RGB2YUV_CONVERSION_COEFC(hw_prep->color_conversion_coeff_c);
527*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF2, val);
528*437bfbebSnyanmisaka
529*437bfbebSnyanmisaka val = VEPU_REG_RGB2YUV_CONVERSION_COEFF(hw_prep->color_conversion_coeff_f);
530*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_RGB2YUV_CONVERSION_COEF3, val);
531*437bfbebSnyanmisaka
532*437bfbebSnyanmisaka val = VEPU_REG_RGB_MASK_B_MSB(hw_prep->b_mask_msb)
533*437bfbebSnyanmisaka | VEPU_REG_RGB_MASK_G_MSB(hw_prep->g_mask_msb)
534*437bfbebSnyanmisaka | VEPU_REG_RGB_MASK_R_MSB(hw_prep->r_mask_msb);
535*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_RGB_MASK_MSB, val); //FIXED
536*437bfbebSnyanmisaka
537*437bfbebSnyanmisaka {
538*437bfbebSnyanmisaka RK_U32 diff_mv_penalty[3] = {0};
539*437bfbebSnyanmisaka diff_mv_penalty[0] = h264_diff_mv_penalty4p[hw_mbrc->qp_init];
540*437bfbebSnyanmisaka diff_mv_penalty[1] = h264_diff_mv_penalty[hw_mbrc->qp_init];
541*437bfbebSnyanmisaka diff_mv_penalty[2] = h264_diff_mv_penalty[hw_mbrc->qp_init];
542*437bfbebSnyanmisaka
543*437bfbebSnyanmisaka val = VEPU_REG_1MV_PENALTY(diff_mv_penalty[1])
544*437bfbebSnyanmisaka | VEPU_REG_QMV_PENALTY(diff_mv_penalty[2])
545*437bfbebSnyanmisaka | VEPU_REG_4MV_PENALTY(diff_mv_penalty[0]);
546*437bfbebSnyanmisaka }
547*437bfbebSnyanmisaka
548*437bfbebSnyanmisaka val |= VEPU_REG_SPLIT_MV_MODE_EN;
549*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_MV_PENALTY, val);
550*437bfbebSnyanmisaka
551*437bfbebSnyanmisaka val = VEPU_REG_H264_LUMA_INIT_QP(hw_mbrc->qp_init)
552*437bfbebSnyanmisaka | VEPU_REG_H264_QP_MAX(hw_mbrc->qp_max)
553*437bfbebSnyanmisaka | VEPU_REG_H264_QP_MIN(hw_mbrc->qp_min)
554*437bfbebSnyanmisaka | VEPU_REG_H264_CHKPT_DISTANCE(hw_mbrc->cp_distance_mbs);
555*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_QP_VAL, val);
556*437bfbebSnyanmisaka
557*437bfbebSnyanmisaka val = VEPU_REG_ZERO_MV_FAVOR_D2(10);
558*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_MVC_RELATE, val);
559*437bfbebSnyanmisaka
560*437bfbebSnyanmisaka val = VEPU_REG_OUTPUT_SWAP32
561*437bfbebSnyanmisaka | VEPU_REG_OUTPUT_SWAP16
562*437bfbebSnyanmisaka | VEPU_REG_OUTPUT_SWAP8
563*437bfbebSnyanmisaka | VEPU_REG_INPUT_SWAP8_(hw_prep->swap_8_in)
564*437bfbebSnyanmisaka | VEPU_REG_INPUT_SWAP16_(hw_prep->swap_16_in)
565*437bfbebSnyanmisaka | VEPU_REG_INPUT_SWAP32_(hw_prep->swap_32_in);
566*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_DATA_ENDIAN, val);
567*437bfbebSnyanmisaka
568*437bfbebSnyanmisaka val = VEPU_REG_PPS_ID(pps->pps_id)
569*437bfbebSnyanmisaka | VEPU_REG_INTRA_PRED_MODE(h264_prev_mode_favor[hw_mbrc->qp_init])
570*437bfbebSnyanmisaka | VEPU_REG_FRAME_NUM(slice->frame_num);
571*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ENC_CTRL3, val);
572*437bfbebSnyanmisaka
573*437bfbebSnyanmisaka val = VEPU_REG_INTERRUPT_TIMEOUT_EN;
574*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_INTERRUPT, val);
575*437bfbebSnyanmisaka
576*437bfbebSnyanmisaka {
577*437bfbebSnyanmisaka RK_U8 dmv_penalty[128] = {0};
578*437bfbebSnyanmisaka RK_U8 dmv_qpel_penalty[128] = {0};
579*437bfbebSnyanmisaka
580*437bfbebSnyanmisaka for (i = 0; i < 128; i++) {
581*437bfbebSnyanmisaka dmv_penalty[i] = i;
582*437bfbebSnyanmisaka dmv_qpel_penalty[i] = MPP_MIN(255, exp_golomb_signed(i));
583*437bfbebSnyanmisaka }
584*437bfbebSnyanmisaka
585*437bfbebSnyanmisaka for (i = 0; i < 128; i += 4) {
586*437bfbebSnyanmisaka val = VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i], 3);
587*437bfbebSnyanmisaka val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 1], 2);
588*437bfbebSnyanmisaka val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 2], 1);
589*437bfbebSnyanmisaka val |= VEPU_REG_DMV_PENALTY_TABLE_BIT(dmv_penalty[i + 3], 0);
590*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_DMV_PENALTY_TBL(i / 4), val);
591*437bfbebSnyanmisaka
592*437bfbebSnyanmisaka val = VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT(
593*437bfbebSnyanmisaka dmv_qpel_penalty[i], 3);
594*437bfbebSnyanmisaka val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT(
595*437bfbebSnyanmisaka dmv_qpel_penalty[i + 1], 2);
596*437bfbebSnyanmisaka val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT(
597*437bfbebSnyanmisaka dmv_qpel_penalty[i + 2], 1);
598*437bfbebSnyanmisaka val |= VEPU_REG_DMV_Q_PIXEL_PENALTY_TABLE_BIT(
599*437bfbebSnyanmisaka dmv_qpel_penalty[i + 3], 0);
600*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_DMV_Q_PIXEL_PENALTY_TBL(i / 4), val);
601*437bfbebSnyanmisaka }
602*437bfbebSnyanmisaka }
603*437bfbebSnyanmisaka
604*437bfbebSnyanmisaka /* set buffers addr */
605*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_LUMA, hw_addr->orig[0]);
606*437bfbebSnyanmisaka if (hw_offset->offset_byte[0])
607*437bfbebSnyanmisaka mpp_dev_set_reg_offset(ctx->dev, VEPU_REG_ADDR_IN_LUMA >> 2,
608*437bfbebSnyanmisaka hw_offset->offset_byte[0]);
609*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_CB, hw_addr->orig[1]);
610*437bfbebSnyanmisaka if (hw_offset->offset_byte[1])
611*437bfbebSnyanmisaka mpp_dev_set_reg_offset(ctx->dev, VEPU_REG_ADDR_IN_CB >> 2,
612*437bfbebSnyanmisaka hw_offset->offset_byte[1]);
613*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_IN_CR, hw_addr->orig[2]);
614*437bfbebSnyanmisaka if (hw_offset->offset_byte[2])
615*437bfbebSnyanmisaka mpp_dev_set_reg_offset(ctx->dev, VEPU_REG_ADDR_IN_CR >> 2,
616*437bfbebSnyanmisaka hw_offset->offset_byte[2]);
617*437bfbebSnyanmisaka
618*437bfbebSnyanmisaka MppBuffer nal_size_table = h264e_vepu_buf_get_nal_size_table(hw_bufs);
619*437bfbebSnyanmisaka RK_S32 nal_size_table_fd = nal_size_table ? mpp_buffer_get_fd(nal_size_table) : 0;
620*437bfbebSnyanmisaka
621*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_OUTPUT_CTRL, nal_size_table_fd);
622*437bfbebSnyanmisaka
623*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REC_LUMA, hw_addr->recn[0]);
624*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REC_CHROMA, hw_addr->recn[1]);
625*437bfbebSnyanmisaka mpp_dev_set_reg_offset(ctx->dev, VEPU_REG_ADDR_REC_CHROMA >> 2, hw_bufs->yuv_size);
626*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REF_LUMA, hw_addr->refr[0]);
627*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ADDR_REF_CHROMA, hw_addr->refr[1]);
628*437bfbebSnyanmisaka mpp_dev_set_reg_offset(ctx->dev, VEPU_REG_ADDR_REF_CHROMA >> 2, hw_bufs->yuv_size);
629*437bfbebSnyanmisaka
630*437bfbebSnyanmisaka /* set important encode mode info */
631*437bfbebSnyanmisaka val = VEPU_REG_MB_HEIGHT(mb_h)
632*437bfbebSnyanmisaka | VEPU_REG_MB_WIDTH(mb_w)
633*437bfbebSnyanmisaka | VEPU_REG_PIC_TYPE(slice->idr_flag)
634*437bfbebSnyanmisaka | VEPU_REG_ENCODE_FORMAT(3)
635*437bfbebSnyanmisaka | VEPU_REG_ENCODE_ENABLE;
636*437bfbebSnyanmisaka H264E_HAL_SET_REG(reg, VEPU_REG_ENCODE_START, val);
637*437bfbebSnyanmisaka
638*437bfbebSnyanmisaka ctx->frame_cnt++;
639*437bfbebSnyanmisaka
640*437bfbebSnyanmisaka hal_h264e_dbg_func("leave %p\n", hal);
641*437bfbebSnyanmisaka return MPP_OK;
642*437bfbebSnyanmisaka }
643*437bfbebSnyanmisaka
hal_h264e_vepu2_start_v2(void * hal,HalEncTask * task)644*437bfbebSnyanmisaka static MPP_RET hal_h264e_vepu2_start_v2(void *hal, HalEncTask *task)
645*437bfbebSnyanmisaka {
646*437bfbebSnyanmisaka MPP_RET ret = MPP_OK;
647*437bfbebSnyanmisaka HalH264eVepu2Ctx *ctx = (HalH264eVepu2Ctx *)hal;
648*437bfbebSnyanmisaka (void)task;
649*437bfbebSnyanmisaka
650*437bfbebSnyanmisaka hal_h264e_dbg_func("enter %p\n", hal);
651*437bfbebSnyanmisaka
652*437bfbebSnyanmisaka if (ctx->dev) {
653*437bfbebSnyanmisaka MppDevRegWrCfg wr_cfg;
654*437bfbebSnyanmisaka MppDevRegRdCfg rd_cfg;
655*437bfbebSnyanmisaka RK_U32 reg_size = sizeof(ctx->regs_set);
656*437bfbebSnyanmisaka
657*437bfbebSnyanmisaka do {
658*437bfbebSnyanmisaka wr_cfg.reg = &ctx->regs_set;
659*437bfbebSnyanmisaka wr_cfg.size = reg_size;
660*437bfbebSnyanmisaka wr_cfg.offset = 0;
661*437bfbebSnyanmisaka
662*437bfbebSnyanmisaka ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
663*437bfbebSnyanmisaka if (ret) {
664*437bfbebSnyanmisaka mpp_err_f("set register write failed %d\n", ret);
665*437bfbebSnyanmisaka break;
666*437bfbebSnyanmisaka }
667*437bfbebSnyanmisaka
668*437bfbebSnyanmisaka rd_cfg.reg = &ctx->regs_get;
669*437bfbebSnyanmisaka rd_cfg.size = reg_size;
670*437bfbebSnyanmisaka rd_cfg.offset = 0;
671*437bfbebSnyanmisaka
672*437bfbebSnyanmisaka ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
673*437bfbebSnyanmisaka if (ret) {
674*437bfbebSnyanmisaka mpp_err_f("set register read failed %d\n", ret);
675*437bfbebSnyanmisaka break;
676*437bfbebSnyanmisaka }
677*437bfbebSnyanmisaka
678*437bfbebSnyanmisaka ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
679*437bfbebSnyanmisaka if (ret) {
680*437bfbebSnyanmisaka mpp_err_f("send cmd failed %d\n", ret);
681*437bfbebSnyanmisaka break;
682*437bfbebSnyanmisaka }
683*437bfbebSnyanmisaka } while (0);
684*437bfbebSnyanmisaka } else
685*437bfbebSnyanmisaka mpp_err("invalid NULL device ctx\n");
686*437bfbebSnyanmisaka
687*437bfbebSnyanmisaka hal_h264e_dbg_func("leave %p\n", hal);
688*437bfbebSnyanmisaka
689*437bfbebSnyanmisaka return ret;
690*437bfbebSnyanmisaka }
691*437bfbebSnyanmisaka
h264e_vepu2_get_mbrc(HalH264eVepuMbRc * mb_rc,H264eVpu2RegSet * reg)692*437bfbebSnyanmisaka static void h264e_vepu2_get_mbrc(HalH264eVepuMbRc *mb_rc, H264eVpu2RegSet *reg)
693*437bfbebSnyanmisaka {
694*437bfbebSnyanmisaka RK_S32 i = 0;
695*437bfbebSnyanmisaka RK_U32 cpt_prev = 0;
696*437bfbebSnyanmisaka RK_U32 overflow = 0;
697*437bfbebSnyanmisaka RK_U32 cpt_idx = VEPU_REG_CHECKPOINT(0) / 4;
698*437bfbebSnyanmisaka RK_U32 *reg_val = reg->val;
699*437bfbebSnyanmisaka
700*437bfbebSnyanmisaka mb_rc->hw_status = reg_val[VEPU_REG_INTERRUPT / 4];
701*437bfbebSnyanmisaka mb_rc->out_strm_size = reg_val[VEPU_REG_STR_BUF_LIMIT / 4] / 8 - mb_rc->hdr_free_size;
702*437bfbebSnyanmisaka mb_rc->qp_sum = ((reg_val[VEPU_REG_QP_SUM_DIV2 / 4] >> 11) & 0x001fffff) * 2;
703*437bfbebSnyanmisaka mb_rc->less_mad_count = (reg_val[VEPU_REG_MB_CTRL / 4] >> 16) & 0xffff;
704*437bfbebSnyanmisaka mb_rc->rlc_count = reg_val[VEPU_REG_RLC_SUM / 4] & 0x3fffff;
705*437bfbebSnyanmisaka
706*437bfbebSnyanmisaka for (i = 0; i < VEPU_CHECK_POINTS_MAX; i++) {
707*437bfbebSnyanmisaka RK_U32 cpt = VEPU_REG_CHECKPOINT_RESULT(reg_val[cpt_idx]);
708*437bfbebSnyanmisaka
709*437bfbebSnyanmisaka if (cpt < cpt_prev)
710*437bfbebSnyanmisaka overflow += (1 << 21);
711*437bfbebSnyanmisaka
712*437bfbebSnyanmisaka cpt_prev = cpt;
713*437bfbebSnyanmisaka mb_rc->cp_usage[i] = cpt + overflow;
714*437bfbebSnyanmisaka cpt_idx += (i & 1);
715*437bfbebSnyanmisaka }
716*437bfbebSnyanmisaka }
717*437bfbebSnyanmisaka
hal_h264e_vepu2_wait_v2(void * hal,HalEncTask * task)718*437bfbebSnyanmisaka static MPP_RET hal_h264e_vepu2_wait_v2(void *hal, HalEncTask *task)
719*437bfbebSnyanmisaka {
720*437bfbebSnyanmisaka HalH264eVepu2Ctx *ctx = (HalH264eVepu2Ctx *)hal;
721*437bfbebSnyanmisaka HalH264eVepuMbRc *hw_mbrc = &ctx->hw_mbrc;
722*437bfbebSnyanmisaka H264NaluType type = task->rc_task->frm.is_idr ? H264_NALU_TYPE_IDR : H264_NALU_TYPE_SLICE;
723*437bfbebSnyanmisaka MppPacket pkt = task->packet;
724*437bfbebSnyanmisaka RK_S32 offset = mpp_packet_get_length(pkt);
725*437bfbebSnyanmisaka MPP_RET ret = MPP_NOK;
726*437bfbebSnyanmisaka
727*437bfbebSnyanmisaka hal_h264e_dbg_func("enter %p\n", hal);
728*437bfbebSnyanmisaka
729*437bfbebSnyanmisaka if (ctx->dev) {
730*437bfbebSnyanmisaka ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
731*437bfbebSnyanmisaka if (ret)
732*437bfbebSnyanmisaka mpp_err_f("poll cmd failed %d\n", ret);
733*437bfbebSnyanmisaka } else {
734*437bfbebSnyanmisaka mpp_err("invalid NULL device ctx\n");
735*437bfbebSnyanmisaka return ret;
736*437bfbebSnyanmisaka }
737*437bfbebSnyanmisaka
738*437bfbebSnyanmisaka h264e_vepu2_get_mbrc(hw_mbrc, &ctx->regs_get);
739*437bfbebSnyanmisaka h264e_vepu_mbrc_update(ctx->rc_ctx, hw_mbrc);
740*437bfbebSnyanmisaka
741*437bfbebSnyanmisaka mpp_packet_add_segment_info(pkt, type, offset, hw_mbrc->out_strm_size);
742*437bfbebSnyanmisaka
743*437bfbebSnyanmisaka {
744*437bfbebSnyanmisaka HalH264eVepuStreamAmend *amend = &ctx->amend;
745*437bfbebSnyanmisaka
746*437bfbebSnyanmisaka if (amend->enable) {
747*437bfbebSnyanmisaka amend->old_length = hw_mbrc->out_strm_size;
748*437bfbebSnyanmisaka h264e_vepu_stream_amend_proc(amend, &ctx->cfg->h264.hw_cfg);
749*437bfbebSnyanmisaka ctx->hw_mbrc.out_strm_size = amend->new_length;
750*437bfbebSnyanmisaka } else if (amend->prefix) {
751*437bfbebSnyanmisaka /* check prefix value */
752*437bfbebSnyanmisaka amend->old_length = hw_mbrc->out_strm_size;
753*437bfbebSnyanmisaka h264e_vepu_stream_amend_sync_ref_idc(amend);
754*437bfbebSnyanmisaka }
755*437bfbebSnyanmisaka }
756*437bfbebSnyanmisaka
757*437bfbebSnyanmisaka task->hw_length += ctx->hw_mbrc.out_strm_size;
758*437bfbebSnyanmisaka
759*437bfbebSnyanmisaka hal_h264e_dbg_func("leave %p\n", hal);
760*437bfbebSnyanmisaka
761*437bfbebSnyanmisaka return MPP_OK;
762*437bfbebSnyanmisaka }
763*437bfbebSnyanmisaka
hal_h264e_vepu2_ret_task_v2(void * hal,HalEncTask * task)764*437bfbebSnyanmisaka static MPP_RET hal_h264e_vepu2_ret_task_v2(void *hal, HalEncTask *task)
765*437bfbebSnyanmisaka {
766*437bfbebSnyanmisaka HalH264eVepu2Ctx *ctx = (HalH264eVepu2Ctx *)hal;
767*437bfbebSnyanmisaka EncRcTaskInfo *rc_info = &task->rc_task->info;
768*437bfbebSnyanmisaka RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
769*437bfbebSnyanmisaka RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
770*437bfbebSnyanmisaka RK_U32 mbs = mb_w * mb_h;
771*437bfbebSnyanmisaka
772*437bfbebSnyanmisaka hal_h264e_dbg_func("enter %p\n", hal);
773*437bfbebSnyanmisaka
774*437bfbebSnyanmisaka task->length += task->hw_length;
775*437bfbebSnyanmisaka
776*437bfbebSnyanmisaka rc_info->bit_real = task->hw_length * 8;
777*437bfbebSnyanmisaka rc_info->quality_real = ctx->hw_mbrc.qp_sum / mbs;
778*437bfbebSnyanmisaka
779*437bfbebSnyanmisaka hal_h264e_dbg_rc("real bit %d quality %d\n", rc_info->bit_real, rc_info->quality_real);
780*437bfbebSnyanmisaka
781*437bfbebSnyanmisaka task->hal_ret.data = rc_info;
782*437bfbebSnyanmisaka task->hal_ret.number = 1;
783*437bfbebSnyanmisaka
784*437bfbebSnyanmisaka hal_h264e_dbg_func("leave %p\n", hal);
785*437bfbebSnyanmisaka
786*437bfbebSnyanmisaka return MPP_OK;
787*437bfbebSnyanmisaka }
788*437bfbebSnyanmisaka
789*437bfbebSnyanmisaka const MppEncHalApi hal_h264e_vepu2 = {
790*437bfbebSnyanmisaka .name = "hal_h264e_vepu2",
791*437bfbebSnyanmisaka .coding = MPP_VIDEO_CodingAVC,
792*437bfbebSnyanmisaka .ctx_size = sizeof(HalH264eVepu2Ctx),
793*437bfbebSnyanmisaka .flag = 0,
794*437bfbebSnyanmisaka .init = hal_h264e_vepu2_init_v2,
795*437bfbebSnyanmisaka .deinit = hal_h264e_vepu2_deinit_v2,
796*437bfbebSnyanmisaka .prepare = NULL,
797*437bfbebSnyanmisaka .get_task = hal_h264e_vepu2_get_task_v2,
798*437bfbebSnyanmisaka .gen_regs = hal_h264e_vepu2_gen_regs_v2,
799*437bfbebSnyanmisaka .start = hal_h264e_vepu2_start_v2,
800*437bfbebSnyanmisaka .wait = hal_h264e_vepu2_wait_v2,
801*437bfbebSnyanmisaka .part_start = NULL,
802*437bfbebSnyanmisaka .part_wait = NULL,
803*437bfbebSnyanmisaka .ret_task = hal_h264e_vepu2_ret_task_v2,
804*437bfbebSnyanmisaka };
805