xref: /rockchip-linux_mpp/mpp/hal/vpu/jpegd/hal_jpegd_vdpu1.c (revision 437bfbeb9567cca9cd9080e3f6954aa9d6a94f18)
1 /*
2  *
3  * Copyright 2017 Rockchip Electronics Co. LTD
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #define MODULE_TAG "HAL_JPEGD_VDPU1"
18 
19 #include <stdio.h>
20 #include <string.h>
21 #include <stdint.h>
22 
23 #include "mpp_env.h"
24 #include "mpp_mem.h"
25 #include "mpp_debug.h"
26 #include "mpp_frame.h"
27 #include "mpp_common.h"
28 
29 #include "jpegd_syntax.h"
30 #include "hal_jpegd_common.h"
31 #include "hal_jpegd_vdpu1.h"
32 #include "hal_jpegd_vdpu1_reg.h"
33 #include "mpp_dec_cb_param.h"
34 
35 static void
jpegd_write_code_word_number(JpegdHalCtx * ctx,JpegdSyntax * syntax)36 jpegd_write_code_word_number(JpegdHalCtx *ctx, JpegdSyntax *syntax)
37 {
38     jpegd_dbg_func("enter\n");
39     JpegdSyntax *s = syntax;
40     AcTable *ac_ptr0 = NULL, *ac_ptr1 = NULL;
41     DcTable *dc_ptr0 = NULL, *dc_ptr1 = NULL;
42 
43     JpegdIocRegInfo *info = (JpegdIocRegInfo *)ctx->regs;
44     JpegRegSet *reg = &info->regs;
45 
46     /* first, select the table we'll use.
47      * this trick is done because hardware always wants luma
48      * table as AC hardware table 0.
49      */
50     if (s->ac_index[0] == HUFFMAN_TABLE_ID_ZERO) {
51         /* Luma's AC uses Huffman table zero */
52         ac_ptr0 = &(s->ac_table[HUFFMAN_TABLE_ID_ZERO]);
53         ac_ptr1 = &(s->ac_table[HUFFMAN_TABLE_ID_ONE]);
54     } else {
55         ac_ptr0 = &(s->ac_table[HUFFMAN_TABLE_ID_ONE]);
56         ac_ptr1 = &(s->ac_table[HUFFMAN_TABLE_ID_ZERO]);
57     }
58 
59     /* write AC table 1 (luma) */
60     reg->reg16.sw_ac1_code1_cnt = ac_ptr0->bits[0];
61     reg->reg16.sw_ac1_code2_cnt = ac_ptr0->bits[1];
62     reg->reg16.sw_ac1_code3_cnt = ac_ptr0->bits[2];
63     reg->reg16.sw_ac1_code4_cnt = ac_ptr0->bits[3];
64     reg->reg16.sw_ac1_code5_cnt = ac_ptr0->bits[4];
65     reg->reg16.sw_ac1_code6_cnt = ac_ptr0->bits[5];
66 
67     reg->reg17.sw_ac1_code7_cnt = ac_ptr0->bits[6];
68     reg->reg17.sw_ac1_code8_cnt = ac_ptr0->bits[7];
69     reg->reg17.sw_ac1_code9_cnt = ac_ptr0->bits[8];
70     reg->reg17.sw_ac1_code10_cnt = ac_ptr0->bits[9];
71 
72     reg->reg18.sw_ac1_code11_cnt = ac_ptr0->bits[10];
73     reg->reg18.sw_ac1_code12_cnt = ac_ptr0->bits[11];
74     reg->reg18.sw_ac1_code13_cnt = ac_ptr0->bits[12];
75     reg->reg18.sw_ac1_code14_cnt = ac_ptr0->bits[13];
76 
77     reg->reg19.sw_ac1_code15_cnt = ac_ptr0->bits[14];
78     reg->reg19.sw_ac1_code16_cnt = ac_ptr0->bits[15];
79 
80     /* table AC2 (the not-luma table) */
81     reg->reg19.sw_ac2_code1_cnt = ac_ptr1->bits[0];
82     reg->reg19.sw_ac2_code2_cnt = ac_ptr1->bits[1];
83     reg->reg19.sw_ac2_code3_cnt = ac_ptr1->bits[2];
84     reg->reg19.sw_ac2_code4_cnt = ac_ptr1->bits[3];
85 
86     reg->reg20.sw_ac2_code5_cnt = ac_ptr1->bits[4];
87     reg->reg20.sw_ac2_code6_cnt = ac_ptr1->bits[5];
88     reg->reg20.sw_ac2_code7_cnt = ac_ptr1->bits[6];
89     reg->reg20.sw_ac2_code8_cnt = ac_ptr1->bits[7];
90 
91     reg->reg21.sw_ac2_code9_cnt = ac_ptr1->bits[8];
92     reg->reg21.sw_ac2_code10_cnt = ac_ptr1->bits[9];
93     reg->reg21.sw_ac2_code11_cnt = ac_ptr1->bits[10];
94     reg->reg21.sw_ac2_code12_cnt = ac_ptr1->bits[11];
95 
96     reg->reg22.sw_ac2_code13_cnt = ac_ptr1->bits[12];
97     reg->reg22.sw_ac2_code14_cnt = ac_ptr1->bits[13];
98     reg->reg22.sw_ac2_code15_cnt = ac_ptr1->bits[14];
99     reg->reg22.sw_ac2_code16_cnt = ac_ptr1->bits[15];
100 
101     /* first, select the table we'll use.
102      * this trick is done because hardware always wants luma
103      * table as DC hardware table 0.
104      */
105     if (s->dc_index[0] == HUFFMAN_TABLE_ID_ZERO) {
106         /* Luma's DC uses Huffman table zero */
107         dc_ptr0 = &(s->dc_table[HUFFMAN_TABLE_ID_ZERO]);
108         dc_ptr1 = &(s->dc_table[HUFFMAN_TABLE_ID_ONE]);
109     } else {
110         dc_ptr0 = &(s->dc_table[HUFFMAN_TABLE_ID_ONE]);
111         dc_ptr1 = &(s->dc_table[HUFFMAN_TABLE_ID_ZERO]);
112     }
113 
114     /* write DC table 1 (luma) */
115     reg->reg23.sw_dc1_code1_cnt = dc_ptr0->bits[0];
116     reg->reg23.sw_dc1_code2_cnt = dc_ptr0->bits[1];
117     reg->reg23.sw_dc1_code3_cnt = dc_ptr0->bits[2];
118     reg->reg23.sw_dc1_code4_cnt = dc_ptr0->bits[3];
119     reg->reg23.sw_dc1_code5_cnt = dc_ptr0->bits[4];
120     reg->reg23.sw_dc1_code6_cnt = dc_ptr0->bits[5];
121     reg->reg23.sw_dc1_code7_cnt = dc_ptr0->bits[6];
122     reg->reg23.sw_dc1_code8_cnt = dc_ptr0->bits[7];
123 
124     reg->reg24.sw_dc1_code9_cnt = dc_ptr0->bits[8];
125     reg->reg24.sw_dc1_code10_cnt = dc_ptr0->bits[9];
126     reg->reg24.sw_dc1_code11_cnt = dc_ptr0->bits[10];
127     reg->reg24.sw_dc1_code12_cnt = dc_ptr0->bits[11];
128     reg->reg24.sw_dc1_code13_cnt = dc_ptr0->bits[12];
129     reg->reg24.sw_dc1_code14_cnt = dc_ptr0->bits[13];
130     reg->reg24.sw_dc1_code15_cnt = dc_ptr0->bits[14];
131     reg->reg24.sw_dc1_code16_cnt = dc_ptr0->bits[15];
132 
133     /* table DC2 (the not-luma table) */
134     reg->reg25.sw_dc2_code1_cnt = dc_ptr1->bits[0];
135     reg->reg25.sw_dc2_code2_cnt = dc_ptr1->bits[1];
136     reg->reg25.sw_dc2_code3_cnt = dc_ptr1->bits[2];
137     reg->reg25.sw_dc2_code4_cnt = dc_ptr1->bits[3];
138     reg->reg25.sw_dc2_code5_cnt = dc_ptr1->bits[4];
139     reg->reg25.sw_dc2_code6_cnt = dc_ptr1->bits[5];
140     reg->reg25.sw_dc2_code7_cnt = dc_ptr1->bits[6];
141     reg->reg25.sw_dc2_code8_cnt = dc_ptr1->bits[7];
142 
143     reg->reg26.sw_dc2_code9_cnt = dc_ptr1->bits[8];
144     reg->reg26.sw_dc2_code10_cnt = dc_ptr1->bits[9];
145     reg->reg26.sw_dc2_code11_cnt = dc_ptr1->bits[10];
146     reg->reg26.sw_dc2_code12_cnt = dc_ptr1->bits[11];
147     reg->reg26.sw_dc2_code13_cnt = dc_ptr1->bits[12];
148     reg->reg26.sw_dc2_code14_cnt = dc_ptr1->bits[13];
149     reg->reg26.sw_dc2_code15_cnt = dc_ptr1->bits[14];
150     reg->reg26.sw_dc2_code16_cnt = dc_ptr1->bits[15];
151 
152     jpegd_dbg_func("exit\n");
153     return;
154 }
155 
156 static void
jpegd_set_stream_offset(JpegdHalCtx * ctx,JpegdSyntax * syntax)157 jpegd_set_stream_offset(JpegdHalCtx *ctx, JpegdSyntax *syntax)
158 {
159     jpegd_dbg_func("enter\n");
160     JpegdSyntax *s = syntax;
161     JpegdIocRegInfo *info = (JpegdIocRegInfo *)ctx->regs;
162     JpegRegSet *reg = &info->regs;
163     RK_U32 offset = 0, byte_cnt = 0;
164     RK_U32 bit_pos_in_byte = 0;
165     RK_U32 strm_len_by_hw = 0;
166 
167     /* calculate and set stream start address to hw,
168      * the offset must be 8-byte aligned.
169      */
170     offset = (s->strm_offset & (~7));
171     reg->reg12_input_stream_base = ctx->pkt_fd;
172     if (offset) {
173         mpp_dev_set_reg_offset(ctx->dev, 12, offset);
174     }
175 
176     /* calculate and set stream start bit to hardware
177      * change current pos to bus address style
178      * remove three lowest bits and add the difference to bitPosInWord
179      * used as bit pos in word not as bit pos in byte actually...
180      */
181     byte_cnt = ((uintptr_t) s->cur_pos & (7));
182     bit_pos_in_byte = byte_cnt * 8; /* 1 Byte = 8 bits */
183     reg->reg5.sw_strm0_start_bit = bit_pos_in_byte;
184 
185     /* set up stream length for HW.
186      * length = size of original buffer - stream we already decoded in SW
187      */
188     strm_len_by_hw = s->pkt_len - offset;
189     reg->reg6_stream_info.sw_stream_len = strm_len_by_hw;
190     reg->reg5.sw_jpeg_stream_all = 1;
191 
192     jpegd_dbg_func("exit\n");
193     return;
194 }
195 
196 static void
jpegd_set_chroma_table_id(JpegdHalCtx * ctx,JpegdSyntax * syntax)197 jpegd_set_chroma_table_id(JpegdHalCtx *ctx, JpegdSyntax *syntax)
198 {
199     jpegd_dbg_func("enter\n");
200     JpegdSyntax *s = syntax;
201     JpegdIocRegInfo *info = (JpegdIocRegInfo *)ctx->regs;
202     JpegRegSet *reg = &info->regs;
203 
204     /* this trick is done because hw always wants
205      * luma table as ac hw table 1
206      */
207     if (s->ac_index[0] == HUFFMAN_TABLE_ID_ZERO) {
208         reg->reg5.sw_cb_ac_vlctable = s->ac_index[1];
209         reg->reg5.sw_cr_ac_vlctable = s->ac_index[2];
210     } else {
211         if (s->ac_index[0] == s->ac_index[1])
212             reg->reg5.sw_cb_ac_vlctable = 0;
213         else
214             reg->reg5.sw_cb_ac_vlctable = 1;
215 
216         if (s->ac_index[0] == s->ac_index[2])
217             reg->reg5.sw_cr_ac_vlctable = 0;
218         else
219             reg->reg5.sw_cr_ac_vlctable = 1;
220     }
221 
222     /* Third DC table selectors */
223     if (s->dc_index[0] == HUFFMAN_TABLE_ID_ZERO) {
224         reg->reg5.sw_cb_dc_vlctable = s->dc_index[1];
225         reg->reg5.sw_cr_dc_vlctable = s->dc_index[2];
226     } else {
227         if (s->dc_index[0] == s->dc_index[1])
228             reg->reg5.sw_cb_dc_vlctable = 0;
229         else
230             reg->reg5.sw_cb_dc_vlctable = 1;
231 
232         if (s->dc_index[0] == s->dc_index[2])
233             reg->reg5.sw_cr_dc_vlctable = 0;
234         else
235             reg->reg5.sw_cr_dc_vlctable = 1;
236     }
237 
238     reg->reg5.sw_cr_dc_vlctable3 = 0;
239     reg->reg5.sw_cb_dc_vlctable3 = 0;
240 
241     jpegd_dbg_func("exit\n");
242     return;
243 }
244 
jpegd_setup_pp(JpegdHalCtx * ctx,JpegdSyntax * syntax)245 static MPP_RET jpegd_setup_pp(JpegdHalCtx *ctx, JpegdSyntax *syntax)
246 {
247     jpegd_dbg_func("enter\n");
248     JpegdIocRegInfo *info = (JpegdIocRegInfo *)ctx->regs;
249     JpegRegSet *regs = &info->regs;
250     post_processor_reg *post = &regs->post;
251     JpegdSyntax *s = syntax;
252 
253     RK_U32 in_color = ctx->pp_info.pp_in_fmt;
254     RK_U32 out_color = ctx->pp_info.pp_out_fmt;
255     RK_U32 dither = ctx->pp_info.dither_enable;
256     RK_U32 crop_width = ctx->pp_info.crop_width;
257     RK_U32 crop_height = ctx->pp_info.crop_height;
258     RK_U32 crop_x = ctx->pp_info.crop_x;
259     RK_U32 crop_y = ctx->pp_info.crop_y;
260     RK_U32 in_width = s->hor_stride;
261     RK_U32 in_height = s->ver_stride;
262     RK_U32 out_width = s->hor_stride;
263     RK_U32 out_height = s->ver_stride;
264     RK_U32 uv_offset = s->hor_stride * s->ver_stride;
265 
266     int video_range = 1;
267 
268     post->reg61_dev_conf.sw_pp_axi_rd_id = 0;
269     post->reg61_dev_conf.sw_pp_axi_wr_id = 0;
270     post->reg61_dev_conf.sw_pp_scmd_dis = 1;
271     post->reg61_dev_conf.sw_pp_max_burst = 16;
272     post->reg61_dev_conf.sw_pp_in_a2_endsel = 1;
273     post->reg61_dev_conf.sw_pp_in_a1_swap32 = 1;
274     post->reg61_dev_conf.sw_pp_in_a1_endian = 1;
275     post->reg61_dev_conf.sw_pp_in_swap32_e = 1;
276     post->reg61_dev_conf.sw_pp_in_endian = 1;
277     post->reg61_dev_conf.sw_pp_out_endian = 1;
278     post->reg61_dev_conf.sw_pp_out_swap32_e = 1;
279 
280     post->reg63_pp_in_lu_base = 0;
281 
282     post->reg88_mask_1_size.sw_ext_orig_width = in_width >> 4;
283 
284     post->reg61_dev_conf.sw_pp_clk_gate_e = 0;
285     post->reg61_dev_conf.sw_pp_ahb_hlock_e = 1;
286     post->reg61_dev_conf.sw_pp_data_disc_e = 1;
287 
288     if (crop_width <= 0) {
289         post->reg92_display.sw_pp_in_w_ext = (((in_width / 16) & 0xE00) >> 9);
290         post->reg72_crop.sw_pp_in_width = ((in_width / 16) & 0x1FF);
291         post->reg92_display.sw_pp_in_h_ext = (((in_height / 16) & 0x700) >> 8);
292         post->reg72_crop.sw_pp_in_height = ((in_height / 16) & 0x0FF);
293     } else {
294         post->reg92_display.sw_pp_in_w_ext =
295             (((crop_width / 16) & 0xE00) >> 9);
296         post->reg72_crop.sw_pp_in_width = ((crop_width / 16) & 0x1FF);
297         post->reg92_display.sw_pp_in_h_ext =
298             (((crop_height / 16) & 0x700) >> 8);
299         post->reg72_crop.sw_pp_in_height = ((crop_height / 16) & 0x0FF);
300 
301         post->reg92_display.sw_crop_startx_ext =
302             (((crop_x / 16) & 0xE00) >> 9);
303         post->reg71_color_coeff_1.sw_crop_startx =
304             ((crop_x / 16) & 0x1FF);
305         post->reg92_display.sw_crop_starty_ext =
306             (((crop_y / 16) & 0x700) >> 8);
307         post->reg72_crop.sw_crop_starty =
308             ((crop_y / 16) & 0x0FF);
309 
310         if (crop_width & 0x0F) {
311             post->reg85_ctrl.sw_pp_crop8_r_e = 1;
312         } else {
313             post->reg85_ctrl.sw_pp_crop8_r_e = 0;
314         }
315         if (crop_height & 0x0F) {
316             post->reg85_ctrl.sw_pp_crop8_d_e = 1;
317         } else {
318             post->reg85_ctrl.sw_pp_crop8_d_e = 0;
319         }
320         in_width = crop_width;
321         in_height = crop_height;
322     }
323 
324     post->reg92_display.sw_display_width = out_width;
325     post->reg85_ctrl.sw_pp_out_width = out_width;
326     post->reg85_ctrl.sw_pp_out_height = out_height;
327     post->reg66_pp_out_lu_base = ctx->frame_fd;
328 
329     switch (in_color) {
330     case    PP_IN_FORMAT_YUV422INTERLAVE:
331     case    PP_IN_FORMAT_YUV420SEMI:
332     case    PP_IN_FORMAT_YUV420PLANAR:
333     case    PP_IN_FORMAT_YUV400:
334     case    PP_IN_FORMAT_YUV422SEMI:
335     case    PP_IN_FORMAT_YUV420SEMITIELED:
336     case    PP_IN_FORMAT_YUV440SEMI:
337         post->reg85_ctrl.sw_pp_in_format = in_color;
338         break;
339     case    PP_IN_FORMAT_YUV444_SEMI:
340         post->reg85_ctrl.sw_pp_in_format = 7;
341         post->reg86_mask_1.sw_pp_in_format_es = 0;
342         break;
343     case    PP_IN_FORMAT_YUV411_SEMI:
344         post->reg85_ctrl.sw_pp_in_format = 0;
345         post->reg86_mask_1.sw_pp_in_format_es = 1;
346         break;
347     default:
348         mpp_err_f("unsupported format:%d", in_color);
349         return -1;
350     }
351 
352     post->reg72_crop.sw_rangemap_coef_y = 9;
353     post->reg86_mask_1.sw_rangemap_coef_c = 9;
354     /*  brightness */
355     post->reg71_color_coeff_1.sw_color_coefff = BRIGHTNESS;
356 
357     if (out_color <= PP_OUT_FORMAT_ARGB) {
358         /*Bt.601*/
359         unsigned int    a = 298;
360         unsigned int    b = 409;
361         unsigned int    c = 208;
362         unsigned int    d = 100;
363         unsigned int    e = 516;
364 
365         /*Bt.709
366         unsigned int    a = 298;
367         unsigned int    b = 459;
368         unsigned int    c = 137;
369         unsigned int    d = 55;
370         unsigned int    e = 544;*/
371 
372         int satur = 0, tmp;
373         if (video_range != 0) {
374             /*Bt.601*/
375             a = 256;
376             b = 350;
377             c = 179;
378             d = 86;
379             e = 443;
380             /*Bt.709
381             a = 256;
382             b = 403;
383             c = 120;
384             d = 48;
385             e = 475;*/
386 
387             post->reg79_scaling_0.sw_ycbcr_range = video_range;
388         }
389         int contrast = CONTRAST;
390         if (contrast != 0) {
391             int thr1y, thr2y, off1, off2, thr1, thr2, a1, a2;
392             if (video_range == 0) {
393                 int tmp1, tmp2;
394                 /* Contrast */
395                 thr1 = (219 * (contrast + 128)) / 512;
396                 thr1y = (219 - 2 * thr1) / 2;
397                 thr2 = 219 - thr1;
398                 thr2y = 219 - thr1y;
399 
400                 tmp1 = (thr1y * 256) / thr1;
401                 tmp2 = ((thr2y - thr1y) * 256) / (thr2 - thr1);
402                 off1 = ((thr1y - ((tmp2 * thr1) / 256)) * a) / 256;
403                 off2 = ((thr2y - ((tmp1 * thr2) / 256)) * a) / 256;
404 
405                 tmp1 = (64 * (contrast + 128)) / 128;
406                 tmp2 = 256 * (128 - tmp1);
407                 a1 = (tmp2 + off2) / thr1;
408                 a2 = a1 + (256 * (off2 - 1)) / (thr2 - thr1);
409             } else {
410                 /* Contrast */
411                 thr1 = (64 * (contrast + 128)) / 128;
412                 thr1y = 128 - thr1;
413                 thr2 = 256 - thr1;
414                 thr2y = 256 - thr1y;
415                 a1 = (thr1y * 256) / thr1;
416                 a2 = ((thr2y - thr1y) * 256) / (thr2 - thr1);
417                 off1 = thr1y - (a2 * thr1) / 256;
418                 off2 = thr2y - (a1 * thr2) / 256;
419             }
420 
421             if (a1 > 1023)
422                 a1 = 1023;
423             else if (a1 < 0)
424                 a1 = 0;
425 
426             if (a2 > 1023)
427                 a2 = 1023;
428             else if (a2 < 0)
429                 a2 = 0;
430 
431             if (thr1 > 255)
432                 thr1 = 255;
433             else if (thr1 < 0)
434                 thr1 = 0;
435 
436             if (thr2 > 255)
437                 thr2 = 255;
438             else if (thr2 < 0)
439                 thr2 = 0;
440 
441             if (off1 > 511)
442                 off1 = 511;
443             else if (off1 < -512)
444                 off1 = -512;
445 
446             if (off2 > 511)
447                 off2 = 511;
448             else if (off2 < -512)
449                 off2 = -512;
450 
451             post->reg68_contrast_adjust.sw_contrast_thr1 = thr1;
452             post->reg69.sw_contrast_thr2 = thr2;
453             post->reg68_contrast_adjust.sw_contrast_off1 = off1;
454             post->reg68_contrast_adjust.sw_contrast_off2 = off2;
455 
456             post->reg69.sw_color_coeffa1 = a1;
457             post->reg69.sw_color_coeffa2 = a2;
458         } else {
459             post->reg68_contrast_adjust.sw_contrast_thr1 = 55;
460             post->reg69.sw_contrast_thr2 = 165;
461             post->reg68_contrast_adjust.sw_contrast_off1 = 0;
462             post->reg68_contrast_adjust.sw_contrast_off2 = 0;
463 
464             tmp = a;
465             if (tmp > 1023)
466                 tmp = 1023;
467             else if (tmp < 0)
468                 tmp = 0;
469 
470             post->reg69.sw_color_coeffa1 = tmp;
471             post->reg69.sw_color_coeffa2 = tmp;
472         }
473 
474         /* saturation */
475         satur = 64 + SATURATION;
476 
477         tmp = (satur * (int) b) / 64;
478         if (tmp > 1023)
479             tmp = 1023;
480         else if (tmp < 0)
481             tmp = 0;
482         post->reg70_color_coeff_0.sw_color_coeffb = (unsigned int) tmp;
483 
484         tmp = (satur * (int) c) / 64;
485         if (tmp > 1023)
486             tmp = 1023;
487         else if (tmp < 0)
488             tmp = 0;
489         post->reg70_color_coeff_0.sw_color_coeffc = (unsigned int) tmp;
490 
491         tmp = (satur * (int) d) / 64;
492         if (tmp > 1023)
493             tmp = 1023;
494         else if (tmp < 0)
495             tmp = 0;
496         post->reg70_color_coeff_0.sw_color_coeffd = (unsigned int) tmp;
497 
498         tmp = (satur * (int) e) / 64;
499         if (tmp > 1023)
500             tmp = 1023;
501         else if (tmp < 0)
502             tmp = 0;
503         post->reg71_color_coeff_1.sw_color_coeffe = (unsigned int) tmp;
504     }
505 
506     if (out_color <= PP_OUT_FORMAT_ARGB) {
507         PpRgbCfg *cfg = get_pp_rgb_Cfg(ctx->output_fmt);
508         post->reg82_r_mask = cfg->r_mask;
509         post->reg83_g_mask = cfg->g_mask;
510         post->reg84_b_mask = cfg->b_mask;
511         post->reg79_scaling_0.sw_rgb_r_padd = cfg->r_padd;
512         post->reg79_scaling_0.sw_rgb_g_padd = cfg->g_padd;
513         post->reg80_scaling_1.sw_rgb_b_padd = cfg->b_padd;
514 
515         if (dither) {
516             jpegd_dbg_hal("we do dither.");
517             post->reg91_pip_2.sw_dither_select_r = cfg->r_dither;
518             post->reg91_pip_2.sw_dither_select_r = cfg->g_dither;
519             post->reg91_pip_2.sw_dither_select_r = cfg->b_dither;
520         } else {
521             jpegd_dbg_hal("we do not dither.");
522         }
523 
524         post->reg79_scaling_0.sw_rgb_pix_in32 = cfg->rgb_in_32;
525         post->reg85_ctrl.sw_pp_out_swap16_e = cfg->swap_16;
526         post->reg61_dev_conf.sw_pp_out_swap32_e = cfg->swap_32;
527         post->reg61_dev_conf.sw_pp_out_endian = cfg->out_endian;
528 
529         post->reg85_ctrl.sw_pp_out_format = 0;
530 
531     } else if (out_color == PP_OUT_FORMAT_YUV422INTERLAVE) {
532         post->reg85_ctrl.sw_pp_out_format = 3;
533     } else if (out_color == PP_OUT_FORMAT_YUV420INTERLAVE) {
534         post->reg85_ctrl.sw_pp_out_format = 5;
535     } else {
536         mpp_err_f("unsuppotred format:%d", out_color);
537         return -1;
538     }
539 
540     post->reg71_color_coeff_1.sw_rotation_mode = 0;
541 
542     unsigned int inw, inh;
543     unsigned int outw, outh;
544 
545     inw = in_width - 1;
546     inh = in_height - 1;
547     outw = out_width - 1;
548     outh = out_height - 1;
549 
550     if (inw < outw) {
551         post->reg80_scaling_1.sw_hor_scale_mode = 1;
552         post->reg79_scaling_0.sw_scale_wratio = (outw << 16) / inw;
553         post->reg81_scaling_2.sw_wscale_invra = (inw << 16) / outw;
554     } else if (inw > outw) {
555         post->reg80_scaling_1.sw_hor_scale_mode = 2;
556         post->reg81_scaling_2.sw_wscale_invra = ((outw + 1) << 16) / (inw + 1);
557     } else
558         post->reg80_scaling_1.sw_hor_scale_mode = 0;
559 
560     if (inh < outh) {
561         post->reg80_scaling_1.sw_ver_scale_mode = 1;
562         post->reg80_scaling_1.sw_scale_hratio = (outh << 16) / inh;
563         post->reg81_scaling_2.sw_hscale_invra = (inh << 16) / outh;
564     } else if (inh > outh) {
565         post->reg80_scaling_1.sw_ver_scale_mode = 2;
566         post->reg81_scaling_2.sw_hscale_invra =
567             ((outh + 1) << 16) / (inh + 1) + 1;
568     } else
569         post->reg80_scaling_1.sw_ver_scale_mode = 0;
570 
571     post->reg60_interrupt.sw_pp_pipeline_e = ctx->pp_info.pp_enable;
572 
573     if (ctx->pp_info.pp_enable) {
574         post->reg60_interrupt.sw_pp_pipeline_e = 1;
575         regs->reg3.sw_dec_out_dis = 1;
576 
577         regs->reg13_cur_pic_base = 0;
578         regs->reg14_sw_jpg_ch_out_base = 0;
579 
580         post->reg66_pp_out_lu_base = ctx->frame_fd;
581         post->reg67_pp_out_ch_base = ctx->frame_fd;
582 
583         if (uv_offset)
584             mpp_dev_set_reg_offset(ctx->dev, 67, uv_offset);
585 
586         jpegd_dbg_hal("output_frame_fd:%x, reg67:%x", ctx->frame_fd,
587                       post->reg67_pp_out_ch_base);
588     } else {
589         // output without pp
590         post->reg60_interrupt.sw_pp_pipeline_e = 0;
591         regs->reg3.sw_dec_out_dis = 0;
592 
593         post->reg66_pp_out_lu_base = 0;
594         post->reg67_pp_out_ch_base = 0;
595 
596         regs->reg13_cur_pic_base = ctx->frame_fd;
597         regs->reg14_sw_jpg_ch_out_base = ctx->frame_fd;
598 
599         if (uv_offset)
600             mpp_dev_set_reg_offset(ctx->dev, 14, uv_offset);
601 
602         jpegd_dbg_hal("output_frame_fd:%x, reg14:%x", ctx->frame_fd,
603                       regs->reg14_sw_jpg_ch_out_base);
604     }
605 
606     jpegd_dbg_func("exit\n");
607     return 0;
608 }
609 
jpegd_regs_init(JpegRegSet * reg)610 static MPP_RET jpegd_regs_init(JpegRegSet *reg)
611 {
612     jpegd_dbg_func("enter\n");
613     memset(reg, 0, sizeof(JpegRegSet));
614     reg->reg2_dec_ctrl.sw_dec_out_tiled_e = 0;
615     reg->reg2_dec_ctrl.sw_dec_scmd_dis = DEC_VDPU1_SCMD_DISABLE;
616     reg->reg2_dec_ctrl.sw_dec_latency = DEC_VDPU1_LATENCY_COMPENSATION;
617 
618     reg->reg2_dec_ctrl.sw_dec_in_endian = DEC_VDPU1_BIG_ENDIAN;
619     reg->reg2_dec_ctrl.sw_dec_out_endian = DEC_VDPU1_LITTLE_ENDIAN;
620     reg->reg2_dec_ctrl.sw_dec_strendian_e = DEC_VDPU1_LITTLE_ENDIAN;
621     reg->reg2_dec_ctrl.sw_dec_outswap32_e = DEC_VDPU1_LITTLE_ENDIAN;
622     reg->reg2_dec_ctrl.sw_dec_inswap32_e = 1;
623     reg->reg2_dec_ctrl.sw_dec_strswap32_e = 1;
624 
625     reg->reg1_interrupt.sw_dec_irq_dis = 0;
626 
627     reg->reg2_dec_ctrl.sw_dec_axi_rn_id = 0xff;
628     reg->reg3.sw_dec_axi_wr_id = 0;
629     reg->reg2_dec_ctrl.sw_dec_max_burst = DEC_VDPU1_BUS_BURST_LENGTH_16;
630     reg->reg2_dec_ctrl.sw_dec_data_disc_e = DEC_VDPU1_DATA_DISCARD_ENABLE;
631 
632     reg->reg2_dec_ctrl.sw_dec_timeout_e = 1;
633     reg->reg2_dec_ctrl.sw_dec_clk_gate_e = 1;
634 
635     jpegd_dbg_func("exit\n");
636     return MPP_OK;
637 }
638 
jpegd_gen_regs(JpegdHalCtx * ctx,JpegdSyntax * syntax)639 static MPP_RET jpegd_gen_regs(JpegdHalCtx *ctx, JpegdSyntax *syntax)
640 {
641     jpegd_dbg_func("enter\n");
642     JpegdIocRegInfo *info = (JpegdIocRegInfo *)ctx->regs;
643     JpegRegSet *reg = &info->regs;
644     JpegdSyntax *s = syntax;
645 
646     jpegd_regs_init(reg);
647 
648     /* Enable jpeg mode */
649     reg->reg1_interrupt.sw_dec_e = 1;
650 
651     reg->reg3.sw_filtering_dis = 1;
652 
653     /* JPEG decoder */
654     reg->reg3.sw_dec_mode = 3;
655     reg->reg3.sw_pjpeg_e = 0;  /* Set JPEG operation mode */
656     reg->reg3.sw_dec_out_dis = 0;
657     reg->reg3.sw_rlc_mode_e = 0;
658 
659     /* frame size, round up the number of mbs */
660     reg->reg4.sw_pic_mb_h_ext = ((((s->ver_stride) >> (4)) & 0x700) >> 8);
661     reg->reg4.sw_pic_mb_w_ext = ((((s->hor_stride) >> (4)) & 0xE00) >> 9);
662     reg->reg4.sw_pic_mb_width = ((s->hor_stride) >> (4)) & 0x1FF;
663     reg->reg4.sw_pic_mb_height_p = ((s->ver_stride) >> (4)) & 0x0FF;
664 
665     reg->reg7.sw_pjpeg_fildown_e = s->fill_bottom;
666     /* Set spectral selection start coefficient */
667     reg->reg7.sw_pjpeg_ss = s->scan_start;
668     /* Set spectral selection end coefficient */
669     reg->reg7.sw_pjpeg_se = s->scan_end;
670     /* Set the point transform used in the preceding scan */
671     reg->reg7.sw_pjpeg_ah = s->prev_shift;
672     /* Set the point transform value */
673     reg->reg7.sw_pjpeg_al = s->point_transform;
674 
675     reg->reg5.sw_jpeg_qtables = s->qtable_cnt;
676     reg->reg5.sw_jpeg_mode = s->yuv_mode;
677     reg->reg5.sw_jpeg_filright_e = s->fill_right;
678 
679     reg->reg15.sw_jpeg_slice_h = 0;
680     /*
681      * Set bit 21 of reg148 to 1, notifying hardware to decode
682      * jpeg including DRI segment
683      */
684     reg->reg5.sw_sync_marker_e = 1;
685 
686     /* tell hardware that height is 8-pixel aligned, but not 16-pixel aligned */
687     if ((s->height % 16) && ((s->height % 16) <= 8) &&
688         (s->yuv_mode == JPEGDEC_YUV422 ||
689          s->yuv_mode == JPEGDEC_YUV444 ||
690          s->yuv_mode == JPEGDEC_YUV411)) {
691         reg->reg15.sw_jpeg_height8_flag = 1;
692     }
693 
694     /* write VLC code word number to register */
695     jpegd_write_code_word_number(ctx, s);
696 
697     /* Create AC/DC/QP tables for hardware */
698     jpegd_write_qp_ac_dc_table(ctx, s);
699 
700     /* Select which tables the chromas use */
701     jpegd_set_chroma_table_id(ctx, s);
702 
703     /* write table base */
704     reg->reg40_qtable_base = mpp_buffer_get_fd(ctx->pTableBase);
705     if (reg->reg40_qtable_base <= 0) {
706         mpp_err_f("get qtable_base failed\n");
707         return MPP_NOK;
708     }
709 
710     /* set up stream position for HW decode */
711     jpegd_set_stream_offset(ctx, s);
712 
713     /* set restart interval */
714     if (s->restart_interval) {
715         reg->reg5.sw_sync_marker_e = 1;
716         /*
717          * If exists DRI segment, bit 0 to bit 15 of reg8
718          * is set to restart interval
719          */
720         reg->reg8.sw_pjpeg_rest_freq = s->restart_interval;
721     } else {
722         reg->reg5.sw_sync_marker_e = 0;
723     }
724 
725     jpegd_setup_pp(ctx, syntax);
726 
727     jpegd_dbg_func("exit\n");
728     return MPP_OK;
729 }
730 
hal_jpegd_vdpu1_init(void * hal,MppHalCfg * cfg)731 MPP_RET hal_jpegd_vdpu1_init(void *hal, MppHalCfg *cfg)
732 {
733     MPP_RET ret = MPP_OK;
734     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
735 
736     mpp_assert(JpegHalCtx);
737     jpegd_dbg_func("enter\n");
738 
739     //configure
740     JpegHalCtx->dec_cb       = cfg->dec_cb;
741     JpegHalCtx->packet_slots = cfg->packet_slots;
742     JpegHalCtx->frame_slots  = cfg->frame_slots;
743     JpegHalCtx->have_pp      = cfg->hw_info->cap_jpg_pp_out;
744 
745     /* allocate regs buffer */
746     if (JpegHalCtx->regs == NULL) {
747         JpegHalCtx->regs = mpp_calloc_size(void, sizeof(JpegdIocRegInfo));
748         if (JpegHalCtx->regs == NULL) {
749             mpp_err("hal jpegd reg alloc failed\n");
750 
751             jpegd_dbg_func("exit\n");
752             return MPP_ERR_NOMEM;
753         }
754     }
755     JpegdIocRegInfo *info = (JpegdIocRegInfo *)JpegHalCtx->regs;
756     memset(info, 0, sizeof(JpegdIocRegInfo));
757 
758     //malloc hw buf
759     if (JpegHalCtx->group == NULL) {
760         ret = mpp_buffer_group_get_internal(&JpegHalCtx->group,
761                                             MPP_BUFFER_TYPE_ION);
762         if (ret) {
763             mpp_err_f("mpp_buffer_group_get failed ret %d\n", ret);
764             return ret;
765         }
766     }
767 
768     ret = mpp_buffer_get(JpegHalCtx->group, &JpegHalCtx->pTableBase,
769                          JPEGD_BASELINE_TABLE_SIZE);
770     if (ret) {
771         mpp_err_f("get table buffer failed ret %d\n", ret);
772         return ret;
773     }
774 
775     PPInfo *pp_info = &(JpegHalCtx->pp_info);
776     memset(pp_info, 0, sizeof(PPInfo));
777     pp_info->pp_enable = 0;
778     pp_info->pp_in_fmt = PP_IN_FORMAT_YUV420SEMI;
779     pp_info->pp_out_fmt = PP_OUT_FORMAT_YUV420INTERLAVE;
780 
781     JpegHalCtx->output_fmt = MPP_FMT_YUV420SP;
782     JpegHalCtx->set_output_fmt_flag = 0;
783 
784     /* init dbg stuff */
785     JpegHalCtx->hal_debug_enable = 0;
786     JpegHalCtx->frame_count = 0;
787     JpegHalCtx->output_yuv_count = 0;
788 
789     jpegd_dbg_func("exit\n");
790     return MPP_OK;
791 }
792 
hal_jpegd_vdpu1_deinit(void * hal)793 MPP_RET hal_jpegd_vdpu1_deinit(void *hal)
794 {
795     MPP_RET ret = MPP_OK;
796     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
797 
798     jpegd_dbg_func("enter\n");
799 
800     if (JpegHalCtx->dev) {
801         mpp_dev_deinit(JpegHalCtx->dev);
802         JpegHalCtx->dev = NULL;
803     }
804 
805     if (JpegHalCtx->pTableBase) {
806         ret = mpp_buffer_put(JpegHalCtx->pTableBase);
807         if (ret) {
808             mpp_err_f("put buffer failed\n");
809             return ret;
810         }
811     }
812 
813     if (JpegHalCtx->group) {
814         ret = mpp_buffer_group_put(JpegHalCtx->group);
815         if (ret) {
816             mpp_err_f("group free buffer failed\n");
817             return ret;
818         }
819     }
820 
821     if (JpegHalCtx->regs) {
822         mpp_free(JpegHalCtx->regs);
823         JpegHalCtx->regs = NULL;
824     }
825 
826     JpegHalCtx->output_fmt = MPP_FMT_YUV420SP;
827     JpegHalCtx->set_output_fmt_flag = 0;
828     JpegHalCtx->hal_debug_enable = 0;
829     JpegHalCtx->frame_count = 0;
830     JpegHalCtx->output_yuv_count = 0;
831 
832     jpegd_dbg_func("exit\n");
833     return MPP_OK;
834 }
835 
hal_jpegd_vdpu1_gen_regs(void * hal,HalTaskInfo * syn)836 MPP_RET hal_jpegd_vdpu1_gen_regs(void *hal,  HalTaskInfo *syn)
837 {
838     jpegd_dbg_func("enter\n");
839     if (NULL == hal || NULL == syn) {
840         mpp_err_f("NULL pointer");
841         return MPP_ERR_NULL_PTR;
842     }
843 
844     MPP_RET ret = MPP_OK;
845     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
846     JpegdSyntax *syntax = (JpegdSyntax *)syn->dec.syntax.data;
847     MppBuffer streambuf = NULL;
848     MppBuffer outputBuf = NULL;
849 
850     if (syn->dec.flags.parse_err)
851         goto RET;
852 
853     ret = jpeg_image_check_size(syntax->hor_stride, syntax->ver_stride);
854     if (ret)
855         goto RET;
856 
857     if (syn->dec.valid) {
858         jpegd_setup_output_fmt(JpegHalCtx, syntax, syn->dec.output);
859         if (ret) {
860             mpp_err_f("setup output format %x failed\n", syntax->output_fmt);
861             goto RET;
862         }
863 
864         /* input stream address */
865         mpp_buf_slot_get_prop(JpegHalCtx->packet_slots, syn->dec.input,
866                               SLOT_BUFFER, &streambuf);
867         JpegHalCtx->pkt_fd = mpp_buffer_get_fd(streambuf);
868         if (JpegHalCtx->pkt_fd <= 0) {
869             mpp_err_f("get pkt_fd failed\n");
870             goto RET;
871         }
872 
873         syntax->pkt_len = jpegd_vdpu_tail_0xFF_patch(streambuf, syntax->pkt_len);
874 
875         /* output picture address */
876         mpp_buf_slot_get_prop(JpegHalCtx->frame_slots, syn->dec.output,
877                               SLOT_BUFFER, &outputBuf);
878         JpegHalCtx->frame_fd = mpp_buffer_get_fd(outputBuf);
879         if (JpegHalCtx->frame_fd <= 0) {
880             mpp_err_f("get frame_fd failed\n");
881             goto RET;
882         }
883 
884         ret = jpegd_gen_regs(JpegHalCtx, syntax);
885         mpp_buffer_sync_end(streambuf);
886         mpp_buffer_sync_end(JpegHalCtx->pTableBase);
887         if (ret != MPP_OK) {
888             mpp_err_f("generate registers failed\n");
889             goto RET;
890         }
891     }
892 
893 
894     jpegd_dbg_func("exit\n");
895     return ret;
896 
897 RET:
898     syn->dec.valid = 0;
899     syn->dec.flags.parse_err = 1;
900     jpegd_dbg_func("exit\n");
901 
902     return ret;
903 }
904 
hal_jpegd_vdpu1_start(void * hal,HalTaskInfo * task)905 MPP_RET hal_jpegd_vdpu1_start(void *hal, HalTaskInfo *task)
906 {
907     MPP_RET ret = MPP_OK;
908     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
909     RK_U32 *regs = (RK_U32 *)JpegHalCtx->regs;
910 
911     jpegd_dbg_func("enter\n");
912     if (task->dec.flags.parse_err)
913         goto __RETURN;
914 
915     do {
916         MppDevRegWrCfg wr_cfg;
917         MppDevRegRdCfg rd_cfg;
918         MppIoctlVersion ioctl_version = mpp_get_ioctl_version();
919         RK_U32 reg_size = ioctl_version ?
920                           sizeof(((JpegdIocRegInfo *)0)->regs) :
921                           sizeof(JpegdIocRegInfo) - EXTRA_INFO_SIZE;
922 
923         if (ROCKCHIP_SOC_RK3036 == mpp_get_soc_type() &&
924             IOCTL_VCODEC_SERVICE == ioctl_version)
925             reg_size -= sizeof(((JpegdIocRegInfo *)0)->regs_diff);
926 
927         wr_cfg.reg = regs;
928         wr_cfg.size = reg_size;
929         wr_cfg.offset = 0;
930 
931         ret = mpp_dev_ioctl(JpegHalCtx->dev, MPP_DEV_REG_WR, &wr_cfg);
932         if (ret) {
933             mpp_err_f("set register write failed %d\n", ret);
934             goto __RETURN;
935         }
936 
937         reg_size = sizeof(((JpegdIocRegInfo *)0)->regs);
938 
939         rd_cfg.reg = regs;
940         rd_cfg.size = reg_size;
941         rd_cfg.offset = 0;
942 
943         ret = mpp_dev_ioctl(JpegHalCtx->dev, MPP_DEV_REG_RD, &rd_cfg);
944         if (ret) {
945             mpp_err_f("set register read failed %d\n", ret);
946             goto __RETURN;
947         }
948 
949         ret = mpp_dev_ioctl(JpegHalCtx->dev, MPP_DEV_CMD_SEND, NULL);
950         if (ret) {
951             mpp_err_f("send cmd failed %d\n", ret);
952             goto __RETURN;
953         }
954     } while (0);
955 
956     jpegd_dbg_func("exit\n");
957     return ret;
958 
959 __RETURN:
960     task->dec.flags.parse_err = 1;
961 
962     jpegd_dbg_func("exit\n");
963     return ret;
964 }
965 
hal_jpegd_vdpu1_wait(void * hal,HalTaskInfo * task)966 MPP_RET hal_jpegd_vdpu1_wait(void *hal, HalTaskInfo *task)
967 {
968     MPP_RET ret = MPP_OK;
969     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
970     JpegRegSet *reg_out = JpegHalCtx->regs;
971     RK_U32 errinfo = 1;
972 
973     jpegd_dbg_func("enter\n");
974     if (task->dec.flags.parse_err)
975         goto __SKIP_HARD;
976 
977     ret = mpp_dev_ioctl(JpegHalCtx->dev, MPP_DEV_CMD_POLL, NULL);
978     if (ret) {
979         task->dec.flags.parse_err = 1;
980         mpp_err_f("poll cmd failed %d\n", ret);
981     }
982 
983 __SKIP_HARD:
984     if (JpegHalCtx->dec_cb) {
985         DecCbHalDone param;
986 
987         param.task = (void *)&task->dec;
988         param.regs = (RK_U32 *)reg_out;
989         if (reg_out->reg1_interrupt.sw_dec_bus_int) {
990             mpp_err_f("IRQ BUS ERROR!");
991         } else if (reg_out->reg1_interrupt.sw_dec_error_int) {
992             /*
993             * NOTE: It is a bug of VDPU1, when sample color is YUV422,
994             * YUV444, YUV411, the height could be aligned with 8 but not 16
995             */
996             if (JpegHalCtx->output_fmt != MPP_FMT_YUV420SP)
997                 ret = MPP_OK;
998             else
999                 mpp_err_f("IRQ STREAM ERROR! %d", JpegHalCtx->output_fmt);
1000         } else if (reg_out->reg1_interrupt.sw_dec_timeout) {
1001             mpp_err_f("IRQ TIMEOUT!");
1002         } else if (reg_out->reg1_interrupt.sw_dec_buffer_int) {
1003             mpp_err_f("IRQ BUFFER EMPTY!");
1004         } else if (reg_out->reg1_interrupt.sw_dec_irq) {
1005             errinfo = 0;
1006             jpegd_dbg_hal("DECODE SUCCESS!");
1007         }
1008         param.hard_err = errinfo;
1009         mpp_callback(JpegHalCtx->dec_cb, &param);
1010     }
1011 
1012     /* debug information */
1013     if (jpegd_debug & JPEGD_DBG_IO) {
1014         static FILE *jpg_file;
1015         static char name[64];
1016         MppBuffer outputBuf = NULL;
1017         void *base = NULL;
1018         mpp_buf_slot_get_prop(JpegHalCtx->frame_slots, task->dec.output,
1019                               SLOT_BUFFER, &outputBuf);
1020         base = mpp_buffer_get_ptr(outputBuf);
1021 
1022         snprintf(name, sizeof(name) - 1, "/data/tmp/output%02d.yuv",
1023                  JpegHalCtx->output_yuv_count);
1024         jpg_file = fopen(name, "wb+");
1025         if (jpg_file) {
1026             JpegdSyntax *s = (JpegdSyntax *)task->dec.syntax.data;
1027             RK_U32 width = s->hor_stride;
1028             RK_U32 height = s->ver_stride;
1029 
1030             fwrite(base, width * height * 3 / 2, 1, jpg_file);
1031             jpegd_dbg_io("frame_%02d output YUV(%d*%d) saving to %s\n",
1032                          JpegHalCtx->output_yuv_count,
1033                          width, height, name);
1034 
1035             fclose(jpg_file);
1036             JpegHalCtx->output_yuv_count++;
1037         }
1038     }
1039 
1040     memset(&reg_out->reg1_interrupt, 0, sizeof(RK_U32));
1041     jpegd_dbg_func("exit\n");
1042 
1043     return ret;
1044 }
1045 
hal_jpegd_vdpu1_control(void * hal,MpiCmd cmd_type,void * param)1046 MPP_RET hal_jpegd_vdpu1_control(void *hal, MpiCmd cmd_type, void *param)
1047 {
1048     jpegd_dbg_func("enter\n");
1049     MPP_RET ret = MPP_OK;
1050     JpegdHalCtx *JpegHalCtx = (JpegdHalCtx *)hal;
1051     if (NULL == JpegHalCtx) {
1052         mpp_err_f("NULL pointer");
1053         return MPP_ERR_NULL_PTR;
1054     }
1055 
1056     switch (cmd_type) {
1057     case MPP_DEC_SET_OUTPUT_FORMAT: {
1058         JpegHalCtx->output_fmt = *((MppFrameFormat *)param);
1059         JpegHalCtx->set_output_fmt_flag = 1;
1060         jpegd_dbg_hal("output_format: 0x%x\n", JpegHalCtx->output_fmt);
1061 
1062         if (!MPP_FRAME_FMT_IS_YUV(JpegHalCtx->output_fmt) && !MPP_FRAME_FMT_IS_RGB(JpegHalCtx->output_fmt)) {
1063             mpp_err_f("invalid output format 0x%x\n", JpegHalCtx->output_fmt);
1064             ret = MPP_ERR_VALUE;
1065         }
1066     } break;
1067     default :
1068         break;
1069     }
1070 
1071     jpegd_dbg_func("exit ret %d\n", ret);
1072     return  ret;
1073 }
1074