xref: /rockchip-linux_mpp/mpp/hal/rkenc/h264e/hal_h264e_vepu540c.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /*
2  * Copyright 2022 Rockchip Electronics Co. LTD
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define MODULE_TAG "hal_h264e_vepu540c"
18 
19 #include <string.h>
20 
21 #include "mpp_env.h"
22 #include "mpp_mem.h"
23 #include "mpp_common.h"
24 #include "mpp_frame_impl.h"
25 #include "mpp_rc.h"
26 #include "mpp_packet_impl.h"
27 
28 #include "h264e_sps.h"
29 #include "h264e_pps.h"
30 #include "h264e_slice.h"
31 
32 #include "hal_h264e_debug.h"
33 #include "hal_bufs.h"
34 #include "mpp_enc_hal.h"
35 #include "vepu5xx_common.h"
36 #include "vepu540c_common.h"
37 
38 #include "hal_h264e_vepu540c_reg.h"
39 #include "hal_h264e_stream_amend.h"
40 
41 #define DUMP_REG 0
42 #define MAX_CORE_NUM 2
43 
44 typedef struct vepu540c_h264e_reg_ctx_t {
45     void                    *reg;
46     RK_U32                  used;
47 } Vepu540cH264eRegCtx;
48 
49 typedef struct HalH264eVepu540cCtx_t {
50     MppEncCfgSet            *cfg;
51 
52     MppDev                  dev;
53     RK_S32                  frame_cnt;
54 
55     /* buffers management */
56     HalBufs                 hw_recn;
57     RK_S32                  pixel_buf_fbc_hdr_size;
58     RK_S32                  pixel_buf_fbc_bdy_size;
59     RK_S32                  pixel_buf_size;
60     RK_S32                  thumb_buf_size;
61     RK_S32                  max_buf_cnt;
62 
63     /* syntax for input from enc_impl */
64     RK_U32                  updated;
65     H264eSps                *sps;
66     H264ePps                *pps;
67     H264eSlice              *slice;
68     H264eFrmInfo            *frms;
69     H264eReorderInfo        *reorder;
70     H264eMarkingInfo        *marking;
71     H264ePrefixNal          *prefix;
72     HalH264eVepuStreamAmend  amend;
73 
74     /* syntax for output to enc_impl */
75     EncRcTaskInfo           hal_rc_cfg;
76 
77     /* roi */
78     void                    *roi_data;
79 
80     /* register */
81     HalVepu540cRegSet       *regs_set;
82 
83     /* external line buffer over 3K */
84     MppBufferGroup          ext_line_buf_grp;
85     RK_S32                  ext_line_buf_size;
86     MppBuffer               ext_line_buf;
87 } HalH264eVepu540cCtx;
88 
89 static RK_S32 h264_aq_tthd_default[16] = {
90     0,  0,  0,  0,
91     3,  3,  5,  5,
92     8,  8,  8,  15,
93     15, 20, 25, 25,
94 };
95 
96 static RK_S32 h264_P_aq_step_default[16] = {
97     -8, -7, -6, -5,
98     -4, -3, -2, -1,
99     0,  1,  2,  3,
100     4,  5,  7,  8,
101 };
102 
103 static RK_S32 h264_I_aq_step_default[16] = {
104     -8, -7, -6, -5,
105     -4, -3, -2, -1,
106     0,  1,  2,  3,
107     4,  5,  8,  8,
108 };
109 
hal_h264e_vepu540c_deinit(void * hal)110 static MPP_RET hal_h264e_vepu540c_deinit(void *hal)
111 {
112     HalH264eVepu540cCtx *p = (HalH264eVepu540cCtx *)hal;
113     hal_h264e_dbg_func("enter %p\n", p);
114 
115     h264e_vepu_stream_amend_deinit(&p->amend);
116 
117     if (p->dev) {
118         mpp_dev_deinit(p->dev);
119         p->dev = NULL;
120     }
121 
122     if (p->ext_line_buf) {
123         mpp_buffer_put(p->ext_line_buf);
124         p->ext_line_buf = NULL;
125     }
126 
127     if (p->ext_line_buf_grp) {
128         mpp_buffer_group_put(p->ext_line_buf_grp);
129         p->ext_line_buf_grp = NULL;
130     }
131 
132     if (p->hw_recn) {
133         hal_bufs_deinit(p->hw_recn);
134         p->hw_recn = NULL;
135     }
136 
137     MPP_FREE(p->regs_set);
138 
139 
140     hal_h264e_dbg_func("leave %p\n", p);
141 
142     return MPP_OK;
143 }
144 
hal_h264e_vepu540c_init(void * hal,MppEncHalCfg * cfg)145 static MPP_RET hal_h264e_vepu540c_init(void *hal, MppEncHalCfg *cfg)
146 {
147     HalH264eVepu540cCtx *p = (HalH264eVepu540cCtx *)hal;
148     MPP_RET ret = MPP_OK;
149     hal_h264e_dbg_func("enter %p\n", p);
150 
151     p->cfg = cfg->cfg;
152 
153     /* update output to MppEnc */
154     cfg->type = VPU_CLIENT_RKVENC;
155     ret = mpp_dev_init(&cfg->dev, cfg->type);
156     if (ret) {
157         mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
158         goto DONE;
159     }
160     p->dev = cfg->dev;
161 
162     ret = hal_bufs_init(&p->hw_recn);
163     if (ret) {
164         mpp_err_f("init vepu buffer failed ret: %d\n", ret);
165         goto DONE;
166     }
167 
168     {   /* setup default hardware config */
169         MppEncHwCfg *hw = &cfg->cfg->hw;
170 
171         hw->qp_delta_row_i  = 1;
172         hw->qp_delta_row    = 2;
173         hw->qbias_i = 683;
174         hw->qbias_p = 341;
175         hw->qbias_en = 0;
176 
177         memcpy(hw->aq_thrd_i, h264_aq_tthd_default, sizeof(hw->aq_thrd_i));
178         memcpy(hw->aq_thrd_p, h264_aq_tthd_default, sizeof(hw->aq_thrd_p));
179         memcpy(hw->aq_step_i, h264_I_aq_step_default, sizeof(hw->aq_step_i));
180         memcpy(hw->aq_step_p, h264_P_aq_step_default, sizeof(hw->aq_step_p));
181     }
182 
183     p->regs_set = mpp_calloc(HalVepu540cRegSet, 1);
184 
185     if (!p->regs_set) {
186         mpp_err("HalVepu540cRegSet alloc fail");
187         return MPP_ERR_MALLOC;
188     }
189 
190 DONE:
191     if (ret)
192         hal_h264e_vepu540c_deinit(hal);
193 
194     h264e_vepu_stream_amend_init(&p->amend);
195 
196     hal_h264e_dbg_func("leave %p\n", p);
197     return ret;
198 }
199 
setup_hal_bufs(HalH264eVepu540cCtx * ctx)200 static void setup_hal_bufs(HalH264eVepu540cCtx *ctx)
201 {
202     MppEncCfgSet *cfg = ctx->cfg;
203     MppEncPrepCfg *prep = &cfg->prep;
204     RK_S32 alignment = 64;
205     RK_S32 aligned_w = MPP_ALIGN(prep->width,  alignment);
206     RK_S32 aligned_h = MPP_ALIGN(prep->height, alignment);
207     RK_S32 pixel_buf_fbc_hdr_size = MPP_ALIGN(aligned_w * aligned_h / 64, SZ_8K);
208     RK_S32 pixel_buf_fbc_bdy_size = aligned_w * aligned_h * 3 / 2;
209     RK_S32 pixel_buf_size = pixel_buf_fbc_hdr_size + pixel_buf_fbc_bdy_size;
210     RK_S32 thumb_buf_size = MPP_ALIGN(aligned_w / 64 * aligned_h / 64 * 256, SZ_8K);
211     RK_S32 old_max_cnt = ctx->max_buf_cnt;
212     RK_S32 new_max_cnt = 2;
213     MppEncRefCfg ref_cfg = cfg->ref_cfg;
214 
215     if (ref_cfg) {
216         MppEncCpbInfo *info = mpp_enc_ref_cfg_get_cpb_info(ref_cfg);
217         if (new_max_cnt < MPP_MAX(new_max_cnt, info->dpb_size + 1))
218             new_max_cnt = MPP_MAX(new_max_cnt, info->dpb_size + 1);
219     }
220 
221     if (aligned_w > (3 * SZ_1K)) {
222         RK_S32 ext_line_buf_size = (aligned_w / 64 - 36) * 56 * 16;
223 
224         if (NULL == ctx->ext_line_buf_grp)
225             mpp_buffer_group_get_internal(&ctx->ext_line_buf_grp, MPP_BUFFER_TYPE_ION);
226         else if (ext_line_buf_size != ctx->ext_line_buf_size) {
227             mpp_buffer_put(ctx->ext_line_buf);
228             ctx->ext_line_buf = NULL;
229             mpp_buffer_group_clear(ctx->ext_line_buf_grp);
230         }
231 
232         mpp_assert(ctx->ext_line_buf_grp);
233 
234         if (NULL == ctx->ext_line_buf)
235             mpp_buffer_get(ctx->ext_line_buf_grp, &ctx->ext_line_buf, ext_line_buf_size);
236 
237         ctx->ext_line_buf_size = ext_line_buf_size;
238     } else {
239         if (ctx->ext_line_buf) {
240             mpp_buffer_put(ctx->ext_line_buf);
241             ctx->ext_line_buf = NULL;
242         }
243 
244         if (ctx->ext_line_buf_grp) {
245             mpp_buffer_group_clear(ctx->ext_line_buf_grp);
246             mpp_buffer_group_put(ctx->ext_line_buf_grp);
247             ctx->ext_line_buf_grp = NULL;
248         }
249         ctx->ext_line_buf_size = 0;
250     }
251 
252     if ((ctx->pixel_buf_fbc_hdr_size != pixel_buf_fbc_hdr_size) ||
253         (ctx->pixel_buf_fbc_bdy_size != pixel_buf_fbc_bdy_size) ||
254         (ctx->pixel_buf_size != pixel_buf_size) ||
255         (ctx->thumb_buf_size != thumb_buf_size) ||
256         (new_max_cnt > old_max_cnt)) {
257         size_t sizes[2];
258 
259         hal_h264e_dbg_detail("frame size %d -> %d max count %d -> %d\n",
260                              ctx->pixel_buf_size, pixel_buf_size,
261                              old_max_cnt, new_max_cnt);
262 
263         /* pixel buffer */
264         sizes[0] = pixel_buf_size;
265         /* thumb buffer */
266         sizes[1] = thumb_buf_size;
267         new_max_cnt = MPP_MAX(new_max_cnt, old_max_cnt);
268 
269         hal_bufs_setup(ctx->hw_recn, new_max_cnt, 2, sizes);
270 
271         ctx->pixel_buf_fbc_hdr_size = pixel_buf_fbc_hdr_size;
272         ctx->pixel_buf_fbc_bdy_size = pixel_buf_fbc_bdy_size;
273         ctx->pixel_buf_size = pixel_buf_size;
274         ctx->thumb_buf_size = thumb_buf_size;
275         ctx->max_buf_cnt = new_max_cnt;
276     }
277 }
278 
hal_h264e_vepu540c_prepare(void * hal)279 static MPP_RET hal_h264e_vepu540c_prepare(void *hal)
280 {
281     HalH264eVepu540cCtx *ctx = (HalH264eVepu540cCtx *)hal;
282     MppEncPrepCfg *prep = &ctx->cfg->prep;
283 
284     hal_h264e_dbg_func("enter %p\n", hal);
285 
286     if (prep->change_res) {
287         RK_S32 i;
288 
289         // pre-alloc required buffers to reduce first frame delay
290         setup_hal_bufs(ctx);
291         for (i = 0; i < ctx->max_buf_cnt; i++)
292             hal_bufs_get_buf(ctx->hw_recn, i);
293 
294         prep->change_res = 0;
295     }
296 
297     hal_h264e_dbg_func("leave %p\n", hal);
298 
299     return MPP_OK;
300 }
301 
update_vepu540c_syntax(HalH264eVepu540cCtx * ctx,MppSyntax * syntax)302 static RK_U32 update_vepu540c_syntax(HalH264eVepu540cCtx *ctx, MppSyntax *syntax)
303 {
304     H264eSyntaxDesc *desc = syntax->data;
305     RK_S32 syn_num = syntax->number;
306     RK_U32 updated = 0;
307     RK_S32 i;
308 
309     for (i = 0; i < syn_num; i++, desc++) {
310         switch (desc->type) {
311         case H264E_SYN_CFG : {
312             hal_h264e_dbg_detail("update cfg");
313             ctx->cfg = desc->p;
314         } break;
315         case H264E_SYN_SPS : {
316             hal_h264e_dbg_detail("update sps");
317             ctx->sps = desc->p;
318         } break;
319         case H264E_SYN_PPS : {
320             hal_h264e_dbg_detail("update pps");
321             ctx->pps = desc->p;
322         } break;
323         case H264E_SYN_DPB : {
324             hal_h264e_dbg_detail("update dpb");
325         } break;
326         case H264E_SYN_SLICE : {
327             hal_h264e_dbg_detail("update slice");
328             ctx->slice = desc->p;
329         } break;
330         case H264E_SYN_FRAME : {
331             hal_h264e_dbg_detail("update frames");
332             ctx->frms = desc->p;
333         } break;
334         case H264E_SYN_PREFIX : {
335             hal_h264e_dbg_detail("update prefix nal");
336             ctx->prefix = desc->p;
337         } break;
338         default : {
339             mpp_log_f("invalid syntax type %d\n", desc->type);
340         } break;
341         }
342 
343         updated |= SYN_TYPE_FLAG(desc->type);
344     }
345 
346     return updated;
347 }
348 
hal_h264e_vepu540c_get_task(void * hal,HalEncTask * task)349 static MPP_RET hal_h264e_vepu540c_get_task(void *hal, HalEncTask *task)
350 {
351     HalH264eVepu540cCtx *ctx = (HalH264eVepu540cCtx *)hal;
352     MppEncH264HwCfg *hw_cfg = &ctx->cfg->h264.hw_cfg;
353     RK_U32 updated = update_vepu540c_syntax(ctx, &task->syntax);
354     EncFrmStatus *frm_status = &task->rc_task->frm;
355     hal_h264e_dbg_func("enter %p\n", hal);
356 
357     if (updated & SYN_TYPE_FLAG(H264E_SYN_CFG))
358         setup_hal_bufs(ctx);
359 
360 
361     if (!frm_status->reencode && mpp_frame_has_meta(task->frame)) {
362         MppMeta meta = mpp_frame_get_meta(task->frame);
363 
364         mpp_meta_get_ptr(meta, KEY_ROI_DATA, (void **)&ctx->roi_data);
365     }
366 
367     /* if not VEPU1/2, update log2_max_frame_num_minus4 in hw_cfg */
368     hw_cfg->hw_log2_max_frame_num_minus4 = ctx->sps->log2_max_frame_num_minus4;
369 
370     h264e_vepu_stream_amend_config(&ctx->amend, task->packet, ctx->cfg,
371                                    ctx->slice, ctx->prefix);
372 
373     hal_h264e_dbg_func("leave %p\n", hal);
374 
375     return MPP_OK;
376 }
377 
setup_vepu540c_normal(HalVepu540cRegSet * regs)378 static void setup_vepu540c_normal(HalVepu540cRegSet *regs)
379 {
380     hal_h264e_dbg_func("enter\n");
381     /* reg000 VERSION is read only */
382 
383     /* reg001 ENC_STRT */
384     regs->reg_ctl.enc_strt.lkt_num           = 0;
385     regs->reg_ctl.enc_strt.vepu_cmd          = 1;
386 
387     regs->reg_ctl.func_en.cke                = 1;
388     regs->reg_ctl.func_en.resetn_hw_en       = 1;
389     regs->reg_ctl.func_en.enc_done_tmvp_en   = 1;
390 
391     /* reg002 ENC_CLR */
392     regs->reg_ctl.enc_clr.safe_clr           = 0;
393     regs->reg_ctl.enc_clr.force_clr          = 0;
394 
395     /* reg003 LKT_ADDR */
396     // regs->reg_ctl.lkt_addr           = 0;
397 
398     /* reg004 INT_EN */
399     regs->reg_ctl.int_en.enc_done_en        = 1;
400     regs->reg_ctl.int_en.lkt_node_done_en   = 1;
401     regs->reg_ctl.int_en.sclr_done_en       = 1;
402     regs->reg_ctl.int_en.vslc_done_en       = 0;
403     regs->reg_ctl.int_en.vbsf_oflw_en       = 1;
404     regs->reg_ctl.int_en.vbuf_lens_en       = 1;
405     regs->reg_ctl.int_en.enc_err_en         = 1;
406     regs->reg_ctl.int_en.dvbm_fcfg_en       = 1;
407     regs->reg_ctl.int_en.wdg_en             = 1;
408     regs->reg_ctl.int_en.lkt_err_int_en     = 1;
409     regs->reg_ctl.int_en.lkt_err_stop_en    = 1;
410     regs->reg_ctl.int_en.lkt_force_stop_en  = 1;
411     regs->reg_ctl.int_en.jslc_done_en       = 1;
412     regs->reg_ctl.int_en.jbsf_oflw_en       = 1;
413     regs->reg_ctl.int_en.jbuf_lens_en       = 1;
414     regs->reg_ctl.int_en.dvbm_dcnt_en       = 1;
415 
416     /* reg005 INT_MSK */
417     regs->reg_ctl.int_msk.enc_done_msk        = 0;
418     regs->reg_ctl.int_msk.lkt_node_done_msk   = 0;
419     regs->reg_ctl.int_msk.sclr_done_msk       = 0;
420     regs->reg_ctl.int_msk.vslc_done_msk       = 0;
421     regs->reg_ctl.int_msk.vbsf_oflw_msk       = 0;
422     regs->reg_ctl.int_msk.vbuf_lens_msk       = 0;
423     regs->reg_ctl.int_msk.enc_err_msk         = 0;
424     regs->reg_ctl.int_msk.dvbm_fcfg_msk       = 0;
425     regs->reg_ctl.int_msk.wdg_msk             = 0;
426     regs->reg_ctl.int_msk.lkt_err_int_msk     = 0;
427     regs->reg_ctl.int_msk.lkt_err_stop_msk    = 0;
428     regs->reg_ctl.int_msk.lkt_force_stop_msk  = 0;
429     regs->reg_ctl.int_msk.jslc_done_msk       = 0;
430     regs->reg_ctl.int_msk.jbsf_oflw_msk       = 0;
431     regs->reg_ctl.int_msk.jbuf_lens_msk       = 0;
432     regs->reg_ctl.int_msk.dvbm_dcnt_msk       = 0;
433 
434     /* reg006 INT_CLR is not set */
435     /* reg007 INT_STA is read only */
436     /* reg008 ~ reg0011 gap */
437     regs->reg_ctl.enc_wdg.vs_load_thd        = 0x5ffff;
438     regs->reg_ctl.enc_wdg.rfp_load_thd       = 0;//xff;
439 
440     /* reg015 DTRNS_MAP */
441     regs->reg_ctl.dtrns_map.jpeg_bus_edin      = 0;
442     regs->reg_ctl.dtrns_map.src_bus_edin       = 0;
443     regs->reg_ctl.dtrns_map.meiw_bus_edin      = 0;
444     regs->reg_ctl.dtrns_map.bsw_bus_edin       = 7;
445     regs->reg_ctl.dtrns_map.lktr_bus_edin      = 0;
446     regs->reg_ctl.dtrns_map.roir_bus_edin      = 0;
447     regs->reg_ctl.dtrns_map.lktw_bus_edin      = 0;
448     regs->reg_ctl.dtrns_map.rec_nfbc_bus_edin  = 0;
449 
450     regs->reg_ctl.dtrns_cfg.axi_brsp_cke   = 0;
451     hal_h264e_dbg_func("leave\n");
452 }
453 
setup_vepu540c_prep(HalVepu540cRegSet * regs,MppEncPrepCfg * prep)454 static MPP_RET setup_vepu540c_prep(HalVepu540cRegSet *regs, MppEncPrepCfg *prep)
455 {
456     VepuFmtCfg cfg;
457     MppFrameFormat fmt = prep->format;
458     MPP_RET ret = vepu5xx_set_fmt(&cfg, fmt);
459     RK_U32 hw_fmt = cfg.format;
460     RK_S32 y_stride;
461     RK_S32 c_stride;
462 
463     hal_h264e_dbg_func("enter\n");
464 
465     /* do nothing when color format is not supported */
466     if (ret)
467         return ret;
468 
469     regs->reg_base.enc_rsl.pic_wd8_m1 = MPP_ALIGN(prep->width, 16) / 8 - 1;
470     regs->reg_base.src_fill.pic_wfill = MPP_ALIGN(prep->width, 16) - prep->width;
471     regs->reg_base.enc_rsl.pic_hd8_m1 = MPP_ALIGN(prep->height, 16) / 8 - 1;
472     regs->reg_base.src_fill.pic_hfill = MPP_ALIGN(prep->height, 16) - prep->height;
473 
474     regs->reg_ctl.dtrns_map.src_bus_edin = cfg.src_endian;
475 
476     regs->reg_base.src_fmt.src_cfmt   = hw_fmt;
477     regs->reg_base.src_fmt.alpha_swap = cfg.alpha_swap;
478     regs->reg_base.src_fmt.rbuv_swap  = cfg.rbuv_swap;
479     regs->reg_base.src_fmt.out_fmt    = (fmt == MPP_FMT_YUV400) ? 0 : 1;
480 
481     y_stride = (MPP_FRAME_FMT_IS_FBC(fmt)) ? (MPP_ALIGN(prep->width, 16)) :
482                (prep->hor_stride) ? (prep->hor_stride) : (prep->width);
483 
484     c_stride = (hw_fmt == VEPU5xx_FMT_YUV422SP || hw_fmt == VEPU5xx_FMT_YUV420SP) ?
485                y_stride : y_stride / 2;
486 
487     if (hw_fmt < VEPU5xx_FMT_ARGB1555) {
488         const VepuRgb2YuvCfg *cfg_coeffs = get_rgb2yuv_cfg(prep->range, prep->color);
489 
490         hal_h264e_dbg_flow("input color range %d colorspace %d", prep->range, prep->color);
491 
492         regs->reg_base.src_udfy.csc_wgt_b2y = cfg_coeffs->_2y.b_coeff;
493         regs->reg_base.src_udfy.csc_wgt_g2y = cfg_coeffs->_2y.g_coeff;
494         regs->reg_base.src_udfy.csc_wgt_r2y = cfg_coeffs->_2y.r_coeff;
495 
496         regs->reg_base.src_udfu.csc_wgt_b2u = cfg_coeffs->_2u.b_coeff;
497         regs->reg_base.src_udfu.csc_wgt_g2u = cfg_coeffs->_2u.g_coeff;
498         regs->reg_base.src_udfu.csc_wgt_r2u = cfg_coeffs->_2u.r_coeff;
499 
500         regs->reg_base.src_udfv.csc_wgt_b2v = cfg_coeffs->_2v.b_coeff;
501         regs->reg_base.src_udfv.csc_wgt_g2v = cfg_coeffs->_2v.g_coeff;
502         regs->reg_base.src_udfv.csc_wgt_r2v = cfg_coeffs->_2v.r_coeff;
503 
504         regs->reg_base.src_udfo.csc_ofst_y  = cfg_coeffs->_2y.offset;
505         regs->reg_base.src_udfo.csc_ofst_u  = cfg_coeffs->_2u.offset;
506         regs->reg_base.src_udfo.csc_ofst_v  = cfg_coeffs->_2v.offset;
507 
508         hal_h264e_dbg_flow("use color range %d colorspace %d", cfg_coeffs->dst_range, cfg_coeffs->color);
509     } else {
510         regs->reg_base.src_udfy.csc_wgt_b2y = cfg.weight[0];
511         regs->reg_base.src_udfy.csc_wgt_g2y = cfg.weight[1];
512         regs->reg_base.src_udfy.csc_wgt_r2y = cfg.weight[2];
513 
514         regs->reg_base.src_udfu.csc_wgt_b2u = cfg.weight[3];
515         regs->reg_base.src_udfu.csc_wgt_g2u = cfg.weight[4];
516         regs->reg_base.src_udfu.csc_wgt_r2u = cfg.weight[5];
517 
518         regs->reg_base.src_udfv.csc_wgt_b2v = cfg.weight[6];
519         regs->reg_base.src_udfv.csc_wgt_g2v = cfg.weight[7];
520         regs->reg_base.src_udfv.csc_wgt_r2v = cfg.weight[8];
521 
522         regs->reg_base.src_udfo.csc_ofst_y  = cfg.offset[0];
523         regs->reg_base.src_udfo.csc_ofst_u  = cfg.offset[1];
524         regs->reg_base.src_udfo.csc_ofst_v  = cfg.offset[2];
525     }
526 
527     regs->reg_base.src_strd0.src_strd0  = y_stride;
528     regs->reg_base.src_strd1.src_strd1  = c_stride;
529 
530     regs->reg_base.src_proc.src_mirr   = prep->mirroring > 0;
531     regs->reg_base.src_proc.src_rot    = prep->rotation;
532     //  regs->reg_base.src_proc.txa_en     = 0;
533 
534     regs->reg_base.sli_cfg.mv_v_lmt_thd = 0;
535     regs->reg_base.sli_cfg.mv_v_lmt_en = 0;
536 
537     regs->reg_base.pic_ofst.pic_ofst_y = 0;
538     regs->reg_base.pic_ofst.pic_ofst_x = 0;
539 
540     hal_h264e_dbg_func("leave\n");
541 
542     return ret;
543 }
544 
setup_vepu540c_codec(HalVepu540cRegSet * regs,H264eSps * sps,H264ePps * pps,H264eSlice * slice)545 static void setup_vepu540c_codec(HalVepu540cRegSet *regs, H264eSps *sps,
546                                  H264ePps *pps, H264eSlice *slice)
547 {
548     hal_h264e_dbg_func("enter\n");
549 
550     regs->reg_base.enc_pic.enc_stnd       = 0;
551     regs->reg_base.enc_pic.cur_frm_ref    = slice->nal_reference_idc > 0;
552     regs->reg_base.enc_pic.bs_scp         = 1;
553 
554     regs->reg_base.synt_nal.nal_ref_idc    = slice->nal_reference_idc;
555     regs->reg_base.synt_nal.nal_unit_type  = slice->nalu_type;
556 
557     regs->reg_base.synt_sps.max_fnum       = sps->log2_max_frame_num_minus4;
558     regs->reg_base.synt_sps.drct_8x8       = sps->direct8x8_inference;
559     regs->reg_base.synt_sps.mpoc_lm4       = sps->log2_max_poc_lsb_minus4;
560 
561     regs->reg_base.synt_pps.etpy_mode      = pps->entropy_coding_mode;
562     regs->reg_base.synt_pps.trns_8x8       = pps->transform_8x8_mode;
563     regs->reg_base.synt_pps.csip_flag      = pps->constrained_intra_pred;
564     regs->reg_base.synt_pps.num_ref0_idx   = pps->num_ref_idx_l0_default_active - 1;
565     regs->reg_base.synt_pps.num_ref1_idx   = pps->num_ref_idx_l1_default_active - 1;
566     regs->reg_base.synt_pps.pic_init_qp    = pps->pic_init_qp;
567     regs->reg_base.synt_pps.cb_ofst        = pps->chroma_qp_index_offset;
568     regs->reg_base.synt_pps.cr_ofst        = pps->second_chroma_qp_index_offset;
569     regs->reg_base.synt_pps.dbf_cp_flg     = pps->deblocking_filter_control;
570 
571     regs->reg_base.synt_sli0.sli_type       = (slice->slice_type == H264_I_SLICE) ? (2) : (0);
572     regs->reg_base.synt_sli0.pps_id         = slice->pic_parameter_set_id;
573     regs->reg_base.synt_sli0.drct_smvp      = 0;
574     regs->reg_base.synt_sli0.num_ref_ovrd   = slice->num_ref_idx_override;
575     regs->reg_base.synt_sli0.cbc_init_idc   = slice->cabac_init_idc;
576     regs->reg_base.synt_sli0.frm_num        = slice->frame_num;
577 
578     regs->reg_base.synt_sli1.idr_pid        = (slice->slice_type == H264_I_SLICE) ? slice->idr_pic_id : (RK_U32)(-1);
579     regs->reg_base.synt_sli1.poc_lsb        = slice->pic_order_cnt_lsb;
580 
581 
582     regs->reg_base.synt_sli2.dis_dblk_idc   = slice->disable_deblocking_filter_idc;
583     regs->reg_base.synt_sli2.sli_alph_ofst  = slice->slice_alpha_c0_offset_div2;
584 
585     h264e_reorder_rd_rewind(slice->reorder);
586     {   /* reorder process */
587         H264eRplmo rplmo;
588         MPP_RET ret = h264e_reorder_rd_op(slice->reorder, &rplmo);
589 
590         if (MPP_OK == ret) {
591             regs->reg_base.synt_sli2.ref_list0_rodr = 1;
592             regs->reg_base.synt_sli2.rodr_pic_idx   = rplmo.modification_of_pic_nums_idc;
593 
594             switch (rplmo.modification_of_pic_nums_idc) {
595             case 0 :
596             case 1 : {
597                 regs->reg_base.synt_sli2.rodr_pic_num   = rplmo.abs_diff_pic_num_minus1;
598             } break;
599             case 2 : {
600                 regs->reg_base.synt_sli2.rodr_pic_num   = rplmo.long_term_pic_idx;
601             } break;
602             default : {
603                 mpp_err_f("invalid modification_of_pic_nums_idc %d\n",
604                           rplmo.modification_of_pic_nums_idc);
605             } break;
606             }
607         } else {
608             // slice->ref_pic_list_modification_flag;
609             regs->reg_base.synt_sli2.ref_list0_rodr = 0;
610             regs->reg_base.synt_sli2.rodr_pic_idx   = 0;
611             regs->reg_base.synt_sli2.rodr_pic_num   = 0;
612         }
613     }
614 
615     /* clear all mmco arg first */
616     regs->reg_base.synt_refm0.nopp_flg               = 0;
617     regs->reg_base.synt_refm0.ltrf_flg               = 0;
618     regs->reg_base.synt_refm0.arpm_flg               = 0;
619     regs->reg_base.synt_refm0.mmco4_pre              = 0;
620     regs->reg_base.synt_refm0.mmco_type0             = 0;
621     regs->reg_base.synt_refm0.mmco_parm0             = 0;
622     regs->reg_base.synt_refm0.mmco_type1             = 0;
623     regs->reg_base.synt_refm1.mmco_parm1             = 0;
624     regs->reg_base.synt_refm0.mmco_type2             = 0;
625     regs->reg_base.synt_refm1.mmco_parm2             = 0;
626     regs->reg_base.synt_refm2.long_term_frame_idx0   = 0;
627     regs->reg_base.synt_refm2.long_term_frame_idx1   = 0;
628     regs->reg_base.synt_refm2.long_term_frame_idx2   = 0;
629 
630     h264e_marking_rd_rewind(slice->marking);
631 
632     /* only update used parameter */
633     if (slice->slice_type == H264_I_SLICE) {
634         regs->reg_base.synt_refm0.nopp_flg       = slice->no_output_of_prior_pics;
635         regs->reg_base.synt_refm0.ltrf_flg       = slice->long_term_reference_flag;
636     } else {
637         if (!h264e_marking_is_empty(slice->marking)) {
638             H264eMmco mmco;
639 
640             regs->reg_base.synt_refm0.arpm_flg       = 1;
641 
642             /* max 3 mmco */
643             do {
644                 RK_S32 type = 0;
645                 RK_S32 param_0 = 0;
646                 RK_S32 param_1 = 0;
647 
648                 h264e_marking_rd_op(slice->marking, &mmco);
649                 type = mmco.mmco;
650                 switch (type) {
651                 case 1 : {
652                     param_0 = mmco.difference_of_pic_nums_minus1;
653                 } break;
654                 case 2 : {
655                     param_0 = mmco.long_term_pic_num;
656                 } break;
657                 case 3 : {
658                     param_0 = mmco.difference_of_pic_nums_minus1;
659                     param_1 = mmco.long_term_frame_idx;
660                 } break;
661                 case 4 : {
662                     param_0 = mmco.max_long_term_frame_idx_plus1;
663                 } break;
664                 case 5 : {
665                 } break;
666                 case 6 : {
667                     param_0 = mmco.long_term_frame_idx;
668                 } break;
669                 default : {
670                     mpp_err_f("unsupported mmco 0 %d\n", type);
671                     type = 0;
672                 } break;
673                 }
674 
675                 regs->reg_base.synt_refm0.mmco_type0 = type;
676                 regs->reg_base.synt_refm0.mmco_parm0 = param_0;
677                 regs->reg_base.synt_refm2.long_term_frame_idx0 = param_1;
678 
679                 if (h264e_marking_is_empty(slice->marking))
680                     break;
681 
682                 h264e_marking_rd_op(slice->marking, &mmco);
683                 type = mmco.mmco;
684                 param_0 = 0;
685                 param_1 = 0;
686                 switch (type) {
687                 case 1 : {
688                     param_0 = mmco.difference_of_pic_nums_minus1;
689                 } break;
690                 case 2 : {
691                     param_0 = mmco.long_term_pic_num;
692                 } break;
693                 case 3 : {
694                     param_0 = mmco.difference_of_pic_nums_minus1;
695                     param_1 = mmco.long_term_frame_idx;
696                 } break;
697                 case 4 : {
698                     param_0 = mmco.max_long_term_frame_idx_plus1;
699                 } break;
700                 case 5 : {
701                 } break;
702                 case 6 : {
703                     param_0 = mmco.long_term_frame_idx;
704                 } break;
705                 default : {
706                     mpp_err_f("unsupported mmco 0 %d\n", type);
707                     type = 0;
708                 } break;
709                 }
710 
711                 regs->reg_base.synt_refm0.mmco_type1 = type;
712                 regs->reg_base.synt_refm1.mmco_parm1 = param_0;
713                 regs->reg_base.synt_refm2.long_term_frame_idx1 = param_1;
714 
715                 if (h264e_marking_is_empty(slice->marking))
716                     break;
717 
718                 h264e_marking_rd_op(slice->marking, &mmco);
719                 type = mmco.mmco;
720                 param_0 = 0;
721                 param_1 = 0;
722                 switch (type) {
723                 case 1 : {
724                     param_0 = mmco.difference_of_pic_nums_minus1;
725                 } break;
726                 case 2 : {
727                     param_0 = mmco.long_term_pic_num;
728                 } break;
729                 case 3 : {
730                     param_0 = mmco.difference_of_pic_nums_minus1;
731                     param_1 = mmco.long_term_frame_idx;
732                 } break;
733                 case 4 : {
734                     param_0 = mmco.max_long_term_frame_idx_plus1;
735                 } break;
736                 case 5 : {
737                 } break;
738                 case 6 : {
739                     param_0 = mmco.long_term_frame_idx;
740                 } break;
741                 default : {
742                     mpp_err_f("unsupported mmco 0 %d\n", type);
743                     type = 0;
744                 } break;
745                 }
746 
747                 regs->reg_base.synt_refm0.mmco_type2 = type;
748                 regs->reg_base.synt_refm1.mmco_parm2 = param_0;
749                 regs->reg_base.synt_refm2.long_term_frame_idx2 = param_1;
750             } while (0);
751         }
752     }
753 
754     hal_h264e_dbg_func("leave\n");
755 }
756 
setup_vepu540c_rdo_pred(HalVepu540cRegSet * regs,H264eSps * sps,H264ePps * pps,H264eSlice * slice)757 static void setup_vepu540c_rdo_pred(HalVepu540cRegSet *regs, H264eSps *sps,
758                                     H264ePps *pps, H264eSlice *slice)
759 {
760     hal_h264e_dbg_func("enter\n");
761 
762     if (slice->slice_type == H264_I_SLICE) {
763         regs->reg_rc_roi.klut_ofst.chrm_klut_ofst = 6;
764     } else {
765         regs->reg_rc_roi.klut_ofst.chrm_klut_ofst = 9;
766     }
767 
768     regs->reg_base.rdo_cfg.rect_size      = (sps->profile_idc == H264_PROFILE_BASELINE &&
769                                              sps->level_idc <= H264_LEVEL_3_0) ? 1 : 0;
770     regs->reg_base.rdo_cfg.vlc_lmt        = (sps->profile_idc < H264_PROFILE_MAIN) &&
771                                             !pps->entropy_coding_mode;
772     regs->reg_base.rdo_cfg.chrm_spcl      = 1;
773     regs->reg_base.rdo_cfg.ccwa_e         = 1;
774     regs->reg_base.rdo_cfg.scl_lst_sel    = pps->pic_scaling_matrix_present;
775     regs->reg_base.rdo_cfg.atf_e          = 1;
776     regs->reg_base.rdo_cfg.atr_e          = 1;
777     regs->reg_base.rdo_cfg.intra_cost_e   = 1;
778     regs->reg_base.iprd_csts.rdo_mark_mode       = 0x100;
779 
780     hal_h264e_dbg_func("leave\n");
781 }
782 
setup_vepu540c_rdo_cfg(vepu540c_rdo_cfg * reg)783 static void setup_vepu540c_rdo_cfg(vepu540c_rdo_cfg *reg)
784 {
785     hal_h264e_dbg_func("enter\n");
786     rdo_skip_par *p_rdo_skip = NULL;
787     rdo_noskip_par *p_rdo_noskip = NULL;
788 
789     reg->rdo_smear_cfg_comb.rdo_smear_en      =  0;
790     reg->rdo_smear_cfg_comb.rdo_smear_lvl16_multi = 9;
791     reg->rdo_smear_cfg_comb.rdo_smear_dlt_qp      = 0 ;
792     reg->rdo_smear_cfg_comb.rdo_smear_order_state = 0;
793     reg->rdo_smear_cfg_comb.stated_mode           = 0;
794     reg->rdo_smear_cfg_comb.online_en             = 0;
795     reg->rdo_smear_cfg_comb.smear_stride          = 0;
796     reg->rdo_smear_madp_thd0_comb.rdo_smear_madp_cur_thd0 =  0;
797     reg->rdo_smear_madp_thd0_comb.rdo_smear_madp_cur_thd1 =  24;
798     reg->rdo_smear_madp_thd1_comb.rdo_smear_madp_cur_thd2 =  48;
799     reg->rdo_smear_madp_thd1_comb.rdo_smear_madp_cur_thd3 =  64;
800     reg->rdo_smear_madp_thd2_comb.rdo_smear_madp_around_thd0 = 16;
801     reg->rdo_smear_madp_thd2_comb.rdo_smear_madp_around_thd1 = 32;
802     reg->rdo_smear_madp_thd3_comb.rdo_smear_madp_around_thd2 = 48;
803     reg->rdo_smear_madp_thd3_comb.rdo_smear_madp_around_thd3 = 96;
804     reg->rdo_smear_madp_thd4_comb.rdo_smear_madp_around_thd4 = 48;
805     reg->rdo_smear_madp_thd4_comb.rdo_smear_madp_around_thd5 = 24;
806     reg->rdo_smear_madp_thd5_comb.rdo_smear_madp_ref_thd0 =  96;
807     reg->rdo_smear_madp_thd5_comb.rdo_smear_madp_ref_thd1 =  48;
808     reg->rdo_smear_cnt_thd0_comb.rdo_smear_cnt_cur_thd0    = 1;
809     reg->rdo_smear_cnt_thd0_comb.rdo_smear_cnt_cur_thd1    = 3;
810     reg->rdo_smear_cnt_thd0_comb.rdo_smear_cnt_cur_thd2    = 1;
811     reg->rdo_smear_cnt_thd0_comb.rdo_smear_cnt_cur_thd3    = 3;
812     reg->rdo_smear_cnt_thd1_comb.rdo_smear_cnt_around_thd0 = 1;
813     reg->rdo_smear_cnt_thd1_comb.rdo_smear_cnt_around_thd1 = 4;
814     reg->rdo_smear_cnt_thd1_comb.rdo_smear_cnt_around_thd2 = 1;
815     reg->rdo_smear_cnt_thd1_comb.rdo_smear_cnt_around_thd3 = 4;
816     reg->rdo_smear_cnt_thd2_comb.rdo_smear_cnt_around_thd4 = 0;
817     reg->rdo_smear_cnt_thd2_comb.rdo_smear_cnt_around_thd5 = 3;
818     reg->rdo_smear_cnt_thd2_comb.rdo_smear_cnt_around_thd6 = 0;
819     reg->rdo_smear_cnt_thd2_comb.rdo_smear_cnt_around_thd7 = 3;
820     reg->rdo_smear_cnt_thd3_comb.rdo_smear_cnt_ref_thd0    = 1 ;
821     reg->rdo_smear_cnt_thd3_comb.rdo_smear_cnt_ref_thd1    = 3;
822     reg->rdo_smear_resi_thd0_comb.rdo_smear_resi_small_cur_th0    = 6;
823     reg->rdo_smear_resi_thd0_comb.rdo_smear_resi_big_cur_th0      = 9;
824     reg->rdo_smear_resi_thd0_comb.rdo_smear_resi_small_cur_th1    = 6;
825     reg->rdo_smear_resi_thd0_comb.rdo_smear_resi_big_cur_th1      = 9;
826     reg->rdo_smear_resi_thd1_comb.rdo_smear_resi_small_around_th0 = 6;
827     reg->rdo_smear_resi_thd1_comb.rdo_smear_resi_big_around_th0   = 11;
828     reg->rdo_smear_resi_thd1_comb.rdo_smear_resi_small_around_th1 = 6;
829     reg->rdo_smear_resi_thd1_comb.rdo_smear_resi_big_around_th1   = 8;
830     reg->rdo_smear_resi_thd2_comb.rdo_smear_resi_small_around_th2 = 9;
831     reg->rdo_smear_resi_thd2_comb.rdo_smear_resi_big_around_th2   = 20;
832     reg->rdo_smear_resi_thd2_comb.rdo_smear_resi_small_around_th3 = 6;
833     reg->rdo_smear_resi_thd2_comb.rdo_smear_resi_big_around_th3  = 20;
834     reg->rdo_smear_resi_thd3_comb.rdo_smear_resi_small_ref_th0  = 7;
835     reg->rdo_smear_resi_thd3_comb.rdo_smear_resi_big_ref_th0 = 16;
836     reg->rdo_smear_st_thd0_comb.rdo_smear_resi_th0 = 10;
837     reg->rdo_smear_st_thd0_comb.rdo_smear_resi_th1 = 6;
838     reg->rdo_smear_st_thd1_comb.rdo_smear_madp_cnt_th0 = 1;
839     reg->rdo_smear_st_thd1_comb.rdo_smear_madp_cnt_th1 = 5;
840     reg->rdo_smear_st_thd1_comb.rdo_smear_madp_cnt_th2 = 1;
841     reg->rdo_smear_st_thd1_comb.rdo_smear_madp_cnt_th3 = 3;
842     reg->rdo_smear_st_thd1_comb.rdo_smear_madp_cnt_th4 = 9;
843     reg->rdo_smear_st_thd1_comb.rdo_smear_madp_cnt_th5 = 10;
844 
845     p_rdo_skip = &reg->rdo_b16_skip;
846     p_rdo_skip->atf_thd0.madp_thd0 = 1;
847     p_rdo_skip->atf_thd0.madp_thd1 = 10;
848     p_rdo_skip->atf_thd1.madp_thd2 = 15;
849     p_rdo_skip->atf_thd1.madp_thd3 = 25;
850     p_rdo_skip->atf_wgt0.wgt0 = 20;
851     p_rdo_skip->atf_wgt0.wgt1 = 16;
852     p_rdo_skip->atf_wgt0.wgt2 = 16;
853     p_rdo_skip->atf_wgt0.wgt3 = 16;
854     p_rdo_skip->atf_wgt1.wgt4 = 16;
855 
856     p_rdo_noskip = &reg->rdo_b16_inter;
857     p_rdo_noskip->ratf_thd0.madp_thd0 = 20;
858     p_rdo_noskip->ratf_thd0.madp_thd1 = 40;
859     p_rdo_noskip->ratf_thd1.madp_thd2 = 72;
860     p_rdo_noskip->atf_wgt.wgt0 =        16;
861     p_rdo_noskip->atf_wgt.wgt1 =        16;
862     p_rdo_noskip->atf_wgt.wgt2 =        16;
863     p_rdo_noskip->atf_wgt.wgt3 =        16;
864 
865     p_rdo_noskip = &reg->rdo_b16_intra;
866     p_rdo_noskip->ratf_thd0.madp_thd0 = 20;
867     p_rdo_noskip->ratf_thd0.madp_thd1 = 40;
868     p_rdo_noskip->ratf_thd1.madp_thd2 = 72;
869     p_rdo_noskip->atf_wgt.wgt0 =        27;
870     p_rdo_noskip->atf_wgt.wgt1 =        25;
871     p_rdo_noskip->atf_wgt.wgt2 =        20;
872     p_rdo_noskip->atf_wgt.wgt3 =        16;
873 
874     reg->rdo_b16_intra_atf_cnt_thd_comb.thd0 = 1;
875     reg->rdo_b16_intra_atf_cnt_thd_comb.thd1 = 4;
876     reg->rdo_b16_intra_atf_cnt_thd_comb.thd2 = 1;
877     reg->rdo_b16_intra_atf_cnt_thd_comb.thd3 = 4;
878     reg->rdo_atf_resi_thd_comb.big_th0     = 16;
879     reg->rdo_atf_resi_thd_comb.big_th1     = 16;
880     reg->rdo_atf_resi_thd_comb.small_th0   = 8;
881     reg->rdo_atf_resi_thd_comb.small_th1   = 8;
882 
883     hal_h264e_dbg_func("leave\n");
884 }
885 
setup_vepu540c_rc_base(HalVepu540cRegSet * regs,HalH264eVepu540cCtx * ctx,EncRcTask * rc_task)886 static void setup_vepu540c_rc_base(HalVepu540cRegSet *regs, HalH264eVepu540cCtx *ctx, EncRcTask *rc_task)
887 {
888     H264eSps *sps = ctx->sps;
889     H264eSlice *slice = ctx->slice;
890     MppEncCfgSet *cfg = ctx->cfg;
891     MppEncRcCfg *rc = &cfg->rc;
892     MppEncHwCfg *hw = &cfg->hw;
893     EncRcTaskInfo *rc_info = &rc_task->info;
894     RK_S32 mb_w = sps->pic_width_in_mbs;
895     RK_S32 mb_h = sps->pic_height_in_mbs;
896     RK_U32 qp_target = rc_info->quality_target;
897     RK_U32 qp_min = rc_info->quality_min;
898     RK_U32 qp_max = rc_info->quality_max;
899     RK_U32 qpmap_mode = 1;
900     RK_S32 mb_target_bits_mul_16 = (rc_info->bit_target << 4) / (mb_w * mb_h);
901     RK_S32 mb_target_bits;
902     RK_S32 negative_bits_thd;
903     RK_S32 positive_bits_thd;
904 
905     hal_h264e_dbg_rc("bittarget %d qp [%d %d %d]\n", rc_info->bit_target,
906                      qp_min, qp_target, qp_max);
907 
908     hal_h264e_dbg_func("enter\n");
909 
910     regs->reg_rc_roi.roi_qthd0.qpmin_area0    = qp_min;
911     regs->reg_rc_roi.roi_qthd0.qpmax_area0    = qp_max;
912     regs->reg_rc_roi.roi_qthd0.qpmin_area1    = qp_min;
913     regs->reg_rc_roi.roi_qthd0.qpmax_area1    = qp_max;
914     regs->reg_rc_roi.roi_qthd0.qpmin_area2    = qp_min;
915 
916     regs->reg_rc_roi.roi_qthd1.qpmax_area2    = qp_max;
917     regs->reg_rc_roi.roi_qthd1.qpmin_area3    = qp_min;
918     regs->reg_rc_roi.roi_qthd1.qpmax_area3    = qp_max;
919     regs->reg_rc_roi.roi_qthd1.qpmin_area4    = qp_min;
920     regs->reg_rc_roi.roi_qthd1.qpmax_area4    = qp_max;
921 
922     regs->reg_rc_roi.roi_qthd2.qpmin_area5    = qp_min;
923     regs->reg_rc_roi.roi_qthd2.qpmax_area5    = qp_max;
924     regs->reg_rc_roi.roi_qthd2.qpmin_area6    = qp_min;
925     regs->reg_rc_roi.roi_qthd2.qpmax_area6    = qp_max;
926     regs->reg_rc_roi.roi_qthd2.qpmin_area7    = qp_min;
927 
928     regs->reg_rc_roi.roi_qthd3.qpmax_area7    = qp_max;
929     regs->reg_rc_roi.roi_qthd3.qpmap_mode     = qpmap_mode;
930 
931     if (rc->rc_mode == MPP_ENC_RC_MODE_FIXQP) {
932         regs->reg_base.enc_pic.pic_qp    = rc_info->quality_target;
933         regs->reg_base.rc_qp.rc_max_qp   = rc_info->quality_target;
934         regs->reg_base.rc_qp.rc_min_qp   = rc_info->quality_target;
935 
936         return;
937     }
938 
939     if (mb_target_bits_mul_16 >= 0x100000)
940         mb_target_bits_mul_16 = 0x50000;
941 
942     mb_target_bits = (mb_target_bits_mul_16 * mb_w) >> 4;
943     negative_bits_thd = 0 - 5 * mb_target_bits / 16;
944     positive_bits_thd = 5 * mb_target_bits / 16;
945 
946     regs->reg_base.enc_pic.pic_qp         = qp_target;
947 
948     regs->reg_base.rc_cfg.rc_en          = 1;
949     regs->reg_base.rc_cfg.aq_en          = 1;
950     regs->reg_base.rc_cfg.aq_mode        = 0;
951     regs->reg_base.rc_cfg.rc_ctu_num     = mb_w;
952 
953     regs->reg_base.rc_qp.rc_qp_range    = (slice->slice_type == H264_I_SLICE) ?
954                                           hw->qp_delta_row_i : hw->qp_delta_row;
955     regs->reg_base.rc_qp.rc_max_qp      = qp_max;
956     regs->reg_base.rc_qp.rc_min_qp      = qp_min;
957 
958     regs->reg_base.rc_tgt.ctu_ebit       = mb_target_bits_mul_16;
959 
960     regs->reg_rc_roi.rc_adj0.qp_adj0        = -2;
961     regs->reg_rc_roi.rc_adj0.qp_adj1        = -1;
962     regs->reg_rc_roi.rc_adj0.qp_adj2        = 0;
963     regs->reg_rc_roi.rc_adj0.qp_adj3        = 1;
964     regs->reg_rc_roi.rc_adj0.qp_adj4        = 2;
965     regs->reg_rc_roi.rc_adj1.qp_adj5        = 0;
966     regs->reg_rc_roi.rc_adj1.qp_adj6        = 0;
967     regs->reg_rc_roi.rc_adj1.qp_adj7        = 0;
968     regs->reg_rc_roi.rc_adj1.qp_adj8        = 0;
969 
970     regs->reg_rc_roi.rc_dthd_0_8[0] = 4 * negative_bits_thd;
971     regs->reg_rc_roi.rc_dthd_0_8[1] = negative_bits_thd;
972     regs->reg_rc_roi.rc_dthd_0_8[2] = positive_bits_thd;
973     regs->reg_rc_roi.rc_dthd_0_8[3] = 4 * positive_bits_thd;
974     regs->reg_rc_roi.rc_dthd_0_8[4] = 0x7FFFFFFF;
975     regs->reg_rc_roi.rc_dthd_0_8[5] = 0x7FFFFFFF;
976     regs->reg_rc_roi.rc_dthd_0_8[6] = 0x7FFFFFFF;
977     regs->reg_rc_roi.rc_dthd_0_8[7] = 0x7FFFFFFF;
978     regs->reg_rc_roi.rc_dthd_0_8[8] = 0x7FFFFFFF;
979 
980     hal_h264e_dbg_func("leave\n");
981 }
982 
setup_vepu540c_io_buf(HalVepu540cRegSet * regs,MppDev dev,HalEncTask * task)983 static void setup_vepu540c_io_buf(HalVepu540cRegSet *regs, MppDev dev,
984                                   HalEncTask *task)
985 {
986     MppFrame frm = task->frame;
987     MppPacket pkt = task->packet;
988     MppBuffer buf_in = mpp_frame_get_buffer(frm);
989     MppBuffer buf_out = task->output;
990     MppFrameFormat fmt = mpp_frame_get_fmt(frm);
991     RK_S32 hor_stride = mpp_frame_get_hor_stride(frm);
992     RK_S32 ver_stride = mpp_frame_get_ver_stride(frm);
993     RK_S32 fd_in = mpp_buffer_get_fd(buf_in);
994     RK_U32 off_in[2] = {0};
995     RK_U32 off_out = mpp_packet_get_length(pkt);
996     size_t siz_out = mpp_buffer_get_size(buf_out);
997     RK_S32 fd_out = mpp_buffer_get_fd(buf_out);
998 
999     hal_h264e_dbg_func("enter\n");
1000 
1001     regs->reg_base.adr_src0   = fd_in;
1002     regs->reg_base.adr_src1   = fd_in;
1003     regs->reg_base.adr_src2   = fd_in;
1004 
1005     regs->reg_base.bsbt_addr  = fd_out;
1006     regs->reg_base.bsbb_addr  = fd_out;
1007     regs->reg_base.adr_bsbs   = fd_out;
1008     regs->reg_base.bsbr_addr  = fd_out;
1009     mpp_dev_set_reg_offset(dev, 172, siz_out);
1010     mpp_dev_set_reg_offset(dev, 174, off_out);
1011 
1012     regs->reg_base.rfpt_h_addr = 0xffffffff;
1013     regs->reg_base.rfpb_h_addr = 0;
1014     regs->reg_base.rfpt_b_addr = 0xffffffff;
1015     regs->reg_base.adr_rfpb_b  = 0;
1016     if (MPP_FRAME_FMT_IS_FBC(fmt)) {
1017         off_in[0] = mpp_frame_get_fbc_offset(frm);;
1018         off_in[1] = 0;
1019     } else if (MPP_FRAME_FMT_IS_YUV(fmt)) {
1020         VepuFmtCfg cfg;
1021 
1022         vepu5xx_set_fmt(&cfg, fmt);
1023         switch (cfg.format) {
1024         case VEPU5xx_FMT_BGRA8888 :
1025         case VEPU5xx_FMT_BGR888 :
1026         case VEPU5xx_FMT_BGR565 : {
1027             off_in[0] = 0;
1028             off_in[1] = 0;
1029         } break;
1030         case VEPU5xx_FMT_YUV420SP :
1031         case VEPU5xx_FMT_YUV422SP : {
1032             off_in[0] = hor_stride * ver_stride;
1033             off_in[1] = hor_stride * ver_stride;
1034         } break;
1035         case VEPU5xx_FMT_YUV422P : {
1036             off_in[0] = hor_stride * ver_stride;
1037             off_in[1] = hor_stride * ver_stride * 3 / 2;
1038         } break;
1039         case VEPU5xx_FMT_YUV420P : {
1040             off_in[0] = hor_stride * ver_stride;
1041             off_in[1] = hor_stride * ver_stride * 5 / 4;
1042         } break;
1043         case VEPU5xx_FMT_YUV400 :
1044         case VEPU5xx_FMT_YUYV422 :
1045         case VEPU5xx_FMT_UYVY422 : {
1046             off_in[0] = 0;
1047             off_in[1] = 0;
1048         } break;
1049         default : {
1050             off_in[0] = 0;
1051             off_in[1] = 0;
1052         } break;
1053         }
1054     }
1055 
1056     mpp_dev_set_reg_offset(dev, 161, off_in[0]);
1057     mpp_dev_set_reg_offset(dev, 162, off_in[1]);
1058 
1059     hal_h264e_dbg_func("leave\n");
1060 }
1061 
setup_vepu540c_recn_refr(HalH264eVepu540cCtx * ctx,HalVepu540cRegSet * regs)1062 static void setup_vepu540c_recn_refr(HalH264eVepu540cCtx *ctx, HalVepu540cRegSet *regs)
1063 {
1064 
1065     MppDev dev = ctx->dev;
1066     H264eFrmInfo *frms = ctx->frms;
1067     HalBufs bufs = ctx->hw_recn;
1068     RK_S32 fbc_hdr_size = ctx->pixel_buf_fbc_hdr_size;
1069 
1070     HalBuf *curr = hal_bufs_get_buf(bufs, frms->curr_idx);
1071     HalBuf *refr = hal_bufs_get_buf(bufs, frms->refr_idx);
1072 
1073     hal_h264e_dbg_func("enter\n");
1074 
1075     if (curr && curr->cnt) {
1076         MppBuffer buf_pixel = curr->buf[0];
1077         MppBuffer buf_thumb = curr->buf[1];
1078         RK_S32 fd = mpp_buffer_get_fd(buf_pixel);
1079 
1080         mpp_assert(buf_pixel);
1081         mpp_assert(buf_thumb);
1082 
1083         regs->reg_base.rfpw_h_addr = fd;
1084         regs->reg_base.rfpw_b_addr = fd;
1085         regs->reg_base.dspw_addr = mpp_buffer_get_fd(buf_thumb);
1086         mpp_dev_set_reg_offset(dev, 164, fbc_hdr_size);
1087     }
1088 
1089     if (refr && refr->cnt) {
1090         MppBuffer buf_pixel = refr->buf[0];
1091         MppBuffer buf_thumb = refr->buf[1];
1092         RK_S32 fd = mpp_buffer_get_fd(buf_pixel);
1093 
1094         mpp_assert(buf_pixel);
1095         mpp_assert(buf_thumb);
1096 
1097         regs->reg_base.rfpr_h_addr = fd;
1098         regs->reg_base.rfpr_b_addr = fd;
1099         regs->reg_base.dspr_addr = mpp_buffer_get_fd(buf_thumb);
1100         mpp_dev_set_reg_offset(dev, 166, fbc_hdr_size);
1101     }
1102     hal_h264e_dbg_func("leave\n");
1103 }
1104 
setup_vepu540c_split(HalVepu540cRegSet * regs,MppEncCfgSet * cfg)1105 static void setup_vepu540c_split(HalVepu540cRegSet *regs, MppEncCfgSet *cfg)
1106 {
1107     hal_h264e_dbg_func("enter\n");
1108 
1109     switch (cfg->split.split_mode) {
1110     case MPP_ENC_SPLIT_NONE : {
1111         regs->reg_base.sli_splt.sli_splt = 0;
1112         regs->reg_base.sli_splt.sli_splt_mode = 0;
1113         regs->reg_base.sli_splt.sli_splt_cpst = 0;
1114         regs->reg_base.sli_splt.sli_max_num_m1 = 0;
1115         regs->reg_base.sli_splt.sli_flsh = 0;
1116         regs->reg_base.sli_cnum.sli_splt_cnum_m1 = 0;
1117 
1118         regs->reg_base.sli_byte.sli_splt_byte = 0;
1119         regs->reg_base.enc_pic.slen_fifo = 0;
1120     } break;
1121     case MPP_ENC_SPLIT_BY_BYTE : {
1122         regs->reg_base.sli_splt.sli_splt = 1;
1123         regs->reg_base.sli_splt.sli_splt_mode = 0;
1124         regs->reg_base.sli_splt.sli_splt_cpst = 0;
1125         regs->reg_base.sli_splt.sli_max_num_m1 = 500;
1126         regs->reg_base.sli_splt.sli_flsh = 1;
1127         regs->reg_base.sli_cnum.sli_splt_cnum_m1 = 0;
1128 
1129         regs->reg_base.sli_byte.sli_splt_byte = cfg->split.split_arg;
1130         regs->reg_base.enc_pic.slen_fifo = 0;
1131         regs->reg_base.enc_pic.slen_fifo = cfg->split.split_out ? 1 : 0;
1132         regs->reg_ctl.int_en.vslc_done_en = regs->reg_base.enc_pic.slen_fifo;
1133     } break;
1134     case MPP_ENC_SPLIT_BY_CTU : {
1135         RK_U32 mb_w = MPP_ALIGN(cfg->prep.width, 16) / 16;
1136         RK_U32 mb_h = MPP_ALIGN(cfg->prep.height, 16) / 16;
1137         RK_U32 slice_num = (mb_w * mb_h + cfg->split.split_arg - 1) / cfg->split.split_arg;
1138 
1139         regs->reg_base.sli_splt.sli_splt = 1;
1140         regs->reg_base.sli_splt.sli_splt_mode = 1;
1141         regs->reg_base.sli_splt.sli_splt_cpst = 0;
1142         regs->reg_base.sli_splt.sli_max_num_m1 = 500;
1143         regs->reg_base.sli_splt.sli_flsh = 1;
1144         regs->reg_base.sli_cnum.sli_splt_cnum_m1 = cfg->split.split_arg - 1;
1145 
1146         regs->reg_base.sli_byte.sli_splt_byte = 0;
1147         regs->reg_base.enc_pic.slen_fifo = cfg->split.split_out ? 1 : 0;
1148         if ((cfg->split.split_out & MPP_ENC_SPLIT_OUT_LOWDELAY) ||
1149             (regs->reg_base.enc_pic.slen_fifo && (slice_num > VEPU540C_SLICE_FIFO_LEN)))
1150             regs->reg_ctl.int_en.vslc_done_en = 1;
1151     } break;
1152     default : {
1153         mpp_log_f("invalide slice split mode %d\n", cfg->split.split_mode);
1154     } break;
1155     }
1156 
1157     hal_h264e_dbg_func("leave\n");
1158 }
1159 
calc_cime_parameter(HalVepu540cRegSet * regs)1160 static void calc_cime_parameter(HalVepu540cRegSet *regs)
1161 {
1162     Vepu540cBaseCfg *base_regs = &regs->reg_base;
1163     RK_S32 x_gmv = 0;
1164     RK_S32 y_gmv = 0;
1165     RK_S32 srch_lftw , srch_rgtw, srch_uph, srch_dwnh;
1166     RK_S32 frm_sta = 0, frm_end = 0, pic_w = 0;
1167     RK_S32 pic_wdt_align =  ((base_regs->enc_rsl.pic_wd8_m1 + 1) * 8 + 63) / 64 * 2;
1168 
1169 
1170     srch_lftw = base_regs->me_rnge.cime_srch_lftw * 4;
1171     srch_rgtw = base_regs->me_rnge.cime_srch_rgtw * 4;
1172     srch_uph = base_regs->me_rnge.cime_srch_uph * 2;
1173     srch_dwnh =  base_regs->me_rnge.cime_srch_dwnh * 2;
1174 
1175     // calc cime_linebuf_w
1176     {
1177         {
1178             if (x_gmv - srch_lftw < 0) {
1179                 frm_sta = 0;
1180             } else {
1181                 frm_sta = (x_gmv - srch_lftw) / 16;
1182             }
1183             if (x_gmv + srch_rgtw < 0) {
1184                 frm_end = pic_wdt_align - 1 + (x_gmv + srch_rgtw) / 16;
1185             } else {
1186                 frm_end = pic_wdt_align - 1 + (x_gmv + srch_rgtw + 15) / 16;
1187             }
1188         }
1189         if (frm_sta < 0) {
1190             frm_sta = 0;
1191         } else if (frm_sta > pic_wdt_align - 1) {
1192             frm_sta = pic_wdt_align - 1;
1193         }
1194         frm_end = mpp_clip(frm_end, 0, pic_wdt_align - 1);
1195         pic_w = (frm_end - frm_sta + 1) * 32;
1196         base_regs->me_cach.cme_linebuf_w = pic_w / 32;
1197     }
1198 
1199     // calc cime_rama_h and cime_rama_max
1200     {
1201         RK_U32 rama_size = 1796;
1202         RK_U32 ramb_h;
1203         RK_U32 ctu_2_h = 2;
1204         RK_U32 cur_srch_8_w, cur_srch_2_h, cur_srch_h;
1205 
1206 
1207         if ((y_gmv % 4 - srch_uph % 4) < 0) {
1208             cur_srch_2_h = (4 + (y_gmv % 4 - srch_uph % 4) % 4 + srch_uph + srch_dwnh) / 2 + ctu_2_h;
1209         } else {
1210             cur_srch_2_h = ((y_gmv % 4 - srch_uph % 4) % 4 + srch_uph + srch_dwnh) / 2 + ctu_2_h;
1211         }
1212         base_regs->me_cach.cime_size_rama = (cur_srch_2_h + 1) / 2 * 2;
1213 
1214         if ((x_gmv % 16 - srch_lftw % 16) < 0) {
1215             cur_srch_8_w = ((16 + (x_gmv % 16 - srch_lftw % 16) % 16 + srch_lftw + srch_rgtw + 15) / 16 + 1) * 2;
1216         } else {
1217             cur_srch_8_w = (((x_gmv % 16 - srch_lftw % 16) % 16 + srch_lftw + srch_rgtw + 15) / 16 + 1) * 2;
1218         }
1219 
1220         cur_srch_h = ctu_2_h;
1221         ramb_h = cur_srch_2_h;
1222         while ((rama_size > ((cur_srch_h - ctu_2_h) * base_regs->me_cach.cme_linebuf_w + (ramb_h * cur_srch_8_w)))
1223                && (cur_srch_h < base_regs->me_cach.cime_size_rama)) {
1224             cur_srch_h = cur_srch_h + ctu_2_h;
1225             if (ramb_h > ctu_2_h * 2) {
1226                 ramb_h = ramb_h - ctu_2_h;
1227             } else {
1228                 ramb_h = ctu_2_h;
1229             }
1230         }
1231 
1232         if (cur_srch_2_h == ctu_2_h * 2) {
1233             cur_srch_h = cur_srch_h + ctu_2_h;
1234             ramb_h = ctu_2_h;
1235         }
1236         if (rama_size < ((cur_srch_h - ctu_2_h) * base_regs->me_cach.cme_linebuf_w + (ramb_h * cur_srch_8_w))) {
1237             cur_srch_h = cur_srch_h - ctu_2_h;
1238         }
1239         base_regs->me_cach.cime_size_rama = ((cur_srch_h - ctu_2_h) * base_regs->me_cach.cme_linebuf_w + ctu_2_h * cur_srch_8_w) / 2;
1240         base_regs->me_cach.cime_hgt_rama = cur_srch_h / 2;
1241     }
1242 
1243 }
1244 
setup_vepu540c_me(HalVepu540cRegSet * regs,H264eSps * sps,H264eSlice * slice)1245 static void setup_vepu540c_me(HalVepu540cRegSet *regs, H264eSps *sps,
1246                               H264eSlice *slice)
1247 {
1248     (void)sps;
1249     (void)slice;
1250     regs->reg_base.me_rnge.cime_srch_dwnh = 15;
1251     regs->reg_base.me_rnge.cime_srch_uph = 14;
1252     regs->reg_base.me_rnge.cime_srch_rgtw = 12;
1253     regs->reg_base.me_rnge.cime_srch_lftw = 12;
1254     regs->reg_base.me_cfg.rme_srch_h    = 3;
1255     regs->reg_base.me_cfg.rme_srch_v    = 3;
1256 
1257     regs->reg_base.me_cfg.srgn_max_num    = 72;
1258     regs->reg_base.me_cfg.cime_dist_thre    = 1024;
1259     regs->reg_base.me_cfg.rme_dis      = 0;
1260     regs->reg_base.me_cfg.fme_dis        = 0;
1261     regs->reg_base.me_rnge.dlt_frm_num    = 0x0;
1262     calc_cime_parameter(regs);
1263     hal_h264e_dbg_func("leave\n");
1264 }
1265 
1266 #define H264E_LAMBDA_TAB_SIZE       (52 * sizeof(RK_U32))
1267 
1268 static RK_U32 h264e_lambda_default[58] = {
1269     0x00000003, 0x00000005, 0x00000006, 0x00000007,
1270     0x00000009, 0x0000000b, 0x0000000e, 0x00000012,
1271     0x00000016, 0x0000001c, 0x00000024, 0x0000002d,
1272     0x00000039, 0x00000048, 0x0000005b, 0x00000073,
1273     0x00000091, 0x000000b6, 0x000000e6, 0x00000122,
1274     0x0000016d, 0x000001cc, 0x00000244, 0x000002db,
1275     0x00000399, 0x00000489, 0x000005b6, 0x00000733,
1276     0x00000912, 0x00000b6d, 0x00000e66, 0x00001224,
1277     0x000016db, 0x00001ccc, 0x00002449, 0x00002db7,
1278     0x00003999, 0x00004892, 0x00005b6f, 0x00007333,
1279     0x00009124, 0x0000b6de, 0x0000e666, 0x00012249,
1280     0x00016dbc, 0x0001cccc, 0x00024492, 0x0002db79,
1281     0x00039999, 0x00048924, 0x0005b6f2, 0x00073333,
1282     0x00091249, 0x000b6de5, 0x000e6666, 0x00122492,
1283     0x0016dbcb, 0x001ccccc,
1284 };
1285 
setup_vepu540c_l2(HalVepu540cRegSet * regs,H264eSlice * slice,MppEncHwCfg * hw)1286 static void setup_vepu540c_l2(HalVepu540cRegSet *regs, H264eSlice *slice, MppEncHwCfg *hw)
1287 {
1288     RK_U32 i;
1289 
1290     hal_h264e_dbg_func("enter\n");
1291 
1292     memcpy(regs->reg_s3.rdo_wgta_qp_grpa_0_51, &h264e_lambda_default[6], H264E_LAMBDA_TAB_SIZE);
1293 
1294     if (hw->qbias_en) {
1295         regs->reg_s3.RDO_QUANT.quant_f_bias_I = hw->qbias_i;
1296         regs->reg_s3.RDO_QUANT.quant_f_bias_P = hw->qbias_p;
1297     } else {
1298         regs->reg_s3.RDO_QUANT.quant_f_bias_I = 683;
1299         regs->reg_s3.RDO_QUANT.quant_f_bias_P = 341;
1300     }
1301     regs->reg_s3.iprd_tthdy4_0.iprd_tthdy4_0 = 1;
1302     regs->reg_s3.iprd_tthdy4_0.iprd_tthdy4_1 = 3;
1303     regs->reg_s3.iprd_tthdy4_1.iprd_tthdy4_2 = 6;
1304     regs->reg_s3.iprd_tthdy4_1.iprd_tthdy4_3 = 8;
1305     regs->reg_s3.iprd_tthdc8_0.iprd_tthdc8_0 = 1;
1306     regs->reg_s3.iprd_tthdc8_0.iprd_tthdc8_1 = 3;
1307     regs->reg_s3.iprd_tthdc8_1.iprd_tthdc8_2 = 6;
1308     regs->reg_s3.iprd_tthdc8_1.iprd_tthdc8_3 = 8;
1309     regs->reg_s3.iprd_tthdy8_0.iprd_tthdy8_0 = 1;
1310     regs->reg_s3.iprd_tthdy8_0.iprd_tthdy8_1 = 3;
1311     regs->reg_s3.iprd_tthdy8_1.iprd_tthdy8_2 = 6;
1312     regs->reg_s3.iprd_tthdy8_1.iprd_tthdy8_3 = 8;
1313     regs->reg_s3.iprd_tthd_ul.iprd_tthd_ul = 4;
1314     regs->reg_s3.iprd_wgty8.iprd_wgty8_0 = 22;
1315     regs->reg_s3.iprd_wgty8.iprd_wgty8_1 = 23;
1316     regs->reg_s3.iprd_wgty8.iprd_wgty8_2 = 20;
1317     regs->reg_s3.iprd_wgty8.iprd_wgty8_3 = 22;
1318     regs->reg_s3.iprd_wgty4.iprd_wgty4_0 = 22;
1319     regs->reg_s3.iprd_wgty4.iprd_wgty4_1 = 26;
1320     regs->reg_s3.iprd_wgty4.iprd_wgty4_2 = 20;
1321     regs->reg_s3.iprd_wgty4.iprd_wgty4_3 = 22;
1322     regs->reg_s3.iprd_wgty16.iprd_wgty16_0 = 22;
1323     regs->reg_s3.iprd_wgty16.iprd_wgty16_1 = 26;
1324     regs->reg_s3.iprd_wgty16.iprd_wgty16_2 = 20;
1325     regs->reg_s3.iprd_wgty16.iprd_wgty16_3 = 22;
1326     regs->reg_s3.iprd_wgtc8.iprd_wgtc8_0 = 18;
1327     regs->reg_s3.iprd_wgtc8.iprd_wgtc8_1 = 21;
1328     regs->reg_s3.iprd_wgtc8.iprd_wgtc8_2 = 20;
1329     regs->reg_s3.iprd_wgtc8.iprd_wgtc8_3 = 19;
1330 
1331 
1332     if (slice->slice_type == H264_I_SLICE) {
1333         regs->reg_s3.ATR_THD0.atr_thd0 = 1;
1334         regs->reg_s3.ATR_THD0.atr_thd1 = 2;
1335         regs->reg_s3.ATR_THD1.atr_thd2 = 6;
1336     } else {
1337         regs->reg_s3.ATR_THD0.atr_thd0 = 2;
1338         regs->reg_s3.ATR_THD0.atr_thd1 = 4;
1339         regs->reg_s3.ATR_THD1.atr_thd2 = 9;
1340     }
1341     regs->reg_s3.ATR_THD1.atr_thdqp = 32;
1342 
1343     if (slice->slice_type == H264_I_SLICE) {
1344         regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt0 = 16;
1345         regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt1 = 16;
1346         regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt2 = 16;
1347 
1348         regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt0 = 22;
1349         regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt1 = 21;
1350         regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt2 = 20;
1351 
1352         regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt0 = 20;
1353         regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt1 = 18;
1354         regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt2 = 16;
1355     } else {
1356         regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt0 = 25;
1357         regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt1 = 20;
1358         regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt2 = 16;
1359 
1360         regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt0 = 25;
1361         regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt1 = 20;
1362         regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt2 = 18;
1363 
1364         regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt0 = 25;
1365         regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt1 = 20;
1366         regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt2 = 16;
1367     }
1368     /* CIME */
1369     {
1370         /* 0x1760 */
1371         regs->reg_s3.cime_sqi_cfg.cime_pmv_num = 1;
1372         regs->reg_s3.cime_sqi_cfg.cime_fuse   = 1;
1373         regs->reg_s3.cime_sqi_cfg.itp_mode    = 0;
1374         regs->reg_s3.cime_sqi_cfg.move_lambda = 0;
1375         regs->reg_s3.cime_sqi_cfg.rime_lvl_mrg     = 0;
1376         regs->reg_s3.cime_sqi_cfg.rime_prelvl_en   = 0;
1377         regs->reg_s3.cime_sqi_cfg.rime_prersu_en   = 0;
1378 
1379         /* 0x1764 */
1380         regs->reg_s3.cime_mvd_th.cime_mvd_th0 = 16;
1381         regs->reg_s3.cime_mvd_th.cime_mvd_th1 = 48;
1382         regs->reg_s3.cime_mvd_th.cime_mvd_th2 = 80;
1383 
1384         /* 0x1768 */
1385         regs->reg_s3.cime_madp_th.cime_madp_th = 16;
1386 
1387         /* 0x176c */
1388         regs->reg_s3.cime_multi.cime_multi0 = 8;
1389         regs->reg_s3.cime_multi.cime_multi1 = 12;
1390         regs->reg_s3.cime_multi.cime_multi2 = 16;
1391         regs->reg_s3.cime_multi.cime_multi3 = 20;
1392     }
1393 
1394     /* RIME && FME */
1395     {
1396         /* 0x1770 */
1397         regs->reg_s3.rime_mvd_th.rime_mvd_th0  = 1;
1398         regs->reg_s3.rime_mvd_th.rime_mvd_th1  = 2;
1399         regs->reg_s3.rime_mvd_th.fme_madp_th   = 0;
1400 
1401         /* 0x1774 */
1402         regs->reg_s3.rime_madp_th.rime_madp_th0 = 8;
1403         regs->reg_s3.rime_madp_th.rime_madp_th1 = 16;
1404 
1405         /* 0x1778 */
1406         regs->reg_s3.rime_multi.rime_multi0 = 4;
1407         regs->reg_s3.rime_multi.rime_multi1 = 8;
1408         regs->reg_s3.rime_multi.rime_multi2 = 12;
1409 
1410         /* 0x177C */
1411         regs->reg_s3.cmv_st_th.cmv_th0 = 64;
1412         regs->reg_s3.cmv_st_th.cmv_th1 = 96;
1413         regs->reg_s3.cmv_st_th.cmv_th2 = 128;
1414     }
1415     /* madi and madp */
1416     {
1417         /* 0x1064 */
1418         regs->reg_rc_roi.madi_st_thd.madi_th0 = 5;
1419         regs->reg_rc_roi.madi_st_thd.madi_th1 = 12;
1420         regs->reg_rc_roi.madi_st_thd.madi_th2 = 20;
1421         /* 0x1068 */
1422         regs->reg_rc_roi.madp_st_thd0.madp_th0 = 4 << 4;
1423         regs->reg_rc_roi.madp_st_thd0.madp_th1 = 9 << 4;
1424         /* 0x106C */
1425         regs->reg_rc_roi.madp_st_thd1.madp_th2 = 15 << 4;
1426     }
1427 
1428     if (slice->slice_type == H264_I_SLICE) {
1429         for (i = 0; i < MPP_ARRAY_ELEMS(h264_aq_tthd_default); i++) {
1430             regs->reg_rc_roi.aq_tthd[i] = hw->aq_thrd_i[i];
1431             regs->reg_rc_roi.aq_step[i] = hw->aq_step_i[i] & 0x3f;
1432         }
1433     } else {
1434         for (i = 0; i < MPP_ARRAY_ELEMS(h264_P_aq_step_default); i++) {
1435             regs->reg_rc_roi.aq_tthd[i] = hw->aq_thrd_p[i];
1436             regs->reg_rc_roi.aq_step[i] = hw->aq_step_p[i] & 0x3f;
1437         }
1438     }
1439 
1440     hal_h264e_dbg_func("leave\n");
1441 }
1442 
setup_vepu540c_ext_line_buf(HalVepu540cRegSet * regs,HalH264eVepu540cCtx * ctx)1443 static void setup_vepu540c_ext_line_buf(HalVepu540cRegSet *regs, HalH264eVepu540cCtx *ctx)
1444 {
1445     if (ctx->ext_line_buf) {
1446         RK_S32 fd = mpp_buffer_get_fd(ctx->ext_line_buf);
1447 
1448         regs->reg_base.ebuft_addr = fd;
1449         regs->reg_base.ebufb_addr = fd;
1450 
1451         mpp_dev_set_reg_offset(ctx->dev, 178, ctx->ext_line_buf_size);
1452     } else {
1453         regs->reg_base.ebuft_addr = 0;
1454         regs->reg_base.ebufb_addr = 0;
1455     }
1456 }
1457 
hal_h264e_vepu540c_gen_regs(void * hal,HalEncTask * task)1458 static MPP_RET hal_h264e_vepu540c_gen_regs(void *hal, HalEncTask *task)
1459 {
1460     HalH264eVepu540cCtx *ctx = (HalH264eVepu540cCtx *)hal;
1461     HalVepu540cRegSet *regs = ctx->regs_set;
1462     MppEncCfgSet *cfg = ctx->cfg;
1463     H264eSps *sps = ctx->sps;
1464     H264ePps *pps = ctx->pps;
1465     H264eSlice *slice = ctx->slice;
1466     MPP_RET ret = MPP_OK;
1467 
1468     hal_h264e_dbg_func("enter %p\n", hal);
1469     hal_h264e_dbg_detail("frame %d generate regs now", ctx->frms->seq_idx);
1470 
1471     /* register setup */
1472     memset(regs, 0, sizeof(*regs));
1473 
1474     setup_vepu540c_normal(regs);
1475     ret = setup_vepu540c_prep(regs, &ctx->cfg->prep);
1476     if (ret)
1477         return ret;
1478 
1479     setup_vepu540c_codec(regs, sps, pps, slice);
1480     setup_vepu540c_rdo_pred(regs, sps, pps, slice);
1481     setup_vepu540c_rdo_cfg(&regs->reg_rdo);
1482 
1483     // scl cfg
1484     memcpy(&regs->reg_scl.q_intra_y8, vepu580_540_h264_flat_scl_tab, sizeof(vepu580_540_h264_flat_scl_tab));
1485 
1486     setup_vepu540c_rc_base(regs, ctx, task->rc_task);
1487     setup_vepu540c_io_buf(regs, ctx->dev, task);
1488     setup_vepu540c_recn_refr(ctx, regs);
1489 
1490     regs->reg_base.meiw_addr = task->md_info ? mpp_buffer_get_fd(task->md_info) : 0;
1491 
1492     regs->reg_base.pic_ofst.pic_ofst_y = mpp_frame_get_offset_y(task->frame);
1493     regs->reg_base.pic_ofst.pic_ofst_x = mpp_frame_get_offset_x(task->frame);
1494 
1495     setup_vepu540c_split(regs, cfg);
1496     setup_vepu540c_me(regs, sps, slice);
1497 
1498     setup_vepu540c_l2(ctx->regs_set, slice, &cfg->hw);
1499     setup_vepu540c_ext_line_buf(regs, ctx);
1500 
1501     if (ctx->roi_data)
1502         vepu540c_set_roi(&ctx->regs_set->reg_rc_roi.roi_cfg, ctx->roi_data,
1503                          ctx->cfg->prep.width, ctx->cfg->prep.height);
1504 
1505     ctx->frame_cnt++;
1506 
1507     hal_h264e_dbg_func("leave %p\n", hal);
1508     return MPP_OK;
1509 }
1510 
hal_h264e_vepu540c_start(void * hal,HalEncTask * task)1511 static MPP_RET hal_h264e_vepu540c_start(void *hal, HalEncTask *task)
1512 {
1513     MPP_RET ret = MPP_OK;
1514     HalH264eVepu540cCtx *ctx = (HalH264eVepu540cCtx *)hal;
1515 
1516     (void) task;
1517 
1518     hal_h264e_dbg_func("enter %p\n", hal);
1519 
1520     do {
1521         MppDevRegWrCfg wr_cfg;
1522         MppDevRegRdCfg rd_cfg;
1523 
1524         wr_cfg.reg = &ctx->regs_set->reg_ctl;
1525         wr_cfg.size = sizeof(ctx->regs_set->reg_ctl);
1526         wr_cfg.offset = VEPU540C_CTL_OFFSET;
1527 #if DUMP_REG
1528         {
1529             RK_U32 i;
1530             RK_U32 *reg = (RK_U32)wr_cfg.reg;
1531             for ( i = 0; i < sizeof(ctx->regs_set->reg_ctl) / sizeof(RK_U32); i++) {
1532                 /* code */
1533                 mpp_log("reg[%d] = 0x%08x\n", i, reg[i]);
1534             }
1535 
1536         }
1537 #endif
1538         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
1539         if (ret) {
1540             mpp_err_f("set register write failed %d\n", ret);
1541             break;
1542         }
1543         wr_cfg.reg = &ctx->regs_set->reg_base;
1544         wr_cfg.size = sizeof(ctx->regs_set->reg_base);
1545         wr_cfg.offset = VEPU540C_BASE_OFFSET;
1546 
1547         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
1548         if (ret) {
1549             mpp_err_f("set register write failed %d\n", ret);
1550             break;
1551         }
1552         wr_cfg.reg = &ctx->regs_set->reg_rc_roi;
1553         wr_cfg.size = sizeof(ctx->regs_set->reg_rc_roi);
1554         wr_cfg.offset = VEPU540C_RCROI_OFFSET;
1555 
1556         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
1557         if (ret) {
1558             mpp_err_f("set register write failed %d\n", ret);
1559             break;
1560         }
1561         wr_cfg.reg = &ctx->regs_set->reg_s3;
1562         wr_cfg.size = sizeof(ctx->regs_set->reg_s3);
1563         wr_cfg.offset = VEPU540C_WEG_OFFSET;
1564 
1565         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
1566         if (ret) {
1567             mpp_err_f("set register write failed %d\n", ret);
1568             break;
1569         }
1570         wr_cfg.reg = &ctx->regs_set->reg_rdo;
1571         wr_cfg.size = sizeof(ctx->regs_set->reg_rdo);
1572         wr_cfg.offset = VEPU540C_RDOCFG_OFFSET;
1573 
1574         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
1575         if (ret) {
1576             mpp_err_f("set register write failed %d\n", ret);
1577             break;
1578         }
1579 
1580         wr_cfg.reg = &ctx->regs_set->reg_scl;
1581         wr_cfg.size = sizeof(ctx->regs_set->reg_scl);
1582         wr_cfg.offset = VEPU540C_SCLCFG_OFFSET;
1583 
1584         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
1585         if (ret) {
1586             mpp_err_f("set register write failed %d\n", ret);
1587             break;
1588         }
1589 
1590         rd_cfg.reg = &ctx->regs_set->reg_st;
1591         rd_cfg.size = sizeof(ctx->regs_set->reg_st);
1592         rd_cfg.offset = VEPU540C_STATUS_OFFSET;
1593 
1594         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
1595         if (ret) {
1596             mpp_err_f("set register read failed %d\n", ret);
1597             break;
1598         }
1599         /* send request to hardware */
1600         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
1601 
1602         if (ret) {
1603             mpp_err_f("send cmd failed %d\n", ret);
1604             break;
1605         }
1606     } while (0);
1607 
1608     hal_h264e_dbg_func("leave %p\n", hal);
1609 
1610     return ret;
1611 }
1612 
hal_h264e_vepu540c_status_check(void * hal)1613 static MPP_RET hal_h264e_vepu540c_status_check(void *hal)
1614 {
1615     HalH264eVepu540cCtx *ctx = (HalH264eVepu540cCtx *)hal;
1616     HalVepu540cRegSet *regs_set = ctx->regs_set;
1617 
1618     if (regs_set->reg_ctl.int_sta.lkt_node_done_sta)
1619         hal_h264e_dbg_detail("lkt_done finish");
1620 
1621     if (regs_set->reg_ctl.int_sta.enc_done_sta)
1622         hal_h264e_dbg_detail("enc_done finish");
1623 
1624     if (regs_set->reg_ctl.int_sta.vslc_done_sta)
1625         hal_h264e_dbg_detail("enc_slice finsh");
1626 
1627     if (regs_set->reg_ctl.int_sta.sclr_done_sta)
1628         hal_h264e_dbg_detail("safe clear finsh");
1629 
1630     if (regs_set->reg_ctl.int_sta.vbsf_oflw_sta)
1631         mpp_err_f("bit stream overflow");
1632 
1633     if (regs_set->reg_ctl.int_sta.vbuf_lens_sta)
1634         mpp_err_f("bus write full");
1635 
1636     if (regs_set->reg_ctl.int_sta.enc_err_sta)
1637         mpp_err_f("bus error");
1638 
1639     if (regs_set->reg_ctl.int_sta.wdg_sta)
1640         mpp_err_f("wdg timeout");
1641 
1642     return MPP_OK;
1643 }
1644 
hal_h264e_vepu540c_wait(void * hal,HalEncTask * task)1645 static MPP_RET hal_h264e_vepu540c_wait(void *hal, HalEncTask *task)
1646 {
1647     MPP_RET ret = MPP_OK;
1648     HalH264eVepu540cCtx *ctx = (HalH264eVepu540cCtx *)hal;
1649     HalVepu540cRegSet *regs_set = ctx->regs_set;
1650     H264NaluType type = task->rc_task->frm.is_idr ?  H264_NALU_TYPE_IDR : H264_NALU_TYPE_SLICE;
1651     MppPacket pkt = task->packet;
1652     RK_S32 offset = mpp_packet_get_length(pkt);
1653 
1654     hal_h264e_dbg_func("enter %p\n", hal);
1655     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
1656     if (ret) {
1657         mpp_err_f("poll cmd failed %d\n", ret);
1658         ret = MPP_ERR_VPUHW;
1659     } else {
1660         hal_h264e_vepu540c_status_check(hal);
1661         task->hw_length += regs_set->reg_st.bs_lgth_l32;
1662     }
1663 
1664     mpp_packet_add_segment_info(pkt, type, offset, regs_set->reg_st.bs_lgth_l32);
1665 
1666     {
1667         HalH264eVepuStreamAmend *amend = &ctx->amend;
1668 
1669         if (amend->enable) {
1670             amend->old_length = task->hw_length;
1671             amend->slice->is_multi_slice = (ctx->cfg->split.split_mode > 0);
1672             h264e_vepu_stream_amend_proc(amend, &ctx->cfg->h264.hw_cfg);
1673             task->hw_length = amend->new_length;
1674         } else if (amend->prefix) {
1675             /* check prefix value */
1676             amend->old_length = task->hw_length;
1677             h264e_vepu_stream_amend_sync_ref_idc(amend);
1678         }
1679     }
1680 
1681     hal_h264e_dbg_func("leave %p\n", hal);
1682 
1683     return ret;
1684 }
1685 
hal_h264e_vepu540c_ret_task(void * hal,HalEncTask * task)1686 static MPP_RET hal_h264e_vepu540c_ret_task(void *hal, HalEncTask *task)
1687 {
1688     HalH264eVepu540cCtx *ctx = (HalH264eVepu540cCtx *)hal;
1689     EncRcTaskInfo *rc_info = &task->rc_task->info;
1690     RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
1691     RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
1692     RK_U32 mbs = mb_w * mb_h;
1693     HalVepu540cRegSet *regs_set = (HalVepu540cRegSet *)ctx->regs_set;
1694     hal_h264e_dbg_func("enter %p\n", hal);
1695 
1696     // update total hardware length
1697     task->length += task->hw_length;
1698 
1699     // setup bit length for rate control
1700     rc_info->bit_real = task->hw_length * 8;
1701     rc_info->quality_real = regs_set->reg_st.qp_sum / mbs;
1702     /*
1703         rc_info->madi = (!regs_set->reg_st.st_bnum_b16.num_b16) ? 0 :
1704                         regs_set->reg_st.madi /  regs_set->reg_st.st_bnum_b16.num_b16;
1705         rc_info->madp = (!regs_set->reg_st.st_bnum_cme.num_ctu) ? 0 :
1706                         regs_set->reg_st.madi / regs_set->reg_st.st_bnum_cme.num_ctu;*/
1707 
1708     rc_info->iblk4_prop = (regs_set->reg_st.st_pnum_i4.pnum_i4 +
1709                            regs_set->reg_st.st_pnum_i8.pnum_i8 +
1710                            regs_set->reg_st.st_pnum_i16.pnum_i16) * 256 / mbs;
1711 
1712     rc_info->sse = ((RK_S64)regs_set->reg_st.sse_h32 << 16) +
1713                    (regs_set->reg_st.st_sse_bsl.sse_l16 & 0xffff);
1714     rc_info->lvl16_inter_num = regs_set->reg_st.st_pnum_p16.pnum_p16;
1715     rc_info->lvl8_inter_num  = regs_set->reg_st.st_pnum_p8.pnum_p8;
1716     rc_info->lvl16_intra_num = regs_set->reg_st.st_pnum_i16.pnum_i16;
1717     rc_info->lvl8_intra_num  = regs_set->reg_st.st_pnum_i8.pnum_i8;
1718     rc_info->lvl4_intra_num  = regs_set->reg_st.st_pnum_i4.pnum_i4;
1719 
1720     ctx->hal_rc_cfg.bit_real = rc_info->bit_real;
1721     ctx->hal_rc_cfg.quality_real = rc_info->quality_real;
1722     ctx->hal_rc_cfg.iblk4_prop = rc_info->iblk4_prop;
1723 
1724     task->hal_ret.data   = &ctx->hal_rc_cfg;
1725     task->hal_ret.number = 1;
1726 
1727     hal_h264e_dbg_func("leave %p\n", hal);
1728 
1729     return MPP_OK;
1730 }
1731 
1732 const MppEncHalApi hal_h264e_vepu540c = {
1733     .name       = "hal_h264e_vepu540c",
1734     .coding     = MPP_VIDEO_CodingAVC,
1735     .ctx_size   = sizeof(HalH264eVepu540cCtx),
1736     .flag       = 0,
1737     .init       = hal_h264e_vepu540c_init,
1738     .deinit     = hal_h264e_vepu540c_deinit,
1739     .prepare    = hal_h264e_vepu540c_prepare,
1740     .get_task   = hal_h264e_vepu540c_get_task,
1741     .gen_regs   = hal_h264e_vepu540c_gen_regs,
1742     .start      = hal_h264e_vepu540c_start,
1743     .wait       = hal_h264e_vepu540c_wait,
1744     .part_start = NULL,
1745     .part_wait  = NULL,
1746     .ret_task   = hal_h264e_vepu540c_ret_task,
1747 };
1748