xref: /rockchip-linux_mpp/mpp/hal/rkenc/h264e/hal_h264e_vepu580.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /*
2  * Copyright 2021 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_vepu580"
18 
19 #include <string.h>
20 
21 #include "mpp_env.h"
22 #include "mpp_mem.h"
23 #include "mpp_common.h"
24 #include "mpp_frame_impl.h"
25 #include "mpp_packet_impl.h"
26 #include "mpp_rc.h"
27 
28 #include "h264e_sps.h"
29 #include "h264e_pps.h"
30 #include "h264e_dpb.h"
31 #include "h264e_slice.h"
32 
33 #include "hal_h264e_debug.h"
34 #include "hal_bufs.h"
35 #include "mpp_enc_hal.h"
36 #include "rkv_enc_def.h"
37 #include "vepu5xx_common.h"
38 #include "vepu580_common.h"
39 #include "vepu5xx.h"
40 #include "hal_h264e_vepu580_reg.h"
41 #include "mpp_enc_cb_param.h"
42 #include "hal_h264e_stream_amend.h"
43 
44 #define DUMP_REG 0
45 #define MAX_TASK_CNT        2
46 
47 typedef struct Vepu580RoiH264BsCfg_t {
48     RK_U64 force_inter   : 42;
49     RK_U64 mode_mask     : 9;
50     RK_U64 reserved      : 10;
51     RK_U64 force_intra   : 1;
52     RK_U64 qp_adj_en     : 1;
53     RK_U64 amv_en        : 1;
54 } Vepu580RoiH264BsCfg;
55 
56 typedef struct HalH264eVepu580Ctx_t {
57     MppEncCfgSet            *cfg;
58 
59     MppDev                  dev;
60     RK_S32                  frame_cnt;
61     RK_U32                  task_cnt;
62 
63     /* buffers management */
64     HalBufs                 hw_recn;
65     RK_S32                  pixel_buf_fbc_hdr_size;
66     RK_S32                  pixel_buf_fbc_bdy_size;
67     RK_S32                  pixel_buf_size;
68     RK_S32                  thumb_buf_size;
69     RK_S32                  max_buf_cnt;
70     MppDevRegOffCfgs        *offsets;
71 
72     /* external line buffer over 4K */
73     MppBufferGroup          ext_line_buf_grp;
74     MppBuffer               ext_line_bufs[MAX_TASK_CNT];
75     RK_S32                  ext_line_buf_size;
76 
77     /* syntax for input from enc_impl */
78     RK_U32                  updated;
79     H264eSps                *sps;
80     H264ePps                *pps;
81     H264eDpb                *dpb;
82     H264eFrmInfo            *frms;
83 
84     /* async encode TSVC info */
85     H264eReorderInfo        *reorder;
86     H264eMarkingInfo        *marking;
87 
88     /* syntax for output to enc_impl */
89     EncRcTaskInfo           hal_rc_cfg;
90 
91     /* roi */
92     void                    *roi_data;
93     MppBufferGroup          roi_grp;
94     MppBuffer               roi_base_cfg_buf;
95     RK_S32                  roi_base_buf_size;
96 
97     /* osd */
98     Vepu5xxOsdCfg           osd_cfg;
99 
100     /* finetune */
101     void                    *tune;
102     MppBuffer               qpmap_base_cfg_buf;
103     MppBuffer               qpmap_qp_cfg_buf;
104     RK_U8*                  md_flag_buf;
105     RK_S32                  qpmap_base_cfg_size;
106     RK_S32                  qpmap_qp_cfg_size;
107     RK_S32                  md_flag_size;
108 
109     /* two-pass deflicker */
110     MppBuffer               buf_pass1;
111 
112     /* register */
113     HalVepu580RegSet        *regs_sets;
114     HalH264eVepuStreamAmend *amend_sets;
115 
116     H264ePrefixNal          *prefix_sets;
117     H264eSlice              *slice_sets;
118 
119     /* frame parallel info */
120     RK_S32                  task_idx;
121     RK_S32                  curr_idx;
122     RK_S32                  prev_idx;
123     HalVepu580RegSet        *regs_set;
124     HalH264eVepuStreamAmend *amend;
125     H264ePrefixNal          *prefix;
126     H264eSlice              *slice;
127 
128     MppBuffer               ext_line_buf;
129 
130     /* slice low delay output callback */
131     MppCbCtx                *output_cb;
132     RK_S32                  poll_slice_max;
133     RK_S32                  poll_cfg_size;
134     MppDevPollCfg           *poll_cfgs;
135 } HalH264eVepu580Ctx;
136 
137 #define CHROMA_KLUT_TAB_SIZE    (24 * sizeof(RK_U32))
138 
139 static RK_U32 h264e_klut_weight[30] = {
140     0x0a000010, 0x00064000, 0x14000020, 0x000c8000,
141     0x28000040, 0x00194000, 0x50800080, 0x0032c000,
142     0xa1000100, 0x00658000, 0x42800200, 0x00cb0001,
143     0x85000400, 0x01964002, 0x0a000800, 0x032c8005,
144     0x14001000, 0x0659400a, 0x28802000, 0x0cb2c014,
145     0x51004000, 0x1965c028, 0xa2808000, 0x32cbc050,
146     0x4500ffff, 0x659780a1, 0x8a81fffe, 0xCC000142,
147     0xFF83FFFF, 0x000001FF,
148 };
149 
150 static RK_U32 disable_rcb_buf = 0;
151 
152 static RK_U32 h264_mode_bias[16] = {
153     0,  2,  4,  6,
154     8,  10, 12, 14,
155     16, 18, 20, 24,
156     28, 32, 64, 128
157 };
158 
159 static RK_S32 h264_aq_tthd_default[16] = {
160     0,  0,  0,  0,
161     3,  3,  5,  5,
162     8,  8,  8,  15,
163     15, 20, 25, 35,
164 };
165 
166 static RK_S32 h264_P_aq_step_default[16] = {
167     -8, -7, -6, -5,
168     -4, -3, -2, -1,
169     0,  1,  2,  3,
170     4,  5,  7,  8,
171 };
172 
173 static RK_S32 h264_I_aq_step_default[16] = {
174     -8, -7, -6, -5,
175     -4, -3, -2, -1,
176     0,  1,  2,  3,
177     4,  5,  6,  8,
178 };
179 
180 #include "hal_h264e_vepu580_tune.c"
181 
setup_ext_line_bufs(HalH264eVepu580Ctx * ctx)182 static void setup_ext_line_bufs(HalH264eVepu580Ctx *ctx)
183 {
184     RK_U32 i;
185 
186     for (i = 0; i < ctx->task_cnt; i++) {
187         if (ctx->ext_line_bufs[i])
188             continue;
189 
190         mpp_buffer_get(ctx->ext_line_buf_grp, &ctx->ext_line_bufs[i],
191                        ctx->ext_line_buf_size);
192     }
193 }
194 
clear_ext_line_bufs(HalH264eVepu580Ctx * ctx)195 static void clear_ext_line_bufs(HalH264eVepu580Ctx *ctx)
196 {
197     RK_U32 i;
198 
199     for (i = 0; i < ctx->task_cnt; i++) {
200         if (ctx->ext_line_bufs[i]) {
201             mpp_buffer_put(ctx->ext_line_bufs[i]);
202             ctx->ext_line_bufs[i] = NULL;
203         }
204     }
205 }
206 
hal_h264e_vepu580_deinit(void * hal)207 static MPP_RET hal_h264e_vepu580_deinit(void *hal)
208 {
209     HalH264eVepu580Ctx *p = (HalH264eVepu580Ctx *)hal;
210     RK_U32 i;
211 
212     hal_h264e_dbg_func("enter %p\n", p);
213 
214     if (p->dev) {
215         mpp_dev_deinit(p->dev);
216         p->dev = NULL;
217     }
218 
219     clear_ext_line_bufs(p);
220 
221     if (p->amend_sets) {
222         for (i = 0; i < p->task_cnt; i++)
223             h264e_vepu_stream_amend_deinit(&p->amend_sets[i]);
224     }
225 
226     MPP_FREE(p->regs_sets);
227     MPP_FREE(p->amend_sets);
228     MPP_FREE(p->prefix_sets);
229     MPP_FREE(p->slice_sets);
230     MPP_FREE(p->reorder);
231     MPP_FREE(p->marking);
232     MPP_FREE(p->poll_cfgs);
233 
234     if (p->ext_line_buf_grp) {
235         mpp_buffer_group_put(p->ext_line_buf_grp);
236         p->ext_line_buf_grp = NULL;
237     }
238 
239     if (p->hw_recn) {
240         hal_bufs_deinit(p->hw_recn);
241         p->hw_recn = NULL;
242     }
243 
244     if (p->roi_base_cfg_buf) {
245         mpp_buffer_put(p->roi_base_cfg_buf);
246         p->roi_base_cfg_buf = NULL;
247         p->roi_base_buf_size = 0;
248     }
249 
250     if (p->roi_grp) {
251         mpp_buffer_group_put(p->roi_grp);
252         p->roi_grp = NULL;
253     }
254 
255     if (p->offsets) {
256         mpp_dev_multi_offset_deinit(p->offsets);
257         p->offsets = NULL;
258     }
259 
260     if (p->buf_pass1) {
261         mpp_buffer_put(p->buf_pass1);
262         p->buf_pass1 = NULL;
263     }
264 
265     if (p->tune) {
266         vepu580_h264e_tune_deinit(p->tune);
267         p->tune = NULL;
268     }
269 
270     if (p->qpmap_base_cfg_buf) {
271         mpp_buffer_put(p->qpmap_base_cfg_buf);
272         p->qpmap_base_cfg_buf = NULL;
273     }
274 
275     if (p->qpmap_qp_cfg_buf) {
276         mpp_buffer_put(p->qpmap_qp_cfg_buf);
277         p->qpmap_qp_cfg_buf = NULL;
278     }
279 
280     if (p->md_flag_buf) {
281         MPP_FREE(p->md_flag_buf);
282     }
283 
284     hal_h264e_dbg_func("leave %p\n", p);
285 
286     return MPP_OK;
287 }
288 
hal_h264e_vepu580_init(void * hal,MppEncHalCfg * cfg)289 static MPP_RET hal_h264e_vepu580_init(void *hal, MppEncHalCfg *cfg)
290 {
291     HalH264eVepu580Ctx *p = (HalH264eVepu580Ctx *)hal;
292     MPP_RET ret = MPP_OK;
293     RK_U32 i;
294 
295     hal_h264e_dbg_func("enter %p\n", p);
296 
297     p->cfg = cfg->cfg;
298 
299     mpp_env_get_u32("disable_rcb_buf", &disable_rcb_buf, 0);
300 
301     /* update output to MppEnc */
302     cfg->type = VPU_CLIENT_RKVENC;
303     ret = mpp_dev_init(&cfg->dev, cfg->type);
304     if (ret) {
305         mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
306         goto DONE;
307     }
308     p->dev = cfg->dev;
309     p->task_cnt = cfg->task_cnt;
310     mpp_assert(p->task_cnt && p->task_cnt <= MAX_TASK_CNT);
311 
312     ret = hal_bufs_init(&p->hw_recn);
313     if (ret) {
314         mpp_err_f("init vepu buffer failed ret: %d\n", ret);
315         goto DONE;
316     }
317 
318     p->regs_sets = mpp_malloc(HalVepu580RegSet, p->task_cnt);
319     if (NULL == p->regs_sets) {
320         ret = MPP_ERR_MALLOC;
321         mpp_err_f("init register buffer failed\n");
322         goto DONE;
323     }
324     p->amend_sets = mpp_malloc(HalH264eVepuStreamAmend, p->task_cnt);
325     if (NULL == p->amend_sets) {
326         ret = MPP_ERR_MALLOC;
327         mpp_err_f("init amend data failed\n");
328         goto DONE;
329     }
330 
331     if (p->task_cnt > 1) {
332         p->prefix_sets = mpp_malloc(H264ePrefixNal, p->task_cnt);
333         if (NULL == p->prefix_sets) {
334             ret = MPP_ERR_MALLOC;
335             mpp_err_f("init amend data failed\n");
336             goto DONE;
337         }
338 
339         p->slice_sets = mpp_malloc(H264eSlice, p->task_cnt);
340         if (NULL == p->slice_sets) {
341             ret = MPP_ERR_MALLOC;
342             mpp_err_f("init amend data failed\n");
343             goto DONE;
344         }
345 
346         p->reorder = mpp_malloc(H264eReorderInfo, 1);
347         if (NULL == p->reorder) {
348             ret = MPP_ERR_MALLOC;
349             mpp_err_f("init amend data failed\n");
350             goto DONE;
351         }
352 
353         p->marking = mpp_malloc(H264eMarkingInfo, 1);
354         if (NULL == p->marking) {
355             ret = MPP_ERR_MALLOC;
356             mpp_err_f("init amend data failed\n");
357             goto DONE;
358         }
359     }
360 
361     p->poll_slice_max = 8;
362     p->poll_cfg_size = (sizeof(p->poll_cfgs) + sizeof(RK_S32) * p->poll_slice_max);
363     p->poll_cfgs = mpp_malloc_size(MppDevPollCfg, p->poll_cfg_size * p->task_cnt);
364     if (NULL == p->poll_cfgs) {
365         ret = MPP_ERR_MALLOC;
366         mpp_err_f("init poll cfg buffer failed\n");
367         goto DONE;
368     }
369 
370     p->osd_cfg.reg_base = &p->regs_sets->reg_osd;
371     p->osd_cfg.dev = p->dev;
372     p->osd_cfg.reg_cfg = NULL;
373     p->osd_cfg.plt_cfg = &p->cfg->plt_cfg;
374     p->osd_cfg.osd_data = NULL;
375     p->osd_cfg.osd_data2 = NULL;
376 
377     {   /* setup default hardware config */
378         MppEncHwCfg *hw = &cfg->cfg->hw;
379 
380         hw->qp_delta_row_i  = 2;
381         hw->qp_delta_row    = 2;
382         hw->extra_buf       = 1;
383         hw->qbias_i         = 683;
384         hw->qbias_p         = 341;
385         hw->qbias_en        = 0;
386 
387         memcpy(hw->aq_thrd_i, h264_aq_tthd_default, sizeof(hw->aq_thrd_i));
388         memcpy(hw->aq_thrd_p, h264_aq_tthd_default, sizeof(hw->aq_thrd_p));
389         memcpy(hw->aq_step_i, h264_I_aq_step_default, sizeof(hw->aq_step_i));
390         memcpy(hw->aq_step_p, h264_P_aq_step_default, sizeof(hw->aq_step_p));
391 
392         for (i = 0; i < MPP_ARRAY_ELEMS(hw->mode_bias); i++)
393             hw->mode_bias[i] = 8;
394 
395         hw->skip_sad  = 8;
396         hw->skip_bias = 8;
397     }
398     mpp_dev_multi_offset_init(&p->offsets, 24);
399     p->osd_cfg.reg_cfg = p->offsets;
400 
401     p->tune = vepu580_h264e_tune_init(p);
402     p->output_cb = cfg->output_cb;
403 
404     cfg->cap_recn_out = 1;
405 
406     for (i = 0; i < p->task_cnt; i++)
407         h264e_vepu_stream_amend_init(&p->amend_sets[i]);
408 
409 DONE:
410     if (ret)
411         hal_h264e_vepu580_deinit(hal);
412 
413     hal_h264e_dbg_func("leave %p\n", p);
414     return ret;
415 }
416 
417 /*
418  * NOTE: recon / refer buffer is FBC data buffer.
419  * And FBC data require extra 16 lines space for hardware io.
420  */
setup_hal_bufs(HalH264eVepu580Ctx * ctx)421 static void setup_hal_bufs(HalH264eVepu580Ctx *ctx)
422 {
423     MppEncCfgSet *cfg = ctx->cfg;
424     MppEncPrepCfg *prep = &cfg->prep;
425     RK_S32 alignment_w = 64;
426     RK_S32 alignment_h = 16;
427     RK_S32 aligned_w = MPP_ALIGN(prep->width,  alignment_w);
428     RK_S32 aligned_h = MPP_ALIGN(prep->height, alignment_h) + 16;
429     RK_S32 pixel_buf_fbc_hdr_size = MPP_ALIGN(aligned_w * aligned_h / 64, SZ_8K);
430     RK_S32 pixel_buf_fbc_bdy_size = aligned_w * aligned_h * 3 / 2;
431     RK_S32 pixel_buf_size = pixel_buf_fbc_hdr_size + pixel_buf_fbc_bdy_size;
432     RK_S32 thumb_buf_size = MPP_ALIGN(aligned_w / 64 * aligned_h / 64 * 256, SZ_8K);
433     RK_S32 old_max_cnt = ctx->max_buf_cnt;
434     RK_S32 new_max_cnt = 4;
435     MppEncRefCfg ref_cfg = cfg->ref_cfg;
436 
437     if (ref_cfg) {
438         MppEncCpbInfo *info = mpp_enc_ref_cfg_get_cpb_info(ref_cfg);
439         if (new_max_cnt < MPP_MAX(new_max_cnt, info->dpb_size + 1))
440             new_max_cnt = MPP_MAX(new_max_cnt, info->dpb_size + 1);
441     }
442 
443     if (aligned_w > SZ_4K) {
444         /* 480 bytes for each ctu above 3072 */
445         RK_S32 ext_line_buf_size = (aligned_w - 3 * SZ_1K) / 64 * 480;
446 
447         if (NULL == ctx->ext_line_buf_grp)
448             mpp_buffer_group_get_internal(&ctx->ext_line_buf_grp, MPP_BUFFER_TYPE_ION);
449         else if (ext_line_buf_size != ctx->ext_line_buf_size) {
450             clear_ext_line_bufs(ctx);
451             mpp_buffer_group_clear(ctx->ext_line_buf_grp);
452         }
453 
454         mpp_assert(ctx->ext_line_buf_grp);
455 
456         ctx->ext_line_buf_size = ext_line_buf_size;
457         setup_ext_line_bufs(ctx);
458     } else {
459         clear_ext_line_bufs(ctx);
460         if (ctx->ext_line_buf_grp) {
461             mpp_buffer_group_clear(ctx->ext_line_buf_grp);
462             mpp_buffer_group_put(ctx->ext_line_buf_grp);
463             ctx->ext_line_buf_grp = NULL;
464         }
465         ctx->ext_line_buf_size = 0;
466     }
467 
468     if ((ctx->pixel_buf_fbc_hdr_size != pixel_buf_fbc_hdr_size) ||
469         (ctx->pixel_buf_fbc_bdy_size != pixel_buf_fbc_bdy_size) ||
470         (ctx->pixel_buf_size != pixel_buf_size) ||
471         (ctx->thumb_buf_size != thumb_buf_size) ||
472         (new_max_cnt > old_max_cnt)) {
473         size_t sizes[2];
474 
475         hal_h264e_dbg_detail("frame size %d -> %d max count %d -> %d\n",
476                              ctx->pixel_buf_size, pixel_buf_size,
477                              old_max_cnt, new_max_cnt);
478 
479         /* pixel buffer */
480         sizes[0] = pixel_buf_size;
481         /* thumb buffer */
482         sizes[1] = thumb_buf_size;
483         new_max_cnt = MPP_MAX(new_max_cnt, old_max_cnt);
484 
485         hal_bufs_setup(ctx->hw_recn, new_max_cnt, 2, sizes);
486 
487         ctx->pixel_buf_fbc_hdr_size = pixel_buf_fbc_hdr_size;
488         ctx->pixel_buf_fbc_bdy_size = pixel_buf_fbc_bdy_size;
489         ctx->pixel_buf_size = pixel_buf_size;
490         ctx->thumb_buf_size = thumb_buf_size;
491         ctx->max_buf_cnt = new_max_cnt;
492     }
493 }
494 
hal_h264e_vepu580_prepare(void * hal)495 static MPP_RET hal_h264e_vepu580_prepare(void *hal)
496 {
497     HalH264eVepu580Ctx *ctx = (HalH264eVepu580Ctx *)hal;
498     MppEncPrepCfg *prep = &ctx->cfg->prep;
499 
500     hal_h264e_dbg_func("enter %p\n", hal);
501 
502     if (prep->change_res) {
503         RK_S32 i;
504 
505         // pre-alloc required buffers to reduce first frame delay
506         setup_hal_bufs(ctx);
507         for (i = 0; i < ctx->max_buf_cnt; i++)
508             hal_bufs_get_buf(ctx->hw_recn, i);
509 
510         prep->change_res = 0;
511     }
512 
513     hal_h264e_dbg_func("leave %p\n", hal);
514 
515     return MPP_OK;
516 }
517 
update_vepu580_syntax(HalH264eVepu580Ctx * ctx,MppSyntax * syntax)518 static RK_U32 update_vepu580_syntax(HalH264eVepu580Ctx *ctx, MppSyntax *syntax)
519 {
520     H264eSyntaxDesc *desc = syntax->data;
521     RK_S32 syn_num = syntax->number;
522     RK_U32 updated = 0;
523     RK_S32 i;
524 
525     for (i = 0; i < syn_num; i++, desc++) {
526         switch (desc->type) {
527         case H264E_SYN_CFG : {
528             hal_h264e_dbg_detail("update cfg");
529             ctx->cfg = desc->p;
530         } break;
531         case H264E_SYN_SPS : {
532             hal_h264e_dbg_detail("update sps");
533             ctx->sps = desc->p;
534         } break;
535         case H264E_SYN_PPS : {
536             hal_h264e_dbg_detail("update pps");
537             ctx->pps = desc->p;
538         } break;
539         case H264E_SYN_DPB : {
540             hal_h264e_dbg_detail("update dpb");
541             ctx->dpb = desc->p;
542         } break;
543         case H264E_SYN_SLICE : {
544             hal_h264e_dbg_detail("update slice");
545             ctx->slice = desc->p;
546         } break;
547         case H264E_SYN_FRAME : {
548             hal_h264e_dbg_detail("update frames");
549             ctx->frms = desc->p;
550         } break;
551         case H264E_SYN_PREFIX : {
552             hal_h264e_dbg_detail("update prefix nal");
553             ctx->prefix = desc->p;
554         } break;
555         default : {
556             mpp_log_f("invalid syntax type %d\n", desc->type);
557         } break;
558         }
559 
560         updated |= SYN_TYPE_FLAG(desc->type);
561     }
562 
563     return updated;
564 }
565 
hal_h264e_vepu580_get_task(void * hal,HalEncTask * task)566 static MPP_RET hal_h264e_vepu580_get_task(void *hal, HalEncTask *task)
567 {
568     HalH264eVepu580Ctx *ctx = (HalH264eVepu580Ctx *)hal;
569     MppEncCfgSet *cfg_set = ctx->cfg;
570     MppEncRefCfgImpl *ref = (MppEncRefCfgImpl *)cfg_set->ref_cfg;
571     MppEncH264HwCfg *hw_cfg = &cfg_set->h264.hw_cfg;
572     RK_U32 updated = update_vepu580_syntax(ctx, &task->syntax);
573     EncFrmStatus *frm_status = &task->rc_task->frm;
574     H264eFrmInfo *frms = ctx->frms;
575 
576     hal_h264e_dbg_func("enter %p\n", hal);
577 
578     if (updated & SYN_TYPE_FLAG(H264E_SYN_CFG))
579         setup_hal_bufs(ctx);
580 
581     if (!frm_status->reencode && mpp_frame_has_meta(task->frame)) {
582         MppMeta meta = mpp_frame_get_meta(task->frame);
583 
584         mpp_meta_get_ptr_d(meta, KEY_ROI_DATA2, (void **)&ctx->roi_data, NULL);
585         mpp_meta_get_ptr_d(meta, KEY_OSD_DATA, (void **)&ctx->osd_cfg.osd_data, NULL);
586         mpp_meta_get_ptr_d(meta, KEY_OSD_DATA2, (void **)&ctx->osd_cfg.osd_data2, NULL);
587     }
588 
589     if (ctx->dpb) {
590         h264e_dpb_hal_start(ctx->dpb, frms->curr_idx);
591         h264e_dpb_hal_start(ctx->dpb, frms->refr_idx);
592     }
593 
594     task->flags.reg_idx = ctx->task_idx;
595     task->flags.curr_idx = frms->curr_idx;
596     task->flags.refr_idx = frms->refr_idx;
597     task->part_first = 1;
598     task->part_last = 0;
599 
600     ctx->ext_line_buf = ctx->ext_line_bufs[ctx->task_idx];
601     ctx->regs_set = &ctx->regs_sets[ctx->task_idx];
602     ctx->amend = &ctx->amend_sets[ctx->task_idx];
603     ctx->osd_cfg.reg_base = &ctx->regs_set->reg_osd;
604 
605     /* if not VEPU1/2, update log2_max_frame_num_minus4 in hw_cfg */
606     hw_cfg->hw_log2_max_frame_num_minus4 = ctx->sps->log2_max_frame_num_minus4;
607 
608     if (ctx->task_cnt > 1 && (ref->lt_cfg_cnt || ref->st_cfg_cnt > 1)) {
609         H264ePrefixNal *prefix = &ctx->prefix_sets[ctx->task_idx];
610         H264eSlice *slice = &ctx->slice_sets[ctx->task_idx];
611 
612         //store async encode TSVC info
613         if (ctx->prefix)
614             memcpy(prefix, ctx->prefix, sizeof(H264ePrefixNal));
615         else
616             prefix = NULL;
617 
618         if (ctx->slice) {
619             memcpy(slice, ctx->slice, sizeof(H264eSlice));
620 
621             /*
622              * Generally, reorder and marking are shared by dpb and slice.
623              * However, async encoding TSVC will change reorder and marking in each task.
624              * Therefore, malloc a special space for async encoding TSVC.
625              */
626             ctx->amend->reorder = ctx->reorder;
627             ctx->amend->marking = ctx->marking;
628         }
629 
630         h264e_vepu_stream_amend_config(ctx->amend, task->packet, ctx->cfg,
631                                        slice, prefix);
632     } else {
633         h264e_vepu_stream_amend_config(ctx->amend, task->packet, ctx->cfg,
634                                        ctx->slice, ctx->prefix);
635     }
636 
637     if (ctx->task_cnt > 1)
638         ctx->task_idx = !ctx->task_idx;
639 
640     hal_h264e_dbg_func("leave %p\n", hal);
641 
642     return MPP_OK;
643 }
644 
setup_vepu580_normal(HalVepu580RegSet * regs)645 static void setup_vepu580_normal(HalVepu580RegSet *regs)
646 {
647     hal_h264e_dbg_func("enter\n");
648 
649     /* reg001 ENC_STRT */
650     regs->reg_ctl.enc_strt.lkt_num           = 0;
651     regs->reg_ctl.enc_strt.vepu_cmd          = 1;
652     regs->reg_ctl.func_en.cke                = 1;
653     regs->reg_ctl.func_en.resetn_hw_en       = 1;
654     regs->reg_ctl.func_en.enc_done_tmvp_en   = 1;
655 
656     /* reg002 ENC_CLR */
657     regs->reg_ctl.enc_clr.safe_clr           = 0;
658     regs->reg_ctl.enc_clr.force_clr          = 0;
659 
660     /* reg004 INT_EN */
661     regs->reg_ctl.int_en.enc_done_en         = 1;
662     regs->reg_ctl.int_en.lkt_node_done_en    = 1;
663     regs->reg_ctl.int_en.sclr_done_en        = 1;
664     regs->reg_ctl.int_en.slc_done_en         = 0;
665     regs->reg_ctl.int_en.bsf_oflw_en         = 1;
666     regs->reg_ctl.int_en.brsp_otsd_en        = 1;
667     regs->reg_ctl.int_en.wbus_err_en         = 1;
668     regs->reg_ctl.int_en.rbus_err_en         = 1;
669     regs->reg_ctl.int_en.wdg_en              = 1;
670 
671     /* reg005 INT_MSK */
672     regs->reg_ctl.int_msk.enc_done_msk       = 0;
673     regs->reg_ctl.int_msk.lkt_node_done_msk  = 0;
674     regs->reg_ctl.int_msk.sclr_done_msk      = 0;
675     regs->reg_ctl.int_msk.slc_done_msk       = 0;
676     regs->reg_ctl.int_msk.bsf_oflw_msk       = 0;
677     regs->reg_ctl.int_msk.brsp_otsd_msk      = 0;
678     regs->reg_ctl.int_msk.wbus_err_msk       = 0;
679     regs->reg_ctl.int_msk.rbus_err_msk       = 0;
680     regs->reg_ctl.int_msk.wdg_msk            = 0;
681 
682     regs->reg_ctl.enc_wdg.vs_load_thd        = 0x1fffff;
683     regs->reg_ctl.enc_wdg.rfp_load_thd       = 0;
684 
685     /* reg015 DTRNS_MAP */
686     regs->reg_ctl.dtrns_map.cmvw_bus_ordr      = 0;
687     regs->reg_ctl.dtrns_map.dspw_bus_ordr      = 0;
688     regs->reg_ctl.dtrns_map.rfpw_bus_ordr      = 0;
689     regs->reg_ctl.dtrns_map.src_bus_edin       = 0;
690     regs->reg_ctl.dtrns_map.meiw_bus_edin      = 0;
691     regs->reg_ctl.dtrns_map.bsw_bus_edin       = 7;
692     regs->reg_ctl.dtrns_map.lktr_bus_edin      = 0;
693     regs->reg_ctl.dtrns_map.roir_bus_edin      = 0;
694     regs->reg_ctl.dtrns_map.lktw_bus_edin      = 0;
695     regs->reg_ctl.dtrns_map.afbc_bsize         = 1;
696 
697     regs->reg_ctl.dtrns_cfg.axi_brsp_cke   = 0;
698     regs->reg_ctl.dtrns_cfg.dspr_otsd      = 1;
699     hal_h264e_dbg_func("leave\n");
700 }
701 
setup_vepu580_prep(HalVepu580RegSet * regs,MppEncPrepCfg * prep,HalEncTask * task)702 static MPP_RET setup_vepu580_prep(HalVepu580RegSet *regs, MppEncPrepCfg *prep,
703                                   HalEncTask *task)
704 {
705     VepuFmtCfg cfg;
706     MppFrameFormat fmt = prep->format;
707     MPP_RET ret = vepu5xx_set_fmt(&cfg, fmt);
708     RK_U32 hw_fmt = cfg.format;
709     RK_S32 y_stride;
710     RK_S32 c_stride;
711 
712     hal_h264e_dbg_func("enter\n");
713 
714     /* do nothing when color format is not supported */
715     if (ret)
716         return ret;
717 
718     regs->reg_base.enc_rsl.pic_wd8_m1 = MPP_ALIGN(prep->width, 16) / 8 - 1;
719     regs->reg_base.src_fill.pic_wfill = MPP_ALIGN(prep->width, 16) - prep->width;
720     regs->reg_base.enc_rsl.pic_hd8_m1 = MPP_ALIGN(prep->height, 16) / 8 - 1;
721     regs->reg_base.src_fill.pic_hfill = MPP_ALIGN(prep->height, 16) - prep->height;
722 
723     regs->reg_ctl.dtrns_map.src_bus_edin = cfg.src_endian;
724 
725     regs->reg_base.src_fmt.src_cfmt   = hw_fmt;
726     regs->reg_base.src_fmt.alpha_swap = cfg.alpha_swap;
727     regs->reg_base.src_fmt.rbuv_swap  = cfg.rbuv_swap;
728     regs->reg_base.src_fmt.out_fmt    = (fmt == MPP_FMT_YUV400) ? 0 : 1;
729 
730     if (MPP_FRAME_FMT_IS_YUV(fmt))
731         regs->reg_base.src_fmt.src_range  = 1;
732     else
733         regs->reg_base.src_fmt.src_range  = (prep->range == MPP_FRAME_RANGE_JPEG) ? 1 : 0;
734 
735     if (MPP_FRAME_FMT_IS_FBC(fmt)) {
736         y_stride = mpp_frame_get_fbc_hdr_stride(task->frame);
737         if (!y_stride)
738             y_stride = MPP_ALIGN(prep->width, 16);
739     } else if (prep->hor_stride) {
740         y_stride = prep->hor_stride;
741     } else {
742         if (hw_fmt == VEPU5xx_FMT_BGRA8888 )
743             y_stride = prep->width * 4;
744         else if (hw_fmt == VEPU5xx_FMT_BGR888 )
745             y_stride = prep->width * 3;
746         else if (hw_fmt == VEPU5xx_FMT_BGR565 ||
747                  hw_fmt == VEPU5xx_FMT_YUYV422 ||
748                  hw_fmt == VEPU5xx_FMT_UYVY422)
749             y_stride = prep->width * 2;
750         else
751             y_stride = prep->width;
752     }
753 
754     switch (hw_fmt) {
755     case VEPU5xx_FMT_YUV444SP : {
756         c_stride = y_stride * 2;
757     } break;
758     case VEPU5xx_FMT_YUV422SP :
759     case VEPU5xx_FMT_YUV420SP :
760     case VEPU5xx_FMT_YUV444P : {
761         c_stride = y_stride;
762     } break;
763     default : {
764         c_stride = y_stride / 2;
765     } break;
766     }
767 
768     if (hw_fmt < VEPU5xx_FMT_ARGB1555) {
769         const VepuRgb2YuvCfg *cfg_coeffs = get_rgb2yuv_cfg(prep->range, prep->color);
770 
771         hal_h264e_dbg_flow("input color range %d colorspace %d", prep->range, prep->color);
772 
773         regs->reg_base.src_udfy.csc_wgt_b2y = cfg_coeffs->_2y.b_coeff;
774         regs->reg_base.src_udfy.csc_wgt_g2y = cfg_coeffs->_2y.g_coeff;
775         regs->reg_base.src_udfy.csc_wgt_r2y = cfg_coeffs->_2y.r_coeff;
776 
777         regs->reg_base.src_udfu.csc_wgt_b2u = cfg_coeffs->_2u.b_coeff;
778         regs->reg_base.src_udfu.csc_wgt_g2u = cfg_coeffs->_2u.g_coeff;
779         regs->reg_base.src_udfu.csc_wgt_r2u = cfg_coeffs->_2u.r_coeff;
780 
781         regs->reg_base.src_udfv.csc_wgt_b2v = cfg_coeffs->_2v.b_coeff;
782         regs->reg_base.src_udfv.csc_wgt_g2v = cfg_coeffs->_2v.g_coeff;
783         regs->reg_base.src_udfv.csc_wgt_r2v = cfg_coeffs->_2v.r_coeff;
784 
785         regs->reg_base.src_udfo.csc_ofst_y  = cfg_coeffs->_2y.offset;
786         regs->reg_base.src_udfo.csc_ofst_u  = cfg_coeffs->_2u.offset;
787         regs->reg_base.src_udfo.csc_ofst_v  = cfg_coeffs->_2v.offset;
788 
789         hal_h264e_dbg_flow("use color range %d colorspace %d", cfg_coeffs->dst_range, cfg_coeffs->color);
790     } else {
791         regs->reg_base.src_udfy.csc_wgt_b2y = cfg.weight[0];
792         regs->reg_base.src_udfy.csc_wgt_g2y = cfg.weight[1];
793         regs->reg_base.src_udfy.csc_wgt_r2y = cfg.weight[2];
794 
795         regs->reg_base.src_udfu.csc_wgt_b2u = cfg.weight[3];
796         regs->reg_base.src_udfu.csc_wgt_g2u = cfg.weight[4];
797         regs->reg_base.src_udfu.csc_wgt_r2u = cfg.weight[5];
798 
799         regs->reg_base.src_udfv.csc_wgt_b2v = cfg.weight[6];
800         regs->reg_base.src_udfv.csc_wgt_g2v = cfg.weight[7];
801         regs->reg_base.src_udfv.csc_wgt_r2v = cfg.weight[8];
802 
803         regs->reg_base.src_udfo.csc_ofst_y  = cfg.offset[0];
804         regs->reg_base.src_udfo.csc_ofst_u  = cfg.offset[1];
805         regs->reg_base.src_udfo.csc_ofst_v  = cfg.offset[2];
806     }
807 
808     regs->reg_base.src_proc.afbcd_en   = MPP_FRAME_FMT_IS_FBC(fmt) ? 1 : 0;
809     regs->reg_base.src_strd0.src_strd0 = y_stride;
810     regs->reg_base.src_strd1.src_strd1 = c_stride;
811 
812     regs->reg_base.src_proc.src_mirr   = prep->mirroring > 0;
813     regs->reg_base.src_proc.src_rot    = prep->rotation;
814     regs->reg_base.src_proc.txa_en     = 0;
815 
816     regs->reg_base.sli_cfg.sli_crs_en  = 1;
817 
818     regs->reg_base.pic_ofst.pic_ofst_y = 0;
819     regs->reg_base.pic_ofst.pic_ofst_x = 0;
820 
821     hal_h264e_dbg_func("leave\n");
822 
823     return ret;
824 }
825 
vepu580_h264e_save_pass1_patch(HalVepu580RegSet * regs,HalH264eVepu580Ctx * ctx)826 static MPP_RET vepu580_h264e_save_pass1_patch(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx)
827 {
828     RK_S32 width_align = MPP_ALIGN(ctx->cfg->prep.width, 64);
829     RK_S32 height_align = MPP_ALIGN(ctx->cfg->prep.height, 16);
830 
831     if (NULL == ctx->buf_pass1) {
832         mpp_buffer_get(NULL, &ctx->buf_pass1, width_align * height_align * 3 / 2);
833         if (!ctx->buf_pass1) {
834             mpp_err("buf_pass1 malloc fail, debreath invaild");
835             return MPP_NOK;
836         }
837     }
838 
839     regs->reg_base.enc_pic.cur_frm_ref = 1;
840     regs->reg_base.rfpw_h_addr = mpp_buffer_get_fd(ctx->buf_pass1);
841     regs->reg_base.rfpw_b_addr = regs->reg_base.rfpw_h_addr;
842     regs->reg_base.enc_pic.rec_fbc_dis = 1;
843 
844     mpp_dev_multi_offset_update(ctx->offsets, 164, width_align * height_align);
845 
846     /* NOTE: disable split to avoid lowdelay slice output */
847     regs->reg_base.sli_splt.sli_splt = 0;
848     regs->reg_base.enc_pic.slen_fifo = 0;
849 
850     return MPP_OK;
851 }
852 
vepu580_h264e_use_pass1_patch(HalVepu580RegSet * regs,HalH264eVepu580Ctx * ctx)853 static MPP_RET vepu580_h264e_use_pass1_patch(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx)
854 {
855     MppEncPrepCfg *prep = &ctx->cfg->prep;
856     RK_S32 hor_stride = MPP_ALIGN(prep->width, 64);
857     RK_S32 ver_stride = MPP_ALIGN(prep->height, 16);
858     RK_S32 frame_size = hor_stride * ver_stride;
859     RK_S32 fd_in = mpp_buffer_get_fd(ctx->buf_pass1);
860 
861     hal_h264e_dbg_func("enter\n");
862 
863     regs->reg_base.src_fmt.src_cfmt   = VEPU5xx_FMT_YUV420SP;
864     regs->reg_base.src_fmt.alpha_swap = 0;
865     regs->reg_base.src_fmt.rbuv_swap  = 0;
866     regs->reg_base.src_fmt.out_fmt    = 1;
867 
868     regs->reg_base.src_proc.afbcd_en   =  0;
869     regs->reg_base.src_strd0.src_strd0  = hor_stride;
870     regs->reg_base.src_strd1.src_strd1  = hor_stride;
871 
872     regs->reg_base.src_proc.src_mirr   = 0;
873     regs->reg_base.src_proc.src_rot    = 0;
874     regs->reg_base.src_proc.txa_en     = 0;
875 
876     regs->reg_base.pic_ofst.pic_ofst_y = 0;
877     regs->reg_base.pic_ofst.pic_ofst_x = 0;
878 
879 
880     regs->reg_base.adr_src0   = fd_in;
881     regs->reg_base.adr_src1   = fd_in;
882     regs->reg_base.adr_src2   = fd_in;
883 
884     mpp_dev_multi_offset_update(ctx->offsets, 161, frame_size);
885     mpp_dev_multi_offset_update(ctx->offsets, 162, frame_size);
886 
887     hal_h264e_dbg_func("leave\n");
888     return MPP_OK;
889 }
890 
setup_vepu580_codec(HalVepu580RegSet * regs,H264eSps * sps,H264ePps * pps,H264eSlice * slice)891 static void setup_vepu580_codec(HalVepu580RegSet *regs, H264eSps *sps,
892                                 H264ePps *pps, H264eSlice *slice)
893 {
894     hal_h264e_dbg_func("enter\n");
895 
896     regs->reg_base.enc_pic.enc_stnd       = 0;
897     regs->reg_base.enc_pic.cur_frm_ref    = slice->nal_reference_idc > 0;
898     regs->reg_base.enc_pic.bs_scp         = 1;
899 
900     regs->reg_base.synt_nal.nal_ref_idc    = slice->nal_reference_idc;
901     regs->reg_base.synt_nal.nal_unit_type  = slice->nalu_type;
902 
903     regs->reg_base.synt_sps.max_fnum       = sps->log2_max_frame_num_minus4;
904     regs->reg_base.synt_sps.drct_8x8       = sps->direct8x8_inference;
905     regs->reg_base.synt_sps.mpoc_lm4       = sps->log2_max_poc_lsb_minus4;
906 
907     regs->reg_base.synt_pps.etpy_mode      = pps->entropy_coding_mode;
908     regs->reg_base.synt_pps.trns_8x8       = pps->transform_8x8_mode;
909     regs->reg_base.synt_pps.csip_flag      = pps->constrained_intra_pred;
910     regs->reg_base.synt_pps.num_ref0_idx   = pps->num_ref_idx_l0_default_active - 1;
911     regs->reg_base.synt_pps.num_ref1_idx   = pps->num_ref_idx_l1_default_active - 1;
912     regs->reg_base.synt_pps.pic_init_qp    = pps->pic_init_qp;
913     regs->reg_base.synt_pps.cb_ofst        = pps->chroma_qp_index_offset;
914     regs->reg_base.synt_pps.cr_ofst        = pps->second_chroma_qp_index_offset;
915     regs->reg_base.synt_pps.wght_pred      = pps->weighted_pred;
916     regs->reg_base.synt_pps.dbf_cp_flg     = pps->deblocking_filter_control;
917 
918     regs->reg_base.synt_sli0.sli_type       = (slice->slice_type == H264_I_SLICE) ? (2) : (0);
919     regs->reg_base.synt_sli0.pps_id         = slice->pic_parameter_set_id;
920     regs->reg_base.synt_sli0.drct_smvp      = 0;
921     regs->reg_base.synt_sli0.num_ref_ovrd   = slice->num_ref_idx_override;
922     regs->reg_base.synt_sli0.cbc_init_idc   = slice->cabac_init_idc;
923     regs->reg_base.synt_sli0.frm_num        = slice->frame_num;
924 
925     regs->reg_base.synt_sli1.idr_pid        = (slice->slice_type == H264_I_SLICE) ? slice->idr_pic_id : (RK_U32)(-1);
926     regs->reg_base.synt_sli1.poc_lsb        = slice->pic_order_cnt_lsb;
927 
928 
929     regs->reg_base.synt_sli2.dis_dblk_idc   = slice->disable_deblocking_filter_idc;
930     regs->reg_base.synt_sli2.sli_alph_ofst  = slice->slice_alpha_c0_offset_div2;
931 
932     h264e_reorder_rd_rewind(slice->reorder);
933     {   /* reorder process */
934         H264eRplmo rplmo;
935         MPP_RET ret = h264e_reorder_rd_op(slice->reorder, &rplmo);
936 
937         if (MPP_OK == ret) {
938             regs->reg_base.synt_sli2.ref_list0_rodr = 1;
939             regs->reg_base.synt_sli2.rodr_pic_idx   = rplmo.modification_of_pic_nums_idc;
940 
941             switch (rplmo.modification_of_pic_nums_idc) {
942             case 0 :
943             case 1 : {
944                 regs->reg_base.synt_sli2.rodr_pic_num   = rplmo.abs_diff_pic_num_minus1;
945             } break;
946             case 2 : {
947                 regs->reg_base.synt_sli2.rodr_pic_num   = rplmo.long_term_pic_idx;
948             } break;
949             default : {
950                 mpp_err_f("invalid modification_of_pic_nums_idc %d\n",
951                           rplmo.modification_of_pic_nums_idc);
952             } break;
953             }
954         } else {
955             // slice->ref_pic_list_modification_flag;
956             regs->reg_base.synt_sli2.ref_list0_rodr = 0;
957             regs->reg_base.synt_sli2.rodr_pic_idx   = 0;
958             regs->reg_base.synt_sli2.rodr_pic_num   = 0;
959         }
960     }
961 
962     /* clear all mmco arg first */
963     regs->reg_base.synt_refm0.nopp_flg               = 0;
964     regs->reg_base.synt_refm0.ltrf_flg               = 0;
965     regs->reg_base.synt_refm0.arpm_flg               = 0;
966     regs->reg_base.synt_refm0.mmco4_pre              = 0;
967     regs->reg_base.synt_refm0.mmco_type0             = 0;
968     regs->reg_base.synt_refm0.mmco_parm0             = 0;
969     regs->reg_base.synt_refm0.mmco_type1             = 0;
970     regs->reg_base.synt_refm1.mmco_parm1             = 0;
971     regs->reg_base.synt_refm0.mmco_type2             = 0;
972     regs->reg_base.synt_refm1.mmco_parm2             = 0;
973     regs->reg_base.synt_refm2.long_term_frame_idx0   = 0;
974     regs->reg_base.synt_refm2.long_term_frame_idx1   = 0;
975     regs->reg_base.synt_refm2.long_term_frame_idx2   = 0;
976 
977     h264e_marking_rd_rewind(slice->marking);
978 
979     /* only update used parameter */
980     if (slice->slice_type == H264_I_SLICE) {
981         regs->reg_base.synt_refm0.nopp_flg       = slice->no_output_of_prior_pics;
982         regs->reg_base.synt_refm0.ltrf_flg       = slice->long_term_reference_flag;
983     } else {
984         if (!h264e_marking_is_empty(slice->marking)) {
985             H264eMmco mmco;
986 
987             regs->reg_base.synt_refm0.arpm_flg       = 1;
988 
989             /* max 3 mmco */
990             do {
991                 RK_S32 type = 0;
992                 RK_S32 param_0 = 0;
993                 RK_S32 param_1 = 0;
994 
995                 h264e_marking_rd_op(slice->marking, &mmco);
996                 type = mmco.mmco;
997                 switch (type) {
998                 case 1 : {
999                     param_0 = mmco.difference_of_pic_nums_minus1;
1000                 } break;
1001                 case 2 : {
1002                     param_0 = mmco.long_term_pic_num;
1003                 } break;
1004                 case 3 : {
1005                     param_0 = mmco.difference_of_pic_nums_minus1;
1006                     param_1 = mmco.long_term_frame_idx;
1007                 } break;
1008                 case 4 : {
1009                     param_0 = mmco.max_long_term_frame_idx_plus1;
1010                 } break;
1011                 case 5 : {
1012                 } break;
1013                 case 6 : {
1014                     param_0 = mmco.long_term_frame_idx;
1015                 } break;
1016                 default : {
1017                     mpp_err_f("unsupported mmco 0 %d\n", type);
1018                     type = 0;
1019                 } break;
1020                 }
1021 
1022                 regs->reg_base.synt_refm0.mmco_type0 = type;
1023                 regs->reg_base.synt_refm0.mmco_parm0 = param_0;
1024                 regs->reg_base.synt_refm2.long_term_frame_idx0 = param_1;
1025 
1026                 if (h264e_marking_is_empty(slice->marking))
1027                     break;
1028 
1029                 h264e_marking_rd_op(slice->marking, &mmco);
1030                 type = mmco.mmco;
1031                 param_0 = 0;
1032                 param_1 = 0;
1033                 switch (type) {
1034                 case 1 : {
1035                     param_0 = mmco.difference_of_pic_nums_minus1;
1036                 } break;
1037                 case 2 : {
1038                     param_0 = mmco.long_term_pic_num;
1039                 } break;
1040                 case 3 : {
1041                     param_0 = mmco.difference_of_pic_nums_minus1;
1042                     param_1 = mmco.long_term_frame_idx;
1043                 } break;
1044                 case 4 : {
1045                     param_0 = mmco.max_long_term_frame_idx_plus1;
1046                 } break;
1047                 case 5 : {
1048                 } break;
1049                 case 6 : {
1050                     param_0 = mmco.long_term_frame_idx;
1051                 } break;
1052                 default : {
1053                     mpp_err_f("unsupported mmco 0 %d\n", type);
1054                     type = 0;
1055                 } break;
1056                 }
1057 
1058                 regs->reg_base.synt_refm0.mmco_type1 = type;
1059                 regs->reg_base.synt_refm1.mmco_parm1 = param_0;
1060                 regs->reg_base.synt_refm2.long_term_frame_idx1 = param_1;
1061 
1062                 if (h264e_marking_is_empty(slice->marking))
1063                     break;
1064 
1065                 h264e_marking_rd_op(slice->marking, &mmco);
1066                 type = mmco.mmco;
1067                 param_0 = 0;
1068                 param_1 = 0;
1069                 switch (type) {
1070                 case 1 : {
1071                     param_0 = mmco.difference_of_pic_nums_minus1;
1072                 } break;
1073                 case 2 : {
1074                     param_0 = mmco.long_term_pic_num;
1075                 } break;
1076                 case 3 : {
1077                     param_0 = mmco.difference_of_pic_nums_minus1;
1078                     param_1 = mmco.long_term_frame_idx;
1079                 } break;
1080                 case 4 : {
1081                     param_0 = mmco.max_long_term_frame_idx_plus1;
1082                 } break;
1083                 case 5 : {
1084                 } break;
1085                 case 6 : {
1086                     param_0 = mmco.long_term_frame_idx;
1087                 } break;
1088                 default : {
1089                     mpp_err_f("unsupported mmco 0 %d\n", type);
1090                     type = 0;
1091                 } break;
1092                 }
1093 
1094                 regs->reg_base.synt_refm0.mmco_type2 = type;
1095                 regs->reg_base.synt_refm1.mmco_parm2 = param_0;
1096                 regs->reg_base.synt_refm2.long_term_frame_idx2 = param_1;
1097             } while (0);
1098         }
1099     }
1100 
1101     hal_h264e_dbg_func("leave\n");
1102 }
1103 
setup_vepu580_rdo_pred(HalVepu580RegSet * regs,H264eSps * sps,H264ePps * pps,H264eSlice * slice)1104 static void setup_vepu580_rdo_pred(HalVepu580RegSet *regs, H264eSps *sps,
1105                                    H264ePps *pps, H264eSlice *slice)
1106 {
1107     hal_h264e_dbg_func("enter\n");
1108 
1109     if (slice->slice_type == H264_I_SLICE) {
1110         regs->reg_rc_klut.klut_ofst.chrm_klut_ofst = 0;
1111         memcpy(&regs->reg_rc_klut.klut_wgt0, &h264e_klut_weight[0], CHROMA_KLUT_TAB_SIZE);
1112     } else {
1113         regs->reg_rc_klut.klut_ofst.chrm_klut_ofst = 3;
1114         memcpy(&regs->reg_rc_klut.klut_wgt0, &h264e_klut_weight[4], CHROMA_KLUT_TAB_SIZE);
1115     }
1116 
1117     regs->reg_base.iprd_csts.vthd_y     = 9;
1118     regs->reg_base.iprd_csts.vthd_c     = 63;
1119 
1120     regs->reg_base.rdo_cfg.rect_size    = (sps->profile_idc == H264_PROFILE_BASELINE &&
1121                                            sps->level_idc <= H264_LEVEL_3_0) ? 1 : 0;
1122     regs->reg_base.rdo_cfg.inter_4x4    = 1;
1123     regs->reg_base.rdo_cfg.vlc_lmt      = (sps->profile_idc < H264_PROFILE_MAIN) &&
1124                                           !pps->entropy_coding_mode;
1125     regs->reg_base.rdo_cfg.chrm_spcl    = 1;
1126     regs->reg_base.rdo_cfg.rdo_mask     = 0;
1127     regs->reg_base.rdo_cfg.ccwa_e       = 1;
1128     regs->reg_base.rdo_cfg.scl_lst_sel  = pps->pic_scaling_matrix_present;
1129     regs->reg_base.rdo_cfg.atr_e        = 1;
1130     regs->reg_base.rdo_cfg.atf_intra_e  = 1;
1131 
1132     hal_h264e_dbg_func("leave\n");
1133 }
1134 
setup_vepu580_rdo_bias_cfg(Vepu580RdoCfg * regs,MppEncHwCfg * hw)1135 static void setup_vepu580_rdo_bias_cfg(Vepu580RdoCfg *regs, MppEncHwCfg *hw)
1136 {
1137     RK_U8 bias = h264_mode_bias[hw->mode_bias[1]];
1138 
1139     regs->rdo_intra_atf_wgt0.atf_rdo_intra_wgt00 = bias > 24 ? bias : 24;
1140     regs->rdo_intra_atf_wgt0.atf_rdo_intra_wgt01 = bias > 22 ? bias : 22;
1141     regs->rdo_intra_atf_wgt0.atf_rdo_intra_wgt02 = bias > 21 ? bias : 21;
1142     regs->rdo_intra_atf_wgt1.atf_rdo_intra_wgt10 = bias > 22 ? bias : 22;
1143     regs->rdo_intra_atf_wgt1.atf_rdo_intra_wgt11 = bias > 21 ? bias : 21;
1144     regs->rdo_intra_atf_wgt1.atf_rdo_intra_wgt12 = bias > 20 ? bias : 20;
1145     regs->rdo_intra_atf_wgt2.atf_rdo_intra_wgt20 = bias > 20 ? bias : 20;
1146     regs->rdo_intra_atf_wgt2.atf_rdo_intra_wgt21 = bias > 19 ? bias : 19;
1147     regs->rdo_intra_atf_wgt2.atf_rdo_intra_wgt22 = bias > 18 ? bias : 18;
1148     regs->rdo_intra_atf_wgt3.atf_rdo_intra_wgt30 = bias;
1149     regs->rdo_intra_atf_wgt3.atf_rdo_intra_wgt31 = bias;
1150     regs->rdo_intra_atf_wgt3.atf_rdo_intra_wgt32 = bias;
1151 
1152     if (hw->skip_bias_en) {
1153         bias = hw->skip_bias;
1154 
1155         regs->rdo_skip_cime_thd0.atf_rdo_skip_cime_thd0 = hw->skip_sad < 10 ? hw->skip_sad : 10;
1156         regs->rdo_skip_cime_thd0.atf_rdo_skip_cime_thd1 = hw->skip_sad < 8  ? hw->skip_sad : 8;
1157         regs->rdo_skip_cime_thd1.atf_rdo_skip_cime_thd2 = hw->skip_sad < 15 ? hw->skip_sad : 15;
1158         regs->rdo_skip_cime_thd1.atf_rdo_skip_cime_thd3 = hw->skip_sad;
1159         regs->rdo_skip_atf_wgt0.atf_rdo_skip_atf_wgt00 = bias > 20 ? bias : 20;
1160         regs->rdo_skip_atf_wgt0.atf_rdo_skip_atf_wgt10 = bias;
1161         regs->rdo_skip_atf_wgt0.atf_rdo_skip_atf_wgt11 = bias;
1162         regs->rdo_skip_atf_wgt0.atf_rdo_skip_atf_wgt12 = bias;
1163         regs->rdo_skip_atf_wgt1.atf_rdo_skip_atf_wgt20 = bias;
1164         regs->rdo_skip_atf_wgt1.atf_rdo_skip_atf_wgt21 = bias;
1165         regs->rdo_skip_atf_wgt1.atf_rdo_skip_atf_wgt22 = bias;
1166         regs->rdo_skip_atf_wgt2.atf_rdo_skip_atf_wgt30 = bias;
1167         regs->rdo_skip_atf_wgt2.atf_rdo_skip_atf_wgt31 = bias;
1168         regs->rdo_skip_atf_wgt2.atf_rdo_skip_atf_wgt32 = bias;
1169         regs->rdo_skip_atf_wgt3.atf_rdo_skip_atf_wgt40 = bias;
1170         regs->rdo_skip_atf_wgt3.atf_rdo_skip_atf_wgt41 = bias;
1171         regs->rdo_skip_atf_wgt3.atf_rdo_skip_atf_wgt42 = bias;
1172     }
1173 }
1174 
setup_vepu580_rdo_cfg(Vepu580RdoCfg * regs)1175 static void setup_vepu580_rdo_cfg(Vepu580RdoCfg *regs)
1176 {
1177     hal_h264e_dbg_func("enter\n");
1178 
1179     /* 0x2000 */
1180     regs->rdo_sqi_cfg.atf_pskip_en = 1;
1181 
1182     /* 0x20CC ~ 0x20D0 */
1183     regs->rdo_intra_cime_thd0.atf_rdo_intra_cime_thd0 = 28;
1184     regs->rdo_intra_cime_thd0.atf_rdo_intra_cime_thd1 = 44;
1185     regs->rdo_intra_cime_thd1.atf_rdo_intra_cime_thd2 = 72;
1186 
1187     /* 0x20D4 ~ 0x20E0 */
1188     regs->rdo_intra_var_thd0.atf_rdo_intra_var_thd00 = 25;
1189     regs->rdo_intra_var_thd0.atf_rdo_intra_var_thd01 = 64;
1190     regs->rdo_intra_var_thd1.atf_rdo_intra_var_thd10 = 25;
1191     regs->rdo_intra_var_thd1.atf_rdo_intra_var_thd11 = 64;
1192     regs->rdo_intra_var_thd2.atf_rdo_intra_var_thd20 = 70;
1193     regs->rdo_intra_var_thd2.atf_rdo_intra_var_thd21 = 100;
1194     regs->rdo_intra_var_thd3.atf_rdo_intra_var_thd30 = 70;
1195     regs->rdo_intra_var_thd3.atf_rdo_intra_var_thd31 = 100;
1196 
1197     /* 0x20E4 ~ 0x20F0 */
1198     regs->rdo_intra_atf_wgt0.atf_rdo_intra_wgt00 = 24;
1199     regs->rdo_intra_atf_wgt0.atf_rdo_intra_wgt01 = 22;
1200     regs->rdo_intra_atf_wgt0.atf_rdo_intra_wgt02 = 21;
1201     regs->rdo_intra_atf_wgt1.atf_rdo_intra_wgt10 = 22;
1202     regs->rdo_intra_atf_wgt1.atf_rdo_intra_wgt11 = 21;
1203     regs->rdo_intra_atf_wgt1.atf_rdo_intra_wgt12 = 20;
1204     regs->rdo_intra_atf_wgt2.atf_rdo_intra_wgt20 = 20;
1205     regs->rdo_intra_atf_wgt2.atf_rdo_intra_wgt21 = 19;
1206     regs->rdo_intra_atf_wgt2.atf_rdo_intra_wgt22 = 18;
1207     regs->rdo_intra_atf_wgt3.atf_rdo_intra_wgt30 = 16;
1208     regs->rdo_intra_atf_wgt3.atf_rdo_intra_wgt31 = 16;
1209     regs->rdo_intra_atf_wgt3.atf_rdo_intra_wgt32 = 16;
1210 
1211     /* 0x211C ~ 0x2130 */
1212     regs->rdo_skip_cime_thd0.atf_rdo_skip_cime_thd0 = 10;
1213     regs->rdo_skip_cime_thd0.atf_rdo_skip_cime_thd1 = 8;
1214     regs->rdo_skip_cime_thd1.atf_rdo_skip_cime_thd2 = 15;
1215     regs->rdo_skip_cime_thd1.atf_rdo_skip_cime_thd3 = 25;
1216     regs->rdo_skip_var_thd0.atf_rdo_skip_var_thd10 = 25;
1217     regs->rdo_skip_var_thd0.atf_rdo_skip_var_thd11 = 40;
1218     regs->rdo_skip_var_thd1.atf_rdo_skip_var_thd20 = 25;
1219     regs->rdo_skip_var_thd1.atf_rdo_skip_var_thd21 = 40;
1220     regs->rdo_skip_var_thd2.atf_rdo_skip_var_thd30 = 70;
1221     regs->rdo_skip_var_thd2.atf_rdo_skip_var_thd31 = 100;
1222     regs->rdo_skip_var_thd3.atf_rdo_skip_var_thd40 = 70;
1223     regs->rdo_skip_var_thd3.atf_rdo_skip_var_thd41 = 100;
1224 
1225     /* 0x2134 ~ 0x2140 */
1226     regs->rdo_skip_atf_wgt0.atf_rdo_skip_atf_wgt00 = 20;
1227     regs->rdo_skip_atf_wgt0.atf_rdo_skip_atf_wgt10 = 16;
1228     regs->rdo_skip_atf_wgt0.atf_rdo_skip_atf_wgt11 = 16;
1229     regs->rdo_skip_atf_wgt0.atf_rdo_skip_atf_wgt12 = 16;
1230     regs->rdo_skip_atf_wgt1.atf_rdo_skip_atf_wgt20 = 16;
1231     regs->rdo_skip_atf_wgt1.atf_rdo_skip_atf_wgt21 = 16;
1232     regs->rdo_skip_atf_wgt1.atf_rdo_skip_atf_wgt22 = 16;
1233     regs->rdo_skip_atf_wgt2.atf_rdo_skip_atf_wgt30 = 16;
1234     regs->rdo_skip_atf_wgt2.atf_rdo_skip_atf_wgt31 = 16;
1235     regs->rdo_skip_atf_wgt2.atf_rdo_skip_atf_wgt32 = 16;
1236     regs->rdo_skip_atf_wgt3.atf_rdo_skip_atf_wgt40 = 16;
1237     regs->rdo_skip_atf_wgt3.atf_rdo_skip_atf_wgt41 = 16;
1238     regs->rdo_skip_atf_wgt3.atf_rdo_skip_atf_wgt42 = 16;
1239 
1240     hal_h264e_dbg_func("leave\n");
1241 }
1242 
setup_vepu580_rc_base(HalVepu580RegSet * regs,HalH264eVepu580Ctx * ctx,EncRcTask * rc_task)1243 static void setup_vepu580_rc_base(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx, EncRcTask *rc_task)
1244 {
1245     EncRcTaskInfo *rc_info = &rc_task->info;
1246     H264eSlice *slice = ctx->slice;
1247     MppEncCfgSet *cfg = ctx->cfg;
1248     MppEncHwCfg *hw = &cfg->hw;
1249     H264eSps *sps = ctx->sps;
1250     MppEncRcCfg *rc = &cfg->rc;
1251     RK_S32 mb_w = sps->pic_width_in_mbs;
1252     RK_S32 mb_h = sps->pic_height_in_mbs;
1253     RK_U32 qp_target = rc_info->quality_target;
1254     RK_U32 qp_min = rc_info->quality_min;
1255     RK_U32 qp_max = rc_info->quality_max;
1256     RK_U32 qpmap_mode = 1;
1257     RK_S32 mb_target_bits_mul_16 = (rc_info->bit_target << 4) / (mb_w * mb_h);
1258     RK_S32 mb_target_bits;
1259     RK_S32 negative_bits_thd;
1260     RK_S32 positive_bits_thd;
1261 
1262     hal_h264e_dbg_rc("bittarget %d qp [%d %d %d]\n", rc_info->bit_target,
1263                      qp_min, qp_target, qp_max);
1264 
1265     hal_h264e_dbg_func("enter\n");
1266 
1267     regs->reg_rc_klut.roi_qthd0.qpmin_area0    = qp_min;
1268     regs->reg_rc_klut.roi_qthd0.qpmax_area0    = qp_max;
1269     regs->reg_rc_klut.roi_qthd0.qpmin_area1    = qp_min;
1270     regs->reg_rc_klut.roi_qthd0.qpmax_area1    = qp_max;
1271     regs->reg_rc_klut.roi_qthd0.qpmin_area2    = qp_min;
1272 
1273     regs->reg_rc_klut.roi_qthd1.qpmax_area2    = qp_max;
1274     regs->reg_rc_klut.roi_qthd1.qpmin_area3    = qp_min;
1275     regs->reg_rc_klut.roi_qthd1.qpmax_area3    = qp_max;
1276     regs->reg_rc_klut.roi_qthd1.qpmin_area4    = qp_min;
1277     regs->reg_rc_klut.roi_qthd1.qpmax_area4    = qp_max;
1278 
1279     regs->reg_rc_klut.roi_qthd2.qpmin_area5    = qp_min;
1280     regs->reg_rc_klut.roi_qthd2.qpmax_area5    = qp_max;
1281     regs->reg_rc_klut.roi_qthd2.qpmin_area6    = qp_min;
1282     regs->reg_rc_klut.roi_qthd2.qpmax_area6    = qp_max;
1283     regs->reg_rc_klut.roi_qthd2.qpmin_area7    = qp_min;
1284 
1285     regs->reg_rc_klut.roi_qthd3.qpmax_area7    = qp_max;
1286     regs->reg_rc_klut.roi_qthd3.qpmap_mode     = qpmap_mode;
1287 
1288     if (rc->rc_mode == MPP_ENC_RC_MODE_FIXQP) {
1289         regs->reg_base.enc_pic.pic_qp    = qp_target;
1290         regs->reg_base.rc_qp.rc_max_qp   = qp_target;
1291         regs->reg_base.rc_qp.rc_min_qp   = qp_target;
1292 
1293         return;
1294     }
1295 
1296     if (mb_target_bits_mul_16 >= 0x100000)
1297         mb_target_bits_mul_16 = 0x50000;
1298 
1299     mb_target_bits = (mb_target_bits_mul_16 * mb_w) >> 4;
1300     negative_bits_thd = 0 - 5 * mb_target_bits / 16;
1301     positive_bits_thd = 5 * mb_target_bits / 16;
1302 
1303     regs->reg_base.enc_pic.pic_qp       = qp_target;
1304     regs->reg_base.rc_cfg.rc_en         = 1;
1305     regs->reg_base.rc_cfg.aq_en         = 1;
1306     regs->reg_base.rc_cfg.aq_mode       = 0;
1307     regs->reg_base.rc_cfg.rc_ctu_num    = mb_w;
1308     regs->reg_base.rc_qp.rc_qp_range    = (slice->slice_type == H264_I_SLICE) ?
1309                                           hw->qp_delta_row_i : hw->qp_delta_row;
1310     regs->reg_base.rc_qp.rc_max_qp      = qp_max;
1311     regs->reg_base.rc_qp.rc_min_qp      = qp_min;
1312     regs->reg_base.rc_tgt.ctu_ebit      = mb_target_bits_mul_16;
1313 
1314     regs->reg_rc_klut.rc_adj0.qp_adj0   = -2;
1315     regs->reg_rc_klut.rc_adj0.qp_adj1   = -1;
1316     regs->reg_rc_klut.rc_adj0.qp_adj2   = 0;
1317     regs->reg_rc_klut.rc_adj0.qp_adj3   = 1;
1318     regs->reg_rc_klut.rc_adj0.qp_adj4   = 2;
1319     regs->reg_rc_klut.rc_adj1.qp_adj5   = 0;
1320     regs->reg_rc_klut.rc_adj1.qp_adj6   = 0;
1321     regs->reg_rc_klut.rc_adj1.qp_adj7   = 0;
1322     regs->reg_rc_klut.rc_adj1.qp_adj8   = 1;
1323 
1324     regs->reg_rc_klut.rc_dthd_0_8[0] = 4 * negative_bits_thd;
1325     regs->reg_rc_klut.rc_dthd_0_8[1] = negative_bits_thd;
1326     regs->reg_rc_klut.rc_dthd_0_8[2] = positive_bits_thd;
1327     regs->reg_rc_klut.rc_dthd_0_8[3] = 4 * positive_bits_thd;
1328     regs->reg_rc_klut.rc_dthd_0_8[4] = 0x7FFFFFFF;
1329     regs->reg_rc_klut.rc_dthd_0_8[5] = 0x7FFFFFFF;
1330     regs->reg_rc_klut.rc_dthd_0_8[6] = 0x7FFFFFFF;
1331     regs->reg_rc_klut.rc_dthd_0_8[7] = 0x7FFFFFFF;
1332     regs->reg_rc_klut.rc_dthd_0_8[8] = 0x7FFFFFFF;
1333 
1334     {
1335         /* 0x1070 ~ 0x1074 */
1336         regs->reg_rc_klut.md_sad_thd.md_sad_thd0 = 4;
1337         regs->reg_rc_klut.md_sad_thd.md_sad_thd1 = 9;
1338         regs->reg_rc_klut.md_sad_thd.md_sad_thd2 = 15;
1339 
1340         regs->reg_rc_klut.madi_thd.madi_thd0 = 4;
1341         regs->reg_rc_klut.madi_thd.madi_thd1 = 9;
1342         regs->reg_rc_klut.madi_thd.madi_thd2 = 15;
1343     }
1344 
1345     if (cfg->rc.rc_mode == MPP_ENC_RC_MODE_SMTRC) {
1346         regs->reg_base.rc_qp.rc_qp_range = 0;
1347     }
1348 
1349     hal_h264e_dbg_func("leave\n");
1350 }
1351 
setup_vepu580_io_buf(HalVepu580RegSet * regs,MppDevRegOffCfgs * offsets,HalEncTask * task)1352 static void setup_vepu580_io_buf(HalVepu580RegSet *regs, MppDevRegOffCfgs *offsets,
1353                                  HalEncTask *task)
1354 {
1355     MppFrame frm = task->frame;
1356     MppPacket pkt = task->packet;
1357     MppBuffer buf_in = mpp_frame_get_buffer(frm);
1358     MppBuffer buf_out = task->output;
1359     MppFrameFormat fmt = mpp_frame_get_fmt(frm);
1360     RK_S32 hor_stride = mpp_frame_get_hor_stride(frm);
1361     RK_S32 ver_stride = mpp_frame_get_ver_stride(frm);
1362     RK_S32 fd_in = mpp_buffer_get_fd(buf_in);
1363     RK_U32 off_in[2] = {0};
1364     RK_U32 off_out = mpp_packet_get_length(pkt);
1365     size_t siz_out = mpp_buffer_get_size(buf_out);
1366     RK_S32 fd_out = mpp_buffer_get_fd(buf_out);
1367 
1368     hal_h264e_dbg_func("enter\n");
1369 
1370     regs->reg_base.adr_src0   = fd_in;
1371     regs->reg_base.adr_src1   = fd_in;
1372     regs->reg_base.adr_src2   = fd_in;
1373 
1374     regs->reg_base.bsbb_addr  = fd_out;
1375     regs->reg_base.bsbr_addr  = fd_out;
1376     regs->reg_base.adr_bsbs   = fd_out;
1377     regs->reg_base.bsbt_addr  = fd_out;
1378 
1379     if (MPP_FRAME_FMT_IS_FBC(fmt)) {
1380         off_in[0] = mpp_frame_get_fbc_offset(frm);;
1381         off_in[1] = 0;
1382     } else if (MPP_FRAME_FMT_IS_YUV(fmt)) {
1383         VepuFmtCfg cfg;
1384 
1385         vepu5xx_set_fmt(&cfg, fmt);
1386         switch (cfg.format) {
1387         case VEPU5xx_FMT_BGRA8888 :
1388         case VEPU5xx_FMT_BGR888 :
1389         case VEPU5xx_FMT_BGR565 : {
1390             off_in[0] = 0;
1391             off_in[1] = 0;
1392         } break;
1393         case VEPU5xx_FMT_YUV420SP :
1394         case VEPU5xx_FMT_YUV422SP : {
1395             off_in[0] = hor_stride * ver_stride;
1396             off_in[1] = hor_stride * ver_stride;
1397         } break;
1398         case VEPU5xx_FMT_YUV422P : {
1399             off_in[0] = hor_stride * ver_stride;
1400             off_in[1] = hor_stride * ver_stride * 3 / 2;
1401         } break;
1402         case VEPU5xx_FMT_YUV420P : {
1403             off_in[0] = hor_stride * ver_stride;
1404             off_in[1] = hor_stride * ver_stride * 5 / 4;
1405         } break;
1406         case VEPU5xx_FMT_YUV400 :
1407         case VEPU5xx_FMT_YUYV422 :
1408         case VEPU5xx_FMT_UYVY422 : {
1409             off_in[0] = 0;
1410             off_in[1] = 0;
1411         } break;
1412         case VEPU5xx_FMT_YUV444SP : {
1413             off_in[0] = hor_stride * ver_stride;
1414             off_in[1] = hor_stride * ver_stride;
1415         } break;
1416         case VEPU5xx_FMT_YUV444P : {
1417             off_in[0] = hor_stride * ver_stride;
1418             off_in[1] = hor_stride * ver_stride * 2;
1419         } break;
1420         default : {
1421             off_in[0] = 0;
1422             off_in[1] = 0;
1423         } break;
1424         }
1425     }
1426 
1427     mpp_dev_multi_offset_update(offsets, 161, off_in[0]);
1428     mpp_dev_multi_offset_update(offsets, 162, off_in[1]);
1429     mpp_dev_multi_offset_update(offsets, 172, siz_out);
1430     mpp_dev_multi_offset_update(offsets, 175, off_out);
1431 
1432     hal_h264e_dbg_func("leave\n");
1433 }
1434 
vepu580_h264_set_one_roi(void * buf,MppEncROIRegion * region,RK_S32 w,RK_S32 h)1435 static MPP_RET vepu580_h264_set_one_roi(void *buf, MppEncROIRegion *region, RK_S32 w, RK_S32 h)
1436 {
1437     Vepu580RoiH264BsCfg *ptr = (Vepu580RoiH264BsCfg *)buf;
1438     RK_S32 mb_w = MPP_ALIGN(w, 16) / 16;
1439     RK_S32 mb_h = MPP_ALIGN(h, 16) / 16;
1440     RK_S32 stride_h = MPP_ALIGN(mb_w, 4);
1441     Vepu580RoiH264BsCfg cfg;
1442     MPP_RET ret = MPP_NOK;
1443 
1444     if (NULL == buf || NULL == region) {
1445         mpp_err_f("invalid buf %p roi %p\n", buf, region);
1446         goto DONE;
1447     }
1448 
1449     RK_S32 roi_width  = (region->w + 15) / 16;
1450     RK_S32 roi_height = (region->h + 15) / 16;
1451     RK_S32 pos_x_init = region->x / 16;
1452     RK_S32 pos_y_init = region->y / 16;
1453     RK_S32 pos_x_end  = pos_x_init + roi_width;
1454     RK_S32 pos_y_end  = pos_y_init + roi_height;
1455     RK_S32 x, y;
1456 
1457     pos_x_end = MPP_MIN(pos_x_end, mb_w);
1458     pos_y_end = MPP_MIN(pos_y_end, mb_h);
1459     pos_x_init = MPP_MAX(pos_x_init, 0);
1460     pos_y_init = MPP_MAX(pos_y_init, 0);
1461 
1462     mpp_assert(pos_x_end > pos_x_init);
1463     mpp_assert(pos_y_end > pos_y_init);
1464 
1465     cfg.force_intra = 1;
1466 
1467     ptr += pos_y_init * stride_h + pos_x_init;
1468     roi_width = pos_x_end - pos_x_init;
1469     roi_height = pos_y_end - pos_y_init;
1470 
1471     for (y = 0; y < roi_height; y++) {
1472         Vepu580RoiH264BsCfg *dst = ptr;
1473 
1474         for (x = 0; x < roi_width; x++, dst++)
1475             memcpy(dst, &cfg, sizeof(cfg));
1476 
1477         ptr += stride_h;
1478     }
1479 DONE:
1480     return ret;
1481 }
1482 
setup_vepu580_intra_refresh(HalVepu580RegSet * regs,HalH264eVepu580Ctx * ctx,RK_U32 refresh_idx)1483 static MPP_RET setup_vepu580_intra_refresh(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx, RK_U32 refresh_idx)
1484 {
1485     MPP_RET ret = MPP_OK;
1486     RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
1487     RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
1488     RK_U32 w = mb_w * 16;
1489     RK_U32 h = mb_h * 16;
1490     MppEncROIRegion *region = NULL;
1491     RK_U32 refresh_num = ctx->cfg->rc.refresh_num;
1492     RK_U32 stride_h = MPP_ALIGN(mb_w, 4);
1493     RK_U32 stride_v = MPP_ALIGN(mb_h, 4);
1494     RK_S32 roi_base_buf_size = stride_h * stride_v * 8;
1495     RK_U32 i = 0;
1496 
1497     hal_h264e_dbg_func("enter\n");
1498 
1499     if (!ctx->cfg->rc.refresh_en) {
1500         ret = MPP_ERR_VALUE;
1501         goto RET;
1502     }
1503 
1504     if (ctx->roi_base_buf_size < roi_base_buf_size) {
1505         if (NULL == ctx->roi_grp)
1506             mpp_buffer_group_get_internal(&ctx->roi_grp, MPP_BUFFER_TYPE_ION);
1507         if (ctx->roi_base_cfg_buf)
1508             mpp_buffer_put(ctx->roi_base_cfg_buf);
1509         mpp_buffer_get(ctx->roi_grp, &ctx->roi_base_cfg_buf, roi_base_buf_size);
1510         ctx->roi_base_buf_size = roi_base_buf_size;
1511     }
1512 
1513     mpp_assert(ctx->roi_base_cfg_buf);
1514     RK_S32 base_cfg_fd = mpp_buffer_get_fd(ctx->roi_base_cfg_buf);
1515     void *base_cfg_buf = mpp_buffer_get_ptr(ctx->roi_base_cfg_buf);
1516     Vepu580RoiH264BsCfg base_cfg;
1517     Vepu580RoiH264BsCfg *base_cfg_ptr = (Vepu580RoiH264BsCfg *)base_cfg_buf;
1518 
1519     base_cfg.force_intra = 0;
1520     base_cfg.qp_adj_en   = 1;
1521 
1522     for (i = 0; i < stride_h * stride_v; i++, base_cfg_ptr++)
1523         memcpy(base_cfg_ptr, &base_cfg, sizeof(base_cfg));
1524 
1525     region = mpp_calloc(MppEncROIRegion, 1);
1526 
1527     if (NULL == region) {
1528         mpp_err_f("Failed to calloc for MppEncROIRegion !\n");
1529         ret = MPP_ERR_MALLOC;
1530     }
1531 
1532     if (ctx->cfg->rc.refresh_mode == MPP_ENC_RC_INTRA_REFRESH_ROW) {
1533         region->x = 0;
1534         region->w = w;
1535         if (refresh_idx > 0) {
1536             region->y = refresh_idx * 16 * refresh_num - 32;
1537             region->h = 16 * refresh_num + 32;
1538         } else {
1539             region->y = refresh_idx * 16 * refresh_num;
1540             region->h = 16 * refresh_num;
1541         }
1542         regs->reg_base.me_rnge.cme_srch_v = 1;
1543     } else if (ctx->cfg->rc.refresh_mode == MPP_ENC_RC_INTRA_REFRESH_COL) {
1544         region->y = 0;
1545         region->h = h;
1546         if (refresh_idx > 0) {
1547             region->x = refresh_idx * 16 * refresh_num - 32;
1548             region->w = 16 * refresh_num + 32;
1549         } else {
1550             region->x = refresh_idx * 16 * refresh_num;
1551             region->w = 16 * refresh_num;
1552         }
1553         regs->reg_base.me_rnge.cme_srch_h = 1;
1554     }
1555 
1556     region->intra = 1;
1557     region->quality = -ctx->cfg->rc.qp_delta_ip;
1558 
1559     region->area_map_en = 1;
1560     region->qp_area_idx = 1;
1561     region->abs_qp_en = 0;
1562 
1563     regs->reg_base.enc_pic.roi_en = 1;
1564     regs->reg_base.roi_addr = base_cfg_fd;
1565     vepu580_h264_set_one_roi(base_cfg_buf, region, w, h);
1566     mpp_free(region);
1567     mpp_buffer_sync_end(ctx->roi_base_cfg_buf);
1568 
1569 RET:
1570     hal_h264e_dbg_func("leave, ret %d\n", ret);
1571     return ret;
1572 }
1573 
setup_vepu580_roi(HalVepu580RegSet * regs,HalH264eVepu580Ctx * ctx)1574 static void setup_vepu580_roi(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx)
1575 {
1576     hal_h264e_dbg_func("enter\n");
1577 
1578     /* memset register on start so do not clear registers again here */
1579     if (ctx->roi_data) {
1580         /* roi setup */
1581         RK_U32 mb_w = MPP_ALIGN(ctx->cfg->prep.width, 64) / 16;
1582         RK_U32 mb_h = MPP_ALIGN(ctx->cfg->prep.height, 64) / 16;
1583         RK_U32 base_cfg_size = mb_w * mb_h * 8;
1584         RK_U32 qp_cfg_size   = mb_w * mb_h * 2;
1585         RK_U32 amv_cfg_size  = mb_w * mb_h / 4;
1586         RK_U32 mv_cfg_size   = mb_w * mb_h * 96 / 4;
1587         MppEncROICfg2 *cfg   = (MppEncROICfg2 *)ctx->roi_data;
1588 
1589         if (mpp_buffer_get_size(cfg->base_cfg_buf) >= base_cfg_size) {
1590             regs->reg_base.enc_pic.roi_en = 1;
1591             regs->reg_base.roi_addr = mpp_buffer_get_fd(cfg->base_cfg_buf);
1592         } else {
1593             mpp_err("roi base cfg buf not enough, roi is invalid");
1594         }
1595 
1596         if (cfg->roi_qp_en) {
1597             if (mpp_buffer_get_size(cfg->qp_cfg_buf) >= qp_cfg_size) {
1598                 regs->reg_base.roi_qp_addr  =  mpp_buffer_get_fd(cfg->qp_cfg_buf);
1599                 regs->reg_base.roi_en.roi_qp_en = 1;
1600             } else {
1601                 mpp_err("roi qp cfg buf not enough, roi is invalid");
1602             }
1603         }
1604 
1605         if (cfg->roi_amv_en) {
1606             if (mpp_buffer_get_size(cfg->amv_cfg_buf) >= amv_cfg_size) {
1607                 regs->reg_base.qoi_amv_addr =  mpp_buffer_get_fd(cfg->amv_cfg_buf);
1608                 regs->reg_base.roi_en.roi_amv_en = 1;
1609             } else {
1610                 mpp_err("roi amv cfg buf not enough, roi is invalid");
1611             }
1612         }
1613 
1614         if (cfg->roi_mv_en) {
1615             if (mpp_buffer_get_size(cfg->mv_cfg_buf) >= mv_cfg_size) {
1616                 regs->reg_base.qoi_mv_addr =  mpp_buffer_get_fd(cfg->mv_cfg_buf);
1617                 regs->reg_base.roi_en.roi_mv_en = 1;
1618             } else {
1619                 mpp_err("roi mv cfg buf not enough, roi is invalid");
1620             }
1621         }
1622     }
1623 
1624     hal_h264e_dbg_func("leave\n");
1625 }
1626 
setup_vepu580_recn_refr(HalH264eVepu580Ctx * ctx,HalVepu580RegSet * regs)1627 static void setup_vepu580_recn_refr(HalH264eVepu580Ctx *ctx, HalVepu580RegSet *regs)
1628 {
1629     H264eFrmInfo *frms = ctx->frms;
1630     HalBufs bufs = ctx->hw_recn;
1631     RK_S32 fbc_hdr_size = ctx->pixel_buf_fbc_hdr_size;
1632 
1633     HalBuf *curr = hal_bufs_get_buf(bufs, frms->curr_idx);
1634     HalBuf *refr = hal_bufs_get_buf(bufs, frms->refr_idx);
1635 
1636     hal_h264e_dbg_func("enter\n");
1637 
1638     if (curr && curr->cnt) {
1639         MppBuffer buf_pixel = curr->buf[0];
1640         MppBuffer buf_thumb = curr->buf[1];
1641         RK_S32 fd = mpp_buffer_get_fd(buf_pixel);
1642 
1643         mpp_assert(buf_pixel);
1644         mpp_assert(buf_thumb);
1645 
1646         regs->reg_base.rfpw_h_addr = fd;
1647         regs->reg_base.rfpw_b_addr = fd;
1648         regs->reg_base.dspw_addr = mpp_buffer_get_fd(buf_thumb);
1649     }
1650 
1651     if (refr && refr->cnt) {
1652         MppBuffer buf_pixel = refr->buf[0];
1653         MppBuffer buf_thumb = refr->buf[1];
1654         RK_S32 fd = mpp_buffer_get_fd(buf_pixel);
1655 
1656         mpp_assert(buf_pixel);
1657         mpp_assert(buf_thumb);
1658 
1659         regs->reg_base.rfpr_h_addr = fd;
1660         regs->reg_base.rfpr_b_addr = fd;
1661         regs->reg_base.dspr_addr = mpp_buffer_get_fd(buf_thumb);
1662     }
1663 
1664     mpp_dev_multi_offset_update(ctx->offsets, 164, fbc_hdr_size);
1665     mpp_dev_multi_offset_update(ctx->offsets, 166, fbc_hdr_size);
1666 
1667     hal_h264e_dbg_func("leave\n");
1668 }
1669 
setup_vepu580_split(HalVepu580RegSet * regs,MppEncCfgSet * enc_cfg)1670 static void setup_vepu580_split(HalVepu580RegSet *regs, MppEncCfgSet *enc_cfg)
1671 {
1672     MppEncSliceSplit *cfg = &enc_cfg->split;
1673 
1674     hal_h264e_dbg_func("enter\n");
1675 
1676     switch (cfg->split_mode) {
1677     case MPP_ENC_SPLIT_NONE : {
1678         regs->reg_base.sli_splt.sli_splt = 0;
1679         regs->reg_base.sli_splt.sli_splt_mode = 0;
1680         regs->reg_base.sli_splt.sli_splt_cpst = 0;
1681         regs->reg_base.sli_splt.sli_max_num_m1 = 0;
1682         regs->reg_base.sli_splt.sli_flsh = 0;
1683         regs->reg_base.sli_cnum.sli_splt_cnum_m1 = 0;
1684 
1685         regs->reg_base.sli_byte.sli_splt_byte = 0;
1686         regs->reg_base.enc_pic.slen_fifo = 0;
1687     } break;
1688     case MPP_ENC_SPLIT_BY_BYTE : {
1689         regs->reg_base.sli_splt.sli_splt = 1;
1690         regs->reg_base.sli_splt.sli_splt_mode = 0;
1691         regs->reg_base.sli_splt.sli_splt_cpst = 0;
1692         regs->reg_base.sli_splt.sli_max_num_m1 = 500;
1693         regs->reg_base.sli_splt.sli_flsh = 1;
1694         regs->reg_base.sli_cnum.sli_splt_cnum_m1 = 0;
1695 
1696         regs->reg_base.sli_byte.sli_splt_byte = cfg->split_arg;
1697         regs->reg_base.enc_pic.slen_fifo = cfg->split_out ? 1 : 0;
1698         regs->reg_ctl.int_en.slc_done_en = regs->reg_base.enc_pic.slen_fifo;
1699     } break;
1700     case MPP_ENC_SPLIT_BY_CTU : {
1701         RK_U32 mb_w = MPP_ALIGN(enc_cfg->prep.width, 16) / 16;
1702         RK_U32 mb_h = MPP_ALIGN(enc_cfg->prep.height, 16) / 16;
1703         RK_U32 slice_num = (mb_w * mb_h + cfg->split_arg - 1) / cfg->split_arg;
1704 
1705         regs->reg_base.sli_splt.sli_splt = 1;
1706         regs->reg_base.sli_splt.sli_splt_mode = 1;
1707         regs->reg_base.sli_splt.sli_splt_cpst = 0;
1708         regs->reg_base.sli_splt.sli_max_num_m1 = 500;
1709         regs->reg_base.sli_splt.sli_flsh = 1;
1710         regs->reg_base.sli_cnum.sli_splt_cnum_m1 = cfg->split_arg - 1;
1711 
1712         regs->reg_base.sli_byte.sli_splt_byte = 0;
1713         regs->reg_base.enc_pic.slen_fifo = cfg->split_out ? 1 : 0;
1714 
1715         if ((cfg->split_out & MPP_ENC_SPLIT_OUT_LOWDELAY) ||
1716             (regs->reg_base.enc_pic.slen_fifo && (slice_num > VEPU580_SLICE_FIFO_LEN)))
1717             regs->reg_ctl.int_en.slc_done_en = 1;
1718 
1719     } break;
1720     default : {
1721         mpp_log_f("invalide slice split mode %d\n", cfg->split_mode);
1722     } break;
1723     }
1724 
1725     hal_h264e_dbg_func("leave\n");
1726 }
1727 
calc_cime_parameter(HalVepu580RegSet * regs,H264eSps * sps)1728 static void calc_cime_parameter(HalVepu580RegSet *regs, H264eSps *sps)
1729 {
1730     Vepu580BaseCfg *base_regs = &regs->reg_base;
1731     RK_S32 x_gmv = base_regs->gmv.gmv_x;
1732     RK_S32 y_gmv = base_regs->gmv.gmv_y;
1733     RK_S32 srch_w = base_regs->me_rnge.cme_srch_h * 4;
1734     RK_S32 srch_h = base_regs->me_rnge.cme_srch_v * 4;
1735     RK_S32 frm_sta = 0, frm_end = 0, pic_w = 0;
1736     RK_S32 pic_wd64 = MPP_ALIGN(sps->pic_width_in_mbs * 16, 64) / 64;
1737 
1738     // calc cime_linebuf_w
1739     {
1740         if (x_gmv - srch_w < 0) {
1741             frm_sta = (x_gmv - srch_w - 15) / 16;
1742         } else {
1743             frm_sta = (x_gmv - srch_w) / 16;
1744         }
1745         frm_sta = mpp_clip(frm_sta, 0, pic_wd64 - 1);
1746 
1747         if (x_gmv + srch_w < 0) {
1748             frm_end = pic_wd64 - 1 + (x_gmv + srch_w) / 16;
1749         } else {
1750             frm_end = pic_wd64 - 1 + (x_gmv + srch_w + 15) / 16;
1751         }
1752         frm_end = mpp_clip(frm_end, 0, pic_wd64 - 1);
1753 
1754         pic_w = (frm_end - frm_sta + 1) * 64;
1755         base_regs->me_cach.cme_linebuf_w = (pic_w ? pic_w : 64) / 64;
1756     }
1757 
1758     // calc cime_cacha_h and cime_cacha_max
1759     {
1760         RK_U32 cime_cacha_max = 2464;
1761         RK_U32 ctu_4_h = 1, ramb_h;
1762         RK_U32 cur_srch_16_w, cur_srch_4_h, cur_srch_max;
1763         RK_U32 cime_cacha_h = ctu_4_h;
1764 
1765         if ((x_gmv % 16 - srch_w % 16) < 0) {
1766             cur_srch_16_w = (16 + (x_gmv % 16 - srch_w % 16) % 16 + srch_w * 2 + 15) / 16 + 1;
1767         } else {
1768             cur_srch_16_w = ((x_gmv % 16 - srch_w % 16) % 16 + srch_w * 2 + 15) / 16 + 1;
1769         }
1770 
1771         if ((y_gmv %  4 - srch_h %  4) < 0) {
1772             cur_srch_4_h  = (4 + (y_gmv %  4 - srch_h %  4) %  4 + srch_h * 2 +  3) / 4  + ctu_4_h;
1773         } else {
1774             cur_srch_4_h  = ((y_gmv %  4 - srch_h %  4) %  4 + srch_h * 2 +  3) / 4  + ctu_4_h;
1775         }
1776 
1777         cur_srch_max = cur_srch_4_h;
1778 
1779         if (base_regs->me_cach.cme_linebuf_w < cur_srch_16_w) {
1780             cur_srch_16_w = base_regs->me_cach.cme_linebuf_w;
1781         }
1782 
1783         ramb_h = cur_srch_4_h;
1784         while ((cime_cacha_h < cur_srch_max) && (cime_cacha_max >
1785                                                  ((cime_cacha_h - ctu_4_h) * base_regs->me_cach.cme_linebuf_w * 4 + (ramb_h * 4 * cur_srch_16_w)))) {
1786             cime_cacha_h = cime_cacha_h + ctu_4_h;
1787 
1788             if (ramb_h > 2 * ctu_4_h) {
1789                 ramb_h = ramb_h - ctu_4_h;
1790             } else {
1791                 ramb_h = ctu_4_h;
1792             }
1793         }
1794 
1795         if (cur_srch_4_h == ctu_4_h) {
1796             cime_cacha_h = cime_cacha_h + ctu_4_h;
1797             ramb_h = 0;
1798         }
1799 
1800         if (cime_cacha_max < ((cime_cacha_h - ctu_4_h) * base_regs->me_cach.cme_linebuf_w * 4 + (ramb_h * 4 * cur_srch_16_w))) {
1801             cime_cacha_h = cime_cacha_h - ctu_4_h;
1802         }
1803         base_regs->me_cach.cme_rama_h = cime_cacha_h;
1804 
1805         /* cime_cacha_max */
1806         {
1807             RK_U32 ram_col_h = (cime_cacha_h - ctu_4_h) / ctu_4_h;
1808             base_regs->me_cach.cme_rama_max = ram_col_h * base_regs->me_cach.cme_linebuf_w + cur_srch_16_w;
1809         }
1810     }
1811 }
1812 
setup_vepu580_me(HalVepu580RegSet * regs,H264eSps * sps,H264eSlice * slice)1813 static void setup_vepu580_me(HalVepu580RegSet *regs, H264eSps *sps,
1814                              H264eSlice *slice)
1815 {
1816     RK_S32 level_idc = sps->level_idc;
1817     RK_S32 cime_w = 176;
1818     RK_S32 cime_h = 112;
1819     RK_S32 cime_blk_w_max = 44;
1820     RK_S32 cime_blk_h_max = 28;
1821 
1822     hal_h264e_dbg_func("enter\n");
1823     /*
1824      * Step 1. limit the mv range by level_idc
1825      * For level 1 and level 1b the vertical MV range is [-64,+63.75]
1826      * For level 1.1, 1.2, 1.3 and 2 the vertical MV range is [-128,+127.75]
1827      */
1828     switch (level_idc) {
1829     case H264_LEVEL_1_0 :
1830     case H264_LEVEL_1_b : {
1831         cime_blk_h_max = 12;
1832     } break;
1833     case H264_LEVEL_1_1 :
1834     case H264_LEVEL_1_2 :
1835     case H264_LEVEL_1_3 :
1836     case H264_LEVEL_2_0 : {
1837         cime_blk_h_max = 28;
1838     } break;
1839     default : {
1840         cime_blk_h_max = 28;
1841     } break;
1842     }
1843 
1844     if (cime_w < cime_blk_w_max * 4)
1845         cime_blk_w_max = cime_w / 4;
1846 
1847     if (cime_h < cime_blk_h_max * 4)
1848         cime_blk_h_max = cime_h / 4;
1849 
1850     /*
1851      * Step 2. limit the mv range by image size
1852      */
1853     if (cime_blk_w_max / 4 * 2 > (sps->pic_width_in_mbs * 2 + 1) / 2)
1854         cime_blk_w_max = (sps->pic_width_in_mbs * 2 + 1) / 2 / 2 * 4;
1855 
1856     if (cime_blk_h_max / 4 > MPP_ALIGN(sps->pic_height_in_mbs * 16, 64) / 128 * 4)
1857         cime_blk_h_max = MPP_ALIGN(sps->pic_height_in_mbs * 16, 64) / 128 * 16;
1858 
1859     regs->reg_base.me_rnge.cme_srch_h     = cime_blk_w_max / 4;
1860     regs->reg_base.me_rnge.cme_srch_v     = cime_blk_h_max / 4;
1861     regs->reg_base.me_rnge.rme_srch_h     = 7;
1862     regs->reg_base.me_rnge.rme_srch_v     = 5;
1863     regs->reg_base.me_rnge.dlt_frm_num    = 0;
1864 
1865     if (slice->slice_type == H264_I_SLICE) {
1866         regs->reg_base.me_cfg.pmv_mdst_h = 0;
1867         regs->reg_base.me_cfg.pmv_mdst_v = 0;
1868     } else {
1869         regs->reg_base.me_cfg.pmv_mdst_h = 5;
1870         regs->reg_base.me_cfg.pmv_mdst_v = 5;
1871     }
1872     regs->reg_base.me_cfg.mv_limit  = (sps->level_idc > 20) ? 2 : ((sps->level_idc >= 11) ? 1 : 0);//2;
1873     regs->reg_base.me_cfg.pmv_num   = 2;
1874     regs->reg_base.me_cfg.rme_dis   = 0;
1875     regs->reg_base.me_cfg.fme_dis   = 0;
1876     regs->reg_base.me_cfg.lvl4_ovrd_en   = 0;
1877 
1878     calc_cime_parameter(regs, sps);
1879 
1880     hal_h264e_dbg_func("leave\n");
1881 }
1882 
1883 #define H264E_LAMBDA_TAB_SIZE       (52 * sizeof(RK_U32))
1884 
1885 static RK_U32 h264e_lambda_default[58] = {
1886     0x00000003, 0x00000005, 0x00000006, 0x00000007,
1887     0x00000009, 0x0000000b, 0x0000000e, 0x00000012,
1888     0x00000016, 0x0000001c, 0x00000024, 0x0000002d,
1889     0x00000039, 0x00000048, 0x0000005b, 0x00000073,
1890     0x00000091, 0x000000b6, 0x000000e6, 0x00000122,
1891     0x0000016d, 0x000001cc, 0x00000244, 0x000002db,
1892     0x00000399, 0x00000489, 0x000005b6, 0x00000733,
1893     0x00000912, 0x00000b6d, 0x00000e66, 0x00001224,
1894     0x000016db, 0x00001ccc, 0x00002449, 0x00002db7,
1895     0x00003999, 0x00004892, 0x00005b6f, 0x00007333,
1896     0x00009124, 0x0000b6de, 0x0000e666, 0x00012249,
1897     0x00016dbc, 0x0001cccc, 0x00024492, 0x0002db79,
1898     0x00039999, 0x00048924, 0x0005b6f2, 0x00073333,
1899     0x00091249, 0x000b6de5, 0x000e6666, 0x00122492,
1900     0x0016dbcb, 0x001ccccc,
1901 };
1902 
setup_vepu580_l2(HalVepu580RegSet * regs,H264eSlice * slice,MppEncHwCfg * hw)1903 static void setup_vepu580_l2(HalVepu580RegSet *regs, H264eSlice *slice, MppEncHwCfg *hw)
1904 {
1905     RK_U32 i;
1906 
1907     hal_h264e_dbg_func("enter\n");
1908 
1909     regs->reg_s3.iprd_wgt_qp_hevc_0_51[0] = 0;
1910     /* ~ */
1911     regs->reg_s3.iprd_wgt_qp_hevc_0_51[51] = 0;
1912 
1913     if (slice->slice_type == H264_I_SLICE) {
1914         memcpy(regs->reg_s3.rdo_wgta_qp_grpa_0_51, &h264e_lambda_default[6], H264E_LAMBDA_TAB_SIZE);
1915     } else {
1916         memcpy(regs->reg_s3.rdo_wgta_qp_grpa_0_51, &h264e_lambda_default[6], H264E_LAMBDA_TAB_SIZE);
1917     }
1918     memset(regs->reg_s3.iprd_wgt_qp_hevc_0_51, 0, H264E_LAMBDA_TAB_SIZE);
1919 
1920     regs->reg_rc_klut.madi_cfg.madi_mode = 0;
1921     regs->reg_rc_klut.madi_cfg.madi_thd  = 25;
1922 
1923     regs->reg_s3.lvl32_intra_CST_THD0.lvl4_intra_cst_thd0 = 1;
1924     regs->reg_s3.lvl32_intra_CST_THD0.lvl4_intra_cst_thd1 = 4;
1925     regs->reg_s3.lvl32_intra_CST_THD1.lvl4_intra_cst_thd2 = 9;
1926     regs->reg_s3.lvl32_intra_CST_THD1.lvl4_intra_cst_thd3 = 36;
1927 
1928     regs->reg_s3.lvl16_intra_CST_THD0.lvl8_intra_chrm_cst_thd0 = 1;
1929     regs->reg_s3.lvl16_intra_CST_THD0.lvl8_intra_chrm_cst_thd1 = 4;
1930     regs->reg_s3.lvl16_intra_CST_THD1.lvl8_intra_chrm_cst_thd2 = 9;
1931     regs->reg_s3.lvl16_intra_CST_THD1.lvl8_intra_chrm_cst_thd3 = 36;
1932 
1933     regs->reg_s3.lvl8_intra_CST_THD0.lvl8_intra_cst_thd0 = 1;
1934     regs->reg_s3.lvl8_intra_CST_THD0.lvl8_intra_cst_thd1 = 4;
1935     regs->reg_s3.lvl8_intra_CST_THD1.lvl8_intra_cst_thd2 = 9;
1936     regs->reg_s3.lvl8_intra_CST_THD1.lvl8_intra_cst_thd3 = 36;
1937 
1938     regs->reg_s3.lvl16_intra_UL_CST_THD.lvl16_intra_ul_cst_thld = 0;
1939     regs->reg_s3.lvl32_intra_CST_WGT0.lvl8_intra_cst_wgt0 = 48;
1940     regs->reg_s3.lvl32_intra_CST_WGT0.lvl8_intra_cst_wgt1 = 60;
1941     regs->reg_s3.lvl32_intra_CST_WGT0.lvl8_intra_cst_wgt2 = 40;
1942     regs->reg_s3.lvl32_intra_CST_WGT0.lvl8_intra_cst_wgt3 = 48;
1943 
1944     regs->reg_s3.lvl32_intra_CST_WGT1.lvl4_intra_cst_wgt0 = 48;
1945     regs->reg_s3.lvl32_intra_CST_WGT1.lvl4_intra_cst_wgt1 = 60;
1946     regs->reg_s3.lvl32_intra_CST_WGT1.lvl4_intra_cst_wgt2 = 40;
1947     regs->reg_s3.lvl32_intra_CST_WGT1.lvl4_intra_cst_wgt3 = 48;
1948 
1949     regs->reg_s3.lvl16_intra_CST_WGT0.lvl16_intra_cst_wgt0 = 48;
1950     regs->reg_s3.lvl16_intra_CST_WGT0.lvl16_intra_cst_wgt1 = 60;
1951     regs->reg_s3.lvl16_intra_CST_WGT0.lvl16_intra_cst_wgt2 = 40;
1952     regs->reg_s3.lvl16_intra_CST_WGT0.lvl16_intra_cst_wgt3 = 48;
1953     /* 0x1728 */
1954     regs->reg_s3.lvl16_intra_CST_WGT1.lvl8_intra_chrm_cst_wgt0 = 36;
1955     regs->reg_s3.lvl16_intra_CST_WGT1.lvl8_intra_chrm_cst_wgt1 = 42;
1956     regs->reg_s3.lvl16_intra_CST_WGT1.lvl8_intra_chrm_cst_wgt2 = 28;
1957     regs->reg_s3.lvl16_intra_CST_WGT1.lvl8_intra_chrm_cst_wgt3 = 32;
1958 
1959     regs->reg_s3.RDO_QUANT.quant_f_bias_P = 171;
1960 
1961     if (slice->slice_type == H264_I_SLICE) {
1962         regs->reg_s3.RDO_QUANT.quant_f_bias_I = 683;
1963         regs->reg_s3.ATR_THD0.atr_thd0 = 1;
1964         regs->reg_s3.ATR_THD0.atr_thd1 = 4;
1965         regs->reg_s3.ATR_THD1.atr_thd2 = 36;
1966     } else {
1967         regs->reg_s3.RDO_QUANT.quant_f_bias_I = 583;
1968         regs->reg_s3.ATR_THD0.atr_thd0 = 4;
1969         regs->reg_s3.ATR_THD0.atr_thd1 = 16;
1970         regs->reg_s3.ATR_THD1.atr_thd2 = 81;
1971     }
1972     regs->reg_s3.ATR_THD1.atr_thdqp = 45;
1973 
1974     if (slice->slice_type == H264_I_SLICE) {
1975         regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt0 = 16;
1976         regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt1 = 16;
1977         regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt2 = 16;
1978 
1979         regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt0 = 22;
1980         regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt1 = 21;
1981         regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt2 = 20;
1982 
1983         regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt0 = 20;
1984         regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt1 = 18;
1985         regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt2 = 16;
1986     } else {
1987         regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt0 = 25;
1988         regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt1 = 20;
1989         regs->reg_s3.Lvl16_ATR_WGT.lvl16_atr_wgt2 = 16;
1990 
1991         regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt0 = 25;
1992         regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt1 = 20;
1993         regs->reg_s3.Lvl8_ATR_WGT.lvl8_atr_wgt2 = 18;
1994 
1995         regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt0 = 25;
1996         regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt1 = 20;
1997         regs->reg_s3.Lvl4_ATR_WGT.lvl4_atr_wgt2 = 16;
1998     }
1999     /* CIME */
2000     {
2001         /* 0x1760 */
2002         regs->reg_s3.cime_sqi_cfg.cime_sad_mod_sel = 0;
2003         regs->reg_s3.cime_sqi_cfg.cime_sad_use_big_block = 1;
2004         regs->reg_s3.cime_sqi_cfg.cime_pmv_set_zero = 1;
2005         regs->reg_s3.cime_sqi_cfg.cime_pmv_num = 3;
2006 
2007         /* 0x1764 */
2008         regs->reg_s3.cime_sqi_thd.cime_mvd_th0 = 32;
2009         regs->reg_s3.cime_sqi_thd.cime_mvd_th1 = 80;
2010         regs->reg_s3.cime_sqi_thd.cime_mvd_th2 = 128;
2011 
2012         /* 0x1768 */
2013         regs->reg_s3.cime_sqi_multi0.cime_multi0 = 4;
2014         regs->reg_s3.cime_sqi_multi0.cime_multi1 = 8;
2015         regs->reg_s3.cime_sqi_multi1.cime_multi2 = 24;
2016         regs->reg_s3.cime_sqi_multi1.cime_multi3 = 24;
2017     }
2018 
2019     /* RIME && FME */
2020     {
2021         /* 0x1770 */
2022         regs->reg_s3.rime_sqi_thd.cime_sad_th0  = 50;
2023         regs->reg_s3.rime_sqi_thd.rime_mvd_th0  = 3;
2024         regs->reg_s3.rime_sqi_thd.rime_mvd_th1  = 8;
2025         regs->reg_s3.rime_sqi_multi.rime_multi0 = 4;
2026         regs->reg_s3.rime_sqi_multi.rime_multi1 = 32;
2027         regs->reg_s3.rime_sqi_multi.rime_multi2 = 128;
2028 
2029         /* 0x1778 */
2030         regs->reg_s3.fme_sqi_thd0.cime_sad_pu16_th = 2;
2031 
2032         /* 0x177C */
2033         regs->reg_s3.fme_sqi_thd1.move_lambda = 1;
2034     }
2035 
2036     if (slice->slice_type == H264_I_SLICE) {
2037         for (i = 0; i < MPP_ARRAY_ELEMS(h264_aq_tthd_default); i++) {
2038             regs->reg_rc_klut.aq_tthd[i] = hw->aq_thrd_i[i];
2039             regs->reg_rc_klut.aq_step[i] = hw->aq_step_i[i] & 0x3f;
2040         }
2041     } else {
2042         for (i = 0; i < MPP_ARRAY_ELEMS(h264_P_aq_step_default); i++) {
2043             regs->reg_rc_klut.aq_tthd[i] = hw->aq_thrd_p[i];
2044             regs->reg_rc_klut.aq_step[i] = hw->aq_step_p[i] & 0x3f;
2045         }
2046     }
2047 
2048     hal_h264e_dbg_func("leave\n");
2049 }
2050 
setup_vepu580_ext_line_buf(HalVepu580RegSet * regs,HalH264eVepu580Ctx * ctx)2051 static void setup_vepu580_ext_line_buf(HalVepu580RegSet *regs, HalH264eVepu580Ctx *ctx)
2052 {
2053     RK_S32 offset = 0;
2054     RK_S32 fd;
2055 
2056     if (!ctx->ext_line_buf) {
2057         regs->reg_base.ebufb_addr = 0;
2058         regs->reg_base.ebufb_addr = 0;
2059         return;
2060     }
2061 
2062     fd = mpp_buffer_get_fd(ctx->ext_line_buf);
2063     offset = ctx->ext_line_buf_size;
2064 
2065     regs->reg_base.ebuft_addr = fd;
2066     regs->reg_base.ebufb_addr = fd;
2067 
2068     mpp_dev_multi_offset_update(ctx->offsets, 182, offset);
2069 
2070     /* rcb info for sram */
2071     if (!disable_rcb_buf) {
2072         MppDevRcbInfoCfg rcb_cfg;
2073 
2074         rcb_cfg.reg_idx = 183;
2075         rcb_cfg.size = offset;
2076 
2077         mpp_dev_ioctl(ctx->dev, MPP_DEV_RCB_INFO, &rcb_cfg);
2078 
2079         rcb_cfg.reg_idx = 182;
2080         rcb_cfg.size = 0;
2081 
2082         mpp_dev_ioctl(ctx->dev, MPP_DEV_RCB_INFO, &rcb_cfg);
2083     }
2084 }
2085 
setup_vepu580_dual_core(HalH264eVepu580Ctx * ctx,H264SliceType slice_type)2086 static MPP_RET setup_vepu580_dual_core(HalH264eVepu580Ctx *ctx, H264SliceType slice_type)
2087 {
2088     Vepu580BaseCfg *reg_base = &ctx->regs_set->reg_base;
2089     RK_U32 dchs_ofst = 9;
2090     RK_U32 dchs_rxe  = 1;
2091 
2092     if (ctx->task_cnt == 1)
2093         return MPP_OK;
2094 
2095     if (slice_type == H264_I_SLICE) {
2096         ctx->curr_idx = 0;
2097         ctx->prev_idx = 0;
2098         dchs_rxe = 0;
2099     }
2100 
2101     reg_base->dual_core.dchs_txid = ctx->curr_idx;
2102     reg_base->dual_core.dchs_rxid = ctx->prev_idx;
2103     reg_base->dual_core.dchs_txe = 1;
2104     reg_base->dual_core.dchs_rxe = dchs_rxe;
2105     reg_base->dual_core.dchs_ofst = dchs_ofst;
2106 
2107     ctx->prev_idx = ctx->curr_idx++;
2108     if (ctx->curr_idx > 3)
2109         ctx->curr_idx = 0;
2110 
2111     return MPP_OK;
2112 }
2113 
hal_h264e_vepu580_gen_regs(void * hal,HalEncTask * task)2114 static MPP_RET hal_h264e_vepu580_gen_regs(void *hal, HalEncTask *task)
2115 {
2116     HalH264eVepu580Ctx *ctx = (HalH264eVepu580Ctx *)hal;
2117     HalVepu580RegSet *regs = ctx->regs_set;
2118     MppEncCfgSet *cfg = ctx->cfg;
2119     H264eSps *sps = ctx->sps;
2120     H264ePps *pps = ctx->pps;
2121     H264eSlice *slice = ctx->slice;
2122     EncRcTask *rc_task = task->rc_task;
2123     EncFrmStatus *frm = &rc_task->frm;
2124     MPP_RET ret = MPP_OK;
2125     EncFrmStatus *frm_status = &task->rc_task->frm;
2126 
2127     hal_h264e_dbg_func("enter %p\n", hal);
2128     hal_h264e_dbg_detail("frame %d generate regs now", ctx->frms->seq_idx);
2129 
2130     /* register setup */
2131     memset(regs, 0, sizeof(*regs));
2132 
2133     setup_vepu580_normal(regs);
2134     ret = setup_vepu580_prep(regs, &ctx->cfg->prep, task);
2135     if (ret)
2136         return ret;
2137 
2138     setup_vepu580_dual_core(ctx, slice->slice_type);
2139     setup_vepu580_codec(regs, sps, pps, slice);
2140     setup_vepu580_rdo_pred(regs, sps, pps, slice);
2141     setup_vepu580_rdo_cfg(&regs->reg_rdo);
2142     setup_vepu580_rdo_bias_cfg(&regs->reg_rdo, &cfg->hw);
2143 
2144     // scl cfg
2145     memcpy(&regs->reg_scl, vepu580_540_h264_flat_scl_tab, sizeof(vepu580_540_h264_flat_scl_tab));
2146 
2147     setup_vepu580_rc_base(regs, ctx, rc_task);
2148     setup_vepu580_io_buf(regs, ctx->offsets, task);
2149     setup_vepu580_roi(regs, ctx);
2150     setup_vepu580_recn_refr(ctx, regs);
2151 
2152     regs->reg_base.meiw_addr = task->md_info ? mpp_buffer_get_fd(task->md_info) : 0;
2153     regs->reg_base.enc_pic.mei_stor = task->md_info ? 1 : 0;
2154     regs->reg_base.pic_ofst.pic_ofst_y = mpp_frame_get_offset_y(task->frame);
2155     regs->reg_base.pic_ofst.pic_ofst_x = mpp_frame_get_offset_x(task->frame);
2156 
2157     setup_vepu580_split(regs, cfg);
2158     setup_vepu580_me(regs, sps, slice);
2159 
2160     if (frm_status->is_i_refresh)
2161         setup_vepu580_intra_refresh(regs, ctx, frm_status->seq_idx % cfg->rc.gop);
2162 
2163     if (cfg->tune.deblur_en && (!rc_task->info.complex_scene) &&
2164         cfg->rc.rc_mode == MPP_ENC_RC_MODE_SMTRC &&
2165         cfg->tune.scene_mode == MPP_ENC_SCENE_MODE_IPC) {
2166         if (MPP_OK != setup_vepu580_qpmap_buf(ctx))
2167             mpp_err("qpmap malloc buffer failed!\n");
2168     }
2169 
2170     vepu580_set_osd(&ctx->osd_cfg);
2171     setup_vepu580_l2(regs, slice, &cfg->hw);
2172     setup_vepu580_ext_line_buf(regs, ctx);
2173     vepu580_h264e_tune_reg_patch(ctx->tune);
2174 
2175     /* two pass register patch */
2176     if (frm->save_pass1)
2177         vepu580_h264e_save_pass1_patch(regs, ctx);
2178 
2179     if (frm->use_pass1)
2180         vepu580_h264e_use_pass1_patch(regs, ctx);
2181 
2182     ctx->frame_cnt++;
2183 
2184     hal_h264e_dbg_func("leave %p\n", hal);
2185     return MPP_OK;
2186 }
2187 
hal_h264e_vepu580_start(void * hal,HalEncTask * task)2188 static MPP_RET hal_h264e_vepu580_start(void *hal, HalEncTask *task)
2189 {
2190     MPP_RET ret = MPP_OK;
2191     HalH264eVepu580Ctx *ctx = (HalH264eVepu580Ctx *)hal;
2192     HalVepu580RegSet *regs = ctx->regs_set;
2193 
2194     (void) task;
2195 
2196     hal_h264e_dbg_func("enter %p\n", hal);
2197 
2198     do {
2199         MppDevRegWrCfg wr_cfg;
2200         MppDevRegRdCfg rd_cfg;
2201 
2202         wr_cfg.reg = &regs->reg_ctl;
2203         wr_cfg.size = sizeof(regs->reg_ctl);
2204         wr_cfg.offset = VEPU580_CONTROL_CFG_OFFSET;
2205 #if DUMP_REG
2206         {
2207             RK_U32 i;
2208             RK_U32 *reg = (RK_U32)wr_cfg.reg;
2209             for ( i = 0; i < sizeof(regs->reg_ctl) / sizeof(RK_U32); i++) {
2210                 /* code */
2211                 mpp_log("reg[%d] = 0x%08x\n", i, reg[i]);
2212             }
2213 
2214         }
2215 #endif
2216         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2217         if (ret) {
2218             mpp_err_f("set register write failed %d\n", ret);
2219             break;
2220         }
2221         wr_cfg.reg = &regs->reg_base;
2222         wr_cfg.size = sizeof(regs->reg_base);
2223         wr_cfg.offset = VEPU580_BASE_CFG_OFFSET;
2224 
2225         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2226         if (ret) {
2227             mpp_err_f("set register write failed %d\n", ret);
2228             break;
2229         }
2230         wr_cfg.reg = &regs->reg_rc_klut;
2231         wr_cfg.size = sizeof(regs->reg_rc_klut);
2232         wr_cfg.offset = VEPU580_RC_KLUT_CFG_OFFSET;
2233 
2234         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2235         if (ret) {
2236             mpp_err_f("set register write failed %d\n", ret);
2237             break;
2238         }
2239         wr_cfg.reg = &regs->reg_s3;
2240         wr_cfg.size = sizeof(regs->reg_s3);
2241         wr_cfg.offset = VEPU580_SECTION_3_OFFSET;
2242 
2243         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2244         if (ret) {
2245             mpp_err_f("set register write failed %d\n", ret);
2246             break;
2247         }
2248         wr_cfg.reg = &regs->reg_rdo;
2249         wr_cfg.size = sizeof(regs->reg_rdo);
2250         wr_cfg.offset = VEPU580_RDO_CFG_OFFSET;
2251 
2252         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2253         if (ret) {
2254             mpp_err_f("set register write failed %d\n", ret);
2255             break;
2256         }
2257 
2258         wr_cfg.reg = &regs->reg_scl;
2259         wr_cfg.size = sizeof(regs->reg_scl);
2260         wr_cfg.offset = VEPU580_SCL_CFG_OFFSET;
2261 
2262         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2263         if (ret) {
2264             mpp_err_f("set register write failed %d\n", ret);
2265             break;
2266         }
2267 
2268         wr_cfg.reg = &regs->reg_osd;
2269         wr_cfg.size = sizeof(regs->reg_osd);
2270         wr_cfg.offset = VEPU580_OSD_OFFSET;
2271 
2272         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
2273         if (ret) {
2274             mpp_err_f("set register write failed %d\n", ret);
2275             break;
2276         }
2277 
2278         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_OFFS, ctx->offsets);
2279         if (ret) {
2280             mpp_err_f("set register offsets failed %d\n", ret);
2281             break;
2282         }
2283 
2284         rd_cfg.reg = &regs->reg_ctl.int_sta;
2285         rd_cfg.size = sizeof(RK_U32);
2286         rd_cfg.offset = VEPU580_REG_BASE_HW_STATUS;
2287 
2288         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
2289         if (ret) {
2290             mpp_err_f("set register read failed %d\n", ret);
2291             break;
2292         }
2293 
2294         rd_cfg.reg = &regs->reg_st;
2295         rd_cfg.size = sizeof(regs->reg_st);
2296         rd_cfg.offset = VEPU580_STATUS_OFFSET;
2297 
2298         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
2299         if (ret) {
2300             mpp_err_f("set register read failed %d\n", ret);
2301             break;
2302         }
2303 
2304         /* send request to hardware */
2305         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
2306         if (ret) {
2307             mpp_err_f("send cmd failed %d\n", ret);
2308             break;
2309         }
2310     } while (0);
2311 
2312     hal_h264e_dbg_func("leave %p\n", hal);
2313 
2314     return ret;
2315 }
2316 
hal_h264e_vepu580_status_check(HalVepu580RegSet * regs)2317 static MPP_RET hal_h264e_vepu580_status_check(HalVepu580RegSet *regs)
2318 {
2319     MPP_RET ret = MPP_OK;
2320 
2321     if (regs->reg_ctl.int_sta.lkt_node_done_sta)
2322         hal_h264e_dbg_detail("lkt_done finish");
2323 
2324     if (regs->reg_ctl.int_sta.enc_done_sta)
2325         hal_h264e_dbg_detail("enc_done finish");
2326 
2327     if (regs->reg_ctl.int_sta.slc_done_sta)
2328         hal_h264e_dbg_detail("enc_slice finsh");
2329 
2330     if (regs->reg_ctl.int_sta.sclr_done_sta)
2331         hal_h264e_dbg_detail("safe clear finsh");
2332 
2333     if (regs->reg_ctl.int_sta.bsf_oflw_sta) {
2334         mpp_err_f("bit stream overflow");
2335         ret = MPP_NOK;
2336     }
2337 
2338     if (regs->reg_ctl.int_sta.brsp_otsd_sta) {
2339         mpp_err_f("bus write full");
2340         ret = MPP_NOK;
2341     }
2342 
2343     if (regs->reg_ctl.int_sta.wbus_err_sta) {
2344         mpp_err_f("bus write error");
2345         ret = MPP_NOK;
2346     }
2347 
2348     if (regs->reg_ctl.int_sta.rbus_err_sta) {
2349         mpp_err_f("bus read error");
2350         ret = MPP_NOK;
2351     }
2352 
2353     if (regs->reg_ctl.int_sta.wdg_sta) {
2354         ret = MPP_NOK;
2355         mpp_err_f("wdg timeout");
2356     }
2357 
2358     return ret;
2359 }
2360 
hal_h264e_vepu580_wait(void * hal,HalEncTask * task)2361 static MPP_RET hal_h264e_vepu580_wait(void *hal, HalEncTask *task)
2362 {
2363     MPP_RET ret = MPP_OK;
2364     HalH264eVepu580Ctx *ctx = (HalH264eVepu580Ctx *)hal;
2365     HalVepu580RegSet *regs = &ctx->regs_sets[task->flags.reg_idx];
2366     RK_U32 split_out = ctx->cfg->split.split_out;
2367     MppPacket pkt = task->packet;
2368     RK_S32 offset = mpp_packet_get_length(pkt);
2369     H264NaluType type = task->rc_task->frm.is_idr ?  H264_NALU_TYPE_IDR : H264_NALU_TYPE_SLICE;
2370     MppEncH264HwCfg *hw_cfg = &ctx->cfg->h264.hw_cfg;
2371     RK_S32 i;
2372 
2373     hal_h264e_dbg_func("enter %p\n", hal);
2374 
2375     /* if pass1 mode, it will disable split mode and the split out need to be disable */
2376     if (task->rc_task->frm.save_pass1)
2377         split_out = 0;
2378 
2379     /* update split_out in hw_cfg */
2380     hw_cfg->hw_split_out = split_out;
2381 
2382     if (split_out) {
2383         EncOutParam param;
2384         RK_U32 slice_len;
2385         RK_U32 slice_last;
2386         MppDevPollCfg *poll_cfg = (MppDevPollCfg *)((char *)ctx->poll_cfgs +
2387                                                     task->flags.reg_idx * ctx->poll_cfg_size);
2388         param.task = task;
2389         param.base = mpp_packet_get_data(task->packet);
2390 
2391         do {
2392             poll_cfg->poll_type = 0;
2393             poll_cfg->poll_ret  = 0;
2394             poll_cfg->count_max = split_out & MPP_ENC_SPLIT_OUT_LOWDELAY ? 1 : ctx->poll_slice_max;
2395             poll_cfg->count_ret = 0;
2396 
2397             ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, poll_cfg);
2398 
2399             for (i = 0; i < poll_cfg->count_ret; i++) {
2400                 slice_last = poll_cfg->slice_info[i].last;
2401                 slice_len = poll_cfg->slice_info[i].length;
2402 
2403                 mpp_packet_add_segment_info(pkt, type, offset, slice_len);
2404                 offset += slice_len;
2405 
2406                 if (split_out & MPP_ENC_SPLIT_OUT_LOWDELAY) {
2407                     param.length = slice_len;
2408 
2409                     if (slice_last)
2410                         ctx->output_cb->cmd = ENC_OUTPUT_FINISH;
2411                     else
2412                         ctx->output_cb->cmd = ENC_OUTPUT_SLICE;
2413 
2414                     mpp_callback(ctx->output_cb, &param);
2415                 }
2416             }
2417         } while (!slice_last);
2418 
2419         ret = hal_h264e_vepu580_status_check(regs);
2420         if (!ret)
2421             task->hw_length += regs->reg_st.bs_lgth_l32;
2422     } else {
2423         ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
2424         if (ret) {
2425             mpp_err_f("poll cmd failed %d\n", ret);
2426             ret = MPP_ERR_VPUHW;
2427         } else {
2428             ret = hal_h264e_vepu580_status_check(regs);
2429             if (!ret)
2430                 task->hw_length += regs->reg_st.bs_lgth_l32;
2431         }
2432 
2433         mpp_packet_add_segment_info(pkt, type, offset, regs->reg_st.bs_lgth_l32);
2434     }
2435 
2436     if (!(split_out & MPP_ENC_SPLIT_OUT_LOWDELAY) && !ret) {
2437         HalH264eVepuStreamAmend *amend = &ctx->amend_sets[task->flags.reg_idx];
2438 
2439         if (amend->enable) {
2440             amend->old_length = task->hw_length;
2441             amend->slice->is_multi_slice = (ctx->cfg->split.split_mode > 0);
2442             h264e_vepu_stream_amend_proc(amend, &ctx->cfg->h264.hw_cfg);
2443             task->hw_length = amend->new_length;
2444         } else if (amend->prefix) {
2445             /* check prefix value */
2446             amend->old_length = task->hw_length;
2447             h264e_vepu_stream_amend_sync_ref_idc(amend);
2448         }
2449     }
2450 
2451     hal_h264e_dbg_func("leave %p ret %d\n", hal, ret);
2452 
2453     return ret;
2454 }
2455 
hal_h264e_vepu580_ret_task(void * hal,HalEncTask * task)2456 static MPP_RET hal_h264e_vepu580_ret_task(void * hal, HalEncTask * task)
2457 {
2458     HalH264eVepu580Ctx *ctx = (HalH264eVepu580Ctx *)hal;
2459     HalVepu580RegSet *regs = &ctx->regs_sets[task->flags.reg_idx];
2460     EncRcTaskInfo *rc_info = &task->rc_task->info;
2461     RK_U32 mb_w = ctx->sps->pic_width_in_mbs;
2462     RK_U32 mb_h = ctx->sps->pic_height_in_mbs;
2463     RK_U32 mbs = mb_w * mb_h;
2464 
2465     hal_h264e_dbg_func("enter %p\n", hal);
2466 
2467     // update total hardware length
2468     task->length += task->hw_length;
2469 
2470     // setup bit length for rate control
2471     rc_info->bit_real = task->hw_length * 8;
2472     rc_info->quality_real = regs->reg_st.qp_sum / mbs;
2473     rc_info->madi = (!regs->reg_st.st_bnum_b16.num_b16) ? 0 :
2474                     regs->reg_st.madi /  regs->reg_st.st_bnum_b16.num_b16;
2475     rc_info->madp = (!regs->reg_st.st_bnum_cme.num_ctu) ? 0 :
2476                     regs->reg_st.madp / regs->reg_st.st_bnum_cme.num_ctu;
2477     rc_info->iblk4_prop = (regs->reg_st.st_pnum_i4.pnum_i4 +
2478                            regs->reg_st.st_pnum_i8.pnum_i8 +
2479                            regs->reg_st.st_pnum_i16.pnum_i16) * 256 / mbs;
2480 
2481     rc_info->sse = ((RK_S64)regs->reg_st.sse_h32 << 16) + (regs->reg_st.st_sse_bsl.sse_l16 & 0xffff);
2482     rc_info->lvl16_inter_num = regs->reg_st.st_pnum_p16.pnum_p16;
2483     rc_info->lvl8_inter_num  = regs->reg_st.st_pnum_p8.pnum_p8;
2484     rc_info->lvl16_intra_num = regs->reg_st.st_pnum_i16.pnum_i16;
2485     rc_info->lvl8_intra_num  = regs->reg_st.st_pnum_i8.pnum_i8;
2486     rc_info->lvl4_intra_num  = regs->reg_st.st_pnum_i4.pnum_i4;
2487 
2488     ctx->hal_rc_cfg.bit_real = rc_info->bit_real;
2489     ctx->hal_rc_cfg.quality_real = rc_info->quality_real;
2490     ctx->hal_rc_cfg.iblk4_prop = rc_info->iblk4_prop;
2491 
2492     task->hal_ret.data   = &ctx->hal_rc_cfg;
2493     task->hal_ret.number = 1;
2494 
2495     //RK_U32 madi_th_cnt0 = ctx->regs_set->reg_st.madi_b16num0;
2496     RK_U32 madi_th_cnt1 = ctx->regs_set->reg_st.madi_b16num1;
2497     RK_U32 madi_th_cnt2 = ctx->regs_set->reg_st.madi_b16num2;
2498     RK_U32 madi_th_cnt3 = ctx->regs_set->reg_st.madi_b16num3;
2499     //RK_U32 madp_th_cnt0 = ctx->regs_set->reg_st.md_sad_b16num0;
2500     RK_U32 madp_th_cnt1 = ctx->regs_set->reg_st.md_sad_b16num1;
2501     RK_U32 madp_th_cnt2 = ctx->regs_set->reg_st.md_sad_b16num2;
2502     RK_U32 madp_th_cnt3 = ctx->regs_set->reg_st.md_sad_b16num3;
2503 
2504     RK_U32 md_cnt = (24 * madp_th_cnt3 + 22 * madp_th_cnt2 + 17 * madp_th_cnt1) >> 2;
2505     RK_U32 madi_cnt = (6 * madi_th_cnt3 + 5 * madi_th_cnt2 + 4 * madi_th_cnt1) >> 2;
2506 
2507     rc_info->motion_level = 0;
2508     if (md_cnt * 100 > 15 * mbs)
2509         rc_info->motion_level = 200;
2510     else if (md_cnt * 100 > 5 * mbs)
2511         rc_info->motion_level = 100;
2512     else
2513         rc_info->motion_level = 0;
2514 
2515     rc_info->complex_level = 0;
2516     if (madi_cnt * 100 > 30 * mbs)
2517         rc_info->complex_level = 2;
2518     else if (madi_cnt * 100 > 13 * mbs)
2519         rc_info->complex_level = 1;
2520     else
2521         rc_info->complex_level = 0;
2522 
2523     hal_h264e_dbg_rc("motion_level %u, complex_level %u\n", rc_info->motion_level, rc_info->complex_level);
2524 
2525     vepu580_h264e_tune_stat_update(ctx->tune, task);
2526 
2527     mpp_dev_multi_offset_reset(ctx->offsets);
2528 
2529     if (ctx->dpb) {
2530         h264e_dpb_hal_end(ctx->dpb, task->flags.curr_idx);
2531         h264e_dpb_hal_end(ctx->dpb, task->flags.refr_idx);
2532     }
2533 
2534     hal_h264e_dbg_func("leave %p\n", hal);
2535 
2536     return MPP_OK;
2537 }
2538 
2539 const MppEncHalApi hal_h264e_vepu580 = {
2540     .name       = "hal_h264e_vepu580",
2541     .coding     = MPP_VIDEO_CodingAVC,
2542     .ctx_size   = sizeof(HalH264eVepu580Ctx),
2543     .flag       = 0,
2544     .init       = hal_h264e_vepu580_init,
2545     .deinit     = hal_h264e_vepu580_deinit,
2546     .prepare    = hal_h264e_vepu580_prepare,
2547     .get_task   = hal_h264e_vepu580_get_task,
2548     .gen_regs   = hal_h264e_vepu580_gen_regs,
2549     .start      = hal_h264e_vepu580_start,
2550     .wait       = hal_h264e_vepu580_wait,
2551     .part_start = NULL,
2552     .part_wait  = NULL,
2553     .ret_task   = hal_h264e_vepu580_ret_task,
2554 };
2555