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