1/* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c
2 *
3 * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
4 *		http://www.samsung.com
5 *
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
7 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/clk.h>
15#include <linux/err.h>
16#include <linux/gfp.h>
17#include <linux/interrupt.h>
18#include <linux/io.h>
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <linux/of.h>
22#include <linux/platform_device.h>
23#include <linux/pm_runtime.h>
24#include <linux/slab.h>
25#include <linux/spinlock.h>
26#include <linux/string.h>
27#include <media/v4l2-mem2mem.h>
28#include <media/v4l2-ioctl.h>
29#include <media/videobuf2-core.h>
30#include <media/videobuf2-dma-contig.h>
31
32#include "jpeg-core.h"
33#include "jpeg-hw-s5p.h"
34#include "jpeg-hw-exynos4.h"
35#include "jpeg-hw-exynos3250.h"
36#include "jpeg-regs.h"
37
38static struct s5p_jpeg_fmt sjpeg_formats[] = {
39	{
40		.name		= "JPEG JFIF",
41		.fourcc		= V4L2_PIX_FMT_JPEG,
42		.flags		= SJPEG_FMT_FLAG_ENC_CAPTURE |
43				  SJPEG_FMT_FLAG_DEC_OUTPUT |
44				  SJPEG_FMT_FLAG_S5P |
45				  SJPEG_FMT_FLAG_EXYNOS3250 |
46				  SJPEG_FMT_FLAG_EXYNOS4,
47	},
48	{
49		.name		= "YUV 4:2:2 packed, YCbYCr",
50		.fourcc		= V4L2_PIX_FMT_YUYV,
51		.depth		= 16,
52		.colplanes	= 1,
53		.h_align	= 4,
54		.v_align	= 3,
55		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
56				  SJPEG_FMT_FLAG_DEC_CAPTURE |
57				  SJPEG_FMT_FLAG_S5P |
58				  SJPEG_FMT_NON_RGB,
59		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
60	},
61	{
62		.name		= "YUV 4:2:2 packed, YCbYCr",
63		.fourcc		= V4L2_PIX_FMT_YUYV,
64		.depth		= 16,
65		.colplanes	= 1,
66		.h_align	= 1,
67		.v_align	= 0,
68		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
69				  SJPEG_FMT_FLAG_DEC_CAPTURE |
70				  SJPEG_FMT_FLAG_EXYNOS4 |
71				  SJPEG_FMT_NON_RGB,
72		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
73	},
74	{
75		.name		= "YUV 4:2:2 packed, YCbYCr",
76		.fourcc		= V4L2_PIX_FMT_YUYV,
77		.depth		= 16,
78		.colplanes	= 1,
79		.h_align	= 2,
80		.v_align	= 0,
81		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
82				  SJPEG_FMT_FLAG_DEC_CAPTURE |
83				  SJPEG_FMT_FLAG_EXYNOS3250 |
84				  SJPEG_FMT_NON_RGB,
85		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
86	},
87	{
88		.name		= "YUV 4:2:2 packed, YCrYCb",
89		.fourcc		= V4L2_PIX_FMT_YVYU,
90		.depth		= 16,
91		.colplanes	= 1,
92		.h_align	= 1,
93		.v_align	= 0,
94		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
95				  SJPEG_FMT_FLAG_DEC_CAPTURE |
96				  SJPEG_FMT_FLAG_EXYNOS4 |
97				  SJPEG_FMT_NON_RGB,
98		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
99	},
100	{
101		.name		= "YUV 4:2:2 packed, YCrYCb",
102		.fourcc		= V4L2_PIX_FMT_YVYU,
103		.depth		= 16,
104		.colplanes	= 1,
105		.h_align	= 2,
106		.v_align	= 0,
107		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
108				  SJPEG_FMT_FLAG_DEC_CAPTURE |
109				  SJPEG_FMT_FLAG_EXYNOS3250 |
110				  SJPEG_FMT_NON_RGB,
111		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
112	},
113	{
114		.name		= "YUV 4:2:2 packed, YCrYCb",
115		.fourcc		= V4L2_PIX_FMT_UYVY,
116		.depth		= 16,
117		.colplanes	= 1,
118		.h_align	= 2,
119		.v_align	= 0,
120		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
121				  SJPEG_FMT_FLAG_DEC_CAPTURE |
122				  SJPEG_FMT_FLAG_EXYNOS3250 |
123				  SJPEG_FMT_NON_RGB,
124		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
125	},
126	{
127		.name		= "YUV 4:2:2 packed, YCrYCb",
128		.fourcc		= V4L2_PIX_FMT_VYUY,
129		.depth		= 16,
130		.colplanes	= 1,
131		.h_align	= 2,
132		.v_align	= 0,
133		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
134				  SJPEG_FMT_FLAG_DEC_CAPTURE |
135				  SJPEG_FMT_FLAG_EXYNOS3250 |
136				  SJPEG_FMT_NON_RGB,
137		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
138	},
139	{
140		.name		= "RGB565",
141		.fourcc		= V4L2_PIX_FMT_RGB565,
142		.depth		= 16,
143		.colplanes	= 1,
144		.h_align	= 0,
145		.v_align	= 0,
146		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
147				  SJPEG_FMT_FLAG_DEC_CAPTURE |
148				  SJPEG_FMT_FLAG_EXYNOS4 |
149				  SJPEG_FMT_RGB,
150		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
151	},
152	{
153		.name		= "RGB565",
154		.fourcc		= V4L2_PIX_FMT_RGB565,
155		.depth		= 16,
156		.colplanes	= 1,
157		.h_align	= 2,
158		.v_align	= 0,
159		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
160				  SJPEG_FMT_FLAG_DEC_CAPTURE |
161				  SJPEG_FMT_FLAG_EXYNOS3250 |
162				  SJPEG_FMT_RGB,
163		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
164	},
165	{
166		.name		= "RGB565X",
167		.fourcc		= V4L2_PIX_FMT_RGB565X,
168		.depth		= 16,
169		.colplanes	= 1,
170		.h_align	= 2,
171		.v_align	= 0,
172		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
173				  SJPEG_FMT_FLAG_DEC_CAPTURE |
174				  SJPEG_FMT_FLAG_EXYNOS3250 |
175				  SJPEG_FMT_RGB,
176		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
177	},
178	{
179		.name		= "RGB565",
180		.fourcc		= V4L2_PIX_FMT_RGB565,
181		.depth		= 16,
182		.colplanes	= 1,
183		.h_align	= 0,
184		.v_align	= 0,
185		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
186				  SJPEG_FMT_FLAG_S5P |
187				  SJPEG_FMT_RGB,
188		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
189	},
190	{
191		.name		= "ARGB8888, 32 bpp",
192		.fourcc		= V4L2_PIX_FMT_RGB32,
193		.depth		= 32,
194		.colplanes	= 1,
195		.h_align	= 0,
196		.v_align	= 0,
197		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
198				  SJPEG_FMT_FLAG_DEC_CAPTURE |
199				  SJPEG_FMT_FLAG_EXYNOS4 |
200				  SJPEG_FMT_RGB,
201		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
202	},
203	{
204		.name		= "ARGB8888, 32 bpp",
205		.fourcc		= V4L2_PIX_FMT_RGB32,
206		.depth		= 32,
207		.colplanes	= 1,
208		.h_align	= 2,
209		.v_align	= 0,
210		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
211				  SJPEG_FMT_FLAG_DEC_CAPTURE |
212				  SJPEG_FMT_FLAG_EXYNOS3250 |
213				  SJPEG_FMT_RGB,
214		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
215	},
216	{
217		.name		= "YUV 4:4:4 planar, Y/CbCr",
218		.fourcc		= V4L2_PIX_FMT_NV24,
219		.depth		= 24,
220		.colplanes	= 2,
221		.h_align	= 0,
222		.v_align	= 0,
223		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
224				  SJPEG_FMT_FLAG_DEC_CAPTURE |
225				  SJPEG_FMT_FLAG_EXYNOS4 |
226				  SJPEG_FMT_NON_RGB,
227		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
228	},
229	{
230		.name		= "YUV 4:4:4 planar, Y/CrCb",
231		.fourcc		= V4L2_PIX_FMT_NV42,
232		.depth		= 24,
233		.colplanes	= 2,
234		.h_align	= 0,
235		.v_align	= 0,
236		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
237				  SJPEG_FMT_FLAG_DEC_CAPTURE |
238				  SJPEG_FMT_FLAG_EXYNOS4 |
239				  SJPEG_FMT_NON_RGB,
240		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_444,
241	},
242	{
243		.name		= "YUV 4:2:2 planar, Y/CrCb",
244		.fourcc		= V4L2_PIX_FMT_NV61,
245		.depth		= 16,
246		.colplanes	= 2,
247		.h_align	= 1,
248		.v_align	= 0,
249		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
250				  SJPEG_FMT_FLAG_DEC_CAPTURE |
251				  SJPEG_FMT_FLAG_EXYNOS4 |
252				  SJPEG_FMT_NON_RGB,
253		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
254	},
255	{
256		.name		= "YUV 4:2:2 planar, Y/CbCr",
257		.fourcc		= V4L2_PIX_FMT_NV16,
258		.depth		= 16,
259		.colplanes	= 2,
260		.h_align	= 1,
261		.v_align	= 0,
262		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
263				  SJPEG_FMT_FLAG_DEC_CAPTURE |
264				  SJPEG_FMT_FLAG_EXYNOS4 |
265				  SJPEG_FMT_NON_RGB,
266		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_422,
267	},
268	{
269		.name		= "YUV 4:2:0 planar, Y/CbCr",
270		.fourcc		= V4L2_PIX_FMT_NV12,
271		.depth		= 12,
272		.colplanes	= 2,
273		.h_align	= 1,
274		.v_align	= 1,
275		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
276				  SJPEG_FMT_FLAG_DEC_CAPTURE |
277				  SJPEG_FMT_FLAG_EXYNOS4 |
278				  SJPEG_FMT_NON_RGB,
279		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
280	},
281	{
282		.name		= "YUV 4:2:0 planar, Y/CbCr",
283		.fourcc		= V4L2_PIX_FMT_NV12,
284		.depth		= 12,
285		.colplanes	= 2,
286		.h_align	= 3,
287		.v_align	= 3,
288		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
289				  SJPEG_FMT_FLAG_DEC_CAPTURE |
290				  SJPEG_FMT_FLAG_EXYNOS3250 |
291				  SJPEG_FMT_NON_RGB,
292		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
293	},
294	{
295		.name		= "YUV 4:2:0 planar, Y/CbCr",
296		.fourcc		= V4L2_PIX_FMT_NV12,
297		.depth		= 12,
298		.colplanes	= 2,
299		.h_align	= 4,
300		.v_align	= 4,
301		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
302				  SJPEG_FMT_FLAG_DEC_CAPTURE |
303				  SJPEG_FMT_FLAG_S5P |
304				  SJPEG_FMT_NON_RGB,
305		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
306	},
307	{
308		.name		= "YUV 4:2:0 planar, Y/CrCb",
309		.fourcc		= V4L2_PIX_FMT_NV21,
310		.depth		= 12,
311		.colplanes	= 2,
312		.h_align	= 3,
313		.v_align	= 3,
314		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
315				  SJPEG_FMT_FLAG_DEC_CAPTURE |
316				  SJPEG_FMT_FLAG_EXYNOS3250 |
317				  SJPEG_FMT_NON_RGB,
318		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
319	},
320	{
321		.name		= "YUV 4:2:0 planar, Y/CrCb",
322		.fourcc		= V4L2_PIX_FMT_NV21,
323		.depth		= 12,
324		.colplanes	= 2,
325		.h_align	= 1,
326		.v_align	= 1,
327		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
328				  SJPEG_FMT_FLAG_DEC_CAPTURE |
329				  SJPEG_FMT_FLAG_EXYNOS3250 |
330				  SJPEG_FMT_FLAG_EXYNOS4 |
331				  SJPEG_FMT_NON_RGB,
332		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
333	},
334	{
335		.name		= "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
336		.fourcc		= V4L2_PIX_FMT_YUV420,
337		.depth		= 12,
338		.colplanes	= 3,
339		.h_align	= 1,
340		.v_align	= 1,
341		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
342				  SJPEG_FMT_FLAG_DEC_CAPTURE |
343				  SJPEG_FMT_FLAG_EXYNOS4 |
344				  SJPEG_FMT_NON_RGB,
345		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
346	},
347	{
348		.name		= "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
349		.fourcc		= V4L2_PIX_FMT_YUV420,
350		.depth		= 12,
351		.colplanes	= 3,
352		.h_align	= 4,
353		.v_align	= 4,
354		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
355				  SJPEG_FMT_FLAG_DEC_CAPTURE |
356				  SJPEG_FMT_FLAG_EXYNOS3250 |
357				  SJPEG_FMT_NON_RGB,
358		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_420,
359	},
360	{
361		.name		= "Gray",
362		.fourcc		= V4L2_PIX_FMT_GREY,
363		.depth		= 8,
364		.colplanes	= 1,
365		.flags		= SJPEG_FMT_FLAG_ENC_OUTPUT |
366				  SJPEG_FMT_FLAG_DEC_CAPTURE |
367				  SJPEG_FMT_FLAG_EXYNOS4 |
368				  SJPEG_FMT_NON_RGB,
369		.subsampling	= V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
370	},
371};
372#define SJPEG_NUM_FORMATS ARRAY_SIZE(sjpeg_formats)
373
374static const unsigned char qtbl_luminance[4][64] = {
375	{/*level 0 - high compression quality */
376		20, 16, 25, 39, 50, 46, 62, 68,
377		16, 18, 23, 38, 38, 53, 65, 68,
378		25, 23, 31, 38, 53, 65, 68, 68,
379		39, 38, 38, 53, 65, 68, 68, 68,
380		50, 38, 53, 65, 68, 68, 68, 68,
381		46, 53, 65, 68, 68, 68, 68, 68,
382		62, 65, 68, 68, 68, 68, 68, 68,
383		68, 68, 68, 68, 68, 68, 68, 68
384	},
385	{/* level 1 */
386		16, 11, 11, 16, 23, 27, 31, 30,
387		11, 12, 12, 15, 20, 23, 23, 30,
388		11, 12, 13, 16, 23, 26, 35, 47,
389		16, 15, 16, 23, 26, 37, 47, 64,
390		23, 20, 23, 26, 39, 51, 64, 64,
391		27, 23, 26, 37, 51, 64, 64, 64,
392		31, 23, 35, 47, 64, 64, 64, 64,
393		30, 30, 47, 64, 64, 64, 64, 64
394	},
395	{/* level 2 */
396		12,  8,  8, 12, 17, 21, 24, 23,
397		 8,  9,  9, 11, 15, 19, 18, 23,
398		 8,  9, 10, 12, 19, 20, 27, 36,
399		12, 11, 12, 21, 20, 28, 36, 53,
400		17, 15, 19, 20, 30, 39, 51, 59,
401		21, 19, 20, 28, 39, 51, 59, 59,
402		24, 18, 27, 36, 51, 59, 59, 59,
403		23, 23, 36, 53, 59, 59, 59, 59
404	},
405	{/* level 3 - low compression quality */
406		 8,  6,  6,  8, 12, 14, 16, 17,
407		 6,  6,  6,  8, 10, 13, 12, 15,
408		 6,  6,  7,  8, 13, 14, 18, 24,
409		 8,  8,  8, 14, 13, 19, 24, 35,
410		12, 10, 13, 13, 20, 26, 34, 39,
411		14, 13, 14, 19, 26, 34, 39, 39,
412		16, 12, 18, 24, 34, 39, 39, 39,
413		17, 15, 24, 35, 39, 39, 39, 39
414	}
415};
416
417static const unsigned char qtbl_chrominance[4][64] = {
418	{/*level 0 - high compression quality */
419		21, 25, 32, 38, 54, 68, 68, 68,
420		25, 28, 24, 38, 54, 68, 68, 68,
421		32, 24, 32, 43, 66, 68, 68, 68,
422		38, 38, 43, 53, 68, 68, 68, 68,
423		54, 54, 66, 68, 68, 68, 68, 68,
424		68, 68, 68, 68, 68, 68, 68, 68,
425		68, 68, 68, 68, 68, 68, 68, 68,
426		68, 68, 68, 68, 68, 68, 68, 68
427	},
428	{/* level 1 */
429		17, 15, 17, 21, 20, 26, 38, 48,
430		15, 19, 18, 17, 20, 26, 35, 43,
431		17, 18, 20, 22, 26, 30, 46, 53,
432		21, 17, 22, 28, 30, 39, 53, 64,
433		20, 20, 26, 30, 39, 48, 64, 64,
434		26, 26, 30, 39, 48, 63, 64, 64,
435		38, 35, 46, 53, 64, 64, 64, 64,
436		48, 43, 53, 64, 64, 64, 64, 64
437	},
438	{/* level 2 */
439		13, 11, 13, 16, 20, 20, 29, 37,
440		11, 14, 14, 14, 16, 20, 26, 32,
441		13, 14, 15, 17, 20, 23, 35, 40,
442		16, 14, 17, 21, 23, 30, 40, 50,
443		20, 16, 20, 23, 30, 37, 50, 59,
444		20, 20, 23, 30, 37, 48, 59, 59,
445		29, 26, 35, 40, 50, 59, 59, 59,
446		37, 32, 40, 50, 59, 59, 59, 59
447	},
448	{/* level 3 - low compression quality */
449		 9,  8,  9, 11, 14, 17, 19, 24,
450		 8, 10,  9, 11, 14, 13, 17, 22,
451		 9,  9, 13, 14, 13, 15, 23, 26,
452		11, 11, 14, 14, 15, 20, 26, 33,
453		14, 14, 13, 15, 20, 24, 33, 39,
454		17, 13, 15, 20, 24, 32, 39, 39,
455		19, 17, 23, 26, 33, 39, 39, 39,
456		24, 22, 26, 33, 39, 39, 39, 39
457	}
458};
459
460static const unsigned char hdctbl0[16] = {
461	0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
462};
463
464static const unsigned char hdctblg0[12] = {
465	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
466};
467static const unsigned char hactbl0[16] = {
468	0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
469};
470static const unsigned char hactblg0[162] = {
471	0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
472	0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
473	0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
474	0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
475	0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
476	0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
477	0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
478	0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
479	0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
480	0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
481	0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
482	0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
483	0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
484	0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
485	0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
486	0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
487	0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
488	0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
489	0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
490	0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
491	0xf9, 0xfa
492};
493
494/*
495 * Fourcc downgrade schema lookup tables for 422 and 420
496 * chroma subsampling - fourcc on each position maps on the
497 * fourcc from the table fourcc_to_dwngrd_schema_id which allows
498 * to get the most suitable fourcc counterpart for the given
499 * downgraded subsampling property.
500 */
501static const u32 subs422_fourcc_dwngrd_schema[] = {
502	V4L2_PIX_FMT_NV16,
503	V4L2_PIX_FMT_NV61,
504};
505
506static const u32 subs420_fourcc_dwngrd_schema[] = {
507	V4L2_PIX_FMT_NV12,
508	V4L2_PIX_FMT_NV21,
509	V4L2_PIX_FMT_NV12,
510	V4L2_PIX_FMT_NV21,
511	V4L2_PIX_FMT_NV12,
512	V4L2_PIX_FMT_NV21,
513	V4L2_PIX_FMT_GREY,
514	V4L2_PIX_FMT_GREY,
515	V4L2_PIX_FMT_GREY,
516	V4L2_PIX_FMT_GREY,
517};
518
519/*
520 * Lookup table for translation of a fourcc to the position
521 * of its downgraded counterpart in the *fourcc_dwngrd_schema
522 * tables.
523 */
524static const u32 fourcc_to_dwngrd_schema_id[] = {
525	V4L2_PIX_FMT_NV24,
526	V4L2_PIX_FMT_NV42,
527	V4L2_PIX_FMT_NV16,
528	V4L2_PIX_FMT_NV61,
529	V4L2_PIX_FMT_YUYV,
530	V4L2_PIX_FMT_YVYU,
531	V4L2_PIX_FMT_NV12,
532	V4L2_PIX_FMT_NV21,
533	V4L2_PIX_FMT_YUV420,
534	V4L2_PIX_FMT_GREY,
535};
536
537static int s5p_jpeg_get_dwngrd_sch_id_by_fourcc(u32 fourcc)
538{
539	int i;
540	for (i = 0; i < ARRAY_SIZE(fourcc_to_dwngrd_schema_id); ++i) {
541		if (fourcc_to_dwngrd_schema_id[i] == fourcc)
542			return i;
543	}
544
545	return -EINVAL;
546}
547
548static int s5p_jpeg_adjust_fourcc_to_subsampling(
549					enum v4l2_jpeg_chroma_subsampling subs,
550					u32 in_fourcc,
551					u32 *out_fourcc,
552					struct s5p_jpeg_ctx *ctx)
553{
554	int dwngrd_sch_id;
555
556	if (ctx->subsampling != V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
557		dwngrd_sch_id =
558			s5p_jpeg_get_dwngrd_sch_id_by_fourcc(in_fourcc);
559		if (dwngrd_sch_id < 0)
560			return -EINVAL;
561	}
562
563	switch (ctx->subsampling) {
564	case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
565		*out_fourcc = V4L2_PIX_FMT_GREY;
566		break;
567	case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
568		if (dwngrd_sch_id >
569				ARRAY_SIZE(subs420_fourcc_dwngrd_schema) - 1)
570			return -EINVAL;
571		*out_fourcc = subs420_fourcc_dwngrd_schema[dwngrd_sch_id];
572		break;
573	case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
574		if (dwngrd_sch_id >
575				ARRAY_SIZE(subs422_fourcc_dwngrd_schema) - 1)
576			return -EINVAL;
577		*out_fourcc = subs422_fourcc_dwngrd_schema[dwngrd_sch_id];
578		break;
579	default:
580		*out_fourcc = V4L2_PIX_FMT_GREY;
581		break;
582	}
583
584	return 0;
585}
586
587static int exynos4x12_decoded_subsampling[] = {
588	V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
589	V4L2_JPEG_CHROMA_SUBSAMPLING_444,
590	V4L2_JPEG_CHROMA_SUBSAMPLING_422,
591	V4L2_JPEG_CHROMA_SUBSAMPLING_420,
592};
593
594static int exynos3250_decoded_subsampling[] = {
595	V4L2_JPEG_CHROMA_SUBSAMPLING_444,
596	V4L2_JPEG_CHROMA_SUBSAMPLING_422,
597	V4L2_JPEG_CHROMA_SUBSAMPLING_420,
598	V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
599	-1,
600	-1,
601	V4L2_JPEG_CHROMA_SUBSAMPLING_411,
602};
603
604static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
605{
606	return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
607}
608
609static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
610{
611	return container_of(fh, struct s5p_jpeg_ctx, fh);
612}
613
614static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
615{
616	WARN_ON(ctx->subsampling > 3);
617
618	switch (ctx->jpeg->variant->version) {
619	case SJPEG_S5P:
620		if (ctx->subsampling > 2)
621			return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
622		return ctx->subsampling;
623	case SJPEG_EXYNOS3250:
624	case SJPEG_EXYNOS5420:
625		if (ctx->subsampling > 3)
626			return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
627		return exynos3250_decoded_subsampling[ctx->subsampling];
628	case SJPEG_EXYNOS4:
629		if (ctx->subsampling > 2)
630			return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
631		return exynos4x12_decoded_subsampling[ctx->subsampling];
632	default:
633		return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
634	}
635}
636
637static inline void s5p_jpeg_set_qtbl(void __iomem *regs,
638				     const unsigned char *qtbl,
639				     unsigned long tab, int len)
640{
641	int i;
642
643	for (i = 0; i < len; i++)
644		writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
645}
646
647static inline void s5p_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
648{
649	/* this driver fills quantisation table 0 with data for luma */
650	s5p_jpeg_set_qtbl(regs, qtbl_luminance[quality],
651			  S5P_JPG_QTBL_CONTENT(0),
652			  ARRAY_SIZE(qtbl_luminance[quality]));
653}
654
655static inline void s5p_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
656{
657	/* this driver fills quantisation table 1 with data for chroma */
658	s5p_jpeg_set_qtbl(regs, qtbl_chrominance[quality],
659			  S5P_JPG_QTBL_CONTENT(1),
660			  ARRAY_SIZE(qtbl_chrominance[quality]));
661}
662
663static inline void s5p_jpeg_set_htbl(void __iomem *regs,
664				     const unsigned char *htbl,
665				     unsigned long tab, int len)
666{
667	int i;
668
669	for (i = 0; i < len; i++)
670		writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
671}
672
673static inline void s5p_jpeg_set_hdctbl(void __iomem *regs)
674{
675	/* this driver fills table 0 for this component */
676	s5p_jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0),
677						ARRAY_SIZE(hdctbl0));
678}
679
680static inline void s5p_jpeg_set_hdctblg(void __iomem *regs)
681{
682	/* this driver fills table 0 for this component */
683	s5p_jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0),
684						ARRAY_SIZE(hdctblg0));
685}
686
687static inline void s5p_jpeg_set_hactbl(void __iomem *regs)
688{
689	/* this driver fills table 0 for this component */
690	s5p_jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0),
691						ARRAY_SIZE(hactbl0));
692}
693
694static inline void s5p_jpeg_set_hactblg(void __iomem *regs)
695{
696	/* this driver fills table 0 for this component */
697	s5p_jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0),
698						ARRAY_SIZE(hactblg0));
699}
700
701static inline void exynos4_jpeg_set_tbl(void __iomem *regs,
702					const unsigned char *tbl,
703					unsigned long tab, int len)
704{
705	int i;
706	unsigned int dword;
707
708	for (i = 0; i < len; i += 4) {
709		dword = tbl[i] |
710			(tbl[i + 1] << 8) |
711			(tbl[i + 2] << 16) |
712			(tbl[i + 3] << 24);
713		writel(dword, regs + tab + i);
714	}
715}
716
717static inline void exynos4_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
718{
719	/* this driver fills quantisation table 0 with data for luma */
720	exynos4_jpeg_set_tbl(regs, qtbl_luminance[quality],
721			     EXYNOS4_QTBL_CONTENT(0),
722			     ARRAY_SIZE(qtbl_luminance[quality]));
723}
724
725static inline void exynos4_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
726{
727	/* this driver fills quantisation table 1 with data for chroma */
728	exynos4_jpeg_set_tbl(regs, qtbl_chrominance[quality],
729			     EXYNOS4_QTBL_CONTENT(1),
730			     ARRAY_SIZE(qtbl_chrominance[quality]));
731}
732
733static void exynos4_jpeg_set_huff_tbl(void __iomem *base)
734{
735	exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCLL,
736							ARRAY_SIZE(hdctbl0));
737	exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCCL,
738							ARRAY_SIZE(hdctbl0));
739	exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCLV,
740							ARRAY_SIZE(hdctblg0));
741	exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCCV,
742							ARRAY_SIZE(hdctblg0));
743	exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACLL,
744							ARRAY_SIZE(hactbl0));
745	exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACCL,
746							ARRAY_SIZE(hactbl0));
747	exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACLV,
748							ARRAY_SIZE(hactblg0));
749	exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACCV,
750							ARRAY_SIZE(hactblg0));
751}
752
753/*
754 * ============================================================================
755 * Device file operations
756 * ============================================================================
757 */
758
759static int queue_init(void *priv, struct vb2_queue *src_vq,
760		      struct vb2_queue *dst_vq);
761static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
762				__u32 pixelformat, unsigned int fmt_type);
763static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
764
765static int s5p_jpeg_open(struct file *file)
766{
767	struct s5p_jpeg *jpeg = video_drvdata(file);
768	struct video_device *vfd = video_devdata(file);
769	struct s5p_jpeg_ctx *ctx;
770	struct s5p_jpeg_fmt *out_fmt, *cap_fmt;
771	int ret = 0;
772
773	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
774	if (!ctx)
775		return -ENOMEM;
776
777	if (mutex_lock_interruptible(&jpeg->lock)) {
778		ret = -ERESTARTSYS;
779		goto free;
780	}
781
782	v4l2_fh_init(&ctx->fh, vfd);
783	/* Use separate control handler per file handle */
784	ctx->fh.ctrl_handler = &ctx->ctrl_handler;
785	file->private_data = &ctx->fh;
786	v4l2_fh_add(&ctx->fh);
787
788	ctx->jpeg = jpeg;
789	if (vfd == jpeg->vfd_encoder) {
790		ctx->mode = S5P_JPEG_ENCODE;
791		out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB565,
792							FMT_TYPE_OUTPUT);
793		cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
794							FMT_TYPE_CAPTURE);
795	} else {
796		ctx->mode = S5P_JPEG_DECODE;
797		out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
798							FMT_TYPE_OUTPUT);
799		cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV,
800							FMT_TYPE_CAPTURE);
801		ctx->scale_factor = EXYNOS3250_DEC_SCALE_FACTOR_8_8;
802	}
803
804	ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
805	if (IS_ERR(ctx->fh.m2m_ctx)) {
806		ret = PTR_ERR(ctx->fh.m2m_ctx);
807		goto error;
808	}
809
810	ctx->out_q.fmt = out_fmt;
811	ctx->cap_q.fmt = cap_fmt;
812
813	ret = s5p_jpeg_controls_create(ctx);
814	if (ret < 0)
815		goto error;
816
817	mutex_unlock(&jpeg->lock);
818	return 0;
819
820error:
821	v4l2_fh_del(&ctx->fh);
822	v4l2_fh_exit(&ctx->fh);
823	mutex_unlock(&jpeg->lock);
824free:
825	kfree(ctx);
826	return ret;
827}
828
829static int s5p_jpeg_release(struct file *file)
830{
831	struct s5p_jpeg *jpeg = video_drvdata(file);
832	struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
833
834	mutex_lock(&jpeg->lock);
835	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
836	v4l2_ctrl_handler_free(&ctx->ctrl_handler);
837	v4l2_fh_del(&ctx->fh);
838	v4l2_fh_exit(&ctx->fh);
839	kfree(ctx);
840	mutex_unlock(&jpeg->lock);
841
842	return 0;
843}
844
845static const struct v4l2_file_operations s5p_jpeg_fops = {
846	.owner		= THIS_MODULE,
847	.open		= s5p_jpeg_open,
848	.release	= s5p_jpeg_release,
849	.poll		= v4l2_m2m_fop_poll,
850	.unlocked_ioctl	= video_ioctl2,
851	.mmap		= v4l2_m2m_fop_mmap,
852};
853
854/*
855 * ============================================================================
856 * video ioctl operations
857 * ============================================================================
858 */
859
860static int get_byte(struct s5p_jpeg_buffer *buf)
861{
862	if (buf->curr >= buf->size)
863		return -1;
864
865	return ((unsigned char *)buf->data)[buf->curr++];
866}
867
868static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
869{
870	unsigned int temp;
871	int byte;
872
873	byte = get_byte(buf);
874	if (byte == -1)
875		return -1;
876	temp = byte << 8;
877	byte = get_byte(buf);
878	if (byte == -1)
879		return -1;
880	*word = (unsigned int)byte | temp;
881	return 0;
882}
883
884static void skip(struct s5p_jpeg_buffer *buf, long len)
885{
886	if (len <= 0)
887		return;
888
889	while (len--)
890		get_byte(buf);
891}
892
893static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
894			       unsigned long buffer, unsigned long size,
895			       struct s5p_jpeg_ctx *ctx)
896{
897	int c, components = 0, notfound;
898	unsigned int height, width, word, subsampling = 0;
899	long length;
900	struct s5p_jpeg_buffer jpeg_buffer;
901
902	jpeg_buffer.size = size;
903	jpeg_buffer.data = buffer;
904	jpeg_buffer.curr = 0;
905
906	notfound = 1;
907	while (notfound) {
908		c = get_byte(&jpeg_buffer);
909		if (c == -1)
910			return false;
911		if (c != 0xff)
912			continue;
913		do
914			c = get_byte(&jpeg_buffer);
915		while (c == 0xff);
916		if (c == -1)
917			return false;
918		if (c == 0)
919			continue;
920		length = 0;
921		switch (c) {
922		/* SOF0: baseline JPEG */
923		case SOF0:
924			if (get_word_be(&jpeg_buffer, &word))
925				break;
926			if (get_byte(&jpeg_buffer) == -1)
927				break;
928			if (get_word_be(&jpeg_buffer, &height))
929				break;
930			if (get_word_be(&jpeg_buffer, &width))
931				break;
932			components = get_byte(&jpeg_buffer);
933			if (components == -1)
934				break;
935			notfound = 0;
936
937			if (components == 1) {
938				subsampling = 0x33;
939			} else {
940				skip(&jpeg_buffer, 1);
941				subsampling = get_byte(&jpeg_buffer);
942				skip(&jpeg_buffer, 1);
943			}
944
945			skip(&jpeg_buffer, components * 2);
946			break;
947
948		/* skip payload-less markers */
949		case RST ... RST + 7:
950		case SOI:
951		case EOI:
952		case TEM:
953			break;
954
955		/* skip uninteresting payload markers */
956		default:
957			if (get_word_be(&jpeg_buffer, &word))
958				break;
959			length = (long)word - 2;
960			skip(&jpeg_buffer, length);
961			break;
962		}
963	}
964	result->w = width;
965	result->h = height;
966	result->size = components;
967
968	switch (subsampling) {
969	case 0x11:
970		ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
971		break;
972	case 0x21:
973		ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
974		break;
975	case 0x22:
976		ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
977		break;
978	case 0x33:
979		ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
980		break;
981	default:
982		return false;
983	}
984
985	return !notfound;
986}
987
988static int s5p_jpeg_querycap(struct file *file, void *priv,
989			   struct v4l2_capability *cap)
990{
991	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
992
993	if (ctx->mode == S5P_JPEG_ENCODE) {
994		strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder",
995			sizeof(cap->driver));
996		strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
997			sizeof(cap->card));
998	} else {
999		strlcpy(cap->driver, S5P_JPEG_M2M_NAME " decoder",
1000			sizeof(cap->driver));
1001		strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
1002			sizeof(cap->card));
1003	}
1004	cap->bus_info[0] = 0;
1005	cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
1006	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1007	return 0;
1008}
1009
1010static int enum_fmt(struct s5p_jpeg_fmt *sjpeg_formats, int n,
1011		    struct v4l2_fmtdesc *f, u32 type)
1012{
1013	int i, num = 0;
1014
1015	for (i = 0; i < n; ++i) {
1016		if (sjpeg_formats[i].flags & type) {
1017			/* index-th format of type type found ? */
1018			if (num == f->index)
1019				break;
1020			/* Correct type but haven't reached our index yet,
1021			 * just increment per-type index */
1022			++num;
1023		}
1024	}
1025
1026	/* Format not found */
1027	if (i >= n)
1028		return -EINVAL;
1029
1030	strlcpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
1031	f->pixelformat = sjpeg_formats[i].fourcc;
1032
1033	return 0;
1034}
1035
1036static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
1037				   struct v4l2_fmtdesc *f)
1038{
1039	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1040
1041	if (ctx->mode == S5P_JPEG_ENCODE)
1042		return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1043				SJPEG_FMT_FLAG_ENC_CAPTURE);
1044
1045	return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1046					SJPEG_FMT_FLAG_DEC_CAPTURE);
1047}
1048
1049static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
1050				   struct v4l2_fmtdesc *f)
1051{
1052	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1053
1054	if (ctx->mode == S5P_JPEG_ENCODE)
1055		return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1056				SJPEG_FMT_FLAG_ENC_OUTPUT);
1057
1058	return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1059					SJPEG_FMT_FLAG_DEC_OUTPUT);
1060}
1061
1062static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
1063					  enum v4l2_buf_type type)
1064{
1065	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1066		return &ctx->out_q;
1067	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1068		return &ctx->cap_q;
1069
1070	return NULL;
1071}
1072
1073static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
1074{
1075	struct vb2_queue *vq;
1076	struct s5p_jpeg_q_data *q_data = NULL;
1077	struct v4l2_pix_format *pix = &f->fmt.pix;
1078	struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
1079
1080	vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1081	if (!vq)
1082		return -EINVAL;
1083
1084	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1085	    ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
1086		return -EINVAL;
1087	q_data = get_q_data(ct, f->type);
1088	BUG_ON(q_data == NULL);
1089
1090	pix->width = q_data->w;
1091	pix->height = q_data->h;
1092	pix->field = V4L2_FIELD_NONE;
1093	pix->pixelformat = q_data->fmt->fourcc;
1094	pix->bytesperline = 0;
1095	if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
1096		u32 bpl = q_data->w;
1097		if (q_data->fmt->colplanes == 1)
1098			bpl = (bpl * q_data->fmt->depth) >> 3;
1099		pix->bytesperline = bpl;
1100	}
1101	pix->sizeimage = q_data->size;
1102
1103	return 0;
1104}
1105
1106static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
1107				u32 pixelformat, unsigned int fmt_type)
1108{
1109	unsigned int k, fmt_flag;
1110
1111	if (ctx->mode == S5P_JPEG_ENCODE)
1112		fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
1113				SJPEG_FMT_FLAG_ENC_OUTPUT :
1114				SJPEG_FMT_FLAG_ENC_CAPTURE;
1115	else
1116		fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
1117				SJPEG_FMT_FLAG_DEC_OUTPUT :
1118				SJPEG_FMT_FLAG_DEC_CAPTURE;
1119
1120	for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
1121		struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
1122		if (fmt->fourcc == pixelformat &&
1123		    fmt->flags & fmt_flag &&
1124		    fmt->flags & ctx->jpeg->variant->fmt_ver_flag) {
1125			return fmt;
1126		}
1127	}
1128
1129	return NULL;
1130}
1131
1132static void jpeg_bound_align_image(struct s5p_jpeg_ctx *ctx,
1133				   u32 *w, unsigned int wmin, unsigned int wmax,
1134				   unsigned int walign,
1135				   u32 *h, unsigned int hmin, unsigned int hmax,
1136				   unsigned int halign)
1137{
1138	int width, height, w_step, h_step;
1139
1140	width = *w;
1141	height = *h;
1142
1143	w_step = 1 << walign;
1144	h_step = 1 << halign;
1145
1146	if (ctx->jpeg->variant->hw3250_compat) {
1147		/*
1148		 * Rightmost and bottommost pixels are cropped by the
1149		 * Exynos3250/compatible JPEG IP for RGB formats, for the
1150		 * specific width and height values respectively. This
1151		 * assignment will result in v4l_bound_align_image returning
1152		 * dimensions reduced by 1 for the aforementioned cases.
1153		 */
1154		if (w_step == 4 && ((width & 3) == 1)) {
1155			wmax = width;
1156			hmax = height;
1157		}
1158	}
1159
1160	v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
1161
1162	if (*w < width && (*w + w_step) < wmax)
1163		*w += w_step;
1164	if (*h < height && (*h + h_step) < hmax)
1165		*h += h_step;
1166}
1167
1168static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
1169			  struct s5p_jpeg_ctx *ctx, int q_type)
1170{
1171	struct v4l2_pix_format *pix = &f->fmt.pix;
1172
1173	if (pix->field == V4L2_FIELD_ANY)
1174		pix->field = V4L2_FIELD_NONE;
1175	else if (pix->field != V4L2_FIELD_NONE)
1176		return -EINVAL;
1177
1178	/* V4L2 specification suggests the driver corrects the format struct
1179	 * if any of the dimensions is unsupported */
1180	if (q_type == FMT_TYPE_OUTPUT)
1181		jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
1182				       S5P_JPEG_MAX_WIDTH, 0,
1183				       &pix->height, S5P_JPEG_MIN_HEIGHT,
1184				       S5P_JPEG_MAX_HEIGHT, 0);
1185	else
1186		jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
1187				       S5P_JPEG_MAX_WIDTH, fmt->h_align,
1188				       &pix->height, S5P_JPEG_MIN_HEIGHT,
1189				       S5P_JPEG_MAX_HEIGHT, fmt->v_align);
1190
1191	if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1192		if (pix->sizeimage <= 0)
1193			pix->sizeimage = PAGE_SIZE;
1194		pix->bytesperline = 0;
1195	} else {
1196		u32 bpl = pix->bytesperline;
1197
1198		if (fmt->colplanes > 1 && bpl < pix->width)
1199			bpl = pix->width; /* planar */
1200
1201		if (fmt->colplanes == 1 && /* packed */
1202		    (bpl << 3) / fmt->depth < pix->width)
1203			bpl = (pix->width * fmt->depth) >> 3;
1204
1205		pix->bytesperline = bpl;
1206		pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
1207	}
1208
1209	return 0;
1210}
1211
1212static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
1213				  struct v4l2_format *f)
1214{
1215	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1216	struct v4l2_pix_format *pix = &f->fmt.pix;
1217	struct s5p_jpeg_fmt *fmt;
1218	int ret;
1219
1220	fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1221						FMT_TYPE_CAPTURE);
1222	if (!fmt) {
1223		v4l2_err(&ctx->jpeg->v4l2_dev,
1224			 "Fourcc format (0x%08x) invalid.\n",
1225			 f->fmt.pix.pixelformat);
1226		return -EINVAL;
1227	}
1228
1229	if ((ctx->jpeg->variant->version != SJPEG_EXYNOS4) ||
1230	    (ctx->mode != S5P_JPEG_DECODE))
1231		goto exit;
1232
1233	/*
1234	 * The exynos4x12 device requires resulting YUV image
1235	 * subsampling not to be lower than the input jpeg subsampling.
1236	 * If this requirement is not met then downgrade the requested
1237	 * capture format to the one with subsampling equal to the input jpeg.
1238	 */
1239	if ((fmt->flags & SJPEG_FMT_NON_RGB) &&
1240	    (fmt->subsampling < ctx->subsampling)) {
1241		ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling,
1242							    fmt->fourcc,
1243							    &pix->pixelformat,
1244							    ctx);
1245		if (ret < 0)
1246			pix->pixelformat = V4L2_PIX_FMT_GREY;
1247
1248		fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1249							FMT_TYPE_CAPTURE);
1250	}
1251
1252	/*
1253	 * Decompression of a JPEG file with 4:2:0 subsampling and odd
1254	 * width to the YUV 4:2:0 compliant formats produces a raw image
1255	 * with broken luma component. Adjust capture format to RGB565
1256	 * in such a case.
1257	 */
1258	if (ctx->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420 &&
1259	    (ctx->out_q.w & 1) &&
1260	    (pix->pixelformat == V4L2_PIX_FMT_NV12 ||
1261	     pix->pixelformat == V4L2_PIX_FMT_NV21 ||
1262	     pix->pixelformat == V4L2_PIX_FMT_YUV420)) {
1263		pix->pixelformat = V4L2_PIX_FMT_RGB565;
1264		fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1265							FMT_TYPE_CAPTURE);
1266	}
1267
1268exit:
1269	return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
1270}
1271
1272static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
1273				  struct v4l2_format *f)
1274{
1275	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1276	struct s5p_jpeg_fmt *fmt;
1277
1278	fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1279						FMT_TYPE_OUTPUT);
1280	if (!fmt) {
1281		v4l2_err(&ctx->jpeg->v4l2_dev,
1282			 "Fourcc format (0x%08x) invalid.\n",
1283			 f->fmt.pix.pixelformat);
1284		return -EINVAL;
1285	}
1286
1287	return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
1288}
1289
1290static int exynos4_jpeg_get_output_buffer_size(struct s5p_jpeg_ctx *ctx,
1291						struct v4l2_format *f,
1292						int fmt_depth)
1293{
1294	struct v4l2_pix_format *pix = &f->fmt.pix;
1295	u32 pix_fmt = f->fmt.pix.pixelformat;
1296	int w = pix->width, h = pix->height, wh_align;
1297
1298	if (pix_fmt == V4L2_PIX_FMT_RGB32 ||
1299	    pix_fmt == V4L2_PIX_FMT_NV24 ||
1300	    pix_fmt == V4L2_PIX_FMT_NV42 ||
1301	    pix_fmt == V4L2_PIX_FMT_NV12 ||
1302	    pix_fmt == V4L2_PIX_FMT_NV21 ||
1303	    pix_fmt == V4L2_PIX_FMT_YUV420)
1304		wh_align = 4;
1305	else
1306		wh_align = 1;
1307
1308	jpeg_bound_align_image(ctx, &w, S5P_JPEG_MIN_WIDTH,
1309			       S5P_JPEG_MAX_WIDTH, wh_align,
1310			       &h, S5P_JPEG_MIN_HEIGHT,
1311			       S5P_JPEG_MAX_HEIGHT, wh_align);
1312
1313	return w * h * fmt_depth >> 3;
1314}
1315
1316static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1317				   struct v4l2_rect *r);
1318
1319static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
1320{
1321	struct vb2_queue *vq;
1322	struct s5p_jpeg_q_data *q_data = NULL;
1323	struct v4l2_pix_format *pix = &f->fmt.pix;
1324	struct v4l2_ctrl *ctrl_subs;
1325	struct v4l2_rect scale_rect;
1326	unsigned int f_type;
1327
1328	vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1329	if (!vq)
1330		return -EINVAL;
1331
1332	q_data = get_q_data(ct, f->type);
1333	BUG_ON(q_data == NULL);
1334
1335	if (vb2_is_busy(vq)) {
1336		v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
1337		return -EBUSY;
1338	}
1339
1340	f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
1341			FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
1342
1343	q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
1344	q_data->w = pix->width;
1345	q_data->h = pix->height;
1346	if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
1347		/*
1348		 * During encoding Exynos4x12 SoCs access wider memory area
1349		 * than it results from Image_x and Image_y values written to
1350		 * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu
1351		 * page fault calculate proper buffer size in such a case.
1352		 */
1353		if (ct->jpeg->variant->version == SJPEG_EXYNOS4 &&
1354		    f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE)
1355			q_data->size = exynos4_jpeg_get_output_buffer_size(ct,
1356							f,
1357							q_data->fmt->depth);
1358		else
1359			q_data->size = q_data->w * q_data->h *
1360						q_data->fmt->depth >> 3;
1361	} else {
1362		q_data->size = pix->sizeimage;
1363	}
1364
1365	if (f_type == FMT_TYPE_OUTPUT) {
1366		ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler,
1367					V4L2_CID_JPEG_CHROMA_SUBSAMPLING);
1368		if (ctrl_subs)
1369			v4l2_ctrl_s_ctrl(ctrl_subs, q_data->fmt->subsampling);
1370		ct->crop_altered = false;
1371	}
1372
1373	/*
1374	 * For decoding init crop_rect with capture buffer dimmensions which
1375	 * contain aligned dimensions of the input JPEG image and do it only
1376	 * if crop rectangle hasn't been altered by the user space e.g. with
1377	 * S_SELECTION ioctl. For encoding assign output buffer dimensions.
1378	 */
1379	if (!ct->crop_altered &&
1380	    ((ct->mode == S5P_JPEG_DECODE && f_type == FMT_TYPE_CAPTURE) ||
1381	     (ct->mode == S5P_JPEG_ENCODE && f_type == FMT_TYPE_OUTPUT))) {
1382		ct->crop_rect.width = pix->width;
1383		ct->crop_rect.height = pix->height;
1384	}
1385
1386	/*
1387	 * Prevent downscaling to YUV420 format by more than 2
1388	 * for Exynos3250/compatible SoC as it produces broken raw image
1389	 * in such cases.
1390	 */
1391	if (ct->mode == S5P_JPEG_DECODE &&
1392	    f_type == FMT_TYPE_CAPTURE &&
1393	    ct->jpeg->variant->hw3250_compat &&
1394	    pix->pixelformat == V4L2_PIX_FMT_YUV420 &&
1395	    ct->scale_factor > 2) {
1396		scale_rect.width = ct->out_q.w / 2;
1397		scale_rect.height = ct->out_q.h / 2;
1398		exynos3250_jpeg_try_downscale(ct, &scale_rect);
1399	}
1400
1401	return 0;
1402}
1403
1404static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
1405				struct v4l2_format *f)
1406{
1407	int ret;
1408
1409	ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
1410	if (ret)
1411		return ret;
1412
1413	return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1414}
1415
1416static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
1417				struct v4l2_format *f)
1418{
1419	int ret;
1420
1421	ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
1422	if (ret)
1423		return ret;
1424
1425	return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1426}
1427
1428static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1429				   struct v4l2_rect *r)
1430{
1431	int w_ratio, h_ratio, scale_factor, cur_ratio, i;
1432
1433	w_ratio = ctx->out_q.w / r->width;
1434	h_ratio = ctx->out_q.h / r->height;
1435
1436	scale_factor = w_ratio > h_ratio ? w_ratio : h_ratio;
1437	scale_factor = clamp_val(scale_factor, 1, 8);
1438
1439	/* Align scale ratio to the nearest power of 2 */
1440	for (i = 0; i <= 3; ++i) {
1441		cur_ratio = 1 << i;
1442		if (scale_factor <= cur_ratio) {
1443			ctx->scale_factor = cur_ratio;
1444			break;
1445		}
1446	}
1447
1448	r->width = round_down(ctx->out_q.w / ctx->scale_factor, 2);
1449	r->height = round_down(ctx->out_q.h / ctx->scale_factor, 2);
1450
1451	ctx->crop_rect.width = r->width;
1452	ctx->crop_rect.height = r->height;
1453	ctx->crop_rect.left = 0;
1454	ctx->crop_rect.top = 0;
1455
1456	ctx->crop_altered = true;
1457
1458	return 0;
1459}
1460
1461/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
1462static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
1463{
1464	if (a->left < b->left || a->top < b->top)
1465		return 0;
1466	if (a->left + a->width > b->left + b->width)
1467		return 0;
1468	if (a->top + a->height > b->top + b->height)
1469		return 0;
1470
1471	return 1;
1472}
1473
1474static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx,
1475				   struct v4l2_rect *r)
1476{
1477	struct v4l2_rect base_rect;
1478	int w_step, h_step;
1479
1480	switch (ctx->cap_q.fmt->fourcc) {
1481	case V4L2_PIX_FMT_NV12:
1482	case V4L2_PIX_FMT_NV21:
1483		w_step = 1;
1484		h_step = 2;
1485		break;
1486	case V4L2_PIX_FMT_YUV420:
1487		w_step = 2;
1488		h_step = 2;
1489		break;
1490	default:
1491		w_step = 1;
1492		h_step = 1;
1493		break;
1494	}
1495
1496	base_rect.top = 0;
1497	base_rect.left = 0;
1498	base_rect.width = ctx->out_q.w;
1499	base_rect.height = ctx->out_q.h;
1500
1501	r->width = round_down(r->width, w_step);
1502	r->height = round_down(r->height, h_step);
1503	r->left = round_down(r->left, 2);
1504	r->top = round_down(r->top, 2);
1505
1506	if (!enclosed_rectangle(r, &base_rect))
1507		return -EINVAL;
1508
1509	ctx->crop_rect.left = r->left;
1510	ctx->crop_rect.top = r->top;
1511	ctx->crop_rect.width = r->width;
1512	ctx->crop_rect.height = r->height;
1513
1514	ctx->crop_altered = true;
1515
1516	return 0;
1517}
1518
1519/*
1520 * V4L2 controls
1521 */
1522
1523static int s5p_jpeg_g_selection(struct file *file, void *priv,
1524			 struct v4l2_selection *s)
1525{
1526	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1527
1528	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
1529	    s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1530		return -EINVAL;
1531
1532	/* For JPEG blob active == default == bounds */
1533	switch (s->target) {
1534	case V4L2_SEL_TGT_CROP:
1535	case V4L2_SEL_TGT_CROP_BOUNDS:
1536	case V4L2_SEL_TGT_CROP_DEFAULT:
1537	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1538		s->r.width = ctx->out_q.w;
1539		s->r.height = ctx->out_q.h;
1540		s->r.left = 0;
1541		s->r.top = 0;
1542		break;
1543	case V4L2_SEL_TGT_COMPOSE:
1544	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1545	case V4L2_SEL_TGT_COMPOSE_PADDED:
1546		s->r.width = ctx->crop_rect.width;
1547		s->r.height =  ctx->crop_rect.height;
1548		s->r.left = ctx->crop_rect.left;
1549		s->r.top = ctx->crop_rect.top;
1550		break;
1551	default:
1552		return -EINVAL;
1553	}
1554	return 0;
1555}
1556
1557/*
1558 * V4L2 controls
1559 */
1560static int s5p_jpeg_s_selection(struct file *file, void *fh,
1561				  struct v4l2_selection *s)
1562{
1563	struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
1564	struct v4l2_rect *rect = &s->r;
1565	int ret = -EINVAL;
1566
1567	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1568		return -EINVAL;
1569
1570	if (s->target == V4L2_SEL_TGT_COMPOSE) {
1571		if (ctx->mode != S5P_JPEG_DECODE)
1572			return -EINVAL;
1573		if (ctx->jpeg->variant->hw3250_compat)
1574			ret = exynos3250_jpeg_try_downscale(ctx, rect);
1575	} else if (s->target == V4L2_SEL_TGT_CROP) {
1576		if (ctx->mode != S5P_JPEG_ENCODE)
1577			return -EINVAL;
1578		if (ctx->jpeg->variant->hw3250_compat)
1579			ret = exynos3250_jpeg_try_crop(ctx, rect);
1580	}
1581
1582	return ret;
1583}
1584
1585static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1586{
1587	struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1588	struct s5p_jpeg *jpeg = ctx->jpeg;
1589	unsigned long flags;
1590
1591	switch (ctrl->id) {
1592	case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1593		spin_lock_irqsave(&jpeg->slock, flags);
1594		ctrl->val = s5p_jpeg_to_user_subsampling(ctx);
1595		spin_unlock_irqrestore(&jpeg->slock, flags);
1596		break;
1597	}
1598
1599	return 0;
1600}
1601
1602static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val)
1603{
1604	switch (ctx->jpeg->variant->version) {
1605	case SJPEG_S5P:
1606		return 0;
1607	case SJPEG_EXYNOS3250:
1608	case SJPEG_EXYNOS5420:
1609		/*
1610		 * The exynos3250/compatible device can produce JPEG image only
1611		 * of 4:4:4 subsampling when given RGB32 source image.
1612		 */
1613		if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
1614			*ctrl_val = 0;
1615		break;
1616	case SJPEG_EXYNOS4:
1617		/*
1618		 * The exynos4x12 device requires input raw image fourcc
1619		 * to be V4L2_PIX_FMT_GREY if gray jpeg format
1620		 * is to be set.
1621		 */
1622		if (ctx->out_q.fmt->fourcc != V4L2_PIX_FMT_GREY &&
1623		    *ctrl_val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY)
1624			return -EINVAL;
1625		break;
1626	}
1627
1628	/*
1629	 * The exynos4x12 and exynos3250/compatible devices require resulting
1630	 * jpeg subsampling not to be lower than the input raw image
1631	 * subsampling.
1632	 */
1633	if (ctx->out_q.fmt->subsampling > *ctrl_val)
1634		*ctrl_val = ctx->out_q.fmt->subsampling;
1635
1636	return 0;
1637}
1638
1639static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl)
1640{
1641	struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1642	unsigned long flags;
1643	int ret = 0;
1644
1645	spin_lock_irqsave(&ctx->jpeg->slock, flags);
1646
1647	if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING)
1648		ret = s5p_jpeg_adjust_subs_ctrl(ctx, &ctrl->val);
1649
1650	spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1651	return ret;
1652}
1653
1654static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
1655{
1656	struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1657	unsigned long flags;
1658
1659	spin_lock_irqsave(&ctx->jpeg->slock, flags);
1660
1661	switch (ctrl->id) {
1662	case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1663		ctx->compr_quality = ctrl->val;
1664		break;
1665	case V4L2_CID_JPEG_RESTART_INTERVAL:
1666		ctx->restart_interval = ctrl->val;
1667		break;
1668	case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1669		ctx->subsampling = ctrl->val;
1670		break;
1671	}
1672
1673	spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1674	return 0;
1675}
1676
1677static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
1678	.g_volatile_ctrl	= s5p_jpeg_g_volatile_ctrl,
1679	.try_ctrl		= s5p_jpeg_try_ctrl,
1680	.s_ctrl			= s5p_jpeg_s_ctrl,
1681};
1682
1683static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
1684{
1685	unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
1686	struct v4l2_ctrl *ctrl;
1687	int ret;
1688
1689	v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
1690
1691	if (ctx->mode == S5P_JPEG_ENCODE) {
1692		v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1693				  V4L2_CID_JPEG_COMPRESSION_QUALITY,
1694				  0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
1695
1696		v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1697				  V4L2_CID_JPEG_RESTART_INTERVAL,
1698				  0, 3, 0xffff, 0);
1699		if (ctx->jpeg->variant->version == SJPEG_S5P)
1700			mask = ~0x06; /* 422, 420 */
1701	}
1702
1703	ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1704				      V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
1705				      V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
1706				      V4L2_JPEG_CHROMA_SUBSAMPLING_422);
1707
1708	if (ctx->ctrl_handler.error) {
1709		ret = ctx->ctrl_handler.error;
1710		goto error_free;
1711	}
1712
1713	if (ctx->mode == S5P_JPEG_DECODE)
1714		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
1715			V4L2_CTRL_FLAG_READ_ONLY;
1716
1717	ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
1718	if (ret < 0)
1719		goto error_free;
1720
1721	return ret;
1722
1723error_free:
1724	v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1725	return ret;
1726}
1727
1728static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
1729	.vidioc_querycap		= s5p_jpeg_querycap,
1730
1731	.vidioc_enum_fmt_vid_cap	= s5p_jpeg_enum_fmt_vid_cap,
1732	.vidioc_enum_fmt_vid_out	= s5p_jpeg_enum_fmt_vid_out,
1733
1734	.vidioc_g_fmt_vid_cap		= s5p_jpeg_g_fmt,
1735	.vidioc_g_fmt_vid_out		= s5p_jpeg_g_fmt,
1736
1737	.vidioc_try_fmt_vid_cap		= s5p_jpeg_try_fmt_vid_cap,
1738	.vidioc_try_fmt_vid_out		= s5p_jpeg_try_fmt_vid_out,
1739
1740	.vidioc_s_fmt_vid_cap		= s5p_jpeg_s_fmt_vid_cap,
1741	.vidioc_s_fmt_vid_out		= s5p_jpeg_s_fmt_vid_out,
1742
1743	.vidioc_reqbufs			= v4l2_m2m_ioctl_reqbufs,
1744	.vidioc_querybuf		= v4l2_m2m_ioctl_querybuf,
1745	.vidioc_qbuf			= v4l2_m2m_ioctl_qbuf,
1746	.vidioc_dqbuf			= v4l2_m2m_ioctl_dqbuf,
1747
1748	.vidioc_streamon		= v4l2_m2m_ioctl_streamon,
1749	.vidioc_streamoff		= v4l2_m2m_ioctl_streamoff,
1750
1751	.vidioc_g_selection		= s5p_jpeg_g_selection,
1752	.vidioc_s_selection		= s5p_jpeg_s_selection,
1753};
1754
1755/*
1756 * ============================================================================
1757 * mem2mem callbacks
1758 * ============================================================================
1759 */
1760
1761static void s5p_jpeg_device_run(void *priv)
1762{
1763	struct s5p_jpeg_ctx *ctx = priv;
1764	struct s5p_jpeg *jpeg = ctx->jpeg;
1765	struct vb2_buffer *src_buf, *dst_buf;
1766	unsigned long src_addr, dst_addr, flags;
1767
1768	spin_lock_irqsave(&ctx->jpeg->slock, flags);
1769
1770	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1771	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1772	src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
1773	dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
1774
1775	s5p_jpeg_reset(jpeg->regs);
1776	s5p_jpeg_poweron(jpeg->regs);
1777	s5p_jpeg_proc_mode(jpeg->regs, ctx->mode);
1778	if (ctx->mode == S5P_JPEG_ENCODE) {
1779		if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
1780			s5p_jpeg_input_raw_mode(jpeg->regs,
1781							S5P_JPEG_RAW_IN_565);
1782		else
1783			s5p_jpeg_input_raw_mode(jpeg->regs,
1784							S5P_JPEG_RAW_IN_422);
1785		s5p_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
1786		s5p_jpeg_dri(jpeg->regs, ctx->restart_interval);
1787		s5p_jpeg_x(jpeg->regs, ctx->out_q.w);
1788		s5p_jpeg_y(jpeg->regs, ctx->out_q.h);
1789		s5p_jpeg_imgadr(jpeg->regs, src_addr);
1790		s5p_jpeg_jpgadr(jpeg->regs, dst_addr);
1791
1792		/* ultimately comes from sizeimage from userspace */
1793		s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
1794
1795		/* JPEG RGB to YCbCr conversion matrix */
1796		s5p_jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
1797		s5p_jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
1798		s5p_jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
1799		s5p_jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
1800		s5p_jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
1801		s5p_jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
1802		s5p_jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
1803		s5p_jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
1804		s5p_jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
1805
1806		/*
1807		 * JPEG IP allows storing 4 quantization tables
1808		 * We fill table 0 for luma and table 1 for chroma
1809		 */
1810		s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1811		s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1812		/* use table 0 for Y */
1813		s5p_jpeg_qtbl(jpeg->regs, 1, 0);
1814		/* use table 1 for Cb and Cr*/
1815		s5p_jpeg_qtbl(jpeg->regs, 2, 1);
1816		s5p_jpeg_qtbl(jpeg->regs, 3, 1);
1817
1818		/* Y, Cb, Cr use Huffman table 0 */
1819		s5p_jpeg_htbl_ac(jpeg->regs, 1);
1820		s5p_jpeg_htbl_dc(jpeg->regs, 1);
1821		s5p_jpeg_htbl_ac(jpeg->regs, 2);
1822		s5p_jpeg_htbl_dc(jpeg->regs, 2);
1823		s5p_jpeg_htbl_ac(jpeg->regs, 3);
1824		s5p_jpeg_htbl_dc(jpeg->regs, 3);
1825	} else { /* S5P_JPEG_DECODE */
1826		s5p_jpeg_rst_int_enable(jpeg->regs, true);
1827		s5p_jpeg_data_num_int_enable(jpeg->regs, true);
1828		s5p_jpeg_final_mcu_num_int_enable(jpeg->regs, true);
1829		if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
1830			s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
1831		else
1832			s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
1833		s5p_jpeg_jpgadr(jpeg->regs, src_addr);
1834		s5p_jpeg_imgadr(jpeg->regs, dst_addr);
1835	}
1836
1837	s5p_jpeg_start(jpeg->regs);
1838
1839	spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1840}
1841
1842static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
1843{
1844	struct s5p_jpeg *jpeg = ctx->jpeg;
1845	struct s5p_jpeg_fmt *fmt;
1846	struct vb2_buffer *vb;
1847	struct s5p_jpeg_addr jpeg_addr = {};
1848	u32 pix_size, padding_bytes = 0;
1849
1850	jpeg_addr.cb = 0;
1851	jpeg_addr.cr = 0;
1852
1853	pix_size = ctx->cap_q.w * ctx->cap_q.h;
1854
1855	if (ctx->mode == S5P_JPEG_ENCODE) {
1856		vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1857		fmt = ctx->out_q.fmt;
1858		if (ctx->out_q.w % 2 && fmt->h_align > 0)
1859			padding_bytes = ctx->out_q.h;
1860	} else {
1861		fmt = ctx->cap_q.fmt;
1862		vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1863	}
1864
1865	jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
1866
1867	if (fmt->colplanes == 2) {
1868		jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes;
1869	} else if (fmt->colplanes == 3) {
1870		jpeg_addr.cb = jpeg_addr.y + pix_size;
1871		if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
1872			jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
1873		else
1874			jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
1875	}
1876
1877	exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr);
1878}
1879
1880static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
1881{
1882	struct s5p_jpeg *jpeg = ctx->jpeg;
1883	struct vb2_buffer *vb;
1884	unsigned int jpeg_addr = 0;
1885
1886	if (ctx->mode == S5P_JPEG_ENCODE)
1887		vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1888	else
1889		vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1890
1891	jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1892	exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
1893}
1894
1895static void exynos4_jpeg_device_run(void *priv)
1896{
1897	struct s5p_jpeg_ctx *ctx = priv;
1898	struct s5p_jpeg *jpeg = ctx->jpeg;
1899	unsigned int bitstream_size;
1900	unsigned long flags;
1901
1902	spin_lock_irqsave(&ctx->jpeg->slock, flags);
1903
1904	if (ctx->mode == S5P_JPEG_ENCODE) {
1905		exynos4_jpeg_sw_reset(jpeg->regs);
1906		exynos4_jpeg_set_interrupt(jpeg->regs);
1907		exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
1908
1909		exynos4_jpeg_set_huff_tbl(jpeg->regs);
1910
1911		/*
1912		 * JPEG IP allows storing 4 quantization tables
1913		 * We fill table 0 for luma and table 1 for chroma
1914		 */
1915		exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1916		exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1917
1918		exynos4_jpeg_set_encode_tbl_select(jpeg->regs,
1919							ctx->compr_quality);
1920		exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
1921							ctx->cap_q.h);
1922
1923		exynos4_jpeg_set_enc_out_fmt(jpeg->regs, ctx->subsampling);
1924		exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->out_q.fmt->fourcc);
1925		exynos4_jpeg_set_img_addr(ctx);
1926		exynos4_jpeg_set_jpeg_addr(ctx);
1927		exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs,
1928							ctx->out_q.fmt->fourcc);
1929	} else {
1930		exynos4_jpeg_sw_reset(jpeg->regs);
1931		exynos4_jpeg_set_interrupt(jpeg->regs);
1932		exynos4_jpeg_set_img_addr(ctx);
1933		exynos4_jpeg_set_jpeg_addr(ctx);
1934		exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->cap_q.fmt->fourcc);
1935
1936		bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
1937
1938		exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
1939	}
1940
1941	exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
1942
1943	spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1944}
1945
1946static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
1947{
1948	struct s5p_jpeg *jpeg = ctx->jpeg;
1949	struct s5p_jpeg_fmt *fmt;
1950	struct vb2_buffer *vb;
1951	struct s5p_jpeg_addr jpeg_addr = {};
1952	u32 pix_size;
1953
1954	pix_size = ctx->cap_q.w * ctx->cap_q.h;
1955
1956	if (ctx->mode == S5P_JPEG_ENCODE) {
1957		vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1958		fmt = ctx->out_q.fmt;
1959	} else {
1960		vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1961		fmt = ctx->cap_q.fmt;
1962	}
1963
1964	jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
1965
1966	if (fmt->colplanes == 2) {
1967		jpeg_addr.cb = jpeg_addr.y + pix_size;
1968	} else if (fmt->colplanes == 3) {
1969		jpeg_addr.cb = jpeg_addr.y + pix_size;
1970		if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
1971			jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
1972		else
1973			jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
1974	}
1975
1976	exynos3250_jpeg_imgadr(jpeg->regs, &jpeg_addr);
1977}
1978
1979static void exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
1980{
1981	struct s5p_jpeg *jpeg = ctx->jpeg;
1982	struct vb2_buffer *vb;
1983	unsigned int jpeg_addr = 0;
1984
1985	if (ctx->mode == S5P_JPEG_ENCODE)
1986		vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1987	else
1988		vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1989
1990	jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1991	exynos3250_jpeg_jpgadr(jpeg->regs, jpeg_addr);
1992}
1993
1994static void exynos3250_jpeg_device_run(void *priv)
1995{
1996	struct s5p_jpeg_ctx *ctx = priv;
1997	struct s5p_jpeg *jpeg = ctx->jpeg;
1998	unsigned long flags;
1999
2000	spin_lock_irqsave(&ctx->jpeg->slock, flags);
2001
2002	exynos3250_jpeg_reset(jpeg->regs);
2003	exynos3250_jpeg_set_dma_num(jpeg->regs);
2004	exynos3250_jpeg_poweron(jpeg->regs);
2005	exynos3250_jpeg_clk_set(jpeg->regs);
2006	exynos3250_jpeg_proc_mode(jpeg->regs, ctx->mode);
2007
2008	if (ctx->mode == S5P_JPEG_ENCODE) {
2009		exynos3250_jpeg_input_raw_fmt(jpeg->regs,
2010					      ctx->out_q.fmt->fourcc);
2011		exynos3250_jpeg_dri(jpeg->regs, ctx->restart_interval);
2012
2013		/*
2014		 * JPEG IP allows storing 4 quantization tables
2015		 * We fill table 0 for luma and table 1 for chroma
2016		 */
2017		s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2018		s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2019		/* use table 0 for Y */
2020		exynos3250_jpeg_qtbl(jpeg->regs, 1, 0);
2021		/* use table 1 for Cb and Cr*/
2022		exynos3250_jpeg_qtbl(jpeg->regs, 2, 1);
2023		exynos3250_jpeg_qtbl(jpeg->regs, 3, 1);
2024
2025		/*
2026		 * Some SoCs require setting Huffman tables before each run
2027		 */
2028		if (jpeg->variant->htbl_reinit) {
2029			s5p_jpeg_set_hdctbl(jpeg->regs);
2030			s5p_jpeg_set_hdctblg(jpeg->regs);
2031			s5p_jpeg_set_hactbl(jpeg->regs);
2032			s5p_jpeg_set_hactblg(jpeg->regs);
2033		}
2034
2035		/* Y, Cb, Cr use Huffman table 0 */
2036		exynos3250_jpeg_htbl_ac(jpeg->regs, 1);
2037		exynos3250_jpeg_htbl_dc(jpeg->regs, 1);
2038		exynos3250_jpeg_htbl_ac(jpeg->regs, 2);
2039		exynos3250_jpeg_htbl_dc(jpeg->regs, 2);
2040		exynos3250_jpeg_htbl_ac(jpeg->regs, 3);
2041		exynos3250_jpeg_htbl_dc(jpeg->regs, 3);
2042
2043		exynos3250_jpeg_set_x(jpeg->regs, ctx->crop_rect.width);
2044		exynos3250_jpeg_set_y(jpeg->regs, ctx->crop_rect.height);
2045		exynos3250_jpeg_stride(jpeg->regs, ctx->out_q.fmt->fourcc,
2046								ctx->out_q.w);
2047		exynos3250_jpeg_offset(jpeg->regs, ctx->crop_rect.left,
2048							ctx->crop_rect.top);
2049		exynos3250_jpeg_set_img_addr(ctx);
2050		exynos3250_jpeg_set_jpeg_addr(ctx);
2051		exynos3250_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
2052
2053		/* ultimately comes from sizeimage from userspace */
2054		exynos3250_jpeg_enc_stream_bound(jpeg->regs, ctx->cap_q.size);
2055
2056		if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565 ||
2057		    ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565X ||
2058		    ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
2059			exynos3250_jpeg_set_y16(jpeg->regs, true);
2060	} else {
2061		exynos3250_jpeg_set_img_addr(ctx);
2062		exynos3250_jpeg_set_jpeg_addr(ctx);
2063		exynos3250_jpeg_stride(jpeg->regs, ctx->cap_q.fmt->fourcc,
2064								ctx->cap_q.w);
2065		exynos3250_jpeg_offset(jpeg->regs, 0, 0);
2066		exynos3250_jpeg_dec_scaling_ratio(jpeg->regs,
2067							ctx->scale_factor);
2068		exynos3250_jpeg_dec_stream_size(jpeg->regs, ctx->out_q.size);
2069		exynos3250_jpeg_output_raw_fmt(jpeg->regs,
2070						ctx->cap_q.fmt->fourcc);
2071	}
2072
2073	exynos3250_jpeg_interrupts_enable(jpeg->regs);
2074
2075	/* JPEG RGB to YCbCr conversion matrix */
2076	exynos3250_jpeg_coef(jpeg->regs, ctx->mode);
2077
2078	exynos3250_jpeg_set_timer(jpeg->regs, EXYNOS3250_IRQ_TIMEOUT);
2079	jpeg->irq_status = 0;
2080	exynos3250_jpeg_start(jpeg->regs);
2081
2082	spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
2083}
2084
2085static int s5p_jpeg_job_ready(void *priv)
2086{
2087	struct s5p_jpeg_ctx *ctx = priv;
2088
2089	if (ctx->mode == S5P_JPEG_DECODE)
2090		return ctx->hdr_parsed;
2091	return 1;
2092}
2093
2094static void s5p_jpeg_job_abort(void *priv)
2095{
2096}
2097
2098static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
2099	.device_run	= s5p_jpeg_device_run,
2100	.job_ready	= s5p_jpeg_job_ready,
2101	.job_abort	= s5p_jpeg_job_abort,
2102};
2103
2104static struct v4l2_m2m_ops exynos3250_jpeg_m2m_ops = {
2105	.device_run	= exynos3250_jpeg_device_run,
2106	.job_ready	= s5p_jpeg_job_ready,
2107	.job_abort	= s5p_jpeg_job_abort,
2108};
2109
2110static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = {
2111	.device_run	= exynos4_jpeg_device_run,
2112	.job_ready	= s5p_jpeg_job_ready,
2113	.job_abort	= s5p_jpeg_job_abort,
2114};
2115
2116/*
2117 * ============================================================================
2118 * Queue operations
2119 * ============================================================================
2120 */
2121
2122static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
2123			   const struct v4l2_format *fmt,
2124			   unsigned int *nbuffers, unsigned int *nplanes,
2125			   unsigned int sizes[], void *alloc_ctxs[])
2126{
2127	struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
2128	struct s5p_jpeg_q_data *q_data = NULL;
2129	unsigned int size, count = *nbuffers;
2130
2131	q_data = get_q_data(ctx, vq->type);
2132	BUG_ON(q_data == NULL);
2133
2134	size = q_data->size;
2135
2136	/*
2137	 * header is parsed during decoding and parsed information stored
2138	 * in the context so we do not allow another buffer to overwrite it
2139	 */
2140	if (ctx->mode == S5P_JPEG_DECODE)
2141		count = 1;
2142
2143	*nbuffers = count;
2144	*nplanes = 1;
2145	sizes[0] = size;
2146	alloc_ctxs[0] = ctx->jpeg->alloc_ctx;
2147
2148	return 0;
2149}
2150
2151static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
2152{
2153	struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2154	struct s5p_jpeg_q_data *q_data = NULL;
2155
2156	q_data = get_q_data(ctx, vb->vb2_queue->type);
2157	BUG_ON(q_data == NULL);
2158
2159	if (vb2_plane_size(vb, 0) < q_data->size) {
2160		pr_err("%s data will not fit into plane (%lu < %lu)\n",
2161				__func__, vb2_plane_size(vb, 0),
2162				(long)q_data->size);
2163		return -EINVAL;
2164	}
2165
2166	vb2_set_plane_payload(vb, 0, q_data->size);
2167
2168	return 0;
2169}
2170
2171static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
2172{
2173	struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2174
2175	if (ctx->mode == S5P_JPEG_DECODE &&
2176	    vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
2177		struct s5p_jpeg_q_data tmp, *q_data;
2178		ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
2179		     (unsigned long)vb2_plane_vaddr(vb, 0),
2180		     min((unsigned long)ctx->out_q.size,
2181			 vb2_get_plane_payload(vb, 0)), ctx);
2182		if (!ctx->hdr_parsed) {
2183			vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
2184			return;
2185		}
2186
2187		q_data = &ctx->out_q;
2188		q_data->w = tmp.w;
2189		q_data->h = tmp.h;
2190
2191		q_data = &ctx->cap_q;
2192		q_data->w = tmp.w;
2193		q_data->h = tmp.h;
2194	}
2195
2196	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
2197}
2198
2199static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
2200{
2201	struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
2202	int ret;
2203
2204	ret = pm_runtime_get_sync(ctx->jpeg->dev);
2205
2206	return ret > 0 ? 0 : ret;
2207}
2208
2209static void s5p_jpeg_stop_streaming(struct vb2_queue *q)
2210{
2211	struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
2212
2213	pm_runtime_put(ctx->jpeg->dev);
2214}
2215
2216static struct vb2_ops s5p_jpeg_qops = {
2217	.queue_setup		= s5p_jpeg_queue_setup,
2218	.buf_prepare		= s5p_jpeg_buf_prepare,
2219	.buf_queue		= s5p_jpeg_buf_queue,
2220	.wait_prepare		= vb2_ops_wait_prepare,
2221	.wait_finish		= vb2_ops_wait_finish,
2222	.start_streaming	= s5p_jpeg_start_streaming,
2223	.stop_streaming		= s5p_jpeg_stop_streaming,
2224};
2225
2226static int queue_init(void *priv, struct vb2_queue *src_vq,
2227		      struct vb2_queue *dst_vq)
2228{
2229	struct s5p_jpeg_ctx *ctx = priv;
2230	int ret;
2231
2232	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2233	src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
2234	src_vq->drv_priv = ctx;
2235	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2236	src_vq->ops = &s5p_jpeg_qops;
2237	src_vq->mem_ops = &vb2_dma_contig_memops;
2238	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2239	src_vq->lock = &ctx->jpeg->lock;
2240
2241	ret = vb2_queue_init(src_vq);
2242	if (ret)
2243		return ret;
2244
2245	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2246	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
2247	dst_vq->drv_priv = ctx;
2248	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2249	dst_vq->ops = &s5p_jpeg_qops;
2250	dst_vq->mem_ops = &vb2_dma_contig_memops;
2251	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2252	dst_vq->lock = &ctx->jpeg->lock;
2253
2254	return vb2_queue_init(dst_vq);
2255}
2256
2257/*
2258 * ============================================================================
2259 * ISR
2260 * ============================================================================
2261 */
2262
2263static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
2264{
2265	struct s5p_jpeg *jpeg = dev_id;
2266	struct s5p_jpeg_ctx *curr_ctx;
2267	struct vb2_buffer *src_buf, *dst_buf;
2268	unsigned long payload_size = 0;
2269	enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
2270	bool enc_jpeg_too_large = false;
2271	bool timer_elapsed = false;
2272	bool op_completed = false;
2273
2274	spin_lock(&jpeg->slock);
2275
2276	curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2277
2278	src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2279	dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2280
2281	if (curr_ctx->mode == S5P_JPEG_ENCODE)
2282		enc_jpeg_too_large = s5p_jpeg_enc_stream_stat(jpeg->regs);
2283	timer_elapsed = s5p_jpeg_timer_stat(jpeg->regs);
2284	op_completed = s5p_jpeg_result_stat_ok(jpeg->regs);
2285	if (curr_ctx->mode == S5P_JPEG_DECODE)
2286		op_completed = op_completed &&
2287					s5p_jpeg_stream_stat_ok(jpeg->regs);
2288
2289	if (enc_jpeg_too_large) {
2290		state = VB2_BUF_STATE_ERROR;
2291		s5p_jpeg_clear_enc_stream_stat(jpeg->regs);
2292	} else if (timer_elapsed) {
2293		state = VB2_BUF_STATE_ERROR;
2294		s5p_jpeg_clear_timer_stat(jpeg->regs);
2295	} else if (!op_completed) {
2296		state = VB2_BUF_STATE_ERROR;
2297	} else {
2298		payload_size = s5p_jpeg_compressed_size(jpeg->regs);
2299	}
2300
2301	dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
2302	dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
2303	dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
2304	dst_buf->v4l2_buf.flags |=
2305		src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
2306
2307	v4l2_m2m_buf_done(src_buf, state);
2308	if (curr_ctx->mode == S5P_JPEG_ENCODE)
2309		vb2_set_plane_payload(dst_buf, 0, payload_size);
2310	v4l2_m2m_buf_done(dst_buf, state);
2311	v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2312
2313	curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs);
2314	spin_unlock(&jpeg->slock);
2315
2316	s5p_jpeg_clear_int(jpeg->regs);
2317
2318	return IRQ_HANDLED;
2319}
2320
2321static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
2322{
2323	unsigned int int_status;
2324	struct vb2_buffer *src_vb, *dst_vb;
2325	struct s5p_jpeg *jpeg = priv;
2326	struct s5p_jpeg_ctx *curr_ctx;
2327	unsigned long payload_size = 0;
2328
2329	spin_lock(&jpeg->slock);
2330
2331	curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2332
2333	src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2334	dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2335
2336	int_status = exynos4_jpeg_get_int_status(jpeg->regs);
2337
2338	if (int_status) {
2339		switch (int_status & 0x1f) {
2340		case 0x1:
2341			jpeg->irq_ret = ERR_PROT;
2342			break;
2343		case 0x2:
2344			jpeg->irq_ret = OK_ENC_OR_DEC;
2345			break;
2346		case 0x4:
2347			jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
2348			break;
2349		case 0x8:
2350			jpeg->irq_ret = ERR_MULTI_SCAN;
2351			break;
2352		case 0x10:
2353			jpeg->irq_ret = ERR_FRAME;
2354			break;
2355		default:
2356			jpeg->irq_ret = ERR_UNKNOWN;
2357			break;
2358		}
2359	} else {
2360		jpeg->irq_ret = ERR_UNKNOWN;
2361	}
2362
2363	if (jpeg->irq_ret == OK_ENC_OR_DEC) {
2364		if (curr_ctx->mode == S5P_JPEG_ENCODE) {
2365			payload_size = exynos4_jpeg_get_stream_size(jpeg->regs);
2366			vb2_set_plane_payload(dst_vb, 0, payload_size);
2367		}
2368		v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
2369		v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
2370	} else {
2371		v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
2372		v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
2373	}
2374
2375	v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2376	curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
2377
2378	spin_unlock(&jpeg->slock);
2379	return IRQ_HANDLED;
2380}
2381
2382static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id)
2383{
2384	struct s5p_jpeg *jpeg = dev_id;
2385	struct s5p_jpeg_ctx *curr_ctx;
2386	struct vb2_buffer *src_buf, *dst_buf;
2387	unsigned long payload_size = 0;
2388	enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
2389	bool interrupt_timeout = false;
2390	u32 irq_status;
2391
2392	spin_lock(&jpeg->slock);
2393
2394	irq_status = exynos3250_jpeg_get_timer_status(jpeg->regs);
2395	if (irq_status & EXYNOS3250_TIMER_INT_STAT) {
2396		exynos3250_jpeg_clear_timer_status(jpeg->regs);
2397		interrupt_timeout = true;
2398		dev_err(jpeg->dev, "Interrupt timeout occurred.\n");
2399	}
2400
2401	irq_status = exynos3250_jpeg_get_int_status(jpeg->regs);
2402	exynos3250_jpeg_clear_int_status(jpeg->regs, irq_status);
2403
2404	jpeg->irq_status |= irq_status;
2405
2406	curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2407
2408	if (!curr_ctx)
2409		goto exit_unlock;
2410
2411	if ((irq_status & EXYNOS3250_HEADER_STAT) &&
2412	    (curr_ctx->mode == S5P_JPEG_DECODE)) {
2413		exynos3250_jpeg_rstart(jpeg->regs);
2414		goto exit_unlock;
2415	}
2416
2417	if (jpeg->irq_status & (EXYNOS3250_JPEG_DONE |
2418				EXYNOS3250_WDMA_DONE |
2419				EXYNOS3250_RDMA_DONE |
2420				EXYNOS3250_RESULT_STAT))
2421		payload_size = exynos3250_jpeg_compressed_size(jpeg->regs);
2422	else if (interrupt_timeout)
2423		state = VB2_BUF_STATE_ERROR;
2424	else
2425		goto exit_unlock;
2426
2427	src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2428	dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2429
2430	dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
2431	dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
2432
2433	v4l2_m2m_buf_done(src_buf, state);
2434	if (curr_ctx->mode == S5P_JPEG_ENCODE)
2435		vb2_set_plane_payload(dst_buf, 0, payload_size);
2436	v4l2_m2m_buf_done(dst_buf, state);
2437	v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2438
2439	curr_ctx->subsampling =
2440			exynos3250_jpeg_get_subsampling_mode(jpeg->regs);
2441exit_unlock:
2442	spin_unlock(&jpeg->slock);
2443	return IRQ_HANDLED;
2444}
2445
2446static void *jpeg_get_drv_data(struct device *dev);
2447
2448/*
2449 * ============================================================================
2450 * Driver basic infrastructure
2451 * ============================================================================
2452 */
2453
2454static int s5p_jpeg_probe(struct platform_device *pdev)
2455{
2456	struct s5p_jpeg *jpeg;
2457	struct resource *res;
2458	int ret;
2459
2460	/* JPEG IP abstraction struct */
2461	jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
2462	if (!jpeg)
2463		return -ENOMEM;
2464
2465	jpeg->variant = jpeg_get_drv_data(&pdev->dev);
2466
2467	mutex_init(&jpeg->lock);
2468	spin_lock_init(&jpeg->slock);
2469	jpeg->dev = &pdev->dev;
2470
2471	/* memory-mapped registers */
2472	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2473
2474	jpeg->regs = devm_ioremap_resource(&pdev->dev, res);
2475	if (IS_ERR(jpeg->regs))
2476		return PTR_ERR(jpeg->regs);
2477
2478	/* interrupt service routine registration */
2479	jpeg->irq = ret = platform_get_irq(pdev, 0);
2480	if (ret < 0) {
2481		dev_err(&pdev->dev, "cannot find IRQ\n");
2482		return ret;
2483	}
2484
2485	ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
2486				0, dev_name(&pdev->dev), jpeg);
2487	if (ret) {
2488		dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
2489		return ret;
2490	}
2491
2492	/* clocks */
2493	jpeg->clk = clk_get(&pdev->dev, "jpeg");
2494	if (IS_ERR(jpeg->clk)) {
2495		dev_err(&pdev->dev, "cannot get clock\n");
2496		ret = PTR_ERR(jpeg->clk);
2497		return ret;
2498	}
2499	dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
2500
2501	jpeg->sclk = clk_get(&pdev->dev, "sclk");
2502	if (IS_ERR(jpeg->sclk))
2503		dev_info(&pdev->dev, "sclk clock not available\n");
2504
2505	/* v4l2 device */
2506	ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
2507	if (ret) {
2508		dev_err(&pdev->dev, "Failed to register v4l2 device\n");
2509		goto clk_get_rollback;
2510	}
2511
2512	/* mem2mem device */
2513	jpeg->m2m_dev = v4l2_m2m_init(jpeg->variant->m2m_ops);
2514	if (IS_ERR(jpeg->m2m_dev)) {
2515		v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
2516		ret = PTR_ERR(jpeg->m2m_dev);
2517		goto device_register_rollback;
2518	}
2519
2520	jpeg->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
2521	if (IS_ERR(jpeg->alloc_ctx)) {
2522		v4l2_err(&jpeg->v4l2_dev, "Failed to init memory allocator\n");
2523		ret = PTR_ERR(jpeg->alloc_ctx);
2524		goto m2m_init_rollback;
2525	}
2526
2527	/* JPEG encoder /dev/videoX node */
2528	jpeg->vfd_encoder = video_device_alloc();
2529	if (!jpeg->vfd_encoder) {
2530		v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
2531		ret = -ENOMEM;
2532		goto vb2_allocator_rollback;
2533	}
2534	snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name),
2535				"%s-enc", S5P_JPEG_M2M_NAME);
2536	jpeg->vfd_encoder->fops		= &s5p_jpeg_fops;
2537	jpeg->vfd_encoder->ioctl_ops	= &s5p_jpeg_ioctl_ops;
2538	jpeg->vfd_encoder->minor	= -1;
2539	jpeg->vfd_encoder->release	= video_device_release;
2540	jpeg->vfd_encoder->lock		= &jpeg->lock;
2541	jpeg->vfd_encoder->v4l2_dev	= &jpeg->v4l2_dev;
2542	jpeg->vfd_encoder->vfl_dir	= VFL_DIR_M2M;
2543
2544	ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
2545	if (ret) {
2546		v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
2547		goto enc_vdev_alloc_rollback;
2548	}
2549
2550	video_set_drvdata(jpeg->vfd_encoder, jpeg);
2551	v4l2_info(&jpeg->v4l2_dev,
2552		  "encoder device registered as /dev/video%d\n",
2553		  jpeg->vfd_encoder->num);
2554
2555	/* JPEG decoder /dev/videoX node */
2556	jpeg->vfd_decoder = video_device_alloc();
2557	if (!jpeg->vfd_decoder) {
2558		v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
2559		ret = -ENOMEM;
2560		goto enc_vdev_register_rollback;
2561	}
2562	snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name),
2563				"%s-dec", S5P_JPEG_M2M_NAME);
2564	jpeg->vfd_decoder->fops		= &s5p_jpeg_fops;
2565	jpeg->vfd_decoder->ioctl_ops	= &s5p_jpeg_ioctl_ops;
2566	jpeg->vfd_decoder->minor	= -1;
2567	jpeg->vfd_decoder->release	= video_device_release;
2568	jpeg->vfd_decoder->lock		= &jpeg->lock;
2569	jpeg->vfd_decoder->v4l2_dev	= &jpeg->v4l2_dev;
2570	jpeg->vfd_decoder->vfl_dir	= VFL_DIR_M2M;
2571
2572	ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
2573	if (ret) {
2574		v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
2575		goto dec_vdev_alloc_rollback;
2576	}
2577
2578	video_set_drvdata(jpeg->vfd_decoder, jpeg);
2579	v4l2_info(&jpeg->v4l2_dev,
2580		  "decoder device registered as /dev/video%d\n",
2581		  jpeg->vfd_decoder->num);
2582
2583	/* final statements & power management */
2584	platform_set_drvdata(pdev, jpeg);
2585
2586	pm_runtime_enable(&pdev->dev);
2587
2588	v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
2589
2590	return 0;
2591
2592dec_vdev_alloc_rollback:
2593	video_device_release(jpeg->vfd_decoder);
2594
2595enc_vdev_register_rollback:
2596	video_unregister_device(jpeg->vfd_encoder);
2597
2598enc_vdev_alloc_rollback:
2599	video_device_release(jpeg->vfd_encoder);
2600
2601vb2_allocator_rollback:
2602	vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
2603
2604m2m_init_rollback:
2605	v4l2_m2m_release(jpeg->m2m_dev);
2606
2607device_register_rollback:
2608	v4l2_device_unregister(&jpeg->v4l2_dev);
2609
2610clk_get_rollback:
2611	clk_put(jpeg->clk);
2612	if (!IS_ERR(jpeg->sclk))
2613		clk_put(jpeg->sclk);
2614
2615	return ret;
2616}
2617
2618static int s5p_jpeg_remove(struct platform_device *pdev)
2619{
2620	struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
2621
2622	pm_runtime_disable(jpeg->dev);
2623
2624	video_unregister_device(jpeg->vfd_decoder);
2625	video_device_release(jpeg->vfd_decoder);
2626	video_unregister_device(jpeg->vfd_encoder);
2627	video_device_release(jpeg->vfd_encoder);
2628	vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
2629	v4l2_m2m_release(jpeg->m2m_dev);
2630	v4l2_device_unregister(&jpeg->v4l2_dev);
2631
2632	if (!pm_runtime_status_suspended(&pdev->dev)) {
2633		clk_disable_unprepare(jpeg->clk);
2634		if (!IS_ERR(jpeg->sclk))
2635			clk_disable_unprepare(jpeg->sclk);
2636	}
2637
2638	clk_put(jpeg->clk);
2639	if (!IS_ERR(jpeg->sclk))
2640		clk_put(jpeg->sclk);
2641
2642	return 0;
2643}
2644
2645#ifdef CONFIG_PM
2646static int s5p_jpeg_runtime_suspend(struct device *dev)
2647{
2648	struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2649
2650	clk_disable_unprepare(jpeg->clk);
2651	if (!IS_ERR(jpeg->sclk))
2652		clk_disable_unprepare(jpeg->sclk);
2653
2654	return 0;
2655}
2656
2657static int s5p_jpeg_runtime_resume(struct device *dev)
2658{
2659	struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2660	unsigned long flags;
2661	int ret;
2662
2663	ret = clk_prepare_enable(jpeg->clk);
2664	if (ret < 0)
2665		return ret;
2666
2667	if (!IS_ERR(jpeg->sclk)) {
2668		ret = clk_prepare_enable(jpeg->sclk);
2669		if (ret < 0)
2670			return ret;
2671	}
2672
2673	spin_lock_irqsave(&jpeg->slock, flags);
2674
2675	/*
2676	 * JPEG IP allows storing two Huffman tables for each component.
2677	 * We fill table 0 for each component and do this here only
2678	 * for S5PC210 and Exynos3250 SoCs. Exynos4x12 and Exynos542x SoC
2679	 * require programming their Huffman tables each time the encoding
2680	 * process is initialized, and thus it is accomplished in the
2681	 * device_run callback of m2m_ops.
2682	 */
2683	if (!jpeg->variant->htbl_reinit) {
2684		s5p_jpeg_set_hdctbl(jpeg->regs);
2685		s5p_jpeg_set_hdctblg(jpeg->regs);
2686		s5p_jpeg_set_hactbl(jpeg->regs);
2687		s5p_jpeg_set_hactblg(jpeg->regs);
2688	}
2689
2690	spin_unlock_irqrestore(&jpeg->slock, flags);
2691
2692	return 0;
2693}
2694#endif /* CONFIG_PM */
2695
2696#ifdef CONFIG_PM_SLEEP
2697static int s5p_jpeg_suspend(struct device *dev)
2698{
2699	if (pm_runtime_suspended(dev))
2700		return 0;
2701
2702	return s5p_jpeg_runtime_suspend(dev);
2703}
2704
2705static int s5p_jpeg_resume(struct device *dev)
2706{
2707	if (pm_runtime_suspended(dev))
2708		return 0;
2709
2710	return s5p_jpeg_runtime_resume(dev);
2711}
2712#endif
2713
2714static const struct dev_pm_ops s5p_jpeg_pm_ops = {
2715	SET_SYSTEM_SLEEP_PM_OPS(s5p_jpeg_suspend, s5p_jpeg_resume)
2716	SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume, NULL)
2717};
2718
2719static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
2720	.version	= SJPEG_S5P,
2721	.jpeg_irq	= s5p_jpeg_irq,
2722	.m2m_ops	= &s5p_jpeg_m2m_ops,
2723	.fmt_ver_flag	= SJPEG_FMT_FLAG_S5P,
2724};
2725
2726static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = {
2727	.version	= SJPEG_EXYNOS3250,
2728	.jpeg_irq	= exynos3250_jpeg_irq,
2729	.m2m_ops	= &exynos3250_jpeg_m2m_ops,
2730	.fmt_ver_flag	= SJPEG_FMT_FLAG_EXYNOS3250,
2731	.hw3250_compat	= 1,
2732};
2733
2734static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
2735	.version	= SJPEG_EXYNOS4,
2736	.jpeg_irq	= exynos4_jpeg_irq,
2737	.m2m_ops	= &exynos4_jpeg_m2m_ops,
2738	.fmt_ver_flag	= SJPEG_FMT_FLAG_EXYNOS4,
2739	.htbl_reinit	= 1,
2740};
2741
2742static struct s5p_jpeg_variant exynos5420_jpeg_drvdata = {
2743	.version	= SJPEG_EXYNOS5420,
2744	.jpeg_irq	= exynos3250_jpeg_irq,		/* intentionally 3250 */
2745	.m2m_ops	= &exynos3250_jpeg_m2m_ops,	/* intentionally 3250 */
2746	.fmt_ver_flag	= SJPEG_FMT_FLAG_EXYNOS3250,	/* intentionally 3250 */
2747	.hw3250_compat	= 1,
2748	.htbl_reinit	= 1,
2749};
2750
2751static const struct of_device_id samsung_jpeg_match[] = {
2752	{
2753		.compatible = "samsung,s5pv210-jpeg",
2754		.data = &s5p_jpeg_drvdata,
2755	}, {
2756		.compatible = "samsung,exynos3250-jpeg",
2757		.data = &exynos3250_jpeg_drvdata,
2758	}, {
2759		.compatible = "samsung,exynos4210-jpeg",
2760		.data = &exynos4_jpeg_drvdata,
2761	}, {
2762		.compatible = "samsung,exynos4212-jpeg",
2763		.data = &exynos4_jpeg_drvdata,
2764	}, {
2765		.compatible = "samsung,exynos5420-jpeg",
2766		.data = &exynos5420_jpeg_drvdata,
2767	},
2768	{},
2769};
2770
2771MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
2772
2773static void *jpeg_get_drv_data(struct device *dev)
2774{
2775	struct s5p_jpeg_variant *driver_data = NULL;
2776	const struct of_device_id *match;
2777
2778	if (!IS_ENABLED(CONFIG_OF) || !dev->of_node)
2779		return &s5p_jpeg_drvdata;
2780
2781	match = of_match_node(samsung_jpeg_match, dev->of_node);
2782
2783	if (match)
2784		driver_data = (struct s5p_jpeg_variant *)match->data;
2785
2786	return driver_data;
2787}
2788
2789static struct platform_driver s5p_jpeg_driver = {
2790	.probe = s5p_jpeg_probe,
2791	.remove = s5p_jpeg_remove,
2792	.driver = {
2793		.of_match_table	= of_match_ptr(samsung_jpeg_match),
2794		.name		= S5P_JPEG_M2M_NAME,
2795		.pm		= &s5p_jpeg_pm_ops,
2796	},
2797};
2798
2799module_platform_driver(s5p_jpeg_driver);
2800
2801MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
2802MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
2803MODULE_DESCRIPTION("Samsung JPEG codec driver");
2804MODULE_LICENSE("GPL");
2805