1 /*
2 * Copyright 2015 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_vepu541"
18
19 #include <string.h>
20
21 #include "mpp_env.h"
22 #include "mpp_mem.h"
23 #include "mpp_soc.h"
24 #include "mpp_frame.h"
25 #include "mpp_common.h"
26 #include "mpp_device.h"
27 #include "mpp_frame_impl.h"
28 #include "mpp_rc.h"
29 #include "mpp_packet_impl.h"
30
31 #include "hal_h264e_debug.h"
32 #include "h264e_sps.h"
33 #include "h264e_pps.h"
34 #include "h264e_slice.h"
35
36 #include "hal_bufs.h"
37 #include "hal_h264e_vepu541.h"
38 #include "hal_h264e_vepu541_reg.h"
39 #include "hal_h264e_vepu541_reg_l2.h"
40 #include "hal_h264e_stream_amend.h"
41 #include "vepu541_common.h"
42 #include "vepu5xx_common.h"
43
44 typedef struct HalH264eVepu541Ctx_t {
45 MppEncCfgSet *cfg;
46
47 MppDev dev;
48 RK_U32 is_vepu540;
49 RK_S32 frame_cnt;
50
51 /* buffers management */
52 HalBufs hw_recn;
53 RK_S32 pixel_buf_fbc_hdr_size;
54 RK_S32 pixel_buf_fbc_bdy_size;
55 RK_S32 pixel_buf_size;
56 RK_S32 thumb_buf_size;
57 RK_S32 max_buf_cnt;
58
59 /* syntax for input from enc_impl */
60 RK_U32 updated;
61 H264eSps *sps;
62 H264ePps *pps;
63 H264eSlice *slice;
64 H264eFrmInfo *frms;
65 H264eReorderInfo *reorder;
66 H264eMarkingInfo *marking;
67 H264ePrefixNal *prefix;
68 HalH264eVepuStreamAmend amend;
69
70 /* syntax for output to enc_impl */
71 EncRcTaskInfo hal_rc_cfg;
72
73 /* roi */
74 MppEncROICfg *roi_data;
75 MppEncROICfg2 *roi_data2;
76 MppBufferGroup roi_grp;
77 MppBuffer roi_buf;
78 RK_S32 roi_buf_size;
79 MppBuffer qpmap;
80
81 /* osd */
82 Vepu5xxOsdCfg osd_cfg;
83
84 /* register */
85 Vepu541H264eRegSet regs_set;
86 Vepu541H264eRegL2Set regs_l2_set;
87 Vepu541H264eRegRet regs_ret;
88 } HalH264eVepu541Ctx;
89
90 #define CHROMA_KLUT_TAB_SIZE (24 * sizeof(RK_U32))
91
92 static RK_U32 h264e_klut_weight[30] = {
93 0x0a000010, 0x00064000, 0x14000020, 0x000c8000,
94 0x28000040, 0x00194000, 0x50800080, 0x0032c000,
95 0xa1000100, 0x00658000, 0x42800200, 0x00cb0001,
96 0x85000400, 0x01964002, 0x0a000800, 0x032c8005,
97 0x14001000, 0x0659400a, 0x28802000, 0x0cb2c014,
98 0x51004000, 0x1965c028, 0xa2808000, 0x32cbc050,
99 0x4500ffff, 0x659780a1, 0x8a81fffe, 0xCC000142,
100 0xFF83FFFF, 0x000001FF,
101 };
102
103 static RK_U32 dump_l1_reg = 0;
104 static RK_U32 dump_l2_reg = 0;
105
106 static RK_S32 h264_aq_tthd_default[16] = {
107 0, 0, 0, 0,
108 3, 3, 5, 5,
109 8, 8, 8, 15,
110 15, 20, 25, 25,
111 };
112
113 static RK_S32 h264_P_aq_step_default[16] = {
114 -8, -7, -6, -5,
115 -4, -3, -2, -1,
116 0, 1, 2, 3,
117 4, 5, 7, 8,
118 };
119
120 static RK_S32 h264_I_aq_step_default[16] = {
121 -8, -7, -6, -5,
122 -4, -3, -2, -1,
123 0, 1, 3, 3,
124 4, 5, 8, 8,
125 };
126
hal_h264e_vepu541_deinit(void * hal)127 static MPP_RET hal_h264e_vepu541_deinit(void *hal)
128 {
129 HalH264eVepu541Ctx *p = (HalH264eVepu541Ctx *)hal;
130
131 hal_h264e_dbg_func("enter %p\n", p);
132
133 h264e_vepu_stream_amend_deinit(&p->amend);
134
135 if (p->dev) {
136 mpp_dev_deinit(p->dev);
137 p->dev = NULL;
138 }
139
140 if (p->roi_buf) {
141 mpp_buffer_put(p->roi_buf);
142 p->roi_buf = NULL;
143 }
144
145 if (p->roi_grp) {
146 mpp_buffer_group_put(p->roi_grp);
147 p->roi_grp = NULL;
148 }
149
150 if (p->hw_recn) {
151 hal_bufs_deinit(p->hw_recn);
152 p->hw_recn = NULL;
153 }
154
155 hal_h264e_dbg_func("leave %p\n", p);
156
157 return MPP_OK;
158 }
159
hal_h264e_vepu541_init(void * hal,MppEncHalCfg * cfg)160 static MPP_RET hal_h264e_vepu541_init(void *hal, MppEncHalCfg *cfg)
161 {
162 HalH264eVepu541Ctx *p = (HalH264eVepu541Ctx *)hal;
163 MPP_RET ret = MPP_OK;
164
165 hal_h264e_dbg_func("enter %p\n", p);
166
167 p->cfg = cfg->cfg;
168
169 /* update output to MppEnc */
170 cfg->type = VPU_CLIENT_RKVENC;
171 ret = mpp_dev_init(&cfg->dev, cfg->type);
172 if (ret) {
173 mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
174 goto DONE;
175 }
176 p->dev = cfg->dev;
177
178 {
179 RockchipSocType soc_type = mpp_get_soc_type();
180
181 if (soc_type == ROCKCHIP_SOC_RK3566 || soc_type == ROCKCHIP_SOC_RK3568)
182 p->is_vepu540 = 1;
183 else
184 p->is_vepu540 = 0;
185 }
186
187 ret = hal_bufs_init(&p->hw_recn);
188 if (ret) {
189 mpp_err_f("init vepu buffer failed ret: %d\n", ret);
190 goto DONE;
191 }
192
193 p->osd_cfg.reg_base = &p->regs_set;
194 p->osd_cfg.dev = p->dev;
195 p->osd_cfg.reg_cfg = NULL;
196 p->osd_cfg.plt_cfg = &p->cfg->plt_cfg;
197 p->osd_cfg.osd_data = NULL;
198 p->osd_cfg.osd_data2 = NULL;
199
200 { /* setup default hardware config */
201 MppEncHwCfg *hw = &cfg->cfg->hw;
202
203 hw->qp_delta_row_i = 0;
204 hw->qp_delta_row = 2;
205 hw->qbias_i = 683;
206 hw->qbias_p = 341;
207 hw->qbias_en = 0;
208
209 memcpy(hw->aq_thrd_i, h264_aq_tthd_default, sizeof(hw->aq_thrd_i));
210 memcpy(hw->aq_thrd_p, h264_aq_tthd_default, sizeof(hw->aq_thrd_p));
211 memcpy(hw->aq_step_i, h264_I_aq_step_default, sizeof(hw->aq_step_i));
212 memcpy(hw->aq_step_p, h264_P_aq_step_default, sizeof(hw->aq_step_p));
213 }
214
215 DONE:
216 if (ret)
217 hal_h264e_vepu541_deinit(hal);
218
219 h264e_vepu_stream_amend_init(&p->amend);
220
221 hal_h264e_dbg_func("leave %p\n", p);
222 return ret;
223 }
224
setup_hal_bufs(HalH264eVepu541Ctx * ctx)225 static void setup_hal_bufs(HalH264eVepu541Ctx *ctx)
226 {
227 MppEncCfgSet *cfg = ctx->cfg;
228 MppEncPrepCfg *prep = &cfg->prep;
229 RK_S32 alignment = 64;
230 RK_S32 aligned_w = MPP_ALIGN(prep->width, alignment);
231 RK_S32 aligned_h = MPP_ALIGN(prep->height, alignment) + 16;
232 RK_S32 pixel_buf_fbc_hdr_size = MPP_ALIGN(aligned_w * aligned_h / 64, SZ_8K);
233 RK_S32 pixel_buf_fbc_bdy_size = aligned_w * aligned_h * 3 / 2;
234 RK_S32 pixel_buf_size = pixel_buf_fbc_hdr_size + pixel_buf_fbc_bdy_size;
235 RK_S32 thumb_buf_size = MPP_ALIGN(aligned_w / 64 * aligned_h / 64 * 256, SZ_8K);
236 RK_S32 old_max_cnt = ctx->max_buf_cnt;
237 RK_S32 new_max_cnt = 2;
238 MppEncRefCfg ref_cfg = cfg->ref_cfg;
239 if (ref_cfg) {
240 MppEncCpbInfo *info = mpp_enc_ref_cfg_get_cpb_info(ref_cfg);
241 if (new_max_cnt < MPP_MAX(new_max_cnt, info->dpb_size + 1))
242 new_max_cnt = MPP_MAX(new_max_cnt, info->dpb_size + 1);
243 }
244
245 if ((ctx->pixel_buf_fbc_hdr_size != pixel_buf_fbc_hdr_size) ||
246 (ctx->pixel_buf_fbc_bdy_size != pixel_buf_fbc_bdy_size) ||
247 (ctx->pixel_buf_size != pixel_buf_size) ||
248 (ctx->thumb_buf_size != thumb_buf_size) ||
249 (new_max_cnt > old_max_cnt)) {
250 size_t sizes[2];
251
252 hal_h264e_dbg_detail("frame size %d -> %d max count %d -> %d\n",
253 ctx->pixel_buf_size, pixel_buf_size,
254 old_max_cnt, new_max_cnt);
255
256 /* pixel buffer */
257 sizes[0] = pixel_buf_size;
258 /* thumb buffer */
259 sizes[1] = thumb_buf_size;
260 new_max_cnt = MPP_MAX(new_max_cnt, old_max_cnt);
261
262 hal_bufs_setup(ctx->hw_recn, new_max_cnt, 2, sizes);
263
264 ctx->pixel_buf_fbc_hdr_size = pixel_buf_fbc_hdr_size;
265 ctx->pixel_buf_fbc_bdy_size = pixel_buf_fbc_bdy_size;
266 ctx->pixel_buf_size = pixel_buf_size;
267 ctx->thumb_buf_size = thumb_buf_size;
268 ctx->max_buf_cnt = new_max_cnt;
269 }
270 }
271
hal_h264e_vepu541_prepare(void * hal)272 static MPP_RET hal_h264e_vepu541_prepare(void *hal)
273 {
274 HalH264eVepu541Ctx *ctx = (HalH264eVepu541Ctx *)hal;
275 MppEncPrepCfg *prep = &ctx->cfg->prep;
276
277 hal_h264e_dbg_func("enter %p\n", hal);
278
279 if (prep->change_res) {
280 RK_S32 i;
281
282 // pre-alloc required buffers to reduce first frame delay
283 setup_hal_bufs(ctx);
284 for (i = 0; i < ctx->max_buf_cnt; i++)
285 hal_bufs_get_buf(ctx->hw_recn, i);
286
287 prep->change_res = 0;
288 }
289
290 hal_h264e_dbg_func("leave %p\n", hal);
291
292 return MPP_OK;
293 }
294
update_vepu541_syntax(HalH264eVepu541Ctx * ctx,MppSyntax * syntax)295 static RK_U32 update_vepu541_syntax(HalH264eVepu541Ctx *ctx, MppSyntax *syntax)
296 {
297 H264eSyntaxDesc *desc = syntax->data;
298 RK_S32 syn_num = syntax->number;
299 RK_U32 updated = 0;
300 RK_S32 i;
301
302 for (i = 0; i < syn_num; i++, desc++) {
303 switch (desc->type) {
304 case H264E_SYN_CFG : {
305 hal_h264e_dbg_detail("update cfg");
306 ctx->cfg = desc->p;
307 } break;
308 case H264E_SYN_SPS : {
309 hal_h264e_dbg_detail("update sps");
310 ctx->sps = desc->p;
311 } break;
312 case H264E_SYN_PPS : {
313 hal_h264e_dbg_detail("update pps");
314 ctx->pps = desc->p;
315 } break;
316 case H264E_SYN_DPB : {
317 hal_h264e_dbg_detail("update dpb");
318 } break;
319 case H264E_SYN_SLICE : {
320 hal_h264e_dbg_detail("update slice");
321 ctx->slice = desc->p;
322 } break;
323 case H264E_SYN_FRAME : {
324 hal_h264e_dbg_detail("update frames");
325 ctx->frms = desc->p;
326 } break;
327 case H264E_SYN_PREFIX : {
328 hal_h264e_dbg_detail("update prefix nal");
329 ctx->prefix = desc->p;
330 } break;
331 default : {
332 mpp_log_f("invalid syntax type %d\n", desc->type);
333 } break;
334 }
335
336 updated |= SYN_TYPE_FLAG(desc->type);
337 }
338
339 return updated;
340 }
341
hal_h264e_vepu541_get_task(void * hal,HalEncTask * task)342 static MPP_RET hal_h264e_vepu541_get_task(void *hal, HalEncTask *task)
343 {
344 HalH264eVepu541Ctx *ctx = (HalH264eVepu541Ctx *)hal;
345 MppEncH264HwCfg *hw_cfg = &ctx->cfg->h264.hw_cfg;
346 RK_U32 updated = update_vepu541_syntax(ctx, &task->syntax);
347 EncFrmStatus *frm_status = &task->rc_task->frm;
348
349 hal_h264e_dbg_func("enter %p\n", hal);
350
351 if (updated & SYN_TYPE_FLAG(H264E_SYN_CFG))
352 setup_hal_bufs(ctx);
353
354 if (!frm_status->reencode && mpp_frame_has_meta(task->frame)) {
355 MppMeta meta = mpp_frame_get_meta(task->frame);
356
357 mpp_meta_get_ptr_d(meta, KEY_ROI_DATA, (void **)&ctx->roi_data, NULL);
358 mpp_meta_get_ptr_d(meta, KEY_ROI_DATA2, (void **)&ctx->roi_data2, NULL);
359 mpp_meta_get_ptr_d(meta, KEY_OSD_DATA, (void **)&ctx->osd_cfg.osd_data, NULL);
360 mpp_meta_get_ptr_d(meta, KEY_OSD_DATA2, (void **)&ctx->osd_cfg.osd_data2, NULL);
361 mpp_meta_get_buffer_d(meta, KEY_QPMAP0, &ctx->qpmap, NULL);
362 }
363
364 /* if not VEPU1/2, update log2_max_frame_num_minus4 in hw_cfg */
365 hw_cfg->hw_log2_max_frame_num_minus4 = ctx->sps->log2_max_frame_num_minus4;
366
367 h264e_vepu_stream_amend_config(&ctx->amend, task->packet, ctx->cfg,
368 ctx->slice, ctx->prefix);
369
370 hal_h264e_dbg_func("leave %p\n", hal);
371
372 return MPP_OK;
373 }
374
setup_vepu541_normal(Vepu541H264eRegSet * regs,RK_U32 is_vepu540)375 static void setup_vepu541_normal(Vepu541H264eRegSet *regs, RK_U32 is_vepu540)
376 {
377 hal_h264e_dbg_func("enter\n");
378 /* reg000 VERSION is read only */
379
380 /* reg001 ENC_STRT */
381 regs->reg001.lkt_num = 0;
382 regs->reg001.rkvenc_cmd = 1;
383 regs->reg001.clk_gate_en = 1;
384 regs->reg001.resetn_hw_en = 0;
385 regs->reg001.enc_done_tmvp_en = 1;
386
387 /* reg002 ENC_CLR */
388 regs->reg002.safe_clr = 0;
389 regs->reg002.force_clr = 0;
390
391 /* reg003 LKT_ADDR */
392 regs->reg003.lkt_addr = 0;
393
394 /* reg004 INT_EN */
395 regs->reg004.enc_done_en = 1;
396 regs->reg004.lkt_done_en = 1;
397 regs->reg004.sclr_done_en = 1;
398 regs->reg004.enc_slice_done_en = 1;
399 regs->reg004.oflw_done_en = 1;
400 regs->reg004.brsp_done_en = 1;
401 regs->reg004.berr_done_en = 1;
402 regs->reg004.rerr_done_en = 1;
403 regs->reg004.wdg_done_en = 0;
404
405 /* reg005 INT_MSK */
406 regs->reg005.enc_done_msk = 0;
407 regs->reg005.lkt_done_msk = 0;
408 regs->reg005.sclr_done_msk = 0;
409 regs->reg005.enc_slice_done_msk = 0;
410 regs->reg005.oflw_done_msk = 0;
411 regs->reg005.brsp_done_msk = 0;
412 regs->reg005.berr_done_msk = 0;
413 regs->reg005.rerr_done_msk = 0;
414 regs->reg005.wdg_done_msk = 0;
415
416 /* reg006 INT_CLR is not set */
417 /* reg007 INT_STA is read only */
418 /* reg008 ~ reg0011 gap */
419 regs->reg014.vs_load_thd = 0;
420 regs->reg014.rfp_load_thrd = 0;
421
422 /* reg015 DTRNS_MAP */
423 regs->reg015.cmvw_bus_ordr = 0;
424 regs->reg015.dspw_bus_ordr = 0;
425 regs->reg015.rfpw_bus_ordr = 0;
426 regs->reg015.src_bus_edin = 0;
427 regs->reg015.meiw_bus_edin = 0;
428 regs->reg015.bsw_bus_edin = 7;
429 regs->reg015.lktr_bus_edin = 0;
430 regs->reg015.roir_bus_edin = 0;
431 regs->reg015.lktw_bus_edin = 0;
432 regs->reg015.afbc_bsize = 1;
433
434 /* reg016 DTRNS_CFG */
435 if (is_vepu540) {
436 /* vepu540 */
437 regs->reg016.vepu540.axi_brsp_cke = 0;
438 regs->reg016.vepu540.dspr_otsd = 1;
439 } else {
440 /* vepu541 */
441 regs->reg016.vepu541.axi_brsp_cke = 0;
442 regs->reg016.vepu541.dspr_otsd = 1;
443 }
444
445 hal_h264e_dbg_func("leave\n");
446 }
447
setup_vepu541_prep(Vepu541H264eRegSet * regs,HalH264eVepu541Ctx * ctx,HalEncTask * task)448 static MPP_RET setup_vepu541_prep(Vepu541H264eRegSet *regs, HalH264eVepu541Ctx *ctx,
449 HalEncTask *task)
450 {
451 VepuFmtCfg cfg;
452 MppEncPrepCfg *prep = &ctx->cfg->prep;
453 MppFrameFormat fmt = prep->format;
454 MPP_RET ret = vepu5xx_set_fmt(&cfg, fmt);
455 RK_U32 hw_fmt = cfg.format;
456 RK_S32 y_stride;
457 RK_S32 c_stride;
458
459 hal_h264e_dbg_func("enter\n");
460
461 /* do nothing when color format is not supported */
462 if (ret)
463 return ret;
464
465 /* reg012 ENC_RSL */
466 regs->reg012.pic_wd8_m1 = MPP_ALIGN(prep->width, 16) / 8 - 1;
467 regs->reg012.pic_wfill = MPP_ALIGN(prep->width, 16) - prep->width;
468 regs->reg012.pic_hd8_m1 = MPP_ALIGN(prep->height, 16) / 8 - 1;
469 regs->reg012.pic_hfill = MPP_ALIGN(prep->height, 16) - prep->height;
470
471 /* reg015 DTRNS_MAP */
472 regs->reg015.src_bus_edin = cfg.src_endian;
473
474 /* reg022 SRC_PROC */
475 regs->reg017.src_cfmt = hw_fmt;
476 regs->reg017.alpha_swap = cfg.alpha_swap;
477 regs->reg017.rbuv_swap = cfg.rbuv_swap;
478 regs->reg017.src_range = cfg.src_range;
479 regs->reg017.out_fmt_cfg = (fmt == MPP_FMT_YUV400) ? 1 : 0;
480
481 if (!ctx->frame_cnt && (fmt == MPP_FMT_YUV420SP_VU || fmt == MPP_FMT_YUV422SP_VU))
482 mpp_logw("Warning: nv21/nv42 fmt not supported, will encode as nv12/nv24.\n");
483
484 if (MPP_FRAME_FMT_IS_FBC(fmt)) {
485 y_stride = mpp_frame_get_fbc_hdr_stride(task->frame);
486 if (!y_stride)
487 y_stride = MPP_ALIGN(prep->hor_stride, 16);
488 } else
489 y_stride = (prep->hor_stride) ? (prep->hor_stride) : (prep->width);
490
491
492 c_stride = (hw_fmt == VEPU5xx_FMT_YUV422SP || hw_fmt == VEPU5xx_FMT_YUV420SP) ?
493 y_stride : y_stride / 2;
494
495 if (hw_fmt < VEPU5xx_FMT_ARGB1555) {
496 const VepuRgb2YuvCfg *cfg_coeffs = get_rgb2yuv_cfg(prep->range, prep->color);
497
498 hal_h264e_dbg_flow("input color range %d colorspace %d", prep->range, prep->color);
499
500 regs->reg018.csc_wgt_b2y = cfg_coeffs->_2y.b_coeff;
501 regs->reg018.csc_wgt_g2y = cfg_coeffs->_2y.g_coeff;
502 regs->reg018.csc_wgt_r2y = cfg_coeffs->_2y.r_coeff;
503
504 regs->reg019.csc_wgt_b2u = cfg_coeffs->_2u.b_coeff;
505 regs->reg019.csc_wgt_g2u = cfg_coeffs->_2u.g_coeff;
506 regs->reg019.csc_wgt_r2u = cfg_coeffs->_2u.r_coeff;
507
508 regs->reg020.csc_wgt_b2v = cfg_coeffs->_2v.b_coeff;
509 regs->reg020.csc_wgt_g2v = cfg_coeffs->_2v.g_coeff;
510 regs->reg020.csc_wgt_r2v = cfg_coeffs->_2v.r_coeff;
511
512 regs->reg021.csc_ofst_y = cfg_coeffs->_2y.offset;
513 regs->reg021.csc_ofst_u = cfg_coeffs->_2u.offset;
514 regs->reg021.csc_ofst_v = cfg_coeffs->_2v.offset;
515
516 hal_h264e_dbg_flow("use color range %d colorspace %d", cfg_coeffs->dst_range, cfg_coeffs->color);
517 } else {
518 regs->reg018.csc_wgt_b2y = cfg.weight[0];
519 regs->reg018.csc_wgt_g2y = cfg.weight[1];
520 regs->reg018.csc_wgt_r2y = cfg.weight[2];
521
522 regs->reg019.csc_wgt_b2u = cfg.weight[3];
523 regs->reg019.csc_wgt_g2u = cfg.weight[4];
524 regs->reg019.csc_wgt_r2u = cfg.weight[5];
525
526 regs->reg020.csc_wgt_b2v = cfg.weight[6];
527 regs->reg020.csc_wgt_g2v = cfg.weight[7];
528 regs->reg020.csc_wgt_r2v = cfg.weight[8];
529
530 regs->reg021.csc_ofst_y = cfg.offset[0];
531 regs->reg021.csc_ofst_u = cfg.offset[1];
532 regs->reg021.csc_ofst_v = cfg.offset[2];
533 }
534
535 regs->reg022.afbcd_en = MPP_FRAME_FMT_IS_FBC(fmt) ? 1 : 0;
536 regs->reg069.src_strd0 = y_stride;
537 regs->reg069.src_strd1 = c_stride;
538
539 regs->reg022.src_mirr = prep->mirroring > 0;
540 regs->reg022.src_rot = prep->rotation;
541 regs->reg022.txa_en = 1;
542
543 regs->reg023.sli_crs_en = 1;
544
545 regs->reg068.pic_ofst_y = 0;
546 regs->reg068.pic_ofst_x = 0;
547
548 hal_h264e_dbg_func("leave\n");
549
550 return ret;
551 }
552
setup_vepu541_codec(Vepu541H264eRegSet * regs,H264eSps * sps,H264ePps * pps,H264eSlice * slice)553 static void setup_vepu541_codec(Vepu541H264eRegSet *regs, H264eSps *sps,
554 H264ePps *pps, H264eSlice *slice)
555 {
556 hal_h264e_dbg_func("enter\n");
557
558 regs->reg013.enc_stnd = 0;
559 regs->reg013.cur_frm_ref = slice->nal_reference_idc > 0;
560 regs->reg013.bs_scp = 1;
561 regs->reg013.lamb_mod_sel = (slice->slice_type == H264_I_SLICE) ? 0 : 1;
562 regs->reg013.atr_thd_sel = 0;
563 regs->reg013.node_int = 0;
564
565 regs->reg103.nal_ref_idc = slice->nal_reference_idc;
566 regs->reg103.nal_unit_type = slice->nalu_type;
567
568 regs->reg104.max_fnum = sps->log2_max_frame_num_minus4;
569 regs->reg104.drct_8x8 = sps->direct8x8_inference;
570 regs->reg104.mpoc_lm4 = sps->log2_max_poc_lsb_minus4;
571
572 regs->reg105.etpy_mode = pps->entropy_coding_mode;
573 regs->reg105.trns_8x8 = pps->transform_8x8_mode;
574 regs->reg105.csip_flag = pps->constrained_intra_pred;
575 regs->reg105.num_ref0_idx = pps->num_ref_idx_l0_default_active - 1;
576 regs->reg105.num_ref1_idx = pps->num_ref_idx_l1_default_active - 1;
577 regs->reg105.pic_init_qp = pps->pic_init_qp;
578 regs->reg105.cb_ofst = pps->chroma_qp_index_offset;
579 regs->reg105.cr_ofst = pps->second_chroma_qp_index_offset;
580 regs->reg105.wght_pred = pps->weighted_pred;
581 regs->reg105.dbf_cp_flg = pps->deblocking_filter_control;
582
583 regs->reg106.sli_type = (slice->slice_type == H264_I_SLICE) ? (2) : (0);
584 regs->reg106.pps_id = slice->pic_parameter_set_id;
585 regs->reg106.drct_smvp = 0;
586 regs->reg106.num_ref_ovrd = slice->num_ref_idx_override;
587 regs->reg106.cbc_init_idc = slice->cabac_init_idc;
588 regs->reg106.frm_num = slice->frame_num;
589
590 regs->reg107.idr_pic_id = (slice->slice_type == H264_I_SLICE) ? slice->idr_pic_id : (RK_U32)(-1);
591 regs->reg107.poc_lsb = slice->pic_order_cnt_lsb;
592
593
594 regs->reg108.dis_dblk_idc = slice->disable_deblocking_filter_idc;
595 regs->reg108.sli_alph_ofst = slice->slice_alpha_c0_offset_div2;
596
597 h264e_reorder_rd_rewind(slice->reorder);
598 { /* reorder process */
599 H264eRplmo rplmo;
600 MPP_RET ret = h264e_reorder_rd_op(slice->reorder, &rplmo);
601
602 if (MPP_OK == ret) {
603 regs->reg108.ref_list0_rodr = 1;
604 regs->reg108.rodr_pic_idx = rplmo.modification_of_pic_nums_idc;
605
606 switch (rplmo.modification_of_pic_nums_idc) {
607 case 0 :
608 case 1 : {
609 regs->reg108.rodr_pic_num = rplmo.abs_diff_pic_num_minus1;
610 } break;
611 case 2 : {
612 regs->reg108.rodr_pic_num = rplmo.long_term_pic_idx;
613 } break;
614 default : {
615 mpp_err_f("invalid modification_of_pic_nums_idc %d\n",
616 rplmo.modification_of_pic_nums_idc);
617 } break;
618 }
619 } else {
620 // slice->ref_pic_list_modification_flag;
621 regs->reg108.ref_list0_rodr = 0;
622 regs->reg108.rodr_pic_idx = 0;
623 regs->reg108.rodr_pic_num = 0;
624 }
625 }
626
627 /* clear all mmco arg first */
628 regs->reg109.nopp_flg = 0;
629 regs->reg109.ltrf_flg = 0;
630 regs->reg109.arpm_flg = 0;
631 regs->reg109.mmco4_pre = 0;
632 regs->reg109.mmco_type0 = 0;
633 regs->reg109.mmco_parm0 = 0;
634 regs->reg109.mmco_type1 = 0;
635 regs->reg110.mmco_parm1 = 0;
636 regs->reg109.mmco_type2 = 0;
637 regs->reg110.mmco_parm2 = 0;
638 regs->reg114.long_term_frame_idx0 = 0;
639 regs->reg114.long_term_frame_idx1 = 0;
640 regs->reg114.long_term_frame_idx2 = 0;
641
642 h264e_marking_rd_rewind(slice->marking);
643
644 /* only update used parameter */
645 if (slice->slice_type == H264_I_SLICE) {
646 regs->reg109.nopp_flg = slice->no_output_of_prior_pics;
647 regs->reg109.ltrf_flg = slice->long_term_reference_flag;
648 } else {
649 if (!h264e_marking_is_empty(slice->marking)) {
650 H264eMmco mmco;
651
652 regs->reg109.arpm_flg = 1;
653
654 /* max 3 mmco */
655 do {
656 RK_S32 type = 0;
657 RK_S32 param_0 = 0;
658 RK_S32 param_1 = 0;
659
660 h264e_marking_rd_op(slice->marking, &mmco);
661 type = mmco.mmco;
662 switch (type) {
663 case 1 : {
664 param_0 = mmco.difference_of_pic_nums_minus1;
665 } break;
666 case 2 : {
667 param_0 = mmco.long_term_pic_num;
668 } break;
669 case 3 : {
670 param_0 = mmco.difference_of_pic_nums_minus1;
671 param_1 = mmco.long_term_frame_idx;
672 } break;
673 case 4 : {
674 param_0 = mmco.max_long_term_frame_idx_plus1;
675 } break;
676 case 5 : {
677 } break;
678 case 6 : {
679 param_0 = mmco.long_term_frame_idx;
680 } break;
681 default : {
682 mpp_err_f("unsupported mmco 0 %d\n", type);
683 type = 0;
684 } break;
685 }
686
687 regs->reg109.mmco_type0 = type;
688 regs->reg109.mmco_parm0 = param_0;
689 regs->reg114.long_term_frame_idx0 = param_1;
690
691 if (h264e_marking_is_empty(slice->marking))
692 break;
693
694 h264e_marking_rd_op(slice->marking, &mmco);
695 type = mmco.mmco;
696 param_0 = 0;
697 param_1 = 0;
698 switch (type) {
699 case 1 : {
700 param_0 = mmco.difference_of_pic_nums_minus1;
701 } break;
702 case 2 : {
703 param_0 = mmco.long_term_pic_num;
704 } break;
705 case 3 : {
706 param_0 = mmco.difference_of_pic_nums_minus1;
707 param_1 = mmco.long_term_frame_idx;
708 } break;
709 case 4 : {
710 param_0 = mmco.max_long_term_frame_idx_plus1;
711 } break;
712 case 5 : {
713 } break;
714 case 6 : {
715 param_0 = mmco.long_term_frame_idx;
716 } break;
717 default : {
718 mpp_err_f("unsupported mmco 0 %d\n", type);
719 type = 0;
720 } break;
721 }
722
723 regs->reg109.mmco_type1 = type;
724 regs->reg110.mmco_parm1 = param_0;
725 regs->reg114.long_term_frame_idx1 = param_1;
726
727 if (h264e_marking_is_empty(slice->marking))
728 break;
729
730 h264e_marking_rd_op(slice->marking, &mmco);
731 type = mmco.mmco;
732 param_0 = 0;
733 param_1 = 0;
734 switch (type) {
735 case 1 : {
736 param_0 = mmco.difference_of_pic_nums_minus1;
737 } break;
738 case 2 : {
739 param_0 = mmco.long_term_pic_num;
740 } break;
741 case 3 : {
742 param_0 = mmco.difference_of_pic_nums_minus1;
743 param_1 = mmco.long_term_frame_idx;
744 } break;
745 case 4 : {
746 param_0 = mmco.max_long_term_frame_idx_plus1;
747 } break;
748 case 5 : {
749 } break;
750 case 6 : {
751 param_0 = mmco.long_term_frame_idx;
752 } break;
753 default : {
754 mpp_err_f("unsupported mmco 0 %d\n", type);
755 type = 0;
756 } break;
757 }
758
759 regs->reg109.mmco_type2 = type;
760 regs->reg110.mmco_parm2 = param_0;
761 regs->reg114.long_term_frame_idx2 = param_1;
762 } while (0);
763 }
764 }
765
766 hal_h264e_dbg_func("leave\n");
767 }
768
setup_vepu541_rdo_pred(Vepu541H264eRegSet * regs,H264eSps * sps,H264ePps * pps,H264eSlice * slice,MppEncCfgSet * cfg)769 static void setup_vepu541_rdo_pred(Vepu541H264eRegSet *regs, H264eSps *sps,
770 H264ePps *pps, H264eSlice *slice, MppEncCfgSet *cfg)
771 {
772 hal_h264e_dbg_func("enter\n");
773
774 if (slice->slice_type == H264_I_SLICE) {
775 regs->reg025.chrm_klut_ofst = 0;
776 memcpy(®s->reg026, &h264e_klut_weight[0], CHROMA_KLUT_TAB_SIZE);
777 } else {
778 regs->reg025.chrm_klut_ofst = 3;
779 if (cfg->tune.scene_mode == MPP_ENC_SCENE_MODE_IPC)
780 memcpy(®s->reg026, &h264e_klut_weight[3], CHROMA_KLUT_TAB_SIZE);
781 else
782 memcpy(®s->reg026, &h264e_klut_weight[0], CHROMA_KLUT_TAB_SIZE);
783 }
784
785 if (cfg->tune.scene_mode == MPP_ENC_SCENE_MODE_IPC) {
786 regs->reg101.vthd_y = 9;
787 regs->reg101.vthd_c = 63;
788 regs->reg102.inter_4x4 = 0;
789 regs->reg102.rdo_mask = 24;
790 regs->reg102.atf_intra_e = 1;
791 } else {
792 regs->reg101.vthd_y = 2501;
793 regs->reg101.vthd_c = 2501;
794 regs->reg102.inter_4x4 = 1;
795 regs->reg102.rdo_mask = 0;
796 regs->reg102.atf_intra_e = 0;
797 }
798
799 regs->reg102.rect_size = (sps->profile_idc == H264_PROFILE_BASELINE &&
800 sps->level_idc <= H264_LEVEL_3_0) ? 1 : 0;
801
802 regs->reg102.vlc_lmt = (sps->profile_idc < H264_PROFILE_MAIN) &&
803 !pps->entropy_coding_mode;
804 regs->reg102.chrm_spcl = 1;
805 regs->reg102.ccwa_e = 1;
806 regs->reg102.scl_lst_sel = pps->pic_scaling_matrix_present;
807 regs->reg102.scl_lst_sel_ = pps->pic_scaling_matrix_present;
808 regs->reg102.atr_e = 1;
809 regs->reg102.atf_edg = 0;
810 regs->reg102.atf_lvl_e = 0;
811 regs->reg102.satd_byps_flg = 0;
812
813 hal_h264e_dbg_func("leave\n");
814 }
815
setup_vepu541_rc_base(Vepu541H264eRegSet * regs,H264eSps * sps,H264eSlice * slice,MppEncHwCfg * hw,EncRcTask * rc_task)816 static void setup_vepu541_rc_base(Vepu541H264eRegSet *regs, H264eSps *sps,
817 H264eSlice *slice, MppEncHwCfg *hw,
818 EncRcTask *rc_task)
819 {
820 EncRcTaskInfo *rc_info = &rc_task->info;
821 RK_S32 mb_w = sps->pic_width_in_mbs;
822 RK_S32 mb_h = sps->pic_height_in_mbs;
823 RK_U32 qp_target = rc_info->quality_target;
824 RK_U32 qp_min = rc_info->quality_min;
825 RK_U32 qp_max = rc_info->quality_max;
826 RK_U32 qpmap_mode = 1;
827 RK_S32 mb_target_bits_mul_16 = (rc_info->bit_target << 4) / (mb_w * mb_h);
828 RK_S32 mb_target_bits;
829 RK_S32 negative_bits_thd;
830 RK_S32 positive_bits_thd;
831
832 hal_h264e_dbg_rc("bittarget %d qp [%d %d %d]\n", rc_info->bit_target,
833 qp_min, qp_target, qp_max);
834
835 if (mb_target_bits_mul_16 >= 0x100000) {
836 mb_target_bits_mul_16 = 0x50000;
837 }
838
839 mb_target_bits = (mb_target_bits_mul_16 * mb_w) >> 4;
840 negative_bits_thd = 0 - mb_target_bits * 5 / 16;
841 positive_bits_thd = mb_target_bits * 5 / 16;
842
843 hal_h264e_dbg_func("enter\n");
844
845 regs->reg013.pic_qp = qp_target;
846
847 regs->reg050.rc_en = 1;
848 regs->reg050.aq_en = 1;
849 regs->reg050.aq_mode = 0;
850 regs->reg050.rc_ctu_num = mb_w;
851
852 regs->reg051.rc_qp_range = (slice->slice_type == H264_I_SLICE) ?
853 hw->qp_delta_row_i : hw->qp_delta_row;
854 regs->reg051.rc_max_qp = qp_max;
855 regs->reg051.rc_min_qp = qp_min;
856
857 regs->reg052.ctu_ebit = mb_target_bits_mul_16;
858
859 regs->reg053.qp_adj0 = -2;
860 regs->reg053.qp_adj1 = -1;
861 regs->reg053.qp_adj2 = 0;
862 regs->reg053.qp_adj3 = 1;
863 regs->reg053.qp_adj4 = 2;
864 regs->reg054.qp_adj5 = 0;
865 regs->reg054.qp_adj6 = 0;
866 regs->reg054.qp_adj7 = 0;
867 regs->reg054.qp_adj8 = 0;
868
869 regs->reg055_063.rc_dthd[0] = 2 * negative_bits_thd;
870 regs->reg055_063.rc_dthd[1] = negative_bits_thd;
871 regs->reg055_063.rc_dthd[2] = positive_bits_thd;
872 regs->reg055_063.rc_dthd[3] = 2 * positive_bits_thd;
873 regs->reg055_063.rc_dthd[4] = 0x7fffffff;
874 regs->reg055_063.rc_dthd[5] = 0x7fffffff;
875 regs->reg055_063.rc_dthd[6] = 0x7fffffff;
876 regs->reg055_063.rc_dthd[7] = 0x7fffffff;
877 regs->reg055_063.rc_dthd[8] = 0x7fffffff;
878
879 regs->reg064.qpmin_area0 = qp_min;
880 regs->reg064.qpmax_area0 = qp_max;
881 regs->reg064.qpmin_area1 = qp_min;
882 regs->reg064.qpmax_area1 = qp_max;
883 regs->reg064.qpmin_area2 = qp_min;
884
885 regs->reg065.qpmax_area2 = qp_max;
886 regs->reg065.qpmin_area3 = qp_min;
887 regs->reg065.qpmax_area3 = qp_max;
888 regs->reg065.qpmin_area4 = qp_min;
889 regs->reg065.qpmax_area4 = qp_max;
890
891 regs->reg066.qpmin_area5 = qp_min;
892 regs->reg066.qpmax_area5 = qp_max;
893 regs->reg066.qpmin_area6 = qp_min;
894 regs->reg066.qpmax_area6 = qp_max;
895 regs->reg066.qpmin_area7 = qp_min;
896
897 regs->reg067.qpmax_area7 = qp_max;
898 regs->reg067.qpmap_mode = qpmap_mode;
899
900 hal_h264e_dbg_func("leave\n");
901 }
902
setup_vepu541_io_buf(Vepu541H264eRegSet * regs,MppDev dev,HalEncTask * task)903 static void setup_vepu541_io_buf(Vepu541H264eRegSet *regs, MppDev dev,
904 HalEncTask *task)
905 {
906 MppFrame frm = task->frame;
907 MppPacket pkt = task->packet;
908 MppBuffer buf_in = mpp_frame_get_buffer(frm);
909 MppBuffer buf_out = task->output;
910 MppFrameFormat fmt = mpp_frame_get_fmt(frm);
911 RK_S32 hor_stride = mpp_frame_get_hor_stride(frm);
912 RK_S32 ver_stride = mpp_frame_get_ver_stride(frm);
913 RK_S32 fd_in = mpp_buffer_get_fd(buf_in);
914 RK_U32 off_in[2] = {0};
915 RK_U32 off_out = mpp_packet_get_length(pkt);
916 size_t siz_out = mpp_buffer_get_size(buf_out);
917 RK_S32 fd_out = mpp_buffer_get_fd(buf_out);
918
919 hal_h264e_dbg_func("enter\n");
920
921 regs->reg070.adr_src0 = fd_in;
922 regs->reg071.adr_src1 = fd_in;
923 regs->reg072.adr_src2 = fd_in;
924
925 regs->reg084.bsbb_addr = fd_out;
926 regs->reg085.bsbr_addr = fd_out;
927 regs->reg086.adr_bsbs = fd_out;
928 regs->reg083.bsbt_addr = fd_out;
929
930 if (MPP_FRAME_FMT_IS_FBC(fmt)) {
931 off_in[0] = mpp_frame_get_fbc_offset(frm);;
932 off_in[1] = 0;
933 } else if (MPP_FRAME_FMT_IS_YUV(fmt)) {
934 VepuFmtCfg cfg;
935
936 vepu5xx_set_fmt(&cfg, fmt);
937 switch (cfg.format) {
938 case VEPU5xx_FMT_BGRA8888 :
939 case VEPU5xx_FMT_BGR888 :
940 case VEPU5xx_FMT_BGR565 : {
941 off_in[0] = 0;
942 off_in[1] = 0;
943 } break;
944 case VEPU5xx_FMT_YUV420SP :
945 case VEPU5xx_FMT_YUV422SP : {
946 off_in[0] = hor_stride * ver_stride;
947 off_in[1] = hor_stride * ver_stride;
948 } break;
949 case VEPU5xx_FMT_YUV422P : {
950 off_in[0] = hor_stride * ver_stride;
951 off_in[1] = hor_stride * ver_stride * 3 / 2;
952 } break;
953 case VEPU5xx_FMT_YUV420P : {
954 off_in[0] = hor_stride * ver_stride;
955 off_in[1] = hor_stride * ver_stride * 5 / 4;
956 } break;
957 case VEPU5xx_FMT_YUV400 :
958 case VEPU5xx_FMT_YUYV422 :
959 case VEPU5xx_FMT_UYVY422 : {
960 off_in[0] = 0;
961 off_in[1] = 0;
962 } break;
963 default : {
964 off_in[0] = 0;
965 off_in[1] = 0;
966 } break;
967 }
968 }
969
970 mpp_dev_set_reg_offset(dev, 71, off_in[0]);
971 mpp_dev_set_reg_offset(dev, 72, off_in[1]);
972 mpp_dev_set_reg_offset(dev, 83, siz_out);
973 mpp_dev_set_reg_offset(dev, 86, off_out);
974
975 hal_h264e_dbg_func("leave\n");
976 }
977
setup_vepu541_intra_refresh(Vepu541H264eRegSet * regs,HalH264eVepu541Ctx * ctx,RK_U32 refresh_idx)978 static MPP_RET setup_vepu541_intra_refresh(Vepu541H264eRegSet *regs, HalH264eVepu541Ctx *ctx, RK_U32 refresh_idx)
979 {
980 MPP_RET ret = MPP_OK;
981 RK_U32 w = ctx->sps->pic_width_in_mbs * 16;
982 RK_U32 h = ctx->sps->pic_height_in_mbs * 16;
983 MppEncROIRegion *region = NULL;
984 RK_U32 refresh_num = ctx->cfg->rc.refresh_num;
985 RK_U32 stride_h = MPP_ALIGN(w / 16, 4);
986 RK_U32 stride_v = MPP_ALIGN(h / 16, 4);
987 RK_U32 i = 0;
988 RK_S32 roi_buf_size;
989
990 hal_h264e_dbg_func("enter\n");
991
992 if (!ctx->cfg->rc.refresh_en) {
993 ret = MPP_ERR_VALUE;
994 goto RET;
995 }
996
997 roi_buf_size = vepu541_get_roi_buf_size(w, h);
998 if (ctx->roi_buf_size < roi_buf_size) {
999 if (NULL == ctx->roi_grp)
1000 mpp_buffer_group_get_internal(&ctx->roi_grp, MPP_BUFFER_TYPE_ION);
1001 if (ctx->roi_buf)
1002 mpp_buffer_put(ctx->roi_buf);
1003
1004 mpp_buffer_get(ctx->roi_grp, &ctx->roi_buf, roi_buf_size);
1005 ctx->roi_buf_size = roi_buf_size;
1006 }
1007
1008 mpp_assert(ctx->roi_buf);
1009 RK_S32 fd = mpp_buffer_get_fd(ctx->roi_buf);
1010 void *buf = mpp_buffer_get_ptr(ctx->roi_buf);
1011 Vepu541RoiCfg cfg;
1012 Vepu541RoiCfg *ptr = (Vepu541RoiCfg *)buf;
1013 cfg.force_intra = 0;
1014 cfg.reserved = 0;
1015 cfg.qp_area_idx = 0;
1016 cfg.qp_area_en = 1;
1017 cfg.qp_adj = 0;
1018 cfg.qp_adj_mode = 0;
1019
1020 for (i = 0; i < stride_h * stride_v; i++, ptr++)
1021 memcpy(ptr, &cfg, sizeof(cfg));
1022
1023 region = mpp_calloc(MppEncROIRegion, 1);
1024
1025 if (NULL == region) {
1026 mpp_err_f("Failed to calloc for MppEncROIRegion !\n");
1027 ret = MPP_ERR_MALLOC;
1028 }
1029
1030 if (ctx->cfg->rc.refresh_mode == MPP_ENC_RC_INTRA_REFRESH_ROW) {
1031 region->x = 0;
1032 region->w = w;
1033 if (refresh_idx > 0) {
1034 region->y = refresh_idx * 16 * refresh_num - 32;
1035 region->h = 16 * refresh_num + 32;
1036 } else {
1037 region->y = refresh_idx * 16 * refresh_num;
1038 region->h = 16 * refresh_num;
1039 }
1040 regs->reg089.cme_srch_v = 1;
1041 } else if (ctx->cfg->rc.refresh_mode == MPP_ENC_RC_INTRA_REFRESH_COL) {
1042 region->y = 0;
1043 region->h = h;
1044 if (refresh_idx > 0) {
1045 region->x = refresh_idx * 16 * refresh_num - 32;
1046 region->w = 16 * refresh_num + 32;
1047 } else {
1048 region->x = refresh_idx * 16 * refresh_num;
1049 region->w = 16 * refresh_num;
1050 }
1051 regs->reg089.cme_srch_h = 1;
1052 }
1053
1054 region->intra = 1;
1055 region->quality = -ctx->cfg->rc.qp_delta_ip;
1056
1057 region->area_map_en = 1;
1058 region->qp_area_idx = 1;
1059 region->abs_qp_en = 0;
1060
1061 regs->reg013.roi_enc = 1;
1062 regs->reg073.roi_addr = fd;
1063 vepu541_set_one_roi(buf, region, w, h);
1064 mpp_free(region);
1065 mpp_buffer_sync_end(ctx->roi_buf);
1066
1067 RET:
1068 hal_h264e_dbg_func("leave, ret %d\n", ret);
1069 return ret;
1070 }
1071
setup_vepu541_roi(Vepu541H264eRegSet * regs,HalH264eVepu541Ctx * ctx)1072 static void setup_vepu541_roi(Vepu541H264eRegSet *regs, HalH264eVepu541Ctx *ctx)
1073 {
1074
1075 hal_h264e_dbg_func("enter\n");
1076
1077 if (ctx->roi_data2) {
1078 MppEncROICfg2 *cfg = ( MppEncROICfg2 *)ctx->roi_data2;
1079
1080 regs->reg013.roi_enc = 1;
1081 regs->reg073.roi_addr = mpp_buffer_get_fd(cfg->base_cfg_buf);
1082 } else if (ctx->qpmap) {
1083 regs->reg013.roi_enc = 1;
1084 regs->reg073.roi_addr = mpp_buffer_get_fd(ctx->qpmap);
1085 } else {
1086 MppEncROICfg *roi = ctx->roi_data;
1087 RK_U32 w = ctx->sps->pic_width_in_mbs * 16;
1088 RK_U32 h = ctx->sps->pic_height_in_mbs * 16;
1089
1090 /* roi setup */
1091 if (roi && roi->number && roi->regions) {
1092 RK_S32 roi_buf_size = vepu541_get_roi_buf_size(w, h);
1093
1094 if (!ctx->roi_buf || roi_buf_size != ctx->roi_buf_size) {
1095 if (NULL == ctx->roi_grp)
1096 mpp_buffer_group_get_internal(&ctx->roi_grp, MPP_BUFFER_TYPE_ION);
1097 else if (roi_buf_size != ctx->roi_buf_size) {
1098 if (ctx->roi_buf) {
1099 mpp_buffer_put(ctx->roi_buf);
1100 ctx->roi_buf = NULL;
1101 }
1102 mpp_buffer_group_clear(ctx->roi_grp);
1103 }
1104
1105 mpp_assert(ctx->roi_grp);
1106
1107 if (NULL == ctx->roi_buf)
1108 mpp_buffer_get(ctx->roi_grp, &ctx->roi_buf, roi_buf_size);
1109
1110 ctx->roi_buf_size = roi_buf_size;
1111 }
1112
1113 mpp_assert(ctx->roi_buf);
1114 RK_S32 fd = mpp_buffer_get_fd(ctx->roi_buf);
1115 void *buf = mpp_buffer_get_ptr(ctx->roi_buf);
1116
1117 regs->reg013.roi_enc = 1;
1118 regs->reg073.roi_addr = fd;
1119
1120 vepu541_set_roi(buf, roi, w, h);
1121 mpp_buffer_sync_end(ctx->roi_buf);
1122 } else {
1123 regs->reg013.roi_enc = 0;
1124 regs->reg073.roi_addr = 0;
1125 }
1126 }
1127
1128 hal_h264e_dbg_func("leave\n");
1129 }
1130
setup_vepu541_recn_refr(Vepu541H264eRegSet * regs,MppDev dev,H264eFrmInfo * frms,HalBufs bufs,RK_S32 fbc_hdr_size)1131 static void setup_vepu541_recn_refr(Vepu541H264eRegSet *regs, MppDev dev,
1132 H264eFrmInfo *frms, HalBufs bufs,
1133 RK_S32 fbc_hdr_size)
1134 {
1135 HalBuf *curr = hal_bufs_get_buf(bufs, frms->curr_idx);
1136 HalBuf *refr = hal_bufs_get_buf(bufs, frms->refr_idx);
1137
1138 hal_h264e_dbg_func("enter\n");
1139
1140 if (curr && curr->cnt) {
1141 MppBuffer buf_pixel = curr->buf[0];
1142 MppBuffer buf_thumb = curr->buf[1];
1143 RK_S32 fd = mpp_buffer_get_fd(buf_pixel);
1144
1145 mpp_assert(buf_pixel);
1146 mpp_assert(buf_thumb);
1147
1148 regs->reg074.rfpw_h_addr = fd;
1149 regs->reg075.rfpw_b_addr = fd;
1150 regs->reg080.dspw_addr = mpp_buffer_get_fd(buf_thumb);
1151
1152 mpp_dev_set_reg_offset(dev, 75, fbc_hdr_size);
1153 }
1154
1155 if (refr && refr->cnt) {
1156 MppBuffer buf_pixel = refr->buf[0];
1157 MppBuffer buf_thumb = refr->buf[1];
1158 RK_S32 fd = mpp_buffer_get_fd(buf_pixel);
1159
1160 mpp_assert(buf_pixel);
1161 mpp_assert(buf_thumb);
1162
1163 regs->reg076.rfpr_h_addr = fd;
1164 regs->reg077.rfpr_b_addr = fd;
1165 regs->reg081.dspr_addr = mpp_buffer_get_fd(buf_thumb);
1166
1167 mpp_dev_set_reg_offset(dev, 77, fbc_hdr_size);
1168 }
1169
1170 hal_h264e_dbg_func("leave\n");
1171 }
1172
setup_vepu541_split(Vepu541H264eRegSet * regs,MppEncSliceSplit * cfg)1173 static void setup_vepu541_split(Vepu541H264eRegSet *regs, MppEncSliceSplit *cfg)
1174 {
1175 hal_h264e_dbg_func("enter\n");
1176
1177 switch (cfg->split_mode) {
1178 case MPP_ENC_SPLIT_NONE : {
1179 regs->reg087.sli_splt = 0;
1180 regs->reg087.sli_splt_mode = 0;
1181 regs->reg087.sli_splt_cpst = 0;
1182 regs->reg087.sli_max_num_m1 = 0;
1183 regs->reg087.sli_flsh = 0;
1184 regs->reg087.sli_splt_cnum_m1 = 0;
1185
1186 regs->reg088.sli_splt_byte = 0;
1187 regs->reg013.slen_fifo = 0;
1188 } break;
1189 case MPP_ENC_SPLIT_BY_BYTE : {
1190 regs->reg087.sli_splt = 1;
1191 regs->reg087.sli_splt_mode = 0;
1192 regs->reg087.sli_splt_cpst = 0;
1193 regs->reg087.sli_max_num_m1 = 500;
1194 regs->reg087.sli_flsh = 1;
1195 regs->reg087.sli_splt_cnum_m1 = 0;
1196
1197 regs->reg088.sli_splt_byte = cfg->split_arg;
1198 regs->reg013.slen_fifo = 0;
1199 } break;
1200 case MPP_ENC_SPLIT_BY_CTU : {
1201 regs->reg087.sli_splt = 1;
1202 regs->reg087.sli_splt_mode = 1;
1203 regs->reg087.sli_splt_cpst = 0;
1204 regs->reg087.sli_max_num_m1 = 500;
1205 regs->reg087.sli_flsh = 1;
1206 regs->reg087.sli_splt_cnum_m1 = cfg->split_arg - 1;
1207
1208 regs->reg088.sli_splt_byte = 0;
1209 regs->reg013.slen_fifo = 0;
1210 } break;
1211 default : {
1212 mpp_log_f("invalide slice split mode %d\n", cfg->split_mode);
1213 } break;
1214 }
1215
1216 hal_h264e_dbg_func("leave\n");
1217 }
1218
setup_vepu540_force_slice_split(Vepu541H264eRegSet * regs,RK_S32 width)1219 static void setup_vepu540_force_slice_split(Vepu541H264eRegSet *regs, RK_S32 width)
1220 {
1221 RK_S32 mb_w = MPP_ALIGN(width, 16) >> 4;
1222
1223 hal_h264e_dbg_func("enter\n");
1224
1225 regs->reg087.sli_splt = 1;
1226 regs->reg087.sli_splt_mode = 1;
1227 regs->reg087.sli_splt_cpst = 0;
1228 regs->reg087.sli_max_num_m1 = 500;
1229 regs->reg087.sli_flsh = 1;
1230 regs->reg087.sli_splt_cnum_m1 = mb_w - 1;
1231
1232 regs->reg088.sli_splt_byte = 0;
1233 regs->reg013.slen_fifo = 0;
1234 regs->reg023.sli_crs_en = 0;
1235
1236 hal_h264e_dbg_func("leave\n");
1237 }
1238
setup_vepu541_me(Vepu541H264eRegSet * regs,H264eSps * sps,H264eSlice * slice,RK_U32 is_vepu540)1239 static void setup_vepu541_me(Vepu541H264eRegSet *regs, H264eSps *sps,
1240 H264eSlice *slice, RK_U32 is_vepu540)
1241 {
1242 RK_S32 level_idc = sps->level_idc;
1243 RK_S32 pic_w = sps->pic_width_in_mbs * 16;
1244 RK_S32 pic_wd64 = (pic_w + 63) / 64;
1245 RK_S32 cime_w = 176;
1246 RK_S32 cime_h = 112;
1247 RK_S32 cime_blk_w_max = 44;
1248 RK_S32 cime_blk_h_max = 28;
1249
1250 hal_h264e_dbg_func("enter\n");
1251 /*
1252 * Step 1. limit the mv range by level_idc
1253 * For level 1 and level 1b the vertical MV range is [-64,+63.75]
1254 * For level 1.1, 1.2, 1.3 and 2 the vertical MV range is [-128,+127.75]
1255 */
1256 switch (level_idc) {
1257 case H264_LEVEL_1_0 :
1258 case H264_LEVEL_1_b : {
1259 cime_blk_h_max = 12;
1260 } break;
1261 case H264_LEVEL_1_1 :
1262 case H264_LEVEL_1_2 :
1263 case H264_LEVEL_1_3 :
1264 case H264_LEVEL_2_0 : {
1265 cime_blk_h_max = 28;
1266 } break;
1267 default : {
1268 cime_blk_h_max = 28;
1269 } break;
1270 }
1271
1272 if (cime_w < cime_blk_w_max * 4)
1273 cime_blk_w_max = cime_w / 4;
1274
1275 if (cime_h < cime_blk_h_max * 4)
1276 cime_blk_h_max = cime_h / 4;
1277
1278 /*
1279 * Step 2. limit the mv range by image size
1280 */
1281 if (cime_blk_w_max / 4 * 2 > (sps->pic_width_in_mbs * 2 + 1) / 2)
1282 cime_blk_w_max = (sps->pic_width_in_mbs * 2 + 1) / 2 / 2 * 4;
1283
1284 if (cime_blk_h_max / 4 > MPP_ALIGN(sps->pic_height_in_mbs * 16, 64) / 128 * 4)
1285 cime_blk_h_max = MPP_ALIGN(sps->pic_height_in_mbs * 16, 64) / 128 * 16;
1286
1287 regs->reg089.cme_srch_h = cime_blk_w_max / 4;
1288 regs->reg089.cme_srch_v = cime_blk_h_max / 4;
1289 regs->reg089.rme_srch_h = 7;
1290 regs->reg089.rme_srch_v = 5;
1291 regs->reg089.dlt_frm_num = 0;
1292
1293 if (slice->slice_type == H264_I_SLICE) {
1294 regs->reg090.pmv_mdst_h = 0;
1295 regs->reg090.pmv_mdst_v = 0;
1296 } else {
1297 regs->reg090.pmv_mdst_h = 5;
1298 regs->reg090.pmv_mdst_v = 5;
1299 }
1300 regs->reg090.mv_limit = 2;
1301 regs->reg090.pmv_num = 2;
1302
1303 if (is_vepu540) {
1304 RK_S32 w_temp = 1296;
1305 RK_S32 h_temp = 1;
1306 RK_S32 h_val_0 = 1;
1307 RK_S32 h_val_1 = 18;
1308 RK_S32 temp0, temp1;
1309 RK_U32 pic_temp = ((regs->reg012.pic_wd8_m1 + 1) * 8 + 63) / 64 * 64;
1310 RK_S32 cime_linebuf_w = pic_temp / 64;
1311
1312 regs->reg091.cme_linebuf_w = cime_linebuf_w;
1313
1314 while ((w_temp > ((h_temp - h_val_0)*cime_linebuf_w * 4 + ((h_val_1 - h_temp) * 4 * 7)))
1315 && (h_temp < 17)) {
1316 h_temp = h_temp + h_val_0;
1317 }
1318 if (w_temp < ((h_temp - h_val_0)*cime_linebuf_w * 4 + ((h_val_1 - h_temp) * 4 * 7)))
1319 h_temp = h_temp - h_val_0;
1320
1321 regs->reg091.cme_rama_h = h_temp;
1322
1323 RK_S32 swin_scope_wd16 = (regs->reg089.cme_srch_h + 3) / 4 * 2 + 1;
1324
1325 temp0 = 2 * regs->reg089.cme_srch_v + 1;
1326 if (temp0 > regs->reg091.cme_rama_h)
1327 temp0 = regs->reg091.cme_rama_h;
1328
1329 temp1 = 0;
1330 if (pic_wd64 >= swin_scope_wd16)
1331 temp1 = swin_scope_wd16;
1332 else
1333 temp1 = pic_wd64 * 2;
1334 regs->reg091.cme_rama_max = pic_wd64 * (temp0 - 1) + temp1;
1335 } else {
1336 if (pic_w > 3584) {
1337 regs->reg091.cme_rama_h = 8;
1338 } else if (pic_w > 3136) {
1339 regs->reg091.cme_rama_h = 9;
1340 } else if (pic_w > 2816) {
1341 regs->reg091.cme_rama_h = 10;
1342 } else if (pic_w > 2560) {
1343 regs->reg091.cme_rama_h = 11;
1344 } else if (pic_w > 2368) {
1345 regs->reg091.cme_rama_h = 12;
1346 } else if (pic_w > 2176) {
1347 regs->reg091.cme_rama_h = 13;
1348 } else if (pic_w > 2048) {
1349 regs->reg091.cme_rama_h = 14;
1350 } else if (pic_w > 1856) {
1351 regs->reg091.cme_rama_h = 15;
1352 } else if (pic_w > 1792) {
1353 regs->reg091.cme_rama_h = 16;
1354 } else {
1355 regs->reg091.cme_rama_h = 17;
1356 }
1357
1358 {
1359 RK_S32 swin_all_4_ver = 2 * regs->reg089.cme_srch_v + 1;
1360 RK_S32 swin_all_16_hor = (regs->reg089.cme_srch_h * 4 + 15) / 16 * 2 + 1;
1361
1362 if (swin_all_4_ver < regs->reg091.cme_rama_h)
1363 regs->reg091.cme_rama_max = (swin_all_4_ver - 1) * pic_wd64 + swin_all_16_hor;
1364 else
1365 regs->reg091.cme_rama_max = (regs->reg091.cme_rama_h - 1) * pic_wd64 + swin_all_16_hor;
1366 }
1367 }
1368 hal_h264e_dbg_func("leave\n");
1369 }
1370
1371 #define H264E_LAMBDA_TAB_SIZE (52 * sizeof(RK_U32))
1372
1373 static RK_U32 h264e_lambda_default[58] = {
1374 0x00000003, 0x00000005, 0x00000006, 0x00000007,
1375 0x00000009, 0x0000000b, 0x0000000e, 0x00000012,
1376 0x00000016, 0x0000001c, 0x00000024, 0x0000002d,
1377 0x00000039, 0x00000048, 0x0000005b, 0x00000073,
1378 0x00000091, 0x000000b6, 0x000000e6, 0x00000122,
1379 0x0000016d, 0x000001cc, 0x00000244, 0x000002db,
1380 0x00000399, 0x00000489, 0x000005b6, 0x00000733,
1381 0x00000912, 0x00000b6d, 0x00000e66, 0x00001224,
1382 0x000016db, 0x00001ccc, 0x00002449, 0x00002db7,
1383 0x00003999, 0x00004892, 0x00005b6f, 0x00007333,
1384 0x00009124, 0x0000b6de, 0x0000e666, 0x00012249,
1385 0x00016dbc, 0x0001cccc, 0x00024492, 0x0002db79,
1386 0x00039999, 0x00048924, 0x0005b6f2, 0x00073333,
1387 0x00091249, 0x000b6de5, 0x000e6666, 0x00122492,
1388 0x0016dbcb, 0x001ccccc,
1389 };
1390
setup_vepu541_l2(Vepu541H264eRegL2Set * regs,H264eSlice * slice,MppEncHwCfg * hw,MppEncCfgSet * cfg)1391 static void setup_vepu541_l2(Vepu541H264eRegL2Set *regs, H264eSlice *slice, MppEncHwCfg *hw, MppEncCfgSet *cfg)
1392 {
1393 RK_U32 i;
1394
1395 hal_h264e_dbg_func("enter\n");
1396
1397 memset(regs, 0, sizeof(*regs));
1398
1399 regs->iprd_tthdy4[0] = 1;
1400 regs->iprd_tthdy4[1] = 4;
1401 regs->iprd_tthdy4[2] = 9;
1402 regs->iprd_tthdy4[3] = 36;
1403
1404 regs->iprd_tthdc8[0] = 1;
1405 regs->iprd_tthdc8[1] = 4;
1406 regs->iprd_tthdc8[2] = 9;
1407 regs->iprd_tthdc8[3] = 36;
1408
1409 regs->iprd_tthdy8[0] = 1;
1410 regs->iprd_tthdy8[1] = 4;
1411 regs->iprd_tthdy8[2] = 9;
1412 regs->iprd_tthdy8[3] = 36;
1413
1414 regs->iprd_wgty8[0] = 0x30;
1415 regs->iprd_wgty8[1] = 0x3c;
1416 regs->iprd_wgty8[2] = 0x28;
1417 regs->iprd_wgty8[3] = 0x30;
1418
1419 regs->iprd_wgty4[0] = 0x30;
1420 regs->iprd_wgty4[1] = 0x3c;
1421 regs->iprd_wgty4[2] = 0x28;
1422 regs->iprd_wgty4[3] = 0x30;
1423
1424 regs->iprd_wgty16[0] = 0x30;
1425 regs->iprd_wgty16[1] = 0x3c;
1426 regs->iprd_wgty16[2] = 0x28;
1427 regs->iprd_wgty16[3] = 0x30;
1428
1429 regs->iprd_wgtc8[0] = 0x24;
1430 regs->iprd_wgtc8[1] = 0x2a;
1431 regs->iprd_wgtc8[2] = 0x1c;
1432 regs->iprd_wgtc8[3] = 0x20;
1433
1434 if (cfg->tune.scene_mode == MPP_ENC_SCENE_MODE_IPC) {
1435 regs->iprd_tthd_ul = 0x0;
1436 regs->rme_mvd_penalty.mvd_pnlt_e = 1;
1437 regs->rme_mvd_penalty.mvd_pnlt_coef = 1;
1438 if (slice->slice_type == H264_I_SLICE) {
1439 regs->qnt_bias_comb.qnt_bias_i = 683;
1440 regs->atr_thd1_h264.atr_thd2 = 36;
1441 regs->atr_wgt16_h264.atr_lv16_wgt0 = 16;
1442 regs->atr_wgt16_h264.atr_lv16_wgt1 = 16;
1443 regs->atr_wgt16_h264.atr_lv16_wgt2 = 16;
1444
1445 regs->atr_wgt8_h264.atr_lv8_wgt0 = 32;
1446 regs->atr_wgt8_h264.atr_lv8_wgt1 = 32;
1447 regs->atr_wgt8_h264.atr_lv8_wgt2 = 32;
1448
1449 regs->atr_wgt4_h264.atr_lv4_wgt0 = 20;
1450 regs->atr_wgt4_h264.atr_lv4_wgt1 = 18;
1451 regs->atr_wgt4_h264.atr_lv4_wgt2 = 16;
1452 } else {
1453 regs->qnt_bias_comb.qnt_bias_i = 583;
1454 regs->atr_thd1_h264.atr_thd2 = 81;
1455 regs->atr_wgt16_h264.atr_lv16_wgt0 = 28;
1456 regs->atr_wgt16_h264.atr_lv16_wgt1 = 27;
1457 regs->atr_wgt16_h264.atr_lv16_wgt2 = 23;
1458
1459 regs->atr_wgt8_h264.atr_lv8_wgt0 = 32;
1460 regs->atr_wgt8_h264.atr_lv8_wgt1 = 32;
1461 regs->atr_wgt8_h264.atr_lv8_wgt2 = 32;
1462
1463 regs->atr_wgt4_h264.atr_lv4_wgt0 = 28;
1464 regs->atr_wgt4_h264.atr_lv4_wgt1 = 27;
1465 regs->atr_wgt4_h264.atr_lv4_wgt2 = 23;
1466 }
1467 } else {
1468 regs->iprd_tthd_ul = 0x9c5;
1469 regs->rme_mvd_penalty.mvd_pnlt_e = 0;
1470 regs->rme_mvd_penalty.mvd_pnlt_coef = 0;
1471 if (slice->slice_type == H264_I_SLICE) {
1472 regs->qnt_bias_comb.qnt_bias_i = 683;
1473 regs->atr_thd1_h264.atr_thd2 = 36;
1474 regs->atr_wgt16_h264.atr_lv16_wgt0 = 16;
1475 regs->atr_wgt16_h264.atr_lv16_wgt1 = 16;
1476 regs->atr_wgt16_h264.atr_lv16_wgt2 = 16;
1477
1478 regs->atr_wgt8_h264.atr_lv8_wgt0 = 20;
1479 regs->atr_wgt8_h264.atr_lv8_wgt1 = 20;
1480 regs->atr_wgt8_h264.atr_lv8_wgt2 = 20;
1481
1482 regs->atr_wgt4_h264.atr_lv4_wgt0 = 20;
1483 regs->atr_wgt4_h264.atr_lv4_wgt1 = 18;
1484 regs->atr_wgt4_h264.atr_lv4_wgt2 = 16;
1485 } else {
1486 regs->qnt_bias_comb.qnt_bias_i = 583;
1487 regs->atr_thd1_h264.atr_thd2 = 81;
1488 regs->atr_wgt16_h264.atr_lv16_wgt0 = 18;
1489 regs->atr_wgt16_h264.atr_lv16_wgt1 = 17;
1490 regs->atr_wgt16_h264.atr_lv16_wgt2 = 16;
1491
1492 regs->atr_wgt8_h264.atr_lv8_wgt0 = 20;
1493 regs->atr_wgt8_h264.atr_lv8_wgt1 = 20;
1494 regs->atr_wgt8_h264.atr_lv8_wgt2 = 20;
1495
1496 regs->atr_wgt4_h264.atr_lv4_wgt0 = 18;
1497 regs->atr_wgt4_h264.atr_lv4_wgt1 = 17;
1498 regs->atr_wgt4_h264.atr_lv4_wgt2 = 16;
1499 }
1500 }
1501
1502 /* 000556ab */
1503 regs->qnt_bias_comb.qnt_bias_p = 171;
1504 if (hw->qbias_en) {
1505 regs->qnt_bias_comb.qnt_bias_i = hw->qbias_i;
1506 regs->qnt_bias_comb.qnt_bias_p = hw->qbias_p;
1507 }
1508
1509 regs->atr_thd0_h264.atr_thd0 = 1;
1510 regs->atr_thd0_h264.atr_thd1 = 4;
1511 regs->atr_thd1_h264.atr_qp = 45;
1512 regs->atf_tthd[0] = 0;
1513 regs->atf_tthd[1] = 64;
1514 regs->atf_tthd[2] = 144;
1515 regs->atf_tthd[3] = 2500;
1516
1517 regs->atf_sthd0_h264.atf_sthd_10 = 80;
1518 regs->atf_sthd0_h264.atf_sthd_max = 280;
1519
1520 regs->atf_sthd1_h264.atf_sthd_11 = 144;
1521 regs->atf_sthd1_h264.atf_sthd_20 = 192;
1522
1523 regs->atf_wgt0_h264.atf_wgt10 = 26;
1524 regs->atf_wgt0_h264.atf_wgt11 = 24;
1525
1526 regs->atf_wgt1_h264.atf_wgt12 = 19;
1527 regs->atf_wgt1_h264.atf_wgt20 = 22;
1528
1529 regs->atf_wgt2_h264.atf_wgt21 = 19;
1530 regs->atf_wgt2_h264.atf_wgt30 = 19;
1531
1532 regs->atf_ofst0_h264.atf_ofst10 = 3500;
1533 regs->atf_ofst0_h264.atf_ofst11 = 3500;
1534
1535 regs->atf_ofst1_h264.atf_ofst12 = 0;
1536 regs->atf_ofst1_h264.atf_ofst20 = 3500;
1537
1538 regs->atf_ofst2_h264.atf_ofst21 = 1000;
1539 regs->atf_ofst2_h264.atf_ofst30 = 0;
1540
1541 regs->iprd_wgt_qp[0] = 0;
1542 /* ~ */
1543 regs->iprd_wgt_qp[51] = 0;
1544
1545 memcpy(regs->wgt_qp_grpa, &h264e_lambda_default[6], H264E_LAMBDA_TAB_SIZE);
1546 memcpy(regs->wgt_qp_grpb, &h264e_lambda_default[5], H264E_LAMBDA_TAB_SIZE);
1547
1548 regs->madi_mode = 0;
1549
1550 memcpy(regs->aq_tthd, h264_aq_tthd_default, sizeof(regs->aq_tthd));
1551
1552 if (slice->slice_type == H264_I_SLICE) {
1553 for (i = 0; i < MPP_ARRAY_ELEMS(regs->aq_step); i++) {
1554 regs->aq_tthd[i] = hw->aq_thrd_i[i];
1555 regs->aq_step[i] = hw->aq_step_i[i] & 0x3f;
1556 }
1557 } else {
1558 for (i = 0; i < MPP_ARRAY_ELEMS(regs->aq_step); i++) {
1559 regs->aq_tthd[i] = hw->aq_thrd_p[i];
1560 regs->aq_step[i] = hw->aq_step_p[i] & 0x3f;
1561 }
1562 }
1563
1564 regs->rme_mvd_penalty.mvd_pnlt_cnst = 16000;
1565 regs->rme_mvd_penalty.mvd_pnlt_lthd = 0;
1566 regs->rme_mvd_penalty.mvd_pnlt_hthd = 0;
1567
1568 regs->atr1_thd0_h264.atr1_thd0 = 1;
1569 regs->atr1_thd0_h264.atr1_thd1 = 4;
1570 regs->atr1_thd1_h264.atr1_thd2 = 49;
1571
1572 mpp_env_get_u32("dump_l2_reg", &dump_l2_reg, 0);
1573
1574 if (dump_l2_reg) {
1575 mpp_log("L2 reg dump start:\n");
1576 RK_U32 *p = (RK_U32 *)regs;
1577
1578 for (i = 0; i < (sizeof(*regs) / sizeof(RK_U32)); i++)
1579 mpp_log("%04x %08x\n", 4 + i * 4, p[i]);
1580
1581 mpp_log("L2 reg done\n");
1582 }
1583
1584 hal_h264e_dbg_func("leave\n");
1585 }
1586
hal_h264e_vepu541_gen_regs(void * hal,HalEncTask * task)1587 static MPP_RET hal_h264e_vepu541_gen_regs(void *hal, HalEncTask *task)
1588 {
1589 HalH264eVepu541Ctx *ctx = (HalH264eVepu541Ctx *)hal;
1590 Vepu541H264eRegSet *regs = &ctx->regs_set;
1591 MppEncCfgSet *cfg = ctx->cfg;
1592 MppEncPrepCfg *prep = &cfg->prep;
1593 H264eSps *sps = ctx->sps;
1594 H264ePps *pps = ctx->pps;
1595 H264eSlice *slice = ctx->slice;
1596 MPP_RET ret = MPP_OK;
1597 EncFrmStatus *frm_status = &task->rc_task->frm;
1598
1599 hal_h264e_dbg_func("enter %p\n", hal);
1600 hal_h264e_dbg_detail("frame %d generate regs now", ctx->frms->seq_idx);
1601
1602 /* register setup */
1603 memset(regs, 0, sizeof(*regs));
1604
1605 setup_vepu541_normal(regs, ctx->is_vepu540);
1606 ret = setup_vepu541_prep(regs, ctx, task);
1607 if (ret)
1608 return ret;
1609
1610 setup_vepu541_codec(regs, sps, pps, slice);
1611 setup_vepu541_rdo_pred(regs, sps, pps, slice, cfg);
1612 setup_vepu541_rc_base(regs, sps, slice, &cfg->hw, task->rc_task);
1613 setup_vepu541_io_buf(regs, ctx->dev, task);
1614 setup_vepu541_roi(regs, ctx);
1615 setup_vepu541_recn_refr(regs, ctx->dev, ctx->frms, ctx->hw_recn,
1616 ctx->pixel_buf_fbc_hdr_size);
1617
1618 regs->reg082.meiw_addr = task->md_info ? mpp_buffer_get_fd(task->md_info) : 0;
1619
1620 regs->reg068.pic_ofst_y = mpp_frame_get_offset_y(task->frame);
1621 regs->reg068.pic_ofst_x = mpp_frame_get_offset_x(task->frame);
1622
1623 setup_vepu541_split(regs, &cfg->split);
1624 if (ctx->is_vepu540 && prep->width > 1920)
1625 setup_vepu540_force_slice_split(regs, prep->width);
1626
1627 setup_vepu541_me(regs, sps, slice, ctx->is_vepu540);
1628
1629 if (frm_status->is_i_refresh)
1630 setup_vepu541_intra_refresh(regs, ctx, frm_status->seq_idx % cfg->rc.gop);
1631
1632 if (ctx->is_vepu540)
1633 vepu540_set_osd(&ctx->osd_cfg);
1634 else
1635 vepu541_set_osd(&ctx->osd_cfg);
1636
1637 setup_vepu541_l2(&ctx->regs_l2_set, slice, &cfg->hw, cfg);
1638
1639 mpp_env_get_u32("dump_l1_reg", &dump_l1_reg, 0);
1640
1641 if (dump_l1_reg) {
1642 mpp_log("L1 reg dump start:\n");
1643 RK_U32 *p = (RK_U32 *)regs;
1644 RK_S32 n = 0x1D0 / sizeof(RK_U32);
1645 RK_S32 i;
1646
1647 for (i = 0; i < n; i++)
1648 mpp_log("%04x %08x\n", i * 4, p[i]);
1649
1650 mpp_log("L1 reg done\n");
1651 }
1652
1653 ctx->frame_cnt++;
1654
1655 hal_h264e_dbg_func("leave %p\n", hal);
1656 return MPP_OK;
1657 }
1658
hal_h264e_vepu541_start(void * hal,HalEncTask * task)1659 static MPP_RET hal_h264e_vepu541_start(void *hal, HalEncTask *task)
1660 {
1661 MPP_RET ret = MPP_OK;
1662 HalH264eVepu541Ctx *ctx = (HalH264eVepu541Ctx *)hal;
1663
1664 (void) task;
1665
1666 hal_h264e_dbg_func("enter %p\n", hal);
1667
1668 do {
1669 MppDevRegWrCfg wr_cfg;
1670 MppDevRegRdCfg rd_cfg;
1671
1672 /* write L2 registers */
1673 wr_cfg.reg = &ctx->regs_l2_set;
1674 wr_cfg.size = sizeof(Vepu541H264eRegL2Set);
1675 wr_cfg.offset = VEPU541_REG_BASE_L2;
1676
1677 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
1678 if (ret) {
1679 mpp_err_f("set register write failed %d\n", ret);
1680 break;
1681 }
1682
1683 /* write L1 registers */
1684 wr_cfg.reg = &ctx->regs_set;
1685 wr_cfg.size = sizeof(Vepu541H264eRegSet);
1686 wr_cfg.offset = 0;
1687
1688 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
1689 if (ret) {
1690 mpp_err_f("set register write failed %d\n", ret);
1691 break;
1692 }
1693
1694 /* set output request */
1695 rd_cfg.reg = &ctx->regs_ret.hw_status;
1696 rd_cfg.size = sizeof(RK_U32);
1697 rd_cfg.offset = VEPU541_REG_BASE_HW_STATUS;
1698
1699 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
1700 if (ret) {
1701 mpp_err_f("set register read failed %d\n", ret);
1702 break;
1703 }
1704
1705 rd_cfg.reg = &ctx->regs_ret.st_bsl;
1706 rd_cfg.size = sizeof(ctx->regs_ret) - 4;
1707 rd_cfg.offset = VEPU541_REG_BASE_STATISTICS;
1708
1709 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
1710 if (ret) {
1711 mpp_err_f("set register read failed %d\n", ret);
1712 break;
1713 }
1714
1715 /* send request to hardware */
1716 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
1717 if (ret) {
1718 mpp_err_f("send cmd failed %d\n", ret);
1719 break;
1720 }
1721 } while (0);
1722
1723 hal_h264e_dbg_func("leave %p\n", hal);
1724
1725 return ret;
1726 }
1727
hal_h264e_vepu541_status_check(void * hal)1728 static MPP_RET hal_h264e_vepu541_status_check(void *hal)
1729 {
1730 HalH264eVepu541Ctx *ctx = (HalH264eVepu541Ctx *)hal;
1731 Vepu541H264eRegRet *regs_ret = &ctx->regs_ret;
1732
1733 if (regs_ret->hw_status.lkt_done_sta)
1734 hal_h264e_dbg_detail("lkt_done finish");
1735
1736 if (regs_ret->hw_status.enc_done_sta)
1737 hal_h264e_dbg_detail("enc_done finish");
1738
1739 if (regs_ret->hw_status.enc_slice_done_sta)
1740 hal_h264e_dbg_detail("enc_slice finsh");
1741
1742 if (regs_ret->hw_status.sclr_done_sta)
1743 hal_h264e_dbg_detail("safe clear finsh");
1744
1745 if (regs_ret->hw_status.oflw_done_sta)
1746 mpp_err_f("bit stream overflow");
1747
1748 if (regs_ret->hw_status.brsp_done_sta)
1749 mpp_err_f("bus write full");
1750
1751 if (regs_ret->hw_status.berr_done_sta)
1752 mpp_err_f("bus write error");
1753
1754 if (regs_ret->hw_status.rerr_done_sta)
1755 mpp_err_f("bus read error");
1756
1757 if (regs_ret->hw_status.wdg_done_sta)
1758 mpp_err_f("wdg timeout");
1759
1760 return MPP_OK;
1761 }
1762
hal_h264e_vepu541_wait(void * hal,HalEncTask * task)1763 static MPP_RET hal_h264e_vepu541_wait(void *hal, HalEncTask *task)
1764 {
1765 MPP_RET ret = MPP_OK;
1766 HalH264eVepu541Ctx *ctx = (HalH264eVepu541Ctx *)hal;
1767 H264NaluType type = task->rc_task->frm.is_idr ? H264_NALU_TYPE_IDR : H264_NALU_TYPE_SLICE;
1768 MppPacket pkt = task->packet;
1769 RK_S32 offset = mpp_packet_get_length(pkt);
1770
1771 hal_h264e_dbg_func("enter %p\n", hal);
1772
1773 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
1774 if (ret) {
1775 mpp_err_f("poll cmd failed %d\n", ret);
1776 ret = MPP_ERR_VPUHW;
1777 } else {
1778 hal_h264e_vepu541_status_check(hal);
1779 task->hw_length += ctx->regs_ret.st_bsl.bs_lgth;
1780 }
1781
1782 mpp_packet_add_segment_info(pkt, type, offset, ctx->regs_ret.st_bsl.bs_lgth);
1783
1784 {
1785 HalH264eVepuStreamAmend *amend = &ctx->amend;
1786
1787 if (amend->enable) {
1788 amend->old_length = task->hw_length;
1789 amend->slice->is_multi_slice = (ctx->cfg->split.split_mode > 0);
1790 h264e_vepu_stream_amend_proc(amend, &ctx->cfg->h264.hw_cfg);
1791 task->hw_length = amend->new_length;
1792 } else if (amend->prefix) {
1793 /* check prefix value */
1794 amend->old_length = task->hw_length;
1795 h264e_vepu_stream_amend_sync_ref_idc(amend);
1796 }
1797 }
1798 hal_h264e_dbg_func("leave %p\n", hal);
1799
1800 return ret;
1801 }
1802
hal_h264e_vepu541_ret_task(void * hal,HalEncTask * task)1803 static MPP_RET hal_h264e_vepu541_ret_task(void *hal, HalEncTask *task)
1804 {
1805 HalH264eVepu541Ctx *ctx = (HalH264eVepu541Ctx *)hal;
1806 EncRcTaskInfo *rc_info = &task->rc_task->info;
1807 RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
1808 RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
1809 RK_U32 mbs = mb_w * mb_h;
1810
1811 hal_h264e_dbg_func("enter %p\n", hal);
1812
1813 // update total hardware length
1814 task->length += task->hw_length;
1815
1816 // setup bit length for rate control
1817 rc_info->bit_real = task->hw_length * 8;
1818 rc_info->quality_real = ctx->regs_ret.st_sse_qp.qp_sum / mbs;
1819 rc_info->madi = (!ctx->regs_ret.st_mb_num) ? 0 :
1820 ctx->regs_ret.st_madi / ctx->regs_ret.st_mb_num;
1821 rc_info->madp = (!ctx->regs_ret.st_ctu_num) ? 0 :
1822 ctx->regs_ret.st_madp / ctx->regs_ret.st_ctu_num;
1823 rc_info->iblk4_prop = (ctx->regs_ret.st_lvl4_intra_num +
1824 ctx->regs_ret.st_lvl8_intra_num +
1825 ctx->regs_ret.st_lvl16_intra_num) * 256 / mbs;
1826
1827 rc_info->sse = ((RK_S64)(ctx->regs_ret.st_sse_qp.sse_h8 & 0xff) << 32) +
1828 ctx->regs_ret.st_sse_l32.sse_l32;
1829 rc_info->lvl16_inter_num = ctx->regs_ret.st_lvl16_inter_num;
1830 rc_info->lvl8_inter_num = ctx->regs_ret.st_lvl8_inter_num;
1831 rc_info->lvl16_intra_num = ctx->regs_ret.st_lvl16_intra_num;
1832 rc_info->lvl8_intra_num = ctx->regs_ret.st_lvl8_intra_num;
1833 rc_info->lvl4_intra_num = ctx->regs_ret.st_lvl4_intra_num;
1834
1835 ctx->hal_rc_cfg.bit_real = rc_info->bit_real;
1836 ctx->hal_rc_cfg.quality_real = rc_info->quality_real;
1837 ctx->hal_rc_cfg.iblk4_prop = rc_info->iblk4_prop;
1838
1839 task->hal_ret.data = &ctx->hal_rc_cfg;
1840 task->hal_ret.number = 1;
1841
1842 hal_h264e_dbg_func("leave %p\n", hal);
1843
1844 return MPP_OK;
1845 }
1846
1847 const MppEncHalApi hal_h264e_vepu541 = {
1848 .name = "hal_h264e_vepu541",
1849 .coding = MPP_VIDEO_CodingAVC,
1850 .ctx_size = sizeof(HalH264eVepu541Ctx),
1851 .flag = 0,
1852 .init = hal_h264e_vepu541_init,
1853 .deinit = hal_h264e_vepu541_deinit,
1854 .prepare = hal_h264e_vepu541_prepare,
1855 .get_task = hal_h264e_vepu541_get_task,
1856 .gen_regs = hal_h264e_vepu541_gen_regs,
1857 .start = hal_h264e_vepu541_start,
1858 .wait = hal_h264e_vepu541_wait,
1859 .part_start = NULL,
1860 .part_wait = NULL,
1861 .ret_task = hal_h264e_vepu541_ret_task,
1862 };
1863