• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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