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, ¶m);
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(®_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