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 = ®->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 = ®->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 = ®->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 = ®s->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(®s->reg_rdo);
1482
1483 // scl cfg
1484 memcpy(®s->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