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