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