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