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