1 /* SPDX-License-Identifier: Apache-2.0 */
2 /*
3 * Copyright (c) 2024 Rockchip Electronics Co., Ltd.
4 */
5
6 #define MODULE_TAG "hal_jpege_vpu720"
7
8 #include <string.h>
9
10 #include "mpp_mem.h"
11 #include "mpp_env.h"
12 #include "mpp_common.h"
13 #include "mpp_buffer_impl.h"
14 #include "mpp_enc_hal.h"
15
16 #include "jpege_syntax.h"
17 #include "hal_jpege_hdr.h"
18 #include "hal_jpege_debug.h"
19 #include "hal_jpege_vpu720.h"
20 #include "hal_jpege_vpu720_reg.h"
21
22 typedef enum JpegeVpu720InFmt_e {
23 JPEGE_VPU720_IN_FMT_TILE_400,
24 JPEGE_VPU720_IN_FMT_TILE_420,
25 JPEGE_VPU720_IN_FMT_TILE_422,
26 JPEGE_VPU720_IN_FMT_TILE_444,
27 JPEGE_VPU720_IN_FMT_YUV422SP,
28 JPEGE_VPU720_IN_FMT_YUV422P,
29 JPEGE_VPU720_IN_FMT_YUV420SP,
30 JPEGE_VPU720_IN_FMT_YUV420P,
31 JPEGE_VPU720_IN_FMT_YUYV,
32 JPEGE_VPU720_IN_FMT_UYVY,
33 JPEGE_VPU720_IN_FMT_YUV400,
34 JPEGE_VPU720_IN_FMT_RESERVED,
35 JPEGE_VPU720_IN_FMT_YUV444SP,
36 JPEGE_VPU720_IN_FMT_YUV444P,
37 } JpegeVpu720InFmt;
38
39 typedef enum JpegeVpu720OutFmt_e {
40 JPEGE_VPU720_OUT_FMT_400 = 0,
41 JPEGE_VPU720_OUT_FMT_420 = 1,
42 JPEGE_VPU720_OUT_FMT_422 = 2,
43 JPEGE_VPU720_OUT_FMT_444 = 3,
44 } JpegeVpu720OutFmt;
45
46 typedef enum JpegeVpu720EncCmd_e {
47 JPEG_VPU720_ENC_MODE_NONE,
48 JPEG_VPU720_ENC_MODE_ONE_FRAME,
49 JPEG_VPU720_ENC_MODE_MULTI_FRAME_START,
50 JPEG_VPU720_ENC_MODE_MULTI_FRAME_UPDATE,
51 JPEG_VPU720_ENC_MODE_LKT_FORCE_PAUSE,
52 JPEG_VPU720_ENC_MODE_LKT_CONTINUE,
53 JPEG_VPU720_ENC_MODE_SAFE_CLR,
54 JPEG_VPU720_ENC_MODE_FORCE_CLR,
55 JPEG_VPU720_ENC_MODE_FORCE_BUTT,
56 } JpegeVpu720EncCmd;
57
58 typedef enum JPEGVpu720ColorRangeTrans_t {
59 JPEG_VPU720_COLOR_RANGE_FULL_TO_LIMIT,
60 JPEG_VPU720_COLOR_RANGE_LIMIT_TO_FULL,
61 } JPEGVpu720ColorRangeTrans;
62
63 typedef enum JPEGVpu720ChromaDownSampleMode_t {
64 JPEG_VPU720_CHROMA_DOWN_SAMPLE_MODE_Average,
65 JPEG_VPU720_CHROMA_DOWN_SAMPLE_MODE_Discard,
66 } JPEGVpu720ChromaDownSampleMode;
67
68 typedef struct JpegeVpu720FmtCfg_t {
69 JpegeVpu720InFmt input_format;
70 JpegeVpu720OutFmt out_format;
71 MppFrameColorRange src_range;
72 MppFrameColorRange dst_range;
73 JPEGVpu720ChromaDownSampleMode chroma_ds_mode;
74 RK_U32 uv_swap;
75 RK_U32 mirror;
76 RK_U32 fix_chroma_en;
77 RK_U32 fix_chroma_u;
78 RK_U32 fix_chroma_v;
79 RK_U32 out_nb_comp;
80 RK_U32 y_stride;
81 RK_U32 uv_stride;
82 RK_U32 u_offset;
83 RK_U32 v_offset;
84 } JpegeVpu720FmtCfg;
85
86 typedef struct JpegeVpu720HalCtx_t {
87 MppEncHalApi api;
88 MppDev dev;
89 void *regs;
90
91 /* @frame_cnt starts from ZERO */
92 RK_U32 frame_cnt;
93 MppEncCfgSet *cfg;
94
95 RK_U32 enc_mode;
96 RK_U32 frame_size;
97 RK_S32 max_buf_cnt;
98 RK_S32 hdr_status;
99 JpegeVpu720FmtCfg fmt_cfg;
100 RK_U8 *src_buf;
101 RK_U8 *dst_buf;
102 RK_S32 buf_size;
103 RK_U32 frame_num;
104
105 JpegeBits bits;
106 JpegeSyntax syntax;
107 RK_S32 hal_start_pos;
108
109 MppBufferGroup group;
110 MppBuffer qtbl_buffer;
111 RK_U16 *qtbl_sw_buf;
112 HalJpegeRc hal_rc;
113 } JpegeVpu720HalCtx;
114
115 #define JPEGE_VPU720_QTABLE_SIZE (64 * 3)
116
hal_jpege_vpu720_init(void * hal,MppEncHalCfg * cfg)117 static MPP_RET hal_jpege_vpu720_init(void *hal, MppEncHalCfg *cfg)
118 {
119 MPP_RET ret = MPP_OK;
120 JpegeVpu720HalCtx *ctx = (JpegeVpu720HalCtx *)hal;
121
122 mpp_env_get_u32("hal_jpege_debug", &hal_jpege_debug, 0);
123
124 hal_jpege_enter();
125
126 ctx->regs = mpp_calloc(JpegeVpu720Reg, 1);
127 ctx->cfg = cfg->cfg;
128
129 ctx->frame_cnt = 0;
130 ctx->enc_mode = JPEG_VPU720_ENC_MODE_ONE_FRAME;
131 cfg->type = VPU_CLIENT_JPEG_ENC;
132 ret = mpp_dev_init(&cfg->dev, cfg->type);
133 if (ret) {
134 mpp_err_f("mpp_dev_init failed. ret: %d\n", ret);
135 return ret;
136 }
137
138 ctx->dev = cfg->dev;
139 jpege_bits_init(&ctx->bits);
140 mpp_assert(ctx->bits);
141 if (ctx->group == NULL) {
142 ret = mpp_buffer_group_get_internal(&ctx->group, MPP_BUFFER_TYPE_ION);
143 if (ret) {
144 mpp_err_f("mpp_buffer_group_get failed ret %d\n", ret);
145 return ret;
146 }
147 }
148
149 ret = mpp_buffer_get(ctx->group, &ctx->qtbl_buffer, JPEGE_VPU720_QTABLE_SIZE * sizeof(RK_U16));
150 mpp_buffer_attach_dev(ctx->qtbl_buffer, ctx->dev);
151 ctx->qtbl_sw_buf = (RK_U16 *)mpp_calloc(RK_U16, JPEGE_VPU720_QTABLE_SIZE);
152 hal_jpege_rc_init(&ctx->hal_rc);
153
154 hal_jpege_leave();
155 return ret;
156 }
157
hal_jpege_vpu720_deinit(void * hal)158 static MPP_RET hal_jpege_vpu720_deinit(void *hal)
159 {
160 MPP_RET ret = MPP_OK;
161 JpegeVpu720HalCtx *ctx = (JpegeVpu720HalCtx *)hal;
162
163 hal_jpege_enter();
164 jpege_bits_deinit(ctx->bits);
165
166 MPP_FREE(ctx->regs);
167 MPP_FREE(ctx->qtbl_sw_buf);
168
169 if (ctx->dev) {
170 mpp_dev_deinit(ctx->dev);
171 ctx->dev = NULL;
172 }
173
174 if (ctx->qtbl_buffer) {
175 ret = mpp_buffer_put(ctx->qtbl_buffer);
176 if (ret) {
177 mpp_err_f("put qtbl buffer failed\n");
178 }
179 }
180
181 if (ctx->group) {
182 ret = mpp_buffer_group_put(ctx->group);
183 if (ret) {
184 mpp_err_f("group free buffer failed\n");
185 }
186 }
187
188 hal_jpege_leave();
189 return MPP_OK;
190 }
191
jpege_vpu720_setup_format(void * hal,HalEncTask * task)192 static MPP_RET jpege_vpu720_setup_format(void *hal, HalEncTask *task)
193 {
194 JpegeVpu720HalCtx *ctx = (JpegeVpu720HalCtx *) hal;
195 MppFrameFormat in_fmt = ctx->cfg->prep.format & MPP_FRAME_FMT_MASK;
196 JpegeVpu720FmtCfg *fmt_cfg = &ctx->fmt_cfg;
197 JpegeSyntax *syntax = &ctx->syntax;
198 MppFrameChromaFormat out_fmt = syntax->format_out;
199 RK_U32 hor_stride = mpp_frame_get_hor_stride(task->frame);
200 RK_U32 ver_stride = mpp_frame_get_ver_stride(task->frame);
201
202 hal_jpege_enter();
203
204 memset(fmt_cfg, 0, sizeof(JpegeVpu720FmtCfg));
205
206 if (MPP_FRAME_FMT_IS_TILE(ctx->cfg->prep.format)) {
207 switch (in_fmt) {
208 case MPP_FMT_YUV400:
209 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_TILE_400;
210 fmt_cfg->y_stride = hor_stride * 4;
211 fmt_cfg->out_format = JPEGE_VPU720_OUT_FMT_400;
212 break;
213 case MPP_FMT_YUV420P:
214 case MPP_FMT_YUV420SP:
215 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_TILE_420;
216 fmt_cfg->y_stride = hor_stride * 4 * 3 / 2;
217 break;
218 case MPP_FMT_YUV422P:
219 case MPP_FMT_YUV422SP:
220 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_TILE_422;
221 fmt_cfg->y_stride = hor_stride * 4 * 2;
222 break;
223 case MPP_FMT_YUV444P:
224 case MPP_FMT_YUV444SP:
225 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_TILE_444;
226 fmt_cfg->y_stride = hor_stride * 4 * 3;
227 break;
228 default:
229 mpp_err("Unsupported input format 0x%08x, with TILE mask.\n", in_fmt);
230 return MPP_ERR_VALUE;
231 break;
232 }
233 } else {
234 switch (in_fmt) {
235 case MPP_FMT_YUV400:
236 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV400;
237 fmt_cfg->y_stride = hor_stride;
238 fmt_cfg->out_format = JPEGE_VPU720_OUT_FMT_400;
239 break;
240 case MPP_FMT_YUV420P:
241 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV420P;
242 fmt_cfg->y_stride = hor_stride;
243 fmt_cfg->uv_stride = hor_stride >> 1;
244 fmt_cfg->u_offset = hor_stride * ver_stride;
245 fmt_cfg->v_offset = fmt_cfg->u_offset + fmt_cfg->uv_stride * (ver_stride >> 1);
246 break;
247 case MPP_FMT_YUV420SP:
248 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV420SP;
249 fmt_cfg->y_stride = hor_stride;
250 fmt_cfg->uv_stride = hor_stride;
251 fmt_cfg->u_offset = hor_stride * ver_stride;
252 break;
253 case MPP_FMT_YUV420SP_VU:
254 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV420SP;
255 fmt_cfg->y_stride = hor_stride;
256 fmt_cfg->uv_stride = hor_stride;
257 fmt_cfg->u_offset = hor_stride * ver_stride;
258 fmt_cfg->uv_swap = 1;
259 break;
260 case MPP_FMT_YUV422P:
261 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV422P;
262 fmt_cfg->y_stride = hor_stride;
263 fmt_cfg->uv_stride = hor_stride >> 1;
264 fmt_cfg->u_offset = hor_stride * ver_stride;
265 fmt_cfg->v_offset = fmt_cfg->u_offset + fmt_cfg->uv_stride * ver_stride;
266 break;
267 case MPP_FMT_YUV422SP:
268 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV422SP;
269 fmt_cfg->y_stride = hor_stride;
270 fmt_cfg->uv_stride = hor_stride;
271 fmt_cfg->u_offset = hor_stride * ver_stride;
272 break;
273 case MPP_FMT_YUV422SP_VU:
274 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV422SP;
275 fmt_cfg->y_stride = hor_stride;
276 fmt_cfg->uv_stride = hor_stride;
277 fmt_cfg->u_offset = hor_stride * ver_stride;
278 fmt_cfg->uv_swap = 1;
279 break;
280 case MPP_FMT_YUV422_YUYV:
281 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUYV;
282 fmt_cfg->y_stride = hor_stride;
283 break;
284 case MPP_FMT_YUV422_UYVY:
285 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_UYVY;
286 fmt_cfg->y_stride = hor_stride;
287 break;
288 case MPP_FMT_YUV422_YVYU:
289 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUYV;
290 fmt_cfg->y_stride = hor_stride;
291 fmt_cfg->uv_swap = 1;
292 break;
293 case MPP_FMT_YUV422_VYUY:
294 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_UYVY;
295 fmt_cfg->y_stride = hor_stride;
296 fmt_cfg->uv_swap = 1;
297 break;
298 case MPP_FMT_YUV444SP:
299 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV444SP;
300 fmt_cfg->y_stride = hor_stride;
301 fmt_cfg->uv_stride = hor_stride << 1;
302 fmt_cfg->u_offset = hor_stride * ver_stride;
303 break;
304 case MPP_FMT_YUV444P:
305 fmt_cfg->input_format = JPEGE_VPU720_IN_FMT_YUV444P;
306 fmt_cfg->y_stride = hor_stride;
307 fmt_cfg->uv_stride = hor_stride;
308 fmt_cfg->u_offset = hor_stride * ver_stride;
309 fmt_cfg->v_offset = fmt_cfg->u_offset << 1;
310 break;
311 default :
312 mpp_err("Unsupported input format 0x%08x\n", in_fmt);
313 return MPP_ERR_VALUE;
314 break;
315 }
316 }
317
318 switch (out_fmt) {
319 case MPP_CHROMA_400:
320 ctx->fmt_cfg.out_format = JPEGE_VPU720_OUT_FMT_400;
321 break;
322 case MPP_CHROMA_420:
323 ctx->fmt_cfg.out_format = JPEGE_VPU720_OUT_FMT_420;
324 break;
325 case MPP_CHROMA_422:
326 ctx->fmt_cfg.out_format = JPEGE_VPU720_OUT_FMT_422;
327 break;
328 case MPP_CHROMA_444:
329 ctx->fmt_cfg.out_format = JPEGE_VPU720_OUT_FMT_444;
330 break;
331 default:
332 ctx->fmt_cfg.out_format = JPEGE_VPU720_OUT_FMT_420;
333 break;
334 }
335 ctx->fmt_cfg.out_nb_comp = ctx->syntax.nb_components;
336
337 switch (ctx->cfg->prep.chroma_ds_mode) {
338 case MPP_FRAME_CHORMA_DOWN_SAMPLE_MODE_AVERAGE:
339 ctx->fmt_cfg.chroma_ds_mode = JPEG_VPU720_CHROMA_DOWN_SAMPLE_MODE_Average;
340 break;
341 case MPP_FRAME_CHORMA_DOWN_SAMPLE_MODE_DISCARD:
342 ctx->fmt_cfg.chroma_ds_mode = JPEG_VPU720_CHROMA_DOWN_SAMPLE_MODE_Discard;
343 break;
344 default:
345 ctx->fmt_cfg.chroma_ds_mode = JPEG_VPU720_CHROMA_DOWN_SAMPLE_MODE_Average;
346 break;
347 }
348
349 hal_jpege_dbg_detail("JPEG format: in 0x%x out 0x%x, hw in_fmt %d, out_fmt %d, ds_mode %d\n",
350 ctx->cfg->prep.format, ctx->cfg->prep.format_out,
351 ctx->fmt_cfg.input_format, ctx->fmt_cfg.out_format,
352 ctx->fmt_cfg.chroma_ds_mode);
353
354 if (ctx->cfg->prep.mirroring)
355 ctx->fmt_cfg.mirror = 1;
356
357 if (ctx->cfg->prep.fix_chroma_en) {
358 ctx->fmt_cfg.fix_chroma_en = 1;
359 ctx->fmt_cfg.fix_chroma_u = ctx->cfg->prep.fix_chroma_u & 0xff;
360 ctx->fmt_cfg.fix_chroma_v = ctx->cfg->prep.fix_chroma_v & 0xff;
361 }
362
363 ctx->fmt_cfg.src_range = (ctx->cfg->prep.range == MPP_FRAME_RANGE_UNSPECIFIED) ?
364 MPP_FRAME_RANGE_JPEG : ctx->cfg->prep.range;
365 ctx->fmt_cfg.dst_range = (ctx->cfg->prep.range_out == MPP_FRAME_RANGE_UNSPECIFIED) ?
366 MPP_FRAME_RANGE_JPEG : ctx->cfg->prep.range_out;
367 hal_jpege_leave();
368 return MPP_OK;
369 }
370
hal_jpege_vpu720_gen_regs(void * hal,HalEncTask * task)371 MPP_RET hal_jpege_vpu720_gen_regs(void *hal, HalEncTask *task)
372 {
373 MPP_RET ret = MPP_OK;
374 JpegeVpu720HalCtx *ctx = (JpegeVpu720HalCtx *) hal;
375 JpegeVpu720Reg *regs = ctx->regs;
376 JpegeVpu720BaseReg *reg_base = ®s->reg_base;
377 JpegeBits bits = ctx->bits;
378 size_t length = mpp_packet_get_length(task->packet);
379 RK_U8 *buf = mpp_buffer_get_ptr(task->output);
380 size_t size = mpp_buffer_get_size(task->output);
381 JpegeSyntax *syntax = &ctx->syntax;
382 RK_U8 *qtbl_base = (RK_U8 *)mpp_buffer_get_ptr(ctx->qtbl_buffer);
383 RK_S32 bitpos;
384 RK_U32 i, j;
385 RK_U32 encode_width;
386 RK_U32 encode_height;
387
388 hal_jpege_enter();
389
390 jpege_vpu720_setup_format(hal, task);
391
392 memset(regs, 0, sizeof(JpegeVpu720Reg));
393
394 mpp_buffer_sync_begin(task->output);
395
396 if (syntax->q_mode == JPEG_QFACTOR) {
397 syntax->q_factor = 100 - task->rc_task->info.quality_target;
398 hal_jpege_rc_update(&ctx->hal_rc, syntax);
399 }
400
401 jpege_bits_setup(bits, buf, (RK_U32)size);
402 jpege_seek_bits(bits, length << 3);
403 write_jpeg_header(bits, syntax, &ctx->hal_rc);
404 mpp_buffer_sync_end(task->output);
405
406 bitpos = jpege_bits_get_bitpos(bits);
407 task->length = (bitpos + 7) >> 3;
408
409 mpp_packet_set_length(task->packet, task->length);
410
411 reg_base->reg001_enc_strt.lkt_num = 0;
412 reg_base->reg001_enc_strt.vepu_cmd = ctx->enc_mode;
413
414 // interupt
415 reg_base->reg004_int_en.fenc_done_en = 1;
416 reg_base->reg004_int_en.lkt_node_done_en = 1;
417 reg_base->reg004_int_en.sclr_done_en = 1;
418 reg_base->reg004_int_en.vslc_done_en = 1;
419 reg_base->reg004_int_en.vbsb_oflw_en = 1;
420 reg_base->reg004_int_en.vbsb_sct_en = 1;
421 reg_base->reg004_int_en.fenc_err_en = 1;
422 reg_base->reg004_int_en.wdg_en = 1;
423 reg_base->reg004_int_en.lkt_oerr_en = 1;
424 reg_base->reg004_int_en.lkt_estp_en = 1;
425 reg_base->reg004_int_en.lkt_fstp_en = 1;
426 reg_base->reg004_int_en.lkt_note_stp_en = 1;
427 reg_base->reg004_int_en.lkt_data_error_en = 1;
428
429 reg_base->reg005_int_msk.fenc_done_msk = 1;
430 reg_base->reg005_int_msk.lkt_node_done_msk = 1;
431 reg_base->reg005_int_msk.sclr_done_msk = 1;
432 reg_base->reg005_int_msk.vslc_done_msk = 1;
433 reg_base->reg005_int_msk.vbsb_oflw_msk = 1;
434 reg_base->reg005_int_msk.vbsb_sct_msk = 1;
435 reg_base->reg005_int_msk.fenc_err_msk = 1;
436 reg_base->reg005_int_msk.wdg_msk = 1;
437 reg_base->reg005_int_msk.lkt_oerr_msk = 1;
438 reg_base->reg005_int_msk.lkt_estp_msk = 1;
439 reg_base->reg005_int_msk.lkt_fstp_msk = 1;
440 reg_base->reg005_int_msk.lkt_note_stp_msk = 1;
441 reg_base->reg005_int_msk.lkt_data_error_msk = 1;
442
443 reg_base->reg008_cru_ctrl.resetn_hw_en = 1;
444 reg_base->reg008_cru_ctrl.sram_ckg_en = 1;
445 reg_base->reg008_cru_ctrl.cke = 1;
446
447 reg_base->reg042_dbus_endn.jbsw_bus_edin = 0xf;
448 reg_base->reg042_dbus_endn.vsl_bus_edin = 0;
449 reg_base->reg042_dbus_endn.ecs_len_edin = 0xf;
450 reg_base->reg042_dbus_endn.sw_qtbl_edin = 0;
451
452 reg_base->reg011_wdg_jpeg = syntax->mcu_cnt * 1000;
453
454 reg_base->reg026_axi_perf_ctrl0.perf_work_e = 1;
455 reg_base->reg026_axi_perf_ctrl0.perf_clr_e = 1;
456
457 for (i = 0; i < 8; i++) {
458 for (j = 0; j < 8; j++) {
459 ctx->qtbl_sw_buf[i * 8 + j] = 0x8000 / ctx->hal_rc.qtables[0][j * 8 + i];
460 ctx->qtbl_sw_buf[64 + i * 8 + j] = 0x8000 / ctx->hal_rc.qtables[1][j * 8 + i];
461 }
462 }
463
464 memcpy(&ctx->qtbl_sw_buf[64 * 2], &ctx->qtbl_sw_buf[64], sizeof(RK_U16) * 64);
465
466 encode_width = MPP_ALIGN(syntax->width, syntax->mcu_width);
467 encode_height = MPP_ALIGN(syntax->height, syntax->mcu_height);
468 reg_base->reg029_sw_enc_rsl.pic_wd8_m1 = encode_width / 8 - 1;
469 reg_base->reg029_sw_enc_rsl.pic_hd8_m1 = encode_height / 8 - 1;
470 reg_base->reg030_sw_src_fill.pic_wfill_jpeg = encode_width - syntax->width;
471 reg_base->reg030_sw_src_fill.pic_hfill_jpeg = encode_height - syntax->height;
472
473 reg_base->reg032_sw_src_fmt.src_fmt = ctx->fmt_cfg.input_format;
474 reg_base->reg032_sw_src_fmt.out_fmt = ctx->fmt_cfg.out_format;
475 reg_base->reg032_sw_src_fmt.rbuv_swap_jpeg = ctx->fmt_cfg.uv_swap;
476 reg_base->reg032_sw_src_fmt.chroma_ds_mode = ctx->fmt_cfg.chroma_ds_mode;
477 reg_base->reg032_sw_src_fmt.src_mirr_jpeg = ctx->fmt_cfg.mirror;
478 reg_base->reg032_sw_src_fmt.chroma_force_en = ctx->fmt_cfg.fix_chroma_en;
479 reg_base->reg032_sw_src_fmt.u_force_value = ctx->fmt_cfg.fix_chroma_u;
480 reg_base->reg032_sw_src_fmt.v_force_value = ctx->fmt_cfg.fix_chroma_v;
481
482 if (ctx->fmt_cfg.src_range != ctx->fmt_cfg.dst_range) {
483 reg_base->reg032_sw_src_fmt.src_range_trns_en = 1;
484 if (ctx->fmt_cfg.src_range == MPP_FRAME_RANGE_MPEG)
485 reg_base->reg032_sw_src_fmt.src_range_trns_sel = JPEG_VPU720_COLOR_RANGE_LIMIT_TO_FULL;
486 else
487 reg_base->reg032_sw_src_fmt.src_range_trns_sel = JPEG_VPU720_COLOR_RANGE_FULL_TO_LIMIT;
488 }
489
490 reg_base->reg033_sw_pic_ofst.pic_ofst_x = mpp_frame_get_offset_x(task->frame);
491 reg_base->reg033_sw_pic_ofst.pic_ofst_y = mpp_frame_get_offset_y(task->frame);
492
493 reg_base->reg034_sw_src_strd_0.src_strd_0 = ctx->fmt_cfg.y_stride;
494 reg_base->reg035_sw_src_strd_1.src_strd_1 = ctx->fmt_cfg.uv_stride;
495
496 reg_base->reg036_sw_jpeg_enc_cfg.rst_intv = syntax->restart_ri;
497 reg_base->reg036_sw_jpeg_enc_cfg.rst_m = 0;
498 reg_base->reg036_sw_jpeg_enc_cfg.pic_last_ecs = 1;
499
500 reg_base->reg022_adr_src0 = mpp_buffer_get_fd(task->input);
501 reg_base->reg023_adr_src1 = reg_base->reg022_adr_src0;
502 reg_base->reg024_adr_src2 = reg_base->reg022_adr_src0;
503
504 reg_base->reg017_adr_bsbt = mpp_buffer_get_fd(task->output);
505 reg_base->reg018_adr_bsbb = reg_base->reg017_adr_bsbt;
506 reg_base->reg019_adr_bsbr = reg_base->reg017_adr_bsbt;
507 reg_base->reg020_adr_bsbs = reg_base->reg017_adr_bsbt;
508
509 reg_base->reg016_adr_qtbl = mpp_buffer_get_fd(ctx->qtbl_buffer);
510 memcpy(qtbl_base, ctx->qtbl_sw_buf, JPEGE_VPU720_QTABLE_SIZE * sizeof(RK_U16));
511 mpp_buffer_sync_end(ctx->qtbl_buffer);
512
513 mpp_dev_set_reg_offset(ctx->dev, 20, mpp_packet_get_length(task->packet));
514 mpp_dev_set_reg_offset(ctx->dev, 17, mpp_buffer_get_size(task->output));
515 mpp_dev_set_reg_offset(ctx->dev, 23, ctx->fmt_cfg.u_offset);
516 mpp_dev_set_reg_offset(ctx->dev, 24, ctx->fmt_cfg.v_offset);
517
518 ctx->frame_num++;
519
520 hal_jpege_leave();
521 return ret;
522 }
523
hal_jpege_vpu720_start(void * hal,HalEncTask * task)524 MPP_RET hal_jpege_vpu720_start(void *hal, HalEncTask *task)
525 {
526 MPP_RET ret = MPP_OK;
527 JpegeVpu720HalCtx *ctx = (JpegeVpu720HalCtx *) hal;
528 JpegeVpu720Reg *regs = ctx->regs;
529 MppDevRegWrCfg cfg_base;
530 MppDevRegRdCfg cfg_st;
531
532 hal_jpege_enter();
533
534 if (task->flags.err) {
535 mpp_err_f("task->flags.err 0x%08x, return early\n", task->flags.err);
536 return MPP_NOK;
537 }
538
539 if (hal_jpege_debug & HAL_JPEGE_DBG_DETAIL) {
540 RK_U32 i = 0;
541 RK_U32 *reg = (RK_U32 *)regs;
542
543 for (i = 0; i < 43; i++) {
544 mpp_log_f("set reg[%03d] : %04x : 0x%08x\n", i, i * 4, reg[i]);
545 }
546 }
547
548 cfg_base.reg = ®s->reg_base;
549 cfg_base.size = sizeof(JpegeVpu720BaseReg);
550 cfg_base.offset = 0;
551
552 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &cfg_base);
553 if (ret) {
554 mpp_err_f("set register write failed %d\n", ret);
555 return ret;
556 }
557
558 cfg_st.reg = ®s->int_state;
559 cfg_st.size = sizeof(RK_U32);
560 cfg_st.offset = JPEGE_VPU720_REG_BASE_INT_STATE;
561 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &cfg_st);
562 if (ret) {
563 mpp_err_f("set register to read int state failed %d\n", ret);
564 }
565 cfg_st.reg = ®s->reg_st;
566 cfg_st.size = sizeof(JpegeVpu720StatusReg);
567 cfg_st.offset = JPEGE_VPU720_REG_STATUS_OFFSET;
568
569 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &cfg_st);
570
571 if (ret) {
572 mpp_err_f("set register to read hw status failed %d\n", ret);
573 }
574
575 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
576 if (ret) {
577 mpp_err_f("send cmd failed %d\n", ret);
578 }
579
580 hal_jpege_leave();
581 return MPP_OK;
582 }
583
hal_jpege_vpu720_wait(void * hal,HalEncTask * task)584 MPP_RET hal_jpege_vpu720_wait(void *hal, HalEncTask *task)
585 {
586 MPP_RET ret = MPP_OK;
587 JpegeVpu720HalCtx *ctx = (JpegeVpu720HalCtx *) hal;
588 JpegeVpu720Reg *regs = (JpegeVpu720Reg *)ctx->regs;
589 JpegeVpu720StatusReg *reg_st = ®s->reg_st;
590 RK_U32 int_state = regs->int_state;
591
592 hal_jpege_enter();
593
594 if (task->flags.err) {
595 mpp_err_f("task->flags.err 0x%08x, return earyl\n", task->flags.err);
596 return ret = MPP_NOK;
597 }
598
599 ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
600 if (ret) {
601 mpp_err_f("poll cmd failed %d\n", ret);
602 return ret = MPP_ERR_VPUHW;
603 } else {
604 if (int_state & 0x170)
605 mpp_err_f("JPEG encoder hw error 0x%08x\n", int_state);
606 else
607 hal_jpege_dbg_simple("JPEG encoder int state 0x%08x\n", int_state);
608
609 hal_jpege_dbg_detail("hw length %d, cycle %d\n",
610 reg_st->st_bsl_l32_jpeg_head_bits,
611 reg_st->st_perf_working_cnt);
612 task->hw_length += reg_st->st_bsl_l32_jpeg_head_bits;
613 }
614
615 hal_jpege_leave();
616 return MPP_OK;
617 }
618
hal_jpege_vpu720_get_task(void * hal,HalEncTask * task)619 MPP_RET hal_jpege_vpu720_get_task(void *hal, HalEncTask *task)
620 {
621 JpegeVpu720HalCtx *ctx = (JpegeVpu720HalCtx *) hal;
622 JpegeSyntax *syntax = (JpegeSyntax *) task->syntax.data;
623
624 hal_jpege_enter();
625 memcpy(&ctx->syntax, syntax, sizeof(ctx->syntax));
626
627 if (ctx->cfg->jpeg.update) {
628 hal_jpege_rc_update(&ctx->hal_rc, syntax);
629 ctx->cfg->jpeg.update = 0;
630 }
631
632 task->rc_task->frm.is_intra = 1;
633
634 // TODO config rc
635 hal_jpege_leave();
636 return MPP_OK;
637 }
638
hal_jpege_vpu720_ret_task(void * hal,HalEncTask * task)639 MPP_RET hal_jpege_vpu720_ret_task(void *hal, HalEncTask *task)
640 {
641 (void)hal;
642 EncRcTaskInfo * rc_info = &task->rc_task->info;
643
644 hal_jpege_enter();
645
646 task->length += task->hw_length;
647
648 // setup bit length for rate control
649 rc_info->bit_real = task->hw_length * 8;
650 rc_info->quality_real = rc_info->quality_target;
651 mpp_buffer_sync_ro_begin(task->output);
652
653 hal_jpege_leave();
654 return MPP_OK;
655 }
656 const MppEncHalApi hal_jpege_vpu720 = {
657 .name = "hal_jpege_vpu720",
658 .coding = MPP_VIDEO_CodingMJPEG,
659 .ctx_size = sizeof(JpegeVpu720HalCtx),
660 .flag = 0,
661 .init = hal_jpege_vpu720_init,
662 .deinit = hal_jpege_vpu720_deinit,
663 .prepare = NULL,
664 .get_task = hal_jpege_vpu720_get_task,
665 .gen_regs = hal_jpege_vpu720_gen_regs,
666 .start = hal_jpege_vpu720_start,
667 .wait = hal_jpege_vpu720_wait,
668 .part_start = NULL,
669 .part_wait = NULL,
670 .ret_task = hal_jpege_vpu720_ret_task,
671 };
672