• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-v4l2.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 
38 static 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 
374 static 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 
417 static 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 
460 static const unsigned char hdctbl0[16] = {
461 	0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
462 };
463 
464 static const unsigned char hdctblg0[12] = {
465 	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
466 };
467 static const unsigned char hactbl0[16] = {
468 	0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
469 };
470 static 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  */
501 static const u32 subs422_fourcc_dwngrd_schema[] = {
502 	V4L2_PIX_FMT_NV16,
503 	V4L2_PIX_FMT_NV61,
504 };
505 
506 static 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  */
524 static 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 
s5p_jpeg_get_dwngrd_sch_id_by_fourcc(u32 fourcc)537 static 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 
s5p_jpeg_adjust_fourcc_to_subsampling(enum v4l2_jpeg_chroma_subsampling subs,u32 in_fourcc,u32 * out_fourcc,struct s5p_jpeg_ctx * ctx)548 static 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 
587 static 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 
594 static 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 
ctrl_to_ctx(struct v4l2_ctrl * c)604 static 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 
fh_to_ctx(struct v4l2_fh * fh)609 static 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 
s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx * ctx)614 static 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 	case SJPEG_EXYNOS5433:
630 		if (ctx->subsampling > 2)
631 			return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
632 		return exynos4x12_decoded_subsampling[ctx->subsampling];
633 	default:
634 		return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
635 	}
636 }
637 
s5p_jpeg_set_qtbl(void __iomem * regs,const unsigned char * qtbl,unsigned long tab,int len)638 static inline void s5p_jpeg_set_qtbl(void __iomem *regs,
639 				     const unsigned char *qtbl,
640 				     unsigned long tab, int len)
641 {
642 	int i;
643 
644 	for (i = 0; i < len; i++)
645 		writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
646 }
647 
s5p_jpeg_set_qtbl_lum(void __iomem * regs,int quality)648 static inline void s5p_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
649 {
650 	/* this driver fills quantisation table 0 with data for luma */
651 	s5p_jpeg_set_qtbl(regs, qtbl_luminance[quality],
652 			  S5P_JPG_QTBL_CONTENT(0),
653 			  ARRAY_SIZE(qtbl_luminance[quality]));
654 }
655 
s5p_jpeg_set_qtbl_chr(void __iomem * regs,int quality)656 static inline void s5p_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
657 {
658 	/* this driver fills quantisation table 1 with data for chroma */
659 	s5p_jpeg_set_qtbl(regs, qtbl_chrominance[quality],
660 			  S5P_JPG_QTBL_CONTENT(1),
661 			  ARRAY_SIZE(qtbl_chrominance[quality]));
662 }
663 
s5p_jpeg_set_htbl(void __iomem * regs,const unsigned char * htbl,unsigned long tab,int len)664 static inline void s5p_jpeg_set_htbl(void __iomem *regs,
665 				     const unsigned char *htbl,
666 				     unsigned long tab, int len)
667 {
668 	int i;
669 
670 	for (i = 0; i < len; i++)
671 		writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
672 }
673 
s5p_jpeg_set_hdctbl(void __iomem * regs)674 static inline void s5p_jpeg_set_hdctbl(void __iomem *regs)
675 {
676 	/* this driver fills table 0 for this component */
677 	s5p_jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0),
678 						ARRAY_SIZE(hdctbl0));
679 }
680 
s5p_jpeg_set_hdctblg(void __iomem * regs)681 static inline void s5p_jpeg_set_hdctblg(void __iomem *regs)
682 {
683 	/* this driver fills table 0 for this component */
684 	s5p_jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0),
685 						ARRAY_SIZE(hdctblg0));
686 }
687 
s5p_jpeg_set_hactbl(void __iomem * regs)688 static inline void s5p_jpeg_set_hactbl(void __iomem *regs)
689 {
690 	/* this driver fills table 0 for this component */
691 	s5p_jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0),
692 						ARRAY_SIZE(hactbl0));
693 }
694 
s5p_jpeg_set_hactblg(void __iomem * regs)695 static inline void s5p_jpeg_set_hactblg(void __iomem *regs)
696 {
697 	/* this driver fills table 0 for this component */
698 	s5p_jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0),
699 						ARRAY_SIZE(hactblg0));
700 }
701 
exynos4_jpeg_set_tbl(void __iomem * regs,const unsigned char * tbl,unsigned long tab,int len)702 static inline void exynos4_jpeg_set_tbl(void __iomem *regs,
703 					const unsigned char *tbl,
704 					unsigned long tab, int len)
705 {
706 	int i;
707 	unsigned int dword;
708 
709 	for (i = 0; i < len; i += 4) {
710 		dword = tbl[i] |
711 			(tbl[i + 1] << 8) |
712 			(tbl[i + 2] << 16) |
713 			(tbl[i + 3] << 24);
714 		writel(dword, regs + tab + i);
715 	}
716 }
717 
exynos4_jpeg_set_qtbl_lum(void __iomem * regs,int quality)718 static inline void exynos4_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
719 {
720 	/* this driver fills quantisation table 0 with data for luma */
721 	exynos4_jpeg_set_tbl(regs, qtbl_luminance[quality],
722 			     EXYNOS4_QTBL_CONTENT(0),
723 			     ARRAY_SIZE(qtbl_luminance[quality]));
724 }
725 
exynos4_jpeg_set_qtbl_chr(void __iomem * regs,int quality)726 static inline void exynos4_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
727 {
728 	/* this driver fills quantisation table 1 with data for chroma */
729 	exynos4_jpeg_set_tbl(regs, qtbl_chrominance[quality],
730 			     EXYNOS4_QTBL_CONTENT(1),
731 			     ARRAY_SIZE(qtbl_chrominance[quality]));
732 }
733 
exynos4_jpeg_set_huff_tbl(void __iomem * base)734 static void exynos4_jpeg_set_huff_tbl(void __iomem *base)
735 {
736 	exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCLL,
737 							ARRAY_SIZE(hdctbl0));
738 	exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCCL,
739 							ARRAY_SIZE(hdctbl0));
740 	exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCLV,
741 							ARRAY_SIZE(hdctblg0));
742 	exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCCV,
743 							ARRAY_SIZE(hdctblg0));
744 	exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACLL,
745 							ARRAY_SIZE(hactbl0));
746 	exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACCL,
747 							ARRAY_SIZE(hactbl0));
748 	exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACLV,
749 							ARRAY_SIZE(hactblg0));
750 	exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACCV,
751 							ARRAY_SIZE(hactblg0));
752 }
753 
__exynos4_huff_tbl(int class,int id,bool lenval)754 static inline int __exynos4_huff_tbl(int class, int id, bool lenval)
755 {
756 	/*
757 	 * class: 0 - DC, 1 - AC
758 	 * id: 0 - Y, 1 - Cb/Cr
759 	 */
760 	if (class) {
761 		if (id)
762 			return lenval ? EXYNOS4_HUFF_TBL_HACCL :
763 				EXYNOS4_HUFF_TBL_HACCV;
764 		return lenval ? EXYNOS4_HUFF_TBL_HACLL : EXYNOS4_HUFF_TBL_HACLV;
765 
766 	}
767 	/* class == 0 */
768 	if (id)
769 		return lenval ? EXYNOS4_HUFF_TBL_HDCCL : EXYNOS4_HUFF_TBL_HDCCV;
770 
771 	return lenval ? EXYNOS4_HUFF_TBL_HDCLL : EXYNOS4_HUFF_TBL_HDCLV;
772 }
773 
exynos4_huff_tbl_len(int class,int id)774 static inline int exynos4_huff_tbl_len(int class, int id)
775 {
776 	return __exynos4_huff_tbl(class, id, true);
777 }
778 
exynos4_huff_tbl_val(int class,int id)779 static inline int exynos4_huff_tbl_val(int class, int id)
780 {
781 	return __exynos4_huff_tbl(class, id, false);
782 }
783 
784 static int get_byte(struct s5p_jpeg_buffer *buf);
785 static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word);
786 static void skip(struct s5p_jpeg_buffer *buf, long len);
787 
exynos4_jpeg_parse_decode_h_tbl(struct s5p_jpeg_ctx * ctx)788 static void exynos4_jpeg_parse_decode_h_tbl(struct s5p_jpeg_ctx *ctx)
789 {
790 	struct s5p_jpeg *jpeg = ctx->jpeg;
791 	struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
792 	struct s5p_jpeg_buffer jpeg_buffer;
793 	unsigned int word;
794 	int c, x, components;
795 
796 	jpeg_buffer.size = 2; /* Ls */
797 	jpeg_buffer.data =
798 		(unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + ctx->out_q.sos + 2;
799 	jpeg_buffer.curr = 0;
800 
801 	word = 0;
802 
803 	if (get_word_be(&jpeg_buffer, &word))
804 		return;
805 	jpeg_buffer.size = (long)word - 2;
806 	jpeg_buffer.data += 2;
807 	jpeg_buffer.curr = 0;
808 
809 	components = get_byte(&jpeg_buffer);
810 	if (components == -1)
811 		return;
812 	while (components--) {
813 		c = get_byte(&jpeg_buffer);
814 		if (c == -1)
815 			return;
816 		x = get_byte(&jpeg_buffer);
817 		if (x == -1)
818 			return;
819 		exynos4_jpeg_select_dec_h_tbl(jpeg->regs, c,
820 					(((x >> 4) & 0x1) << 1) | (x & 0x1));
821 	}
822 
823 }
824 
exynos4_jpeg_parse_huff_tbl(struct s5p_jpeg_ctx * ctx)825 static void exynos4_jpeg_parse_huff_tbl(struct s5p_jpeg_ctx *ctx)
826 {
827 	struct s5p_jpeg *jpeg = ctx->jpeg;
828 	struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
829 	struct s5p_jpeg_buffer jpeg_buffer;
830 	unsigned int word;
831 	int c, i, n, j;
832 
833 	for (j = 0; j < ctx->out_q.dht.n; ++j) {
834 		jpeg_buffer.size = ctx->out_q.dht.len[j];
835 		jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) +
836 				   ctx->out_q.dht.marker[j];
837 		jpeg_buffer.curr = 0;
838 
839 		word = 0;
840 		while (jpeg_buffer.curr < jpeg_buffer.size) {
841 			char id, class;
842 
843 			c = get_byte(&jpeg_buffer);
844 			if (c == -1)
845 				return;
846 			id = c & 0xf;
847 			class = (c >> 4) & 0xf;
848 			n = 0;
849 			for (i = 0; i < 16; ++i) {
850 				c = get_byte(&jpeg_buffer);
851 				if (c == -1)
852 					return;
853 				word |= c << ((i % 4) * 8);
854 				if ((i + 1) % 4 == 0) {
855 					writel(word, jpeg->regs +
856 					exynos4_huff_tbl_len(class, id) +
857 					(i / 4) * 4);
858 					word = 0;
859 				}
860 				n += c;
861 			}
862 			word = 0;
863 			for (i = 0; i < n; ++i) {
864 				c = get_byte(&jpeg_buffer);
865 				if (c == -1)
866 					return;
867 				word |= c << ((i % 4) * 8);
868 				if ((i + 1) % 4 == 0) {
869 					writel(word, jpeg->regs +
870 					exynos4_huff_tbl_val(class, id) +
871 					(i / 4) * 4);
872 					word = 0;
873 				}
874 			}
875 			if (i % 4) {
876 				writel(word, jpeg->regs +
877 				exynos4_huff_tbl_val(class, id) + (i / 4) * 4);
878 			}
879 			word = 0;
880 		}
881 	}
882 }
883 
exynos4_jpeg_parse_decode_q_tbl(struct s5p_jpeg_ctx * ctx)884 static void exynos4_jpeg_parse_decode_q_tbl(struct s5p_jpeg_ctx *ctx)
885 {
886 	struct s5p_jpeg *jpeg = ctx->jpeg;
887 	struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
888 	struct s5p_jpeg_buffer jpeg_buffer;
889 	int c, x, components;
890 
891 	jpeg_buffer.size = ctx->out_q.sof_len;
892 	jpeg_buffer.data =
893 		(unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + ctx->out_q.sof;
894 	jpeg_buffer.curr = 0;
895 
896 	skip(&jpeg_buffer, 5); /* P, Y, X */
897 	components = get_byte(&jpeg_buffer);
898 	if (components == -1)
899 		return;
900 
901 	exynos4_jpeg_set_dec_components(jpeg->regs, components);
902 
903 	while (components--) {
904 		c = get_byte(&jpeg_buffer);
905 		if (c == -1)
906 			return;
907 		skip(&jpeg_buffer, 1);
908 		x = get_byte(&jpeg_buffer);
909 		if (x == -1)
910 			return;
911 		exynos4_jpeg_select_dec_q_tbl(jpeg->regs, c, x);
912 	}
913 }
914 
exynos4_jpeg_parse_q_tbl(struct s5p_jpeg_ctx * ctx)915 static void exynos4_jpeg_parse_q_tbl(struct s5p_jpeg_ctx *ctx)
916 {
917 	struct s5p_jpeg *jpeg = ctx->jpeg;
918 	struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
919 	struct s5p_jpeg_buffer jpeg_buffer;
920 	unsigned int word;
921 	int c, i, j;
922 
923 	for (j = 0; j < ctx->out_q.dqt.n; ++j) {
924 		jpeg_buffer.size = ctx->out_q.dqt.len[j];
925 		jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) +
926 				   ctx->out_q.dqt.marker[j];
927 		jpeg_buffer.curr = 0;
928 
929 		word = 0;
930 		while (jpeg_buffer.size - jpeg_buffer.curr >= 65) {
931 			char id;
932 
933 			c = get_byte(&jpeg_buffer);
934 			if (c == -1)
935 				return;
936 			id = c & 0xf;
937 			/* nonzero means extended mode - not supported */
938 			if ((c >> 4) & 0xf)
939 				return;
940 			for (i = 0; i < 64; ++i) {
941 				c = get_byte(&jpeg_buffer);
942 				if (c == -1)
943 					return;
944 				word |= c << ((i % 4) * 8);
945 				if ((i + 1) % 4 == 0) {
946 					writel(word, jpeg->regs +
947 					EXYNOS4_QTBL_CONTENT(id) + (i / 4) * 4);
948 					word = 0;
949 				}
950 			}
951 			word = 0;
952 		}
953 	}
954 }
955 
956 /*
957  * ============================================================================
958  * Device file operations
959  * ============================================================================
960  */
961 
962 static int queue_init(void *priv, struct vb2_queue *src_vq,
963 		      struct vb2_queue *dst_vq);
964 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
965 				__u32 pixelformat, unsigned int fmt_type);
966 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
967 
s5p_jpeg_open(struct file * file)968 static int s5p_jpeg_open(struct file *file)
969 {
970 	struct s5p_jpeg *jpeg = video_drvdata(file);
971 	struct video_device *vfd = video_devdata(file);
972 	struct s5p_jpeg_ctx *ctx;
973 	struct s5p_jpeg_fmt *out_fmt, *cap_fmt;
974 	int ret = 0;
975 
976 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
977 	if (!ctx)
978 		return -ENOMEM;
979 
980 	if (mutex_lock_interruptible(&jpeg->lock)) {
981 		ret = -ERESTARTSYS;
982 		goto free;
983 	}
984 
985 	v4l2_fh_init(&ctx->fh, vfd);
986 	/* Use separate control handler per file handle */
987 	ctx->fh.ctrl_handler = &ctx->ctrl_handler;
988 	file->private_data = &ctx->fh;
989 	v4l2_fh_add(&ctx->fh);
990 
991 	ctx->jpeg = jpeg;
992 	if (vfd == jpeg->vfd_encoder) {
993 		ctx->mode = S5P_JPEG_ENCODE;
994 		out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB565,
995 							FMT_TYPE_OUTPUT);
996 		cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
997 							FMT_TYPE_CAPTURE);
998 	} else {
999 		ctx->mode = S5P_JPEG_DECODE;
1000 		out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
1001 							FMT_TYPE_OUTPUT);
1002 		cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV,
1003 							FMT_TYPE_CAPTURE);
1004 		ctx->scale_factor = EXYNOS3250_DEC_SCALE_FACTOR_8_8;
1005 	}
1006 
1007 	ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
1008 	if (IS_ERR(ctx->fh.m2m_ctx)) {
1009 		ret = PTR_ERR(ctx->fh.m2m_ctx);
1010 		goto error;
1011 	}
1012 
1013 	ctx->out_q.fmt = out_fmt;
1014 	ctx->cap_q.fmt = cap_fmt;
1015 
1016 	ret = s5p_jpeg_controls_create(ctx);
1017 	if (ret < 0)
1018 		goto error;
1019 
1020 	mutex_unlock(&jpeg->lock);
1021 	return 0;
1022 
1023 error:
1024 	v4l2_fh_del(&ctx->fh);
1025 	v4l2_fh_exit(&ctx->fh);
1026 	mutex_unlock(&jpeg->lock);
1027 free:
1028 	kfree(ctx);
1029 	return ret;
1030 }
1031 
s5p_jpeg_release(struct file * file)1032 static int s5p_jpeg_release(struct file *file)
1033 {
1034 	struct s5p_jpeg *jpeg = video_drvdata(file);
1035 	struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
1036 
1037 	mutex_lock(&jpeg->lock);
1038 	v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1039 	v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1040 	v4l2_fh_del(&ctx->fh);
1041 	v4l2_fh_exit(&ctx->fh);
1042 	kfree(ctx);
1043 	mutex_unlock(&jpeg->lock);
1044 
1045 	return 0;
1046 }
1047 
1048 static const struct v4l2_file_operations s5p_jpeg_fops = {
1049 	.owner		= THIS_MODULE,
1050 	.open		= s5p_jpeg_open,
1051 	.release	= s5p_jpeg_release,
1052 	.poll		= v4l2_m2m_fop_poll,
1053 	.unlocked_ioctl	= video_ioctl2,
1054 	.mmap		= v4l2_m2m_fop_mmap,
1055 };
1056 
1057 /*
1058  * ============================================================================
1059  * video ioctl operations
1060  * ============================================================================
1061  */
1062 
get_byte(struct s5p_jpeg_buffer * buf)1063 static int get_byte(struct s5p_jpeg_buffer *buf)
1064 {
1065 	if (buf->curr >= buf->size)
1066 		return -1;
1067 
1068 	return ((unsigned char *)buf->data)[buf->curr++];
1069 }
1070 
get_word_be(struct s5p_jpeg_buffer * buf,unsigned int * word)1071 static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
1072 {
1073 	unsigned int temp;
1074 	int byte;
1075 
1076 	byte = get_byte(buf);
1077 	if (byte == -1)
1078 		return -1;
1079 	temp = byte << 8;
1080 	byte = get_byte(buf);
1081 	if (byte == -1)
1082 		return -1;
1083 	*word = (unsigned int)byte | temp;
1084 	return 0;
1085 }
1086 
skip(struct s5p_jpeg_buffer * buf,long len)1087 static void skip(struct s5p_jpeg_buffer *buf, long len)
1088 {
1089 	if (len <= 0)
1090 		return;
1091 
1092 	while (len--)
1093 		get_byte(buf);
1094 }
1095 
s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data * result,unsigned long buffer,unsigned long size,struct s5p_jpeg_ctx * ctx)1096 static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
1097 			       unsigned long buffer, unsigned long size,
1098 			       struct s5p_jpeg_ctx *ctx)
1099 {
1100 	int c, components = 0, notfound, n_dht = 0, n_dqt = 0;
1101 	unsigned int height = 0, width = 0, word, subsampling = 0;
1102 	unsigned int sos = 0, sof = 0, sof_len = 0;
1103 	unsigned int dht[S5P_JPEG_MAX_MARKER], dht_len[S5P_JPEG_MAX_MARKER];
1104 	unsigned int dqt[S5P_JPEG_MAX_MARKER], dqt_len[S5P_JPEG_MAX_MARKER];
1105 	long length;
1106 	struct s5p_jpeg_buffer jpeg_buffer;
1107 
1108 	jpeg_buffer.size = size;
1109 	jpeg_buffer.data = buffer;
1110 	jpeg_buffer.curr = 0;
1111 
1112 	notfound = 1;
1113 	while (notfound || !sos) {
1114 		c = get_byte(&jpeg_buffer);
1115 		if (c == -1)
1116 			return false;
1117 		if (c != 0xff)
1118 			continue;
1119 		do
1120 			c = get_byte(&jpeg_buffer);
1121 		while (c == 0xff);
1122 		if (c == -1)
1123 			return false;
1124 		if (c == 0)
1125 			continue;
1126 		length = 0;
1127 		switch (c) {
1128 		/* SOF0: baseline JPEG */
1129 		case SOF0:
1130 			if (get_word_be(&jpeg_buffer, &word))
1131 				break;
1132 			length = (long)word - 2;
1133 			if (!length)
1134 				return false;
1135 			sof = jpeg_buffer.curr; /* after 0xffc0 */
1136 			sof_len = length;
1137 			if (get_byte(&jpeg_buffer) == -1)
1138 				break;
1139 			if (get_word_be(&jpeg_buffer, &height))
1140 				break;
1141 			if (get_word_be(&jpeg_buffer, &width))
1142 				break;
1143 			components = get_byte(&jpeg_buffer);
1144 			if (components == -1)
1145 				break;
1146 
1147 			if (components == 1) {
1148 				subsampling = 0x33;
1149 			} else {
1150 				skip(&jpeg_buffer, 1);
1151 				subsampling = get_byte(&jpeg_buffer);
1152 				skip(&jpeg_buffer, 1);
1153 			}
1154 			if (components > 3)
1155 				return false;
1156 			skip(&jpeg_buffer, components * 2);
1157 			notfound = 0;
1158 			break;
1159 
1160 		case DQT:
1161 			if (get_word_be(&jpeg_buffer, &word))
1162 				break;
1163 			length = (long)word - 2;
1164 			if (!length)
1165 				return false;
1166 			if (n_dqt >= S5P_JPEG_MAX_MARKER)
1167 				return false;
1168 			dqt[n_dqt] = jpeg_buffer.curr; /* after 0xffdb */
1169 			dqt_len[n_dqt++] = length;
1170 			skip(&jpeg_buffer, length);
1171 			break;
1172 
1173 		case DHT:
1174 			if (get_word_be(&jpeg_buffer, &word))
1175 				break;
1176 			length = (long)word - 2;
1177 			if (!length)
1178 				return false;
1179 			if (n_dht >= S5P_JPEG_MAX_MARKER)
1180 				return false;
1181 			dht[n_dht] = jpeg_buffer.curr; /* after 0xffc4 */
1182 			dht_len[n_dht++] = length;
1183 			skip(&jpeg_buffer, length);
1184 			break;
1185 
1186 		case SOS:
1187 			sos = jpeg_buffer.curr - 2; /* 0xffda */
1188 			break;
1189 
1190 		/* skip payload-less markers */
1191 		case RST ... RST + 7:
1192 		case SOI:
1193 		case EOI:
1194 		case TEM:
1195 			break;
1196 
1197 		/* skip uninteresting payload markers */
1198 		default:
1199 			if (get_word_be(&jpeg_buffer, &word))
1200 				break;
1201 			length = (long)word - 2;
1202 			skip(&jpeg_buffer, length);
1203 			break;
1204 		}
1205 	}
1206 	result->w = width;
1207 	result->h = height;
1208 	result->sos = sos;
1209 	result->dht.n = n_dht;
1210 	while (n_dht--) {
1211 		result->dht.marker[n_dht] = dht[n_dht];
1212 		result->dht.len[n_dht] = dht_len[n_dht];
1213 	}
1214 	result->dqt.n = n_dqt;
1215 	while (n_dqt--) {
1216 		result->dqt.marker[n_dqt] = dqt[n_dqt];
1217 		result->dqt.len[n_dqt] = dqt_len[n_dqt];
1218 	}
1219 	result->sof = sof;
1220 	result->sof_len = sof_len;
1221 	result->size = result->components = components;
1222 
1223 	switch (subsampling) {
1224 	case 0x11:
1225 		ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
1226 		break;
1227 	case 0x21:
1228 		ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
1229 		break;
1230 	case 0x22:
1231 		ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
1232 		break;
1233 	case 0x33:
1234 		ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
1235 		break;
1236 	default:
1237 		return false;
1238 	}
1239 
1240 	return !notfound && sos;
1241 }
1242 
s5p_jpeg_querycap(struct file * file,void * priv,struct v4l2_capability * cap)1243 static int s5p_jpeg_querycap(struct file *file, void *priv,
1244 			   struct v4l2_capability *cap)
1245 {
1246 	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1247 
1248 	if (ctx->mode == S5P_JPEG_ENCODE) {
1249 		strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder",
1250 			sizeof(cap->driver));
1251 		strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
1252 			sizeof(cap->card));
1253 	} else {
1254 		strlcpy(cap->driver, S5P_JPEG_M2M_NAME " decoder",
1255 			sizeof(cap->driver));
1256 		strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
1257 			sizeof(cap->card));
1258 	}
1259 	cap->bus_info[0] = 0;
1260 	cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
1261 	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1262 	return 0;
1263 }
1264 
enum_fmt(struct s5p_jpeg_ctx * ctx,struct s5p_jpeg_fmt * sjpeg_formats,int n,struct v4l2_fmtdesc * f,u32 type)1265 static int enum_fmt(struct s5p_jpeg_ctx *ctx,
1266 		    struct s5p_jpeg_fmt *sjpeg_formats, int n,
1267 		    struct v4l2_fmtdesc *f, u32 type)
1268 {
1269 	int i, num = 0;
1270 	unsigned int fmt_ver_flag = ctx->jpeg->variant->fmt_ver_flag;
1271 
1272 	for (i = 0; i < n; ++i) {
1273 		if (sjpeg_formats[i].flags & type &&
1274 		    sjpeg_formats[i].flags & fmt_ver_flag) {
1275 			/* index-th format of type type found ? */
1276 			if (num == f->index)
1277 				break;
1278 			/* Correct type but haven't reached our index yet,
1279 			 * just increment per-type index */
1280 			++num;
1281 		}
1282 	}
1283 
1284 	/* Format not found */
1285 	if (i >= n)
1286 		return -EINVAL;
1287 
1288 	strlcpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
1289 	f->pixelformat = sjpeg_formats[i].fourcc;
1290 
1291 	return 0;
1292 }
1293 
s5p_jpeg_enum_fmt_vid_cap(struct file * file,void * priv,struct v4l2_fmtdesc * f)1294 static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
1295 				   struct v4l2_fmtdesc *f)
1296 {
1297 	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1298 
1299 	if (ctx->mode == S5P_JPEG_ENCODE)
1300 		return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f,
1301 				SJPEG_FMT_FLAG_ENC_CAPTURE);
1302 
1303 	return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f,
1304 			SJPEG_FMT_FLAG_DEC_CAPTURE);
1305 }
1306 
s5p_jpeg_enum_fmt_vid_out(struct file * file,void * priv,struct v4l2_fmtdesc * f)1307 static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
1308 				   struct v4l2_fmtdesc *f)
1309 {
1310 	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1311 
1312 	if (ctx->mode == S5P_JPEG_ENCODE)
1313 		return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f,
1314 				SJPEG_FMT_FLAG_ENC_OUTPUT);
1315 
1316 	return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f,
1317 			SJPEG_FMT_FLAG_DEC_OUTPUT);
1318 }
1319 
get_q_data(struct s5p_jpeg_ctx * ctx,enum v4l2_buf_type type)1320 static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
1321 					  enum v4l2_buf_type type)
1322 {
1323 	if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1324 		return &ctx->out_q;
1325 	if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1326 		return &ctx->cap_q;
1327 
1328 	return NULL;
1329 }
1330 
s5p_jpeg_g_fmt(struct file * file,void * priv,struct v4l2_format * f)1331 static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
1332 {
1333 	struct vb2_queue *vq;
1334 	struct s5p_jpeg_q_data *q_data = NULL;
1335 	struct v4l2_pix_format *pix = &f->fmt.pix;
1336 	struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
1337 
1338 	vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1339 	if (!vq)
1340 		return -EINVAL;
1341 
1342 	if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1343 	    ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
1344 		return -EINVAL;
1345 	q_data = get_q_data(ct, f->type);
1346 	BUG_ON(q_data == NULL);
1347 
1348 	pix->width = q_data->w;
1349 	pix->height = q_data->h;
1350 	pix->field = V4L2_FIELD_NONE;
1351 	pix->pixelformat = q_data->fmt->fourcc;
1352 	pix->bytesperline = 0;
1353 	if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
1354 		u32 bpl = q_data->w;
1355 		if (q_data->fmt->colplanes == 1)
1356 			bpl = (bpl * q_data->fmt->depth) >> 3;
1357 		pix->bytesperline = bpl;
1358 	}
1359 	pix->sizeimage = q_data->size;
1360 
1361 	return 0;
1362 }
1363 
s5p_jpeg_find_format(struct s5p_jpeg_ctx * ctx,u32 pixelformat,unsigned int fmt_type)1364 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
1365 				u32 pixelformat, unsigned int fmt_type)
1366 {
1367 	unsigned int k, fmt_flag;
1368 
1369 	if (ctx->mode == S5P_JPEG_ENCODE)
1370 		fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
1371 				SJPEG_FMT_FLAG_ENC_OUTPUT :
1372 				SJPEG_FMT_FLAG_ENC_CAPTURE;
1373 	else
1374 		fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
1375 				SJPEG_FMT_FLAG_DEC_OUTPUT :
1376 				SJPEG_FMT_FLAG_DEC_CAPTURE;
1377 
1378 	for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
1379 		struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
1380 		if (fmt->fourcc == pixelformat &&
1381 		    fmt->flags & fmt_flag &&
1382 		    fmt->flags & ctx->jpeg->variant->fmt_ver_flag) {
1383 			return fmt;
1384 		}
1385 	}
1386 
1387 	return NULL;
1388 }
1389 
jpeg_bound_align_image(struct s5p_jpeg_ctx * ctx,u32 * w,unsigned int wmin,unsigned int wmax,unsigned int walign,u32 * h,unsigned int hmin,unsigned int hmax,unsigned int halign)1390 static void jpeg_bound_align_image(struct s5p_jpeg_ctx *ctx,
1391 				   u32 *w, unsigned int wmin, unsigned int wmax,
1392 				   unsigned int walign,
1393 				   u32 *h, unsigned int hmin, unsigned int hmax,
1394 				   unsigned int halign)
1395 {
1396 	int width, height, w_step, h_step;
1397 
1398 	width = *w;
1399 	height = *h;
1400 
1401 	w_step = 1 << walign;
1402 	h_step = 1 << halign;
1403 
1404 	if (ctx->jpeg->variant->hw3250_compat) {
1405 		/*
1406 		 * Rightmost and bottommost pixels are cropped by the
1407 		 * Exynos3250/compatible JPEG IP for RGB formats, for the
1408 		 * specific width and height values respectively. This
1409 		 * assignment will result in v4l_bound_align_image returning
1410 		 * dimensions reduced by 1 for the aforementioned cases.
1411 		 */
1412 		if (w_step == 4 && ((width & 3) == 1)) {
1413 			wmax = width;
1414 			hmax = height;
1415 		}
1416 	}
1417 
1418 	v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
1419 
1420 	if (*w < width && (*w + w_step) < wmax)
1421 		*w += w_step;
1422 	if (*h < height && (*h + h_step) < hmax)
1423 		*h += h_step;
1424 }
1425 
vidioc_try_fmt(struct v4l2_format * f,struct s5p_jpeg_fmt * fmt,struct s5p_jpeg_ctx * ctx,int q_type)1426 static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
1427 			  struct s5p_jpeg_ctx *ctx, int q_type)
1428 {
1429 	struct v4l2_pix_format *pix = &f->fmt.pix;
1430 
1431 	if (pix->field == V4L2_FIELD_ANY)
1432 		pix->field = V4L2_FIELD_NONE;
1433 	else if (pix->field != V4L2_FIELD_NONE)
1434 		return -EINVAL;
1435 
1436 	/* V4L2 specification suggests the driver corrects the format struct
1437 	 * if any of the dimensions is unsupported */
1438 	if (q_type == FMT_TYPE_OUTPUT)
1439 		jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
1440 				       S5P_JPEG_MAX_WIDTH, 0,
1441 				       &pix->height, S5P_JPEG_MIN_HEIGHT,
1442 				       S5P_JPEG_MAX_HEIGHT, 0);
1443 	else
1444 		jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
1445 				       S5P_JPEG_MAX_WIDTH, fmt->h_align,
1446 				       &pix->height, S5P_JPEG_MIN_HEIGHT,
1447 				       S5P_JPEG_MAX_HEIGHT, fmt->v_align);
1448 
1449 	if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1450 		if (pix->sizeimage <= 0)
1451 			pix->sizeimage = PAGE_SIZE;
1452 		pix->bytesperline = 0;
1453 	} else {
1454 		u32 bpl = pix->bytesperline;
1455 
1456 		if (fmt->colplanes > 1 && bpl < pix->width)
1457 			bpl = pix->width; /* planar */
1458 
1459 		if (fmt->colplanes == 1 && /* packed */
1460 		    (bpl << 3) / fmt->depth < pix->width)
1461 			bpl = (pix->width * fmt->depth) >> 3;
1462 
1463 		pix->bytesperline = bpl;
1464 		pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
1465 	}
1466 
1467 	return 0;
1468 }
1469 
s5p_jpeg_try_fmt_vid_cap(struct file * file,void * priv,struct v4l2_format * f)1470 static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
1471 				  struct v4l2_format *f)
1472 {
1473 	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1474 	struct v4l2_pix_format *pix = &f->fmt.pix;
1475 	struct s5p_jpeg_fmt *fmt;
1476 	int ret;
1477 
1478 	fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1479 						FMT_TYPE_CAPTURE);
1480 	if (!fmt) {
1481 		v4l2_err(&ctx->jpeg->v4l2_dev,
1482 			 "Fourcc format (0x%08x) invalid.\n",
1483 			 f->fmt.pix.pixelformat);
1484 		return -EINVAL;
1485 	}
1486 
1487 	if (!ctx->jpeg->variant->hw_ex4_compat || ctx->mode != S5P_JPEG_DECODE)
1488 		goto exit;
1489 
1490 	/*
1491 	 * The exynos4x12 device requires resulting YUV image
1492 	 * subsampling not to be lower than the input jpeg subsampling.
1493 	 * If this requirement is not met then downgrade the requested
1494 	 * capture format to the one with subsampling equal to the input jpeg.
1495 	 */
1496 	if ((fmt->flags & SJPEG_FMT_NON_RGB) &&
1497 	    (fmt->subsampling < ctx->subsampling)) {
1498 		ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling,
1499 							    fmt->fourcc,
1500 							    &pix->pixelformat,
1501 							    ctx);
1502 		if (ret < 0)
1503 			pix->pixelformat = V4L2_PIX_FMT_GREY;
1504 
1505 		fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1506 							FMT_TYPE_CAPTURE);
1507 	}
1508 
1509 	/*
1510 	 * Decompression of a JPEG file with 4:2:0 subsampling and odd
1511 	 * width to the YUV 4:2:0 compliant formats produces a raw image
1512 	 * with broken luma component. Adjust capture format to RGB565
1513 	 * in such a case.
1514 	 */
1515 	if (ctx->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420 &&
1516 	    (ctx->out_q.w & 1) &&
1517 	    (pix->pixelformat == V4L2_PIX_FMT_NV12 ||
1518 	     pix->pixelformat == V4L2_PIX_FMT_NV21 ||
1519 	     pix->pixelformat == V4L2_PIX_FMT_YUV420)) {
1520 		pix->pixelformat = V4L2_PIX_FMT_RGB565;
1521 		fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1522 							FMT_TYPE_CAPTURE);
1523 	}
1524 
1525 exit:
1526 	return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
1527 }
1528 
s5p_jpeg_try_fmt_vid_out(struct file * file,void * priv,struct v4l2_format * f)1529 static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
1530 				  struct v4l2_format *f)
1531 {
1532 	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1533 	struct s5p_jpeg_fmt *fmt;
1534 
1535 	fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1536 						FMT_TYPE_OUTPUT);
1537 	if (!fmt) {
1538 		v4l2_err(&ctx->jpeg->v4l2_dev,
1539 			 "Fourcc format (0x%08x) invalid.\n",
1540 			 f->fmt.pix.pixelformat);
1541 		return -EINVAL;
1542 	}
1543 
1544 	return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
1545 }
1546 
exynos4_jpeg_get_output_buffer_size(struct s5p_jpeg_ctx * ctx,struct v4l2_format * f,int fmt_depth)1547 static int exynos4_jpeg_get_output_buffer_size(struct s5p_jpeg_ctx *ctx,
1548 						struct v4l2_format *f,
1549 						int fmt_depth)
1550 {
1551 	struct v4l2_pix_format *pix = &f->fmt.pix;
1552 	u32 pix_fmt = f->fmt.pix.pixelformat;
1553 	int w = pix->width, h = pix->height, wh_align;
1554 
1555 	if (pix_fmt == V4L2_PIX_FMT_RGB32 ||
1556 	    pix_fmt == V4L2_PIX_FMT_NV24 ||
1557 	    pix_fmt == V4L2_PIX_FMT_NV42 ||
1558 	    pix_fmt == V4L2_PIX_FMT_NV12 ||
1559 	    pix_fmt == V4L2_PIX_FMT_NV21 ||
1560 	    pix_fmt == V4L2_PIX_FMT_YUV420)
1561 		wh_align = 4;
1562 	else
1563 		wh_align = 1;
1564 
1565 	jpeg_bound_align_image(ctx, &w, S5P_JPEG_MIN_WIDTH,
1566 			       S5P_JPEG_MAX_WIDTH, wh_align,
1567 			       &h, S5P_JPEG_MIN_HEIGHT,
1568 			       S5P_JPEG_MAX_HEIGHT, wh_align);
1569 
1570 	return w * h * fmt_depth >> 3;
1571 }
1572 
1573 static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1574 				   struct v4l2_rect *r);
1575 
s5p_jpeg_s_fmt(struct s5p_jpeg_ctx * ct,struct v4l2_format * f)1576 static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
1577 {
1578 	struct vb2_queue *vq;
1579 	struct s5p_jpeg_q_data *q_data = NULL;
1580 	struct v4l2_pix_format *pix = &f->fmt.pix;
1581 	struct v4l2_ctrl *ctrl_subs;
1582 	struct v4l2_rect scale_rect;
1583 	unsigned int f_type;
1584 
1585 	vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1586 	if (!vq)
1587 		return -EINVAL;
1588 
1589 	q_data = get_q_data(ct, f->type);
1590 	BUG_ON(q_data == NULL);
1591 
1592 	if (vb2_is_busy(vq)) {
1593 		v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
1594 		return -EBUSY;
1595 	}
1596 
1597 	f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
1598 			FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
1599 
1600 	q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
1601 	q_data->w = pix->width;
1602 	q_data->h = pix->height;
1603 	if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
1604 		/*
1605 		 * During encoding Exynos4x12 SoCs access wider memory area
1606 		 * than it results from Image_x and Image_y values written to
1607 		 * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu
1608 		 * page fault calculate proper buffer size in such a case.
1609 		 */
1610 		if (ct->jpeg->variant->hw_ex4_compat &&
1611 		    f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE)
1612 			q_data->size = exynos4_jpeg_get_output_buffer_size(ct,
1613 							f,
1614 							q_data->fmt->depth);
1615 		else
1616 			q_data->size = q_data->w * q_data->h *
1617 						q_data->fmt->depth >> 3;
1618 	} else {
1619 		q_data->size = pix->sizeimage;
1620 	}
1621 
1622 	if (f_type == FMT_TYPE_OUTPUT) {
1623 		ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler,
1624 					V4L2_CID_JPEG_CHROMA_SUBSAMPLING);
1625 		if (ctrl_subs)
1626 			v4l2_ctrl_s_ctrl(ctrl_subs, q_data->fmt->subsampling);
1627 		ct->crop_altered = false;
1628 	}
1629 
1630 	/*
1631 	 * For decoding init crop_rect with capture buffer dimmensions which
1632 	 * contain aligned dimensions of the input JPEG image and do it only
1633 	 * if crop rectangle hasn't been altered by the user space e.g. with
1634 	 * S_SELECTION ioctl. For encoding assign output buffer dimensions.
1635 	 */
1636 	if (!ct->crop_altered &&
1637 	    ((ct->mode == S5P_JPEG_DECODE && f_type == FMT_TYPE_CAPTURE) ||
1638 	     (ct->mode == S5P_JPEG_ENCODE && f_type == FMT_TYPE_OUTPUT))) {
1639 		ct->crop_rect.width = pix->width;
1640 		ct->crop_rect.height = pix->height;
1641 	}
1642 
1643 	/*
1644 	 * Prevent downscaling to YUV420 format by more than 2
1645 	 * for Exynos3250/compatible SoC as it produces broken raw image
1646 	 * in such cases.
1647 	 */
1648 	if (ct->mode == S5P_JPEG_DECODE &&
1649 	    f_type == FMT_TYPE_CAPTURE &&
1650 	    ct->jpeg->variant->hw3250_compat &&
1651 	    pix->pixelformat == V4L2_PIX_FMT_YUV420 &&
1652 	    ct->scale_factor > 2) {
1653 		scale_rect.width = ct->out_q.w / 2;
1654 		scale_rect.height = ct->out_q.h / 2;
1655 		exynos3250_jpeg_try_downscale(ct, &scale_rect);
1656 	}
1657 
1658 	return 0;
1659 }
1660 
s5p_jpeg_s_fmt_vid_cap(struct file * file,void * priv,struct v4l2_format * f)1661 static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
1662 				struct v4l2_format *f)
1663 {
1664 	int ret;
1665 
1666 	ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
1667 	if (ret)
1668 		return ret;
1669 
1670 	return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1671 }
1672 
s5p_jpeg_s_fmt_vid_out(struct file * file,void * priv,struct v4l2_format * f)1673 static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
1674 				struct v4l2_format *f)
1675 {
1676 	int ret;
1677 
1678 	ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
1679 	if (ret)
1680 		return ret;
1681 
1682 	return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1683 }
1684 
exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx * ctx,struct v4l2_rect * r)1685 static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1686 				   struct v4l2_rect *r)
1687 {
1688 	int w_ratio, h_ratio, scale_factor, cur_ratio, i;
1689 
1690 	w_ratio = ctx->out_q.w / r->width;
1691 	h_ratio = ctx->out_q.h / r->height;
1692 
1693 	scale_factor = w_ratio > h_ratio ? w_ratio : h_ratio;
1694 	scale_factor = clamp_val(scale_factor, 1, 8);
1695 
1696 	/* Align scale ratio to the nearest power of 2 */
1697 	for (i = 0; i <= 3; ++i) {
1698 		cur_ratio = 1 << i;
1699 		if (scale_factor <= cur_ratio) {
1700 			ctx->scale_factor = cur_ratio;
1701 			break;
1702 		}
1703 	}
1704 
1705 	r->width = round_down(ctx->out_q.w / ctx->scale_factor, 2);
1706 	r->height = round_down(ctx->out_q.h / ctx->scale_factor, 2);
1707 
1708 	ctx->crop_rect.width = r->width;
1709 	ctx->crop_rect.height = r->height;
1710 	ctx->crop_rect.left = 0;
1711 	ctx->crop_rect.top = 0;
1712 
1713 	ctx->crop_altered = true;
1714 
1715 	return 0;
1716 }
1717 
1718 /* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
enclosed_rectangle(struct v4l2_rect * a,struct v4l2_rect * b)1719 static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
1720 {
1721 	if (a->left < b->left || a->top < b->top)
1722 		return 0;
1723 	if (a->left + a->width > b->left + b->width)
1724 		return 0;
1725 	if (a->top + a->height > b->top + b->height)
1726 		return 0;
1727 
1728 	return 1;
1729 }
1730 
exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx * ctx,struct v4l2_rect * r)1731 static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx,
1732 				   struct v4l2_rect *r)
1733 {
1734 	struct v4l2_rect base_rect;
1735 	int w_step, h_step;
1736 
1737 	switch (ctx->cap_q.fmt->fourcc) {
1738 	case V4L2_PIX_FMT_NV12:
1739 	case V4L2_PIX_FMT_NV21:
1740 		w_step = 1;
1741 		h_step = 2;
1742 		break;
1743 	case V4L2_PIX_FMT_YUV420:
1744 		w_step = 2;
1745 		h_step = 2;
1746 		break;
1747 	default:
1748 		w_step = 1;
1749 		h_step = 1;
1750 		break;
1751 	}
1752 
1753 	base_rect.top = 0;
1754 	base_rect.left = 0;
1755 	base_rect.width = ctx->out_q.w;
1756 	base_rect.height = ctx->out_q.h;
1757 
1758 	r->width = round_down(r->width, w_step);
1759 	r->height = round_down(r->height, h_step);
1760 	r->left = round_down(r->left, 2);
1761 	r->top = round_down(r->top, 2);
1762 
1763 	if (!enclosed_rectangle(r, &base_rect))
1764 		return -EINVAL;
1765 
1766 	ctx->crop_rect.left = r->left;
1767 	ctx->crop_rect.top = r->top;
1768 	ctx->crop_rect.width = r->width;
1769 	ctx->crop_rect.height = r->height;
1770 
1771 	ctx->crop_altered = true;
1772 
1773 	return 0;
1774 }
1775 
1776 /*
1777  * V4L2 controls
1778  */
1779 
s5p_jpeg_g_selection(struct file * file,void * priv,struct v4l2_selection * s)1780 static int s5p_jpeg_g_selection(struct file *file, void *priv,
1781 			 struct v4l2_selection *s)
1782 {
1783 	struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1784 
1785 	if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
1786 	    s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1787 		return -EINVAL;
1788 
1789 	/* For JPEG blob active == default == bounds */
1790 	switch (s->target) {
1791 	case V4L2_SEL_TGT_CROP:
1792 	case V4L2_SEL_TGT_CROP_BOUNDS:
1793 	case V4L2_SEL_TGT_CROP_DEFAULT:
1794 	case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1795 		s->r.width = ctx->out_q.w;
1796 		s->r.height = ctx->out_q.h;
1797 		s->r.left = 0;
1798 		s->r.top = 0;
1799 		break;
1800 	case V4L2_SEL_TGT_COMPOSE:
1801 	case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1802 	case V4L2_SEL_TGT_COMPOSE_PADDED:
1803 		s->r.width = ctx->crop_rect.width;
1804 		s->r.height =  ctx->crop_rect.height;
1805 		s->r.left = ctx->crop_rect.left;
1806 		s->r.top = ctx->crop_rect.top;
1807 		break;
1808 	default:
1809 		return -EINVAL;
1810 	}
1811 	return 0;
1812 }
1813 
1814 /*
1815  * V4L2 controls
1816  */
s5p_jpeg_s_selection(struct file * file,void * fh,struct v4l2_selection * s)1817 static int s5p_jpeg_s_selection(struct file *file, void *fh,
1818 				  struct v4l2_selection *s)
1819 {
1820 	struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
1821 	struct v4l2_rect *rect = &s->r;
1822 	int ret = -EINVAL;
1823 
1824 	if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1825 		return -EINVAL;
1826 
1827 	if (s->target == V4L2_SEL_TGT_COMPOSE) {
1828 		if (ctx->mode != S5P_JPEG_DECODE)
1829 			return -EINVAL;
1830 		if (ctx->jpeg->variant->hw3250_compat)
1831 			ret = exynos3250_jpeg_try_downscale(ctx, rect);
1832 	} else if (s->target == V4L2_SEL_TGT_CROP) {
1833 		if (ctx->mode != S5P_JPEG_ENCODE)
1834 			return -EINVAL;
1835 		if (ctx->jpeg->variant->hw3250_compat)
1836 			ret = exynos3250_jpeg_try_crop(ctx, rect);
1837 	}
1838 
1839 	return ret;
1840 }
1841 
s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl * ctrl)1842 static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1843 {
1844 	struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1845 	struct s5p_jpeg *jpeg = ctx->jpeg;
1846 	unsigned long flags;
1847 
1848 	switch (ctrl->id) {
1849 	case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1850 		spin_lock_irqsave(&jpeg->slock, flags);
1851 		ctrl->val = s5p_jpeg_to_user_subsampling(ctx);
1852 		spin_unlock_irqrestore(&jpeg->slock, flags);
1853 		break;
1854 	}
1855 
1856 	return 0;
1857 }
1858 
s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx * ctx,int * ctrl_val)1859 static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val)
1860 {
1861 	switch (ctx->jpeg->variant->version) {
1862 	case SJPEG_S5P:
1863 		return 0;
1864 	case SJPEG_EXYNOS3250:
1865 	case SJPEG_EXYNOS5420:
1866 		/*
1867 		 * The exynos3250/compatible device can produce JPEG image only
1868 		 * of 4:4:4 subsampling when given RGB32 source image.
1869 		 */
1870 		if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
1871 			*ctrl_val = 0;
1872 		break;
1873 	case SJPEG_EXYNOS4:
1874 		/*
1875 		 * The exynos4x12 device requires input raw image fourcc
1876 		 * to be V4L2_PIX_FMT_GREY if gray jpeg format
1877 		 * is to be set.
1878 		 */
1879 		if (ctx->out_q.fmt->fourcc != V4L2_PIX_FMT_GREY &&
1880 		    *ctrl_val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY)
1881 			return -EINVAL;
1882 		break;
1883 	}
1884 
1885 	/*
1886 	 * The exynos4x12 and exynos3250/compatible devices require resulting
1887 	 * jpeg subsampling not to be lower than the input raw image
1888 	 * subsampling.
1889 	 */
1890 	if (ctx->out_q.fmt->subsampling > *ctrl_val)
1891 		*ctrl_val = ctx->out_q.fmt->subsampling;
1892 
1893 	return 0;
1894 }
1895 
s5p_jpeg_try_ctrl(struct v4l2_ctrl * ctrl)1896 static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl)
1897 {
1898 	struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1899 	unsigned long flags;
1900 	int ret = 0;
1901 
1902 	spin_lock_irqsave(&ctx->jpeg->slock, flags);
1903 
1904 	if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING)
1905 		ret = s5p_jpeg_adjust_subs_ctrl(ctx, &ctrl->val);
1906 
1907 	spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1908 	return ret;
1909 }
1910 
s5p_jpeg_s_ctrl(struct v4l2_ctrl * ctrl)1911 static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
1912 {
1913 	struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1914 	unsigned long flags;
1915 
1916 	spin_lock_irqsave(&ctx->jpeg->slock, flags);
1917 
1918 	switch (ctrl->id) {
1919 	case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1920 		ctx->compr_quality = ctrl->val;
1921 		break;
1922 	case V4L2_CID_JPEG_RESTART_INTERVAL:
1923 		ctx->restart_interval = ctrl->val;
1924 		break;
1925 	case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1926 		ctx->subsampling = ctrl->val;
1927 		break;
1928 	}
1929 
1930 	spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1931 	return 0;
1932 }
1933 
1934 static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
1935 	.g_volatile_ctrl	= s5p_jpeg_g_volatile_ctrl,
1936 	.try_ctrl		= s5p_jpeg_try_ctrl,
1937 	.s_ctrl			= s5p_jpeg_s_ctrl,
1938 };
1939 
s5p_jpeg_controls_create(struct s5p_jpeg_ctx * ctx)1940 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
1941 {
1942 	unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
1943 	struct v4l2_ctrl *ctrl;
1944 	int ret;
1945 
1946 	v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
1947 
1948 	if (ctx->mode == S5P_JPEG_ENCODE) {
1949 		v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1950 				  V4L2_CID_JPEG_COMPRESSION_QUALITY,
1951 				  0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
1952 
1953 		v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1954 				  V4L2_CID_JPEG_RESTART_INTERVAL,
1955 				  0, 0xffff, 1, 0);
1956 		if (ctx->jpeg->variant->version == SJPEG_S5P)
1957 			mask = ~0x06; /* 422, 420 */
1958 	}
1959 
1960 	ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1961 				      V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
1962 				      V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
1963 				      V4L2_JPEG_CHROMA_SUBSAMPLING_422);
1964 
1965 	if (ctx->ctrl_handler.error) {
1966 		ret = ctx->ctrl_handler.error;
1967 		goto error_free;
1968 	}
1969 
1970 	if (ctx->mode == S5P_JPEG_DECODE)
1971 		ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
1972 			V4L2_CTRL_FLAG_READ_ONLY;
1973 
1974 	ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
1975 	if (ret < 0)
1976 		goto error_free;
1977 
1978 	return ret;
1979 
1980 error_free:
1981 	v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1982 	return ret;
1983 }
1984 
1985 static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
1986 	.vidioc_querycap		= s5p_jpeg_querycap,
1987 
1988 	.vidioc_enum_fmt_vid_cap	= s5p_jpeg_enum_fmt_vid_cap,
1989 	.vidioc_enum_fmt_vid_out	= s5p_jpeg_enum_fmt_vid_out,
1990 
1991 	.vidioc_g_fmt_vid_cap		= s5p_jpeg_g_fmt,
1992 	.vidioc_g_fmt_vid_out		= s5p_jpeg_g_fmt,
1993 
1994 	.vidioc_try_fmt_vid_cap		= s5p_jpeg_try_fmt_vid_cap,
1995 	.vidioc_try_fmt_vid_out		= s5p_jpeg_try_fmt_vid_out,
1996 
1997 	.vidioc_s_fmt_vid_cap		= s5p_jpeg_s_fmt_vid_cap,
1998 	.vidioc_s_fmt_vid_out		= s5p_jpeg_s_fmt_vid_out,
1999 
2000 	.vidioc_reqbufs			= v4l2_m2m_ioctl_reqbufs,
2001 	.vidioc_querybuf		= v4l2_m2m_ioctl_querybuf,
2002 	.vidioc_qbuf			= v4l2_m2m_ioctl_qbuf,
2003 	.vidioc_dqbuf			= v4l2_m2m_ioctl_dqbuf,
2004 
2005 	.vidioc_streamon		= v4l2_m2m_ioctl_streamon,
2006 	.vidioc_streamoff		= v4l2_m2m_ioctl_streamoff,
2007 
2008 	.vidioc_g_selection		= s5p_jpeg_g_selection,
2009 	.vidioc_s_selection		= s5p_jpeg_s_selection,
2010 };
2011 
2012 /*
2013  * ============================================================================
2014  * mem2mem callbacks
2015  * ============================================================================
2016  */
2017 
s5p_jpeg_device_run(void * priv)2018 static void s5p_jpeg_device_run(void *priv)
2019 {
2020 	struct s5p_jpeg_ctx *ctx = priv;
2021 	struct s5p_jpeg *jpeg = ctx->jpeg;
2022 	struct vb2_v4l2_buffer *src_buf, *dst_buf;
2023 	unsigned long src_addr, dst_addr, flags;
2024 
2025 	spin_lock_irqsave(&ctx->jpeg->slock, flags);
2026 
2027 	src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2028 	dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2029 	src_addr = vb2_dma_contig_plane_dma_addr(&src_buf->vb2_buf, 0);
2030 	dst_addr = vb2_dma_contig_plane_dma_addr(&dst_buf->vb2_buf, 0);
2031 
2032 	s5p_jpeg_reset(jpeg->regs);
2033 	s5p_jpeg_poweron(jpeg->regs);
2034 	s5p_jpeg_proc_mode(jpeg->regs, ctx->mode);
2035 	if (ctx->mode == S5P_JPEG_ENCODE) {
2036 		if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
2037 			s5p_jpeg_input_raw_mode(jpeg->regs,
2038 							S5P_JPEG_RAW_IN_565);
2039 		else
2040 			s5p_jpeg_input_raw_mode(jpeg->regs,
2041 							S5P_JPEG_RAW_IN_422);
2042 		s5p_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
2043 		s5p_jpeg_dri(jpeg->regs, ctx->restart_interval);
2044 		s5p_jpeg_x(jpeg->regs, ctx->out_q.w);
2045 		s5p_jpeg_y(jpeg->regs, ctx->out_q.h);
2046 		s5p_jpeg_imgadr(jpeg->regs, src_addr);
2047 		s5p_jpeg_jpgadr(jpeg->regs, dst_addr);
2048 
2049 		/* ultimately comes from sizeimage from userspace */
2050 		s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
2051 
2052 		/* JPEG RGB to YCbCr conversion matrix */
2053 		s5p_jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
2054 		s5p_jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
2055 		s5p_jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
2056 		s5p_jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
2057 		s5p_jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
2058 		s5p_jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
2059 		s5p_jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
2060 		s5p_jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
2061 		s5p_jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
2062 
2063 		/*
2064 		 * JPEG IP allows storing 4 quantization tables
2065 		 * We fill table 0 for luma and table 1 for chroma
2066 		 */
2067 		s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2068 		s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2069 		/* use table 0 for Y */
2070 		s5p_jpeg_qtbl(jpeg->regs, 1, 0);
2071 		/* use table 1 for Cb and Cr*/
2072 		s5p_jpeg_qtbl(jpeg->regs, 2, 1);
2073 		s5p_jpeg_qtbl(jpeg->regs, 3, 1);
2074 
2075 		/* Y, Cb, Cr use Huffman table 0 */
2076 		s5p_jpeg_htbl_ac(jpeg->regs, 1);
2077 		s5p_jpeg_htbl_dc(jpeg->regs, 1);
2078 		s5p_jpeg_htbl_ac(jpeg->regs, 2);
2079 		s5p_jpeg_htbl_dc(jpeg->regs, 2);
2080 		s5p_jpeg_htbl_ac(jpeg->regs, 3);
2081 		s5p_jpeg_htbl_dc(jpeg->regs, 3);
2082 	} else { /* S5P_JPEG_DECODE */
2083 		s5p_jpeg_rst_int_enable(jpeg->regs, true);
2084 		s5p_jpeg_data_num_int_enable(jpeg->regs, true);
2085 		s5p_jpeg_final_mcu_num_int_enable(jpeg->regs, true);
2086 		if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
2087 			s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
2088 		else
2089 			s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
2090 		s5p_jpeg_jpgadr(jpeg->regs, src_addr);
2091 		s5p_jpeg_imgadr(jpeg->regs, dst_addr);
2092 	}
2093 
2094 	s5p_jpeg_start(jpeg->regs);
2095 
2096 	spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
2097 }
2098 
exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx * ctx)2099 static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
2100 {
2101 	struct s5p_jpeg *jpeg = ctx->jpeg;
2102 	struct s5p_jpeg_fmt *fmt;
2103 	struct vb2_v4l2_buffer *vb;
2104 	struct s5p_jpeg_addr jpeg_addr = {};
2105 	u32 pix_size, padding_bytes = 0;
2106 
2107 	jpeg_addr.cb = 0;
2108 	jpeg_addr.cr = 0;
2109 
2110 	pix_size = ctx->cap_q.w * ctx->cap_q.h;
2111 
2112 	if (ctx->mode == S5P_JPEG_ENCODE) {
2113 		vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2114 		fmt = ctx->out_q.fmt;
2115 		if (ctx->out_q.w % 2 && fmt->h_align > 0)
2116 			padding_bytes = ctx->out_q.h;
2117 	} else {
2118 		fmt = ctx->cap_q.fmt;
2119 		vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2120 	}
2121 
2122 	jpeg_addr.y = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0);
2123 
2124 	if (fmt->colplanes == 2) {
2125 		jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes;
2126 	} else if (fmt->colplanes == 3) {
2127 		jpeg_addr.cb = jpeg_addr.y + pix_size;
2128 		if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
2129 			jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
2130 		else
2131 			jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
2132 	}
2133 
2134 	exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr);
2135 }
2136 
exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx * ctx)2137 static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
2138 {
2139 	struct s5p_jpeg *jpeg = ctx->jpeg;
2140 	struct vb2_v4l2_buffer *vb;
2141 	unsigned int jpeg_addr = 0;
2142 
2143 	if (ctx->mode == S5P_JPEG_ENCODE)
2144 		vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2145 	else
2146 		vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2147 
2148 	jpeg_addr = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0);
2149 	if (jpeg->variant->version == SJPEG_EXYNOS5433 &&
2150 	    ctx->mode == S5P_JPEG_DECODE)
2151 		jpeg_addr += ctx->out_q.sos;
2152 	exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
2153 }
2154 
exynos4_jpeg_set_img_fmt(void __iomem * base,unsigned int img_fmt)2155 static inline void exynos4_jpeg_set_img_fmt(void __iomem *base,
2156 					    unsigned int img_fmt)
2157 {
2158 	__exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS4);
2159 }
2160 
exynos5433_jpeg_set_img_fmt(void __iomem * base,unsigned int img_fmt)2161 static inline void exynos5433_jpeg_set_img_fmt(void __iomem *base,
2162 					       unsigned int img_fmt)
2163 {
2164 	__exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS5433);
2165 }
2166 
exynos4_jpeg_set_enc_out_fmt(void __iomem * base,unsigned int out_fmt)2167 static inline void exynos4_jpeg_set_enc_out_fmt(void __iomem *base,
2168 						unsigned int out_fmt)
2169 {
2170 	__exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS4);
2171 }
2172 
exynos5433_jpeg_set_enc_out_fmt(void __iomem * base,unsigned int out_fmt)2173 static inline void exynos5433_jpeg_set_enc_out_fmt(void __iomem *base,
2174 						   unsigned int out_fmt)
2175 {
2176 	__exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS5433);
2177 }
2178 
exynos4_jpeg_device_run(void * priv)2179 static void exynos4_jpeg_device_run(void *priv)
2180 {
2181 	struct s5p_jpeg_ctx *ctx = priv;
2182 	struct s5p_jpeg *jpeg = ctx->jpeg;
2183 	unsigned int bitstream_size;
2184 	unsigned long flags;
2185 
2186 	spin_lock_irqsave(&jpeg->slock, flags);
2187 
2188 	if (ctx->mode == S5P_JPEG_ENCODE) {
2189 		exynos4_jpeg_sw_reset(jpeg->regs);
2190 		exynos4_jpeg_set_interrupt(jpeg->regs, jpeg->variant->version);
2191 		exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
2192 
2193 		exynos4_jpeg_set_huff_tbl(jpeg->regs);
2194 
2195 		/*
2196 		 * JPEG IP allows storing 4 quantization tables
2197 		 * We fill table 0 for luma and table 1 for chroma
2198 		 */
2199 		exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2200 		exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2201 
2202 		exynos4_jpeg_set_encode_tbl_select(jpeg->regs,
2203 							ctx->compr_quality);
2204 		exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
2205 							ctx->cap_q.h);
2206 
2207 		if (ctx->jpeg->variant->version == SJPEG_EXYNOS4) {
2208 			exynos4_jpeg_set_enc_out_fmt(jpeg->regs,
2209 						     ctx->subsampling);
2210 			exynos4_jpeg_set_img_fmt(jpeg->regs,
2211 						 ctx->out_q.fmt->fourcc);
2212 		} else {
2213 			exynos5433_jpeg_set_enc_out_fmt(jpeg->regs,
2214 							ctx->subsampling);
2215 			exynos5433_jpeg_set_img_fmt(jpeg->regs,
2216 						    ctx->out_q.fmt->fourcc);
2217 		}
2218 		exynos4_jpeg_set_img_addr(ctx);
2219 		exynos4_jpeg_set_jpeg_addr(ctx);
2220 		exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs,
2221 							ctx->out_q.fmt->fourcc);
2222 	} else {
2223 		exynos4_jpeg_sw_reset(jpeg->regs);
2224 		exynos4_jpeg_set_interrupt(jpeg->regs,
2225 					   jpeg->variant->version);
2226 		exynos4_jpeg_set_img_addr(ctx);
2227 		exynos4_jpeg_set_jpeg_addr(ctx);
2228 
2229 		if (jpeg->variant->version == SJPEG_EXYNOS5433) {
2230 			exynos4_jpeg_parse_huff_tbl(ctx);
2231 			exynos4_jpeg_parse_decode_h_tbl(ctx);
2232 
2233 			exynos4_jpeg_parse_q_tbl(ctx);
2234 			exynos4_jpeg_parse_decode_q_tbl(ctx);
2235 
2236 			exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
2237 
2238 			exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
2239 					ctx->cap_q.h);
2240 			exynos5433_jpeg_set_enc_out_fmt(jpeg->regs,
2241 							ctx->subsampling);
2242 			exynos5433_jpeg_set_img_fmt(jpeg->regs,
2243 						    ctx->cap_q.fmt->fourcc);
2244 			bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 16);
2245 		} else {
2246 			exynos4_jpeg_set_img_fmt(jpeg->regs,
2247 						 ctx->cap_q.fmt->fourcc);
2248 			bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
2249 		}
2250 
2251 		exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
2252 	}
2253 
2254 	exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
2255 
2256 	spin_unlock_irqrestore(&jpeg->slock, flags);
2257 }
2258 
exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx * ctx)2259 static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
2260 {
2261 	struct s5p_jpeg *jpeg = ctx->jpeg;
2262 	struct s5p_jpeg_fmt *fmt;
2263 	struct vb2_v4l2_buffer *vb;
2264 	struct s5p_jpeg_addr jpeg_addr = {};
2265 	u32 pix_size;
2266 
2267 	pix_size = ctx->cap_q.w * ctx->cap_q.h;
2268 
2269 	if (ctx->mode == S5P_JPEG_ENCODE) {
2270 		vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2271 		fmt = ctx->out_q.fmt;
2272 	} else {
2273 		vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2274 		fmt = ctx->cap_q.fmt;
2275 	}
2276 
2277 	jpeg_addr.y = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0);
2278 
2279 	if (fmt->colplanes == 2) {
2280 		jpeg_addr.cb = jpeg_addr.y + pix_size;
2281 	} else if (fmt->colplanes == 3) {
2282 		jpeg_addr.cb = jpeg_addr.y + pix_size;
2283 		if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
2284 			jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
2285 		else
2286 			jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
2287 	}
2288 
2289 	exynos3250_jpeg_imgadr(jpeg->regs, &jpeg_addr);
2290 }
2291 
exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx * ctx)2292 static void exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
2293 {
2294 	struct s5p_jpeg *jpeg = ctx->jpeg;
2295 	struct vb2_v4l2_buffer *vb;
2296 	unsigned int jpeg_addr = 0;
2297 
2298 	if (ctx->mode == S5P_JPEG_ENCODE)
2299 		vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2300 	else
2301 		vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2302 
2303 	jpeg_addr = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0);
2304 	exynos3250_jpeg_jpgadr(jpeg->regs, jpeg_addr);
2305 }
2306 
exynos3250_jpeg_device_run(void * priv)2307 static void exynos3250_jpeg_device_run(void *priv)
2308 {
2309 	struct s5p_jpeg_ctx *ctx = priv;
2310 	struct s5p_jpeg *jpeg = ctx->jpeg;
2311 	unsigned long flags;
2312 
2313 	spin_lock_irqsave(&ctx->jpeg->slock, flags);
2314 
2315 	exynos3250_jpeg_reset(jpeg->regs);
2316 	exynos3250_jpeg_set_dma_num(jpeg->regs);
2317 	exynos3250_jpeg_poweron(jpeg->regs);
2318 	exynos3250_jpeg_clk_set(jpeg->regs);
2319 	exynos3250_jpeg_proc_mode(jpeg->regs, ctx->mode);
2320 
2321 	if (ctx->mode == S5P_JPEG_ENCODE) {
2322 		exynos3250_jpeg_input_raw_fmt(jpeg->regs,
2323 					      ctx->out_q.fmt->fourcc);
2324 		exynos3250_jpeg_dri(jpeg->regs, ctx->restart_interval);
2325 
2326 		/*
2327 		 * JPEG IP allows storing 4 quantization tables
2328 		 * We fill table 0 for luma and table 1 for chroma
2329 		 */
2330 		s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2331 		s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2332 		/* use table 0 for Y */
2333 		exynos3250_jpeg_qtbl(jpeg->regs, 1, 0);
2334 		/* use table 1 for Cb and Cr*/
2335 		exynos3250_jpeg_qtbl(jpeg->regs, 2, 1);
2336 		exynos3250_jpeg_qtbl(jpeg->regs, 3, 1);
2337 
2338 		/*
2339 		 * Some SoCs require setting Huffman tables before each run
2340 		 */
2341 		if (jpeg->variant->htbl_reinit) {
2342 			s5p_jpeg_set_hdctbl(jpeg->regs);
2343 			s5p_jpeg_set_hdctblg(jpeg->regs);
2344 			s5p_jpeg_set_hactbl(jpeg->regs);
2345 			s5p_jpeg_set_hactblg(jpeg->regs);
2346 		}
2347 
2348 		/* Y, Cb, Cr use Huffman table 0 */
2349 		exynos3250_jpeg_htbl_ac(jpeg->regs, 1);
2350 		exynos3250_jpeg_htbl_dc(jpeg->regs, 1);
2351 		exynos3250_jpeg_htbl_ac(jpeg->regs, 2);
2352 		exynos3250_jpeg_htbl_dc(jpeg->regs, 2);
2353 		exynos3250_jpeg_htbl_ac(jpeg->regs, 3);
2354 		exynos3250_jpeg_htbl_dc(jpeg->regs, 3);
2355 
2356 		exynos3250_jpeg_set_x(jpeg->regs, ctx->crop_rect.width);
2357 		exynos3250_jpeg_set_y(jpeg->regs, ctx->crop_rect.height);
2358 		exynos3250_jpeg_stride(jpeg->regs, ctx->out_q.fmt->fourcc,
2359 								ctx->out_q.w);
2360 		exynos3250_jpeg_offset(jpeg->regs, ctx->crop_rect.left,
2361 							ctx->crop_rect.top);
2362 		exynos3250_jpeg_set_img_addr(ctx);
2363 		exynos3250_jpeg_set_jpeg_addr(ctx);
2364 		exynos3250_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
2365 
2366 		/* ultimately comes from sizeimage from userspace */
2367 		exynos3250_jpeg_enc_stream_bound(jpeg->regs, ctx->cap_q.size);
2368 
2369 		if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565 ||
2370 		    ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565X ||
2371 		    ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
2372 			exynos3250_jpeg_set_y16(jpeg->regs, true);
2373 	} else {
2374 		exynos3250_jpeg_set_img_addr(ctx);
2375 		exynos3250_jpeg_set_jpeg_addr(ctx);
2376 		exynos3250_jpeg_stride(jpeg->regs, ctx->cap_q.fmt->fourcc,
2377 								ctx->cap_q.w);
2378 		exynos3250_jpeg_offset(jpeg->regs, 0, 0);
2379 		exynos3250_jpeg_dec_scaling_ratio(jpeg->regs,
2380 							ctx->scale_factor);
2381 		exynos3250_jpeg_dec_stream_size(jpeg->regs, ctx->out_q.size);
2382 		exynos3250_jpeg_output_raw_fmt(jpeg->regs,
2383 						ctx->cap_q.fmt->fourcc);
2384 	}
2385 
2386 	exynos3250_jpeg_interrupts_enable(jpeg->regs);
2387 
2388 	/* JPEG RGB to YCbCr conversion matrix */
2389 	exynos3250_jpeg_coef(jpeg->regs, ctx->mode);
2390 
2391 	exynos3250_jpeg_set_timer(jpeg->regs, EXYNOS3250_IRQ_TIMEOUT);
2392 	jpeg->irq_status = 0;
2393 	exynos3250_jpeg_start(jpeg->regs);
2394 
2395 	spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
2396 }
2397 
s5p_jpeg_job_ready(void * priv)2398 static int s5p_jpeg_job_ready(void *priv)
2399 {
2400 	struct s5p_jpeg_ctx *ctx = priv;
2401 
2402 	if (ctx->mode == S5P_JPEG_DECODE)
2403 		return ctx->hdr_parsed;
2404 	return 1;
2405 }
2406 
s5p_jpeg_job_abort(void * priv)2407 static void s5p_jpeg_job_abort(void *priv)
2408 {
2409 }
2410 
2411 static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
2412 	.device_run	= s5p_jpeg_device_run,
2413 	.job_ready	= s5p_jpeg_job_ready,
2414 	.job_abort	= s5p_jpeg_job_abort,
2415 };
2416 
2417 static struct v4l2_m2m_ops exynos3250_jpeg_m2m_ops = {
2418 	.device_run	= exynos3250_jpeg_device_run,
2419 	.job_ready	= s5p_jpeg_job_ready,
2420 	.job_abort	= s5p_jpeg_job_abort,
2421 };
2422 
2423 static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = {
2424 	.device_run	= exynos4_jpeg_device_run,
2425 	.job_ready	= s5p_jpeg_job_ready,
2426 	.job_abort	= s5p_jpeg_job_abort,
2427 };
2428 
2429 /*
2430  * ============================================================================
2431  * Queue operations
2432  * ============================================================================
2433  */
2434 
s5p_jpeg_queue_setup(struct vb2_queue * vq,const void * parg,unsigned int * nbuffers,unsigned int * nplanes,unsigned int sizes[],void * alloc_ctxs[])2435 static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
2436 			   const void *parg,
2437 			   unsigned int *nbuffers, unsigned int *nplanes,
2438 			   unsigned int sizes[], void *alloc_ctxs[])
2439 {
2440 	struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
2441 	struct s5p_jpeg_q_data *q_data = NULL;
2442 	unsigned int size, count = *nbuffers;
2443 
2444 	q_data = get_q_data(ctx, vq->type);
2445 	BUG_ON(q_data == NULL);
2446 
2447 	size = q_data->size;
2448 
2449 	/*
2450 	 * header is parsed during decoding and parsed information stored
2451 	 * in the context so we do not allow another buffer to overwrite it
2452 	 */
2453 	if (ctx->mode == S5P_JPEG_DECODE)
2454 		count = 1;
2455 
2456 	*nbuffers = count;
2457 	*nplanes = 1;
2458 	sizes[0] = size;
2459 	alloc_ctxs[0] = ctx->jpeg->alloc_ctx;
2460 
2461 	return 0;
2462 }
2463 
s5p_jpeg_buf_prepare(struct vb2_buffer * vb)2464 static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
2465 {
2466 	struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2467 	struct s5p_jpeg_q_data *q_data = NULL;
2468 
2469 	q_data = get_q_data(ctx, vb->vb2_queue->type);
2470 	BUG_ON(q_data == NULL);
2471 
2472 	if (vb2_plane_size(vb, 0) < q_data->size) {
2473 		pr_err("%s data will not fit into plane (%lu < %lu)\n",
2474 				__func__, vb2_plane_size(vb, 0),
2475 				(long)q_data->size);
2476 		return -EINVAL;
2477 	}
2478 
2479 	vb2_set_plane_payload(vb, 0, q_data->size);
2480 
2481 	return 0;
2482 }
2483 
s5p_jpeg_buf_queue(struct vb2_buffer * vb)2484 static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
2485 {
2486 	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
2487 	struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2488 
2489 	if (ctx->mode == S5P_JPEG_DECODE &&
2490 	    vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
2491 		struct s5p_jpeg_q_data tmp, *q_data;
2492 		ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
2493 		     (unsigned long)vb2_plane_vaddr(vb, 0),
2494 		     min((unsigned long)ctx->out_q.size,
2495 			 vb2_get_plane_payload(vb, 0)), ctx);
2496 		if (!ctx->hdr_parsed) {
2497 			vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
2498 			return;
2499 		}
2500 
2501 		q_data = &ctx->out_q;
2502 		q_data->w = tmp.w;
2503 		q_data->h = tmp.h;
2504 		q_data->sos = tmp.sos;
2505 		memcpy(q_data->dht.marker, tmp.dht.marker,
2506 		       sizeof(tmp.dht.marker));
2507 		memcpy(q_data->dht.len, tmp.dht.len, sizeof(tmp.dht.len));
2508 		q_data->dht.n = tmp.dht.n;
2509 		memcpy(q_data->dqt.marker, tmp.dqt.marker,
2510 		       sizeof(tmp.dqt.marker));
2511 		memcpy(q_data->dqt.len, tmp.dqt.len, sizeof(tmp.dqt.len));
2512 		q_data->dqt.n = tmp.dqt.n;
2513 		q_data->sof = tmp.sof;
2514 		q_data->sof_len = tmp.sof_len;
2515 
2516 		q_data = &ctx->cap_q;
2517 		q_data->w = tmp.w;
2518 		q_data->h = tmp.h;
2519 	}
2520 
2521 	v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
2522 }
2523 
s5p_jpeg_start_streaming(struct vb2_queue * q,unsigned int count)2524 static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
2525 {
2526 	struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
2527 	int ret;
2528 
2529 	ret = pm_runtime_get_sync(ctx->jpeg->dev);
2530 
2531 	return ret > 0 ? 0 : ret;
2532 }
2533 
s5p_jpeg_stop_streaming(struct vb2_queue * q)2534 static void s5p_jpeg_stop_streaming(struct vb2_queue *q)
2535 {
2536 	struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
2537 
2538 	pm_runtime_put(ctx->jpeg->dev);
2539 }
2540 
2541 static struct vb2_ops s5p_jpeg_qops = {
2542 	.queue_setup		= s5p_jpeg_queue_setup,
2543 	.buf_prepare		= s5p_jpeg_buf_prepare,
2544 	.buf_queue		= s5p_jpeg_buf_queue,
2545 	.wait_prepare		= vb2_ops_wait_prepare,
2546 	.wait_finish		= vb2_ops_wait_finish,
2547 	.start_streaming	= s5p_jpeg_start_streaming,
2548 	.stop_streaming		= s5p_jpeg_stop_streaming,
2549 };
2550 
queue_init(void * priv,struct vb2_queue * src_vq,struct vb2_queue * dst_vq)2551 static int queue_init(void *priv, struct vb2_queue *src_vq,
2552 		      struct vb2_queue *dst_vq)
2553 {
2554 	struct s5p_jpeg_ctx *ctx = priv;
2555 	int ret;
2556 
2557 	src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2558 	src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
2559 	src_vq->drv_priv = ctx;
2560 	src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2561 	src_vq->ops = &s5p_jpeg_qops;
2562 	src_vq->mem_ops = &vb2_dma_contig_memops;
2563 	src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2564 	src_vq->lock = &ctx->jpeg->lock;
2565 
2566 	ret = vb2_queue_init(src_vq);
2567 	if (ret)
2568 		return ret;
2569 
2570 	dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2571 	dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
2572 	dst_vq->drv_priv = ctx;
2573 	dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2574 	dst_vq->ops = &s5p_jpeg_qops;
2575 	dst_vq->mem_ops = &vb2_dma_contig_memops;
2576 	dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2577 	dst_vq->lock = &ctx->jpeg->lock;
2578 
2579 	return vb2_queue_init(dst_vq);
2580 }
2581 
2582 /*
2583  * ============================================================================
2584  * ISR
2585  * ============================================================================
2586  */
2587 
s5p_jpeg_irq(int irq,void * dev_id)2588 static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
2589 {
2590 	struct s5p_jpeg *jpeg = dev_id;
2591 	struct s5p_jpeg_ctx *curr_ctx;
2592 	struct vb2_v4l2_buffer *src_buf, *dst_buf;
2593 	unsigned long payload_size = 0;
2594 	enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
2595 	bool enc_jpeg_too_large = false;
2596 	bool timer_elapsed = false;
2597 	bool op_completed = false;
2598 
2599 	spin_lock(&jpeg->slock);
2600 
2601 	curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2602 
2603 	src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2604 	dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2605 
2606 	if (curr_ctx->mode == S5P_JPEG_ENCODE)
2607 		enc_jpeg_too_large = s5p_jpeg_enc_stream_stat(jpeg->regs);
2608 	timer_elapsed = s5p_jpeg_timer_stat(jpeg->regs);
2609 	op_completed = s5p_jpeg_result_stat_ok(jpeg->regs);
2610 	if (curr_ctx->mode == S5P_JPEG_DECODE)
2611 		op_completed = op_completed &&
2612 					s5p_jpeg_stream_stat_ok(jpeg->regs);
2613 
2614 	if (enc_jpeg_too_large) {
2615 		state = VB2_BUF_STATE_ERROR;
2616 		s5p_jpeg_clear_enc_stream_stat(jpeg->regs);
2617 	} else if (timer_elapsed) {
2618 		state = VB2_BUF_STATE_ERROR;
2619 		s5p_jpeg_clear_timer_stat(jpeg->regs);
2620 	} else if (!op_completed) {
2621 		state = VB2_BUF_STATE_ERROR;
2622 	} else {
2623 		payload_size = s5p_jpeg_compressed_size(jpeg->regs);
2624 	}
2625 
2626 	dst_buf->timecode = src_buf->timecode;
2627 	dst_buf->timestamp = src_buf->timestamp;
2628 	dst_buf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
2629 	dst_buf->flags |=
2630 		src_buf->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
2631 
2632 	v4l2_m2m_buf_done(src_buf, state);
2633 	if (curr_ctx->mode == S5P_JPEG_ENCODE)
2634 		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size);
2635 	v4l2_m2m_buf_done(dst_buf, state);
2636 	v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2637 
2638 	curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs);
2639 	spin_unlock(&jpeg->slock);
2640 
2641 	s5p_jpeg_clear_int(jpeg->regs);
2642 
2643 	return IRQ_HANDLED;
2644 }
2645 
exynos4_jpeg_irq(int irq,void * priv)2646 static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
2647 {
2648 	unsigned int int_status;
2649 	struct vb2_v4l2_buffer *src_vb, *dst_vb;
2650 	struct s5p_jpeg *jpeg = priv;
2651 	struct s5p_jpeg_ctx *curr_ctx;
2652 	unsigned long payload_size = 0;
2653 
2654 	spin_lock(&jpeg->slock);
2655 
2656 	curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2657 
2658 	src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2659 	dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2660 
2661 	int_status = exynos4_jpeg_get_int_status(jpeg->regs);
2662 
2663 	if (int_status) {
2664 		switch (int_status & 0x1f) {
2665 		case 0x1:
2666 			jpeg->irq_ret = ERR_PROT;
2667 			break;
2668 		case 0x2:
2669 			jpeg->irq_ret = OK_ENC_OR_DEC;
2670 			break;
2671 		case 0x4:
2672 			jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
2673 			break;
2674 		case 0x8:
2675 			jpeg->irq_ret = ERR_MULTI_SCAN;
2676 			break;
2677 		case 0x10:
2678 			jpeg->irq_ret = ERR_FRAME;
2679 			break;
2680 		default:
2681 			jpeg->irq_ret = ERR_UNKNOWN;
2682 			break;
2683 		}
2684 	} else {
2685 		jpeg->irq_ret = ERR_UNKNOWN;
2686 	}
2687 
2688 	if (jpeg->irq_ret == OK_ENC_OR_DEC) {
2689 		if (curr_ctx->mode == S5P_JPEG_ENCODE) {
2690 			payload_size = exynos4_jpeg_get_stream_size(jpeg->regs);
2691 			vb2_set_plane_payload(&dst_vb->vb2_buf,
2692 					0, payload_size);
2693 		}
2694 		v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
2695 		v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
2696 	} else {
2697 		v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
2698 		v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
2699 	}
2700 
2701 	v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2702 	if (jpeg->variant->version == SJPEG_EXYNOS4)
2703 		curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
2704 
2705 	spin_unlock(&jpeg->slock);
2706 	return IRQ_HANDLED;
2707 }
2708 
exynos3250_jpeg_irq(int irq,void * dev_id)2709 static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id)
2710 {
2711 	struct s5p_jpeg *jpeg = dev_id;
2712 	struct s5p_jpeg_ctx *curr_ctx;
2713 	struct vb2_v4l2_buffer *src_buf, *dst_buf;
2714 	unsigned long payload_size = 0;
2715 	enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
2716 	bool interrupt_timeout = false;
2717 	u32 irq_status;
2718 
2719 	spin_lock(&jpeg->slock);
2720 
2721 	irq_status = exynos3250_jpeg_get_timer_status(jpeg->regs);
2722 	if (irq_status & EXYNOS3250_TIMER_INT_STAT) {
2723 		exynos3250_jpeg_clear_timer_status(jpeg->regs);
2724 		interrupt_timeout = true;
2725 		dev_err(jpeg->dev, "Interrupt timeout occurred.\n");
2726 	}
2727 
2728 	irq_status = exynos3250_jpeg_get_int_status(jpeg->regs);
2729 	exynos3250_jpeg_clear_int_status(jpeg->regs, irq_status);
2730 
2731 	jpeg->irq_status |= irq_status;
2732 
2733 	curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2734 
2735 	if (!curr_ctx)
2736 		goto exit_unlock;
2737 
2738 	if ((irq_status & EXYNOS3250_HEADER_STAT) &&
2739 	    (curr_ctx->mode == S5P_JPEG_DECODE)) {
2740 		exynos3250_jpeg_rstart(jpeg->regs);
2741 		goto exit_unlock;
2742 	}
2743 
2744 	if (jpeg->irq_status & (EXYNOS3250_JPEG_DONE |
2745 				EXYNOS3250_WDMA_DONE |
2746 				EXYNOS3250_RDMA_DONE |
2747 				EXYNOS3250_RESULT_STAT))
2748 		payload_size = exynos3250_jpeg_compressed_size(jpeg->regs);
2749 	else if (interrupt_timeout)
2750 		state = VB2_BUF_STATE_ERROR;
2751 	else
2752 		goto exit_unlock;
2753 
2754 	src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2755 	dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2756 
2757 	dst_buf->timecode = src_buf->timecode;
2758 	dst_buf->timestamp = src_buf->timestamp;
2759 
2760 	v4l2_m2m_buf_done(src_buf, state);
2761 	if (curr_ctx->mode == S5P_JPEG_ENCODE)
2762 		vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size);
2763 	v4l2_m2m_buf_done(dst_buf, state);
2764 	v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2765 
2766 	curr_ctx->subsampling =
2767 			exynos3250_jpeg_get_subsampling_mode(jpeg->regs);
2768 exit_unlock:
2769 	spin_unlock(&jpeg->slock);
2770 	return IRQ_HANDLED;
2771 }
2772 
2773 static void *jpeg_get_drv_data(struct device *dev);
2774 
2775 /*
2776  * ============================================================================
2777  * Driver basic infrastructure
2778  * ============================================================================
2779  */
2780 
s5p_jpeg_probe(struct platform_device * pdev)2781 static int s5p_jpeg_probe(struct platform_device *pdev)
2782 {
2783 	struct s5p_jpeg *jpeg;
2784 	struct resource *res;
2785 	int i, ret;
2786 
2787 	/* JPEG IP abstraction struct */
2788 	jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
2789 	if (!jpeg)
2790 		return -ENOMEM;
2791 
2792 	jpeg->variant = jpeg_get_drv_data(&pdev->dev);
2793 
2794 	mutex_init(&jpeg->lock);
2795 	spin_lock_init(&jpeg->slock);
2796 	jpeg->dev = &pdev->dev;
2797 
2798 	/* memory-mapped registers */
2799 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2800 
2801 	jpeg->regs = devm_ioremap_resource(&pdev->dev, res);
2802 	if (IS_ERR(jpeg->regs))
2803 		return PTR_ERR(jpeg->regs);
2804 
2805 	/* interrupt service routine registration */
2806 	jpeg->irq = ret = platform_get_irq(pdev, 0);
2807 	if (ret < 0) {
2808 		dev_err(&pdev->dev, "cannot find IRQ\n");
2809 		return ret;
2810 	}
2811 
2812 	ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
2813 				0, dev_name(&pdev->dev), jpeg);
2814 	if (ret) {
2815 		dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
2816 		return ret;
2817 	}
2818 
2819 	/* clocks */
2820 	for (i = 0; i < jpeg->variant->num_clocks; i++) {
2821 		jpeg->clocks[i] = devm_clk_get(&pdev->dev,
2822 					      jpeg->variant->clk_names[i]);
2823 		if (IS_ERR(jpeg->clocks[i])) {
2824 			dev_err(&pdev->dev, "failed to get clock: %s\n",
2825 				jpeg->variant->clk_names[i]);
2826 			return PTR_ERR(jpeg->clocks[i]);
2827 		}
2828 	}
2829 
2830 	/* v4l2 device */
2831 	ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
2832 	if (ret) {
2833 		dev_err(&pdev->dev, "Failed to register v4l2 device\n");
2834 		return ret;
2835 	}
2836 
2837 	/* mem2mem device */
2838 	jpeg->m2m_dev = v4l2_m2m_init(jpeg->variant->m2m_ops);
2839 	if (IS_ERR(jpeg->m2m_dev)) {
2840 		v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
2841 		ret = PTR_ERR(jpeg->m2m_dev);
2842 		goto device_register_rollback;
2843 	}
2844 
2845 	jpeg->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
2846 	if (IS_ERR(jpeg->alloc_ctx)) {
2847 		v4l2_err(&jpeg->v4l2_dev, "Failed to init memory allocator\n");
2848 		ret = PTR_ERR(jpeg->alloc_ctx);
2849 		goto m2m_init_rollback;
2850 	}
2851 
2852 	/* JPEG encoder /dev/videoX node */
2853 	jpeg->vfd_encoder = video_device_alloc();
2854 	if (!jpeg->vfd_encoder) {
2855 		v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
2856 		ret = -ENOMEM;
2857 		goto vb2_allocator_rollback;
2858 	}
2859 	snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name),
2860 				"%s-enc", S5P_JPEG_M2M_NAME);
2861 	jpeg->vfd_encoder->fops		= &s5p_jpeg_fops;
2862 	jpeg->vfd_encoder->ioctl_ops	= &s5p_jpeg_ioctl_ops;
2863 	jpeg->vfd_encoder->minor	= -1;
2864 	jpeg->vfd_encoder->release	= video_device_release;
2865 	jpeg->vfd_encoder->lock		= &jpeg->lock;
2866 	jpeg->vfd_encoder->v4l2_dev	= &jpeg->v4l2_dev;
2867 	jpeg->vfd_encoder->vfl_dir	= VFL_DIR_M2M;
2868 
2869 	ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
2870 	if (ret) {
2871 		v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
2872 		video_device_release(jpeg->vfd_encoder);
2873 		goto vb2_allocator_rollback;
2874 	}
2875 
2876 	video_set_drvdata(jpeg->vfd_encoder, jpeg);
2877 	v4l2_info(&jpeg->v4l2_dev,
2878 		  "encoder device registered as /dev/video%d\n",
2879 		  jpeg->vfd_encoder->num);
2880 
2881 	/* JPEG decoder /dev/videoX node */
2882 	jpeg->vfd_decoder = video_device_alloc();
2883 	if (!jpeg->vfd_decoder) {
2884 		v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
2885 		ret = -ENOMEM;
2886 		goto enc_vdev_register_rollback;
2887 	}
2888 	snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name),
2889 				"%s-dec", S5P_JPEG_M2M_NAME);
2890 	jpeg->vfd_decoder->fops		= &s5p_jpeg_fops;
2891 	jpeg->vfd_decoder->ioctl_ops	= &s5p_jpeg_ioctl_ops;
2892 	jpeg->vfd_decoder->minor	= -1;
2893 	jpeg->vfd_decoder->release	= video_device_release;
2894 	jpeg->vfd_decoder->lock		= &jpeg->lock;
2895 	jpeg->vfd_decoder->v4l2_dev	= &jpeg->v4l2_dev;
2896 	jpeg->vfd_decoder->vfl_dir	= VFL_DIR_M2M;
2897 
2898 	ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
2899 	if (ret) {
2900 		v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
2901 		video_device_release(jpeg->vfd_decoder);
2902 		goto enc_vdev_register_rollback;
2903 	}
2904 
2905 	video_set_drvdata(jpeg->vfd_decoder, jpeg);
2906 	v4l2_info(&jpeg->v4l2_dev,
2907 		  "decoder device registered as /dev/video%d\n",
2908 		  jpeg->vfd_decoder->num);
2909 
2910 	/* final statements & power management */
2911 	platform_set_drvdata(pdev, jpeg);
2912 
2913 	pm_runtime_enable(&pdev->dev);
2914 
2915 	v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
2916 
2917 	return 0;
2918 
2919 enc_vdev_register_rollback:
2920 	video_unregister_device(jpeg->vfd_encoder);
2921 
2922 vb2_allocator_rollback:
2923 	vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
2924 
2925 m2m_init_rollback:
2926 	v4l2_m2m_release(jpeg->m2m_dev);
2927 
2928 device_register_rollback:
2929 	v4l2_device_unregister(&jpeg->v4l2_dev);
2930 
2931 	return ret;
2932 }
2933 
s5p_jpeg_remove(struct platform_device * pdev)2934 static int s5p_jpeg_remove(struct platform_device *pdev)
2935 {
2936 	struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
2937 	int i;
2938 
2939 	pm_runtime_disable(jpeg->dev);
2940 
2941 	video_unregister_device(jpeg->vfd_decoder);
2942 	video_unregister_device(jpeg->vfd_encoder);
2943 	vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
2944 	v4l2_m2m_release(jpeg->m2m_dev);
2945 	v4l2_device_unregister(&jpeg->v4l2_dev);
2946 
2947 	if (!pm_runtime_status_suspended(&pdev->dev)) {
2948 		for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
2949 			clk_disable_unprepare(jpeg->clocks[i]);
2950 	}
2951 
2952 	return 0;
2953 }
2954 
2955 #ifdef CONFIG_PM
s5p_jpeg_runtime_suspend(struct device * dev)2956 static int s5p_jpeg_runtime_suspend(struct device *dev)
2957 {
2958 	struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2959 	int i;
2960 
2961 	for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
2962 		clk_disable_unprepare(jpeg->clocks[i]);
2963 
2964 	return 0;
2965 }
2966 
s5p_jpeg_runtime_resume(struct device * dev)2967 static int s5p_jpeg_runtime_resume(struct device *dev)
2968 {
2969 	struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2970 	unsigned long flags;
2971 	int i, ret;
2972 
2973 	for (i = 0; i < jpeg->variant->num_clocks; i++) {
2974 		ret = clk_prepare_enable(jpeg->clocks[i]);
2975 		if (ret) {
2976 			while (--i > 0)
2977 				clk_disable_unprepare(jpeg->clocks[i]);
2978 			return ret;
2979 		}
2980 	}
2981 
2982 	spin_lock_irqsave(&jpeg->slock, flags);
2983 
2984 	/*
2985 	 * JPEG IP allows storing two Huffman tables for each component.
2986 	 * We fill table 0 for each component and do this here only
2987 	 * for S5PC210 and Exynos3250 SoCs. Exynos4x12 and Exynos542x SoC
2988 	 * require programming their Huffman tables each time the encoding
2989 	 * process is initialized, and thus it is accomplished in the
2990 	 * device_run callback of m2m_ops.
2991 	 */
2992 	if (!jpeg->variant->htbl_reinit) {
2993 		s5p_jpeg_set_hdctbl(jpeg->regs);
2994 		s5p_jpeg_set_hdctblg(jpeg->regs);
2995 		s5p_jpeg_set_hactbl(jpeg->regs);
2996 		s5p_jpeg_set_hactblg(jpeg->regs);
2997 	}
2998 
2999 	spin_unlock_irqrestore(&jpeg->slock, flags);
3000 
3001 	return 0;
3002 }
3003 #endif /* CONFIG_PM */
3004 
3005 #ifdef CONFIG_PM_SLEEP
s5p_jpeg_suspend(struct device * dev)3006 static int s5p_jpeg_suspend(struct device *dev)
3007 {
3008 	if (pm_runtime_suspended(dev))
3009 		return 0;
3010 
3011 	return s5p_jpeg_runtime_suspend(dev);
3012 }
3013 
s5p_jpeg_resume(struct device * dev)3014 static int s5p_jpeg_resume(struct device *dev)
3015 {
3016 	if (pm_runtime_suspended(dev))
3017 		return 0;
3018 
3019 	return s5p_jpeg_runtime_resume(dev);
3020 }
3021 #endif
3022 
3023 static const struct dev_pm_ops s5p_jpeg_pm_ops = {
3024 	SET_SYSTEM_SLEEP_PM_OPS(s5p_jpeg_suspend, s5p_jpeg_resume)
3025 	SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume, NULL)
3026 };
3027 
3028 static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
3029 	.version	= SJPEG_S5P,
3030 	.jpeg_irq	= s5p_jpeg_irq,
3031 	.m2m_ops	= &s5p_jpeg_m2m_ops,
3032 	.fmt_ver_flag	= SJPEG_FMT_FLAG_S5P,
3033 	.clk_names	= {"jpeg"},
3034 	.num_clocks	= 1,
3035 };
3036 
3037 static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = {
3038 	.version	= SJPEG_EXYNOS3250,
3039 	.jpeg_irq	= exynos3250_jpeg_irq,
3040 	.m2m_ops	= &exynos3250_jpeg_m2m_ops,
3041 	.fmt_ver_flag	= SJPEG_FMT_FLAG_EXYNOS3250,
3042 	.hw3250_compat	= 1,
3043 	.clk_names	= {"jpeg", "sclk"},
3044 	.num_clocks	= 2,
3045 };
3046 
3047 static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
3048 	.version	= SJPEG_EXYNOS4,
3049 	.jpeg_irq	= exynos4_jpeg_irq,
3050 	.m2m_ops	= &exynos4_jpeg_m2m_ops,
3051 	.fmt_ver_flag	= SJPEG_FMT_FLAG_EXYNOS4,
3052 	.htbl_reinit	= 1,
3053 	.clk_names	= {"jpeg"},
3054 	.num_clocks	= 1,
3055 	.hw_ex4_compat	= 1,
3056 };
3057 
3058 static struct s5p_jpeg_variant exynos5420_jpeg_drvdata = {
3059 	.version	= SJPEG_EXYNOS5420,
3060 	.jpeg_irq	= exynos3250_jpeg_irq,		/* intentionally 3250 */
3061 	.m2m_ops	= &exynos3250_jpeg_m2m_ops,	/* intentionally 3250 */
3062 	.fmt_ver_flag	= SJPEG_FMT_FLAG_EXYNOS3250,	/* intentionally 3250 */
3063 	.hw3250_compat	= 1,
3064 	.htbl_reinit	= 1,
3065 	.clk_names	= {"jpeg"},
3066 	.num_clocks	= 1,
3067 };
3068 
3069 static struct s5p_jpeg_variant exynos5433_jpeg_drvdata = {
3070 	.version	= SJPEG_EXYNOS5433,
3071 	.jpeg_irq	= exynos4_jpeg_irq,
3072 	.m2m_ops	= &exynos4_jpeg_m2m_ops,
3073 	.fmt_ver_flag	= SJPEG_FMT_FLAG_EXYNOS4,
3074 	.htbl_reinit	= 1,
3075 	.clk_names	= {"pclk", "aclk", "aclk_xiu", "sclk"},
3076 	.num_clocks	= 4,
3077 	.hw_ex4_compat	= 1,
3078 };
3079 
3080 static const struct of_device_id samsung_jpeg_match[] = {
3081 	{
3082 		.compatible = "samsung,s5pv210-jpeg",
3083 		.data = &s5p_jpeg_drvdata,
3084 	}, {
3085 		.compatible = "samsung,exynos3250-jpeg",
3086 		.data = &exynos3250_jpeg_drvdata,
3087 	}, {
3088 		.compatible = "samsung,exynos4210-jpeg",
3089 		.data = &exynos4_jpeg_drvdata,
3090 	}, {
3091 		.compatible = "samsung,exynos4212-jpeg",
3092 		.data = &exynos4_jpeg_drvdata,
3093 	}, {
3094 		.compatible = "samsung,exynos5420-jpeg",
3095 		.data = &exynos5420_jpeg_drvdata,
3096 	}, {
3097 		.compatible = "samsung,exynos5433-jpeg",
3098 		.data = &exynos5433_jpeg_drvdata,
3099 	},
3100 	{},
3101 };
3102 
3103 MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
3104 
jpeg_get_drv_data(struct device * dev)3105 static void *jpeg_get_drv_data(struct device *dev)
3106 {
3107 	struct s5p_jpeg_variant *driver_data = NULL;
3108 	const struct of_device_id *match;
3109 
3110 	if (!IS_ENABLED(CONFIG_OF) || !dev->of_node)
3111 		return &s5p_jpeg_drvdata;
3112 
3113 	match = of_match_node(samsung_jpeg_match, dev->of_node);
3114 
3115 	if (match)
3116 		driver_data = (struct s5p_jpeg_variant *)match->data;
3117 
3118 	return driver_data;
3119 }
3120 
3121 static struct platform_driver s5p_jpeg_driver = {
3122 	.probe = s5p_jpeg_probe,
3123 	.remove = s5p_jpeg_remove,
3124 	.driver = {
3125 		.of_match_table	= of_match_ptr(samsung_jpeg_match),
3126 		.name		= S5P_JPEG_M2M_NAME,
3127 		.pm		= &s5p_jpeg_pm_ops,
3128 	},
3129 };
3130 
3131 module_platform_driver(s5p_jpeg_driver);
3132 
3133 MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
3134 MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
3135 MODULE_DESCRIPTION("Samsung JPEG codec driver");
3136 MODULE_LICENSE("GPL");
3137