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