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