Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi...
[deliverable/linux.git] / drivers / media / platform / s5p-jpeg / jpeg-core.c
CommitLineData
2c3fb08b 1/* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c
bb677f3a 2 *
3246fdaa 3 * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
bb677f3a
AP
4 * http://www.samsung.com
5 *
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
80529ae5 7 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
bb677f3a
AP
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>
f7074ab3 21#include <linux/of.h>
bb677f3a
AP
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>
c139990e 29#include <media/videobuf2-v4l2.h>
bb677f3a
AP
30#include <media/videobuf2-dma-contig.h>
31
32#include "jpeg-core.h"
9f7b62d9 33#include "jpeg-hw-s5p.h"
80529ae5 34#include "jpeg-hw-exynos4.h"
3246fdaa 35#include "jpeg-hw-exynos3250.h"
80529ae5 36#include "jpeg-regs.h"
bb677f3a 37
80529ae5 38static struct s5p_jpeg_fmt sjpeg_formats[] = {
bb677f3a 39 {
fb6f8c02
AP
40 .name = "JPEG JFIF",
41 .fourcc = V4L2_PIX_FMT_JPEG,
80529ae5
JA
42 .flags = SJPEG_FMT_FLAG_ENC_CAPTURE |
43 SJPEG_FMT_FLAG_DEC_OUTPUT |
44 SJPEG_FMT_FLAG_S5P |
3246fdaa 45 SJPEG_FMT_FLAG_EXYNOS3250 |
80529ae5
JA
46 SJPEG_FMT_FLAG_EXYNOS4,
47 },
48 {
49 .name = "YUV 4:2:2 packed, YCbYCr",
50 .fourcc = V4L2_PIX_FMT_YUYV,
51 .depth = 16,
fb6f8c02 52 .colplanes = 1,
80529ae5
JA
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,
bb677f3a
AP
60 },
61 {
62 .name = "YUV 4:2:2 packed, YCbYCr",
63 .fourcc = V4L2_PIX_FMT_YUYV,
64 .depth = 16,
65 .colplanes = 1,
80529ae5
JA
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 },
3246fdaa
JA
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 },
80529ae5
JA
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,
bb677f3a 99 },
3246fdaa
JA
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 },
bb677f3a
AP
139 {
140 .name = "RGB565",
141 .fourcc = V4L2_PIX_FMT_RGB565,
142 .depth = 16,
143 .colplanes = 1,
80529ae5
JA
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 },
3246fdaa
JA
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 },
80529ae5
JA
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 },
3246fdaa
JA
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 },
80529ae5
JA
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,
bb677f3a 254 },
bb677f3a 255 {
80529ae5
JA
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",
c97ba28b 270 .fourcc = V4L2_PIX_FMT_NV12,
a62cffef 271 .depth = 12,
80529ae5
JA
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,
bb677f3a 280 },
3246fdaa
JA
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 },
bb677f3a 294 {
80529ae5
JA
295 .name = "YUV 4:2:0 planar, Y/CbCr",
296 .fourcc = V4L2_PIX_FMT_NV12,
a62cffef
JA
297 .depth = 12,
298 .colplanes = 2,
bb677f3a 299 .h_align = 4,
a62cffef 300 .v_align = 4,
3246fdaa
JA
301 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
302 SJPEG_FMT_FLAG_DEC_CAPTURE |
80529ae5
JA
303 SJPEG_FMT_FLAG_S5P |
304 SJPEG_FMT_NON_RGB,
305 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
bb677f3a 306 },
3246fdaa
JA
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 },
bb677f3a 320 {
80529ae5
JA
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 |
3246fdaa 329 SJPEG_FMT_FLAG_EXYNOS3250 |
80529ae5
JA
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 },
3246fdaa
JA
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 },
80529ae5
JA
360 {
361 .name = "Gray",
362 .fourcc = V4L2_PIX_FMT_GREY,
363 .depth = 8,
bb677f3a 364 .colplanes = 1,
80529ae5
JA
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,
bb677f3a
AP
370 },
371};
80529ae5 372#define SJPEG_NUM_FORMATS ARRAY_SIZE(sjpeg_formats)
bb677f3a
AP
373
374static const unsigned char qtbl_luminance[4][64] = {
78e5a3ce
JA
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
bb677f3a
AP
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 },
78e5a3ce
JA
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
bb677f3a
AP
414 }
415};
416
417static const unsigned char qtbl_chrominance[4][64] = {
78e5a3ce
JA
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
bb677f3a
AP
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 },
78e5a3ce
JA
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
bb677f3a
AP
457 }
458};
459
460static const unsigned char hdctbl0[16] = {
461 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
462};
463
464static const unsigned char hdctblg0[12] = {
465 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
466};
467static const unsigned char hactbl0[16] = {
468 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
469};
470static const unsigned char hactblg0[162] = {
471 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
472 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
473 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
474 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
475 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
476 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
477 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
478 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
479 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
480 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
481 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
482 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
483 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
484 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
485 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
486 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
487 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
488 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
489 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
490 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
491 0xf9, 0xfa
492};
493
337777a4
JA
494/*
495 * Fourcc downgrade schema lookup tables for 422 and 420
496 * chroma subsampling - fourcc on each position maps on the
497 * fourcc from the table fourcc_to_dwngrd_schema_id which allows
498 * to get the most suitable fourcc counterpart for the given
499 * downgraded subsampling property.
500 */
501static const u32 subs422_fourcc_dwngrd_schema[] = {
502 V4L2_PIX_FMT_NV16,
503 V4L2_PIX_FMT_NV61,
504};
505
506static const u32 subs420_fourcc_dwngrd_schema[] = {
507 V4L2_PIX_FMT_NV12,
508 V4L2_PIX_FMT_NV21,
509 V4L2_PIX_FMT_NV12,
510 V4L2_PIX_FMT_NV21,
511 V4L2_PIX_FMT_NV12,
512 V4L2_PIX_FMT_NV21,
513 V4L2_PIX_FMT_GREY,
514 V4L2_PIX_FMT_GREY,
515 V4L2_PIX_FMT_GREY,
516 V4L2_PIX_FMT_GREY,
517};
518
519/*
520 * Lookup table for translation of a fourcc to the position
521 * of its downgraded counterpart in the *fourcc_dwngrd_schema
522 * tables.
523 */
524static const u32 fourcc_to_dwngrd_schema_id[] = {
525 V4L2_PIX_FMT_NV24,
526 V4L2_PIX_FMT_NV42,
527 V4L2_PIX_FMT_NV16,
528 V4L2_PIX_FMT_NV61,
529 V4L2_PIX_FMT_YUYV,
530 V4L2_PIX_FMT_YVYU,
531 V4L2_PIX_FMT_NV12,
532 V4L2_PIX_FMT_NV21,
533 V4L2_PIX_FMT_YUV420,
534 V4L2_PIX_FMT_GREY,
535};
536
537static int s5p_jpeg_get_dwngrd_sch_id_by_fourcc(u32 fourcc)
538{
539 int i;
540 for (i = 0; i < ARRAY_SIZE(fourcc_to_dwngrd_schema_id); ++i) {
541 if (fourcc_to_dwngrd_schema_id[i] == fourcc)
542 return i;
543 }
544
545 return -EINVAL;
546}
547
548static int s5p_jpeg_adjust_fourcc_to_subsampling(
549 enum v4l2_jpeg_chroma_subsampling subs,
550 u32 in_fourcc,
551 u32 *out_fourcc,
552 struct s5p_jpeg_ctx *ctx)
553{
554 int dwngrd_sch_id;
555
556 if (ctx->subsampling != V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
557 dwngrd_sch_id =
558 s5p_jpeg_get_dwngrd_sch_id_by_fourcc(in_fourcc);
559 if (dwngrd_sch_id < 0)
560 return -EINVAL;
561 }
562
563 switch (ctx->subsampling) {
564 case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
565 *out_fourcc = V4L2_PIX_FMT_GREY;
566 break;
567 case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
568 if (dwngrd_sch_id >
569 ARRAY_SIZE(subs420_fourcc_dwngrd_schema) - 1)
570 return -EINVAL;
571 *out_fourcc = subs420_fourcc_dwngrd_schema[dwngrd_sch_id];
572 break;
573 case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
574 if (dwngrd_sch_id >
575 ARRAY_SIZE(subs422_fourcc_dwngrd_schema) - 1)
576 return -EINVAL;
577 *out_fourcc = subs422_fourcc_dwngrd_schema[dwngrd_sch_id];
578 break;
579 default:
580 *out_fourcc = V4L2_PIX_FMT_GREY;
581 break;
582 }
583
584 return 0;
585}
586
303b0a96
JA
587static int exynos4x12_decoded_subsampling[] = {
588 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
589 V4L2_JPEG_CHROMA_SUBSAMPLING_444,
590 V4L2_JPEG_CHROMA_SUBSAMPLING_422,
591 V4L2_JPEG_CHROMA_SUBSAMPLING_420,
592};
593
3246fdaa
JA
594static int exynos3250_decoded_subsampling[] = {
595 V4L2_JPEG_CHROMA_SUBSAMPLING_444,
596 V4L2_JPEG_CHROMA_SUBSAMPLING_422,
597 V4L2_JPEG_CHROMA_SUBSAMPLING_420,
598 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
599 -1,
600 -1,
601 V4L2_JPEG_CHROMA_SUBSAMPLING_411,
602};
603
15f4bc3b
SN
604static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
605{
606 return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
607}
608
275de24d
SN
609static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
610{
611 return container_of(fh, struct s5p_jpeg_ctx, fh);
612}
613
303b0a96
JA
614static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
615{
616 WARN_ON(ctx->subsampling > 3);
617
3246fdaa
JA
618 switch (ctx->jpeg->variant->version) {
619 case SJPEG_S5P:
303b0a96
JA
620 if (ctx->subsampling > 2)
621 return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
622 return ctx->subsampling;
3246fdaa 623 case SJPEG_EXYNOS3250:
7c15fd4b 624 case SJPEG_EXYNOS5420:
3246fdaa
JA
625 if (ctx->subsampling > 3)
626 return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
627 return exynos3250_decoded_subsampling[ctx->subsampling];
628 case SJPEG_EXYNOS4:
6c96dbbc 629 case SJPEG_EXYNOS5433:
303b0a96
JA
630 if (ctx->subsampling > 2)
631 return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
632 return exynos4x12_decoded_subsampling[ctx->subsampling];
3246fdaa
JA
633 default:
634 return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
303b0a96
JA
635 }
636}
637
31dc0ac0
JA
638static inline void s5p_jpeg_set_qtbl(void __iomem *regs,
639 const unsigned char *qtbl,
640 unsigned long tab, int len)
bb677f3a
AP
641{
642 int i;
643
644 for (i = 0; i < len; i++)
645 writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
646}
647
31dc0ac0 648static inline void s5p_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
bb677f3a
AP
649{
650 /* this driver fills quantisation table 0 with data for luma */
31dc0ac0
JA
651 s5p_jpeg_set_qtbl(regs, qtbl_luminance[quality],
652 S5P_JPG_QTBL_CONTENT(0),
653 ARRAY_SIZE(qtbl_luminance[quality]));
bb677f3a
AP
654}
655
31dc0ac0 656static inline void s5p_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
bb677f3a
AP
657{
658 /* this driver fills quantisation table 1 with data for chroma */
31dc0ac0
JA
659 s5p_jpeg_set_qtbl(regs, qtbl_chrominance[quality],
660 S5P_JPG_QTBL_CONTENT(1),
661 ARRAY_SIZE(qtbl_chrominance[quality]));
bb677f3a
AP
662}
663
31dc0ac0
JA
664static inline void s5p_jpeg_set_htbl(void __iomem *regs,
665 const unsigned char *htbl,
666 unsigned long tab, int len)
bb677f3a
AP
667{
668 int i;
669
670 for (i = 0; i < len; i++)
671 writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
672}
673
31dc0ac0 674static inline void s5p_jpeg_set_hdctbl(void __iomem *regs)
bb677f3a
AP
675{
676 /* this driver fills table 0 for this component */
31dc0ac0
JA
677 s5p_jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0),
678 ARRAY_SIZE(hdctbl0));
bb677f3a
AP
679}
680
31dc0ac0 681static inline void s5p_jpeg_set_hdctblg(void __iomem *regs)
bb677f3a
AP
682{
683 /* this driver fills table 0 for this component */
31dc0ac0
JA
684 s5p_jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0),
685 ARRAY_SIZE(hdctblg0));
bb677f3a
AP
686}
687
31dc0ac0 688static inline void s5p_jpeg_set_hactbl(void __iomem *regs)
bb677f3a
AP
689{
690 /* this driver fills table 0 for this component */
31dc0ac0
JA
691 s5p_jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0),
692 ARRAY_SIZE(hactbl0));
bb677f3a
AP
693}
694
31dc0ac0 695static inline void s5p_jpeg_set_hactblg(void __iomem *regs)
bb677f3a
AP
696{
697 /* this driver fills table 0 for this component */
31dc0ac0
JA
698 s5p_jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0),
699 ARRAY_SIZE(hactblg0));
bb677f3a
AP
700}
701
80529ae5
JA
702static 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
718static 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
726static 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
af425be8 734static void exynos4_jpeg_set_huff_tbl(void __iomem *base)
80529ae5
JA
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
6c96dbbc
AP
754static 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
774static inline int exynos4_huff_tbl_len(int class, int id)
775{
776 return __exynos4_huff_tbl(class, id, true);
777}
778
779static inline int exynos4_huff_tbl_val(int class, int id)
780{
781 return __exynos4_huff_tbl(class, id, false);
782}
783
784static int get_byte(struct s5p_jpeg_buffer *buf);
785static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word);
786static void skip(struct s5p_jpeg_buffer *buf, long len);
787
788static void exynos4_jpeg_parse_decode_h_tbl(struct s5p_jpeg_ctx *ctx)
789{
790 struct s5p_jpeg *jpeg = ctx->jpeg;
791 struct vb2_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, 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
825static void exynos4_jpeg_parse_huff_tbl(struct s5p_jpeg_ctx *ctx)
826{
827 struct s5p_jpeg *jpeg = ctx->jpeg;
828 struct vb2_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, 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
884static void exynos4_jpeg_parse_decode_q_tbl(struct s5p_jpeg_ctx *ctx)
885{
886 struct s5p_jpeg *jpeg = ctx->jpeg;
887 struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
888 struct s5p_jpeg_buffer jpeg_buffer;
6c96dbbc
AP
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, 0) + ctx->out_q.sof;
894 jpeg_buffer.curr = 0;
895
6c96dbbc
AP
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
915static void exynos4_jpeg_parse_q_tbl(struct s5p_jpeg_ctx *ctx)
916{
917 struct s5p_jpeg *jpeg = ctx->jpeg;
918 struct vb2_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, 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
bb677f3a
AP
956/*
957 * ============================================================================
958 * Device file operations
959 * ============================================================================
960 */
961
962static int queue_init(void *priv, struct vb2_queue *src_vq,
963 struct vb2_queue *dst_vq);
80529ae5
JA
964static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
965 __u32 pixelformat, unsigned int fmt_type);
15f4bc3b 966static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
bb677f3a
AP
967
968static 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;
80529ae5 973 struct s5p_jpeg_fmt *out_fmt, *cap_fmt;
275de24d 974 int ret = 0;
bb677f3a 975
b5146c96 976 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
bb677f3a
AP
977 if (!ctx)
978 return -ENOMEM;
979
b0d5cd6b
HV
980 if (mutex_lock_interruptible(&jpeg->lock)) {
981 ret = -ERESTARTSYS;
982 goto free;
983 }
984
275de24d 985 v4l2_fh_init(&ctx->fh, vfd);
15f4bc3b
SN
986 /* Use separate control handler per file handle */
987 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
275de24d
SN
988 file->private_data = &ctx->fh;
989 v4l2_fh_add(&ctx->fh);
990
bb677f3a
AP
991 ctx->jpeg = jpeg;
992 if (vfd == jpeg->vfd_encoder) {
993 ctx->mode = S5P_JPEG_ENCODE;
80529ae5
JA
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);
bb677f3a
AP
998 } else {
999 ctx->mode = S5P_JPEG_DECODE;
80529ae5
JA
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);
3246fdaa 1004 ctx->scale_factor = EXYNOS3250_DEC_SCALE_FACTOR_8_8;
bb677f3a
AP
1005 }
1006
718cf4a9
SN
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);
275de24d 1010 goto error;
bb677f3a
AP
1011 }
1012
1013 ctx->out_q.fmt = out_fmt;
80529ae5
JA
1014 ctx->cap_q.fmt = cap_fmt;
1015
1016 ret = s5p_jpeg_controls_create(ctx);
1017 if (ret < 0)
1018 goto error;
1019
b0d5cd6b 1020 mutex_unlock(&jpeg->lock);
bb677f3a 1021 return 0;
275de24d
SN
1022
1023error:
1024 v4l2_fh_del(&ctx->fh);
1025 v4l2_fh_exit(&ctx->fh);
b0d5cd6b
HV
1026 mutex_unlock(&jpeg->lock);
1027free:
275de24d
SN
1028 kfree(ctx);
1029 return ret;
bb677f3a
AP
1030}
1031
1032static int s5p_jpeg_release(struct file *file)
1033{
b0d5cd6b 1034 struct s5p_jpeg *jpeg = video_drvdata(file);
275de24d 1035 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
bb677f3a 1036
b0d5cd6b 1037 mutex_lock(&jpeg->lock);
718cf4a9 1038 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
15f4bc3b 1039 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
275de24d
SN
1040 v4l2_fh_del(&ctx->fh);
1041 v4l2_fh_exit(&ctx->fh);
bb677f3a 1042 kfree(ctx);
80529ae5 1043 mutex_unlock(&jpeg->lock);
bb677f3a
AP
1044
1045 return 0;
1046}
1047
bb677f3a
AP
1048static const struct v4l2_file_operations s5p_jpeg_fops = {
1049 .owner = THIS_MODULE,
1050 .open = s5p_jpeg_open,
1051 .release = s5p_jpeg_release,
718cf4a9 1052 .poll = v4l2_m2m_fop_poll,
bb677f3a 1053 .unlocked_ioctl = video_ioctl2,
718cf4a9 1054 .mmap = v4l2_m2m_fop_mmap,
bb677f3a
AP
1055};
1056
1057/*
1058 * ============================================================================
1059 * video ioctl operations
1060 * ============================================================================
1061 */
1062
1063static 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
1071static 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
1087static 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
1096static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
f8433962
JA
1097 unsigned long buffer, unsigned long size,
1098 struct s5p_jpeg_ctx *ctx)
bb677f3a 1099{
6c96dbbc
AP
1100 int c, components = 0, notfound, n_dht = 0, n_dqt = 0;
1101 unsigned int height, width, word, subsampling = 0, sos = 0, sof = 0,
1102 sof_len = 0;
1103 unsigned int dht[S5P_JPEG_MAX_MARKER], dht_len[S5P_JPEG_MAX_MARKER],
1104 dqt[S5P_JPEG_MAX_MARKER], dqt_len[S5P_JPEG_MAX_MARKER];
bb677f3a
AP
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;
6c96dbbc 1113 while (notfound || !sos) {
bb677f3a
AP
1114 c = get_byte(&jpeg_buffer);
1115 if (c == -1)
a35f6003 1116 return false;
bb677f3a
AP
1117 if (c != 0xff)
1118 continue;
1119 do
1120 c = get_byte(&jpeg_buffer);
1121 while (c == 0xff);
1122 if (c == -1)
a35f6003 1123 return false;
bb677f3a
AP
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;
6c96dbbc
AP
1132 length = (long)word - 2;
1133 if (!length)
1134 return false;
1135 sof = jpeg_buffer.curr; /* after 0xffc0 */
1136 sof_len = length;
bb677f3a
AP
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;
bb677f3a 1146
f8433962
JA
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 }
6c96dbbc
AP
1154 if (components > 3)
1155 return false;
f8433962 1156 skip(&jpeg_buffer, components * 2);
6c96dbbc
AP
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 */
bb677f3a
AP
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;
6c96dbbc
AP
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;
f8433962
JA
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
6c96dbbc 1240 return !notfound && sos;
bb677f3a
AP
1241}
1242
1243static int s5p_jpeg_querycap(struct file *file, void *priv,
1244 struct v4l2_capability *cap)
1245{
275de24d 1246 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
bb677f3a
AP
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;
8c17e5e3
HV
1260 cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
1261 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
bb677f3a
AP
1262 return 0;
1263}
1264
80529ae5 1265static int enum_fmt(struct s5p_jpeg_fmt *sjpeg_formats, int n,
bb677f3a
AP
1266 struct v4l2_fmtdesc *f, u32 type)
1267{
1268 int i, num = 0;
1269
1270 for (i = 0; i < n; ++i) {
80529ae5 1271 if (sjpeg_formats[i].flags & type) {
bb677f3a
AP
1272 /* index-th format of type type found ? */
1273 if (num == f->index)
1274 break;
1275 /* Correct type but haven't reached our index yet,
1276 * just increment per-type index */
1277 ++num;
1278 }
1279 }
1280
1281 /* Format not found */
1282 if (i >= n)
1283 return -EINVAL;
1284
80529ae5
JA
1285 strlcpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
1286 f->pixelformat = sjpeg_formats[i].fourcc;
bb677f3a
AP
1287
1288 return 0;
1289}
1290
1291static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
1292 struct v4l2_fmtdesc *f)
1293{
275de24d 1294 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
bb677f3a
AP
1295
1296 if (ctx->mode == S5P_JPEG_ENCODE)
80529ae5
JA
1297 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1298 SJPEG_FMT_FLAG_ENC_CAPTURE);
bb677f3a 1299
80529ae5
JA
1300 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1301 SJPEG_FMT_FLAG_DEC_CAPTURE);
bb677f3a
AP
1302}
1303
1304static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
1305 struct v4l2_fmtdesc *f)
1306{
275de24d 1307 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
bb677f3a
AP
1308
1309 if (ctx->mode == S5P_JPEG_ENCODE)
80529ae5
JA
1310 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1311 SJPEG_FMT_FLAG_ENC_OUTPUT);
bb677f3a 1312
80529ae5
JA
1313 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1314 SJPEG_FMT_FLAG_DEC_OUTPUT);
bb677f3a
AP
1315}
1316
1317static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
1318 enum v4l2_buf_type type)
1319{
1320 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1321 return &ctx->out_q;
1322 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1323 return &ctx->cap_q;
1324
1325 return NULL;
1326}
1327
1328static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
1329{
1330 struct vb2_queue *vq;
1331 struct s5p_jpeg_q_data *q_data = NULL;
1332 struct v4l2_pix_format *pix = &f->fmt.pix;
275de24d 1333 struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
bb677f3a 1334
718cf4a9 1335 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
bb677f3a
AP
1336 if (!vq)
1337 return -EINVAL;
1338
1339 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1340 ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
1341 return -EINVAL;
1342 q_data = get_q_data(ct, f->type);
1343 BUG_ON(q_data == NULL);
1344
1345 pix->width = q_data->w;
1346 pix->height = q_data->h;
1347 pix->field = V4L2_FIELD_NONE;
1348 pix->pixelformat = q_data->fmt->fourcc;
1349 pix->bytesperline = 0;
1350 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
1351 u32 bpl = q_data->w;
1352 if (q_data->fmt->colplanes == 1)
1353 bpl = (bpl * q_data->fmt->depth) >> 3;
1354 pix->bytesperline = bpl;
1355 }
1356 pix->sizeimage = q_data->size;
1357
1358 return 0;
1359}
1360
80529ae5
JA
1361static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
1362 u32 pixelformat, unsigned int fmt_type)
bb677f3a 1363{
b245168c 1364 unsigned int k, fmt_flag;
bb677f3a 1365
80529ae5
JA
1366 if (ctx->mode == S5P_JPEG_ENCODE)
1367 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
1368 SJPEG_FMT_FLAG_ENC_OUTPUT :
1369 SJPEG_FMT_FLAG_ENC_CAPTURE;
1370 else
1371 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
1372 SJPEG_FMT_FLAG_DEC_OUTPUT :
1373 SJPEG_FMT_FLAG_DEC_CAPTURE;
bb677f3a 1374
80529ae5
JA
1375 for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
1376 struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
1377 if (fmt->fourcc == pixelformat &&
1378 fmt->flags & fmt_flag &&
b245168c 1379 fmt->flags & ctx->jpeg->variant->fmt_ver_flag) {
bb677f3a 1380 return fmt;
80529ae5 1381 }
bb677f3a
AP
1382 }
1383
1384 return NULL;
bb677f3a
AP
1385}
1386
e9e7dfe5
JA
1387static void jpeg_bound_align_image(struct s5p_jpeg_ctx *ctx,
1388 u32 *w, unsigned int wmin, unsigned int wmax,
bb677f3a
AP
1389 unsigned int walign,
1390 u32 *h, unsigned int hmin, unsigned int hmax,
1391 unsigned int halign)
1392{
1393 int width, height, w_step, h_step;
1394
1395 width = *w;
1396 height = *h;
1397
1398 w_step = 1 << walign;
1399 h_step = 1 << halign;
e9e7dfe5 1400
7c15fd4b 1401 if (ctx->jpeg->variant->hw3250_compat) {
e9e7dfe5
JA
1402 /*
1403 * Rightmost and bottommost pixels are cropped by the
7c15fd4b
AP
1404 * Exynos3250/compatible JPEG IP for RGB formats, for the
1405 * specific width and height values respectively. This
1406 * assignment will result in v4l_bound_align_image returning
1407 * dimensions reduced by 1 for the aforementioned cases.
e9e7dfe5
JA
1408 */
1409 if (w_step == 4 && ((width & 3) == 1)) {
1410 wmax = width;
1411 hmax = height;
1412 }
1413 }
1414
bb677f3a
AP
1415 v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
1416
1417 if (*w < width && (*w + w_step) < wmax)
1418 *w += w_step;
1419 if (*h < height && (*h + h_step) < hmax)
1420 *h += h_step;
bb677f3a
AP
1421}
1422
1423static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
1424 struct s5p_jpeg_ctx *ctx, int q_type)
1425{
1426 struct v4l2_pix_format *pix = &f->fmt.pix;
1427
1428 if (pix->field == V4L2_FIELD_ANY)
1429 pix->field = V4L2_FIELD_NONE;
1430 else if (pix->field != V4L2_FIELD_NONE)
1431 return -EINVAL;
1432
1433 /* V4L2 specification suggests the driver corrects the format struct
1434 * if any of the dimensions is unsupported */
80529ae5 1435 if (q_type == FMT_TYPE_OUTPUT)
e9e7dfe5 1436 jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
bb677f3a
AP
1437 S5P_JPEG_MAX_WIDTH, 0,
1438 &pix->height, S5P_JPEG_MIN_HEIGHT,
1439 S5P_JPEG_MAX_HEIGHT, 0);
1440 else
e9e7dfe5 1441 jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
bb677f3a
AP
1442 S5P_JPEG_MAX_WIDTH, fmt->h_align,
1443 &pix->height, S5P_JPEG_MIN_HEIGHT,
1444 S5P_JPEG_MAX_HEIGHT, fmt->v_align);
1445
1446 if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1447 if (pix->sizeimage <= 0)
1448 pix->sizeimage = PAGE_SIZE;
1449 pix->bytesperline = 0;
1450 } else {
1451 u32 bpl = pix->bytesperline;
1452
1453 if (fmt->colplanes > 1 && bpl < pix->width)
1454 bpl = pix->width; /* planar */
1455
1456 if (fmt->colplanes == 1 && /* packed */
cc690904 1457 (bpl << 3) / fmt->depth < pix->width)
bb677f3a
AP
1458 bpl = (pix->width * fmt->depth) >> 3;
1459
1460 pix->bytesperline = bpl;
1461 pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
1462 }
1463
1464 return 0;
1465}
1466
1467static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
1468 struct v4l2_format *f)
1469{
275de24d 1470 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
337777a4 1471 struct v4l2_pix_format *pix = &f->fmt.pix;
bb677f3a 1472 struct s5p_jpeg_fmt *fmt;
337777a4 1473 int ret;
bb677f3a 1474
80529ae5
JA
1475 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1476 FMT_TYPE_CAPTURE);
1477 if (!fmt) {
bb677f3a
AP
1478 v4l2_err(&ctx->jpeg->v4l2_dev,
1479 "Fourcc format (0x%08x) invalid.\n",
1480 f->fmt.pix.pixelformat);
1481 return -EINVAL;
1482 }
1483
6c96dbbc 1484 if (!ctx->jpeg->variant->hw_ex4_compat || ctx->mode != S5P_JPEG_DECODE)
2caeeb0c
JA
1485 goto exit;
1486
337777a4
JA
1487 /*
1488 * The exynos4x12 device requires resulting YUV image
1489 * subsampling not to be lower than the input jpeg subsampling.
1490 * If this requirement is not met then downgrade the requested
1491 * capture format to the one with subsampling equal to the input jpeg.
1492 */
2caeeb0c 1493 if ((fmt->flags & SJPEG_FMT_NON_RGB) &&
337777a4
JA
1494 (fmt->subsampling < ctx->subsampling)) {
1495 ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling,
1496 fmt->fourcc,
1497 &pix->pixelformat,
1498 ctx);
1499 if (ret < 0)
1500 pix->pixelformat = V4L2_PIX_FMT_GREY;
1501
1502 fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1503 FMT_TYPE_CAPTURE);
1504 }
1505
2caeeb0c
JA
1506 /*
1507 * Decompression of a JPEG file with 4:2:0 subsampling and odd
1508 * width to the YUV 4:2:0 compliant formats produces a raw image
1509 * with broken luma component. Adjust capture format to RGB565
1510 * in such a case.
1511 */
1512 if (ctx->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420 &&
1513 (ctx->out_q.w & 1) &&
1514 (pix->pixelformat == V4L2_PIX_FMT_NV12 ||
1515 pix->pixelformat == V4L2_PIX_FMT_NV21 ||
1516 pix->pixelformat == V4L2_PIX_FMT_YUV420)) {
1517 pix->pixelformat = V4L2_PIX_FMT_RGB565;
1518 fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1519 FMT_TYPE_CAPTURE);
1520 }
1521
1522exit:
80529ae5 1523 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
bb677f3a
AP
1524}
1525
1526static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
1527 struct v4l2_format *f)
1528{
275de24d 1529 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
bb677f3a 1530 struct s5p_jpeg_fmt *fmt;
bb677f3a 1531
80529ae5
JA
1532 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1533 FMT_TYPE_OUTPUT);
1534 if (!fmt) {
bb677f3a
AP
1535 v4l2_err(&ctx->jpeg->v4l2_dev,
1536 "Fourcc format (0x%08x) invalid.\n",
1537 f->fmt.pix.pixelformat);
1538 return -EINVAL;
1539 }
1540
80529ae5 1541 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
bb677f3a
AP
1542}
1543
b2254d6f
JA
1544static int exynos4_jpeg_get_output_buffer_size(struct s5p_jpeg_ctx *ctx,
1545 struct v4l2_format *f,
1546 int fmt_depth)
1547{
1548 struct v4l2_pix_format *pix = &f->fmt.pix;
1549 u32 pix_fmt = f->fmt.pix.pixelformat;
1550 int w = pix->width, h = pix->height, wh_align;
77401dd7 1551 int padding = 0;
b2254d6f
JA
1552
1553 if (pix_fmt == V4L2_PIX_FMT_RGB32 ||
77401dd7 1554 pix_fmt == V4L2_PIX_FMT_RGB565 ||
b2254d6f
JA
1555 pix_fmt == V4L2_PIX_FMT_NV24 ||
1556 pix_fmt == V4L2_PIX_FMT_NV42 ||
1557 pix_fmt == V4L2_PIX_FMT_NV12 ||
1558 pix_fmt == V4L2_PIX_FMT_NV21 ||
1559 pix_fmt == V4L2_PIX_FMT_YUV420)
1560 wh_align = 4;
1561 else
1562 wh_align = 1;
1563
e9e7dfe5 1564 jpeg_bound_align_image(ctx, &w, S5P_JPEG_MIN_WIDTH,
b2254d6f
JA
1565 S5P_JPEG_MAX_WIDTH, wh_align,
1566 &h, S5P_JPEG_MIN_HEIGHT,
1567 S5P_JPEG_MAX_HEIGHT, wh_align);
1568
77401dd7
AP
1569 if (ctx->jpeg->variant->version == SJPEG_EXYNOS4)
1570 padding = PAGE_SIZE;
1571
1572 return (w * h * fmt_depth >> 3) + padding;
b2254d6f
JA
1573}
1574
5a71671a
JA
1575static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1576 struct v4l2_rect *r);
1577
bb677f3a
AP
1578static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
1579{
1580 struct vb2_queue *vq;
1581 struct s5p_jpeg_q_data *q_data = NULL;
1582 struct v4l2_pix_format *pix = &f->fmt.pix;
4a30d30b 1583 struct v4l2_ctrl *ctrl_subs;
5a71671a 1584 struct v4l2_rect scale_rect;
80529ae5 1585 unsigned int f_type;
bb677f3a 1586
718cf4a9 1587 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
bb677f3a
AP
1588 if (!vq)
1589 return -EINVAL;
1590
1591 q_data = get_q_data(ct, f->type);
1592 BUG_ON(q_data == NULL);
1593
1594 if (vb2_is_busy(vq)) {
1595 v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
1596 return -EBUSY;
1597 }
1598
80529ae5
JA
1599 f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
1600 FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
1601
1602 q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
bb677f3a
AP
1603 q_data->w = pix->width;
1604 q_data->h = pix->height;
b2254d6f
JA
1605 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
1606 /*
1607 * During encoding Exynos4x12 SoCs access wider memory area
1608 * than it results from Image_x and Image_y values written to
1609 * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu
1610 * page fault calculate proper buffer size in such a case.
1611 */
6c96dbbc 1612 if (ct->jpeg->variant->hw_ex4_compat &&
b2254d6f
JA
1613 f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE)
1614 q_data->size = exynos4_jpeg_get_output_buffer_size(ct,
1615 f,
1616 q_data->fmt->depth);
1617 else
1618 q_data->size = q_data->w * q_data->h *
1619 q_data->fmt->depth >> 3;
1620 } else {
bb677f3a 1621 q_data->size = pix->sizeimage;
b2254d6f 1622 }
bb677f3a 1623
4a30d30b
JA
1624 if (f_type == FMT_TYPE_OUTPUT) {
1625 ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler,
1626 V4L2_CID_JPEG_CHROMA_SUBSAMPLING);
1627 if (ctrl_subs)
1628 v4l2_ctrl_s_ctrl(ctrl_subs, q_data->fmt->subsampling);
dfd96900
JA
1629 ct->crop_altered = false;
1630 }
1631
1632 /*
1633 * For decoding init crop_rect with capture buffer dimmensions which
1634 * contain aligned dimensions of the input JPEG image and do it only
1635 * if crop rectangle hasn't been altered by the user space e.g. with
1636 * S_SELECTION ioctl. For encoding assign output buffer dimensions.
1637 */
1638 if (!ct->crop_altered &&
1639 ((ct->mode == S5P_JPEG_DECODE && f_type == FMT_TYPE_CAPTURE) ||
1640 (ct->mode == S5P_JPEG_ENCODE && f_type == FMT_TYPE_OUTPUT))) {
1641 ct->crop_rect.width = pix->width;
1642 ct->crop_rect.height = pix->height;
1643 }
5a71671a
JA
1644
1645 /*
1646 * Prevent downscaling to YUV420 format by more than 2
7c15fd4b 1647 * for Exynos3250/compatible SoC as it produces broken raw image
5a71671a
JA
1648 * in such cases.
1649 */
1650 if (ct->mode == S5P_JPEG_DECODE &&
1651 f_type == FMT_TYPE_CAPTURE &&
7c15fd4b 1652 ct->jpeg->variant->hw3250_compat &&
5a71671a
JA
1653 pix->pixelformat == V4L2_PIX_FMT_YUV420 &&
1654 ct->scale_factor > 2) {
1655 scale_rect.width = ct->out_q.w / 2;
1656 scale_rect.height = ct->out_q.h / 2;
1657 exynos3250_jpeg_try_downscale(ct, &scale_rect);
4a30d30b
JA
1658 }
1659
bb677f3a
AP
1660 return 0;
1661}
1662
1663static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
1664 struct v4l2_format *f)
1665{
1666 int ret;
1667
1668 ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
1669 if (ret)
1670 return ret;
1671
275de24d 1672 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
bb677f3a
AP
1673}
1674
1675static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
1676 struct v4l2_format *f)
1677{
1678 int ret;
1679
1680 ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
1681 if (ret)
1682 return ret;
1683
275de24d 1684 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
bb677f3a
AP
1685}
1686
3246fdaa
JA
1687static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1688 struct v4l2_rect *r)
1689{
1690 int w_ratio, h_ratio, scale_factor, cur_ratio, i;
1691
1692 w_ratio = ctx->out_q.w / r->width;
1693 h_ratio = ctx->out_q.h / r->height;
1694
1695 scale_factor = w_ratio > h_ratio ? w_ratio : h_ratio;
1696 scale_factor = clamp_val(scale_factor, 1, 8);
1697
1698 /* Align scale ratio to the nearest power of 2 */
1699 for (i = 0; i <= 3; ++i) {
1700 cur_ratio = 1 << i;
1701 if (scale_factor <= cur_ratio) {
1702 ctx->scale_factor = cur_ratio;
1703 break;
1704 }
1705 }
1706
1707 r->width = round_down(ctx->out_q.w / ctx->scale_factor, 2);
1708 r->height = round_down(ctx->out_q.h / ctx->scale_factor, 2);
1709
1710 ctx->crop_rect.width = r->width;
1711 ctx->crop_rect.height = r->height;
1712 ctx->crop_rect.left = 0;
1713 ctx->crop_rect.top = 0;
1714
1715 ctx->crop_altered = true;
1716
1717 return 0;
1718}
1719
1720/* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
1721static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
1722{
1723 if (a->left < b->left || a->top < b->top)
1724 return 0;
1725 if (a->left + a->width > b->left + b->width)
1726 return 0;
1727 if (a->top + a->height > b->top + b->height)
1728 return 0;
1729
1730 return 1;
1731}
1732
1733static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx,
1734 struct v4l2_rect *r)
1735{
1736 struct v4l2_rect base_rect;
1737 int w_step, h_step;
1738
1739 switch (ctx->cap_q.fmt->fourcc) {
1740 case V4L2_PIX_FMT_NV12:
1741 case V4L2_PIX_FMT_NV21:
1742 w_step = 1;
1743 h_step = 2;
1744 break;
1745 case V4L2_PIX_FMT_YUV420:
1746 w_step = 2;
1747 h_step = 2;
1748 break;
1749 default:
1750 w_step = 1;
1751 h_step = 1;
1752 break;
1753 }
1754
1755 base_rect.top = 0;
1756 base_rect.left = 0;
1757 base_rect.width = ctx->out_q.w;
1758 base_rect.height = ctx->out_q.h;
1759
1760 r->width = round_down(r->width, w_step);
1761 r->height = round_down(r->height, h_step);
1762 r->left = round_down(r->left, 2);
1763 r->top = round_down(r->top, 2);
1764
1765 if (!enclosed_rectangle(r, &base_rect))
1766 return -EINVAL;
1767
1768 ctx->crop_rect.left = r->left;
1769 ctx->crop_rect.top = r->top;
1770 ctx->crop_rect.width = r->width;
1771 ctx->crop_rect.height = r->height;
1772
1773 ctx->crop_altered = true;
1774
1775 return 0;
1776}
1777
1778/*
1779 * V4L2 controls
1780 */
1781
9f3bd320 1782static int s5p_jpeg_g_selection(struct file *file, void *priv,
bb677f3a
AP
1783 struct v4l2_selection *s)
1784{
275de24d 1785 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
bb677f3a
AP
1786
1787 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
38a6ef33 1788 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
bb677f3a
AP
1789 return -EINVAL;
1790
1791 /* For JPEG blob active == default == bounds */
1792 switch (s->target) {
c1334823 1793 case V4L2_SEL_TGT_CROP:
bb677f3a
AP
1794 case V4L2_SEL_TGT_CROP_BOUNDS:
1795 case V4L2_SEL_TGT_CROP_DEFAULT:
bb677f3a
AP
1796 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1797 s->r.width = ctx->out_q.w;
1798 s->r.height = ctx->out_q.h;
fac4d961
JA
1799 s->r.left = 0;
1800 s->r.top = 0;
bb677f3a 1801 break;
fac4d961 1802 case V4L2_SEL_TGT_COMPOSE:
bb677f3a
AP
1803 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1804 case V4L2_SEL_TGT_COMPOSE_PADDED:
fac4d961
JA
1805 s->r.width = ctx->crop_rect.width;
1806 s->r.height = ctx->crop_rect.height;
1807 s->r.left = ctx->crop_rect.left;
1808 s->r.top = ctx->crop_rect.top;
bb677f3a
AP
1809 break;
1810 default:
1811 return -EINVAL;
1812 }
bb677f3a
AP
1813 return 0;
1814}
1815
15f4bc3b
SN
1816/*
1817 * V4L2 controls
1818 */
3246fdaa
JA
1819static int s5p_jpeg_s_selection(struct file *file, void *fh,
1820 struct v4l2_selection *s)
1821{
1822 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
1823 struct v4l2_rect *rect = &s->r;
1824 int ret = -EINVAL;
1825
1826 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1827 return -EINVAL;
1828
1829 if (s->target == V4L2_SEL_TGT_COMPOSE) {
1830 if (ctx->mode != S5P_JPEG_DECODE)
1831 return -EINVAL;
7c15fd4b 1832 if (ctx->jpeg->variant->hw3250_compat)
3246fdaa
JA
1833 ret = exynos3250_jpeg_try_downscale(ctx, rect);
1834 } else if (s->target == V4L2_SEL_TGT_CROP) {
1835 if (ctx->mode != S5P_JPEG_ENCODE)
1836 return -EINVAL;
7c15fd4b 1837 if (ctx->jpeg->variant->hw3250_compat)
3246fdaa
JA
1838 ret = exynos3250_jpeg_try_crop(ctx, rect);
1839 }
1840
1841 return ret;
1842}
15f4bc3b
SN
1843
1844static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
bb677f3a 1845{
15f4bc3b
SN
1846 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1847 struct s5p_jpeg *jpeg = ctx->jpeg;
1848 unsigned long flags;
bb677f3a 1849
15f4bc3b
SN
1850 switch (ctrl->id) {
1851 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1852 spin_lock_irqsave(&jpeg->slock, flags);
303b0a96 1853 ctrl->val = s5p_jpeg_to_user_subsampling(ctx);
15f4bc3b
SN
1854 spin_unlock_irqrestore(&jpeg->slock, flags);
1855 break;
1856 }
bb677f3a
AP
1857
1858 return 0;
1859}
1860
39c344c4 1861static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val)
11fbea3e 1862{
39c344c4
JA
1863 switch (ctx->jpeg->variant->version) {
1864 case SJPEG_S5P:
1865 return 0;
1866 case SJPEG_EXYNOS3250:
7c15fd4b 1867 case SJPEG_EXYNOS5420:
39c344c4 1868 /*
7c15fd4b 1869 * The exynos3250/compatible device can produce JPEG image only
39c344c4
JA
1870 * of 4:4:4 subsampling when given RGB32 source image.
1871 */
1872 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
1873 *ctrl_val = 0;
1874 break;
1875 case SJPEG_EXYNOS4:
11fbea3e
JA
1876 /*
1877 * The exynos4x12 device requires input raw image fourcc
1878 * to be V4L2_PIX_FMT_GREY if gray jpeg format
1879 * is to be set.
1880 */
1881 if (ctx->out_q.fmt->fourcc != V4L2_PIX_FMT_GREY &&
39c344c4
JA
1882 *ctrl_val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY)
1883 return -EINVAL;
1884 break;
11fbea3e
JA
1885 }
1886
39c344c4 1887 /*
7c15fd4b 1888 * The exynos4x12 and exynos3250/compatible devices require resulting
39c344c4
JA
1889 * jpeg subsampling not to be lower than the input raw image
1890 * subsampling.
1891 */
1892 if (ctx->out_q.fmt->subsampling > *ctrl_val)
1893 *ctrl_val = ctx->out_q.fmt->subsampling;
1894
1895 return 0;
1896}
1897
1898static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl)
1899{
1900 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1901 unsigned long flags;
1902 int ret = 0;
1903
1904 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1905
1906 if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING)
1907 ret = s5p_jpeg_adjust_subs_ctrl(ctx, &ctrl->val);
1908
11fbea3e
JA
1909 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1910 return ret;
1911}
1912
15f4bc3b 1913static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
bb677f3a 1914{
15f4bc3b
SN
1915 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1916 unsigned long flags;
bb677f3a 1917
15f4bc3b 1918 spin_lock_irqsave(&ctx->jpeg->slock, flags);
bb677f3a 1919
15f4bc3b
SN
1920 switch (ctrl->id) {
1921 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
78e5a3ce 1922 ctx->compr_quality = ctrl->val;
15f4bc3b
SN
1923 break;
1924 case V4L2_CID_JPEG_RESTART_INTERVAL:
1925 ctx->restart_interval = ctrl->val;
1926 break;
1927 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1928 ctx->subsampling = ctrl->val;
1929 break;
1930 }
1931
1932 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1933 return 0;
1934}
1935
1936static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
1937 .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl,
11fbea3e 1938 .try_ctrl = s5p_jpeg_try_ctrl,
15f4bc3b
SN
1939 .s_ctrl = s5p_jpeg_s_ctrl,
1940};
1941
1942static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
1943{
1944 unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
1945 struct v4l2_ctrl *ctrl;
088f8300 1946 int ret;
15f4bc3b
SN
1947
1948 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
bb677f3a 1949
15f4bc3b
SN
1950 if (ctx->mode == S5P_JPEG_ENCODE) {
1951 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1952 V4L2_CID_JPEG_COMPRESSION_QUALITY,
78e5a3ce 1953 0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
15f4bc3b
SN
1954
1955 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1956 V4L2_CID_JPEG_RESTART_INTERVAL,
1957 0, 3, 0xffff, 0);
fdf9e2bc
JA
1958 if (ctx->jpeg->variant->version == SJPEG_S5P)
1959 mask = ~0x06; /* 422, 420 */
15f4bc3b
SN
1960 }
1961
1962 ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1963 V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
1964 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
1965 V4L2_JPEG_CHROMA_SUBSAMPLING_422);
bb677f3a 1966
088f8300
JA
1967 if (ctx->ctrl_handler.error) {
1968 ret = ctx->ctrl_handler.error;
1969 goto error_free;
1970 }
15f4bc3b
SN
1971
1972 if (ctx->mode == S5P_JPEG_DECODE)
1973 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
1974 V4L2_CTRL_FLAG_READ_ONLY;
088f8300
JA
1975
1976 ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
1977 if (ret < 0)
1978 goto error_free;
1979
1980 return ret;
1981
1982error_free:
1983 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1984 return ret;
bb677f3a
AP
1985}
1986
1987static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
1988 .vidioc_querycap = s5p_jpeg_querycap,
1989
1990 .vidioc_enum_fmt_vid_cap = s5p_jpeg_enum_fmt_vid_cap,
1991 .vidioc_enum_fmt_vid_out = s5p_jpeg_enum_fmt_vid_out,
1992
1993 .vidioc_g_fmt_vid_cap = s5p_jpeg_g_fmt,
1994 .vidioc_g_fmt_vid_out = s5p_jpeg_g_fmt,
1995
1996 .vidioc_try_fmt_vid_cap = s5p_jpeg_try_fmt_vid_cap,
1997 .vidioc_try_fmt_vid_out = s5p_jpeg_try_fmt_vid_out,
1998
1999 .vidioc_s_fmt_vid_cap = s5p_jpeg_s_fmt_vid_cap,
2000 .vidioc_s_fmt_vid_out = s5p_jpeg_s_fmt_vid_out,
2001
718cf4a9
SN
2002 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
2003 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
2004 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
2005 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
bb677f3a 2006
718cf4a9
SN
2007 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
2008 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
bb677f3a
AP
2009
2010 .vidioc_g_selection = s5p_jpeg_g_selection,
3246fdaa 2011 .vidioc_s_selection = s5p_jpeg_s_selection,
bb677f3a
AP
2012};
2013
2014/*
2015 * ============================================================================
2016 * mem2mem callbacks
2017 * ============================================================================
2018 */
2019
2020static void s5p_jpeg_device_run(void *priv)
2021{
2022 struct s5p_jpeg_ctx *ctx = priv;
2023 struct s5p_jpeg *jpeg = ctx->jpeg;
2024 struct vb2_buffer *src_buf, *dst_buf;
b3c932a9
JA
2025 unsigned long src_addr, dst_addr, flags;
2026
2027 spin_lock_irqsave(&ctx->jpeg->slock, flags);
bb677f3a 2028
718cf4a9
SN
2029 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2030 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
bb677f3a
AP
2031 src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
2032 dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
2033
9f7b62d9
JA
2034 s5p_jpeg_reset(jpeg->regs);
2035 s5p_jpeg_poweron(jpeg->regs);
2036 s5p_jpeg_proc_mode(jpeg->regs, ctx->mode);
bb677f3a
AP
2037 if (ctx->mode == S5P_JPEG_ENCODE) {
2038 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
9f7b62d9
JA
2039 s5p_jpeg_input_raw_mode(jpeg->regs,
2040 S5P_JPEG_RAW_IN_565);
bb677f3a 2041 else
9f7b62d9
JA
2042 s5p_jpeg_input_raw_mode(jpeg->regs,
2043 S5P_JPEG_RAW_IN_422);
2044 s5p_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
2045 s5p_jpeg_dri(jpeg->regs, ctx->restart_interval);
2046 s5p_jpeg_x(jpeg->regs, ctx->out_q.w);
2047 s5p_jpeg_y(jpeg->regs, ctx->out_q.h);
2048 s5p_jpeg_imgadr(jpeg->regs, src_addr);
2049 s5p_jpeg_jpgadr(jpeg->regs, dst_addr);
bb677f3a
AP
2050
2051 /* ultimately comes from sizeimage from userspace */
9f7b62d9 2052 s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
bb677f3a
AP
2053
2054 /* JPEG RGB to YCbCr conversion matrix */
9f7b62d9
JA
2055 s5p_jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
2056 s5p_jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
2057 s5p_jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
2058 s5p_jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
2059 s5p_jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
2060 s5p_jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
2061 s5p_jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
2062 s5p_jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
2063 s5p_jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
bb677f3a
AP
2064
2065 /*
2066 * JPEG IP allows storing 4 quantization tables
2067 * We fill table 0 for luma and table 1 for chroma
2068 */
31dc0ac0
JA
2069 s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2070 s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
bb677f3a 2071 /* use table 0 for Y */
9f7b62d9 2072 s5p_jpeg_qtbl(jpeg->regs, 1, 0);
bb677f3a 2073 /* use table 1 for Cb and Cr*/
9f7b62d9
JA
2074 s5p_jpeg_qtbl(jpeg->regs, 2, 1);
2075 s5p_jpeg_qtbl(jpeg->regs, 3, 1);
bb677f3a
AP
2076
2077 /* Y, Cb, Cr use Huffman table 0 */
9f7b62d9
JA
2078 s5p_jpeg_htbl_ac(jpeg->regs, 1);
2079 s5p_jpeg_htbl_dc(jpeg->regs, 1);
2080 s5p_jpeg_htbl_ac(jpeg->regs, 2);
2081 s5p_jpeg_htbl_dc(jpeg->regs, 2);
2082 s5p_jpeg_htbl_ac(jpeg->regs, 3);
2083 s5p_jpeg_htbl_dc(jpeg->regs, 3);
fb6f8c02 2084 } else { /* S5P_JPEG_DECODE */
9f7b62d9
JA
2085 s5p_jpeg_rst_int_enable(jpeg->regs, true);
2086 s5p_jpeg_data_num_int_enable(jpeg->regs, true);
2087 s5p_jpeg_final_mcu_num_int_enable(jpeg->regs, true);
fb6f8c02 2088 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
9f7b62d9 2089 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
fb6f8c02 2090 else
9f7b62d9
JA
2091 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
2092 s5p_jpeg_jpgadr(jpeg->regs, src_addr);
2093 s5p_jpeg_imgadr(jpeg->regs, dst_addr);
bb677f3a 2094 }
15f4bc3b 2095
9f7b62d9 2096 s5p_jpeg_start(jpeg->regs);
b3c932a9
JA
2097
2098 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
bb677f3a
AP
2099}
2100
80529ae5
JA
2101static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
2102{
2103 struct s5p_jpeg *jpeg = ctx->jpeg;
2104 struct s5p_jpeg_fmt *fmt;
2105 struct vb2_buffer *vb;
12b05566 2106 struct s5p_jpeg_addr jpeg_addr = {};
80529ae5
JA
2107 u32 pix_size, padding_bytes = 0;
2108
cb0c3f5f
TN
2109 jpeg_addr.cb = 0;
2110 jpeg_addr.cr = 0;
2111
80529ae5
JA
2112 pix_size = ctx->cap_q.w * ctx->cap_q.h;
2113
2114 if (ctx->mode == S5P_JPEG_ENCODE) {
2115 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2116 fmt = ctx->out_q.fmt;
2117 if (ctx->out_q.w % 2 && fmt->h_align > 0)
2118 padding_bytes = ctx->out_q.h;
2119 } else {
2120 fmt = ctx->cap_q.fmt;
2121 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2122 }
2123
2124 jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
2125
2126 if (fmt->colplanes == 2) {
2127 jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes;
2128 } else if (fmt->colplanes == 3) {
2129 jpeg_addr.cb = jpeg_addr.y + pix_size;
2130 if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
2131 jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
2132 else
2133 jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
2134 }
2135
2136 exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr);
2137}
2138
2139static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
2140{
2141 struct s5p_jpeg *jpeg = ctx->jpeg;
2142 struct vb2_buffer *vb;
2143 unsigned int jpeg_addr = 0;
2144
2145 if (ctx->mode == S5P_JPEG_ENCODE)
2146 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2147 else
2148 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2149
2150 jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
6c96dbbc
AP
2151 if (jpeg->variant->version == SJPEG_EXYNOS5433 &&
2152 ctx->mode == S5P_JPEG_DECODE)
2153 jpeg_addr += ctx->out_q.sos;
80529ae5
JA
2154 exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
2155}
2156
6c96dbbc
AP
2157static inline void exynos4_jpeg_set_img_fmt(void __iomem *base,
2158 unsigned int img_fmt)
2159{
2160 __exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS4);
2161}
2162
2163static inline void exynos5433_jpeg_set_img_fmt(void __iomem *base,
2164 unsigned int img_fmt)
2165{
2166 __exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS5433);
2167}
2168
2169static inline void exynos4_jpeg_set_enc_out_fmt(void __iomem *base,
2170 unsigned int out_fmt)
2171{
2172 __exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS4);
2173}
2174
2175static inline void exynos5433_jpeg_set_enc_out_fmt(void __iomem *base,
2176 unsigned int out_fmt)
2177{
2178 __exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS5433);
2179}
2180
80529ae5
JA
2181static void exynos4_jpeg_device_run(void *priv)
2182{
2183 struct s5p_jpeg_ctx *ctx = priv;
2184 struct s5p_jpeg *jpeg = ctx->jpeg;
2185 unsigned int bitstream_size;
2186 unsigned long flags;
2187
6c96dbbc 2188 spin_lock_irqsave(&jpeg->slock, flags);
80529ae5
JA
2189
2190 if (ctx->mode == S5P_JPEG_ENCODE) {
2191 exynos4_jpeg_sw_reset(jpeg->regs);
6c96dbbc 2192 exynos4_jpeg_set_interrupt(jpeg->regs, jpeg->variant->version);
80529ae5
JA
2193 exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
2194
2195 exynos4_jpeg_set_huff_tbl(jpeg->regs);
2196
2197 /*
2198 * JPEG IP allows storing 4 quantization tables
2199 * We fill table 0 for luma and table 1 for chroma
2200 */
2201 exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2202 exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2203
2204 exynos4_jpeg_set_encode_tbl_select(jpeg->regs,
2205 ctx->compr_quality);
2206 exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
2207 ctx->cap_q.h);
2208
6c96dbbc
AP
2209 if (ctx->jpeg->variant->version == SJPEG_EXYNOS4) {
2210 exynos4_jpeg_set_enc_out_fmt(jpeg->regs,
2211 ctx->subsampling);
2212 exynos4_jpeg_set_img_fmt(jpeg->regs,
2213 ctx->out_q.fmt->fourcc);
2214 } else {
2215 exynos5433_jpeg_set_enc_out_fmt(jpeg->regs,
2216 ctx->subsampling);
2217 exynos5433_jpeg_set_img_fmt(jpeg->regs,
2218 ctx->out_q.fmt->fourcc);
2219 }
80529ae5
JA
2220 exynos4_jpeg_set_img_addr(ctx);
2221 exynos4_jpeg_set_jpeg_addr(ctx);
2222 exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs,
2223 ctx->out_q.fmt->fourcc);
2224 } else {
2225 exynos4_jpeg_sw_reset(jpeg->regs);
6c96dbbc
AP
2226 exynos4_jpeg_set_interrupt(jpeg->regs,
2227 jpeg->variant->version);
80529ae5
JA
2228 exynos4_jpeg_set_img_addr(ctx);
2229 exynos4_jpeg_set_jpeg_addr(ctx);
80529ae5 2230
6c96dbbc
AP
2231 if (jpeg->variant->version == SJPEG_EXYNOS5433) {
2232 exynos4_jpeg_parse_huff_tbl(ctx);
2233 exynos4_jpeg_parse_decode_h_tbl(ctx);
2234
2235 exynos4_jpeg_parse_q_tbl(ctx);
2236 exynos4_jpeg_parse_decode_q_tbl(ctx);
2237
2238 exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
2239
2240 exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
2241 ctx->cap_q.h);
2242 exynos5433_jpeg_set_enc_out_fmt(jpeg->regs,
2243 ctx->subsampling);
2244 exynos5433_jpeg_set_img_fmt(jpeg->regs,
2245 ctx->cap_q.fmt->fourcc);
2246 bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 16);
2247 } else {
2248 exynos4_jpeg_set_img_fmt(jpeg->regs,
2249 ctx->cap_q.fmt->fourcc);
2250 bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
2251 }
80529ae5
JA
2252
2253 exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
2254 }
2255
2256 exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
2257
6c96dbbc 2258 spin_unlock_irqrestore(&jpeg->slock, flags);
80529ae5
JA
2259}
2260
3246fdaa
JA
2261static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
2262{
2263 struct s5p_jpeg *jpeg = ctx->jpeg;
2264 struct s5p_jpeg_fmt *fmt;
2265 struct vb2_buffer *vb;
12b05566 2266 struct s5p_jpeg_addr jpeg_addr = {};
3246fdaa
JA
2267 u32 pix_size;
2268
2269 pix_size = ctx->cap_q.w * ctx->cap_q.h;
2270
2271 if (ctx->mode == S5P_JPEG_ENCODE) {
2272 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2273 fmt = ctx->out_q.fmt;
2274 } else {
2275 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2276 fmt = ctx->cap_q.fmt;
2277 }
2278
2279 jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
2280
2281 if (fmt->colplanes == 2) {
2282 jpeg_addr.cb = jpeg_addr.y + pix_size;
2283 } else if (fmt->colplanes == 3) {
2284 jpeg_addr.cb = jpeg_addr.y + pix_size;
2285 if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
2286 jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
2287 else
2288 jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
2289 }
2290
2291 exynos3250_jpeg_imgadr(jpeg->regs, &jpeg_addr);
2292}
2293
2294static void exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
2295{
2296 struct s5p_jpeg *jpeg = ctx->jpeg;
2297 struct vb2_buffer *vb;
2298 unsigned int jpeg_addr = 0;
2299
2300 if (ctx->mode == S5P_JPEG_ENCODE)
2301 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2302 else
2303 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2304
2305 jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
2306 exynos3250_jpeg_jpgadr(jpeg->regs, jpeg_addr);
2307}
2308
2309static void exynos3250_jpeg_device_run(void *priv)
2310{
2311 struct s5p_jpeg_ctx *ctx = priv;
2312 struct s5p_jpeg *jpeg = ctx->jpeg;
2313 unsigned long flags;
2314
2315 spin_lock_irqsave(&ctx->jpeg->slock, flags);
2316
2317 exynos3250_jpeg_reset(jpeg->regs);
2318 exynos3250_jpeg_set_dma_num(jpeg->regs);
2319 exynos3250_jpeg_poweron(jpeg->regs);
2320 exynos3250_jpeg_clk_set(jpeg->regs);
2321 exynos3250_jpeg_proc_mode(jpeg->regs, ctx->mode);
2322
2323 if (ctx->mode == S5P_JPEG_ENCODE) {
2324 exynos3250_jpeg_input_raw_fmt(jpeg->regs,
2325 ctx->out_q.fmt->fourcc);
2326 exynos3250_jpeg_dri(jpeg->regs, ctx->restart_interval);
2327
2328 /*
2329 * JPEG IP allows storing 4 quantization tables
2330 * We fill table 0 for luma and table 1 for chroma
2331 */
2332 s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2333 s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2334 /* use table 0 for Y */
2335 exynos3250_jpeg_qtbl(jpeg->regs, 1, 0);
2336 /* use table 1 for Cb and Cr*/
2337 exynos3250_jpeg_qtbl(jpeg->regs, 2, 1);
2338 exynos3250_jpeg_qtbl(jpeg->regs, 3, 1);
2339
7c15fd4b
AP
2340 /*
2341 * Some SoCs require setting Huffman tables before each run
2342 */
2343 if (jpeg->variant->htbl_reinit) {
2344 s5p_jpeg_set_hdctbl(jpeg->regs);
2345 s5p_jpeg_set_hdctblg(jpeg->regs);
2346 s5p_jpeg_set_hactbl(jpeg->regs);
2347 s5p_jpeg_set_hactblg(jpeg->regs);
2348 }
2349
3246fdaa
JA
2350 /* Y, Cb, Cr use Huffman table 0 */
2351 exynos3250_jpeg_htbl_ac(jpeg->regs, 1);
2352 exynos3250_jpeg_htbl_dc(jpeg->regs, 1);
2353 exynos3250_jpeg_htbl_ac(jpeg->regs, 2);
2354 exynos3250_jpeg_htbl_dc(jpeg->regs, 2);
2355 exynos3250_jpeg_htbl_ac(jpeg->regs, 3);
2356 exynos3250_jpeg_htbl_dc(jpeg->regs, 3);
2357
2358 exynos3250_jpeg_set_x(jpeg->regs, ctx->crop_rect.width);
2359 exynos3250_jpeg_set_y(jpeg->regs, ctx->crop_rect.height);
2360 exynos3250_jpeg_stride(jpeg->regs, ctx->out_q.fmt->fourcc,
2361 ctx->out_q.w);
2362 exynos3250_jpeg_offset(jpeg->regs, ctx->crop_rect.left,
2363 ctx->crop_rect.top);
2364 exynos3250_jpeg_set_img_addr(ctx);
2365 exynos3250_jpeg_set_jpeg_addr(ctx);
2366 exynos3250_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
2367
2368 /* ultimately comes from sizeimage from userspace */
2369 exynos3250_jpeg_enc_stream_bound(jpeg->regs, ctx->cap_q.size);
2370
2371 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565 ||
2372 ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565X ||
2373 ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
2374 exynos3250_jpeg_set_y16(jpeg->regs, true);
2375 } else {
2376 exynos3250_jpeg_set_img_addr(ctx);
2377 exynos3250_jpeg_set_jpeg_addr(ctx);
2378 exynos3250_jpeg_stride(jpeg->regs, ctx->cap_q.fmt->fourcc,
2379 ctx->cap_q.w);
2380 exynos3250_jpeg_offset(jpeg->regs, 0, 0);
2381 exynos3250_jpeg_dec_scaling_ratio(jpeg->regs,
2382 ctx->scale_factor);
2383 exynos3250_jpeg_dec_stream_size(jpeg->regs, ctx->out_q.size);
2384 exynos3250_jpeg_output_raw_fmt(jpeg->regs,
2385 ctx->cap_q.fmt->fourcc);
2386 }
2387
2388 exynos3250_jpeg_interrupts_enable(jpeg->regs);
2389
2390 /* JPEG RGB to YCbCr conversion matrix */
2391 exynos3250_jpeg_coef(jpeg->regs, ctx->mode);
2392
2393 exynos3250_jpeg_set_timer(jpeg->regs, EXYNOS3250_IRQ_TIMEOUT);
2394 jpeg->irq_status = 0;
2395 exynos3250_jpeg_start(jpeg->regs);
2396
2397 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
2398}
2399
bb677f3a
AP
2400static int s5p_jpeg_job_ready(void *priv)
2401{
2402 struct s5p_jpeg_ctx *ctx = priv;
2403
2404 if (ctx->mode == S5P_JPEG_DECODE)
2405 return ctx->hdr_parsed;
2406 return 1;
2407}
2408
2409static void s5p_jpeg_job_abort(void *priv)
2410{
2411}
2412
2413static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
2414 .device_run = s5p_jpeg_device_run,
2415 .job_ready = s5p_jpeg_job_ready,
2416 .job_abort = s5p_jpeg_job_abort,
3246fdaa
JA
2417};
2418
2419static struct v4l2_m2m_ops exynos3250_jpeg_m2m_ops = {
2420 .device_run = exynos3250_jpeg_device_run,
2421 .job_ready = s5p_jpeg_job_ready,
2422 .job_abort = s5p_jpeg_job_abort,
2423};
2424
bf689bb8 2425static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = {
80529ae5
JA
2426 .device_run = exynos4_jpeg_device_run,
2427 .job_ready = s5p_jpeg_job_ready,
2428 .job_abort = s5p_jpeg_job_abort,
bb677f3a
AP
2429};
2430
2431/*
2432 * ============================================================================
2433 * Queue operations
2434 * ============================================================================
2435 */
2436
719c174e 2437static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
719c174e 2438 unsigned int *nbuffers, unsigned int *nplanes,
36c0f8b3 2439 unsigned int sizes[], struct device *alloc_devs[])
bb677f3a
AP
2440{
2441 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
2442 struct s5p_jpeg_q_data *q_data = NULL;
2443 unsigned int size, count = *nbuffers;
2444
2445 q_data = get_q_data(ctx, vq->type);
2446 BUG_ON(q_data == NULL);
2447
2448 size = q_data->size;
2449
2450 /*
2451 * header is parsed during decoding and parsed information stored
2452 * in the context so we do not allow another buffer to overwrite it
2453 */
2454 if (ctx->mode == S5P_JPEG_DECODE)
2455 count = 1;
2456
2457 *nbuffers = count;
2458 *nplanes = 1;
2459 sizes[0] = size;
bb677f3a
AP
2460
2461 return 0;
2462}
2463
2464static 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
2484static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
2485{
2d700715 2486 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
bb677f3a
AP
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,
f8433962 2495 vb2_get_plane_payload(vb, 0)), ctx);
bb677f3a
AP
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;
6c96dbbc
AP
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;
bb677f3a
AP
2515
2516 q_data = &ctx->cap_q;
2517 q_data->w = tmp.w;
2518 q_data->h = tmp.h;
bb677f3a 2519 }
bb677f3a 2520
2d700715 2521 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
bb677f3a
AP
2522}
2523
2524static 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
e37559b2 2534static void s5p_jpeg_stop_streaming(struct vb2_queue *q)
bb677f3a
AP
2535{
2536 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
2537
2538 pm_runtime_put(ctx->jpeg->dev);
bb677f3a
AP
2539}
2540
2541static 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,
718cf4a9
SN
2545 .wait_prepare = vb2_ops_wait_prepare,
2546 .wait_finish = vb2_ops_wait_finish,
bb677f3a
AP
2547 .start_streaming = s5p_jpeg_start_streaming,
2548 .stop_streaming = s5p_jpeg_stop_streaming,
2549};
2550
2551static 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
bb677f3a
AP
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;
ade48681 2563 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
718cf4a9 2564 src_vq->lock = &ctx->jpeg->lock;
c781e4a5 2565 src_vq->dev = ctx->jpeg->dev;
bb677f3a
AP
2566
2567 ret = vb2_queue_init(src_vq);
2568 if (ret)
2569 return ret;
2570
bb677f3a
AP
2571 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2572 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
2573 dst_vq->drv_priv = ctx;
2574 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2575 dst_vq->ops = &s5p_jpeg_qops;
2576 dst_vq->mem_ops = &vb2_dma_contig_memops;
ade48681 2577 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
718cf4a9 2578 dst_vq->lock = &ctx->jpeg->lock;
c781e4a5 2579 dst_vq->dev = ctx->jpeg->dev;
bb677f3a
AP
2580
2581 return vb2_queue_init(dst_vq);
2582}
2583
2584/*
2585 * ============================================================================
2586 * ISR
2587 * ============================================================================
2588 */
2589
2590static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
2591{
2592 struct s5p_jpeg *jpeg = dev_id;
2593 struct s5p_jpeg_ctx *curr_ctx;
2d700715 2594 struct vb2_v4l2_buffer *src_buf, *dst_buf;
bb677f3a
AP
2595 unsigned long payload_size = 0;
2596 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
2597 bool enc_jpeg_too_large = false;
2598 bool timer_elapsed = false;
2599 bool op_completed = false;
2600
15f4bc3b
SN
2601 spin_lock(&jpeg->slock);
2602
bb677f3a
AP
2603 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2604
718cf4a9
SN
2605 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2606 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
bb677f3a
AP
2607
2608 if (curr_ctx->mode == S5P_JPEG_ENCODE)
9f7b62d9
JA
2609 enc_jpeg_too_large = s5p_jpeg_enc_stream_stat(jpeg->regs);
2610 timer_elapsed = s5p_jpeg_timer_stat(jpeg->regs);
2611 op_completed = s5p_jpeg_result_stat_ok(jpeg->regs);
bb677f3a 2612 if (curr_ctx->mode == S5P_JPEG_DECODE)
9f7b62d9
JA
2613 op_completed = op_completed &&
2614 s5p_jpeg_stream_stat_ok(jpeg->regs);
bb677f3a
AP
2615
2616 if (enc_jpeg_too_large) {
2617 state = VB2_BUF_STATE_ERROR;
9f7b62d9 2618 s5p_jpeg_clear_enc_stream_stat(jpeg->regs);
bb677f3a
AP
2619 } else if (timer_elapsed) {
2620 state = VB2_BUF_STATE_ERROR;
9f7b62d9 2621 s5p_jpeg_clear_timer_stat(jpeg->regs);
bb677f3a
AP
2622 } else if (!op_completed) {
2623 state = VB2_BUF_STATE_ERROR;
2624 } else {
9f7b62d9 2625 payload_size = s5p_jpeg_compressed_size(jpeg->regs);
bb677f3a
AP
2626 }
2627
2d700715 2628 dst_buf->timecode = src_buf->timecode;
d6dd645e 2629 dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
2d700715
JS
2630 dst_buf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
2631 dst_buf->flags |=
2632 src_buf->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
aca326ae 2633
bb677f3a
AP
2634 v4l2_m2m_buf_done(src_buf, state);
2635 if (curr_ctx->mode == S5P_JPEG_ENCODE)
2d700715 2636 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size);
bb677f3a 2637 v4l2_m2m_buf_done(dst_buf, state);
718cf4a9 2638 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
bb677f3a 2639
9f7b62d9 2640 curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs);
15f4bc3b 2641 spin_unlock(&jpeg->slock);
fb6f8c02 2642
9f7b62d9 2643 s5p_jpeg_clear_int(jpeg->regs);
bb677f3a
AP
2644
2645 return IRQ_HANDLED;
2646}
2647
80529ae5
JA
2648static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
2649{
2650 unsigned int int_status;
2d700715 2651 struct vb2_v4l2_buffer *src_vb, *dst_vb;
80529ae5
JA
2652 struct s5p_jpeg *jpeg = priv;
2653 struct s5p_jpeg_ctx *curr_ctx;
2654 unsigned long payload_size = 0;
2655
2656 spin_lock(&jpeg->slock);
2657
2658 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2659
2660 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2661 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2662
2663 int_status = exynos4_jpeg_get_int_status(jpeg->regs);
2664
2665 if (int_status) {
2666 switch (int_status & 0x1f) {
2667 case 0x1:
2668 jpeg->irq_ret = ERR_PROT;
2669 break;
2670 case 0x2:
2671 jpeg->irq_ret = OK_ENC_OR_DEC;
2672 break;
2673 case 0x4:
2674 jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
2675 break;
2676 case 0x8:
2677 jpeg->irq_ret = ERR_MULTI_SCAN;
2678 break;
2679 case 0x10:
2680 jpeg->irq_ret = ERR_FRAME;
2681 break;
2682 default:
2683 jpeg->irq_ret = ERR_UNKNOWN;
2684 break;
2685 }
2686 } else {
2687 jpeg->irq_ret = ERR_UNKNOWN;
2688 }
2689
2690 if (jpeg->irq_ret == OK_ENC_OR_DEC) {
2691 if (curr_ctx->mode == S5P_JPEG_ENCODE) {
2692 payload_size = exynos4_jpeg_get_stream_size(jpeg->regs);
2d700715
JS
2693 vb2_set_plane_payload(&dst_vb->vb2_buf,
2694 0, payload_size);
80529ae5
JA
2695 }
2696 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
2697 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
2698 } else {
2699 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
2700 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
2701 }
2702
2703 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
6c96dbbc
AP
2704 if (jpeg->variant->version == SJPEG_EXYNOS4)
2705 curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
80529ae5
JA
2706
2707 spin_unlock(&jpeg->slock);
2708 return IRQ_HANDLED;
2709}
2710
3246fdaa
JA
2711static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id)
2712{
2713 struct s5p_jpeg *jpeg = dev_id;
2714 struct s5p_jpeg_ctx *curr_ctx;
2d700715 2715 struct vb2_v4l2_buffer *src_buf, *dst_buf;
3246fdaa
JA
2716 unsigned long payload_size = 0;
2717 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
2718 bool interrupt_timeout = false;
2719 u32 irq_status;
2720
2721 spin_lock(&jpeg->slock);
2722
2723 irq_status = exynos3250_jpeg_get_timer_status(jpeg->regs);
2724 if (irq_status & EXYNOS3250_TIMER_INT_STAT) {
2725 exynos3250_jpeg_clear_timer_status(jpeg->regs);
2726 interrupt_timeout = true;
2727 dev_err(jpeg->dev, "Interrupt timeout occurred.\n");
2728 }
2729
2730 irq_status = exynos3250_jpeg_get_int_status(jpeg->regs);
2731 exynos3250_jpeg_clear_int_status(jpeg->regs, irq_status);
2732
2733 jpeg->irq_status |= irq_status;
2734
2735 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2736
2737 if (!curr_ctx)
2738 goto exit_unlock;
2739
2740 if ((irq_status & EXYNOS3250_HEADER_STAT) &&
2741 (curr_ctx->mode == S5P_JPEG_DECODE)) {
2742 exynos3250_jpeg_rstart(jpeg->regs);
2743 goto exit_unlock;
2744 }
2745
2746 if (jpeg->irq_status & (EXYNOS3250_JPEG_DONE |
2747 EXYNOS3250_WDMA_DONE |
2748 EXYNOS3250_RDMA_DONE |
2749 EXYNOS3250_RESULT_STAT))
2750 payload_size = exynos3250_jpeg_compressed_size(jpeg->regs);
2751 else if (interrupt_timeout)
2752 state = VB2_BUF_STATE_ERROR;
2753 else
2754 goto exit_unlock;
2755
2756 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2757 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2758
2d700715 2759 dst_buf->timecode = src_buf->timecode;
d6dd645e 2760 dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
3246fdaa
JA
2761
2762 v4l2_m2m_buf_done(src_buf, state);
2763 if (curr_ctx->mode == S5P_JPEG_ENCODE)
2d700715 2764 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size);
3246fdaa
JA
2765 v4l2_m2m_buf_done(dst_buf, state);
2766 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2767
2768 curr_ctx->subsampling =
2769 exynos3250_jpeg_get_subsampling_mode(jpeg->regs);
2770exit_unlock:
2771 spin_unlock(&jpeg->slock);
2772 return IRQ_HANDLED;
2773}
2774
79a38a8c 2775static void *jpeg_get_drv_data(struct device *dev);
80529ae5 2776
bb677f3a
AP
2777/*
2778 * ============================================================================
2779 * Driver basic infrastructure
2780 * ============================================================================
2781 */
2782
2783static int s5p_jpeg_probe(struct platform_device *pdev)
2784{
2785 struct s5p_jpeg *jpeg;
2786 struct resource *res;
b95a24d6 2787 int i, ret;
bb677f3a
AP
2788
2789 /* JPEG IP abstraction struct */
5b58b954 2790 jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
bb677f3a
AP
2791 if (!jpeg)
2792 return -ENOMEM;
2793
79a38a8c 2794 jpeg->variant = jpeg_get_drv_data(&pdev->dev);
80529ae5 2795
bb677f3a 2796 mutex_init(&jpeg->lock);
15f4bc3b 2797 spin_lock_init(&jpeg->slock);
bb677f3a
AP
2798 jpeg->dev = &pdev->dev;
2799
2800 /* memory-mapped registers */
2801 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
bb677f3a 2802
f23999ec
TR
2803 jpeg->regs = devm_ioremap_resource(&pdev->dev, res);
2804 if (IS_ERR(jpeg->regs))
2805 return PTR_ERR(jpeg->regs);
bb677f3a 2806
bb677f3a
AP
2807 /* interrupt service routine registration */
2808 jpeg->irq = ret = platform_get_irq(pdev, 0);
2809 if (ret < 0) {
2810 dev_err(&pdev->dev, "cannot find IRQ\n");
5b58b954 2811 return ret;
bb677f3a
AP
2812 }
2813
80529ae5
JA
2814 ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
2815 0, dev_name(&pdev->dev), jpeg);
bb677f3a
AP
2816 if (ret) {
2817 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
5b58b954 2818 return ret;
bb677f3a
AP
2819 }
2820
2821 /* clocks */
b95a24d6
MS
2822 for (i = 0; i < jpeg->variant->num_clocks; i++) {
2823 jpeg->clocks[i] = devm_clk_get(&pdev->dev,
2824 jpeg->variant->clk_names[i]);
2825 if (IS_ERR(jpeg->clocks[i])) {
2826 dev_err(&pdev->dev, "failed to get clock: %s\n",
2827 jpeg->variant->clk_names[i]);
2828 return PTR_ERR(jpeg->clocks[i]);
2829 }
bb677f3a 2830 }
3246fdaa 2831
bb677f3a
AP
2832 /* v4l2 device */
2833 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
2834 if (ret) {
2835 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
b95a24d6 2836 return ret;
bb677f3a
AP
2837 }
2838
2839 /* mem2mem device */
bf689bb8 2840 jpeg->m2m_dev = v4l2_m2m_init(jpeg->variant->m2m_ops);
bb677f3a
AP
2841 if (IS_ERR(jpeg->m2m_dev)) {
2842 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
2843 ret = PTR_ERR(jpeg->m2m_dev);
2844 goto device_register_rollback;
2845 }
2846
712b617e 2847 vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
bb677f3a
AP
2848
2849 /* JPEG encoder /dev/videoX node */
2850 jpeg->vfd_encoder = video_device_alloc();
2851 if (!jpeg->vfd_encoder) {
2852 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
2853 ret = -ENOMEM;
c781e4a5 2854 goto m2m_init_rollback;
bb677f3a 2855 }
baaf046d
SWK
2856 snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name),
2857 "%s-enc", S5P_JPEG_M2M_NAME);
bb677f3a
AP
2858 jpeg->vfd_encoder->fops = &s5p_jpeg_fops;
2859 jpeg->vfd_encoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
2860 jpeg->vfd_encoder->minor = -1;
2861 jpeg->vfd_encoder->release = video_device_release;
2862 jpeg->vfd_encoder->lock = &jpeg->lock;
2863 jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev;
954f340f 2864 jpeg->vfd_encoder->vfl_dir = VFL_DIR_M2M;
bb677f3a
AP
2865
2866 ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
2867 if (ret) {
2868 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
7a1d4e7c 2869 video_device_release(jpeg->vfd_encoder);
c781e4a5 2870 goto m2m_init_rollback;
bb677f3a
AP
2871 }
2872
2873 video_set_drvdata(jpeg->vfd_encoder, jpeg);
2874 v4l2_info(&jpeg->v4l2_dev,
2875 "encoder device registered as /dev/video%d\n",
2876 jpeg->vfd_encoder->num);
2877
2878 /* JPEG decoder /dev/videoX node */
2879 jpeg->vfd_decoder = video_device_alloc();
2880 if (!jpeg->vfd_decoder) {
2881 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
2882 ret = -ENOMEM;
2883 goto enc_vdev_register_rollback;
2884 }
baaf046d
SWK
2885 snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name),
2886 "%s-dec", S5P_JPEG_M2M_NAME);
bb677f3a
AP
2887 jpeg->vfd_decoder->fops = &s5p_jpeg_fops;
2888 jpeg->vfd_decoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
2889 jpeg->vfd_decoder->minor = -1;
2890 jpeg->vfd_decoder->release = video_device_release;
2891 jpeg->vfd_decoder->lock = &jpeg->lock;
2892 jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev;
7f7d8fe2 2893 jpeg->vfd_decoder->vfl_dir = VFL_DIR_M2M;
bb677f3a
AP
2894
2895 ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
2896 if (ret) {
2897 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
7a1d4e7c
AP
2898 video_device_release(jpeg->vfd_decoder);
2899 goto enc_vdev_register_rollback;
bb677f3a
AP
2900 }
2901
2902 video_set_drvdata(jpeg->vfd_decoder, jpeg);
2903 v4l2_info(&jpeg->v4l2_dev,
2904 "decoder device registered as /dev/video%d\n",
2905 jpeg->vfd_decoder->num);
2906
2907 /* final statements & power management */
2908 platform_set_drvdata(pdev, jpeg);
2909
2910 pm_runtime_enable(&pdev->dev);
2911
2912 v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
2913
2914 return 0;
2915
bb677f3a
AP
2916enc_vdev_register_rollback:
2917 video_unregister_device(jpeg->vfd_encoder);
2918
bb677f3a
AP
2919m2m_init_rollback:
2920 v4l2_m2m_release(jpeg->m2m_dev);
2921
2922device_register_rollback:
2923 v4l2_device_unregister(&jpeg->v4l2_dev);
2924
bb677f3a
AP
2925 return ret;
2926}
2927
2928static int s5p_jpeg_remove(struct platform_device *pdev)
2929{
2930 struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
b95a24d6 2931 int i;
bb677f3a
AP
2932
2933 pm_runtime_disable(jpeg->dev);
2934
2935 video_unregister_device(jpeg->vfd_decoder);
bb677f3a 2936 video_unregister_device(jpeg->vfd_encoder);
712b617e 2937 vb2_dma_contig_clear_max_seg_size(&pdev->dev);
bb677f3a
AP
2938 v4l2_m2m_release(jpeg->m2m_dev);
2939 v4l2_device_unregister(&jpeg->v4l2_dev);
2940
3246fdaa 2941 if (!pm_runtime_status_suspended(&pdev->dev)) {
b95a24d6
MS
2942 for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
2943 clk_disable_unprepare(jpeg->clocks[i]);
3246fdaa 2944 }
f1347132 2945
bb677f3a
AP
2946 return 0;
2947}
2948
e243c7c1 2949#ifdef CONFIG_PM
bb677f3a
AP
2950static int s5p_jpeg_runtime_suspend(struct device *dev)
2951{
f1347132 2952 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
b95a24d6 2953 int i;
f1347132 2954
b95a24d6
MS
2955 for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
2956 clk_disable_unprepare(jpeg->clocks[i]);
f1347132 2957
bb677f3a
AP
2958 return 0;
2959}
2960
2961static int s5p_jpeg_runtime_resume(struct device *dev)
2962{
2963 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
b3c932a9 2964 unsigned long flags;
b95a24d6 2965 int i, ret;
f1347132 2966
b95a24d6
MS
2967 for (i = 0; i < jpeg->variant->num_clocks; i++) {
2968 ret = clk_prepare_enable(jpeg->clocks[i]);
2969 if (ret) {
2970 while (--i > 0)
2971 clk_disable_unprepare(jpeg->clocks[i]);
3246fdaa 2972 return ret;
b95a24d6 2973 }
3246fdaa
JA
2974 }
2975
b3c932a9
JA
2976 spin_lock_irqsave(&jpeg->slock, flags);
2977
bb677f3a 2978 /*
3246fdaa 2979 * JPEG IP allows storing two Huffman tables for each component.
80529ae5 2980 * We fill table 0 for each component and do this here only
7c15fd4b
AP
2981 * for S5PC210 and Exynos3250 SoCs. Exynos4x12 and Exynos542x SoC
2982 * require programming their Huffman tables each time the encoding
2983 * process is initialized, and thus it is accomplished in the
2984 * device_run callback of m2m_ops.
bb677f3a 2985 */
7c15fd4b 2986 if (!jpeg->variant->htbl_reinit) {
80529ae5
JA
2987 s5p_jpeg_set_hdctbl(jpeg->regs);
2988 s5p_jpeg_set_hdctblg(jpeg->regs);
2989 s5p_jpeg_set_hactbl(jpeg->regs);
2990 s5p_jpeg_set_hactblg(jpeg->regs);
2991 }
31dc0ac0 2992
b3c932a9
JA
2993 spin_unlock_irqrestore(&jpeg->slock, flags);
2994
bb677f3a
AP
2995 return 0;
2996}
e243c7c1 2997#endif /* CONFIG_PM */
bb677f3a 2998
de3767aa 2999#ifdef CONFIG_PM_SLEEP
f1347132
JA
3000static int s5p_jpeg_suspend(struct device *dev)
3001{
3002 if (pm_runtime_suspended(dev))
3003 return 0;
3004
3005 return s5p_jpeg_runtime_suspend(dev);
3006}
3007
3008static int s5p_jpeg_resume(struct device *dev)
3009{
3010 if (pm_runtime_suspended(dev))
3011 return 0;
3012
3013 return s5p_jpeg_runtime_resume(dev);
3014}
de3767aa 3015#endif
f1347132 3016
bb677f3a 3017static const struct dev_pm_ops s5p_jpeg_pm_ops = {
f1347132
JA
3018 SET_SYSTEM_SLEEP_PM_OPS(s5p_jpeg_suspend, s5p_jpeg_resume)
3019 SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume, NULL)
bb677f3a
AP
3020};
3021
80529ae5
JA
3022static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
3023 .version = SJPEG_S5P,
3024 .jpeg_irq = s5p_jpeg_irq,
bf689bb8 3025 .m2m_ops = &s5p_jpeg_m2m_ops,
b245168c 3026 .fmt_ver_flag = SJPEG_FMT_FLAG_S5P,
b95a24d6
MS
3027 .clk_names = {"jpeg"},
3028 .num_clocks = 1,
f7074ab3 3029};
80529ae5 3030
3246fdaa
JA
3031static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = {
3032 .version = SJPEG_EXYNOS3250,
3033 .jpeg_irq = exynos3250_jpeg_irq,
3034 .m2m_ops = &exynos3250_jpeg_m2m_ops,
3035 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250,
7c15fd4b 3036 .hw3250_compat = 1,
b95a24d6
MS
3037 .clk_names = {"jpeg", "sclk"},
3038 .num_clocks = 2,
3246fdaa
JA
3039};
3040
80529ae5
JA
3041static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
3042 .version = SJPEG_EXYNOS4,
3043 .jpeg_irq = exynos4_jpeg_irq,
bf689bb8 3044 .m2m_ops = &exynos4_jpeg_m2m_ops,
b245168c 3045 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4,
7c15fd4b 3046 .htbl_reinit = 1,
b95a24d6
MS
3047 .clk_names = {"jpeg"},
3048 .num_clocks = 1,
6c96dbbc 3049 .hw_ex4_compat = 1,
7c15fd4b
AP
3050};
3051
3052static struct s5p_jpeg_variant exynos5420_jpeg_drvdata = {
3053 .version = SJPEG_EXYNOS5420,
3054 .jpeg_irq = exynos3250_jpeg_irq, /* intentionally 3250 */
3055 .m2m_ops = &exynos3250_jpeg_m2m_ops, /* intentionally 3250 */
3056 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250, /* intentionally 3250 */
3057 .hw3250_compat = 1,
3058 .htbl_reinit = 1,
b95a24d6
MS
3059 .clk_names = {"jpeg"},
3060 .num_clocks = 1,
80529ae5
JA
3061};
3062
6c96dbbc
AP
3063static struct s5p_jpeg_variant exynos5433_jpeg_drvdata = {
3064 .version = SJPEG_EXYNOS5433,
3065 .jpeg_irq = exynos4_jpeg_irq,
3066 .m2m_ops = &exynos4_jpeg_m2m_ops,
3067 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4,
3068 .htbl_reinit = 1,
3069 .clk_names = {"pclk", "aclk", "aclk_xiu", "sclk"},
3070 .num_clocks = 4,
3071 .hw_ex4_compat = 1,
3072};
3073
80529ae5
JA
3074static const struct of_device_id samsung_jpeg_match[] = {
3075 {
3076 .compatible = "samsung,s5pv210-jpeg",
3077 .data = &s5p_jpeg_drvdata,
3246fdaa
JA
3078 }, {
3079 .compatible = "samsung,exynos3250-jpeg",
3080 .data = &exynos3250_jpeg_drvdata,
80529ae5
JA
3081 }, {
3082 .compatible = "samsung,exynos4210-jpeg",
3246fdaa 3083 .data = &exynos4_jpeg_drvdata,
80529ae5
JA
3084 }, {
3085 .compatible = "samsung,exynos4212-jpeg",
3086 .data = &exynos4_jpeg_drvdata,
7c15fd4b
AP
3087 }, {
3088 .compatible = "samsung,exynos5420-jpeg",
3089 .data = &exynos5420_jpeg_drvdata,
6c96dbbc
AP
3090 }, {
3091 .compatible = "samsung,exynos5433-jpeg",
3092 .data = &exynos5433_jpeg_drvdata,
80529ae5
JA
3093 },
3094 {},
3095};
3096
3097MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
3098
79a38a8c 3099static void *jpeg_get_drv_data(struct device *dev)
80529ae5
JA
3100{
3101 struct s5p_jpeg_variant *driver_data = NULL;
3102 const struct of_device_id *match;
3103
79a38a8c
JA
3104 if (!IS_ENABLED(CONFIG_OF) || !dev->of_node)
3105 return &s5p_jpeg_drvdata;
3106
3107 match = of_match_node(samsung_jpeg_match, dev->of_node);
3108
80529ae5
JA
3109 if (match)
3110 driver_data = (struct s5p_jpeg_variant *)match->data;
3111
3112 return driver_data;
3113}
f7074ab3 3114
bb677f3a
AP
3115static struct platform_driver s5p_jpeg_driver = {
3116 .probe = s5p_jpeg_probe,
3117 .remove = s5p_jpeg_remove,
3118 .driver = {
80529ae5 3119 .of_match_table = of_match_ptr(samsung_jpeg_match),
80529ae5
JA
3120 .name = S5P_JPEG_M2M_NAME,
3121 .pm = &s5p_jpeg_pm_ops,
bb677f3a
AP
3122 },
3123};
3124
87e94294 3125module_platform_driver(s5p_jpeg_driver);
bb677f3a
AP
3126
3127MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
80529ae5 3128MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
bb677f3a
AP
3129MODULE_DESCRIPTION("Samsung JPEG codec driver");
3130MODULE_LICENSE("GPL");
This page took 0.411216 seconds and 5 git commands to generate.