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(®_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