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