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 = ®s->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 = ®s->reg_ctl;
360 JpegVepu511Base *reg_base = ®s->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 = ®_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, ®s->reg_osd.osd_jpeg_cfg);
436
437 {
438 RK_U16 *tbl = ®s->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 = ®_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 = ®_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