xref: /rockchip-linux_mpp/mpp/hal/rkenc/jpege/hal_jpege_vepu511.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /* SPDX-License-Identifier: Apache-2.0 */
2 /*
3  * Copyright (c) 2025 Rockchip Electronics Co., Ltd.
4  */
5 
6 #define MODULE_TAG  "hal_jpege_v511"
7 
8 #include <linux/string.h>
9 
10 #include <string.h>
11 #include <math.h>
12 #include <limits.h>
13 
14 #include "mpp_env.h"
15 #include "mpp_mem.h"
16 #include "mpp_soc.h"
17 #include "mpp_common.h"
18 #include "mpp_frame_impl.h"
19 
20 #include "hal_jpege_debug.h"
21 #include "jpege_syntax.h"
22 #include "hal_bufs.h"
23 #include "rkv_enc_def.h"
24 #include "vepu5xx_common.h"
25 #include "vepu511_common.h"
26 #include "hal_jpege_vepu511.h"
27 #include "hal_jpege_vepu511_reg.h"
28 #include "hal_jpege_hdr.h"
29 
30 typedef struct JpegeV511HalContext_t {
31     MppEncHalApi        api;
32     MppDev              dev;
33     void                *regs;
34     void                *reg_out;
35 
36     void                *dump_files;
37 
38     RK_S32              frame_type;
39     RK_S32              last_frame_type;
40 
41     /* @frame_cnt starts from ZERO */
42     RK_U32              frame_cnt;
43     void                *roi_data;
44     MppEncCfgSet        *cfg;
45     Vepu511OsdCfg       osd_cfg;
46 
47     RK_U32              enc_mode;
48     RK_U32              frame_size;
49     RK_S32              max_buf_cnt;
50     RK_S32              hdr_status;
51     void                *input_fmt;
52     RK_U8               *src_buf;
53     RK_U8               *dst_buf;
54     RK_S32              buf_size;
55     RK_U32              frame_num;
56     RK_S32              fbc_header_len;
57     RK_U32              title_num;
58 
59     JpegeBits           bits;
60     JpegeSyntax         syntax;
61     HalJpegeRc          hal_rc;
62 } JpegeV511HalContext;
63 
hal_jpege_vepu511_init(void * hal,MppEncHalCfg * cfg)64 MPP_RET hal_jpege_vepu511_init(void *hal, MppEncHalCfg *cfg)
65 {
66     MPP_RET ret = MPP_OK;
67     JpegeV511HalContext *ctx = (JpegeV511HalContext *)hal;
68 
69     mpp_env_get_u32("hal_jpege_debug", &hal_jpege_debug, 0);
70     hal_jpege_enter();
71 
72     ctx->reg_out  = mpp_calloc(JpegV511Status, 1);
73     ctx->regs           = mpp_calloc(JpegV511RegSet, 1);
74     ctx->input_fmt      = mpp_calloc(VepuFmtCfg, 1);
75     ctx->cfg            = cfg->cfg;
76     ctx->frame_cnt = 0;
77     ctx->enc_mode = 1;
78     cfg->type = VPU_CLIENT_RKVENC;
79     ret = mpp_dev_init(&cfg->dev, cfg->type);
80     if (ret) {
81         mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
82         return ret;
83     }
84 
85     ctx->dev = cfg->dev;
86     jpege_bits_init(&ctx->bits);
87     mpp_assert(ctx->bits);
88     hal_jpege_rc_init(&ctx->hal_rc);
89 
90     hal_jpege_leave();
91     return ret;
92 }
93 
hal_jpege_vepu511_deinit(void * hal)94 MPP_RET hal_jpege_vepu511_deinit(void *hal)
95 {
96     JpegeV511HalContext *ctx = (JpegeV511HalContext *)hal;
97 
98     hal_jpege_enter();
99     jpege_bits_deinit(ctx->bits);
100 
101     MPP_FREE(ctx->regs);
102     MPP_FREE(ctx->reg_out);
103     MPP_FREE(ctx->input_fmt);
104 
105     if (ctx->dev) {
106         mpp_dev_deinit(ctx->dev);
107         ctx->dev = NULL;
108     }
109     hal_jpege_leave();
110     return MPP_OK;
111 }
112 
hal_jpege_vepu511_prepare(void * hal)113 static MPP_RET hal_jpege_vepu511_prepare(void *hal)
114 {
115     JpegeV511HalContext *ctx = (JpegeV511HalContext *)hal;
116 
117     hal_jpege_dbg_func("enter %p\n", hal);
118     VepuFmtCfg *fmt = (VepuFmtCfg *)ctx->input_fmt;
119     vepu5xx_set_fmt(fmt, ctx->cfg->prep.format);
120 
121     hal_jpege_dbg_func("leave %p\n", hal);
122 
123     return MPP_OK;
124 }
125 
vepu511_jpeg_set_patch_info(MppDev dev,JpegeSyntax * syn,VepuFmt input_fmt,HalEncTask * task)126 static MPP_RET vepu511_jpeg_set_patch_info(MppDev dev, JpegeSyntax *syn,
127                                            VepuFmt input_fmt,
128                                            HalEncTask *task)
129 {
130     RK_U32 hor_stride = syn->hor_stride;
131     RK_U32 ver_stride = syn->ver_stride ? syn->ver_stride : syn->height;
132     RK_U32 frame_size = hor_stride * ver_stride;
133     RK_U32 u_offset = 0, v_offset = 0;
134     MPP_RET ret = MPP_OK;
135 
136     if (MPP_FRAME_FMT_IS_FBC(mpp_frame_get_fmt(task->frame))) {
137         u_offset = mpp_frame_get_fbc_offset(task->frame);
138         v_offset = u_offset;
139     } else {
140         switch (input_fmt) {
141         case VEPU5xx_FMT_YUV420P: {
142             u_offset = frame_size;
143             v_offset = frame_size * 5 / 4;
144         } break;
145         case VEPU5xx_FMT_YUV420SP:
146         case VEPU5xx_FMT_YUV422SP: {
147             u_offset = frame_size;
148             v_offset = frame_size;
149         } break;
150         case VEPU5xx_FMT_YUV422P: {
151             u_offset = frame_size;
152             v_offset = frame_size * 3 / 2;
153         } break;
154         case VEPU5xx_FMT_YUV400 :
155         case VEPU5xx_FMT_YUYV422:
156         case VEPU5xx_FMT_UYVY422: {
157             u_offset = 0;
158             v_offset = 0;
159         } break;
160         case VEPU5xx_FMT_YUV444SP : {
161             u_offset = frame_size;
162             v_offset = frame_size;
163         } break;
164         case VEPU5xx_FMT_YUV444P : {
165             u_offset = frame_size;
166             v_offset = frame_size * 2;
167         } break;
168         case VEPU5xx_FMT_BGR565:
169         case VEPU5xx_FMT_BGR888:
170         case VEPU5xx_FMT_BGRA8888: {
171             u_offset = 0;
172             v_offset = 0;
173         } break;
174         default: {
175             mpp_err("unknown color space: %d\n", input_fmt);
176             u_offset = frame_size;
177             v_offset = frame_size * 5 / 4;
178         }
179         }
180     }
181 
182     /* input cb addr */
183     if (u_offset)
184         mpp_dev_set_reg_offset(dev, 265, u_offset);
185 
186     /* input cr addr */
187     if (v_offset)
188         mpp_dev_set_reg_offset(dev, 266, v_offset);
189 
190     return ret;
191 }
192 
vepu511_set_jpeg_reg(Vepu511JpegCfg * cfg)193 MPP_RET vepu511_set_jpeg_reg(Vepu511JpegCfg *cfg)
194 {
195     HalEncTask *task = ( HalEncTask *)cfg->enc_task;
196     JpegeSyntax *syn = (JpegeSyntax *)task->syntax.data;
197     Vepu511JpegReg *regs = (Vepu511JpegReg *)cfg->jpeg_reg_base;
198     VepuFmtCfg *fmt = (VepuFmtCfg *)cfg->input_fmt;
199     RK_U32 pic_width_align8, pic_height_align8;
200     RK_S32 stridey = 0;
201     RK_S32 stridec = 0;
202 
203     pic_width_align8 = (syn->width + 7) & (~7);
204     pic_height_align8 = (syn->height + 7) & (~7);
205 
206     regs->adr_src0 =  mpp_buffer_get_fd(task->input);
207     regs->adr_src1 = regs->adr_src0;
208     regs->adr_src2 = regs->adr_src0;
209 
210     vepu511_jpeg_set_patch_info(cfg->dev, syn, (VepuFmt)fmt->format, task);
211 
212     regs->adr_bsbt = mpp_buffer_get_fd(task->output);
213     regs->adr_bsbb = regs->adr_bsbt;
214     regs->adr_bsbs = regs->adr_bsbt;
215     regs->adr_bsbr = regs->adr_bsbt;
216 
217     mpp_dev_set_reg_offset(cfg->dev, 258, mpp_packet_get_length(task->packet));
218     mpp_dev_set_reg_offset(cfg->dev, 256, mpp_buffer_get_size(task->output));
219 
220     regs->enc_rsl.pic_wd8_m1    = pic_width_align8 / 8 - 1;
221     regs->src_fill.pic_wfill    = (syn->width & 0x7)
222                                   ? (8 - (syn->width & 0x7)) : 0;
223     regs->enc_rsl.pic_hd8_m1    = pic_height_align8 / 8 - 1;
224     regs->src_fill.pic_hfill    = (syn->height & 0x7)
225                                   ? (8 - (syn->height & 0x7)) : 0;
226 
227     regs->src_fmt.src_cfmt = fmt->format;
228     regs->src_fmt.alpha_swap = fmt->alpha_swap;
229     regs->src_fmt.rbuv_swap  = fmt->rbuv_swap;
230     regs->src_fmt.src_range_trns_en  = 0;
231     regs->src_fmt.src_range_trns_sel = 0;
232     regs->src_fmt.chroma_ds_mode     = 0;
233     regs->src_proc.src_mirr = syn->mirroring > 0;
234     regs->src_proc.src_rot = syn->rotation;
235 
236     if (MPP_FRAME_FMT_IS_FBC(mpp_frame_get_fmt(task->frame))) {
237         regs->src_proc.rkfbcd_en = 1;
238 
239         stridey = mpp_frame_get_fbc_hdr_stride(task->frame);
240         if (!stridey)
241             stridey = MPP_ALIGN(syn->hor_stride, 16) >> 2;
242     } else if (syn->hor_stride) {
243         stridey = syn->hor_stride;
244     } else {
245         if (regs->src_fmt.src_cfmt == VEPU5xx_FMT_BGRA8888)
246             stridey = syn->width * 4;
247         else if (regs->src_fmt.src_cfmt == VEPU5xx_FMT_BGR888 ||
248                  regs->src_fmt.src_cfmt == VEPU5xx_FMT_YUV444P ||
249                  regs->src_fmt.src_cfmt == VEPU5xx_FMT_YUV444SP)
250             stridey = syn->width * 3;
251         else if (regs->src_fmt.src_cfmt == VEPU5xx_FMT_BGR565 ||
252                  regs->src_fmt.src_cfmt == VEPU5xx_FMT_YUYV422 ||
253                  regs->src_fmt.src_cfmt == VEPU5xx_FMT_UYVY422)
254             stridey = syn->width * 2;
255     }
256 
257     stridec = (regs->src_fmt.src_cfmt == VEPU5xx_FMT_YUV422SP ||
258                regs->src_fmt.src_cfmt == VEPU5xx_FMT_YUV420SP ||
259                regs->src_fmt.src_cfmt == VEPU5xx_FMT_YUV444P) ?
260               stridey : stridey / 2;
261 
262     if (regs->src_fmt.src_cfmt == VEPU5xx_FMT_YUV444SP)
263         stridec = stridey * 2;
264 
265     if (regs->src_fmt.src_cfmt < VEPU5xx_FMT_ARGB1555) {
266         regs->src_udfy.csc_wgt_r2y = 66;
267         regs->src_udfy.csc_wgt_g2y = 129;
268         regs->src_udfy.csc_wgt_b2y = 25;
269 
270         regs->src_udfu.csc_wgt_r2u = -38;
271         regs->src_udfu.csc_wgt_g2u = -74;
272         regs->src_udfu.csc_wgt_b2u = 112;
273 
274         regs->src_udfv.csc_wgt_r2v = 112;
275         regs->src_udfv.csc_wgt_g2v = -94;
276         regs->src_udfv.csc_wgt_b2v = -18;
277 
278         regs->src_udfo.csc_ofst_y = 16;
279         regs->src_udfo.csc_ofst_u = 128;
280         regs->src_udfo.csc_ofst_v = 128;
281     }
282 
283     regs->src_strd0.src_strd0  = stridey;
284     regs->src_strd1.src_strd1  = stridec;
285     regs->pic_ofst.pic_ofst_y = mpp_frame_get_offset_y(task->frame);
286     regs->pic_ofst.pic_ofst_x = mpp_frame_get_offset_x(task->frame);
287 
288     regs->y_cfg.bias_y = 0;
289     regs->u_cfg.bias_u = 0;
290     regs->v_cfg.bias_v = 0;
291 
292     regs->base_cfg.ri  = syn->restart_ri;
293     regs->base_cfg.out_mode = 0;
294     regs->base_cfg.start_rst_m = 0;
295     regs->base_cfg.pic_last_ecs = 1;
296     regs->base_cfg.stnd = 1;
297 
298     regs->uvc_cfg.uvc_partition0_len = 0;
299     regs->uvc_cfg.uvc_partition_len = 0;
300     regs->uvc_cfg.uvc_skip_len = 0;
301     return MPP_OK;
302 }
303 
hal_jpege_vepu511_set_roi(JpegeV511HalContext * ctx)304 static void hal_jpege_vepu511_set_roi(JpegeV511HalContext *ctx)
305 {
306     MppJpegROICfg *roi_cfg = (MppJpegROICfg *)ctx->roi_data;
307     JpegV511RegSet *regs = ctx->regs;
308     Vepu511JpegRoiRegion *reg_regions = &regs->reg_base.jpegReg.roi_regions[0];
309     MppJpegROIRegion *region;
310     RK_U32 frame_width = ctx->cfg->prep.width;
311     RK_U32 frame_height = ctx->cfg->prep.height;
312     RK_S32 i;
313 
314     if (roi_cfg == NULL)
315         return;
316 
317     if (roi_cfg->non_roi_en) {
318         if (roi_cfg->non_roi_level <= MPP_MAX_JPEG_ROI_LEVEL) {
319             reg_regions->roi_cfg1.frm_rdoq_en = 1;
320             reg_regions->roi_cfg1.frm_rdoq_level = roi_cfg->non_roi_level;
321         } else {
322             mpp_err_f("none roi level[%d] is invalid\n", roi_cfg->non_roi_level);
323         }
324     }
325 
326     for (i = 0; i < MPP_MAX_JPEG_ROI_NUM; i++) {
327         region = &roi_cfg->regions[i];
328         if (!region->roi_en)
329             continue;
330 
331         if (region->w == 0 || region->h == 0 ||
332             region->x + region->w > frame_width ||
333             region->y + region->h > frame_height) {
334             mpp_err_f("region[%d]: x[%d] y[%d] w[%d] h[%d] is invalid, frame width[%d] height[%d]\n",
335                       i, region->x, region->y, region->w,
336                       region->h, frame_width, frame_height);
337             continue;
338         }
339 
340         if (region->level > MPP_MAX_JPEG_ROI_LEVEL) {
341             mpp_err_f("region[%d]: roi level[%d] is invalid\n", i, region->level);
342             continue;
343         }
344 
345         reg_regions->roi_cfg0.roi0_rdoq_en = 1;
346         reg_regions->roi_cfg0.roi0_rdoq_start_x = MPP_ALIGN(region->x, 16) >> 3;
347         reg_regions->roi_cfg0.roi0_rdoq_start_y = MPP_ALIGN(region->y, 16) >> 3;
348         reg_regions->roi_cfg0.roi0_rdoq_level = region->level;
349         reg_regions->roi_cfg1.roi0_rdoq_width_m1 = (MPP_ALIGN(region->w, 16) >> 3) - 1;
350         reg_regions->roi_cfg1.roi0_rdoq_height_m1 = (MPP_ALIGN(region->h, 16) >> 3) - 1;
351         reg_regions++;
352     }
353 }
354 
hal_jpege_vepu511_gen_regs(void * hal,HalEncTask * task)355 MPP_RET hal_jpege_vepu511_gen_regs(void *hal, HalEncTask *task)
356 {
357     JpegeV511HalContext *ctx = (JpegeV511HalContext *)hal;
358     JpegV511RegSet *regs = ctx->regs;
359     Vepu511ControlCfg *reg_ctl = &regs->reg_ctl;
360     JpegVepu511Base *reg_base = &regs->reg_base;
361     JpegeBits bits = ctx->bits;
362     size_t length = mpp_packet_get_length(task->packet);
363     RK_U8  *buf = mpp_buffer_get_ptr(task->output);
364     size_t size = mpp_buffer_get_size(task->output);
365     JpegeSyntax *syntax = &ctx->syntax;
366     VepuFmtCfg *fmt = (VepuFmtCfg *)ctx->input_fmt;
367     Vepu511JpegCfg cfg;
368     RK_S32 bitpos;
369 
370     hal_jpege_enter();
371     cfg.enc_task = task;
372     cfg.jpeg_reg_base = &reg_base->jpegReg;
373     cfg.dev = ctx->dev;
374     cfg.input_fmt = ctx->input_fmt;
375 
376     memset(regs, 0, sizeof(JpegV511RegSet));
377 
378     if (syntax->q_mode == JPEG_QFACTOR) {
379         syntax->q_factor = 100 - task->rc_task->info.quality_target;
380         hal_jpege_rc_update(&ctx->hal_rc, syntax);
381     }
382 
383     /* write header to output buffer */
384     jpege_bits_setup(bits, buf, (RK_U32)size);
385     /* seek length bytes data */
386     jpege_seek_bits(bits, length << 3);
387     /* NOTE: write header will update qtable */
388     write_jpeg_header(bits, syntax, &ctx->hal_rc);
389 
390     bitpos = jpege_bits_get_bitpos(bits);
391     task->length = (bitpos + 7) >> 3;
392     mpp_buffer_sync_partial_end(task->output, 0, task->length);
393     mpp_packet_set_length(task->packet, task->length);
394     reg_ctl->enc_strt.lkt_num      = 0;
395     reg_ctl->enc_strt.vepu_cmd     = ctx->enc_mode;
396     reg_ctl->enc_clr.safe_clr      = 0x0;
397     reg_ctl->enc_clr.force_clr     = 0x0;
398 
399     reg_ctl->int_en.enc_done_en         = 1;
400     reg_ctl->int_en.lkt_node_done_en    = 1;
401     reg_ctl->int_en.sclr_done_en        = 1;
402     reg_ctl->int_en.vslc_done_en         = 1;
403     reg_ctl->int_en.vbsf_oflw_en         = 1;
404 
405     reg_ctl->int_en.jbuf_lens_en        = 1;
406     reg_ctl->int_en.enc_err_en          = 1;
407     reg_ctl->int_en.vsrc_err_en         = 1;
408     reg_ctl->int_en.wdg_en              = 1;
409     reg_ctl->int_en.lkt_err_int_en      = 0;
410     reg_ctl->int_en.lkt_err_stop_en     = 0;
411     reg_ctl->int_en.lkt_force_stop_en   = 0;
412     reg_ctl->int_en.jslc_done_en        = 0;
413     reg_ctl->int_en.jbsf_oflw_en        = 0;
414     reg_ctl->int_en.dvbm_err_en         = 0;
415 
416     reg_ctl->dtrns_map.jpeg_bus_edin    = 0x7;
417     reg_ctl->dtrns_map.src_bus_edin     = 0x0;
418     reg_ctl->dtrns_map.meiw_bus_edin    = 0x0;
419     reg_ctl->dtrns_map.bsw_bus_edin     = 0x0;
420     reg_ctl->dtrns_map.lktr_bus_edin    = 0x0;
421     reg_ctl->dtrns_map.roir_bus_edin    = 0x0;
422     reg_ctl->dtrns_map.lktw_bus_edin    = 0x0;
423     reg_ctl->dtrns_map.rec_nfbc_bus_edin   = 0x0;
424     reg_ctl->dtrns_cfg.jsrc_bus_edin = fmt->src_endian;
425     reg_base->common.enc_pic.enc_stnd = 2; // disable h264 or hevc
426 
427     reg_ctl->dtrns_cfg.axi_brsp_cke     = 0x0;
428     reg_ctl->enc_wdg.vs_load_thd        = 0x1fffff;
429     reg_base->common.enc_pic.jpeg_slen_fifo = 0;
430 
431     vepu511_set_jpeg_reg(&cfg);
432     hal_jpege_vepu511_set_roi(ctx);
433 
434     if (ctx->osd_cfg.osd_data3 || ctx->osd_cfg.osd_data)
435         vepu511_set_osd(&ctx->osd_cfg, &regs->reg_osd.osd_jpeg_cfg);
436 
437     {
438         RK_U16 *tbl = &regs->jpeg_table.qua_tab0[0];
439         RK_U32 i, j;
440 
441         for ( i = 0; i < 8; i++) {
442             for ( j = 0; j < 8; j++) {
443                 tbl[i * 8 + j] = 0x8000 / ctx->hal_rc.qtables[0][j * 8 + i];
444             }
445         }
446         tbl += 64;
447         for ( i = 0; i < 8; i++) {
448             for ( j = 0; j < 8; j++) {
449                 tbl[i * 8 + j] = 0x8000 / ctx->hal_rc.qtables[1][j * 8 + i];
450             }
451         }
452         tbl += 64;
453         for ( i = 0; i < 8; i++) {
454             for ( j = 0; j < 8; j++) {
455                 tbl[i * 8 + j] = 0x8000 / ctx->hal_rc.qtables[1][j * 8 + i];
456             }
457         }
458     }
459     ctx->frame_num++;
460 
461     hal_jpege_leave();
462     return MPP_OK;
463 }
464 
hal_jpege_vepu511_start(void * hal,HalEncTask * enc_task)465 MPP_RET hal_jpege_vepu511_start(void *hal, HalEncTask *enc_task)
466 {
467     MPP_RET ret = MPP_OK;
468     JpegeV511HalContext *ctx = (JpegeV511HalContext *)hal;
469     JpegV511RegSet *hw_regs = ctx->regs;
470     JpegV511Status *reg_out = ctx->reg_out;
471     MppDevRegWrCfg cfg;
472     MppDevRegRdCfg cfg1;
473     hal_jpege_enter();
474 
475     if (enc_task->flags.err) {
476         mpp_err_f("enc_task->flags.err %08x, return e arly",
477                   enc_task->flags.err);
478         return MPP_NOK;
479     }
480 
481     cfg.reg = (RK_U32*)&hw_regs->reg_ctl;
482     cfg.size = sizeof(Vepu511ControlCfg);
483     cfg.offset = VEPU511_CTL_OFFSET;
484 
485     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &cfg);
486     if (ret) {
487         mpp_err_f("set register write failed %d\n", ret);
488         return ret;
489     }
490 
491     cfg.reg = &hw_regs->jpeg_table;
492     cfg.size = sizeof(JpegVepu511Tab);
493     cfg.offset = VEPU511_JPEGTAB_OFFSET;
494 
495     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &cfg);
496     if (ret) {
497         mpp_err_f("set register write failed %d\n", ret);
498         return ret;
499     }
500 
501     cfg.reg = &hw_regs->reg_base;
502     cfg.size = sizeof(JpegVepu511Base);
503     cfg.offset = VEPU511_FRAME_OFFSET;
504 
505     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &cfg);
506     if (ret) {
507         mpp_err_f("set register write failed %d\n", ret);
508         return ret;
509     }
510 
511     cfg.reg = &hw_regs->reg_osd;
512     cfg.size = sizeof(Vepu511OsdRegs);
513     cfg.offset = VEPU511_OSD_OFFSET;
514 
515     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &cfg);
516     if (ret) {
517         mpp_err_f("set register write failed %d\n", ret);
518         return ret;
519     }
520 
521     cfg1.reg = &reg_out->hw_status;
522     cfg1.size = sizeof(RK_U32);
523     cfg1.offset = VEPU511_REG_BASE_HW_STATUS;
524 
525     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &cfg1);
526     if (ret) {
527         mpp_err_f("set register read failed %d\n", ret);
528         return ret;
529     }
530 
531     cfg1.reg = &reg_out->st;
532     cfg1.size = sizeof(JpegV511Status) - 4;
533     cfg1.offset = VEPU511_STATUS_OFFSET;
534 
535     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &cfg1);
536     if (ret) {
537         mpp_err_f("set register read failed %d\n", ret);
538         return ret;
539     }
540 
541     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
542     if (ret) {
543         mpp_err_f("send cmd failed %d\n", ret);
544     }
545     hal_jpege_leave();
546     return ret;
547 }
548 
hal_jpege_vepu511_status_check(void * hal)549 static MPP_RET hal_jpege_vepu511_status_check(void *hal)
550 {
551     JpegeV511HalContext *ctx = (JpegeV511HalContext *)hal;
552     JpegV511Status *elem = (JpegV511Status *)ctx->reg_out;
553 
554     RK_U32 hw_status = elem->hw_status;
555 
556     if (hw_status & RKV_ENC_INT_LINKTABLE_FINISH)
557         mpp_err_f("RKV_ENC_INT_LINKTABLE_FINISH");
558 
559     if (hw_status & RKV_ENC_INT_ONE_SLICE_FINISH)
560         mpp_err_f("RKV_ENC_INT_ONE_SLICE_FINISH");
561 
562     if (hw_status & RKV_ENC_INT_SAFE_CLEAR_FINISH)
563         mpp_err_f("RKV_ENC_INT_SAFE_CLEAR_FINISH");
564 
565     if (hw_status & RKV_ENC_INT_BIT_STREAM_OVERFLOW)
566         mpp_err_f("RKV_ENC_INT_BIT_STREAM_OVERFLOW");
567 
568     if (hw_status & RKV_ENC_INT_BUS_WRITE_FULL)
569         mpp_err_f("RKV_ENC_INT_BUS_WRITE_FULL");
570 
571     if (hw_status & RKV_ENC_INT_BUS_WRITE_ERROR)
572         mpp_err_f("RKV_ENC_INT_BUS_WRITE_ERROR");
573 
574     if (hw_status & RKV_ENC_INT_BUS_READ_ERROR)
575         mpp_err_f("RKV_ENC_INT_BUS_READ_ERROR");
576 
577     if (hw_status & RKV_ENC_INT_TIMEOUT_ERROR)
578         mpp_err_f("RKV_ENC_INT_TIMEOUT_ERROR");
579 
580     return MPP_OK;
581 }
582 
hal_jpege_vepu511_wait(void * hal,HalEncTask * task)583 MPP_RET hal_jpege_vepu511_wait(void *hal, HalEncTask *task)
584 {
585     MPP_RET ret = MPP_OK;
586     JpegeV511HalContext *ctx = (JpegeV511HalContext *)hal;
587     HalEncTask *enc_task = task;
588     JpegV511Status *elem = (JpegV511Status *)ctx->reg_out;
589     hal_jpege_enter();
590 
591     if (enc_task->flags.err) {
592         mpp_err_f("enc_task->flags.err %08x, return early",
593                   enc_task->flags.err);
594         return MPP_NOK;
595     }
596 
597     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
598     if (ret) {
599         mpp_err_f("poll cmd failed %d\n", ret);
600         ret = MPP_ERR_VPUHW;
601     } else {
602         hal_jpege_vepu511_status_check(hal);
603         task->hw_length += elem->st.jpeg_head_bits_l32;
604     }
605 
606     hal_jpege_leave();
607     return ret;
608 }
609 
hal_jpege_vepu511_get_task(void * hal,HalEncTask * task)610 MPP_RET hal_jpege_vepu511_get_task(void *hal, HalEncTask *task)
611 {
612     JpegeV511HalContext *ctx = (JpegeV511HalContext *)hal;
613     MppFrame frame = task->frame;
614     EncFrmStatus  *frm_status = &task->rc_task->frm;
615     JpegeSyntax *syntax = (JpegeSyntax *)task->syntax.data;
616 
617     hal_jpege_enter();
618 
619     memcpy(&ctx->syntax, syntax, sizeof(ctx->syntax));
620     ctx->last_frame_type = ctx->frame_type;
621 
622     if (!frm_status->reencode && mpp_frame_has_meta(task->frame)) {
623         MppMeta meta = mpp_frame_get_meta(frame);
624 
625         mpp_meta_get_ptr(meta, KEY_JPEG_ROI_DATA, (void **)&ctx->roi_data);
626         mpp_meta_get_ptr(meta, KEY_OSD_DATA3, (void **)&ctx->osd_cfg.osd_data3);
627 
628     }
629 
630     if (ctx->cfg->jpeg.update) {
631         hal_jpege_rc_update(&ctx->hal_rc, syntax);
632         ctx->cfg->jpeg.update = 0;
633     }
634 
635     task->rc_task->frm.is_intra = 1;
636 
637     hal_jpege_leave();
638     return MPP_OK;
639 }
640 
hal_jpege_vepu511_ret_task(void * hal,HalEncTask * task)641 MPP_RET hal_jpege_vepu511_ret_task(void *hal, HalEncTask *task)
642 {
643     (void)hal;
644     EncRcTaskInfo *rc_info = &task->rc_task->info;
645     hal_jpege_enter();
646 
647     task->length += task->hw_length;
648 
649     // setup bit length for rate control
650     rc_info->bit_real = task->hw_length * 8;
651     rc_info->quality_real = rc_info->quality_target;
652 
653     hal_jpege_leave();
654     return MPP_OK;
655 }
656 
657 const MppEncHalApi hal_jpege_vepu511 = {
658     .name       = "hal_jpege_v511",
659     .coding     = MPP_VIDEO_CodingMJPEG,
660     .ctx_size   = sizeof(JpegeV511HalContext),
661     .flag       = 0,
662     .init       = hal_jpege_vepu511_init,
663     .deinit     = hal_jpege_vepu511_deinit,
664     .prepare    = hal_jpege_vepu511_prepare,
665     .get_task   = hal_jpege_vepu511_get_task,
666     .gen_regs   = hal_jpege_vepu511_gen_regs,
667     .start      = hal_jpege_vepu511_start,
668     .wait       = hal_jpege_vepu511_wait,
669     .part_start = NULL,
670     .part_wait  = NULL,
671     .ret_task   = hal_jpege_vepu511_ret_task,
672 };
673