xref: /rockchip-linux_mpp/mpp/hal/vpu/jpegd/hal_jpegd_rkv.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /*
2  * Copyright 2020 Rockchip Electronics Co. LTD
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #define MODULE_TAG "hal_jpegd_rkv"
17 
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdint.h>
21 
22 #include "mpp_env.h"
23 #include "mpp_mem.h"
24 #include "mpp_debug.h"
25 #include "mpp_frame.h"
26 #include "mpp_common.h"
27 #include "mpp_buffer_impl.h"
28 
29 #include "jpegd_syntax.h"
30 #include "hal_jpegd_common.h"
31 #include "hal_jpegd_rkv.h"
32 #include "hal_jpegd_rkv_reg.h"
33 #include "mpp_dec_cb_param.h"
34 
35 // Support 8-bit precision only
36 #define NB_COMPONENTS (3)
37 #define RKD_QUANTIZATION_TBL_SIZE (8*8*2*NB_COMPONENTS)
38 #define RKD_HUFFMAN_MINCODE_TBL_SIZE (16*3*2*NB_COMPONENTS)
39 #define RKD_HUFFMAN_VALUE_TBL_SIZE (16*12*NB_COMPONENTS)
40 #define RKD_HUFFMAN_MINCODE_TBL_OFFSET (RKD_QUANTIZATION_TBL_SIZE)
41 #define RKD_HUFFMAN_VALUE_TBL_OFFSET (RKD_HUFFMAN_MINCODE_TBL_OFFSET + MPP_ALIGN(RKD_HUFFMAN_MINCODE_TBL_SIZE, 64))
42 #define RKD_TABLE_SIZE (RKD_HUFFMAN_VALUE_TBL_OFFSET + RKD_HUFFMAN_VALUE_TBL_SIZE)
43 
jpegd_write_rkv_qtbl(JpegdHalCtx * ctx,JpegdSyntax * syntax)44 MPP_RET jpegd_write_rkv_qtbl(JpegdHalCtx *ctx, JpegdSyntax *syntax)
45 {
46     jpegd_dbg_func("enter\n");
47     MPP_RET ret = MPP_OK;
48     JpegdSyntax *s = syntax;
49     RK_U16 *base = (RK_U16 *)mpp_buffer_get_ptr(ctx->pTableBase);
50     RK_U16 table_tmp[QUANTIZE_TABLE_LENGTH] = {0};
51     RK_U32 i, j , idx;
52 
53     for (j = 0; j < s->nb_components; j++) {
54         idx = s->quant_index[j];
55 
56         //turn zig-zag order to raster-scan order
57         for (i = 0; i < QUANTIZE_TABLE_LENGTH; i++) {
58             table_tmp[zzOrder[i]] = s->quant_matrixes[idx][i];
59         }
60 
61         memcpy(base + j * QUANTIZE_TABLE_LENGTH, table_tmp, sizeof(RK_U16) * QUANTIZE_TABLE_LENGTH);
62     }
63 
64     if (jpegd_debug & JPEGD_DBG_HAL_TBL) {
65         RK_U8 *data = (RK_U8 *)mpp_buffer_get_ptr(ctx->pTableBase);
66 
67         mpp_log("--------------Quant tbl----------------------\n");
68         for (i = 0; i < RKD_QUANTIZATION_TBL_SIZE; i += 8) {
69             mpp_log("%02x%02x%02x%02x%02x%02x%02x%02x\n",
70                     data[i + 7], data[i + 6], data[i + 5], data[i + 4],
71                     data[i + 3], data[i + 2], data[i + 1], data[i + 0]);
72         }
73     }
74 
75     jpegd_dbg_func("exit\n");
76     return ret;
77 
78 }
79 
jpegd_write_rkv_htbl(JpegdHalCtx * ctx,JpegdSyntax * jpegd_syntax)80 MPP_RET jpegd_write_rkv_htbl(JpegdHalCtx *ctx, JpegdSyntax *jpegd_syntax)
81 {
82     jpegd_dbg_func("enter\n");
83     MPP_RET ret = MPP_OK;
84 
85     JpegdSyntax *s = jpegd_syntax;
86     void * htbl_ptr[6] = {NULL};
87     RK_U32 i, j, k = 0;
88     RK_U8 *p_htbl_value = (RK_U8 *)mpp_buffer_get_ptr(ctx->pTableBase) + RKD_HUFFMAN_VALUE_TBL_OFFSET;
89     RK_U16 *p_htbl_mincode = (RK_U16 *)mpp_buffer_get_ptr(ctx->pTableBase) + RKD_HUFFMAN_MINCODE_TBL_OFFSET  / 2;
90     RK_U16 min_code_ac[16] = {0};
91     RK_U16 min_code_dc[16] = {0};
92     RK_U16 acc_addr_ac[16] = {0};
93     RK_U16 acc_addr_dc[16] = {0};
94     RK_U8 htbl_value[192] = {0};
95     RK_U16 code = 0;
96     RK_S32 addr = 0;
97     RK_U32 len = 0;
98     AcTable *ac_ptr;
99     DcTable *dc_ptr;
100 
101     htbl_ptr[0] = &s->dc_table[s->dc_index[0]];
102     htbl_ptr[1] = &s->ac_table[s->ac_index[0]];
103 
104     htbl_ptr[2] = &s->dc_table[s->dc_index[1]];
105     htbl_ptr[3] = &s->ac_table[s->ac_index[1]];
106 
107     htbl_ptr[4] = htbl_ptr[2];
108     htbl_ptr[5] = htbl_ptr[3];
109 
110     for (k = 0; k < s->nb_components; k++) {
111         dc_ptr = (DcTable *)htbl_ptr[k * 2];
112         ac_ptr = (AcTable *)htbl_ptr[k * 2 + 1];
113 
114         len = dc_ptr->bits[0];
115         code = addr = 0;
116         min_code_dc[0] = 0;
117         acc_addr_dc[0] = 0;
118 
119         for (j = 0; j < 16; j++) {
120             len = dc_ptr->bits[j];
121 
122             if (len == 0 && j > 0) {
123                 if (code > (min_code_dc[j - 1] << 1))
124                     min_code_dc[j] = code;
125                 else
126                     min_code_dc[j] = min_code_dc[j - 1] << 1;
127             } else {
128                 min_code_dc[j] = code;
129             }
130 
131             code += len;
132             addr += len;
133             acc_addr_dc[j] = addr;
134             code <<= 1;
135 
136         }
137 
138         if (dc_ptr->bits[15])
139             min_code_dc[0] = min_code_dc[15] + dc_ptr->bits[15] - 1;
140         else
141             min_code_dc[0] = min_code_dc[15];
142 
143         len = ac_ptr->bits[0];
144         code = addr = 0;
145         min_code_ac[0] = 0;
146         acc_addr_ac[0] = 0;
147         for (j = 0; j < 16; j++) {
148             len = ac_ptr->bits[j];
149 
150             if (len == 0 && j > 0) {
151                 if (code > (min_code_ac[j - 1] << 1))
152                     min_code_ac[j] = code;
153                 else
154                     min_code_ac[j] = min_code_ac[j - 1] << 1;
155             } else {
156                 min_code_ac[j] = code;
157             }
158 
159             code += len;
160             addr += len;
161             acc_addr_ac[j] = addr;
162             code <<= 1;
163         }
164 
165         if (ac_ptr->bits[15])
166             min_code_ac[0] = min_code_ac[15] + ac_ptr->bits[15] - 1;
167         else
168             min_code_ac[0] = min_code_ac[15];
169 
170         for (i = 0; i < 16; i++) {
171             *p_htbl_mincode++ = min_code_dc[i];
172         }
173 
174         for (i = 0; i < 8; i++) {
175             *p_htbl_mincode++ = acc_addr_dc[2 * i] | acc_addr_dc[2 * i + 1] << 8;
176         }
177 
178         for (i = 0; i < 16; i++) {
179             *p_htbl_mincode++ = min_code_ac[i];
180         }
181 
182         for (i = 0; i < 8; i++) {
183             *p_htbl_mincode++ = acc_addr_ac[2 * i] | acc_addr_ac[2 * i + 1] << 8;
184         }
185 
186         for (i = 0; i < MAX_DC_HUFFMAN_TABLE_LENGTH; i++) {
187             htbl_value[i] = dc_ptr->vals[i];
188         }
189 
190         for (i = 0; i < MAX_AC_HUFFMAN_TABLE_LENGTH; i++) {
191             htbl_value[i + 16] = ac_ptr->vals[i];
192         }
193 
194         for (i = 0; i < 12 * 16; i++) {
195             *p_htbl_value++ = htbl_value[i];
196         }
197     }
198 
199     if (jpegd_debug & JPEGD_DBG_HAL_TBL) {
200         RK_U8 *data = (RK_U8 *)mpp_buffer_get_ptr(ctx->pTableBase) + RKD_HUFFMAN_VALUE_TBL_OFFSET;
201 
202         mpp_log("--------------huffman value tbl----------------------\n");
203         for (i = 0; i < RKD_HUFFMAN_VALUE_TBL_SIZE; i += 8) {
204             mpp_log("%02x%02x%02x%02x%02x%02x%02x%02x\n",
205                     data[i + 7], data[i + 6], data[i + 5], data[i + 4],
206                     data[i + 3], data[i + 2], data[i + 1], data[i + 0]);
207         }
208 
209         data = NULL;
210         data = (RK_U8 *)mpp_buffer_get_ptr(ctx->pTableBase) + RKD_HUFFMAN_MINCODE_TBL_OFFSET;
211 
212         mpp_log("--------------huffman mincode tbl----------------------\n");
213         for (i = 0; i < RKD_HUFFMAN_MINCODE_TBL_SIZE; i += 8) {
214             mpp_log("%02x%02x%02x%02x%02x%02x%02x%02x\n",
215                     data[i + 7], data[i + 6], data[i + 5], data[i + 4],
216                     data[i + 3], data[i + 2], data[i + 1], data[i + 0]);
217         }
218     }
219 
220     jpegd_dbg_func("exit\n");
221     return ret;
222 }
223 
hal_jpegd_rkv_init(void * hal,MppHalCfg * cfg)224 MPP_RET hal_jpegd_rkv_init(void *hal, MppHalCfg *cfg)
225 {
226     jpegd_dbg_func("enter\n");
227     MPP_RET ret = MPP_OK;
228     JpegdHalCtx *ctx = (JpegdHalCtx *)hal;
229     if (NULL == ctx) {
230         ctx = (JpegdHalCtx *)mpp_calloc(JpegdHalCtx, 1);
231         if (NULL == ctx) {
232             mpp_err_f("NULL pointer");
233             return MPP_ERR_NULL_PTR;
234         }
235     }
236 
237     ctx->dec_cb       = cfg->dec_cb;
238     ctx->packet_slots = cfg->packet_slots;
239     ctx->frame_slots  = cfg->frame_slots;
240 
241     /* allocate regs buffer */
242     if (ctx->regs == NULL) {
243         ctx->regs = mpp_calloc_size(void, sizeof(JpegRegSet));
244         if (ctx->regs == NULL) {
245             mpp_err("hal jpegd reg alloc failed\n");
246 
247             jpegd_dbg_func("exit\n");
248             return MPP_ERR_NOMEM;
249         }
250     }
251 
252     if (ctx->group == NULL) {
253         ret = mpp_buffer_group_get_internal(&ctx->group, MPP_BUFFER_TYPE_ION);
254         if (ret) {
255             mpp_err_f("mpp_buffer_group_get failed ret %d\n", ret);
256             return ret;
257         }
258     }
259 
260     ret = mpp_buffer_get(ctx->group, &ctx->pTableBase, RKD_TABLE_SIZE);
261     if (ret) {
262         mpp_err_f("Get table buffer failed, ret %d\n", ret);
263     }
264 
265     mpp_buffer_attach_dev(ctx->pTableBase, ctx->dev);
266 
267     jpegd_dbg_func("exit\n");
268     return ret;
269 }
270 
setup_output_fmt(JpegdHalCtx * ctx,JpegdSyntax * syntax,RK_S32 out_idx)271 static MPP_RET setup_output_fmt(JpegdHalCtx *ctx, JpegdSyntax *syntax, RK_S32 out_idx)
272 {
273 
274     jpegd_dbg_func("enter\n");
275     MPP_RET ret = MPP_OK;
276     JpegdSyntax *s = syntax;
277     JpegRegSet *regs = (JpegRegSet *)ctx->regs;
278     RK_U32 stride = syntax->hor_stride;
279     MppFrame frm = NULL;
280 
281     mpp_buf_slot_get_prop(ctx->frame_slots, out_idx, SLOT_FRAME_PTR, &frm);
282 
283     if (ctx->scale) {
284         if (ctx->scale == 2)
285             regs->reg2_sys.scaledown_mode = SCALEDOWN_HALF;
286         if (ctx->scale == 4)
287             regs->reg2_sys.scaledown_mode = SCALEDOWN_QUARTER;
288         if (ctx->scale == 8)
289             regs->reg2_sys.scaledown_mode = SCALEDOWN_ONE_EIGHTS;
290     } else {
291         regs->reg2_sys.scaledown_mode = SCALEDOWN_DISABLE;
292     }
293 
294     mpp_frame_set_hor_stride_pixel(frm, stride);
295 
296     if (ctx->set_output_fmt_flag && (ctx->output_fmt != s->output_fmt)) {   // PP enable
297         if (MPP_FRAME_FMT_IS_YUV(ctx->output_fmt) && s->output_fmt != MPP_FMT_YUV400) {
298             if (ctx->output_fmt == MPP_FMT_YUV420SP)
299                 regs->reg2_sys.yuv_out_format = YUV_OUT_FMT_2_NV12;
300             else if (ctx->output_fmt == MPP_FMT_YUV422_YUYV)
301                 /* Only support yuv422 and yuv444.
302                  * Other format transformation won't report hardware irq error,
303                  * and won't get a correct YUV image.
304                 */
305                 regs->reg2_sys.yuv_out_format = YUV_OUT_FMT_2_YUYV;
306             else if (ctx->output_fmt == MPP_FMT_YUV422_YVYU) {
307                 regs->reg2_sys.out_cbcr_swap = 1;
308                 regs->reg2_sys.yuv_out_format = YUV_OUT_FMT_2_YUYV;
309             } else if (ctx->output_fmt == MPP_FMT_YUV420SP_VU) {
310                 regs->reg2_sys.yuv_out_format = YUV_OUT_FMT_2_NV12;
311                 regs->reg2_sys.out_cbcr_swap = 1;
312             }
313         } else if (MPP_FRAME_FMT_IS_RGB(ctx->output_fmt)) {
314             if (ctx->output_fmt == MPP_FMT_RGB888) {
315                 regs->reg2_sys.yuv_out_format = YUV_OUT_FMT_2_RGB888;
316                 mpp_frame_set_hor_stride(frm, stride * 3);
317             } else if (ctx->output_fmt == (MPP_FMT_BGR565 | MPP_FRAME_FMT_LE_MASK) ||
318                        ctx->output_fmt == MPP_FMT_RGB565) { // bgr565le or rgb565be
319                 regs->reg2_sys.yuv_out_format = YUV_OUT_FMT_2_RGB565;
320                 mpp_frame_set_hor_stride(frm, stride * 2);
321             } else {
322                 mpp_err_f("unsupported output format %d\n", ctx->output_fmt);
323                 ret = MPP_NOK;
324             }
325             MppFrameColorRange color_range = MPP_FRAME_RANGE_UNSPECIFIED;
326             color_range = mpp_frame_get_color_range(frm);
327             if (color_range != MPP_FRAME_RANGE_MPEG)
328                 regs->reg2_sys.yuv2rgb_range = YUV_TO_RGB_FULL_RANGE;
329             else
330                 regs->reg2_sys.yuv2rgb_range = YUV_TO_RGB_LIMIT_RANGE;
331         }
332     } else {    //keep original format
333         regs->reg2_sys.yuv_out_format = YUV_OUT_FMT_NO_TRANS;
334         ctx->output_fmt = s->output_fmt;
335     }
336 
337     if (MPP_FRAME_FMT_IS_TILE(ctx->output_fmt))
338         regs->reg2_sys.dec_out_sequence = OUTPUT_TILE;
339     else
340         regs->reg2_sys.dec_out_sequence = OUTPUT_RASTER;
341 
342     jpegd_dbg_hal("convert format %d to format %d\n", s->output_fmt, ctx->output_fmt);
343 
344     if ((s->yuv_mode == YUV_MODE_420 && regs->reg2_sys.yuv_out_format == YUV_OUT_FMT_NO_TRANS) ||
345         (regs->reg2_sys.yuv_out_format == YUV_OUT_FMT_2_NV12))
346         regs->reg2_sys.fill_down_e = 1;
347     else
348         regs->reg2_sys.fill_down_e = s->fill_bottom;
349     regs->reg2_sys.fill_right_e = s->fill_right;
350 
351     mpp_frame_set_fmt(frm, ctx->output_fmt);
352 
353     jpegd_dbg_func("exit\n");
354     return ret;
355 }
356 
jpegd_gen_regs(JpegdHalCtx * ctx,JpegdSyntax * syntax)357 static MPP_RET jpegd_gen_regs(JpegdHalCtx *ctx, JpegdSyntax *syntax)
358 {
359     jpegd_dbg_func("enter\n");
360     MPP_RET ret = MPP_OK;
361     JpegdSyntax *s = syntax;
362     JpegRegSet *regs = (JpegRegSet *)ctx->regs;
363 
364     regs->reg1_int.dec_e = 1;
365     regs->reg1_int.dec_timeout_e = 1;
366     regs->reg1_int.buf_empty_e = 1;
367 
368     regs->reg3_pic_size.pic_width_m1 = s->width - 1;
369     regs->reg3_pic_size.pic_height_m1 = s->height - 1;
370 
371     if (s->sample_precision != DCT_SAMPLE_PRECISION_8 || s->qtbl_entry > TBL_ENTRY_3)
372         return MPP_NOK;
373 
374     regs->reg4_pic_fmt.pixel_depth = BIT_DEPTH_8;
375     if (s->nb_components == 1) {
376         regs->reg4_pic_fmt.htables_sel = TBL_ENTRY_1;
377     }
378 
379     if (s->nb_components > 1) {
380         regs->reg4_pic_fmt.qtables_sel = (s->qtbl_entry > 1) ? TBL_ENTRY_3 : TBL_ENTRY_2;
381         regs->reg4_pic_fmt.htables_sel = (s->htbl_entry > 0x0f) ? TBL_ENTRY_3 : TBL_ENTRY_2;
382     } else {
383         regs->reg4_pic_fmt.qtables_sel = TBL_ENTRY_1;
384         regs->reg4_pic_fmt.htables_sel = TBL_ENTRY_1;
385     }
386 
387     if (s->restart_interval) {
388         regs->reg4_pic_fmt.dri_e = RST_ENABLE;
389         regs->reg4_pic_fmt.dri_mcu_num_m1 = s->restart_interval - 1;
390     }
391 
392     switch (s->yuv_mode) {
393     case JPEGDEC_YUV400:
394     case JPEGDEC_YUV420:
395     case JPEGDEC_YUV422:
396         regs->reg4_pic_fmt.jpeg_mode = s->yuv_mode;
397         break;
398     case JPEGDEC_YUV411:
399         regs->reg4_pic_fmt.jpeg_mode = YUV_MODE_411;
400         break;
401     case JPEGDEC_YUV440:
402         regs->reg4_pic_fmt.jpeg_mode = YUV_MODE_440;
403         break;
404     case JPEGDEC_YUV444:
405         regs->reg4_pic_fmt.jpeg_mode = YUV_MODE_444;
406         break;
407     default:
408         mpp_err_f("unsupported yuv mode %d\n", s->yuv_mode);
409         break;
410     }
411 
412     RK_U32 out_width = MPP_ALIGN(s->width, 16);
413     RK_U32 out_height = s->height;
414     out_width = out_width >> regs->reg2_sys.scaledown_mode;
415     out_width = MPP_ALIGN(out_width, 16);
416     out_height = regs->reg2_sys.fill_down_e ? MPP_ALIGN(out_height, 16) : MPP_ALIGN(out_height, 8);
417     out_height = out_height >> regs->reg2_sys.scaledown_mode;
418     jpegd_dbg_hal("output scale %d, width %d, height %d\n", regs->reg2_sys.scaledown_mode, out_width, out_height);
419 
420     RK_U32 y_hor_stride = out_width >> 4;
421     RK_U32 y_virstride = 0;
422     RK_U32 uv_hor_virstride = 0;
423 
424     switch (regs->reg2_sys.yuv_out_format) {
425     case YUV_OUT_FMT_2_RGB888:
426         y_hor_stride *= 3;
427         break;
428     case YUV_OUT_FMT_2_RGB565:
429     case YUV_OUT_FMT_2_YUYV:
430         y_hor_stride *= 2;
431         break;
432     case YUV_OUT_FMT_NO_TRANS:
433         switch (regs->reg4_pic_fmt.jpeg_mode) {
434         case YUV_MODE_440:
435         case YUV_MODE_444:
436             uv_hor_virstride = y_hor_stride * 2;
437             break;
438         case YUV_MODE_411:
439             uv_hor_virstride = y_hor_stride >> 1;
440             break;
441         case YUV_MODE_400:
442             uv_hor_virstride = 0;
443             break;
444         default:
445             uv_hor_virstride = y_hor_stride;
446             break;
447         }
448         break;
449     case YUV_OUT_FMT_2_NV12:
450         uv_hor_virstride = y_hor_stride;
451         break;
452     }
453 
454     y_virstride = y_hor_stride * out_height;
455     if (regs->reg2_sys.dec_out_sequence == OUTPUT_TILE) {
456         // The new JPEG decoder supports tile 4x4 output by default.
457         if (mpp_get_soc_type() >= ROCKCHIP_SOC_RK3576) {
458             switch (regs->reg2_sys.yuv_out_format) {
459             case YUV_OUT_FMT_2_YUYV:
460                 y_hor_stride = y_hor_stride * 4 * 2;
461                 break;
462             case YUV_OUT_FMT_NO_TRANS:
463                 switch (regs->reg4_pic_fmt.jpeg_mode) {
464                 case YUV_MODE_422:
465                 case YUV_MODE_440:
466                     y_hor_stride = y_hor_stride * 4 * 2;
467                     break;
468                 case YUV_MODE_444:
469                     y_hor_stride = y_hor_stride * 4 * 3;
470                     break;
471                 case YUV_MODE_411:
472                 case YUV_MODE_420:
473                     y_hor_stride = y_hor_stride * 4 * 3 / 2;
474                     break;
475                 case YUV_MODE_400:
476                     y_hor_stride = y_hor_stride * 4;
477                     break;
478                 default:
479                     return MPP_NOK;
480                     break;
481                 }
482                 break;
483             case YUV_OUT_FMT_2_NV12:
484                 y_hor_stride = y_hor_stride * 4 * 3 / 2;
485                 break;
486             }
487 
488             uv_hor_virstride = 0;
489         } else {
490             y_hor_stride <<= 3;
491             uv_hor_virstride <<= 3;
492         }
493     }
494 
495     regs->reg5_hor_virstride.y_hor_virstride = y_hor_stride & 0xffff;
496     regs->reg5_hor_virstride.uv_hor_virstride = uv_hor_virstride & 0xffff;
497     regs->reg6_y_virstride.y_virstride = y_virstride;
498 
499     regs->reg7_tbl_len.y_hor_virstride_h = (y_hor_stride >> 16) & 1;
500 
501     if (s->qtable_cnt)
502         regs->reg7_tbl_len.qtbl_len = regs->reg4_pic_fmt.qtables_sel * 8 - 1;
503     else
504         regs->reg7_tbl_len.qtbl_len = 0;
505 
506     // 8 bit precision 12, 12 bit precision 16;
507     regs->reg7_tbl_len.htbl_value_len = regs->reg4_pic_fmt.htables_sel * (regs->reg4_pic_fmt.pixel_depth ? 16 : 12) - 1;
508 
509     switch (regs->reg4_pic_fmt.htables_sel) {
510     case TBL_ENTRY_0 :
511         regs->reg7_tbl_len.htbl_mincode_len = 0;
512         regs->reg7_tbl_len.htbl_value_len = 0;
513         break;
514     case TBL_ENTRY_2 :
515         regs->reg7_tbl_len.htbl_mincode_len = (s->nb_components - 1) * 6 - 1;
516         break;
517     case TBL_ENTRY_1 :
518     case TBL_ENTRY_3 :
519         regs->reg7_tbl_len.htbl_mincode_len = s->nb_components * 6 - 1;
520         break;
521     default :
522         mpp_err_f("unsupported htable_sel %d\n", regs->reg4_pic_fmt.htables_sel);
523         break;
524     }
525 
526     RK_U32 strm_offset = 0;
527     RK_U32 hw_strm_offset = 0;
528     RK_U8 start_byte = 0;
529     RK_U32 table_fd = mpp_buffer_get_fd(ctx->pTableBase);
530 
531     if (table_fd <= 0) {
532         mpp_err_f("get table_fd failed\n");
533         return MPP_NOK;
534     }
535 
536     strm_offset = s->strm_offset;
537     hw_strm_offset = strm_offset - strm_offset % 16;
538     start_byte = strm_offset % 16;
539 
540     regs->reg8_strm_len.stream_len = (MPP_ALIGN((s->pkt_len - hw_strm_offset), 16) - 1) >> 4;
541     regs->reg8_strm_len.strm_start_byte = start_byte;
542 
543     regs->reg9_qtbl_base = table_fd;
544     regs->reg10_htbl_mincode_base = table_fd;
545     regs->reg11_htbl_value_base = table_fd;
546     regs->reg13_dec_out_base = ctx->frame_fd;
547     regs->reg12_strm_base = ctx->pkt_fd;
548 
549     mpp_dev_set_reg_offset(ctx->dev, 12, hw_strm_offset);
550     mpp_dev_set_reg_offset(ctx->dev, 10, RKD_HUFFMAN_MINCODE_TBL_OFFSET);
551     mpp_dev_set_reg_offset(ctx->dev, 11, RKD_HUFFMAN_VALUE_TBL_OFFSET);
552 
553     regs->reg14_strm_error.error_prc_mode = 1;
554     regs->reg14_strm_error.strm_ffff_err_mode = 2;
555     regs->reg14_strm_error.strm_other_mark_mode = 2;
556     regs->reg14_strm_error.strm_dri_seq_err_mode = 0;
557 
558     regs->reg16_clk_gate.val = 0xff;
559 
560     regs->reg30_perf_latency_ctrl0.axi_per_work_e = 1;
561     regs->reg30_perf_latency_ctrl0.axi_per_clr_e = 1;
562     regs->reg30_perf_latency_ctrl0.axi_cnt_type = 1;
563     regs->reg30_perf_latency_ctrl0.rd_latency_id = 0xa;
564 
565     jpegd_write_rkv_htbl(ctx, s);
566 
567     jpegd_write_rkv_qtbl(ctx, s);
568 
569     jpegd_dbg_func("exit\n");
570     return ret;
571 }
572 
hal_jpegd_rkv_deinit(void * hal)573 MPP_RET hal_jpegd_rkv_deinit(void *hal)
574 {
575     MPP_RET ret = MPP_OK;
576     JpegdHalCtx *ctx = (JpegdHalCtx *)hal;
577 
578     jpegd_dbg_func("enter\n");
579 
580     if (ctx->dev) {
581         mpp_dev_deinit(ctx->dev);
582         ctx->dev = NULL;
583     }
584 
585     if (ctx->pTableBase) {
586         ret = mpp_buffer_put(ctx->pTableBase);
587         if (ret) {
588             mpp_err_f("put buffer failed\n");
589             return ret;
590         }
591     }
592 
593     if (ctx->group) {
594         ret = mpp_buffer_group_put(ctx->group);
595         if (ret) {
596             mpp_err_f("group free buffer failed\n");
597             return ret;
598         }
599     }
600 
601     if (ctx->regs) {
602         mpp_free(ctx->regs);
603         ctx->regs = NULL;
604     }
605 
606     ctx->output_fmt = MPP_FMT_YUV420SP;
607     ctx->set_output_fmt_flag = 0;
608     ctx->hal_debug_enable = 0;
609     ctx->frame_count = 0;
610     ctx->output_yuv_count = 0;
611 
612     jpegd_dbg_func("exit\n");
613     return ret;
614 }
615 
hal_jpegd_rkv_gen_regs(void * hal,HalTaskInfo * syn)616 MPP_RET hal_jpegd_rkv_gen_regs(void *hal,  HalTaskInfo *syn)
617 {
618     jpegd_dbg_func("enter\n");
619     MPP_RET ret = MPP_OK;
620     JpegdHalCtx *ctx = (JpegdHalCtx *)hal;
621     JpegdSyntax *s = (JpegdSyntax *)syn->dec.syntax.data;
622 
623     MppBuffer strm_buf = NULL;
624     MppBuffer output_buf = NULL;
625 
626     if (syn->dec.flags.parse_err)
627         goto __RETURN;
628 
629     mpp_buf_slot_get_prop(ctx->packet_slots, syn->dec.input, SLOT_BUFFER, & strm_buf);
630     mpp_buf_slot_get_prop(ctx->frame_slots, syn->dec.output, SLOT_BUFFER, &output_buf);
631 
632     ctx->pkt_fd = mpp_buffer_get_fd(strm_buf);
633     if (ctx->pkt_fd <= 0) {
634         mpp_err_f("get pkt_fd failed\n");
635         goto __RETURN;
636     }
637 
638     ctx->frame_fd = mpp_buffer_get_fd(output_buf);
639     if (ctx->frame_fd <= 0) {
640         mpp_err_f("get frame_fd failed\n");
641         goto __RETURN;
642     }
643 
644     memset(ctx->regs, 0, sizeof(JpegRegSet));
645 
646     setup_output_fmt(ctx, s, syn->dec.output);
647 
648     ret = jpegd_gen_regs(ctx, s);
649     mpp_buffer_sync_end(strm_buf);
650     mpp_buffer_sync_end(ctx->pTableBase);
651 
652     if (ret != MPP_OK) {
653         mpp_err_f("generate registers failed\n");
654         goto __RETURN;
655     }
656 
657     syn->dec.valid = 1;
658     jpegd_dbg_func("exit\n");
659     return ret;
660 
661 __RETURN:
662     syn->dec.flags.parse_err = 1;
663     jpegd_dbg_func("exit\n");
664     return ret;
665 }
666 
hal_jpegd_rkv_start(void * hal,HalTaskInfo * task)667 MPP_RET hal_jpegd_rkv_start(void *hal, HalTaskInfo *task)
668 {
669     MPP_RET ret = MPP_OK;
670     JpegdHalCtx * ctx = (JpegdHalCtx *)hal;
671     RK_U32 *regs = (RK_U32 *)ctx->regs;
672 
673     jpegd_dbg_func("enter\n");
674     if (task->dec.flags.parse_err)
675         goto __RETURN;
676 
677     MppDevRegWrCfg wr_cfg;
678     MppDevRegRdCfg rd_cfg;
679     RK_U32 reg_size = JPEGD_REG_NUM * sizeof(RK_U32);
680     RK_U8 i = 0;
681 
682     wr_cfg.reg = regs;
683     wr_cfg.size = reg_size;
684     wr_cfg.offset = 0;
685 
686     if (jpegd_debug & JPEGD_DBG_HAL_INFO) {
687         for (i = 0; i < JPEGD_REG_NUM; i++) {
688             mpp_log_f("send reg[%d]=0x%08x\n", i, regs[i]);
689         }
690     }
691 
692     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_WR, &wr_cfg);
693 
694     if (ret) {
695         mpp_err_f("set register write failed %d\n", ret);
696         goto __RETURN;
697     }
698 
699     rd_cfg.reg = regs;
700     rd_cfg.size = reg_size;
701     rd_cfg.offset = 0;
702 
703     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_REG_RD, &rd_cfg);
704 
705     if (ret) {
706         mpp_err_f("set register read failed %d\n", ret);
707         goto __RETURN;
708     }
709 
710     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_SEND, NULL);
711 
712     if (ret) {
713         mpp_err_f("send cmd failed %d\n", ret);
714         goto __RETURN;
715     }
716 
717     jpegd_dbg_func("exit\n");
718     return ret;
719 
720 __RETURN:
721     task->dec.flags.parse_err = 1;
722     jpegd_dbg_func("exit\n");
723     return ret;
724 }
725 
hal_jpegd_rkv_wait(void * hal,HalTaskInfo * task)726 MPP_RET hal_jpegd_rkv_wait(void *hal, HalTaskInfo *task)
727 {
728     MPP_RET ret = MPP_OK;
729     JpegdHalCtx *ctx = (JpegdHalCtx *)hal;
730     JpegRegSet *reg_out = ctx->regs;
731     RK_U32 errinfo = 0;
732     RK_U8 i = 0;
733 
734     jpegd_dbg_func("enter\n");
735     if (task->dec.flags.parse_err)
736         goto __SKIP_HARD;
737 
738     ret = mpp_dev_ioctl(ctx->dev, MPP_DEV_CMD_POLL, NULL);
739 
740     if (ret) {
741         task->dec.flags.parse_err = 1;
742         mpp_err_f("poll cmd failed %d\n", ret);
743     }
744 
745 __SKIP_HARD:
746     if (ctx->dec_cb) {
747         DecCbHalDone param;
748 
749         param.task = (void *)&task->dec;
750         param.regs = (RK_U32 *)reg_out;
751         if (!reg_out->reg1_int.dec_irq || !reg_out->reg1_int.dec_rdy_sta
752             || reg_out->reg1_int.dec_bus_sta || reg_out->reg1_int.dec_error_sta
753             || reg_out->reg1_int.dec_timeout_sta
754             || reg_out->reg1_int.dec_buf_empty_sta) {
755             mpp_err("decode result: failed, irq 0x%08x\n", ((RK_U32 *)reg_out)[1]);
756             errinfo = 1;
757         }
758         param.hard_err = errinfo;
759         mpp_callback(ctx->dec_cb, &param);
760     }
761     if (jpegd_debug & JPEGD_DBG_HAL_INFO) {
762         for (i = 0; i < JPEGD_REG_NUM; i++) {
763             mpp_log_f("read regs[%d]=0x%08x\n", i, ((RK_U32*)reg_out)[i]);
764         }
765     }
766 
767     jpegd_dbg_hal("decode one frame in cycles: %d\n", reg_out->reg39_perf_working_cnt);
768     if (jpegd_debug & JPEGD_DBG_IO) {
769         FILE *jpg_file;
770         char name[32];
771         MppBuffer outputBuf = NULL;
772         void *base = NULL;
773         mpp_buf_slot_get_prop(ctx->frame_slots, task->dec.output, SLOT_BUFFER, &outputBuf);
774         base = mpp_buffer_get_ptr(outputBuf);
775 
776         snprintf(name, sizeof(name) - 1, "/data/tmp/output%02d.yuv", ctx->output_yuv_count);
777         jpg_file = fopen(name, "wb+");
778         if (jpg_file) {
779             JpegdSyntax *s = (JpegdSyntax *) task->dec.syntax.data;
780             RK_U32 width = s->hor_stride;
781             RK_U32 height = s->ver_stride;
782 
783             fwrite(base, width * height * 3, 1, jpg_file);
784             jpegd_dbg_io("frame_%02d output YUV(%d*%d) saving to %s\n", ctx->output_yuv_count,
785                          width, height, name);
786             fclose(jpg_file);
787             ctx->output_yuv_count++;
788         }
789     }
790 
791     memset(&reg_out->reg1_int, 0, sizeof(RK_U32));
792 
793     jpegd_dbg_func("exit\n");
794     return ret;
795 }
796 
hal_jpegd_rkv_control(void * hal,MpiCmd cmd_type,void * param)797 MPP_RET hal_jpegd_rkv_control(void *hal, MpiCmd cmd_type, void *param)
798 {
799     jpegd_dbg_func("enter\n");
800     MPP_RET ret = MPP_OK;
801     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
802 
803     if (NULL == JpegHalCtx) {
804         mpp_err_f("NULL pointer");
805         return MPP_ERR_NULL_PTR;
806     }
807 
808     switch (cmd_type) {
809     case MPP_DEC_SET_OUTPUT_FORMAT: {
810         MppFrameFormat output_fmt = *((MppFrameFormat *)param);
811         RockchipSocType soc_type = mpp_get_soc_type();
812         MppFrameFormat frm_fmt = output_fmt & MPP_FRAME_FMT_MASK;
813 
814         if (MPP_FRAME_FMT_IS_FBC(output_fmt)) {
815             ret = MPP_ERR_VALUE;
816         }
817 
818         if (MPP_FRAME_FMT_IS_TILE(output_fmt)) {
819             if (soc_type < ROCKCHIP_SOC_RK3576 || MPP_FRAME_FMT_IS_RGB(output_fmt)) {
820                 ret = MPP_ERR_VALUE;
821             }
822         }
823 
824         if (MPP_FRAME_FMT_IS_RGB(output_fmt)) {
825             // The new JPEG decoder defaults to no RGB support.
826             if (soc_type >= ROCKCHIP_SOC_RK3576) {
827                 ret = MPP_ERR_VALUE;
828             } else if (soc_type >= ROCKCHIP_SOC_RK3588) {
829                 // only rgb565be and rgb888 supported
830                 if (output_fmt != MPP_FMT_RGB555 && output_fmt != MPP_FMT_RGB888 ) {
831                     ret = MPP_ERR_VALUE;
832                 }
833             } else {
834                 // only bgr565le and rgb 888 supported
835                 if (frm_fmt != (MPP_FMT_BGR565 | MPP_FRAME_FMT_LE_MASK)
836                     && output_fmt != MPP_FMT_RGB888) {
837                     ret = MPP_ERR_VALUE;
838                 }
839             }
840         }
841 
842         if (ret) {
843             mpp_err_f("invalid output format 0x%x\n", output_fmt);
844         } else {
845             JpegHalCtx->output_fmt = output_fmt;
846             JpegHalCtx->set_output_fmt_flag = 1;
847             jpegd_dbg_hal("output_format: 0x%x\n", JpegHalCtx->output_fmt);
848         }
849     } break;
850     //TODO support scale and tile output
851     default :
852         break;
853     }
854 
855     jpegd_dbg_func("exit ret %d\n", ret);
856     return ret;
857 }
858