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