1 /*
2 * drivers/amlogic/amports/jpegenc.c
3 *
4 * Copyright (C) 2015 Amlogic, Inc. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 */
17
18 #include <linux/kernel.h>
19 #include <linux/types.h>
20 #include <linux/errno.h>
21 #include <linux/interrupt.h>
22 #include <linux/timer.h>
23 #include <linux/compat.h>
24 #include <linux/fs.h>
25 #include <linux/sched.h>
26 #include <linux/slab.h>
27 #include <linux/dma-mapping.h>
28 #include <linux/platform_device.h>
29 #include <linux/spinlock.h>
30 #include <linux/ctype.h>
31
32 #include <linux/amlogic/media/frame_sync/ptsserv.h>
33 #include <linux/amlogic/media/utils/amstream.h>
34 #include <linux/amlogic/media/canvas/canvas.h>
35 #include <linux/amlogic/media/canvas/canvas_mgr.h>
36 #include <linux/amlogic/media/codec_mm/codec_mm.h>
37 #include <linux/amlogic/media/utils/vdec_reg.h>
38 #include "../../../frame_provider/decoder/utils/vdec.h"
39 #include <linux/delay.h>
40 #include <linux/poll.h>
41 #include <linux/of.h>
42 #include <linux/of_fdt.h>
43 #include <linux/dma-map-ops.h>
44 #include <linux/amlogic/media/utils/amports_config.h>
45 #include "../../../frame_provider/decoder/utils/firmware.h"
46 #include "../../../frame_provider/decoder/utils/amvdec.h"
47 #include "jpegenc.h"
48 #include <linux/amlogic/media/utils/amlog.h>
49 //#include "amports_priv.h"
50 #include <linux/of_reserved_mem.h>
51
52 #ifdef CONFIG_AM_ENCODER
53 #include "encoder.h"
54 #endif
55
56 #define JPEGENC_CANVAS_INDEX 0xE4
57 #define JPEGENC_CANVAS_MAX_INDEX 0xE7
58
59 #define ENC_CANVAS_OFFSET JPEGENC_CANVAS_INDEX
60
61 #define LOG_ALL 0
62 #define LOG_INFO 1
63 #define LOG_DEBUG 2
64 #define LOG_ERROR 3
65
66 #define jenc_pr(level, x...) \
67 do { \
68 if (level >= jpegenc_print_level) \
69 printk(x); \
70 } while (0)
71
72 #define DRIVER_NAME "jpegenc"
73 #define CLASS_NAME "jpegenc"
74 #define DEVICE_NAME "jpegenc"
75
76 #define MIN_SIZE jpegenc_buffspec[0].min_buffsize
77 /* #define EXTEAN_QUANT_TABLE */
78
79 static s32 jpegenc_device_major;
80 static struct device *jpegenc_dev;
81 static u32 jpegenc_print_level = LOG_DEBUG;
82
83 static u32 clock_level = 1;
84 static u16 gQuantTable[2][DCTSIZE2];
85 #ifdef EXTEAN_QUANT_TABLE
86 static u16 *gExternalQuantTablePtr;
87 static bool external_quant_table_available;
88 #endif
89
90 static DEFINE_SPINLOCK(lock);
91
92 #define JPEGENC_BUFFER_LEVEL_VGA 0
93 #define JPEGENC_BUFFER_LEVEL_2M 1
94 #define JPEGENC_BUFFER_LEVEL_3M 2
95 #define JPEGENC_BUFFER_LEVEL_5M 3
96 #define JPEGENC_BUFFER_LEVEL_8M 4
97 #define JPEGENC_BUFFER_LEVEL_13M 5
98 #define JPEGENC_BUFFER_LEVEL_HD 6
99
100 const s8 *glevel_str[] = {
101 "VGA",
102 "2M",
103 "3M",
104 "5M",
105 "8M",
106 "13M",
107 "HD",
108 };
109
110 const struct Jpegenc_BuffInfo_s jpegenc_buffspec[] = {
111 {
112 .lev_id = JPEGENC_BUFFER_LEVEL_VGA,
113 .max_width = 640,
114 .max_height = 640,
115 .min_buffsize = 0x330000,
116 .input = {
117 .buf_start = 0,
118 .buf_size = 0x12c000,
119 },
120 .assit = {
121 .buf_start = 0x12d000,
122 .buf_size = 0x2000,
123 },
124 .bitstream = {
125 .buf_start = 0x130000,
126 .buf_size = 0x200000,
127 }
128 }, {
129 .lev_id = JPEGENC_BUFFER_LEVEL_2M,
130 .max_width = 1600,
131 .max_height = 1600,
132 .min_buffsize = 0x960000,
133 .input = {
134 .buf_start = 0,
135 .buf_size = 0x753000,
136 },
137 .assit = {
138 .buf_start = 0x754000,
139 .buf_size = 0x2000,
140 },
141 .bitstream = {
142 .buf_start = 0x760000,
143 .buf_size = 0x200000,
144 }
145 }, {
146 .lev_id = JPEGENC_BUFFER_LEVEL_3M,
147 .max_width = 2048,
148 .max_height = 2048,
149 .min_buffsize = 0xe10000,
150 .input = {
151 .buf_start = 0,
152 .buf_size = 0xc00000,
153 },
154 .assit = {
155 .buf_start = 0xc01000,
156 .buf_size = 0x2000,
157 },
158 .bitstream = {
159 .buf_start = 0xc10000,
160 .buf_size = 0x200000,
161 }
162 }, {
163 .lev_id = JPEGENC_BUFFER_LEVEL_5M,
164 .max_width = 2624,
165 .max_height = 2624,
166 .min_buffsize = 0x1800000,
167 .input = {
168 .buf_start = 0,
169 .buf_size = 0x13B3000,
170 },
171 .assit = {
172 .buf_start = 0x13B4000,
173 .buf_size = 0x2000,
174 },
175 .bitstream = {
176 .buf_start = 0x1400000,
177 .buf_size = 0x400000,
178 }
179 }, {
180 .lev_id = JPEGENC_BUFFER_LEVEL_8M,
181 .max_width = 3264,
182 .max_height = 3264,
183 .min_buffsize = 0x2300000,
184 .input = {
185 .buf_start = 0,
186 .buf_size = 0x1e7b000,
187 },
188 .assit = {
189 .buf_start = 0x1e7c000,
190 .buf_size = 0x2000,
191 },
192 .bitstream = {
193 .buf_start = 0x1f00000,
194 .buf_size = 0x400000,
195 }
196 }, {
197 .lev_id = JPEGENC_BUFFER_LEVEL_13M,
198 .max_width = 8192,
199 .max_height = 8192,
200 .min_buffsize = 0xc400000,
201 .input = {
202 .buf_start = 0,
203 .buf_size = 0xc000000,
204 },
205 .assit = {
206 .buf_start = 0xc001000,
207 .buf_size = 0x2000,
208 },
209 .bitstream = {
210 .buf_start = 0xc010000,
211 .buf_size = 0x3f0000,
212 }
213 }, {
214 .lev_id = JPEGENC_BUFFER_LEVEL_HD,
215 .max_width = 8192,
216 .max_height = 8192,
217 .min_buffsize = 0xc400000,
218 .input = {
219 .buf_start = 0,
220 .buf_size = 0xc000000,
221 },
222 .assit = {
223 .buf_start = 0xc001000,
224 .buf_size = 0x2000,
225 },
226 .bitstream = {
227 .buf_start = 0xc010000,
228 .buf_size = 0x3f0000,
229 }
230 }
231 };
232
233 const char *jpegenc_ucode[] = {
234 "gxl_jpeg_enc",//"jpegenc_mc",
235 };
236
237 static struct jpegenc_manager_s gJpegenc;
238
239 static const u16 jpeg_quant[7][DCTSIZE2] = {
240 { /* jpeg_quant[0][] : Luma, Canon */
241 0x06, 0x06, 0x08, 0x0A, 0x0A, 0x10, 0x15, 0x19,
242 0x06, 0x0A, 0x0A, 0x0E, 0x12, 0x1F, 0x29, 0x29,
243 0x08, 0x0A, 0x0E, 0x12, 0x21, 0x29, 0x29, 0x29,
244 0x0A, 0x0E, 0x12, 0x14, 0x23, 0x29, 0x29, 0x29,
245 0x0A, 0x12, 0x21, 0x23, 0x27, 0x29, 0x29, 0x29,
246 0x10, 0x1F, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
247 0x15, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
248 0x19, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29
249 },
250 { /* jpeg_quant[1][] : Chroma, Canon */
251 0x0A, 0x0E, 0x10, 0x14, 0x15, 0x1D, 0x2B, 0x35,
252 0x0E, 0x12, 0x14, 0x1D, 0x25, 0x3E, 0x54, 0x54,
253 0x10, 0x14, 0x19, 0x25, 0x40, 0x54, 0x54, 0x54,
254 0x14, 0x1D, 0x25, 0x27, 0x48, 0x54, 0x54, 0x54,
255 0x15, 0x25, 0x40, 0x48, 0x4E, 0x54, 0x54, 0x54,
256 0x1D, 0x3E, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54,
257 0x2B, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54,
258 0x35, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54
259 },
260 { /* jpeg_quant[2][] : Luma, spec example Table K.1 */
261 16, 11, 10, 16, 24, 40, 51, 61,
262 12, 12, 14, 19, 26, 58, 60, 55,
263 14, 13, 16, 24, 40, 57, 69, 56,
264 14, 17, 22, 29, 51, 87, 80, 62,
265 18, 22, 37, 56, 68, 109, 103, 77,
266 24, 35, 55, 64, 81, 104, 113, 92,
267 49, 64, 78, 87, 103, 121, 120, 101,
268 72, 92, 95, 98, 112, 100, 103, 99
269 },
270 { /* jpeg_quant[3][] : Chroma, spec example Table K.2 */
271 17, 18, 24, 47, 99, 99, 99, 99,
272 18, 21, 26, 66, 99, 99, 99, 99,
273 24, 26, 56, 99, 99, 99, 99, 99,
274 47, 66, 99, 99, 99, 99, 99, 99,
275 99, 99, 99, 99, 99, 99, 99, 99,
276 99, 99, 99, 99, 99, 99, 99, 99,
277 99, 99, 99, 99, 99, 99, 99, 99,
278 99, 99, 99, 99, 99, 99, 99, 99
279 },
280 { /* jpeg_quant[4][] : Luma, spec example Table K.1,
281 modified to create long ZRL */
282 16, 11, 10, 16, 24, 40, 51, 61,
283 12, 12, 14, 19, 26, 58, 60, 55,
284 14, 13, 16, 24, 40, 57, 69, 56,
285 14, 17, 22, 29, 51, 87, 80, 62,
286 18, 22, 37, 56, 68, 109, 103, 77,
287 24, 35, 55, 64, 81, 104, 113, 92,
288 49, 64, 78, 87, 103, 121, 120, 101,
289 72, 92, 95, 98, 112, 100, 103, 16
290 },
291 { /* jpeg_quant[5][] : Chroma, spec example Table K.2,
292 modified to create long ZRL */
293 17, 18, 24, 47, 99, 99, 99, 99,
294 18, 21, 26, 66, 99, 99, 99, 99,
295 24, 26, 56, 99, 99, 99, 99, 99,
296 47, 66, 99, 99, 99, 99, 99, 99,
297 99, 99, 99, 99, 99, 99, 99, 99,
298 99, 99, 99, 99, 99, 99, 99, 99,
299 99, 99, 99, 99, 99, 99, 99, 99,
300 99, 99, 99, 99, 99, 99, 99, 17
301 },
302 { /* jpeg_quant[6][] : no compression */
303 1, 1, 1, 1, 1, 1, 1, 1,
304 1, 1, 1, 1, 1, 1, 1, 1,
305 1, 1, 1, 1, 1, 1, 1, 1,
306 1, 1, 1, 1, 1, 1, 1, 1,
307 1, 1, 1, 1, 1, 1, 1, 1,
308 1, 1, 1, 1, 1, 1, 1, 1,
309 1, 1, 1, 1, 1, 1, 1, 1,
310 1, 1, 1, 1, 1, 1, 1, 1
311 }
312 }; /* jpeg_quant */
313
314 static const u8 jpeg_huffman_dc[2][16 + 12] = {
315 { /* jpeg_huffman_dc[0][] */
316 0x00, /* number of code length=1 */
317 0x01,
318 0x05,
319 0x01,
320 0x01,
321 0x01,
322 0x01,
323 0x01,
324 0x01,
325 0x00,
326 0x00,
327 0x00,
328 0x00,
329 0x00,
330 0x00,
331 0x00, /* number of code length=16 */
332
333 /* Entry index for code with
334 minimum code length (=2 in this case) */
335 0x00,
336 0x01, 0x02, 0x03, 0x04, 0x05,
337 0x06,
338 0x07,
339 0x08,
340 0x09,
341 0x0A,
342 0x0B
343 },
344 { /* jpeg_huffman_dc[1][] */
345 0x00, /* number of code length=1 */
346 0x03,
347 0x01,
348 0x01,
349 0x01,
350 0x01,
351 0x01,
352 0x01,
353 0x01,
354 0x01,
355 0x01,
356 0x00,
357 0x00,
358 0x00,
359 0x00,
360 0x00, /* number of code length=16 */
361
362 /* Entry index for code with
363 minimum code length (=2 in this case) */
364 0x00, 0x01, 0x02,
365 0x03,
366 0x04,
367 0x05,
368 0x06,
369 0x07,
370 0x08,
371 0x09,
372 0x0A,
373 0x0B
374 }
375 }; /* jpeg_huffman_dc */
376
377 static const u8 jpeg_huffman_ac[2][16 + 162] = {
378 { /* jpeg_huffman_ac[0][] */
379 0x00, /* number of code length=1 */
380 0x02,
381 0x01,
382 0x03,
383 0x03,
384 0x02,
385 0x04,
386 0x03,
387 0x05,
388 0x05,
389 0x04,
390 0x04,
391 0x00,
392 0x00,
393 0x01,
394 0x7D, /* number of code length=16 */
395
396 /* Entry index for code with
397 minimum code length (=2 in this case) */
398 0x01, 0x02,
399 0x03,
400 0x00, 0x04, 0x11,
401 0x05, 0x12, 0x21,
402 0x31, 0x41,
403 0x06, 0x13, 0x51, 0x61,
404 0x07, 0x22, 0x71,
405 0x14, 0x32, 0x81, 0x91, 0xA1,
406 0x08, 0x23, 0x42, 0xB1, 0xC1,
407 0x15, 0x52, 0xD1, 0xF0,
408 0x24, 0x33, 0x62, 0x72,
409 0x82,
410 0x09, 0x0A, 0x16, 0x17, 0x18, 0x19,
411 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29,
412 0x2A, 0x34, 0x35, 0x36,
413 0x37, 0x38, 0x39, 0x3A, 0x43, 0x44,
414 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A,
415 0x53, 0x54, 0x55, 0x56,
416 0x57, 0x58, 0x59, 0x5A, 0x63, 0x64,
417 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A,
418 0x73, 0x74, 0x75, 0x76,
419 0x77, 0x78, 0x79, 0x7A, 0x83, 0x84,
420 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A,
421 0x92, 0x93, 0x94, 0x95,
422 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2,
423 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8,
424 0xA9, 0xAA, 0xB2, 0xB3,
425 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9,
426 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6,
427 0xC7, 0xC8, 0xC9, 0xCA,
428 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7,
429 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3,
430 0xE4, 0xE5, 0xE6, 0xE7,
431 0xE8, 0xE9, 0xEA, 0xF1, 0xF2, 0xF3,
432 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9,
433 0xFA
434 },
435 { /* jpeg_huffman_ac[1][] */
436 0x00, /* number of code length=1 */
437 0x02,
438 0x01,
439 0x02,
440 0x04,
441 0x04,
442 0x03,
443 0x04,
444 0x07,
445 0x05,
446 0x04,
447 0x04,
448 0x00,
449 0x01,
450 0x02,
451 0x77, /* number of code length=16 */
452
453 /* Entry index for code with
454 minimum code length (=2 in this case) */
455 0x00, 0x01,
456 0x02,
457 0x03, 0x11,
458 0x04, 0x05, 0x21, 0x31,
459 0x06, 0x12, 0x41, 0x51,
460 0x07, 0x61, 0x71,
461 0x13, 0x22, 0x32, 0x81,
462 0x08, 0x14, 0x42, 0x91, 0xA1, 0xB1, 0xC1,
463 0x09, 0x23, 0x33, 0x52, 0xF0,
464 0x15, 0x62, 0x72, 0xD1,
465 0x0A, 0x16, 0x24, 0x34,
466
467 0xE1,
468 0x25, 0xF1,
469 0x17, 0x18, 0x19, 0x1A, 0x26, 0x27,
470 0x28, 0x29, 0x2A, 0x35, 0x36, 0x37,
471 0x38, 0x39, 0x3A, 0x43,
472 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
473 0x4A, 0x53, 0x54, 0x55, 0x56, 0x57,
474 0x58, 0x59, 0x5A, 0x63,
475 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
476 0x6A, 0x73, 0x74, 0x75, 0x76, 0x77,
477 0x78, 0x79, 0x7A, 0x82,
478 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
479 0x89, 0x8A, 0x92, 0x93, 0x94, 0x95,
480 0x96, 0x97, 0x98, 0x99,
481 0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
482 0xA7, 0xA8, 0xA9, 0xAA, 0xB2, 0xB3,
483 0xB4, 0xB5, 0xB6, 0xB7,
484 0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4,
485 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA,
486 0xD2, 0xD3, 0xD4, 0xD5,
487 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE2,
488 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8,
489 0xE9, 0xEA, 0xF2, 0xF3,
490 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA
491 }
492 }; /* jpeg_huffman_ac */
493
494 static void dma_flush(u32 buf_start, u32 buf_size);
495
zigzag(s32 i)496 static s32 zigzag(s32 i)
497 {
498 s32 zigzag_i;
499 switch (i) {
500 case 0:
501 zigzag_i = 0;
502 break;
503 case 1:
504 zigzag_i = 1;
505 break;
506 case 2:
507 zigzag_i = 8;
508 break;
509 case 3:
510 zigzag_i = 16;
511 break;
512 case 4:
513 zigzag_i = 9;
514 break;
515 case 5:
516 zigzag_i = 2;
517 break;
518 case 6:
519 zigzag_i = 3;
520 break;
521 case 7:
522 zigzag_i = 10;
523 break;
524 case 8:
525 zigzag_i = 17;
526 break;
527 case 9:
528 zigzag_i = 24;
529 break;
530 case 10:
531 zigzag_i = 32;
532 break;
533 case 11:
534 zigzag_i = 25;
535 break;
536 case 12:
537 zigzag_i = 18;
538 break;
539 case 13:
540 zigzag_i = 11;
541 break;
542 case 14:
543 zigzag_i = 4;
544 break;
545 case 15:
546 zigzag_i = 5;
547 break;
548 case 16:
549 zigzag_i = 12;
550 break;
551 case 17:
552 zigzag_i = 19;
553 break;
554 case 18:
555 zigzag_i = 26;
556 break;
557 case 19:
558 zigzag_i = 33;
559 break;
560 case 20:
561 zigzag_i = 40;
562 break;
563 case 21:
564 zigzag_i = 48;
565 break;
566 case 22:
567 zigzag_i = 41;
568 break;
569 case 23:
570 zigzag_i = 34;
571 break;
572 case 24:
573 zigzag_i = 27;
574 break;
575 case 25:
576 zigzag_i = 20;
577 break;
578 case 26:
579 zigzag_i = 13;
580 break;
581 case 27:
582 zigzag_i = 6;
583 break;
584 case 28:
585 zigzag_i = 7;
586 break;
587 case 29:
588 zigzag_i = 14;
589 break;
590 case 30:
591 zigzag_i = 21;
592 break;
593 case 31:
594 zigzag_i = 28;
595 break;
596 case 32:
597 zigzag_i = 35;
598 break;
599 case 33:
600 zigzag_i = 42;
601 break;
602 case 34:
603 zigzag_i = 49;
604 break;
605 case 35:
606 zigzag_i = 56;
607 break;
608 case 36:
609 zigzag_i = 57;
610 break;
611 case 37:
612 zigzag_i = 50;
613 break;
614 case 38:
615 zigzag_i = 43;
616 break;
617 case 39:
618 zigzag_i = 36;
619 break;
620 case 40:
621 zigzag_i = 29;
622 break;
623 case 41:
624 zigzag_i = 22;
625 break;
626 case 42:
627 zigzag_i = 15;
628 break;
629 case 43:
630 zigzag_i = 23;
631 break;
632 case 44:
633 zigzag_i = 30;
634 break;
635 case 45:
636 zigzag_i = 37;
637 break;
638 case 46:
639 zigzag_i = 44;
640 break;
641 case 47:
642 zigzag_i = 51;
643 break;
644 case 48:
645 zigzag_i = 58;
646 break;
647 case 49:
648 zigzag_i = 59;
649 break;
650 case 50:
651 zigzag_i = 52;
652 break;
653 case 51:
654 zigzag_i = 45;
655 break;
656 case 52:
657 zigzag_i = 38;
658 break;
659 case 53:
660 zigzag_i = 31;
661 break;
662 case 54:
663 zigzag_i = 39;
664 break;
665 case 55:
666 zigzag_i = 46;
667 break;
668 case 56:
669 zigzag_i = 53;
670 break;
671 case 57:
672 zigzag_i = 60;
673 break;
674 case 58:
675 zigzag_i = 61;
676 break;
677 case 59:
678 zigzag_i = 54;
679 break;
680 case 60:
681 zigzag_i = 47;
682 break;
683 case 61:
684 zigzag_i = 55;
685 break;
686 case 62:
687 zigzag_i = 62;
688 break;
689 default:
690 zigzag_i = 63;
691 break;
692 }
693 return zigzag_i;
694 }
695
696 /* Perform convertion from Q to 1/Q */
reciprocal(u32 q)697 u32 reciprocal(u32 q)
698 {
699 u32 q_recip;
700
701 /* 65535 * (1/q) */
702 switch (q) {
703 case 0:
704 q_recip = 0;
705 break;
706 case 1:
707 q_recip = 65535;
708 break;
709 case 2:
710 q_recip = 32768;
711 break;
712 case 3:
713 q_recip = 21845;
714 break;
715 case 4:
716 q_recip = 16384;
717 break;
718 case 5:
719 q_recip = 13107;
720 break;
721 case 6:
722 q_recip = 10923;
723 break;
724 case 7:
725 q_recip = 9362;
726 break;
727 case 8:
728 q_recip = 8192;
729 break;
730 case 9:
731 q_recip = 7282;
732 break;
733 case 10:
734 q_recip = 6554;
735 break;
736 case 11:
737 q_recip = 5958;
738 break;
739 case 12:
740 q_recip = 5461;
741 break;
742 case 13:
743 q_recip = 5041;
744 break;
745 case 14:
746 q_recip = 4681;
747 break;
748 case 15:
749 q_recip = 4369;
750 break;
751 case 16:
752 q_recip = 4096;
753 break;
754 case 17:
755 q_recip = 3855;
756 break;
757 case 18:
758 q_recip = 3641;
759 break;
760 case 19:
761 q_recip = 3449;
762 break;
763 case 20:
764 q_recip = 3277;
765 break;
766 case 21:
767 q_recip = 3121;
768 break;
769 case 22:
770 q_recip = 2979;
771 break;
772 case 23:
773 q_recip = 2849;
774 break;
775 case 24:
776 q_recip = 2731;
777 break;
778 case 25:
779 q_recip = 2621;
780 break;
781 case 26:
782 q_recip = 2521;
783 break;
784 case 27:
785 q_recip = 2427;
786 break;
787 case 28:
788 q_recip = 2341;
789 break;
790 case 29:
791 q_recip = 2260;
792 break;
793 case 30:
794 q_recip = 2185;
795 break;
796 case 31:
797 q_recip = 2114;
798 break;
799 case 32:
800 q_recip = 2048;
801 break;
802 case 33:
803 q_recip = 1986;
804 break;
805 case 34:
806 q_recip = 1928;
807 break;
808 case 35:
809 q_recip = 1872;
810 break;
811 case 36:
812 q_recip = 1820;
813 break;
814 case 37:
815 q_recip = 1771;
816 break;
817 case 38:
818 q_recip = 1725;
819 break;
820 case 39:
821 q_recip = 1680;
822 break;
823 case 40:
824 q_recip = 1638;
825 break;
826 case 41:
827 q_recip = 1598;
828 break;
829 case 42:
830 q_recip = 1560;
831 break;
832 case 43:
833 q_recip = 1524;
834 break;
835 case 44:
836 q_recip = 1489;
837 break;
838 case 45:
839 q_recip = 1456;
840 break;
841 case 46:
842 q_recip = 1425;
843 break;
844 case 47:
845 q_recip = 1394;
846 break;
847 case 48:
848 q_recip = 1365;
849 break;
850 case 49:
851 q_recip = 1337;
852 break;
853 case 50:
854 q_recip = 1311;
855 break;
856 case 51:
857 q_recip = 1285;
858 break;
859 case 52:
860 q_recip = 1260;
861 break;
862 case 53:
863 q_recip = 1237;
864 break;
865 case 54:
866 q_recip = 1214;
867 break;
868 case 55:
869 q_recip = 1192;
870 break;
871 case 56:
872 q_recip = 1170;
873 break;
874 case 57:
875 q_recip = 1150;
876 break;
877 case 58:
878 q_recip = 1130;
879 break;
880 case 59:
881 q_recip = 1111;
882 break;
883 case 60:
884 q_recip = 1092;
885 break;
886 case 61:
887 q_recip = 1074;
888 break;
889 case 62:
890 q_recip = 1057;
891 break;
892 case 63:
893 q_recip = 1040;
894 break;
895 case 64:
896 q_recip = 1024;
897 break;
898 case 65:
899 q_recip = 1008;
900 break;
901 case 66:
902 q_recip = 993;
903 break;
904 case 67:
905 q_recip = 978;
906 break;
907 case 68:
908 q_recip = 964;
909 break;
910 case 69:
911 q_recip = 950;
912 break;
913 case 70:
914 q_recip = 936;
915 break;
916 case 71:
917 q_recip = 923;
918 break;
919 case 72:
920 q_recip = 910;
921 break;
922 case 73:
923 q_recip = 898;
924 break;
925 case 74:
926 q_recip = 886;
927 break;
928 case 75:
929 q_recip = 874;
930 break;
931 case 76:
932 q_recip = 862;
933 break;
934 case 77:
935 q_recip = 851;
936 break;
937 case 78:
938 q_recip = 840;
939 break;
940 case 79:
941 q_recip = 830;
942 break;
943 case 80:
944 q_recip = 819;
945 break;
946 case 81:
947 q_recip = 809;
948 break;
949 case 82:
950 q_recip = 799;
951 break;
952 case 83:
953 q_recip = 790;
954 break;
955 case 84:
956 q_recip = 780;
957 break;
958 case 85:
959 q_recip = 771;
960 break;
961 case 86:
962 q_recip = 762;
963 break;
964 case 87:
965 q_recip = 753;
966 break;
967 case 88:
968 q_recip = 745;
969 break;
970 case 89:
971 q_recip = 736;
972 break;
973 case 90:
974 q_recip = 728;
975 break;
976 case 91:
977 q_recip = 720;
978 break;
979 case 92:
980 q_recip = 712;
981 break;
982 case 93:
983 q_recip = 705;
984 break;
985 case 94:
986 q_recip = 697;
987 break;
988 case 95:
989 q_recip = 690;
990 break;
991 case 96:
992 q_recip = 683;
993 break;
994 case 97:
995 q_recip = 676;
996 break;
997 case 98:
998 q_recip = 669;
999 break;
1000 case 99:
1001 q_recip = 662;
1002 break;
1003 case 100:
1004 q_recip = 655;
1005 break;
1006 case 101:
1007 q_recip = 649;
1008 break;
1009 case 102:
1010 q_recip = 643;
1011 break;
1012 case 103:
1013 q_recip = 636;
1014 break;
1015 case 104:
1016 q_recip = 630;
1017 break;
1018 case 105:
1019 q_recip = 624;
1020 break;
1021 case 106:
1022 q_recip = 618;
1023 break;
1024 case 107:
1025 q_recip = 612;
1026 break;
1027 case 108:
1028 q_recip = 607;
1029 break;
1030 case 109:
1031 q_recip = 601;
1032 break;
1033 case 110:
1034 q_recip = 596;
1035 break;
1036 case 111:
1037 q_recip = 590;
1038 break;
1039 case 112:
1040 q_recip = 585;
1041 break;
1042 case 113:
1043 q_recip = 580;
1044 break;
1045 case 114:
1046 q_recip = 575;
1047 break;
1048 case 115:
1049 q_recip = 570;
1050 break;
1051 case 116:
1052 q_recip = 565;
1053 break;
1054 case 117:
1055 q_recip = 560;
1056 break;
1057 case 118:
1058 q_recip = 555;
1059 break;
1060 case 119:
1061 q_recip = 551;
1062 break;
1063 case 120:
1064 q_recip = 546;
1065 break;
1066 case 121:
1067 q_recip = 542;
1068 break;
1069 case 122:
1070 q_recip = 537;
1071 break;
1072 case 123:
1073 q_recip = 533;
1074 break;
1075 case 124:
1076 q_recip = 529;
1077 break;
1078 case 125:
1079 q_recip = 524;
1080 break;
1081 case 126:
1082 q_recip = 520;
1083 break;
1084 case 127:
1085 q_recip = 516;
1086 break;
1087 case 128:
1088 q_recip = 512;
1089 break;
1090 case 129:
1091 q_recip = 508;
1092 break;
1093 case 130:
1094 q_recip = 504;
1095 break;
1096 case 131:
1097 q_recip = 500;
1098 break;
1099 case 132:
1100 q_recip = 496;
1101 break;
1102 case 133:
1103 q_recip = 493;
1104 break;
1105 case 134:
1106 q_recip = 489;
1107 break;
1108 case 135:
1109 q_recip = 485;
1110 break;
1111 case 136:
1112 q_recip = 482;
1113 break;
1114 case 137:
1115 q_recip = 478;
1116 break;
1117 case 138:
1118 q_recip = 475;
1119 break;
1120 case 139:
1121 q_recip = 471;
1122 break;
1123 case 140:
1124 q_recip = 468;
1125 break;
1126 case 141:
1127 q_recip = 465;
1128 break;
1129 case 142:
1130 q_recip = 462;
1131 break;
1132 case 143:
1133 q_recip = 458;
1134 break;
1135 case 144:
1136 q_recip = 455;
1137 break;
1138 case 145:
1139 q_recip = 452;
1140 break;
1141 case 146:
1142 q_recip = 449;
1143 break;
1144 case 147:
1145 q_recip = 446;
1146 break;
1147 case 148:
1148 q_recip = 443;
1149 break;
1150 case 149:
1151 q_recip = 440;
1152 break;
1153 case 150:
1154 q_recip = 437;
1155 break;
1156 case 151:
1157 q_recip = 434;
1158 break;
1159 case 152:
1160 q_recip = 431;
1161 break;
1162 case 153:
1163 q_recip = 428;
1164 break;
1165 case 154:
1166 q_recip = 426;
1167 break;
1168 case 155:
1169 q_recip = 423;
1170 break;
1171 case 156:
1172 q_recip = 420;
1173 break;
1174 case 157:
1175 q_recip = 417;
1176 break;
1177 case 158:
1178 q_recip = 415;
1179 break;
1180 case 159:
1181 q_recip = 412;
1182 break;
1183 case 160:
1184 q_recip = 410;
1185 break;
1186 case 161:
1187 q_recip = 407;
1188 break;
1189 case 162:
1190 q_recip = 405;
1191 break;
1192 case 163:
1193 q_recip = 402;
1194 break;
1195 case 164:
1196 q_recip = 400;
1197 break;
1198 case 165:
1199 q_recip = 397;
1200 break;
1201 case 166:
1202 q_recip = 395;
1203 break;
1204 case 167:
1205 q_recip = 392;
1206 break;
1207 case 168:
1208 q_recip = 390;
1209 break;
1210 case 169:
1211 q_recip = 388;
1212 break;
1213 case 170:
1214 q_recip = 386;
1215 break;
1216 case 171:
1217 q_recip = 383;
1218 break;
1219 case 172:
1220 q_recip = 381;
1221 break;
1222 case 173:
1223 q_recip = 379;
1224 break;
1225 case 174:
1226 q_recip = 377;
1227 break;
1228 case 175:
1229 q_recip = 374;
1230 break;
1231 case 176:
1232 q_recip = 372;
1233 break;
1234 case 177:
1235 q_recip = 370;
1236 break;
1237 case 178:
1238 q_recip = 368;
1239 break;
1240 case 179:
1241 q_recip = 366;
1242 break;
1243 case 180:
1244 q_recip = 364;
1245 break;
1246 case 181:
1247 q_recip = 362;
1248 break;
1249 case 182:
1250 q_recip = 360;
1251 break;
1252 case 183:
1253 q_recip = 358;
1254 break;
1255 case 184:
1256 q_recip = 356;
1257 break;
1258 case 185:
1259 q_recip = 354;
1260 break;
1261 case 186:
1262 q_recip = 352;
1263 break;
1264 case 187:
1265 q_recip = 350;
1266 break;
1267 case 188:
1268 q_recip = 349;
1269 break;
1270 case 189:
1271 q_recip = 347;
1272 break;
1273 case 190:
1274 q_recip = 345;
1275 break;
1276 case 191:
1277 q_recip = 343;
1278 break;
1279 case 192:
1280 q_recip = 341;
1281 break;
1282 case 193:
1283 q_recip = 340;
1284 break;
1285 case 194:
1286 q_recip = 338;
1287 break;
1288 case 195:
1289 q_recip = 336;
1290 break;
1291 case 196:
1292 q_recip = 334;
1293 break;
1294 case 197:
1295 q_recip = 333;
1296 break;
1297 case 198:
1298 q_recip = 331;
1299 break;
1300 case 199:
1301 q_recip = 329;
1302 break;
1303 case 200:
1304 q_recip = 328;
1305 break;
1306 case 201:
1307 q_recip = 326;
1308 break;
1309 case 202:
1310 q_recip = 324;
1311 break;
1312 case 203:
1313 q_recip = 323;
1314 break;
1315 case 204:
1316 q_recip = 321;
1317 break;
1318 case 205:
1319 q_recip = 320;
1320 break;
1321 case 206:
1322 q_recip = 318;
1323 break;
1324 case 207:
1325 q_recip = 317;
1326 break;
1327 case 208:
1328 q_recip = 315;
1329 break;
1330 case 209:
1331 q_recip = 314;
1332 break;
1333 case 210:
1334 q_recip = 312;
1335 break;
1336 case 211:
1337 q_recip = 311;
1338 break;
1339 case 212:
1340 q_recip = 309;
1341 break;
1342 case 213:
1343 q_recip = 308;
1344 break;
1345 case 214:
1346 q_recip = 306;
1347 break;
1348 case 215:
1349 q_recip = 305;
1350 break;
1351 case 216:
1352 q_recip = 303;
1353 break;
1354 case 217:
1355 q_recip = 302;
1356 break;
1357 case 218:
1358 q_recip = 301;
1359 break;
1360 case 219:
1361 q_recip = 299;
1362 break;
1363 case 220:
1364 q_recip = 298;
1365 break;
1366 case 221:
1367 q_recip = 297;
1368 break;
1369 case 222:
1370 q_recip = 295;
1371 break;
1372 case 223:
1373 q_recip = 294;
1374 break;
1375 case 224:
1376 q_recip = 293;
1377 break;
1378 case 225:
1379 q_recip = 291;
1380 break;
1381 case 226:
1382 q_recip = 290;
1383 break;
1384 case 227:
1385 q_recip = 289;
1386 break;
1387 case 228:
1388 q_recip = 287;
1389 break;
1390 case 229:
1391 q_recip = 286;
1392 break;
1393 case 230:
1394 q_recip = 285;
1395 break;
1396 case 231:
1397 q_recip = 284;
1398 break;
1399 case 232:
1400 q_recip = 282;
1401 break;
1402 case 233:
1403 q_recip = 281;
1404 break;
1405 case 234:
1406 q_recip = 280;
1407 break;
1408 case 235:
1409 q_recip = 279;
1410 break;
1411 case 236:
1412 q_recip = 278;
1413 break;
1414 case 237:
1415 q_recip = 277;
1416 break;
1417 case 238:
1418 q_recip = 275;
1419 break;
1420 case 239:
1421 q_recip = 274;
1422 break;
1423 case 240:
1424 q_recip = 273;
1425 break;
1426 case 241:
1427 q_recip = 272;
1428 break;
1429 case 242:
1430 q_recip = 271;
1431 break;
1432 case 243:
1433 q_recip = 270;
1434 break;
1435 case 244:
1436 q_recip = 269;
1437 break;
1438 case 245:
1439 q_recip = 267;
1440 break;
1441 case 246:
1442 q_recip = 266;
1443 break;
1444 case 247:
1445 q_recip = 265;
1446 break;
1447 case 248:
1448 q_recip = 264;
1449 break;
1450 case 249:
1451 q_recip = 263;
1452 break;
1453 case 250:
1454 q_recip = 262;
1455 break;
1456 case 251:
1457 q_recip = 261;
1458 break;
1459 case 252:
1460 q_recip = 260;
1461 break;
1462 case 253:
1463 q_recip = 259;
1464 break;
1465 case 254:
1466 q_recip = 258;
1467 break;
1468 default:
1469 q_recip = 257;
1470 break;
1471 }
1472 return q_recip;
1473 } /* reciprocal */
1474
push_word(u8 * base,s32 * offset,u32 word)1475 static void push_word(u8 *base, s32 *offset, u32 word)
1476 {
1477 u8 *ptr;
1478 s32 i;
1479 s32 bytes = (word >> 24) & 0xff;
1480 for (i = bytes - 1; i >= 0; i--) {
1481 ptr = base + *offset;
1482 (*offset)++;
1483 if (i == 0)
1484 *ptr = word & 0xff;
1485 else if (i == 1)
1486 *ptr = (word >> 8) & 0xff;
1487 else if (i == 2)
1488 *ptr = (word >> 16) & 0xff;
1489 }
1490 }
1491
jpeg_quality_scaling(s32 quality)1492 static s32 jpeg_quality_scaling(s32 quality)
1493 {
1494 if (quality <= 0)
1495 quality = 1;
1496 if (quality > 100)
1497 quality = 100;
1498
1499 if (quality < 50)
1500 quality = 5000 / quality;
1501 else
1502 quality = 200 - quality * 2;
1503 return quality;
1504 }
1505
_convert_quant_table(u16 * qtable,u16 * basic_table,s32 scale_factor,bool force_baseline)1506 static void _convert_quant_table(u16 *qtable, u16 *basic_table,
1507 s32 scale_factor, bool force_baseline)
1508 {
1509 s32 i = 0;
1510 s32 temp;
1511 for (i = 0; i < DCTSIZE2; i++) {
1512 temp = ((s32)basic_table[i] * scale_factor + 50) / 100;
1513 /* limit the values to the valid range */
1514 if (temp <= 0)
1515 temp = 1;
1516 /* max quantizer needed for 12 bits */
1517 if (temp > 32767)
1518 temp = 32767;
1519 /* limit to baseline range if requested */
1520 if (force_baseline && temp > 255)
1521 temp = 255;
1522 qtable[i] = (u16)temp;
1523 }
1524 }
1525
convert_quant_table(u16 * qtable,u16 * basic_table,s32 scale_factor)1526 static void convert_quant_table(u16 *qtable, u16 *basic_table,
1527 s32 scale_factor)
1528 {
1529 _convert_quant_table(qtable, basic_table, scale_factor, true);
1530 }
1531
write_jpeg_quant_lut(s32 table_num)1532 static void write_jpeg_quant_lut(s32 table_num)
1533 {
1534 s32 i;
1535 u32 data32;
1536
1537 for (i = 0; i < DCTSIZE2; i += 2) {
1538 data32 = reciprocal(gQuantTable[table_num][i]);
1539 data32 |= reciprocal(gQuantTable[table_num][i + 1]) << 16;
1540 WRITE_HREG(HCODEC_QDCT_JPEG_QUANT_DATA, data32);
1541 }
1542 }
1543
write_jpeg_huffman_lut_dc(s32 table_num)1544 static void write_jpeg_huffman_lut_dc(s32 table_num)
1545 {
1546 u32 code_len, code_word, pos, addr;
1547 u32 num_code_len;
1548 u32 lut[12];
1549 u32 i, j;
1550
1551 code_len = 1;
1552 code_word = 1;
1553 pos = 16;
1554
1555 /* Construct DC Huffman table */
1556 for (i = 0; i < 16; i++) {
1557 num_code_len = jpeg_huffman_dc[table_num][i];
1558 for (j = 0; j < num_code_len; j++) {
1559 code_word = (code_word + 1) & ((1 << code_len) - 1);
1560 if (code_len < i + 1) {
1561 code_word <<= (i + 1 - code_len);
1562 code_len = i + 1;
1563 }
1564 addr = jpeg_huffman_dc[table_num][pos];
1565 lut[addr] = ((code_len - 1) << 16) | (code_word);
1566 pos++;
1567 }
1568 }
1569
1570 /* Write DC Huffman table to HW */
1571 for (i = 0; i < 12; i++)
1572 WRITE_HREG(HCODEC_VLC_HUFFMAN_DATA, lut[i]);
1573 }
1574
write_jpeg_huffman_lut_ac(s32 table_num)1575 static void write_jpeg_huffman_lut_ac(s32 table_num)
1576 {
1577 u32 code_len, code_word, pos;
1578 u32 num_code_len;
1579 u32 run, size;
1580 u32 data, addr = 0;
1581 u32 lut[162];
1582 u32 i, j;
1583 code_len = 1;
1584 code_word = 1;
1585 pos = 16;
1586
1587 /* Construct AC Huffman table */
1588 for (i = 0; i < 16; i++) {
1589 num_code_len = jpeg_huffman_ac[table_num][i];
1590 for (j = 0; j < num_code_len; j++) {
1591 code_word = (code_word + 1) & ((1 << code_len) - 1);
1592 if (code_len < i + 1) {
1593 code_word <<= (i + 1 - code_len);
1594 code_len = i + 1;
1595 }
1596 run = jpeg_huffman_ac[table_num][pos] >> 4;
1597 size = jpeg_huffman_ac[table_num][pos] & 0xf;
1598 data = ((code_len - 1) << 16) | (code_word);
1599 if (size == 0) {
1600 if (run == 0)
1601 addr = 0; /* EOB */
1602 else if (run == 0xf)
1603 addr = 161; /* ZRL */
1604 else
1605 jenc_pr(LOG_ERROR,
1606 "Error: Illegal AC Huffman table format!\n");
1607 } else if (size <= 0xa)
1608 addr = 1 + 16 * (size - 1) + run;
1609 else
1610 jenc_pr(LOG_ERROR,
1611 "Error: Illegal AC Huffman table format!\n");
1612 lut[addr] = data;
1613 pos++;
1614 }
1615 }
1616
1617 /* Write AC Huffman table to HW */
1618 for (i = 0; i < 162; i++)
1619 WRITE_HREG(HCODEC_VLC_HUFFMAN_DATA, lut[i]);
1620 }
1621
prepare_jpeg_header(struct jpegenc_wq_s * wq)1622 static void prepare_jpeg_header(struct jpegenc_wq_s *wq)
1623 {
1624 s32 pic_format;
1625 s32 pic_width, pic_height;
1626 s32 q_sel_comp0, q_sel_comp1, q_sel_comp2;
1627 s32 dc_huff_sel_comp0, dc_huff_sel_comp1, dc_huff_sel_comp2;
1628 s32 ac_huff_sel_comp0, ac_huff_sel_comp1, ac_huff_sel_comp2;
1629 s32 lastcoeff_sel;
1630 s32 jdct_intr_sel;
1631 s32 h_factor_comp0, v_factor_comp0;
1632 s32 h_factor_comp1, v_factor_comp1;
1633 s32 h_factor_comp2, v_factor_comp2;
1634 s32 q_num;
1635 s32 tq[2];
1636 s32 dc_huff_num, ac_huff_num;
1637 s32 dc_th[2], ac_th[2];
1638 u32 header_bytes = 0;
1639 u32 bak_header_bytes = 0;
1640 s32 i, j;
1641 u8 *assitbuf = (u8 *)wq->AssitstreamStartVirtAddr;
1642
1643 if (wq->cmd.output_fmt >= JPEGENC_MAX_FRAME_FMT)
1644 jenc_pr(LOG_ERROR, "Input format is wrong!\n");
1645 switch (wq->cmd.output_fmt) {
1646 case JPEGENC_FMT_NV21:
1647 case JPEGENC_FMT_NV12:
1648 case JPEGENC_FMT_YUV420:
1649 pic_format = 3;
1650 break;
1651 case JPEGENC_FMT_YUV422_SINGLE:
1652 pic_format = 2;
1653 break;
1654 case JPEGENC_FMT_YUV444_SINGLE:
1655 case JPEGENC_FMT_YUV444_PLANE:
1656 pic_format = 1;
1657 break;
1658 default:
1659 pic_format = 0;
1660 break;
1661 }
1662
1663 pic_width = wq->cmd.encoder_width;
1664 pic_height = wq->cmd.encoder_height;
1665
1666 q_sel_comp0 = QUANT_SEL_COMP0;
1667 q_sel_comp1 = QUANT_SEL_COMP1;
1668 q_sel_comp2 = QUANT_SEL_COMP2;
1669
1670 dc_huff_sel_comp0 = DC_HUFF_SEL_COMP0;
1671 dc_huff_sel_comp1 = DC_HUFF_SEL_COMP1;
1672 dc_huff_sel_comp2 = DC_HUFF_SEL_COMP2;
1673 ac_huff_sel_comp0 = AC_HUFF_SEL_COMP0;
1674 ac_huff_sel_comp1 = AC_HUFF_SEL_COMP1;
1675 ac_huff_sel_comp2 = AC_HUFF_SEL_COMP2;
1676 lastcoeff_sel = JDCT_LASTCOEFF_SEL;
1677 jdct_intr_sel = JDCT_INTR_SEL;
1678
1679 if (pic_format == 2) {
1680 /* YUV422 */
1681 h_factor_comp0 = 1;
1682 v_factor_comp0 = 0;
1683 h_factor_comp1 = 0;
1684 v_factor_comp1 = 0;
1685 h_factor_comp2 = 0;
1686 v_factor_comp2 = 0;
1687 } else if (pic_format == 3) {
1688 /* YUV420 */
1689 h_factor_comp0 = 1;
1690 v_factor_comp0 = 1;
1691 h_factor_comp1 = 0;
1692 v_factor_comp1 = 0;
1693 h_factor_comp2 = 0;
1694 v_factor_comp2 = 0;
1695 } else {
1696 /* RGB or YUV */
1697 h_factor_comp0 = 0;
1698 v_factor_comp0 = 0;
1699 h_factor_comp1 = 0;
1700 v_factor_comp1 = 0;
1701 h_factor_comp2 = 0;
1702 v_factor_comp2 = 0;
1703 }
1704
1705 /* SOI marke */
1706 push_word(assitbuf, &header_bytes,
1707 (2 << 24) | /* Number of bytes */
1708 (0xffd8 << 0)); /* data: SOI marker */
1709
1710 /* Define quantization tables */
1711 q_num = 1;
1712 #if 0
1713 if ((q_sel_comp0 != q_sel_comp1) ||
1714 (q_sel_comp0 != q_sel_comp2) ||
1715 (q_sel_comp1 != q_sel_comp2))
1716 #endif
1717 q_num++;
1718 #if 0
1719 tq[0] = q_sel_comp0;
1720 tq[1] = (q_sel_comp0 != q_sel_comp1) ? q_sel_comp1 :
1721 (q_sel_comp0 != q_sel_comp2) ? q_sel_comp2 :
1722 q_sel_comp0;
1723 #endif
1724 tq[0] = 0;
1725 tq[1] = q_num - 1;
1726
1727 /* data: DQT marker */
1728 push_word(assitbuf, &header_bytes,
1729 (2 << 24) | (0xffdb << 0));
1730 /* data: Lq */
1731 push_word(assitbuf, &header_bytes,
1732 (2 << 24) | ((2 + 65 * q_num) << 0));
1733
1734 /* Add Quantization table bytes */
1735 /* header_bytes += (2 + (2 + 65 * q_num)); */
1736 for (i = 0; i < q_num; i++) {
1737 /* data: {Pq,Tq} */
1738 push_word(assitbuf, &header_bytes,
1739 (1 << 24) | (i << 0));
1740 for (j = 0; j < DCTSIZE2; j++) {
1741 /* data: Qk */
1742 push_word(assitbuf, &header_bytes,
1743 (1 << 24) |
1744 ((gQuantTable[tq[i]][zigzag(j)]) << 0));
1745 }
1746 }
1747
1748 /* Define Huffman tables */
1749 dc_huff_num = 1;
1750 if ((dc_huff_sel_comp0 != dc_huff_sel_comp1) ||
1751 (dc_huff_sel_comp0 != dc_huff_sel_comp2) ||
1752 (dc_huff_sel_comp1 != dc_huff_sel_comp2))
1753 dc_huff_num++;
1754
1755 ac_huff_num = 1;
1756 if ((ac_huff_sel_comp0 != ac_huff_sel_comp1) ||
1757 (ac_huff_sel_comp0 != ac_huff_sel_comp2) ||
1758 (ac_huff_sel_comp1 != ac_huff_sel_comp2))
1759 ac_huff_num++;
1760
1761 dc_th[0] = dc_huff_sel_comp0;
1762 dc_th[1] = (dc_huff_sel_comp0 != dc_huff_sel_comp1) ?
1763 dc_huff_sel_comp1 : (dc_huff_sel_comp0 != dc_huff_sel_comp2) ?
1764 dc_huff_sel_comp2 : dc_huff_sel_comp0;
1765
1766 ac_th[0] = ac_huff_sel_comp0;
1767 ac_th[1] = (ac_huff_sel_comp0 != ac_huff_sel_comp1) ?
1768 ac_huff_sel_comp1 : (ac_huff_sel_comp0 != ac_huff_sel_comp2) ?
1769 ac_huff_sel_comp2 : ac_huff_sel_comp0;
1770
1771 /* data: DHT marker */
1772 push_word(assitbuf, &header_bytes,
1773 (2 << 24) | (0xffc4 << 0));
1774 /* data: Lh */
1775 push_word(assitbuf, &header_bytes,
1776 (2 << 24) |
1777 ((2 + (1 + 16 + 12) * dc_huff_num +
1778 (1 + 16 + 162) * ac_huff_num) << 0));
1779
1780 /* Add Huffman table bytes */
1781 /* data: {Tc,Th} */
1782 for (i = 0; i < dc_huff_num; i++) {
1783 push_word(assitbuf, &header_bytes,
1784 (1 << 24) | (i << 0));
1785 for (j = 0; j < 16 + 12; j++) {
1786 /* data: Li then Vi,j */
1787 push_word(assitbuf, &header_bytes,
1788 (1 << 24) |
1789 ((jpeg_huffman_dc[dc_th[i]][j]) << 0));
1790 }
1791 }
1792 for (i = 0; i < ac_huff_num; i++) {
1793 push_word(assitbuf, &header_bytes,
1794 (1 << 24) |
1795 (1 << 4) | /* data: Tc */
1796 (i << 0)); /* data: Th */
1797 for (j = 0; j < 16 + 162; j++) {
1798 /* data: Li then Vi,j */
1799 push_word(assitbuf, &header_bytes,
1800 (1 << 24) |
1801 ((jpeg_huffman_ac[ac_th[i]][j]) << 0));
1802 }
1803 }
1804
1805 /* Frame header */
1806 /* Add Frame header bytes */
1807 /* header_bytes += (2 + (8 + 3 * 3)); */
1808 push_word(assitbuf, &header_bytes,
1809 (2 << 24) | /* Number of bytes */
1810 (0xffc0 << 0)); /* data: SOF_0 marker */
1811 /* data: Lf */
1812 push_word(assitbuf, &header_bytes,
1813 (2 << 24) | ((8 + 3 * 3) << 0));
1814 /* data: P -- Sample precision */
1815 push_word(assitbuf,
1816 &header_bytes, (1 << 24) | (8 << 0));
1817 /* data: Y -- Number of lines */
1818 push_word(assitbuf,
1819 &header_bytes, (2 << 24) | (pic_height << 0));
1820 /* data: X -- Number of samples per line */
1821 push_word(assitbuf,
1822 &header_bytes, (2 << 24) | (pic_width << 0));
1823 /* data: Nf -- Number of components in a frame */
1824 push_word(assitbuf,
1825 &header_bytes, (1 << 24) | (3 << 0));
1826 /* data: C0 -- Comp0 identifier */
1827 push_word(assitbuf,
1828 &header_bytes, (1 << 24) | (0 << 0));
1829 push_word(assitbuf,
1830 &header_bytes, (1 << 24) |
1831 /* data: H0 -- Comp0 horizontal sampling factor */
1832 ((h_factor_comp0 + 1) << 4) |
1833 /* data: V0 -- Comp0 vertical sampling factor */
1834 ((v_factor_comp0 + 1) << 0));
1835
1836 /* data: Tq0 -- Comp0 quantization table seletor */
1837 push_word(assitbuf,
1838 &header_bytes, (1 << 24) | (0 << 0));
1839 /* data: C1 -- Comp1 identifier */
1840 push_word(assitbuf,
1841 &header_bytes, (1 << 24) | (1 << 0));
1842 push_word(assitbuf,
1843 &header_bytes, (1 << 24) |
1844 /* data: H1 -- Comp1 horizontal sampling factor */
1845 ((h_factor_comp1 + 1) << 4) |
1846 /* data: V1 -- Comp1 vertical sampling factor */
1847 ((v_factor_comp1 + 1) << 0));
1848 /* data: Tq1 -- Comp1 quantization table seletor */
1849 push_word(assitbuf,
1850 &header_bytes, (1 << 24) |
1851 (((q_sel_comp0 != q_sel_comp1) ? 1 : 0) << 0));
1852 /* data: C2 -- Comp2 identifier */
1853 push_word(assitbuf,
1854 &header_bytes, (1 << 24) | (2 << 0));
1855 push_word(assitbuf,
1856 &header_bytes, (1 << 24) |
1857 /* data: H2 -- Comp2 horizontal sampling factor */
1858 ((h_factor_comp2 + 1) << 4) |
1859 /* data: V2 -- Comp2 vertical sampling factor */
1860 ((v_factor_comp2 + 1) << 0));
1861 /* data: Tq2 -- Comp2 quantization table seletor */
1862 push_word(assitbuf,
1863 &header_bytes, (1 << 24) |
1864 (((q_sel_comp0 != q_sel_comp2) ? 1 : 0) << 0));
1865
1866 /* Scan header */
1867 bak_header_bytes = header_bytes + (2 + (6 + 2 * 3));
1868
1869 /* Add Scan header bytes */
1870 /* header_bytes += (2 + (6+2*3)); */
1871 /* If total header bytes is not multiple of 8,
1872 then fill 0xff byte between Frame header segment
1873 and the Scan header segment. */
1874 /* header_bytes = ((header_bytes + 7)/8)*8; */
1875 bak_header_bytes = ((bak_header_bytes + 7) / 8) * 8 - bak_header_bytes;
1876 for (i = 0; i < bak_header_bytes; i++)
1877 push_word(assitbuf,
1878 &header_bytes,
1879 (1 << 24) | (0xff << 0)); /* 0xff filler */
1880
1881 push_word(assitbuf,
1882 &header_bytes,
1883 (2 << 24) | /* Number of bytes */
1884 (0xffda << 0)); /* data: SOS marker */
1885
1886 /* data: Ls */
1887 push_word(assitbuf,
1888 &header_bytes, (2 << 24) | ((6 + 2 * 3) << 0));
1889 /* data: Ns -- Number of components in a scan */
1890 push_word(assitbuf,
1891 &header_bytes, (1 << 24) | (3 << 0));
1892 /* data: Cs0 -- Comp0 identifier */
1893 push_word(assitbuf,
1894 &header_bytes, (1 << 24) | (0 << 0));
1895 push_word(assitbuf,
1896 &header_bytes, (1 << 24) |
1897 (0 << 4) | /* data: Td0 -- Comp0 DC Huffman table selector */
1898 (0 << 0)); /* data: Ta0 -- Comp0 AC Huffman table selector */
1899 /* data: Cs1 -- Comp1 identifier */
1900 push_word(assitbuf,
1901 &header_bytes, (1 << 24) | (1 << 0));
1902 push_word(assitbuf,
1903 &header_bytes, (1 << 24) |
1904 /* data: Td1 -- Comp1 DC Huffman table selector */
1905 (((dc_huff_sel_comp0 != dc_huff_sel_comp1) ? 1 : 0) << 4) |
1906 /* data: Ta1 -- Comp1 AC Huffman table selector */
1907 (((ac_huff_sel_comp0 != ac_huff_sel_comp1) ? 1 : 0) << 0));
1908 /* data: Cs2 -- Comp2 identifier */
1909 push_word(assitbuf,
1910 &header_bytes, (1 << 24) | (2 << 0));
1911 push_word(assitbuf,
1912 &header_bytes, (1 << 24) |
1913 /* data: Td2 -- Comp2 DC Huffman table selector */
1914 (((dc_huff_sel_comp0 != dc_huff_sel_comp2) ? 1 : 0) << 4) |
1915 /* data: Ta2 -- Comp2 AC Huffman table selector */
1916 (((ac_huff_sel_comp0 != ac_huff_sel_comp2) ? 1 : 0) << 0));
1917 push_word(assitbuf, &header_bytes,
1918 (3 << 24) |
1919 (0 << 16) | /* data: Ss = 0 */
1920 (63 << 8) | /* data: Se = 63 */
1921 (0 << 4) | /* data: Ah = 0 */
1922 (0 << 0)); /* data: Al = 0 */
1923 jenc_pr(LOG_INFO, "jpeg header bytes is %d\n", header_bytes);
1924 wq->headbytes = header_bytes;
1925 }
1926
init_jpeg_encoder(struct jpegenc_wq_s * wq)1927 static void init_jpeg_encoder(struct jpegenc_wq_s *wq)
1928 {
1929 u32 data32;
1930 s32 pic_format; /* 0=RGB; 1=YUV; 2=YUV422; 3=YUV420 */
1931 s32 pic_x_start, pic_x_end, pic_y_start, pic_y_end;
1932 s32 pic_width, pic_height;
1933 s32 q_sel_comp0, q_sel_comp1, q_sel_comp2;
1934 s32 dc_huff_sel_comp0, dc_huff_sel_comp1, dc_huff_sel_comp2;
1935 s32 ac_huff_sel_comp0, ac_huff_sel_comp1, ac_huff_sel_comp2;
1936 s32 lastcoeff_sel;
1937 s32 jdct_intr_sel;
1938 s32 h_factor_comp0, v_factor_comp0;
1939 s32 h_factor_comp1, v_factor_comp1;
1940 s32 h_factor_comp2, v_factor_comp2;
1941
1942 jenc_pr(LOG_INFO, "Initialize JPEG Encoder ....\n");
1943 if (wq->cmd.output_fmt >= JPEGENC_MAX_FRAME_FMT)
1944 jenc_pr(LOG_ERROR, "Input format is wrong!\n");
1945 switch (wq->cmd.output_fmt) {
1946 case JPEGENC_FMT_NV21:
1947 case JPEGENC_FMT_NV12:
1948 case JPEGENC_FMT_YUV420:
1949 pic_format = 3;
1950 break;
1951 case JPEGENC_FMT_YUV422_SINGLE:
1952 pic_format = 2;
1953 break;
1954 case JPEGENC_FMT_YUV444_SINGLE:
1955 case JPEGENC_FMT_YUV444_PLANE:
1956 pic_format = 1;
1957 break;
1958 default:
1959 pic_format = 0;
1960 break;
1961 }
1962
1963 pic_x_start = 0;
1964 pic_x_end = wq->cmd.encoder_width - 1;
1965 pic_y_start = 0;
1966 pic_y_end = wq->cmd.encoder_height - 1;
1967 pic_width = wq->cmd.encoder_width;
1968 pic_height = wq->cmd.encoder_height;
1969
1970 q_sel_comp0 = wq->cmd.QuantTable_id * 2;
1971 q_sel_comp1 = q_sel_comp0 + 1;
1972 q_sel_comp2 = q_sel_comp1;
1973
1974 dc_huff_sel_comp0 = DC_HUFF_SEL_COMP0;
1975 dc_huff_sel_comp1 = DC_HUFF_SEL_COMP1;
1976 dc_huff_sel_comp2 = DC_HUFF_SEL_COMP2;
1977 ac_huff_sel_comp0 = AC_HUFF_SEL_COMP0;
1978 ac_huff_sel_comp1 = AC_HUFF_SEL_COMP1;
1979 ac_huff_sel_comp2 = AC_HUFF_SEL_COMP2;
1980 lastcoeff_sel = JDCT_LASTCOEFF_SEL;
1981 jdct_intr_sel = JDCT_INTR_SEL;
1982
1983 if (pic_format == 2) {
1984 /* YUV422 */
1985 h_factor_comp0 = 1;
1986 v_factor_comp0 = 0;
1987 h_factor_comp1 = 0;
1988 v_factor_comp1 = 0;
1989 h_factor_comp2 = 0;
1990 v_factor_comp2 = 0;
1991 } else if (pic_format == 3) {
1992 /* YUV420 */
1993 h_factor_comp0 = 1;
1994 v_factor_comp0 = 1;
1995 h_factor_comp1 = 0;
1996 v_factor_comp1 = 0;
1997 h_factor_comp2 = 0;
1998 v_factor_comp2 = 0;
1999 } else {
2000 /* RGB or YUV */
2001 h_factor_comp0 = 0;
2002 v_factor_comp0 = 0;
2003 h_factor_comp1 = 0;
2004 v_factor_comp1 = 0;
2005 h_factor_comp2 = 0;
2006 v_factor_comp2 = 0;
2007 }
2008
2009 /* Configure picture size and format */
2010 WRITE_HREG(HCODEC_VLC_PIC_SIZE, pic_width | (pic_height << 16));
2011 WRITE_HREG(HCODEC_VLC_PIC_POSITION, pic_format | (lastcoeff_sel << 4));
2012 WRITE_HREG(HCODEC_QDCT_JPEG_X_START_END,
2013 ((pic_x_end << 16) | (pic_x_start << 0)));
2014 WRITE_HREG(HCODEC_QDCT_JPEG_Y_START_END,
2015 ((pic_y_end << 16) | (pic_y_start << 0)));
2016
2017 /* Configure quantization tables */
2018 #ifdef EXTEAN_QUANT_TABLE
2019 if (external_quant_table_available) {
2020 convert_quant_table(&gQuantTable[0][0],
2021 &gExternalQuantTablePtr[0],
2022 wq->cmd.jpeg_quality);
2023 convert_quant_table(&gQuantTable[1][0],
2024 &gExternalQuantTablePtr[DCTSIZE2],
2025 wq->cmd.jpeg_quality);
2026 q_sel_comp0 = 0;
2027 q_sel_comp1 = 1;
2028 q_sel_comp2 = 1;
2029 } else
2030 #endif
2031 {
2032 s32 tq[2];
2033 tq[0] = q_sel_comp0;
2034 tq[1] = (q_sel_comp0 != q_sel_comp1) ?
2035 q_sel_comp1 : (q_sel_comp0 != q_sel_comp2) ?
2036 q_sel_comp2 : q_sel_comp0;
2037 convert_quant_table(&gQuantTable[0][0],
2038 (u16 *)&jpeg_quant[tq[0]],
2039 wq->cmd.jpeg_quality);
2040 if (tq[0] != tq[1])
2041 convert_quant_table(&gQuantTable[1][0],
2042 (u16 *)&jpeg_quant[tq[1]],
2043 wq->cmd.jpeg_quality);
2044 q_sel_comp0 = tq[0];
2045 q_sel_comp1 = tq[1];
2046 q_sel_comp2 = tq[1];
2047 }
2048
2049 /* Set Quantization LUT start address */
2050 data32 = 0;
2051 data32 |= 0 << 8; /* [8] 0=Write LUT, 1=Read */
2052 data32 |= 0 << 0; /* [5:0] Start addr = 0 */
2053
2054 WRITE_HREG(HCODEC_QDCT_JPEG_QUANT_ADDR, data32);
2055
2056 /* Burst-write Quantization LUT data */
2057 write_jpeg_quant_lut(0);
2058 if (q_sel_comp0 != q_sel_comp1)
2059 write_jpeg_quant_lut(1);
2060 #if 0
2061 write_jpeg_quant_lut(q_sel_comp0);
2062 if (q_sel_comp1 != q_sel_comp0)
2063 write_jpeg_quant_lut(q_sel_comp1);
2064 if ((q_sel_comp2 != q_sel_comp0) && (q_sel_comp2 != q_sel_comp1))
2065 write_jpeg_quant_lut(q_sel_comp2);
2066 #endif
2067
2068 /* Configure Huffman tables */
2069
2070 /* Set DC Huffman LUT start address */
2071 data32 = 0;
2072 data32 |= 0 << 16; /* [16] 0=Write LUT, 1=Read */
2073 data32 |= 0 << 0; /* [8:0] Start addr = 0 */
2074 WRITE_HREG(HCODEC_VLC_HUFFMAN_ADDR, data32);
2075
2076 /* Burst-write DC Huffman LUT data */
2077 write_jpeg_huffman_lut_dc(dc_huff_sel_comp0);
2078 if (dc_huff_sel_comp1 != dc_huff_sel_comp0)
2079 write_jpeg_huffman_lut_dc(dc_huff_sel_comp1);
2080
2081 #if 0
2082 if ((dc_huff_sel_comp2 != dc_huff_sel_comp0)
2083 && (dc_huff_sel_comp2 != dc_huff_sel_comp1))
2084 write_jpeg_huffman_lut_dc(dc_huff_sel_comp2);
2085 #endif
2086
2087 /* Set AC Huffman LUT start address */
2088 data32 = 0;
2089 data32 |= 0 << 16; /* [16] 0=Write LUT, 1=Read */
2090 data32 |= 24 << 0; /* [8:0] Start addr = 0 */
2091 WRITE_HREG(HCODEC_VLC_HUFFMAN_ADDR, data32);
2092
2093 /* Burst-write AC Huffman LUT data */
2094 write_jpeg_huffman_lut_ac(ac_huff_sel_comp0);
2095 if (ac_huff_sel_comp1 != ac_huff_sel_comp0)
2096 write_jpeg_huffman_lut_ac(ac_huff_sel_comp1);
2097
2098 #if 0
2099 if ((ac_huff_sel_comp2 != ac_huff_sel_comp0)
2100 && (ac_huff_sel_comp2 != ac_huff_sel_comp1))
2101 write_jpeg_huffman_lut_ac(ac_huff_sel_comp2);
2102 #endif
2103
2104 /* Configure general control registers */
2105 data32 = 0;
2106 /* [19:18] dct_inflow_ctrl: 0=No halt; */
2107 /* 1=DCT halts request at end of each 8x8 block; */
2108 /* 2=DCT halts request at end of each MCU. */
2109 data32 |= 0 << 18;
2110 /* [17:16] jpeg_coeff_last_sel: */
2111 /* 0=Mark last coeff at the end of an 8x8 block, */
2112 /* 1=Mark last coeff at the end of an MCU */
2113 /* 2=Mark last coeff at the end of a scan */
2114 data32 |= lastcoeff_sel << 16;
2115 /* [15] jpeg_quant_sel_comp2 */
2116 data32 |= ((q_sel_comp2 == q_sel_comp0) ? 0 : 1) << 15;
2117 /* [14] jpeg_v_factor_comp2 */
2118 data32 |= v_factor_comp2 << 14;
2119 /* [13] jpeg_h_factor_comp2 */
2120 data32 |= h_factor_comp2 << 13;
2121 /* [12] jpeg_comp2_en */
2122 data32 |= 1 << 12;
2123 /* [11] jpeg_quant_sel_comp1 */
2124 data32 |= ((q_sel_comp1 == q_sel_comp0) ? 0 : 1) << 11;
2125 /* [10] jpeg_v_factor_comp1 */
2126 data32 |= v_factor_comp1 << 10;
2127 /* [9] jpeg_h_factor_comp1 */
2128 data32 |= h_factor_comp1 << 9;
2129 /* [8] jpeg_comp1_en */
2130 data32 |= 1 << 8;
2131 /* [7] jpeg_quant_sel_comp0 */
2132 data32 |= 0 << 7;
2133 /* [6] jpeg_v_factor_comp0 */
2134 data32 |= v_factor_comp0 << 6;
2135 /* [5] jpeg_h_factor_comp0 */
2136 data32 |= h_factor_comp0 << 5;
2137 /* [4] jpeg_comp0_en */
2138 data32 |= 1 << 4;
2139 /* [3:1] jdct_intr_sel:0=Disable intr; */
2140 /* 1=Intr at end of each 8x8 block of DCT input; */
2141 /* 2=Intr at end of each MCU of DCT input; */
2142 /* 3=Intr at end of a scan of DCT input; */
2143 /* 4=Intr at end of each 8x8 block of DCT output; */
2144 /* 5=Intr at end of each MCU of DCT output; */
2145 /* 6=Intr at end of a scan of DCT output. */
2146 data32 |= jdct_intr_sel << 1;
2147 /* [0] jpeg_en */
2148 data32 |= 1 << 0;
2149 WRITE_HREG(HCODEC_QDCT_JPEG_CTRL, data32);
2150
2151 data32 = 0;
2152 /* [29] jpeg_comp2_ac_table_sel */
2153 /*
2154 data32 |= ((ac_huff_sel_comp2 == ac_huff_sel_comp0) ? 0 : 1 << 29;
2155 */
2156 data32 |= 1 << 29;
2157 /* [28] jpeg_comp2_dc_table_sel */
2158 /*
2159 data32 |= ((dc_huff_sel_comp2 == dc_huff_sel_comp0) ? 0 : 1) << 28;
2160 */
2161 data32 |= 1 << 28;
2162 /* [26:25] jpeg_comp2_cnt_max */
2163 data32 |= ((h_factor_comp2 + 1) * (v_factor_comp2 + 1) - 1) << 25;
2164 /* [24] jpeg_comp2_en */
2165 data32 |= 1 << 24;
2166 /* [21] jpeg_comp1_ac_table_sel */
2167 /*
2168 data32 |= ((ac_huff_sel_comp1 == ac_huff_sel_comp0) ? 0 : 1) << 21;
2169 */
2170 data32 |= 1 << 21;
2171 /* [20] jpeg_comp1_dc_table_sel */
2172 /*
2173 data32 |= ((dc_huff_sel_comp1 == dc_huff_sel_comp0) ? 0 : 1) << 20;
2174 */
2175 data32 |= 1 << 20;
2176 /* [18:17] jpeg_comp1_cnt_max */
2177 data32 |= ((h_factor_comp1 + 1) * (v_factor_comp1 + 1) - 1) << 17;
2178 /* [16] jpeg_comp1_en */
2179 data32 |= 1 << 16;
2180 /* [13] jpeg_comp0_ac_table_sel */
2181 data32 |= 0 << 13;
2182 /* [12] jpeg_comp0_dc_table_sel */
2183 data32 |= 0 << 12;
2184 /* [10:9] jpeg_comp0_cnt_max */
2185 data32 |= ((h_factor_comp0 + 1) * (v_factor_comp0 + 1) - 1) << 9;
2186 /* [8] jpeg_comp0_en */
2187 data32 |= 1 << 8;
2188 /* [0] jpeg_en, will be enbled by amrisc */
2189 data32 |= 0 << 0;
2190 WRITE_HREG(HCODEC_VLC_JPEG_CTRL, data32);
2191
2192 WRITE_HREG(HCODEC_QDCT_MB_CONTROL,
2193 (1 << 9) | /* mb_info_soft_reset */
2194 (1 << 0)); /* mb read buffer soft reset */
2195
2196 WRITE_HREG(HCODEC_QDCT_MB_CONTROL,
2197 (0 << 28) | /* ignore_t_p8x8 */
2198 (0 << 27) | /* zero_mc_out_null_non_skipped_mb */
2199 (0 << 26) | /* no_mc_out_null_non_skipped_mb */
2200 (0 << 25) | /* mc_out_even_skipped_mb */
2201 (0 << 24) | /* mc_out_wait_cbp_ready */
2202 (0 << 23) | /* mc_out_wait_mb_type_ready */
2203 (0 << 29) | /* ie_start_int_enable */
2204 (0 << 19) | /* i_pred_enable */
2205 (0 << 20) | /* ie_sub_enable */
2206 (0 << 18) | /* iq_enable */
2207 (0 << 17) | /* idct_enable */
2208 (0 << 14) | /* mb_pause_enable */
2209 (1 << 13) | /* q_enable */
2210 (1 << 12) | /* dct_enable */
2211 (0 << 10) | /* mb_info_en */
2212 (0 << 3) | /* endian */
2213 (0 << 1) | /* mb_read_en */
2214 (0 << 0)); /* soft reset */
2215
2216 /* Assember JPEG file header */
2217 prepare_jpeg_header(wq);
2218 }
2219
jpegenc_init_output_buffer(struct jpegenc_wq_s * wq)2220 static void jpegenc_init_output_buffer(struct jpegenc_wq_s *wq)
2221 {
2222 WRITE_HREG(HCODEC_VLC_VB_MEM_CTL,
2223 ((1 << 31) | (0x3f << 24) |
2224 (0x20 << 16) | (2 << 0)));
2225 WRITE_HREG(HCODEC_VLC_VB_START_PTR,
2226 wq->BitstreamStart);
2227 WRITE_HREG(HCODEC_VLC_VB_WR_PTR,
2228 wq->BitstreamStart);
2229 WRITE_HREG(HCODEC_VLC_VB_SW_RD_PTR,
2230 wq->BitstreamStart);
2231 WRITE_HREG(HCODEC_VLC_VB_END_PTR,
2232 wq->BitstreamEnd);
2233 WRITE_HREG(HCODEC_VLC_VB_CONTROL, 1);
2234 WRITE_HREG(HCODEC_VLC_VB_CONTROL,
2235 ((0 << 14) | (7 << 3) |
2236 (1 << 1) | (0 << 0)));
2237 }
2238
jpegenc_buffspec_init(struct jpegenc_wq_s * wq)2239 static void jpegenc_buffspec_init(struct jpegenc_wq_s *wq)
2240 {
2241 /* input dct buffer config */
2242 wq->InputBuffStart = wq->buf_start +
2243 gJpegenc.mem.bufspec->input.buf_start;
2244 wq->InputBuffEnd = wq->InputBuffStart +
2245 gJpegenc.mem.bufspec->input.buf_size - 1;
2246 jenc_pr(LOG_INFO, "InputBuffStart is 0x%x\n", wq->InputBuffStart);
2247
2248 /* assit stream buffer config */
2249 //wq->AssitStart = wq->buf_start + gJpegenc.mem.bufspec->assit.buf_start;
2250 //wq->AssitEnd = wq->BitstreamStart + gJpegenc.mem.bufspec->assit.buf_size - 1;
2251 wq->AssitStart = wq->buf_start + gJpegenc.mem.bufspec->assit.buf_start;
2252 wq->AssitEnd = wq->AssitStart + gJpegenc.mem.bufspec->assit.buf_size - 1;
2253 /* output stream buffer config */
2254 wq->BitstreamStart = wq->buf_start +
2255 gJpegenc.mem.bufspec->bitstream.buf_start;
2256 wq->BitstreamEnd = wq->BitstreamStart +
2257 gJpegenc.mem.bufspec->bitstream.buf_size - 1;
2258 jenc_pr(LOG_INFO, "BitstreamStart is 0x%x\n", wq->BitstreamStart);
2259
2260 #if 0
2261 wq->AssitstreamStartVirtAddr = phys_to_virt(wq->AssitStart);
2262 #else
2263 wq->AssitstreamStartVirtAddr =
2264 codec_mm_vmap(wq->AssitStart, (wq->AssitEnd - wq->AssitStart + 1));
2265 #endif
2266 //jenc_pr(LOG_ERROR, "[%s:%d], (wq->AssitEnd - wq->AssitStart + 1)=%d\n",
2267 //__FUNCTION__, __LINE__, (wq->AssitEnd - wq->AssitStart + 1));
2268 jenc_pr(LOG_ERROR, "AssitstreamStartVirtAddr is %p\n",
2269 wq->AssitstreamStartVirtAddr);
2270 }
2271
2272 /* for temp */
2273 #define HCODEC_MFDIN_REGC_MBLP (HCODEC_MFDIN_REGB_AMPC + 0x1)
2274 #define HCODEC_MFDIN_REG0D (HCODEC_MFDIN_REGB_AMPC + 0x2)
2275 #define HCODEC_MFDIN_REG0E (HCODEC_MFDIN_REGB_AMPC + 0x3)
2276 #define HCODEC_MFDIN_REG0F (HCODEC_MFDIN_REGB_AMPC + 0x4)
2277 #define HCODEC_MFDIN_REG10 (HCODEC_MFDIN_REGB_AMPC + 0x5)
2278 #define HCODEC_MFDIN_REG11 (HCODEC_MFDIN_REGB_AMPC + 0x6)
2279 #define HCODEC_MFDIN_REG12 (HCODEC_MFDIN_REGB_AMPC + 0x7)
2280 #define HCODEC_MFDIN_REG13 (HCODEC_MFDIN_REGB_AMPC + 0x8)
2281 #define HCODEC_MFDIN_REG14 (HCODEC_MFDIN_REGB_AMPC + 0x9)
2282 #define HCODEC_MFDIN_REG15 (HCODEC_MFDIN_REGB_AMPC + 0xa)
2283 #define HCODEC_MFDIN_REG16 (HCODEC_MFDIN_REGB_AMPC + 0xb)
2284
mfdin_basic_jpeg(u32 input,u8 iformat,u8 oformat,u32 picsize_x,u32 picsize_y,u8 r2y_en,u8 ifmt_extra)2285 static void mfdin_basic_jpeg(
2286 u32 input, u8 iformat, u8 oformat, u32 picsize_x,
2287 u32 picsize_y, u8 r2y_en, u8 ifmt_extra)
2288 {
2289 u8 dsample_en; /* Downsample Enable */
2290 u8 interp_en; /* Interpolation Enable */
2291 u8 y_size; /* 0:16 Pixels for y direction pickup; 1:8 pixels */
2292 u8 r2y_mode; /* RGB2YUV Mode, range(0~3) */
2293 /* mfdin_reg3_canv[25:24]; */
2294 /* bytes per pixel in x direction for index0, 0:half 1:1 2:2 3:3 */
2295 u8 canv_idx0_bppx;
2296 /* mfdin_reg3_canv[27:26]; */
2297 /* bytes per pixel in x direction for index1-2, 0:half 1:1 2:2 3:3 */
2298 u8 canv_idx1_bppx;
2299 /* mfdin_reg3_canv[29:28]; */
2300 /* bytes per pixel in y direction for index0, 0:half 1:1 2:2 3:3 */
2301 u8 canv_idx0_bppy;
2302 /* mfdin_reg3_canv[31:30]; */
2303 /* bytes per pixel in y direction for index1-2, 0:half 1:1 2:2 3:3 */
2304 u8 canv_idx1_bppy;
2305 u8 ifmt444, ifmt422, ifmt420, linear_bytes4p;
2306 u32 linear_bytesperline;
2307 bool linear_enable = false;
2308 s32 reg_offset;
2309 bool format_err = false;
2310
2311 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_TXL) {
2312 if ((iformat == 7) && (ifmt_extra > 2))
2313 format_err = true;
2314 } else if (iformat == 7)
2315 format_err = true;
2316
2317 if (format_err) {
2318 jenc_pr(LOG_ERROR,
2319 "mfdin format err, iformat:%d, ifmt_extra:%d\n",
2320 iformat, ifmt_extra);
2321 return;
2322 }
2323 if (iformat != 7)
2324 ifmt_extra = 0;
2325
2326 ifmt444 = ((iformat == 1) || (iformat == 5) || (iformat == 8)
2327 || (iformat == 9) || (iformat == 12)) ? 1 : 0;
2328 if (iformat == 7 && ifmt_extra == 1)
2329 ifmt444 = 1;
2330 ifmt422 = ((iformat == 0) || (iformat == 10)) ? 1 : 0;
2331 if (iformat == 7 && ifmt_extra != 1)
2332 ifmt422 = 1;
2333 ifmt420 = ((iformat == 2) || (iformat == 3) || (iformat == 4)
2334 || (iformat == 11)) ? 1 : 0;
2335 dsample_en = ((ifmt444 && (oformat != 2))
2336 || (ifmt422 && (oformat == 0))) ? 1 : 0;
2337 interp_en = ((ifmt422 && (oformat == 2))
2338 || (ifmt420 && (oformat != 0))) ? 1 : 0;
2339 y_size = (oformat != 0) ? 1 : 0;
2340 /* r2y_mode = (r2y_en == 1) ? 1 : 0; */
2341 r2y_mode = 1;
2342 canv_idx0_bppx = (iformat == 1) ? 3 : (iformat == 0) ? 2 : 1;
2343 canv_idx1_bppx = (iformat == 4) ? 0 : 1;
2344 canv_idx0_bppy = 1;
2345 canv_idx1_bppy = (iformat == 5) ? 1 : 0;
2346 if ((iformat == 8) || (iformat == 9) || (iformat == 12))
2347 linear_bytes4p = 3;
2348 else if (iformat == 10)
2349 linear_bytes4p = 2;
2350 else if (iformat == 11)
2351 linear_bytes4p = 1;
2352 else
2353 linear_bytes4p = 0;
2354 linear_bytesperline = picsize_x * linear_bytes4p;
2355
2356 if (iformat < 8)
2357 linear_enable = false;
2358 else
2359 linear_enable = true;
2360
2361 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) {
2362 reg_offset = -8;
2363 WRITE_HREG((HCODEC_MFDIN_REG8_DMBL + reg_offset),
2364 (picsize_x << 14) | (picsize_y << 0));
2365 } else {
2366 reg_offset = 0;
2367 WRITE_HREG((HCODEC_MFDIN_REG8_DMBL + reg_offset),
2368 (picsize_x << 12) | (picsize_y << 0));
2369 }
2370
2371 WRITE_HREG((HCODEC_MFDIN_REG1_CTRL + reg_offset),
2372 (iformat << 0) | (oformat << 4) |
2373 (dsample_en << 6) | (y_size << 8) |
2374 (interp_en << 9) | (r2y_en << 12) |
2375 (r2y_mode << 13) | (ifmt_extra << 16) |
2376 (2 << 29));
2377
2378 if (linear_enable == false) {
2379 WRITE_HREG((HCODEC_MFDIN_REG3_CANV + reg_offset),
2380 (input & 0xffffff) |
2381 (canv_idx1_bppy << 30) |
2382 (canv_idx0_bppy << 28) |
2383 (canv_idx1_bppx << 26) |
2384 (canv_idx0_bppx << 24));
2385 WRITE_HREG((HCODEC_MFDIN_REG4_LNR0 + reg_offset),
2386 (0 << 16) | (0 << 0));
2387 WRITE_HREG((HCODEC_MFDIN_REG5_LNR1 + reg_offset), 0);
2388 } else {
2389 WRITE_HREG((HCODEC_MFDIN_REG3_CANV + reg_offset),
2390 (canv_idx1_bppy << 30) |
2391 (canv_idx0_bppy << 28) |
2392 (canv_idx1_bppx << 26) |
2393 (canv_idx0_bppx << 24));
2394 WRITE_HREG((HCODEC_MFDIN_REG4_LNR0 + reg_offset),
2395 (linear_bytes4p << 16) | (linear_bytesperline << 0));
2396 WRITE_HREG((HCODEC_MFDIN_REG5_LNR1 + reg_offset), input);
2397 }
2398
2399 WRITE_HREG((HCODEC_MFDIN_REG9_ENDN + reg_offset),
2400 (7 << 0) | (6 << 3) | (5 << 6) |
2401 (4 << 9) | (3 << 12) | (2 << 15) |
2402 (1 << 18) | (0 << 21));
2403 return;
2404 }
2405
set_jpeg_input_format(struct jpegenc_wq_s * wq,struct jpegenc_request_s * cmd)2406 static s32 set_jpeg_input_format(struct jpegenc_wq_s *wq,
2407 struct jpegenc_request_s *cmd)
2408 {
2409 s32 ret = 0;
2410 u8 iformat = JPEGENC_MAX_FRAME_FMT;
2411 u8 oformat = JPEGENC_MAX_FRAME_FMT;
2412 u8 r2y_en = 0;
2413 u32 picsize_x, picsize_y;
2414 u32 canvas_w = 0;
2415 u32 input = cmd->src;
2416 u8 ifmt_extra = 0;
2417
2418 jenc_pr(LOG_INFO, "************begin set input format**************\n");
2419 jenc_pr(LOG_INFO, "type is %d\n", cmd->type);
2420 jenc_pr(LOG_INFO, "input_fmt is %d\n", cmd->input_fmt);
2421 jenc_pr(LOG_INFO, "output_fmt is %d\n", cmd->output_fmt);
2422 jenc_pr(LOG_INFO, "input is 0x%x\n", cmd->src);
2423 jenc_pr(LOG_INFO, "size is %d\n", cmd->framesize);
2424 jenc_pr(LOG_INFO, "quality is %d\n", cmd->jpeg_quality);
2425 jenc_pr(LOG_INFO, "quant tbl_id is %d\n", cmd->QuantTable_id);
2426 jenc_pr(LOG_INFO, "flush flag is %d\n", cmd->flush_flag);
2427 jenc_pr(LOG_INFO, "************end set input format**************\n");
2428
2429 if ((cmd->input_fmt == JPEGENC_FMT_RGB565)
2430 || (cmd->input_fmt >= JPEGENC_MAX_FRAME_FMT))
2431 return -1;
2432
2433 picsize_x = ((cmd->encoder_width + 15) >> 4) << 4;
2434 picsize_y = ((cmd->encoder_height + 15) >> 4) << 4;
2435 if (cmd->output_fmt == JPEGENC_FMT_YUV422_SINGLE)
2436 oformat = 1;
2437 else
2438 oformat = 0;
2439 if ((cmd->type == JPEGENC_LOCAL_BUFF) ||
2440 (cmd->type == JPEGENC_PHYSICAL_BUFF)) {
2441 if (cmd->type == JPEGENC_LOCAL_BUFF) {
2442 if (cmd->flush_flag & JPEGENC_FLUSH_FLAG_INPUT)
2443 dma_flush(wq->InputBuffStart,
2444 cmd->framesize);
2445 input = wq->InputBuffStart;
2446 }
2447 if ((cmd->input_fmt <= JPEGENC_FMT_YUV444_PLANE) ||
2448 (cmd->input_fmt >= JPEGENC_FMT_YUV422_12BIT))
2449 r2y_en = 0;
2450 else
2451 r2y_en = 1;
2452
2453 if (cmd->input_fmt >= JPEGENC_FMT_YUV422_12BIT) {
2454 iformat = 7;
2455 ifmt_extra =
2456 cmd->input_fmt - JPEGENC_FMT_YUV422_12BIT;
2457 if (cmd->input_fmt == JPEGENC_FMT_YUV422_12BIT)
2458 canvas_w = picsize_x * 24 / 8;
2459 else if (cmd->input_fmt == JPEGENC_FMT_YUV444_10BIT)
2460 canvas_w = picsize_x * 32 / 8;
2461 else
2462 canvas_w = (picsize_x * 20 + 7) / 8;
2463 canvas_w = ((canvas_w + 31) >> 5) << 5;
2464 canvas_config(ENC_CANVAS_OFFSET,
2465 input,
2466 canvas_w, picsize_y,
2467 CANVAS_ADDR_NOWRAP,
2468 CANVAS_BLKMODE_LINEAR);
2469 input = ENC_CANVAS_OFFSET;
2470 input = input & 0xff;
2471 } else if (cmd->input_fmt == JPEGENC_FMT_YUV422_SINGLE) {
2472 iformat = 0;
2473 canvas_w = picsize_x * 2;
2474 canvas_w = ((canvas_w + 31) >> 5) << 5;
2475 canvas_config(ENC_CANVAS_OFFSET,
2476 input,
2477 canvas_w, picsize_y,
2478 CANVAS_ADDR_NOWRAP,
2479 CANVAS_BLKMODE_LINEAR);
2480 input = ENC_CANVAS_OFFSET;
2481 } else if ((cmd->input_fmt == JPEGENC_FMT_YUV444_SINGLE)
2482 || (cmd->input_fmt == JPEGENC_FMT_RGB888)) {
2483 iformat = 1;
2484 if (cmd->input_fmt == JPEGENC_FMT_RGB888)
2485 r2y_en = 1;
2486 canvas_w = picsize_x * 3;
2487 canvas_w = ((canvas_w + 31) >> 5) << 5;
2488 canvas_config(ENC_CANVAS_OFFSET,
2489 input,
2490 canvas_w, picsize_y,
2491 CANVAS_ADDR_NOWRAP,
2492 CANVAS_BLKMODE_LINEAR);
2493 input = ENC_CANVAS_OFFSET;
2494 } else if ((cmd->input_fmt == JPEGENC_FMT_NV21)
2495 || (cmd->input_fmt == JPEGENC_FMT_NV12)) {
2496 canvas_w = ((cmd->encoder_width + 31) >> 5) << 5;
2497 iformat = (cmd->input_fmt == JPEGENC_FMT_NV21) ? 2 : 3;
2498 canvas_config(ENC_CANVAS_OFFSET,
2499 input,
2500 canvas_w, picsize_y,
2501 CANVAS_ADDR_NOWRAP,
2502 CANVAS_BLKMODE_LINEAR);
2503
2504 canvas_config(ENC_CANVAS_OFFSET + 1,
2505 input + canvas_w * picsize_y, canvas_w,
2506 picsize_y / 2, CANVAS_ADDR_NOWRAP,
2507 CANVAS_BLKMODE_LINEAR);
2508
2509 input = ((ENC_CANVAS_OFFSET + 1) << 8) | ENC_CANVAS_OFFSET;
2510 } else if (cmd->input_fmt == JPEGENC_FMT_YUV420) {
2511 iformat = 4;
2512 canvas_w = ((cmd->encoder_width + 63) >> 6) << 6;
2513 canvas_config(ENC_CANVAS_OFFSET,
2514 input,
2515 canvas_w, picsize_y,
2516 CANVAS_ADDR_NOWRAP,
2517 CANVAS_BLKMODE_LINEAR);
2518 canvas_config(ENC_CANVAS_OFFSET + 2,
2519 input + canvas_w * picsize_y,
2520 canvas_w / 2, picsize_y / 2,
2521 CANVAS_ADDR_NOWRAP,
2522 CANVAS_BLKMODE_LINEAR);
2523 canvas_config(ENC_CANVAS_OFFSET + 2,
2524 input + canvas_w * picsize_y * 5 / 4,
2525 canvas_w / 2, picsize_y / 2,
2526 CANVAS_ADDR_NOWRAP,
2527 CANVAS_BLKMODE_LINEAR);
2528 input = ((ENC_CANVAS_OFFSET + 2) << 16) |
2529 ((ENC_CANVAS_OFFSET + 1) << 8) |
2530 ENC_CANVAS_OFFSET;
2531 } else if ((cmd->input_fmt == JPEGENC_FMT_YUV444_PLANE)
2532 || (cmd->input_fmt == JPEGENC_FMT_RGB888_PLANE)) {
2533 iformat = 5;
2534 if (cmd->input_fmt == JPEGENC_FMT_RGB888_PLANE)
2535 r2y_en = 1;
2536 canvas_w = ((cmd->encoder_width + 31) >> 5) << 5;
2537 canvas_config(ENC_CANVAS_OFFSET,
2538 input,
2539 canvas_w, picsize_y,
2540 CANVAS_ADDR_NOWRAP,
2541 CANVAS_BLKMODE_LINEAR);
2542 canvas_config(ENC_CANVAS_OFFSET + 1,
2543 input + canvas_w * picsize_y, canvas_w,
2544 picsize_y, CANVAS_ADDR_NOWRAP,
2545 CANVAS_BLKMODE_LINEAR);
2546 canvas_config(ENC_CANVAS_OFFSET + 2,
2547 input + canvas_w * picsize_y * 2,
2548 canvas_w, picsize_y, CANVAS_ADDR_NOWRAP,
2549 CANVAS_BLKMODE_LINEAR);
2550 input = ((ENC_CANVAS_OFFSET + 2) << 16) |
2551 ((ENC_CANVAS_OFFSET + 1) << 8) |
2552 ENC_CANVAS_OFFSET;
2553 } else if (cmd->input_fmt == JPEGENC_FMT_RGBA8888) {
2554 iformat = 12;
2555 r2y_en = 1;
2556 }
2557 ret = 0;
2558 } else if (cmd->type == JPEGENC_CANVAS_BUFF) {
2559 r2y_en = 0;
2560 if (cmd->input_fmt == JPEGENC_FMT_YUV422_SINGLE) {
2561 iformat = 0;
2562 input = input & 0xff;
2563 } else if (cmd->input_fmt == JPEGENC_FMT_YUV444_SINGLE) {
2564 iformat = 1;
2565 input = input & 0xff;
2566 } else if ((cmd->input_fmt == JPEGENC_FMT_NV21)
2567 || (cmd->input_fmt == JPEGENC_FMT_NV12)) {
2568 iformat = (cmd->input_fmt == JPEGENC_FMT_NV21) ? 2 : 3;
2569 input = input & 0xffff;
2570 } else if (cmd->input_fmt == JPEGENC_FMT_YUV420) {
2571 iformat = 4;
2572 input = input & 0xffffff;
2573 } else if ((cmd->input_fmt == JPEGENC_FMT_YUV444_PLANE)
2574 || (cmd->input_fmt == JPEGENC_FMT_RGB888_PLANE)) {
2575 if (cmd->input_fmt == JPEGENC_FMT_RGB888_PLANE)
2576 r2y_en = 1;
2577 iformat = 5;
2578 input = input & 0xffffff;
2579 } else if ((cmd->input_fmt == JPEGENC_FMT_YUV422_12BIT)
2580 || (cmd->input_fmt == JPEGENC_FMT_YUV444_10BIT)
2581 || (cmd->input_fmt == JPEGENC_FMT_YUV422_10BIT)) {
2582 iformat = 7;
2583 ifmt_extra = cmd->input_fmt - JPEGENC_FMT_YUV422_12BIT;
2584 input = input & 0xff;
2585 } else
2586 ret = -1;
2587 }
2588 if (ret == 0)
2589 mfdin_basic_jpeg(input, iformat, oformat,
2590 picsize_x, picsize_y, r2y_en, ifmt_extra);
2591 return ret;
2592 }
2593
jpegenc_isr_tasklet(ulong data)2594 static void jpegenc_isr_tasklet(ulong data)
2595 {
2596 struct jpegenc_manager_s *manager = (struct jpegenc_manager_s *)data;
2597 jenc_pr(LOG_INFO, "encoder is done %d\n", manager->encode_hw_status);
2598 if ((manager->encode_hw_status == JPEGENC_ENCODER_DONE)
2599 && (manager->process_irq)) {
2600 manager->wq.hw_status = manager->encode_hw_status;
2601 manager->wq.output_size = READ_HREG(HCODEC_VLC_TOTAL_BYTES);
2602 jenc_pr(LOG_INFO, "encoder size %d\n", manager->wq.output_size);
2603 atomic_inc(&manager->wq.ready);
2604 wake_up_interruptible(&manager->wq.complete);
2605 }
2606 }
2607
jpegenc_isr(s32 irq_number,void * para)2608 static irqreturn_t jpegenc_isr(s32 irq_number, void *para)
2609 {
2610 struct jpegenc_manager_s *manager = (struct jpegenc_manager_s *)para;
2611 WRITE_HREG(HCODEC_ASSIST_MBOX2_CLR_REG, 1);
2612 manager->encode_hw_status = READ_HREG(JPEGENC_ENCODER_STATUS);
2613 if (manager->encode_hw_status == JPEGENC_ENCODER_DONE) {
2614 manager->process_irq = true;
2615 tasklet_schedule(&manager->tasklet);
2616 }
2617 return IRQ_HANDLED;
2618 }
2619
jpegenc_start(void)2620 static void jpegenc_start(void)
2621 {
2622 READ_VREG(DOS_SW_RESET1);
2623 READ_VREG(DOS_SW_RESET1);
2624 READ_VREG(DOS_SW_RESET1);
2625
2626 WRITE_VREG(DOS_SW_RESET1, (1 << 12) | (1 << 11));
2627 WRITE_VREG(DOS_SW_RESET1, 0);
2628
2629 READ_VREG(DOS_SW_RESET1);
2630 READ_VREG(DOS_SW_RESET1);
2631 READ_VREG(DOS_SW_RESET1);
2632
2633 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)
2634 WRITE_HREG((HCODEC_MFDIN_REG7_SCMD - 8), (1 << 28)),
2635 WRITE_HREG(HCODEC_MPSR, 0x0001);
2636 }
2637
_jpegenc_stop(void)2638 static void _jpegenc_stop(void)
2639 {
2640 ulong timeout = jiffies + HZ;
2641
2642 WRITE_HREG(HCODEC_MPSR, 0);
2643 WRITE_HREG(HCODEC_CPSR, 0);
2644 while (READ_HREG(HCODEC_IMEM_DMA_CTRL) & 0x8000) {
2645 if (time_after(jiffies, timeout))
2646 break;
2647 }
2648 READ_VREG(DOS_SW_RESET1);
2649 READ_VREG(DOS_SW_RESET1);
2650 READ_VREG(DOS_SW_RESET1);
2651
2652 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)
2653 WRITE_VREG(DOS_SW_RESET1,
2654 (1 << 12) | (1 << 11) |
2655 (1 << 2) | (1 << 6) |
2656 (1 << 7) | (1 << 8) |
2657 (1 << 14) | (1 << 16) |
2658 (1 << 17));
2659 else
2660 WRITE_VREG(DOS_SW_RESET1,
2661 (1 << 12) | (1 << 11) |
2662 (1 << 2) | (1 << 6) |
2663 (1 << 7) | (1 << 8) |
2664 (1 << 16) | (1 << 17));
2665
2666 WRITE_VREG(DOS_SW_RESET1, 0);
2667
2668 READ_VREG(DOS_SW_RESET1);
2669 READ_VREG(DOS_SW_RESET1);
2670 READ_VREG(DOS_SW_RESET1);
2671 }
2672
2673 static void __iomem *mc_addr;
2674 static u32 mc_addr_map;
2675 #define MC_SIZE (4096 * 4)
jpegenc_loadmc(const char * p)2676 s32 jpegenc_loadmc(const char *p)
2677 {
2678 ulong timeout;
2679 s32 ret = 0;
2680
2681 /* use static mempry*/
2682 if (mc_addr == NULL) {
2683 mc_addr = kmalloc(MC_SIZE, GFP_KERNEL);
2684 if (!mc_addr) {
2685 jenc_pr(LOG_ERROR,
2686 "jpegenc loadmc iomap mc addr error.\n");
2687 return -ENOMEM;
2688 }
2689 }
2690
2691 #ifdef KER49
2692 ret = get_decoder_firmware_data(VFORMAT_JPEG_ENC, p,
2693 (u8 *)mc_addr, MC_SIZE);
2694 #else
2695 ret = get_data_from_name(p, (u8 *)mc_addr);
2696 #endif
2697 if (ret < 0) {
2698 jenc_pr(LOG_ERROR,
2699 "jpegenc microcode fail ret=%d, name: %s.\n",
2700 ret, p);
2701 }
2702
2703 mc_addr_map = dma_map_single(
2704 &gJpegenc.this_pdev->dev,
2705 mc_addr, MC_SIZE, DMA_TO_DEVICE);
2706
2707 WRITE_HREG(HCODEC_MPSR, 0);
2708 WRITE_HREG(HCODEC_CPSR, 0);
2709
2710 /* Read CBUS register for timing */
2711 timeout = READ_HREG(HCODEC_MPSR);
2712 timeout = READ_HREG(HCODEC_MPSR);
2713
2714 timeout = jiffies + HZ;
2715
2716 WRITE_HREG(HCODEC_IMEM_DMA_ADR, mc_addr_map);
2717 WRITE_HREG(HCODEC_IMEM_DMA_COUNT, 0x1000);
2718 WRITE_HREG(HCODEC_IMEM_DMA_CTRL, (0x8000 | (7 << 16)));
2719
2720 while (READ_HREG(HCODEC_IMEM_DMA_CTRL) & 0x8000) {
2721 if (time_before(jiffies, timeout))
2722 schedule();
2723 else {
2724 jenc_pr(LOG_ERROR, "hcodec load mc error\n");
2725 ret = -EBUSY;
2726 break;
2727 }
2728 }
2729
2730 dma_unmap_single(
2731 &gJpegenc.this_pdev->dev,
2732 mc_addr_map, MC_SIZE, DMA_TO_DEVICE);
2733 return ret;
2734 }
2735
jpegenc_on(void)2736 bool jpegenc_on(void)
2737 {
2738 bool hcodec_on;
2739 ulong flags;
2740
2741 spin_lock_irqsave(&lock, flags);
2742
2743 hcodec_on = vdec_on(VDEC_HCODEC);
2744 hcodec_on &= (gJpegenc.opened > 0);
2745
2746 spin_unlock_irqrestore(&lock, flags);
2747 return hcodec_on;
2748 }
2749
jpegenc_poweron(u32 clock)2750 static s32 jpegenc_poweron(u32 clock)
2751 {
2752 ulong flags;
2753 u32 data32;
2754
2755 data32 = 0;
2756
2757 amports_switch_gate("vdec", 1);
2758
2759 spin_lock_irqsave(&lock, flags);
2760
2761 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) {
2762 WRITE_AOREG(AO_RTI_PWR_CNTL_REG0,
2763 (READ_AOREG(AO_RTI_PWR_CNTL_REG0) & (~0x18)));
2764 udelay(10);
2765 /* Powerup HCODEC */
2766 /* [1:0] HCODEC */
2767 WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
2768 READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) &
2769 ((get_cpu_type() == MESON_CPU_MAJOR_ID_SM1 ||
2770 get_cpu_type() >= MESON_CPU_MAJOR_ID_TM2)
2771 ? ~0x1 : ~0x3));
2772 udelay(10);
2773 }
2774
2775 WRITE_VREG(DOS_SW_RESET1, 0xffffffff);
2776 WRITE_VREG(DOS_SW_RESET1, 0);
2777
2778 /* Enable Dos internal clock gating */
2779 jpegenc_clock_enable(clock);
2780
2781 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) {
2782 /* Powerup HCODEC memories */
2783 WRITE_VREG(DOS_MEM_PD_HCODEC, 0x0);
2784
2785 /* Remove HCODEC ISO */
2786 WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
2787 READ_AOREG(AO_RTI_GEN_PWR_ISO0) &
2788 ((get_cpu_type() == MESON_CPU_MAJOR_ID_SM1 ||
2789 get_cpu_type() >= MESON_CPU_MAJOR_ID_TM2)
2790 ? ~0x1 : ~0x30));
2791 udelay(10);
2792 }
2793 /* Disable auto-clock gate */
2794 WRITE_VREG(DOS_GEN_CTRL0, (READ_VREG(DOS_GEN_CTRL0) | 0x1));
2795 WRITE_VREG(DOS_GEN_CTRL0, (READ_VREG(DOS_GEN_CTRL0) & 0xFFFFFFFE));
2796
2797 spin_unlock_irqrestore(&lock, flags);
2798
2799 mdelay(10);
2800 return 0;
2801 }
2802
jpegenc_poweroff(void)2803 static s32 jpegenc_poweroff(void)
2804 {
2805 ulong flags;
2806
2807 spin_lock_irqsave(&lock, flags);
2808
2809 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) {
2810 /* enable HCODEC isolation */
2811 WRITE_AOREG(AO_RTI_GEN_PWR_ISO0,
2812 READ_AOREG(AO_RTI_GEN_PWR_ISO0) | 0x30);
2813 /* power off HCODEC memories */
2814 WRITE_VREG(DOS_MEM_PD_HCODEC, 0xffffffffUL);
2815 }
2816 /* disable HCODEC clock */
2817 jpegenc_clock_disable();
2818
2819 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8) {
2820 /* HCODEC power off */
2821 WRITE_AOREG(AO_RTI_GEN_PWR_SLEEP0,
2822 READ_AOREG(AO_RTI_GEN_PWR_SLEEP0) | 0x3);
2823 }
2824
2825 spin_unlock_irqrestore(&lock, flags);
2826
2827 /* release DOS clk81 clock gating */
2828 amports_switch_gate("vdec", 0);
2829 return 0;
2830 }
2831
jpegenc_reset(void)2832 void jpegenc_reset(void)
2833 {
2834 READ_VREG(DOS_SW_RESET1);
2835 READ_VREG(DOS_SW_RESET1);
2836 READ_VREG(DOS_SW_RESET1);
2837 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)
2838 WRITE_VREG(DOS_SW_RESET1,
2839 (1 << 2) | (1 << 6) |
2840 (1 << 7) | (1 << 8) |
2841 (1 << 14) | (1 << 16) |
2842 (1 << 17));
2843 else
2844 WRITE_VREG(DOS_SW_RESET1,
2845 (1 << 2) | (1 << 6) | (1 << 7) |
2846 (1 << 8) | (1 << 16) | (1 << 17));
2847 WRITE_VREG(DOS_SW_RESET1, 0);
2848 READ_VREG(DOS_SW_RESET1);
2849 READ_VREG(DOS_SW_RESET1);
2850 READ_VREG(DOS_SW_RESET1);
2851 }
2852
jpegenc_init(void)2853 static s32 jpegenc_init(void)
2854 {
2855 jpegenc_poweron(clock_level);
2856 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_MG9TV) {
2857 WRITE_HREG(HCODEC_ASSIST_MMC_CTRL1, 0x32);
2858 } else {
2859 WRITE_HREG(HCODEC_ASSIST_MMC_CTRL1, 0x2);
2860 }
2861
2862 jenc_pr(LOG_ALL, "start to load microcode: %s\n", jpegenc_ucode[0]);
2863 if (jpegenc_loadmc(jpegenc_ucode[0]) < 0)
2864 return -EBUSY;
2865
2866 jenc_pr(LOG_ALL, "succeed to load microcode\n");
2867 gJpegenc.process_irq = false;
2868
2869 if (request_irq(gJpegenc.irq_num, jpegenc_isr, IRQF_SHARED,
2870 "jpegenc-irq", (void *)&gJpegenc) == 0)
2871 gJpegenc.irq_requested = true;
2872 else
2873 gJpegenc.irq_requested = false;
2874
2875 WRITE_HREG(JPEGENC_ENCODER_STATUS, JPEGENC_ENCODER_IDLE);
2876
2877 gJpegenc.inited = true;
2878
2879 return 0;
2880 }
2881
convert_cmd(struct jpegenc_wq_s * wq,u32 * cmd_info)2882 static s32 convert_cmd(struct jpegenc_wq_s *wq, u32 *cmd_info)
2883 {
2884 if (!wq) {
2885 jenc_pr(LOG_ERROR, "jpegenc convert_cmd error\n");
2886 return -1;
2887 }
2888 memset(&wq->cmd, 0, sizeof(struct jpegenc_request_s));
2889 wq->cmd.type = cmd_info[0];
2890 wq->cmd.input_fmt = cmd_info[1];
2891 wq->cmd.output_fmt = cmd_info[2];
2892 wq->cmd.encoder_width = cmd_info[3];
2893 wq->cmd.encoder_height = cmd_info[4];
2894 wq->cmd.framesize = cmd_info[5];
2895 wq->cmd.src = cmd_info[6];
2896 wq->cmd.jpeg_quality = cmd_info[7];
2897 wq->cmd.QuantTable_id = cmd_info[8];
2898 wq->cmd.flush_flag = cmd_info[9];
2899 if ((wq->cmd.encoder_width > wq->max_width) ||
2900 (wq->cmd.encoder_height > wq->max_height)) {
2901 jenc_pr(LOG_ERROR,
2902 "set encode size %dx%d is larger than supported (%dx%d).\n",
2903 wq->cmd.encoder_width,
2904 wq->cmd.encoder_height,
2905 wq->max_width,
2906 wq->max_height);
2907 return -1;
2908 }
2909 wq->cmd.jpeg_quality = jpeg_quality_scaling((s32)cmd_info[7]);
2910 if (wq->cmd.QuantTable_id < 4) {
2911 jenc_pr(LOG_INFO,
2912 "JPEGENC_SEL_QUANT_TABLE : %d.\n",
2913 wq->cmd.QuantTable_id);
2914 } else {
2915 wq->cmd.QuantTable_id = 0;
2916 jenc_pr(LOG_ERROR,
2917 "JPEGENC_SEL_QUANT_TABLE invaild. target value: %d.\n",
2918 cmd_info[8]);
2919 }
2920 jenc_pr(LOG_INFO,
2921 "target quality : %d, jpeg_quality value: %d.\n",
2922 cmd_info[7], wq->cmd.jpeg_quality);
2923 return 0;
2924 }
2925
jpegenc_start_cmd(struct jpegenc_wq_s * wq)2926 static void jpegenc_start_cmd(struct jpegenc_wq_s *wq)
2927 {
2928 gJpegenc.process_irq = false;
2929 gJpegenc.encode_hw_status = JPEGENC_ENCODER_IDLE;
2930
2931 jpegenc_reset();
2932 set_jpeg_input_format(wq, &wq->cmd);
2933
2934 init_jpeg_encoder(wq);
2935 jpegenc_init_output_buffer(wq);
2936 /* clear mailbox interrupt */
2937 WRITE_HREG(HCODEC_ASSIST_MBOX2_CLR_REG, 1);
2938
2939 /* enable mailbox interrupt */
2940 WRITE_HREG(HCODEC_ASSIST_MBOX2_MASK, 1);
2941 gJpegenc.encode_hw_status = JPEGENC_ENCODER_IDLE;
2942 WRITE_HREG(JPEGENC_ENCODER_STATUS, JPEGENC_ENCODER_IDLE);
2943 gJpegenc.process_irq = false;
2944 jpegenc_start();
2945 jenc_pr(LOG_INFO, "jpegenc_start\n");
2946 }
2947
jpegenc_stop(void)2948 static void jpegenc_stop(void)
2949 {
2950 if ((gJpegenc.irq_num >= 0) &&
2951 (gJpegenc.irq_requested == true)) {
2952 free_irq(gJpegenc.irq_num, &gJpegenc);
2953 gJpegenc.irq_requested = false;
2954 }
2955 _jpegenc_stop();
2956 jpegenc_poweroff();
2957 jenc_pr(LOG_INFO, "jpegenc_stop\n");
2958 }
2959
dma_flush(u32 buf_start,u32 buf_size)2960 static void dma_flush(u32 buf_start, u32 buf_size)
2961 {
2962 dma_sync_single_for_device(&gJpegenc.this_pdev->dev,
2963 buf_start, buf_size, DMA_TO_DEVICE);
2964 }
2965
cache_flush(u32 buf_start,u32 buf_size)2966 static void cache_flush(u32 buf_start, u32 buf_size)
2967 {
2968 dma_sync_single_for_cpu(&gJpegenc.this_pdev->dev,
2969 buf_start, buf_size, DMA_FROM_DEVICE);
2970 }
2971
jpegenc_open(struct inode * inode,struct file * file)2972 static s32 jpegenc_open(struct inode *inode, struct file *file)
2973 {
2974 struct jpegenc_wq_s *wq;
2975 s32 r;
2976 jenc_pr(LOG_DEBUG, "jpegenc open\n");
2977
2978 #ifdef CONFIG_AM_ENCODER
2979 if (amvenc_avc_on() == true) {
2980 jenc_pr(LOG_ERROR, "hcodec in use for AVC Encode now.\n");
2981 return -EBUSY;
2982 }
2983 #endif
2984
2985 file->private_data = NULL;
2986
2987 spin_lock(&gJpegenc.sem_lock);
2988
2989 if (gJpegenc.opened > 0) {
2990 spin_unlock(&gJpegenc.sem_lock);
2991 jenc_pr(LOG_ERROR, "jpegenc open busy.\n");
2992 return -EBUSY;
2993 }
2994
2995 wq = &gJpegenc.wq;
2996 wq->buf_start = gJpegenc.mem.buf_start;
2997 wq->buf_size = gJpegenc.mem.buf_size;
2998 gJpegenc.opened++;
2999 spin_unlock(&gJpegenc.sem_lock);
3000 #ifdef CONFIG_CMA
3001 jenc_pr(LOG_ERROR, "use_reserve:%d, gJpegenc.mem.buf_sizea:%u\n",
3002 gJpegenc.use_reserve, gJpegenc.mem.buf_size);
3003
3004 if (gJpegenc.use_reserve == false) {
3005 /*wq->venc_pages = dma_alloc_from_contiguous(&gJpegenc.this_pdev->dev, gJpegenc.mem.buf_size >> PAGE_SHIFT, 0);
3006 if (wq->venc_pages) {
3007 wq->buf_start = page_to_phys(wq->venc_pages);
3008 wq->buf_size = gJpegenc.mem.buf_size;
3009 jenc_pr(LOG_DEBUG,
3010 "allocating phys 0x%x, size %dk.\n",
3011 wq->buf_start, wq->buf_size >> 10);
3012 } else {
3013 jenc_pr(LOG_ERROR,
3014 "CMA failed to allocate dma buffer for %s.\n",
3015 gJpegenc.this_pdev->name);
3016 spin_lock(&gJpegenc.sem_lock);
3017 gJpegenc.opened--;
3018 spin_unlock(&gJpegenc.sem_lock);
3019 return -ENOMEM;
3020 }*/
3021 wq->buf_start = codec_mm_alloc_for_dma(DRIVER_NAME, gJpegenc.mem.buf_size >> PAGE_SHIFT, 0, 0);
3022
3023 if (wq->buf_start) {
3024 wq->buf_size = gJpegenc.mem.buf_size;
3025
3026 jenc_pr(LOG_ERROR,
3027 "allocating phys 0x%x, sizeeee %dk\n",
3028 wq->buf_start, wq->buf_size >> 10);//, codec_mm_vmap(wq->buf_start, wq->buf_size));
3029 } else {
3030 jenc_pr(LOG_ERROR,
3031 "CMA failed to allocate dma buffer for %s.\n",
3032 gJpegenc.this_pdev->name);
3033 spin_lock(&gJpegenc.sem_lock);
3034 gJpegenc.opened--;
3035 spin_unlock(&gJpegenc.sem_lock);
3036 return -ENOMEM;
3037 }
3038 }
3039 #endif
3040
3041 spin_lock(&gJpegenc.sem_lock);
3042 init_waitqueue_head(&wq->complete);
3043 atomic_set(&wq->ready, 0);
3044 wq->AssitstreamStartVirtAddr = NULL;
3045 memset(gQuantTable, 0, sizeof(gQuantTable));
3046 wq->cmd.QuantTable_id = 0;
3047 wq->cmd.jpeg_quality = 90;
3048 wq->max_width = gJpegenc.mem.bufspec->max_width;
3049 wq->max_height = gJpegenc.mem.bufspec->max_height;
3050 wq->headbytes = 0;
3051 file->private_data = (void *)wq;
3052
3053 #ifdef EXTEAN_QUANT_TABLE
3054 gExternalQuantTablePtr = NULL;
3055 external_quant_table_available = false;
3056 #endif
3057 spin_unlock(&gJpegenc.sem_lock);
3058 r = 0;
3059 return r;
3060 }
3061
jpegenc_release(struct inode * inode,struct file * file)3062 static s32 jpegenc_release(struct inode *inode, struct file *file)
3063 {
3064 struct jpegenc_wq_s *wq = (struct jpegenc_wq_s *)file->private_data;
3065
3066 if (wq != &gJpegenc.wq) {
3067 jenc_pr(LOG_ERROR, "jpegenc release error\n");
3068 return -1;
3069 }
3070 if (gJpegenc.inited) {
3071 jpegenc_stop();
3072 gJpegenc.inited = false;
3073 }
3074 memset(gQuantTable, 0, sizeof(gQuantTable));
3075
3076 if (wq->AssitstreamStartVirtAddr)
3077 wq->AssitstreamStartVirtAddr = NULL;
3078
3079 #ifdef CONFIG_CMA
3080 #if 0
3081 if (wq->venc_pages) {
3082 dma_release_from_contiguous(
3083 &gJpegenc.this_pdev->dev,
3084 wq->venc_pages,
3085 wq->buf_size >> PAGE_SHIFT);
3086 wq->venc_pages = NULL;
3087 }
3088 #endif
3089 if (wq->buf_start) {
3090 wq->venc_pages = NULL;
3091 codec_mm_free_for_dma(DRIVER_NAME, wq->buf_start);
3092 jenc_pr(LOG_ERROR, "jpegenc release memory\n");
3093 wq->buf_start = 0;
3094 }
3095 #endif
3096 wq->buf_start = 0;
3097 wq->buf_size = 0;
3098 #ifdef EXTEAN_QUANT_TABLE
3099 kfree(gExternalQuantTablePtr);
3100 gExternalQuantTablePtr = NULL;
3101 external_quant_table_available = false;
3102 #endif
3103 spin_lock(&gJpegenc.sem_lock);
3104 if (gJpegenc.opened > 0)
3105 gJpegenc.opened--;
3106 spin_unlock(&gJpegenc.sem_lock);
3107 jenc_pr(LOG_DEBUG, "jpegenc release\n");
3108 return 0;
3109 }
3110
jpegenc_ioctl(struct file * file,u32 cmd,ulong arg)3111 static long jpegenc_ioctl(struct file *file, u32 cmd, ulong arg)
3112 {
3113 long r = 0;
3114 struct jpegenc_wq_s *wq = (struct jpegenc_wq_s *)file->private_data;
3115 #define MAX_ADDR_INFO_SIZE 30
3116 u32 addr_info[MAX_ADDR_INFO_SIZE + 4];
3117 switch (cmd) {
3118 case JPEGENC_IOC_NEW_CMD:
3119 if (copy_from_user(addr_info, (void *)arg,
3120 MAX_ADDR_INFO_SIZE * sizeof(u32))) {
3121 jenc_pr(LOG_ERROR,
3122 "jpegenc get new cmd error.\n");
3123 return -1;
3124 }
3125 if (!convert_cmd(wq, addr_info))
3126 jpegenc_start_cmd(wq);
3127 break;
3128 case JPEGENC_IOC_GET_STAGE:
3129 put_user(wq->hw_status, (u32 *)arg);
3130 break;
3131 case JPEGENC_IOC_GET_OUTPUT_SIZE:
3132 cache_flush(wq->BitstreamStart, wq->output_size);
3133 addr_info[0] = wq->headbytes;
3134 addr_info[1] = wq->output_size;
3135 r = copy_to_user((u32 *)arg, addr_info , 2 * sizeof(u32));
3136 break;
3137 case JPEGENC_IOC_CONFIG_INIT:
3138 jpegenc_init();
3139 jpegenc_buffspec_init(wq);
3140 break;
3141 case JPEGENC_IOC_GET_BUFFINFO:
3142 addr_info[0] = gJpegenc.mem.buf_size;
3143 addr_info[1] = gJpegenc.mem.bufspec->input.buf_start;
3144 addr_info[2] = gJpegenc.mem.bufspec->input.buf_size;
3145 addr_info[3] = gJpegenc.mem.bufspec->assit.buf_start;
3146 addr_info[4] = gJpegenc.mem.bufspec->assit.buf_size;
3147 addr_info[5] = gJpegenc.mem.bufspec->bitstream.buf_start;
3148 addr_info[6] = gJpegenc.mem.bufspec->bitstream.buf_size;
3149 r = copy_to_user((u32 *)arg, addr_info , 7 * sizeof(u32));
3150
3151 break;
3152 case JPEGENC_IOC_GET_DEVINFO:
3153 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) {
3154 /* GXL send same id of GXTVBB to upper*/
3155 r = copy_to_user((s8 *)arg, JPEGENC_DEVINFO_GXTVBB,
3156 strlen(JPEGENC_DEVINFO_GXTVBB));
3157 } else if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXTVBB) {
3158 r = copy_to_user((s8 *)arg, JPEGENC_DEVINFO_GXTVBB,
3159 strlen(JPEGENC_DEVINFO_GXTVBB));
3160 } else if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXBB) {
3161 r = copy_to_user((s8 *)arg, JPEGENC_DEVINFO_GXBB,
3162 strlen(JPEGENC_DEVINFO_GXBB));
3163 } else if (get_cpu_type() == MESON_CPU_MAJOR_ID_MG9TV) {
3164 r = copy_to_user((s8 *)arg, JPEGENC_DEVINFO_G9,
3165 strlen(JPEGENC_DEVINFO_G9));
3166 } else {
3167 r = copy_to_user((s8 *)arg, JPEGENC_DEVINFO_M8,
3168 strlen(JPEGENC_DEVINFO_M8));
3169 }
3170 break;
3171 case JPEGENC_IOC_SET_EXT_QUANT_TABLE:
3172 #ifdef EXTEAN_QUANT_TABLE
3173 if (arg == 0) {
3174 kfree(gExternalQuantTablePtr);
3175 gExternalQuantTablePtr = NULL;
3176 external_quant_table_available = false;
3177 } else {
3178 void __user *argp = (void __user *)arg;
3179 gExternalQuantTablePtr =
3180 kmalloc(sizeof(u16) * DCTSIZE2 * 2,
3181 GFP_KERNEL);
3182 if (gExternalQuantTablePtr) {
3183 if (copy_from_user
3184 (gExternalQuantTablePtr, argp,
3185 sizeof(u16) * DCTSIZE2 * 2)) {
3186 r = -1;
3187 break;
3188 }
3189 external_quant_table_available = true;
3190 r = 0;
3191 } else {
3192 jenc_pr(LOG_ERROR,
3193 "gExternalQuantTablePtr malloc fail\n");
3194 r = -1;
3195 }
3196 }
3197 #else
3198 r = 0;
3199 #endif
3200 break;
3201 default:
3202 r = -1;
3203 break;
3204 }
3205 return r;
3206 }
3207
3208 #ifdef CONFIG_COMPAT
jpegenc_compat_ioctl(struct file * filp,unsigned int cmd,unsigned long args)3209 static long jpegenc_compat_ioctl(struct file *filp,
3210 unsigned int cmd, unsigned long args)
3211 {
3212 unsigned long ret;
3213
3214 args = (unsigned long)compat_ptr(args);
3215 ret = jpegenc_ioctl(filp, cmd, args);
3216 return ret;
3217 }
3218 #endif
3219
jpegenc_mmap(struct file * filp,struct vm_area_struct * vma)3220 static s32 jpegenc_mmap(struct file *filp, struct vm_area_struct *vma)
3221 {
3222 struct jpegenc_wq_s *wq = (struct jpegenc_wq_s *)filp->private_data;
3223 ulong off = vma->vm_pgoff << PAGE_SHIFT;
3224 ulong vma_size = vma->vm_end - vma->vm_start;
3225
3226 if (vma_size == 0) {
3227 jenc_pr(LOG_ERROR, "vma_size is 0\n");
3228 return -EAGAIN;
3229 }
3230 off += wq->buf_start;
3231 jenc_pr(LOG_INFO, "vma_size is %ld, off is %ld\n", vma_size, off);
3232 vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_IO;
3233 /* vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); */
3234 if (remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
3235 vma->vm_end - vma->vm_start, vma->vm_page_prot)) {
3236 jenc_pr(LOG_ERROR, "set_cached: failed remap_pfn_range\n");
3237 return -EAGAIN;
3238 }
3239 return 0;
3240 }
3241
jpegenc_poll(struct file * file,poll_table * wait_table)3242 static u32 jpegenc_poll(struct file *file, poll_table *wait_table)
3243 {
3244 struct jpegenc_wq_s *wq = (struct jpegenc_wq_s *)file->private_data;
3245 poll_wait(file, &wq->complete, wait_table);
3246
3247 if (atomic_read(&wq->ready)) {
3248 atomic_dec(&wq->ready);
3249 return POLLIN | POLLRDNORM;
3250 }
3251 return 0;
3252 }
3253
3254 static const struct file_operations jpegenc_fops = {
3255 .owner = THIS_MODULE,
3256 .open = jpegenc_open,
3257 .mmap = jpegenc_mmap,
3258 .release = jpegenc_release,
3259 .unlocked_ioctl = jpegenc_ioctl,
3260 #ifdef CONFIG_COMPAT
3261 .compat_ioctl = jpegenc_compat_ioctl,
3262 #endif
3263 .poll = jpegenc_poll,
3264 };
3265
jpegenc_wq_init(void)3266 static s32 jpegenc_wq_init(void)
3267 {
3268 jenc_pr(LOG_DEBUG, "jpegenc_wq_init.\n");
3269 gJpegenc.irq_requested = false;
3270 gJpegenc.process_irq = false;
3271 gJpegenc.inited = false;
3272 gJpegenc.opened = 0;
3273 gJpegenc.encode_hw_status = JPEGENC_ENCODER_IDLE;
3274 spin_lock_init(&gJpegenc.sem_lock);
3275
3276 tasklet_init(&gJpegenc.tasklet,
3277 jpegenc_isr_tasklet,
3278 (ulong)&gJpegenc);
3279
3280 if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)
3281 clock_level = 5;
3282 else if (get_cpu_type() >= MESON_CPU_MAJOR_ID_M8M2)
3283 clock_level = 3;
3284 else
3285 clock_level = 1;
3286 return 0;
3287 }
3288
jpegenc_wq_uninit(void)3289 static s32 jpegenc_wq_uninit(void)
3290 {
3291 s32 r = -1;
3292 jenc_pr(LOG_DEBUG, "uninit encode wq.\n");
3293 if (gJpegenc.encode_hw_status == JPEGENC_ENCODER_IDLE) {
3294 if ((gJpegenc.irq_num >= 0) &&
3295 (gJpegenc.irq_requested == true)) {
3296 free_irq(gJpegenc.irq_num, &gJpegenc);
3297 gJpegenc.irq_requested = false;
3298 }
3299 r = 0;
3300 }
3301 return r;
3302 }
3303
jpegenc_status_show(struct class * cla,struct class_attribute * attr,char * buf)3304 static ssize_t jpegenc_status_show(struct class *cla,
3305 struct class_attribute *attr, char *buf)
3306 {
3307 s32 irq_num;
3308 u32 hw_status, width, height;
3309 bool process_irq;
3310 bool inited;
3311 bool use_reserve;
3312 u32 cma_size, max_w, max_h;
3313 u32 buffer_start, buffer_size;
3314 u8 lev, opened;
3315 struct Jpegenc_Buff_s res;
3316
3317 spin_lock(&gJpegenc.sem_lock);
3318
3319 irq_num = gJpegenc.irq_num;
3320 hw_status = gJpegenc.encode_hw_status;
3321 process_irq = gJpegenc.process_irq;
3322 inited = gJpegenc.inited;
3323 opened = gJpegenc.opened;
3324 use_reserve = gJpegenc.use_reserve;
3325 res.buf_start = gJpegenc.mem.reserve_mem.buf_start;
3326 res.buf_size = gJpegenc.mem.reserve_mem.buf_size;
3327 buffer_start = gJpegenc.mem.buf_start;
3328 buffer_size = gJpegenc.mem.buf_size;
3329 lev = gJpegenc.mem.cur_buf_lev;
3330 max_w = gJpegenc.mem.bufspec->max_width;
3331 max_h = gJpegenc.mem.bufspec->max_height;
3332 width = gJpegenc.wq.cmd.encoder_width;
3333 height = gJpegenc.wq.cmd.encoder_height;
3334 #ifdef CONFIG_CMA
3335 cma_size = gJpegenc.mem.cma_pool_size / SZ_1M;
3336 #endif
3337 spin_unlock(&gJpegenc.sem_lock);
3338
3339 jenc_pr(LOG_DEBUG,
3340 "jpegenc width: %d, encode height: %d.\n",
3341 width, height);
3342 jenc_pr(LOG_DEBUG,
3343 "jpegenc hw_status: %d, process_irq: %s.\n",
3344 hw_status, process_irq ? "true" : "false");
3345 jenc_pr(LOG_DEBUG,
3346 "jpegenc irq num: %d, inited: %s, opened: %d\n",
3347 irq_num, inited ? "true" : "false", opened);
3348 if (use_reserve) {
3349 jenc_pr(LOG_DEBUG,
3350 "jpegenc reserve memory, buffer start: 0x%x, size: %d MB.\n",
3351 res.buf_start, res.buf_size / SZ_1M);
3352 } else {
3353 #ifdef CONFIG_CMA
3354 jenc_pr(LOG_DEBUG, "jpegenc cma pool size: %d.\n", cma_size);
3355 #endif
3356 }
3357 jenc_pr(LOG_DEBUG, "jpegenc buffer start: 0x%x, size: 0x%x\n",
3358 buffer_start, buffer_size);
3359 jenc_pr(LOG_DEBUG, "buffer level: %s\n", glevel_str[lev]);
3360 return snprintf(buf, 40, "max size: %dx%d\n", max_w, max_h);
3361 }
3362
3363 static CLASS_ATTR_RO(jpegenc_status);
3364
3365 static struct attribute *jpegenc_class_attrs[] = {
3366 &class_attr_jpegenc_status.attr,
3367 NULL
3368 };
3369
3370 ATTRIBUTE_GROUPS(jpegenc_class);
3371
3372 static struct class jpegenc_class = {
3373 .name = CLASS_NAME,
3374 .class_groups = jpegenc_class_groups,
3375 };
3376
init_jpegenc_device(void)3377 s32 init_jpegenc_device(void)
3378 {
3379 s32 r = 0;
3380 r = register_chrdev(0, DEVICE_NAME, &jpegenc_fops);
3381 if (r <= 0) {
3382 jenc_pr(LOG_ERROR, "register jpegenc device error\n");
3383 return r;
3384 }
3385 jpegenc_device_major = r;
3386
3387 r = class_register(&jpegenc_class);
3388 if (r < 0) {
3389 jenc_pr(LOG_ERROR, "error create jpegenc class.\n");
3390 return r;
3391 }
3392
3393 jpegenc_dev = device_create(&jpegenc_class, NULL,
3394 MKDEV(jpegenc_device_major, 0), NULL,
3395 DEVICE_NAME);
3396
3397 if (IS_ERR(jpegenc_dev)) {
3398 jenc_pr(LOG_ERROR, "create jpegenc device error.\n");
3399 class_unregister(&jpegenc_class);
3400 return -1;
3401 }
3402 return r;
3403 }
3404
uninit_jpegenc_device(void)3405 s32 uninit_jpegenc_device(void)
3406 {
3407 if (jpegenc_dev)
3408 device_destroy(&jpegenc_class, MKDEV(jpegenc_device_major, 0));
3409
3410 class_destroy(&jpegenc_class);
3411
3412 unregister_chrdev(jpegenc_device_major, DEVICE_NAME);
3413 return 0;
3414 }
3415
jpegenc_mem_device_init(struct reserved_mem * rmem,struct device * dev)3416 static s32 jpegenc_mem_device_init(struct reserved_mem *rmem,
3417 struct device *dev)
3418 {
3419 s32 r;
3420 struct resource res;
3421 if (!rmem) {
3422 jenc_pr(LOG_ERROR,
3423 "Can't obtain I/O memory, will allocate jpegenc buffer!\n");
3424 r = -EFAULT;
3425 return r;
3426 }
3427 res.start = (phys_addr_t) rmem->base;
3428 res.end = res.start + (phys_addr_t) rmem->size - 1;
3429 gJpegenc.mem.reserve_mem.buf_start = res.start;
3430 gJpegenc.mem.reserve_mem.buf_size = res.end - res.start + 1;
3431 if (gJpegenc.mem.reserve_mem.buf_size >=
3432 jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_VGA].min_buffsize)
3433 gJpegenc.use_reserve = true;
3434 else {
3435 jenc_pr(LOG_ERROR,
3436 "jpegenc reserve_mem too small, size is %d.\n",
3437 gJpegenc.mem.reserve_mem.buf_size);
3438 gJpegenc.mem.reserve_mem.buf_start = 0;
3439 gJpegenc.mem.reserve_mem.buf_size = 0;
3440 return -EFAULT;
3441 }
3442 return r;
3443 }
3444
jpegenc_probe(struct platform_device * pdev)3445 static s32 jpegenc_probe(struct platform_device *pdev)
3446 {
3447 s32 res_irq;
3448 s32 idx;
3449
3450 jenc_pr(LOG_DEBUG, "jpegenc probe start.\n");
3451
3452 gJpegenc.this_pdev = pdev;
3453 gJpegenc.use_reserve = false;
3454 memset(&gJpegenc.mem, 0, sizeof(struct jpegenc_meminfo_s));
3455
3456 idx = of_reserved_mem_device_init(&pdev->dev);
3457
3458 if (idx != 0) {
3459 jenc_pr(LOG_DEBUG,
3460 "jpegenc memory resource undefined.\n");
3461 }
3462
3463 if (gJpegenc.use_reserve == false) {
3464 #ifndef CONFIG_CMA
3465 jenc_pr(LOG_ERROR,
3466 "jpegenc memory is invaild, probe fail!\n");
3467 return -EFAULT;
3468 #else
3469 gJpegenc.mem.cma_pool_size = 0x2300000;
3470 //codec_mm_get_total_size();
3471
3472 jenc_pr(LOG_ERROR,
3473 "jpegenc - cma memory pool size: %d MB\n",
3474 (u32)gJpegenc.mem.cma_pool_size / SZ_1M);
3475
3476 gJpegenc.mem.buf_size = gJpegenc.mem.cma_pool_size;
3477 gJpegenc.mem.buf_size = 0x2300000;
3478 #endif
3479 } else {
3480 gJpegenc.mem.buf_start = gJpegenc.mem.reserve_mem.buf_start;
3481 gJpegenc.mem.buf_size = gJpegenc.mem.reserve_mem.buf_size;
3482 }
3483
3484 if (gJpegenc.mem.buf_size >=
3485 jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_HD].min_buffsize) {
3486 gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_HD;
3487 gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
3488 &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_HD];
3489 } else if (gJpegenc.mem.buf_size >=
3490 jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_13M].min_buffsize) {
3491 gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_13M;
3492 gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
3493 &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_13M];
3494 } else if (gJpegenc.mem.buf_size >=
3495 jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_8M].min_buffsize) {
3496 gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_8M;
3497 gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
3498 &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_8M];
3499 } else if (gJpegenc.mem.buf_size >=
3500 jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_5M].min_buffsize) {
3501 gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_5M;
3502 gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
3503 &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_5M];
3504 } else if (gJpegenc.mem.buf_size >=
3505 jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_3M].min_buffsize) {
3506 gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_3M;
3507 gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
3508 &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_3M];
3509 } else if (gJpegenc.mem.buf_size >=
3510 jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_2M].min_buffsize) {
3511 gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_2M;
3512 gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
3513 &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_2M];
3514 } else if (gJpegenc.mem.buf_size >=
3515 jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_VGA].min_buffsize) {
3516 gJpegenc.mem.cur_buf_lev = JPEGENC_BUFFER_LEVEL_VGA;
3517 gJpegenc.mem.bufspec = (struct Jpegenc_BuffInfo_s *)
3518 &jpegenc_buffspec[JPEGENC_BUFFER_LEVEL_VGA];
3519 } else {
3520 jenc_pr(LOG_ERROR,
3521 "jpegenc probe memory too small, size is %d.\n",
3522 gJpegenc.mem.buf_size);
3523 gJpegenc.mem.buf_start = 0;
3524 gJpegenc.mem.buf_size = 0;
3525 return -EFAULT;
3526 }
3527
3528 res_irq = platform_get_irq(pdev, 0);
3529 if (res_irq < 0) {
3530 jenc_pr(LOG_ERROR, "[%s] get irq error!", __func__);
3531 return -EINVAL;
3532 }
3533
3534 gJpegenc.irq_num = res_irq;
3535
3536 jenc_pr(LOG_DEBUG,
3537 "jpegenc memory config sucess, buff size is 0x%x, level: %s\n",
3538 gJpegenc.mem.buf_size,
3539 glevel_str[gJpegenc.mem.cur_buf_lev]);
3540
3541 jpegenc_wq_init();
3542 init_jpegenc_device();
3543 jenc_pr(LOG_DEBUG, "jpegenc probe end.\n");
3544 return 0;
3545 }
3546
jpegenc_remove(struct platform_device * pdev)3547 static s32 jpegenc_remove(struct platform_device *pdev)
3548 {
3549 if (jpegenc_wq_uninit())
3550 jenc_pr(LOG_ERROR, "jpegenc_wq_uninit error.\n");
3551 uninit_jpegenc_device();
3552 jenc_pr(LOG_DEBUG, "jpegenc remove.\n");
3553 return 0;
3554 }
3555
3556 static const struct of_device_id amlogic_jpegenc_dt_match[] = {
3557 {
3558 .compatible = "amlogic, jpegenc",
3559 },
3560 {},
3561 };
3562
3563 static struct platform_driver jpegenc_driver = {
3564 .probe = jpegenc_probe,
3565 .remove = jpegenc_remove,
3566 .driver = {
3567 .name = DRIVER_NAME,
3568 .of_match_table = amlogic_jpegenc_dt_match,
3569 }
3570 };
3571
3572 static struct codec_profile_t jpegenc_profile = {
3573 .name = "jpegenc",
3574 .profile = ""
3575 };
3576
jpegenc_driver_init_module(void)3577 static s32 __init jpegenc_driver_init_module(void)
3578 {
3579 jenc_pr(LOG_DEBUG, "jpegenc module init\n");
3580
3581 if (platform_driver_register(&jpegenc_driver)) {
3582 jenc_pr(LOG_ERROR, "failed to register jpegenc driver\n");
3583 return -ENODEV;
3584 }
3585 vcodec_profile_register(&jpegenc_profile);
3586 return 0;
3587 }
3588
jpegenc_driver_remove_module(void)3589 static void __exit jpegenc_driver_remove_module(void)
3590 {
3591 jenc_pr(LOG_DEBUG, "jpegenc module remove.\n");
3592 platform_driver_unregister(&jpegenc_driver);
3593 }
3594
3595 static const struct reserved_mem_ops rmem_jpegenc_ops = {
3596 .device_init = jpegenc_mem_device_init,
3597 };
3598
jpegenc_mem_setup(struct reserved_mem * rmem)3599 static s32 __init jpegenc_mem_setup(struct reserved_mem *rmem)
3600 {
3601 rmem->ops = &rmem_jpegenc_ops;
3602 jenc_pr(LOG_DEBUG, "jpegenc reserved mem setup.\n");
3603 return 0;
3604 }
3605
3606 module_param(clock_level, uint, 0664);
3607 MODULE_PARM_DESC(clock_level, "\n clock_level\n");
3608
3609 module_param(jpegenc_print_level, uint, 0664);
3610 MODULE_PARM_DESC(jpegenc_print_level, "\n jpegenc_print_level\n");
3611
3612 module_init(jpegenc_driver_init_module);
3613 module_exit(jpegenc_driver_remove_module);
3614 RESERVEDMEM_OF_DECLARE(jpegenc, "amlogic, jpegenc-memory", jpegenc_mem_setup);
3615
3616 MODULE_DESCRIPTION("AMLOGIC JPEG Encoder Driver");
3617 MODULE_LICENSE("GPL");
3618 MODULE_AUTHOR("simon.zheng <simon.zheng@amlogic.com>");
3619