xref: /rockchip-linux_mpp/mpp/hal/rkenc/jpege/hal_jpege_vpu720.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
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 = &regs->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 = &regs->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 = &regs->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 = &regs->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 = &regs->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