PM / sleep: Asynchronous threads for suspend_noirq
[linux/fpc-iii.git] / drivers / media / platform / s5p-jpeg / jpeg-core.c
blob7d68d0b9966aa7774edfa1ccce40100768632bab
1 /* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c
3 * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
7 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
14 #include <linux/clk.h>
15 #include <linux/err.h>
16 #include <linux/gfp.h>
17 #include <linux/interrupt.h>
18 #include <linux/io.h>
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/of.h>
22 #include <linux/platform_device.h>
23 #include <linux/pm_runtime.h>
24 #include <linux/slab.h>
25 #include <linux/spinlock.h>
26 #include <linux/string.h>
27 #include <media/v4l2-mem2mem.h>
28 #include <media/v4l2-ioctl.h>
29 #include <media/videobuf2-core.h>
30 #include <media/videobuf2-dma-contig.h>
32 #include "jpeg-core.h"
33 #include "jpeg-hw-s5p.h"
34 #include "jpeg-hw-exynos4.h"
35 #include "jpeg-regs.h"
37 static struct s5p_jpeg_fmt sjpeg_formats[] = {
39 .name = "JPEG JFIF",
40 .fourcc = V4L2_PIX_FMT_JPEG,
41 .flags = SJPEG_FMT_FLAG_ENC_CAPTURE |
42 SJPEG_FMT_FLAG_DEC_OUTPUT |
43 SJPEG_FMT_FLAG_S5P |
44 SJPEG_FMT_FLAG_EXYNOS4,
47 .name = "YUV 4:2:2 packed, YCbYCr",
48 .fourcc = V4L2_PIX_FMT_YUYV,
49 .depth = 16,
50 .colplanes = 1,
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,
60 .name = "YUV 4:2:2 packed, YCbYCr",
61 .fourcc = V4L2_PIX_FMT_YUYV,
62 .depth = 16,
63 .colplanes = 1,
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,
73 .name = "YUV 4:2:2 packed, YCrYCb",
74 .fourcc = V4L2_PIX_FMT_YVYU,
75 .depth = 16,
76 .colplanes = 1,
77 .h_align = 1,
78 .v_align = 0,
79 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
80 SJPEG_FMT_FLAG_DEC_CAPTURE |
81 SJPEG_FMT_FLAG_EXYNOS4 |
82 SJPEG_FMT_NON_RGB,
83 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
86 .name = "RGB565",
87 .fourcc = V4L2_PIX_FMT_RGB565,
88 .depth = 16,
89 .colplanes = 1,
90 .h_align = 0,
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_RGB,
96 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
99 .name = "RGB565",
100 .fourcc = V4L2_PIX_FMT_RGB565,
101 .depth = 16,
102 .colplanes = 1,
103 .h_align = 0,
104 .v_align = 0,
105 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
106 SJPEG_FMT_FLAG_S5P |
107 SJPEG_FMT_RGB,
108 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
111 .name = "ARGB8888, 32 bpp",
112 .fourcc = V4L2_PIX_FMT_RGB32,
113 .depth = 32,
114 .colplanes = 1,
115 .h_align = 0,
116 .v_align = 0,
117 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
118 SJPEG_FMT_FLAG_DEC_CAPTURE |
119 SJPEG_FMT_FLAG_EXYNOS4 |
120 SJPEG_FMT_RGB,
121 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
124 .name = "YUV 4:4:4 planar, Y/CbCr",
125 .fourcc = V4L2_PIX_FMT_NV24,
126 .depth = 24,
127 .colplanes = 2,
128 .h_align = 0,
129 .v_align = 0,
130 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
131 SJPEG_FMT_FLAG_DEC_CAPTURE |
132 SJPEG_FMT_FLAG_EXYNOS4 |
133 SJPEG_FMT_NON_RGB,
134 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
137 .name = "YUV 4:4:4 planar, Y/CrCb",
138 .fourcc = V4L2_PIX_FMT_NV42,
139 .depth = 24,
140 .colplanes = 2,
141 .h_align = 0,
142 .v_align = 0,
143 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
144 SJPEG_FMT_FLAG_DEC_CAPTURE |
145 SJPEG_FMT_FLAG_EXYNOS4 |
146 SJPEG_FMT_NON_RGB,
147 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
150 .name = "YUV 4:2:2 planar, Y/CrCb",
151 .fourcc = V4L2_PIX_FMT_NV61,
152 .depth = 16,
153 .colplanes = 2,
154 .h_align = 1,
155 .v_align = 0,
156 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
157 SJPEG_FMT_FLAG_DEC_CAPTURE |
158 SJPEG_FMT_FLAG_EXYNOS4 |
159 SJPEG_FMT_NON_RGB,
160 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
163 .name = "YUV 4:2:2 planar, Y/CbCr",
164 .fourcc = V4L2_PIX_FMT_NV16,
165 .depth = 16,
166 .colplanes = 2,
167 .h_align = 1,
168 .v_align = 0,
169 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
170 SJPEG_FMT_FLAG_DEC_CAPTURE |
171 SJPEG_FMT_FLAG_EXYNOS4 |
172 SJPEG_FMT_NON_RGB,
173 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
176 .name = "YUV 4:2:0 planar, Y/CbCr",
177 .fourcc = V4L2_PIX_FMT_NV12,
178 .depth = 12,
179 .colplanes = 2,
180 .h_align = 1,
181 .v_align = 1,
182 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
183 SJPEG_FMT_FLAG_DEC_CAPTURE |
184 SJPEG_FMT_FLAG_EXYNOS4 |
185 SJPEG_FMT_NON_RGB,
186 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
189 .name = "YUV 4:2:0 planar, Y/CbCr",
190 .fourcc = V4L2_PIX_FMT_NV12,
191 .depth = 12,
192 .colplanes = 2,
193 .h_align = 4,
194 .v_align = 4,
195 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
196 SJPEG_FMT_FLAG_DEC_CAPTURE |
197 SJPEG_FMT_FLAG_S5P |
198 SJPEG_FMT_NON_RGB,
199 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
202 .name = "YUV 4:2:0 planar, Y/CrCb",
203 .fourcc = V4L2_PIX_FMT_NV21,
204 .depth = 12,
205 .colplanes = 2,
206 .h_align = 1,
207 .v_align = 1,
208 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
209 SJPEG_FMT_FLAG_DEC_CAPTURE |
210 SJPEG_FMT_FLAG_EXYNOS4 |
211 SJPEG_FMT_NON_RGB,
212 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
215 .name = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
216 .fourcc = V4L2_PIX_FMT_YUV420,
217 .depth = 12,
218 .colplanes = 3,
219 .h_align = 1,
220 .v_align = 1,
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_420,
228 .name = "Gray",
229 .fourcc = V4L2_PIX_FMT_GREY,
230 .depth = 8,
231 .colplanes = 1,
232 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
233 SJPEG_FMT_FLAG_DEC_CAPTURE |
234 SJPEG_FMT_FLAG_EXYNOS4 |
235 SJPEG_FMT_NON_RGB,
236 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
239 #define SJPEG_NUM_FORMATS ARRAY_SIZE(sjpeg_formats)
241 static const unsigned char qtbl_luminance[4][64] = {
242 {/*level 0 - high compression quality */
243 20, 16, 25, 39, 50, 46, 62, 68,
244 16, 18, 23, 38, 38, 53, 65, 68,
245 25, 23, 31, 38, 53, 65, 68, 68,
246 39, 38, 38, 53, 65, 68, 68, 68,
247 50, 38, 53, 65, 68, 68, 68, 68,
248 46, 53, 65, 68, 68, 68, 68, 68,
249 62, 65, 68, 68, 68, 68, 68, 68,
250 68, 68, 68, 68, 68, 68, 68, 68
252 {/* level 1 */
253 16, 11, 11, 16, 23, 27, 31, 30,
254 11, 12, 12, 15, 20, 23, 23, 30,
255 11, 12, 13, 16, 23, 26, 35, 47,
256 16, 15, 16, 23, 26, 37, 47, 64,
257 23, 20, 23, 26, 39, 51, 64, 64,
258 27, 23, 26, 37, 51, 64, 64, 64,
259 31, 23, 35, 47, 64, 64, 64, 64,
260 30, 30, 47, 64, 64, 64, 64, 64
262 {/* level 2 */
263 12, 8, 8, 12, 17, 21, 24, 23,
264 8, 9, 9, 11, 15, 19, 18, 23,
265 8, 9, 10, 12, 19, 20, 27, 36,
266 12, 11, 12, 21, 20, 28, 36, 53,
267 17, 15, 19, 20, 30, 39, 51, 59,
268 21, 19, 20, 28, 39, 51, 59, 59,
269 24, 18, 27, 36, 51, 59, 59, 59,
270 23, 23, 36, 53, 59, 59, 59, 59
272 {/* level 3 - low compression quality */
273 8, 6, 6, 8, 12, 14, 16, 17,
274 6, 6, 6, 8, 10, 13, 12, 15,
275 6, 6, 7, 8, 13, 14, 18, 24,
276 8, 8, 8, 14, 13, 19, 24, 35,
277 12, 10, 13, 13, 20, 26, 34, 39,
278 14, 13, 14, 19, 26, 34, 39, 39,
279 16, 12, 18, 24, 34, 39, 39, 39,
280 17, 15, 24, 35, 39, 39, 39, 39
284 static const unsigned char qtbl_chrominance[4][64] = {
285 {/*level 0 - high compression quality */
286 21, 25, 32, 38, 54, 68, 68, 68,
287 25, 28, 24, 38, 54, 68, 68, 68,
288 32, 24, 32, 43, 66, 68, 68, 68,
289 38, 38, 43, 53, 68, 68, 68, 68,
290 54, 54, 66, 68, 68, 68, 68, 68,
291 68, 68, 68, 68, 68, 68, 68, 68,
292 68, 68, 68, 68, 68, 68, 68, 68,
293 68, 68, 68, 68, 68, 68, 68, 68
295 {/* level 1 */
296 17, 15, 17, 21, 20, 26, 38, 48,
297 15, 19, 18, 17, 20, 26, 35, 43,
298 17, 18, 20, 22, 26, 30, 46, 53,
299 21, 17, 22, 28, 30, 39, 53, 64,
300 20, 20, 26, 30, 39, 48, 64, 64,
301 26, 26, 30, 39, 48, 63, 64, 64,
302 38, 35, 46, 53, 64, 64, 64, 64,
303 48, 43, 53, 64, 64, 64, 64, 64
305 {/* level 2 */
306 13, 11, 13, 16, 20, 20, 29, 37,
307 11, 14, 14, 14, 16, 20, 26, 32,
308 13, 14, 15, 17, 20, 23, 35, 40,
309 16, 14, 17, 21, 23, 30, 40, 50,
310 20, 16, 20, 23, 30, 37, 50, 59,
311 20, 20, 23, 30, 37, 48, 59, 59,
312 29, 26, 35, 40, 50, 59, 59, 59,
313 37, 32, 40, 50, 59, 59, 59, 59
315 {/* level 3 - low compression quality */
316 9, 8, 9, 11, 14, 17, 19, 24,
317 8, 10, 9, 11, 14, 13, 17, 22,
318 9, 9, 13, 14, 13, 15, 23, 26,
319 11, 11, 14, 14, 15, 20, 26, 33,
320 14, 14, 13, 15, 20, 24, 33, 39,
321 17, 13, 15, 20, 24, 32, 39, 39,
322 19, 17, 23, 26, 33, 39, 39, 39,
323 24, 22, 26, 33, 39, 39, 39, 39
327 static const unsigned char hdctbl0[16] = {
328 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
331 static const unsigned char hdctblg0[12] = {
332 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
334 static const unsigned char hactbl0[16] = {
335 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
337 static const unsigned char hactblg0[162] = {
338 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
339 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
340 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
341 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
342 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
343 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
344 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
345 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
346 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
347 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
348 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
349 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
350 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
351 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
352 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
353 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
354 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
355 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
356 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
357 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
358 0xf9, 0xfa
362 * Fourcc downgrade schema lookup tables for 422 and 420
363 * chroma subsampling - fourcc on each position maps on the
364 * fourcc from the table fourcc_to_dwngrd_schema_id which allows
365 * to get the most suitable fourcc counterpart for the given
366 * downgraded subsampling property.
368 static const u32 subs422_fourcc_dwngrd_schema[] = {
369 V4L2_PIX_FMT_NV16,
370 V4L2_PIX_FMT_NV61,
373 static const u32 subs420_fourcc_dwngrd_schema[] = {
374 V4L2_PIX_FMT_NV12,
375 V4L2_PIX_FMT_NV21,
376 V4L2_PIX_FMT_NV12,
377 V4L2_PIX_FMT_NV21,
378 V4L2_PIX_FMT_NV12,
379 V4L2_PIX_FMT_NV21,
380 V4L2_PIX_FMT_GREY,
381 V4L2_PIX_FMT_GREY,
382 V4L2_PIX_FMT_GREY,
383 V4L2_PIX_FMT_GREY,
387 * Lookup table for translation of a fourcc to the position
388 * of its downgraded counterpart in the *fourcc_dwngrd_schema
389 * tables.
391 static const u32 fourcc_to_dwngrd_schema_id[] = {
392 V4L2_PIX_FMT_NV24,
393 V4L2_PIX_FMT_NV42,
394 V4L2_PIX_FMT_NV16,
395 V4L2_PIX_FMT_NV61,
396 V4L2_PIX_FMT_YUYV,
397 V4L2_PIX_FMT_YVYU,
398 V4L2_PIX_FMT_NV12,
399 V4L2_PIX_FMT_NV21,
400 V4L2_PIX_FMT_YUV420,
401 V4L2_PIX_FMT_GREY,
404 static int s5p_jpeg_get_dwngrd_sch_id_by_fourcc(u32 fourcc)
406 int i;
407 for (i = 0; i < ARRAY_SIZE(fourcc_to_dwngrd_schema_id); ++i) {
408 if (fourcc_to_dwngrd_schema_id[i] == fourcc)
409 return i;
412 return -EINVAL;
415 static int s5p_jpeg_adjust_fourcc_to_subsampling(
416 enum v4l2_jpeg_chroma_subsampling subs,
417 u32 in_fourcc,
418 u32 *out_fourcc,
419 struct s5p_jpeg_ctx *ctx)
421 int dwngrd_sch_id;
423 if (ctx->subsampling != V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
424 dwngrd_sch_id =
425 s5p_jpeg_get_dwngrd_sch_id_by_fourcc(in_fourcc);
426 if (dwngrd_sch_id < 0)
427 return -EINVAL;
430 switch (ctx->subsampling) {
431 case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
432 *out_fourcc = V4L2_PIX_FMT_GREY;
433 break;
434 case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
435 if (dwngrd_sch_id >
436 ARRAY_SIZE(subs420_fourcc_dwngrd_schema) - 1)
437 return -EINVAL;
438 *out_fourcc = subs420_fourcc_dwngrd_schema[dwngrd_sch_id];
439 break;
440 case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
441 if (dwngrd_sch_id >
442 ARRAY_SIZE(subs422_fourcc_dwngrd_schema) - 1)
443 return -EINVAL;
444 *out_fourcc = subs422_fourcc_dwngrd_schema[dwngrd_sch_id];
445 break;
446 default:
447 *out_fourcc = V4L2_PIX_FMT_GREY;
448 break;
451 return 0;
454 static int exynos4x12_decoded_subsampling[] = {
455 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
456 V4L2_JPEG_CHROMA_SUBSAMPLING_444,
457 V4L2_JPEG_CHROMA_SUBSAMPLING_422,
458 V4L2_JPEG_CHROMA_SUBSAMPLING_420,
461 static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
463 return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
466 static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
468 return container_of(fh, struct s5p_jpeg_ctx, fh);
471 static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
473 WARN_ON(ctx->subsampling > 3);
475 if (ctx->jpeg->variant->version == SJPEG_S5P) {
476 if (ctx->subsampling > 2)
477 return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
478 return ctx->subsampling;
479 } else {
480 if (ctx->subsampling > 2)
481 return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
482 return exynos4x12_decoded_subsampling[ctx->subsampling];
486 static inline void s5p_jpeg_set_qtbl(void __iomem *regs,
487 const unsigned char *qtbl,
488 unsigned long tab, int len)
490 int i;
492 for (i = 0; i < len; i++)
493 writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
496 static inline void s5p_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
498 /* this driver fills quantisation table 0 with data for luma */
499 s5p_jpeg_set_qtbl(regs, qtbl_luminance[quality],
500 S5P_JPG_QTBL_CONTENT(0),
501 ARRAY_SIZE(qtbl_luminance[quality]));
504 static inline void s5p_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
506 /* this driver fills quantisation table 1 with data for chroma */
507 s5p_jpeg_set_qtbl(regs, qtbl_chrominance[quality],
508 S5P_JPG_QTBL_CONTENT(1),
509 ARRAY_SIZE(qtbl_chrominance[quality]));
512 static inline void s5p_jpeg_set_htbl(void __iomem *regs,
513 const unsigned char *htbl,
514 unsigned long tab, int len)
516 int i;
518 for (i = 0; i < len; i++)
519 writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
522 static inline void s5p_jpeg_set_hdctbl(void __iomem *regs)
524 /* this driver fills table 0 for this component */
525 s5p_jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0),
526 ARRAY_SIZE(hdctbl0));
529 static inline void s5p_jpeg_set_hdctblg(void __iomem *regs)
531 /* this driver fills table 0 for this component */
532 s5p_jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0),
533 ARRAY_SIZE(hdctblg0));
536 static inline void s5p_jpeg_set_hactbl(void __iomem *regs)
538 /* this driver fills table 0 for this component */
539 s5p_jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0),
540 ARRAY_SIZE(hactbl0));
543 static inline void s5p_jpeg_set_hactblg(void __iomem *regs)
545 /* this driver fills table 0 for this component */
546 s5p_jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0),
547 ARRAY_SIZE(hactblg0));
550 static inline void exynos4_jpeg_set_tbl(void __iomem *regs,
551 const unsigned char *tbl,
552 unsigned long tab, int len)
554 int i;
555 unsigned int dword;
557 for (i = 0; i < len; i += 4) {
558 dword = tbl[i] |
559 (tbl[i + 1] << 8) |
560 (tbl[i + 2] << 16) |
561 (tbl[i + 3] << 24);
562 writel(dword, regs + tab + i);
566 static inline void exynos4_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
568 /* this driver fills quantisation table 0 with data for luma */
569 exynos4_jpeg_set_tbl(regs, qtbl_luminance[quality],
570 EXYNOS4_QTBL_CONTENT(0),
571 ARRAY_SIZE(qtbl_luminance[quality]));
574 static inline void exynos4_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
576 /* this driver fills quantisation table 1 with data for chroma */
577 exynos4_jpeg_set_tbl(regs, qtbl_chrominance[quality],
578 EXYNOS4_QTBL_CONTENT(1),
579 ARRAY_SIZE(qtbl_chrominance[quality]));
582 void exynos4_jpeg_set_huff_tbl(void __iomem *base)
584 exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCLL,
585 ARRAY_SIZE(hdctbl0));
586 exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCCL,
587 ARRAY_SIZE(hdctbl0));
588 exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCLV,
589 ARRAY_SIZE(hdctblg0));
590 exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCCV,
591 ARRAY_SIZE(hdctblg0));
592 exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACLL,
593 ARRAY_SIZE(hactbl0));
594 exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACCL,
595 ARRAY_SIZE(hactbl0));
596 exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACLV,
597 ARRAY_SIZE(hactblg0));
598 exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACCV,
599 ARRAY_SIZE(hactblg0));
603 * ============================================================================
604 * Device file operations
605 * ============================================================================
608 static int queue_init(void *priv, struct vb2_queue *src_vq,
609 struct vb2_queue *dst_vq);
610 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
611 __u32 pixelformat, unsigned int fmt_type);
612 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
614 static int s5p_jpeg_open(struct file *file)
616 struct s5p_jpeg *jpeg = video_drvdata(file);
617 struct video_device *vfd = video_devdata(file);
618 struct s5p_jpeg_ctx *ctx;
619 struct s5p_jpeg_fmt *out_fmt, *cap_fmt;
620 int ret = 0;
622 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
623 if (!ctx)
624 return -ENOMEM;
626 if (mutex_lock_interruptible(&jpeg->lock)) {
627 ret = -ERESTARTSYS;
628 goto free;
631 v4l2_fh_init(&ctx->fh, vfd);
632 /* Use separate control handler per file handle */
633 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
634 file->private_data = &ctx->fh;
635 v4l2_fh_add(&ctx->fh);
637 ctx->jpeg = jpeg;
638 if (vfd == jpeg->vfd_encoder) {
639 ctx->mode = S5P_JPEG_ENCODE;
640 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB565,
641 FMT_TYPE_OUTPUT);
642 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
643 FMT_TYPE_CAPTURE);
644 } else {
645 ctx->mode = S5P_JPEG_DECODE;
646 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
647 FMT_TYPE_OUTPUT);
648 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV,
649 FMT_TYPE_CAPTURE);
652 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
653 if (IS_ERR(ctx->fh.m2m_ctx)) {
654 ret = PTR_ERR(ctx->fh.m2m_ctx);
655 goto error;
658 ctx->out_q.fmt = out_fmt;
659 ctx->cap_q.fmt = cap_fmt;
661 ret = s5p_jpeg_controls_create(ctx);
662 if (ret < 0)
663 goto error;
665 mutex_unlock(&jpeg->lock);
666 return 0;
668 error:
669 v4l2_fh_del(&ctx->fh);
670 v4l2_fh_exit(&ctx->fh);
671 mutex_unlock(&jpeg->lock);
672 free:
673 kfree(ctx);
674 return ret;
677 static int s5p_jpeg_release(struct file *file)
679 struct s5p_jpeg *jpeg = video_drvdata(file);
680 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
682 mutex_lock(&jpeg->lock);
683 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
684 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
685 v4l2_fh_del(&ctx->fh);
686 v4l2_fh_exit(&ctx->fh);
687 kfree(ctx);
688 mutex_unlock(&jpeg->lock);
690 return 0;
693 static const struct v4l2_file_operations s5p_jpeg_fops = {
694 .owner = THIS_MODULE,
695 .open = s5p_jpeg_open,
696 .release = s5p_jpeg_release,
697 .poll = v4l2_m2m_fop_poll,
698 .unlocked_ioctl = video_ioctl2,
699 .mmap = v4l2_m2m_fop_mmap,
703 * ============================================================================
704 * video ioctl operations
705 * ============================================================================
708 static int get_byte(struct s5p_jpeg_buffer *buf)
710 if (buf->curr >= buf->size)
711 return -1;
713 return ((unsigned char *)buf->data)[buf->curr++];
716 static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
718 unsigned int temp;
719 int byte;
721 byte = get_byte(buf);
722 if (byte == -1)
723 return -1;
724 temp = byte << 8;
725 byte = get_byte(buf);
726 if (byte == -1)
727 return -1;
728 *word = (unsigned int)byte | temp;
729 return 0;
732 static void skip(struct s5p_jpeg_buffer *buf, long len)
734 if (len <= 0)
735 return;
737 while (len--)
738 get_byte(buf);
741 static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
742 unsigned long buffer, unsigned long size,
743 struct s5p_jpeg_ctx *ctx)
745 int c, components, notfound;
746 unsigned int height, width, word, subsampling = 0;
747 long length;
748 struct s5p_jpeg_buffer jpeg_buffer;
750 jpeg_buffer.size = size;
751 jpeg_buffer.data = buffer;
752 jpeg_buffer.curr = 0;
754 notfound = 1;
755 while (notfound) {
756 c = get_byte(&jpeg_buffer);
757 if (c == -1)
758 break;
759 if (c != 0xff)
760 continue;
762 c = get_byte(&jpeg_buffer);
763 while (c == 0xff);
764 if (c == -1)
765 break;
766 if (c == 0)
767 continue;
768 length = 0;
769 switch (c) {
770 /* SOF0: baseline JPEG */
771 case SOF0:
772 if (get_word_be(&jpeg_buffer, &word))
773 break;
774 if (get_byte(&jpeg_buffer) == -1)
775 break;
776 if (get_word_be(&jpeg_buffer, &height))
777 break;
778 if (get_word_be(&jpeg_buffer, &width))
779 break;
780 components = get_byte(&jpeg_buffer);
781 if (components == -1)
782 break;
783 notfound = 0;
785 if (components == 1) {
786 subsampling = 0x33;
787 } else {
788 skip(&jpeg_buffer, 1);
789 subsampling = get_byte(&jpeg_buffer);
790 skip(&jpeg_buffer, 1);
793 skip(&jpeg_buffer, components * 2);
794 break;
796 /* skip payload-less markers */
797 case RST ... RST + 7:
798 case SOI:
799 case EOI:
800 case TEM:
801 break;
803 /* skip uninteresting payload markers */
804 default:
805 if (get_word_be(&jpeg_buffer, &word))
806 break;
807 length = (long)word - 2;
808 skip(&jpeg_buffer, length);
809 break;
812 result->w = width;
813 result->h = height;
814 result->size = components;
816 switch (subsampling) {
817 case 0x11:
818 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
819 break;
820 case 0x21:
821 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
822 break;
823 case 0x22:
824 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
825 break;
826 case 0x33:
827 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
828 break;
829 default:
830 return false;
833 return !notfound;
836 static int s5p_jpeg_querycap(struct file *file, void *priv,
837 struct v4l2_capability *cap)
839 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
841 if (ctx->mode == S5P_JPEG_ENCODE) {
842 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder",
843 sizeof(cap->driver));
844 strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
845 sizeof(cap->card));
846 } else {
847 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " decoder",
848 sizeof(cap->driver));
849 strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
850 sizeof(cap->card));
852 cap->bus_info[0] = 0;
854 * This is only a mem-to-mem video device. The capture and output
855 * device capability flags are left only for backward compatibility
856 * and are scheduled for removal.
858 cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M |
859 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT;
860 return 0;
863 static int enum_fmt(struct s5p_jpeg_fmt *sjpeg_formats, int n,
864 struct v4l2_fmtdesc *f, u32 type)
866 int i, num = 0;
868 for (i = 0; i < n; ++i) {
869 if (sjpeg_formats[i].flags & type) {
870 /* index-th format of type type found ? */
871 if (num == f->index)
872 break;
873 /* Correct type but haven't reached our index yet,
874 * just increment per-type index */
875 ++num;
879 /* Format not found */
880 if (i >= n)
881 return -EINVAL;
883 strlcpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
884 f->pixelformat = sjpeg_formats[i].fourcc;
886 return 0;
889 static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
890 struct v4l2_fmtdesc *f)
892 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
894 if (ctx->mode == S5P_JPEG_ENCODE)
895 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
896 SJPEG_FMT_FLAG_ENC_CAPTURE);
898 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
899 SJPEG_FMT_FLAG_DEC_CAPTURE);
902 static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
903 struct v4l2_fmtdesc *f)
905 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
907 if (ctx->mode == S5P_JPEG_ENCODE)
908 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
909 SJPEG_FMT_FLAG_ENC_OUTPUT);
911 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
912 SJPEG_FMT_FLAG_DEC_OUTPUT);
915 static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
916 enum v4l2_buf_type type)
918 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
919 return &ctx->out_q;
920 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
921 return &ctx->cap_q;
923 return NULL;
926 static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
928 struct vb2_queue *vq;
929 struct s5p_jpeg_q_data *q_data = NULL;
930 struct v4l2_pix_format *pix = &f->fmt.pix;
931 struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
933 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
934 if (!vq)
935 return -EINVAL;
937 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
938 ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
939 return -EINVAL;
940 q_data = get_q_data(ct, f->type);
941 BUG_ON(q_data == NULL);
943 pix->width = q_data->w;
944 pix->height = q_data->h;
945 pix->field = V4L2_FIELD_NONE;
946 pix->pixelformat = q_data->fmt->fourcc;
947 pix->bytesperline = 0;
948 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
949 u32 bpl = q_data->w;
950 if (q_data->fmt->colplanes == 1)
951 bpl = (bpl * q_data->fmt->depth) >> 3;
952 pix->bytesperline = bpl;
954 pix->sizeimage = q_data->size;
956 return 0;
959 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
960 u32 pixelformat, unsigned int fmt_type)
962 unsigned int k, fmt_flag, ver_flag;
964 if (ctx->mode == S5P_JPEG_ENCODE)
965 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
966 SJPEG_FMT_FLAG_ENC_OUTPUT :
967 SJPEG_FMT_FLAG_ENC_CAPTURE;
968 else
969 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
970 SJPEG_FMT_FLAG_DEC_OUTPUT :
971 SJPEG_FMT_FLAG_DEC_CAPTURE;
973 if (ctx->jpeg->variant->version == SJPEG_S5P)
974 ver_flag = SJPEG_FMT_FLAG_S5P;
975 else
976 ver_flag = SJPEG_FMT_FLAG_EXYNOS4;
978 for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
979 struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
980 if (fmt->fourcc == pixelformat &&
981 fmt->flags & fmt_flag &&
982 fmt->flags & ver_flag) {
983 return fmt;
987 return NULL;
990 static void jpeg_bound_align_image(u32 *w, unsigned int wmin, unsigned int wmax,
991 unsigned int walign,
992 u32 *h, unsigned int hmin, unsigned int hmax,
993 unsigned int halign)
995 int width, height, w_step, h_step;
997 width = *w;
998 height = *h;
1000 w_step = 1 << walign;
1001 h_step = 1 << halign;
1002 v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
1004 if (*w < width && (*w + w_step) < wmax)
1005 *w += w_step;
1006 if (*h < height && (*h + h_step) < hmax)
1007 *h += h_step;
1011 static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
1012 struct s5p_jpeg_ctx *ctx, int q_type)
1014 struct v4l2_pix_format *pix = &f->fmt.pix;
1016 if (pix->field == V4L2_FIELD_ANY)
1017 pix->field = V4L2_FIELD_NONE;
1018 else if (pix->field != V4L2_FIELD_NONE)
1019 return -EINVAL;
1021 /* V4L2 specification suggests the driver corrects the format struct
1022 * if any of the dimensions is unsupported */
1023 if (q_type == FMT_TYPE_OUTPUT)
1024 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
1025 S5P_JPEG_MAX_WIDTH, 0,
1026 &pix->height, S5P_JPEG_MIN_HEIGHT,
1027 S5P_JPEG_MAX_HEIGHT, 0);
1028 else
1029 jpeg_bound_align_image(&pix->width, S5P_JPEG_MIN_WIDTH,
1030 S5P_JPEG_MAX_WIDTH, fmt->h_align,
1031 &pix->height, S5P_JPEG_MIN_HEIGHT,
1032 S5P_JPEG_MAX_HEIGHT, fmt->v_align);
1034 if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1035 if (pix->sizeimage <= 0)
1036 pix->sizeimage = PAGE_SIZE;
1037 pix->bytesperline = 0;
1038 } else {
1039 u32 bpl = pix->bytesperline;
1041 if (fmt->colplanes > 1 && bpl < pix->width)
1042 bpl = pix->width; /* planar */
1044 if (fmt->colplanes == 1 && /* packed */
1045 (bpl << 3) / fmt->depth < pix->width)
1046 bpl = (pix->width * fmt->depth) >> 3;
1048 pix->bytesperline = bpl;
1049 pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
1052 return 0;
1055 static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
1056 struct v4l2_format *f)
1058 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1059 struct v4l2_pix_format *pix = &f->fmt.pix;
1060 struct s5p_jpeg_fmt *fmt;
1061 int ret;
1063 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1064 FMT_TYPE_CAPTURE);
1065 if (!fmt) {
1066 v4l2_err(&ctx->jpeg->v4l2_dev,
1067 "Fourcc format (0x%08x) invalid.\n",
1068 f->fmt.pix.pixelformat);
1069 return -EINVAL;
1073 * The exynos4x12 device requires resulting YUV image
1074 * subsampling not to be lower than the input jpeg subsampling.
1075 * If this requirement is not met then downgrade the requested
1076 * capture format to the one with subsampling equal to the input jpeg.
1078 if ((ctx->jpeg->variant->version != SJPEG_S5P) &&
1079 (ctx->mode == S5P_JPEG_DECODE) &&
1080 (fmt->flags & SJPEG_FMT_NON_RGB) &&
1081 (fmt->subsampling < ctx->subsampling)) {
1082 ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling,
1083 fmt->fourcc,
1084 &pix->pixelformat,
1085 ctx);
1086 if (ret < 0)
1087 pix->pixelformat = V4L2_PIX_FMT_GREY;
1089 fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1090 FMT_TYPE_CAPTURE);
1093 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
1096 static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
1097 struct v4l2_format *f)
1099 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1100 struct s5p_jpeg_fmt *fmt;
1102 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1103 FMT_TYPE_OUTPUT);
1104 if (!fmt) {
1105 v4l2_err(&ctx->jpeg->v4l2_dev,
1106 "Fourcc format (0x%08x) invalid.\n",
1107 f->fmt.pix.pixelformat);
1108 return -EINVAL;
1111 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
1114 static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
1116 struct vb2_queue *vq;
1117 struct s5p_jpeg_q_data *q_data = NULL;
1118 struct v4l2_pix_format *pix = &f->fmt.pix;
1119 struct v4l2_ctrl *ctrl_subs;
1120 unsigned int f_type;
1122 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1123 if (!vq)
1124 return -EINVAL;
1126 q_data = get_q_data(ct, f->type);
1127 BUG_ON(q_data == NULL);
1129 if (vb2_is_busy(vq)) {
1130 v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
1131 return -EBUSY;
1134 f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
1135 FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
1137 q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
1138 q_data->w = pix->width;
1139 q_data->h = pix->height;
1140 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)
1141 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
1142 else
1143 q_data->size = pix->sizeimage;
1145 if (f_type == FMT_TYPE_OUTPUT) {
1146 ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler,
1147 V4L2_CID_JPEG_CHROMA_SUBSAMPLING);
1148 if (ctrl_subs)
1149 v4l2_ctrl_s_ctrl(ctrl_subs, q_data->fmt->subsampling);
1152 return 0;
1155 static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
1156 struct v4l2_format *f)
1158 int ret;
1160 ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
1161 if (ret)
1162 return ret;
1164 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1167 static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
1168 struct v4l2_format *f)
1170 int ret;
1172 ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
1173 if (ret)
1174 return ret;
1176 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1179 static int s5p_jpeg_g_selection(struct file *file, void *priv,
1180 struct v4l2_selection *s)
1182 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1184 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
1185 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1186 ctx->jpeg->variant->version != SJPEG_S5P)
1187 return -EINVAL;
1189 /* For JPEG blob active == default == bounds */
1190 switch (s->target) {
1191 case V4L2_SEL_TGT_CROP:
1192 case V4L2_SEL_TGT_CROP_BOUNDS:
1193 case V4L2_SEL_TGT_CROP_DEFAULT:
1194 case V4L2_SEL_TGT_COMPOSE:
1195 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1196 s->r.width = ctx->out_q.w;
1197 s->r.height = ctx->out_q.h;
1198 break;
1199 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1200 case V4L2_SEL_TGT_COMPOSE_PADDED:
1201 s->r.width = ctx->cap_q.w;
1202 s->r.height = ctx->cap_q.h;
1203 break;
1204 default:
1205 return -EINVAL;
1207 s->r.left = 0;
1208 s->r.top = 0;
1209 return 0;
1213 * V4L2 controls
1216 static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1218 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1219 struct s5p_jpeg *jpeg = ctx->jpeg;
1220 unsigned long flags;
1222 switch (ctrl->id) {
1223 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1224 spin_lock_irqsave(&jpeg->slock, flags);
1225 ctrl->val = s5p_jpeg_to_user_subsampling(ctx);
1226 spin_unlock_irqrestore(&jpeg->slock, flags);
1227 break;
1230 return 0;
1233 static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl)
1235 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1236 unsigned long flags;
1237 int ret = 0;
1239 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1241 if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING) {
1242 if (ctx->jpeg->variant->version == SJPEG_S5P)
1243 goto error_free;
1245 * The exynos4x12 device requires input raw image fourcc
1246 * to be V4L2_PIX_FMT_GREY if gray jpeg format
1247 * is to be set.
1249 if (ctx->out_q.fmt->fourcc != V4L2_PIX_FMT_GREY &&
1250 ctrl->val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
1251 ret = -EINVAL;
1252 goto error_free;
1255 * The exynos4x12 device requires resulting jpeg subsampling
1256 * not to be lower than the input raw image subsampling.
1258 if (ctx->out_q.fmt->subsampling > ctrl->val)
1259 ctrl->val = ctx->out_q.fmt->subsampling;
1262 error_free:
1263 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1264 return ret;
1267 static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
1269 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1270 unsigned long flags;
1272 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1274 switch (ctrl->id) {
1275 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1276 ctx->compr_quality = ctrl->val;
1277 break;
1278 case V4L2_CID_JPEG_RESTART_INTERVAL:
1279 ctx->restart_interval = ctrl->val;
1280 break;
1281 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1282 ctx->subsampling = ctrl->val;
1283 break;
1286 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1287 return 0;
1290 static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
1291 .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl,
1292 .try_ctrl = s5p_jpeg_try_ctrl,
1293 .s_ctrl = s5p_jpeg_s_ctrl,
1296 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
1298 unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
1299 struct v4l2_ctrl *ctrl;
1300 int ret;
1302 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
1304 if (ctx->mode == S5P_JPEG_ENCODE) {
1305 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1306 V4L2_CID_JPEG_COMPRESSION_QUALITY,
1307 0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
1309 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1310 V4L2_CID_JPEG_RESTART_INTERVAL,
1311 0, 3, 0xffff, 0);
1312 if (ctx->jpeg->variant->version == SJPEG_S5P)
1313 mask = ~0x06; /* 422, 420 */
1316 ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1317 V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
1318 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
1319 V4L2_JPEG_CHROMA_SUBSAMPLING_422);
1321 if (ctx->ctrl_handler.error) {
1322 ret = ctx->ctrl_handler.error;
1323 goto error_free;
1326 if (ctx->mode == S5P_JPEG_DECODE)
1327 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
1328 V4L2_CTRL_FLAG_READ_ONLY;
1330 ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
1331 if (ret < 0)
1332 goto error_free;
1334 return ret;
1336 error_free:
1337 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1338 return ret;
1341 static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
1342 .vidioc_querycap = s5p_jpeg_querycap,
1344 .vidioc_enum_fmt_vid_cap = s5p_jpeg_enum_fmt_vid_cap,
1345 .vidioc_enum_fmt_vid_out = s5p_jpeg_enum_fmt_vid_out,
1347 .vidioc_g_fmt_vid_cap = s5p_jpeg_g_fmt,
1348 .vidioc_g_fmt_vid_out = s5p_jpeg_g_fmt,
1350 .vidioc_try_fmt_vid_cap = s5p_jpeg_try_fmt_vid_cap,
1351 .vidioc_try_fmt_vid_out = s5p_jpeg_try_fmt_vid_out,
1353 .vidioc_s_fmt_vid_cap = s5p_jpeg_s_fmt_vid_cap,
1354 .vidioc_s_fmt_vid_out = s5p_jpeg_s_fmt_vid_out,
1356 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
1357 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
1358 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
1359 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
1361 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
1362 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
1364 .vidioc_g_selection = s5p_jpeg_g_selection,
1368 * ============================================================================
1369 * mem2mem callbacks
1370 * ============================================================================
1373 static void s5p_jpeg_device_run(void *priv)
1375 struct s5p_jpeg_ctx *ctx = priv;
1376 struct s5p_jpeg *jpeg = ctx->jpeg;
1377 struct vb2_buffer *src_buf, *dst_buf;
1378 unsigned long src_addr, dst_addr, flags;
1380 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1382 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1383 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1384 src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
1385 dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
1387 s5p_jpeg_reset(jpeg->regs);
1388 s5p_jpeg_poweron(jpeg->regs);
1389 s5p_jpeg_proc_mode(jpeg->regs, ctx->mode);
1390 if (ctx->mode == S5P_JPEG_ENCODE) {
1391 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
1392 s5p_jpeg_input_raw_mode(jpeg->regs,
1393 S5P_JPEG_RAW_IN_565);
1394 else
1395 s5p_jpeg_input_raw_mode(jpeg->regs,
1396 S5P_JPEG_RAW_IN_422);
1397 s5p_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
1398 s5p_jpeg_dri(jpeg->regs, ctx->restart_interval);
1399 s5p_jpeg_x(jpeg->regs, ctx->out_q.w);
1400 s5p_jpeg_y(jpeg->regs, ctx->out_q.h);
1401 s5p_jpeg_imgadr(jpeg->regs, src_addr);
1402 s5p_jpeg_jpgadr(jpeg->regs, dst_addr);
1404 /* ultimately comes from sizeimage from userspace */
1405 s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
1407 /* JPEG RGB to YCbCr conversion matrix */
1408 s5p_jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
1409 s5p_jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
1410 s5p_jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
1411 s5p_jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
1412 s5p_jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
1413 s5p_jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
1414 s5p_jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
1415 s5p_jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
1416 s5p_jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
1419 * JPEG IP allows storing 4 quantization tables
1420 * We fill table 0 for luma and table 1 for chroma
1422 s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1423 s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1424 /* use table 0 for Y */
1425 s5p_jpeg_qtbl(jpeg->regs, 1, 0);
1426 /* use table 1 for Cb and Cr*/
1427 s5p_jpeg_qtbl(jpeg->regs, 2, 1);
1428 s5p_jpeg_qtbl(jpeg->regs, 3, 1);
1430 /* Y, Cb, Cr use Huffman table 0 */
1431 s5p_jpeg_htbl_ac(jpeg->regs, 1);
1432 s5p_jpeg_htbl_dc(jpeg->regs, 1);
1433 s5p_jpeg_htbl_ac(jpeg->regs, 2);
1434 s5p_jpeg_htbl_dc(jpeg->regs, 2);
1435 s5p_jpeg_htbl_ac(jpeg->regs, 3);
1436 s5p_jpeg_htbl_dc(jpeg->regs, 3);
1437 } else { /* S5P_JPEG_DECODE */
1438 s5p_jpeg_rst_int_enable(jpeg->regs, true);
1439 s5p_jpeg_data_num_int_enable(jpeg->regs, true);
1440 s5p_jpeg_final_mcu_num_int_enable(jpeg->regs, true);
1441 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
1442 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
1443 else
1444 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
1445 s5p_jpeg_jpgadr(jpeg->regs, src_addr);
1446 s5p_jpeg_imgadr(jpeg->regs, dst_addr);
1449 s5p_jpeg_start(jpeg->regs);
1451 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1454 static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
1456 struct s5p_jpeg *jpeg = ctx->jpeg;
1457 struct s5p_jpeg_fmt *fmt;
1458 struct vb2_buffer *vb;
1459 struct s5p_jpeg_addr jpeg_addr;
1460 u32 pix_size, padding_bytes = 0;
1462 pix_size = ctx->cap_q.w * ctx->cap_q.h;
1464 if (ctx->mode == S5P_JPEG_ENCODE) {
1465 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1466 fmt = ctx->out_q.fmt;
1467 if (ctx->out_q.w % 2 && fmt->h_align > 0)
1468 padding_bytes = ctx->out_q.h;
1469 } else {
1470 fmt = ctx->cap_q.fmt;
1471 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1474 jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
1476 if (fmt->colplanes == 2) {
1477 jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes;
1478 } else if (fmt->colplanes == 3) {
1479 jpeg_addr.cb = jpeg_addr.y + pix_size;
1480 if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
1481 jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
1482 else
1483 jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
1486 exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr);
1489 static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
1491 struct s5p_jpeg *jpeg = ctx->jpeg;
1492 struct vb2_buffer *vb;
1493 unsigned int jpeg_addr = 0;
1495 if (ctx->mode == S5P_JPEG_ENCODE)
1496 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1497 else
1498 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1500 jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1501 exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
1504 static void exynos4_jpeg_device_run(void *priv)
1506 struct s5p_jpeg_ctx *ctx = priv;
1507 struct s5p_jpeg *jpeg = ctx->jpeg;
1508 unsigned int bitstream_size;
1509 unsigned long flags;
1511 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1513 if (ctx->mode == S5P_JPEG_ENCODE) {
1514 exynos4_jpeg_sw_reset(jpeg->regs);
1515 exynos4_jpeg_set_interrupt(jpeg->regs);
1516 exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
1518 exynos4_jpeg_set_huff_tbl(jpeg->regs);
1521 * JPEG IP allows storing 4 quantization tables
1522 * We fill table 0 for luma and table 1 for chroma
1524 exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1525 exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1527 exynos4_jpeg_set_encode_tbl_select(jpeg->regs,
1528 ctx->compr_quality);
1529 exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
1530 ctx->cap_q.h);
1532 exynos4_jpeg_set_enc_out_fmt(jpeg->regs, ctx->subsampling);
1533 exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->out_q.fmt->fourcc);
1534 exynos4_jpeg_set_img_addr(ctx);
1535 exynos4_jpeg_set_jpeg_addr(ctx);
1536 exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs,
1537 ctx->out_q.fmt->fourcc);
1538 } else {
1539 exynos4_jpeg_sw_reset(jpeg->regs);
1540 exynos4_jpeg_set_interrupt(jpeg->regs);
1541 exynos4_jpeg_set_img_addr(ctx);
1542 exynos4_jpeg_set_jpeg_addr(ctx);
1543 exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->cap_q.fmt->fourcc);
1545 bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
1547 exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
1550 exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
1552 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1555 static int s5p_jpeg_job_ready(void *priv)
1557 struct s5p_jpeg_ctx *ctx = priv;
1559 if (ctx->mode == S5P_JPEG_DECODE)
1560 return ctx->hdr_parsed;
1561 return 1;
1564 static void s5p_jpeg_job_abort(void *priv)
1568 static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
1569 .device_run = s5p_jpeg_device_run,
1570 .job_ready = s5p_jpeg_job_ready,
1571 .job_abort = s5p_jpeg_job_abort,
1574 static struct v4l2_m2m_ops exynos_jpeg_m2m_ops = {
1575 .device_run = exynos4_jpeg_device_run,
1576 .job_ready = s5p_jpeg_job_ready,
1577 .job_abort = s5p_jpeg_job_abort,
1581 * ============================================================================
1582 * Queue operations
1583 * ============================================================================
1586 static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
1587 const struct v4l2_format *fmt,
1588 unsigned int *nbuffers, unsigned int *nplanes,
1589 unsigned int sizes[], void *alloc_ctxs[])
1591 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
1592 struct s5p_jpeg_q_data *q_data = NULL;
1593 unsigned int size, count = *nbuffers;
1595 q_data = get_q_data(ctx, vq->type);
1596 BUG_ON(q_data == NULL);
1598 size = q_data->size;
1601 * header is parsed during decoding and parsed information stored
1602 * in the context so we do not allow another buffer to overwrite it
1604 if (ctx->mode == S5P_JPEG_DECODE)
1605 count = 1;
1607 *nbuffers = count;
1608 *nplanes = 1;
1609 sizes[0] = size;
1610 alloc_ctxs[0] = ctx->jpeg->alloc_ctx;
1612 return 0;
1615 static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
1617 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1618 struct s5p_jpeg_q_data *q_data = NULL;
1620 q_data = get_q_data(ctx, vb->vb2_queue->type);
1621 BUG_ON(q_data == NULL);
1623 if (vb2_plane_size(vb, 0) < q_data->size) {
1624 pr_err("%s data will not fit into plane (%lu < %lu)\n",
1625 __func__, vb2_plane_size(vb, 0),
1626 (long)q_data->size);
1627 return -EINVAL;
1630 vb2_set_plane_payload(vb, 0, q_data->size);
1632 return 0;
1635 static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
1637 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1639 if (ctx->mode == S5P_JPEG_DECODE &&
1640 vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1641 struct s5p_jpeg_q_data tmp, *q_data;
1642 ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
1643 (unsigned long)vb2_plane_vaddr(vb, 0),
1644 min((unsigned long)ctx->out_q.size,
1645 vb2_get_plane_payload(vb, 0)), ctx);
1646 if (!ctx->hdr_parsed) {
1647 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
1648 return;
1651 q_data = &ctx->out_q;
1652 q_data->w = tmp.w;
1653 q_data->h = tmp.h;
1655 q_data = &ctx->cap_q;
1656 q_data->w = tmp.w;
1657 q_data->h = tmp.h;
1660 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
1663 static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
1665 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1666 int ret;
1668 ret = pm_runtime_get_sync(ctx->jpeg->dev);
1670 return ret > 0 ? 0 : ret;
1673 static int s5p_jpeg_stop_streaming(struct vb2_queue *q)
1675 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
1677 pm_runtime_put(ctx->jpeg->dev);
1679 return 0;
1682 static struct vb2_ops s5p_jpeg_qops = {
1683 .queue_setup = s5p_jpeg_queue_setup,
1684 .buf_prepare = s5p_jpeg_buf_prepare,
1685 .buf_queue = s5p_jpeg_buf_queue,
1686 .wait_prepare = vb2_ops_wait_prepare,
1687 .wait_finish = vb2_ops_wait_finish,
1688 .start_streaming = s5p_jpeg_start_streaming,
1689 .stop_streaming = s5p_jpeg_stop_streaming,
1692 static int queue_init(void *priv, struct vb2_queue *src_vq,
1693 struct vb2_queue *dst_vq)
1695 struct s5p_jpeg_ctx *ctx = priv;
1696 int ret;
1698 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1699 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1700 src_vq->drv_priv = ctx;
1701 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1702 src_vq->ops = &s5p_jpeg_qops;
1703 src_vq->mem_ops = &vb2_dma_contig_memops;
1704 src_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1705 src_vq->lock = &ctx->jpeg->lock;
1707 ret = vb2_queue_init(src_vq);
1708 if (ret)
1709 return ret;
1711 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1712 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1713 dst_vq->drv_priv = ctx;
1714 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1715 dst_vq->ops = &s5p_jpeg_qops;
1716 dst_vq->mem_ops = &vb2_dma_contig_memops;
1717 dst_vq->timestamp_type = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1718 dst_vq->lock = &ctx->jpeg->lock;
1720 return vb2_queue_init(dst_vq);
1724 * ============================================================================
1725 * ISR
1726 * ============================================================================
1729 static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
1731 struct s5p_jpeg *jpeg = dev_id;
1732 struct s5p_jpeg_ctx *curr_ctx;
1733 struct vb2_buffer *src_buf, *dst_buf;
1734 unsigned long payload_size = 0;
1735 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
1736 bool enc_jpeg_too_large = false;
1737 bool timer_elapsed = false;
1738 bool op_completed = false;
1740 spin_lock(&jpeg->slock);
1742 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1744 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
1745 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
1747 if (curr_ctx->mode == S5P_JPEG_ENCODE)
1748 enc_jpeg_too_large = s5p_jpeg_enc_stream_stat(jpeg->regs);
1749 timer_elapsed = s5p_jpeg_timer_stat(jpeg->regs);
1750 op_completed = s5p_jpeg_result_stat_ok(jpeg->regs);
1751 if (curr_ctx->mode == S5P_JPEG_DECODE)
1752 op_completed = op_completed &&
1753 s5p_jpeg_stream_stat_ok(jpeg->regs);
1755 if (enc_jpeg_too_large) {
1756 state = VB2_BUF_STATE_ERROR;
1757 s5p_jpeg_clear_enc_stream_stat(jpeg->regs);
1758 } else if (timer_elapsed) {
1759 state = VB2_BUF_STATE_ERROR;
1760 s5p_jpeg_clear_timer_stat(jpeg->regs);
1761 } else if (!op_completed) {
1762 state = VB2_BUF_STATE_ERROR;
1763 } else {
1764 payload_size = s5p_jpeg_compressed_size(jpeg->regs);
1767 dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
1768 dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
1770 v4l2_m2m_buf_done(src_buf, state);
1771 if (curr_ctx->mode == S5P_JPEG_ENCODE)
1772 vb2_set_plane_payload(dst_buf, 0, payload_size);
1773 v4l2_m2m_buf_done(dst_buf, state);
1774 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
1776 curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs);
1777 spin_unlock(&jpeg->slock);
1779 s5p_jpeg_clear_int(jpeg->regs);
1781 return IRQ_HANDLED;
1784 static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
1786 unsigned int int_status;
1787 struct vb2_buffer *src_vb, *dst_vb;
1788 struct s5p_jpeg *jpeg = priv;
1789 struct s5p_jpeg_ctx *curr_ctx;
1790 unsigned long payload_size = 0;
1792 spin_lock(&jpeg->slock);
1794 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
1796 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
1797 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
1799 int_status = exynos4_jpeg_get_int_status(jpeg->regs);
1801 if (int_status) {
1802 switch (int_status & 0x1f) {
1803 case 0x1:
1804 jpeg->irq_ret = ERR_PROT;
1805 break;
1806 case 0x2:
1807 jpeg->irq_ret = OK_ENC_OR_DEC;
1808 break;
1809 case 0x4:
1810 jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
1811 break;
1812 case 0x8:
1813 jpeg->irq_ret = ERR_MULTI_SCAN;
1814 break;
1815 case 0x10:
1816 jpeg->irq_ret = ERR_FRAME;
1817 break;
1818 default:
1819 jpeg->irq_ret = ERR_UNKNOWN;
1820 break;
1822 } else {
1823 jpeg->irq_ret = ERR_UNKNOWN;
1826 if (jpeg->irq_ret == OK_ENC_OR_DEC) {
1827 if (curr_ctx->mode == S5P_JPEG_ENCODE) {
1828 payload_size = exynos4_jpeg_get_stream_size(jpeg->regs);
1829 vb2_set_plane_payload(dst_vb, 0, payload_size);
1831 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
1832 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
1833 } else {
1834 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
1835 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
1838 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
1839 curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
1841 spin_unlock(&jpeg->slock);
1842 return IRQ_HANDLED;
1845 static void *jpeg_get_drv_data(struct platform_device *pdev);
1848 * ============================================================================
1849 * Driver basic infrastructure
1850 * ============================================================================
1853 static int s5p_jpeg_probe(struct platform_device *pdev)
1855 struct s5p_jpeg *jpeg;
1856 struct resource *res;
1857 struct v4l2_m2m_ops *samsung_jpeg_m2m_ops;
1858 int ret;
1860 if (!pdev->dev.of_node)
1861 return -ENODEV;
1863 /* JPEG IP abstraction struct */
1864 jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
1865 if (!jpeg)
1866 return -ENOMEM;
1868 jpeg->variant = jpeg_get_drv_data(pdev);
1870 mutex_init(&jpeg->lock);
1871 spin_lock_init(&jpeg->slock);
1872 jpeg->dev = &pdev->dev;
1874 /* memory-mapped registers */
1875 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1877 jpeg->regs = devm_ioremap_resource(&pdev->dev, res);
1878 if (IS_ERR(jpeg->regs))
1879 return PTR_ERR(jpeg->regs);
1881 /* interrupt service routine registration */
1882 jpeg->irq = ret = platform_get_irq(pdev, 0);
1883 if (ret < 0) {
1884 dev_err(&pdev->dev, "cannot find IRQ\n");
1885 return ret;
1888 ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
1889 0, dev_name(&pdev->dev), jpeg);
1890 if (ret) {
1891 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
1892 return ret;
1895 /* clocks */
1896 jpeg->clk = clk_get(&pdev->dev, "jpeg");
1897 if (IS_ERR(jpeg->clk)) {
1898 dev_err(&pdev->dev, "cannot get clock\n");
1899 ret = PTR_ERR(jpeg->clk);
1900 return ret;
1902 dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
1904 /* v4l2 device */
1905 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
1906 if (ret) {
1907 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
1908 goto clk_get_rollback;
1911 if (jpeg->variant->version == SJPEG_S5P)
1912 samsung_jpeg_m2m_ops = &s5p_jpeg_m2m_ops;
1913 else
1914 samsung_jpeg_m2m_ops = &exynos_jpeg_m2m_ops;
1916 /* mem2mem device */
1917 jpeg->m2m_dev = v4l2_m2m_init(samsung_jpeg_m2m_ops);
1918 if (IS_ERR(jpeg->m2m_dev)) {
1919 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
1920 ret = PTR_ERR(jpeg->m2m_dev);
1921 goto device_register_rollback;
1924 jpeg->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1925 if (IS_ERR(jpeg->alloc_ctx)) {
1926 v4l2_err(&jpeg->v4l2_dev, "Failed to init memory allocator\n");
1927 ret = PTR_ERR(jpeg->alloc_ctx);
1928 goto m2m_init_rollback;
1931 /* JPEG encoder /dev/videoX node */
1932 jpeg->vfd_encoder = video_device_alloc();
1933 if (!jpeg->vfd_encoder) {
1934 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1935 ret = -ENOMEM;
1936 goto vb2_allocator_rollback;
1938 snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name),
1939 "%s-enc", S5P_JPEG_M2M_NAME);
1940 jpeg->vfd_encoder->fops = &s5p_jpeg_fops;
1941 jpeg->vfd_encoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1942 jpeg->vfd_encoder->minor = -1;
1943 jpeg->vfd_encoder->release = video_device_release;
1944 jpeg->vfd_encoder->lock = &jpeg->lock;
1945 jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev;
1946 jpeg->vfd_encoder->vfl_dir = VFL_DIR_M2M;
1948 ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
1949 if (ret) {
1950 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1951 goto enc_vdev_alloc_rollback;
1954 video_set_drvdata(jpeg->vfd_encoder, jpeg);
1955 v4l2_info(&jpeg->v4l2_dev,
1956 "encoder device registered as /dev/video%d\n",
1957 jpeg->vfd_encoder->num);
1959 /* JPEG decoder /dev/videoX node */
1960 jpeg->vfd_decoder = video_device_alloc();
1961 if (!jpeg->vfd_decoder) {
1962 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
1963 ret = -ENOMEM;
1964 goto enc_vdev_register_rollback;
1966 snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name),
1967 "%s-dec", S5P_JPEG_M2M_NAME);
1968 jpeg->vfd_decoder->fops = &s5p_jpeg_fops;
1969 jpeg->vfd_decoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
1970 jpeg->vfd_decoder->minor = -1;
1971 jpeg->vfd_decoder->release = video_device_release;
1972 jpeg->vfd_decoder->lock = &jpeg->lock;
1973 jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev;
1974 jpeg->vfd_decoder->vfl_dir = VFL_DIR_M2M;
1976 ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
1977 if (ret) {
1978 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
1979 goto dec_vdev_alloc_rollback;
1982 video_set_drvdata(jpeg->vfd_decoder, jpeg);
1983 v4l2_info(&jpeg->v4l2_dev,
1984 "decoder device registered as /dev/video%d\n",
1985 jpeg->vfd_decoder->num);
1987 /* final statements & power management */
1988 platform_set_drvdata(pdev, jpeg);
1990 pm_runtime_enable(&pdev->dev);
1992 v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
1994 return 0;
1996 dec_vdev_alloc_rollback:
1997 video_device_release(jpeg->vfd_decoder);
1999 enc_vdev_register_rollback:
2000 video_unregister_device(jpeg->vfd_encoder);
2002 enc_vdev_alloc_rollback:
2003 video_device_release(jpeg->vfd_encoder);
2005 vb2_allocator_rollback:
2006 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
2008 m2m_init_rollback:
2009 v4l2_m2m_release(jpeg->m2m_dev);
2011 device_register_rollback:
2012 v4l2_device_unregister(&jpeg->v4l2_dev);
2014 clk_get_rollback:
2015 clk_put(jpeg->clk);
2017 return ret;
2020 static int s5p_jpeg_remove(struct platform_device *pdev)
2022 struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
2024 pm_runtime_disable(jpeg->dev);
2026 video_unregister_device(jpeg->vfd_decoder);
2027 video_device_release(jpeg->vfd_decoder);
2028 video_unregister_device(jpeg->vfd_encoder);
2029 video_device_release(jpeg->vfd_encoder);
2030 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
2031 v4l2_m2m_release(jpeg->m2m_dev);
2032 v4l2_device_unregister(&jpeg->v4l2_dev);
2034 if (!pm_runtime_status_suspended(&pdev->dev))
2035 clk_disable_unprepare(jpeg->clk);
2037 clk_put(jpeg->clk);
2039 return 0;
2042 static int s5p_jpeg_runtime_suspend(struct device *dev)
2044 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2046 clk_disable_unprepare(jpeg->clk);
2048 return 0;
2051 static int s5p_jpeg_runtime_resume(struct device *dev)
2053 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2054 unsigned long flags;
2055 int ret;
2057 ret = clk_prepare_enable(jpeg->clk);
2058 if (ret < 0)
2059 return ret;
2061 spin_lock_irqsave(&jpeg->slock, flags);
2064 * JPEG IP allows storing two Huffman tables for each component
2065 * We fill table 0 for each component and do this here only
2066 * for S5PC210 device as Exynos4x12 requires programming its
2067 * Huffman tables each time the encoding process is initialized.
2069 if (jpeg->variant->version == SJPEG_S5P) {
2070 s5p_jpeg_set_hdctbl(jpeg->regs);
2071 s5p_jpeg_set_hdctblg(jpeg->regs);
2072 s5p_jpeg_set_hactbl(jpeg->regs);
2073 s5p_jpeg_set_hactblg(jpeg->regs);
2076 spin_unlock_irqrestore(&jpeg->slock, flags);
2078 return 0;
2081 static int s5p_jpeg_suspend(struct device *dev)
2083 if (pm_runtime_suspended(dev))
2084 return 0;
2086 return s5p_jpeg_runtime_suspend(dev);
2089 static int s5p_jpeg_resume(struct device *dev)
2091 if (pm_runtime_suspended(dev))
2092 return 0;
2094 return s5p_jpeg_runtime_resume(dev);
2097 static const struct dev_pm_ops s5p_jpeg_pm_ops = {
2098 SET_SYSTEM_SLEEP_PM_OPS(s5p_jpeg_suspend, s5p_jpeg_resume)
2099 SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume, NULL)
2102 #ifdef CONFIG_OF
2103 static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
2104 .version = SJPEG_S5P,
2105 .jpeg_irq = s5p_jpeg_irq,
2108 static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
2109 .version = SJPEG_EXYNOS4,
2110 .jpeg_irq = exynos4_jpeg_irq,
2113 static const struct of_device_id samsung_jpeg_match[] = {
2115 .compatible = "samsung,s5pv210-jpeg",
2116 .data = &s5p_jpeg_drvdata,
2117 }, {
2118 .compatible = "samsung,exynos4210-jpeg",
2119 .data = &s5p_jpeg_drvdata,
2120 }, {
2121 .compatible = "samsung,exynos4212-jpeg",
2122 .data = &exynos4_jpeg_drvdata,
2127 MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
2129 static void *jpeg_get_drv_data(struct platform_device *pdev)
2131 struct s5p_jpeg_variant *driver_data = NULL;
2132 const struct of_device_id *match;
2134 match = of_match_node(of_match_ptr(samsung_jpeg_match),
2135 pdev->dev.of_node);
2136 if (match)
2137 driver_data = (struct s5p_jpeg_variant *)match->data;
2139 return driver_data;
2141 #endif
2143 static struct platform_driver s5p_jpeg_driver = {
2144 .probe = s5p_jpeg_probe,
2145 .remove = s5p_jpeg_remove,
2146 .driver = {
2147 .of_match_table = of_match_ptr(samsung_jpeg_match),
2148 .owner = THIS_MODULE,
2149 .name = S5P_JPEG_M2M_NAME,
2150 .pm = &s5p_jpeg_pm_ops,
2154 module_platform_driver(s5p_jpeg_driver);
2156 MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
2157 MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
2158 MODULE_DESCRIPTION("Samsung JPEG codec driver");
2159 MODULE_LICENSE("GPL");