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