1 // SPDX-License-Identifier: GPL-2.0-only
2 /* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c
4 * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
5 * http://www.samsung.com
7 * Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>
8 * Author: Jacek Anaszewski <j.anaszewski@samsung.com>
11 #include <linux/clk.h>
12 #include <linux/err.h>
13 #include <linux/gfp.h>
14 #include <linux/interrupt.h>
16 #include <linux/kernel.h>
17 #include <linux/module.h>
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>
24 #include <media/v4l2-event.h>
25 #include <media/v4l2-mem2mem.h>
26 #include <media/v4l2-ioctl.h>
27 #include <media/videobuf2-v4l2.h>
28 #include <media/videobuf2-dma-contig.h>
30 #include "jpeg-core.h"
31 #include "jpeg-hw-s5p.h"
32 #include "jpeg-hw-exynos4.h"
33 #include "jpeg-hw-exynos3250.h"
34 #include "jpeg-regs.h"
36 static struct s5p_jpeg_fmt sjpeg_formats[] = {
39 .fourcc = V4L2_PIX_FMT_JPEG,
40 .flags = SJPEG_FMT_FLAG_ENC_CAPTURE |
41 SJPEG_FMT_FLAG_DEC_OUTPUT |
43 SJPEG_FMT_FLAG_EXYNOS3250 |
44 SJPEG_FMT_FLAG_EXYNOS4,
47 .name = "YUV 4:2:2 packed, YCbYCr",
48 .fourcc = V4L2_PIX_FMT_YUYV,
53 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
54 SJPEG_FMT_FLAG_DEC_CAPTURE |
57 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
60 .name = "YUV 4:2:2 packed, YCbYCr",
61 .fourcc = V4L2_PIX_FMT_YUYV,
66 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
67 SJPEG_FMT_FLAG_DEC_CAPTURE |
68 SJPEG_FMT_FLAG_EXYNOS4 |
70 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
73 .name = "YUV 4:2:2 packed, YCbYCr",
74 .fourcc = V4L2_PIX_FMT_YUYV,
79 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
80 SJPEG_FMT_FLAG_DEC_CAPTURE |
81 SJPEG_FMT_FLAG_EXYNOS3250 |
83 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
86 .name = "YUV 4:2:2 packed, YCrYCb",
87 .fourcc = V4L2_PIX_FMT_YVYU,
92 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
93 SJPEG_FMT_FLAG_DEC_CAPTURE |
94 SJPEG_FMT_FLAG_EXYNOS4 |
96 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
99 .name = "YUV 4:2:2 packed, YCrYCb",
100 .fourcc = V4L2_PIX_FMT_YVYU,
105 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
106 SJPEG_FMT_FLAG_DEC_CAPTURE |
107 SJPEG_FMT_FLAG_EXYNOS3250 |
109 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
112 .name = "YUV 4:2:2 packed, YCrYCb",
113 .fourcc = V4L2_PIX_FMT_UYVY,
118 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
119 SJPEG_FMT_FLAG_DEC_CAPTURE |
120 SJPEG_FMT_FLAG_EXYNOS3250 |
122 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
125 .name = "YUV 4:2:2 packed, YCrYCb",
126 .fourcc = V4L2_PIX_FMT_VYUY,
131 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
132 SJPEG_FMT_FLAG_DEC_CAPTURE |
133 SJPEG_FMT_FLAG_EXYNOS3250 |
135 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
139 .fourcc = V4L2_PIX_FMT_RGB565,
144 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
145 SJPEG_FMT_FLAG_DEC_CAPTURE |
146 SJPEG_FMT_FLAG_EXYNOS4 |
148 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
152 .fourcc = V4L2_PIX_FMT_RGB565,
157 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
158 SJPEG_FMT_FLAG_DEC_CAPTURE |
159 SJPEG_FMT_FLAG_EXYNOS3250 |
161 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
165 .fourcc = V4L2_PIX_FMT_RGB565X,
170 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
171 SJPEG_FMT_FLAG_DEC_CAPTURE |
172 SJPEG_FMT_FLAG_EXYNOS3250 |
174 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
178 .fourcc = V4L2_PIX_FMT_RGB565,
183 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
186 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
189 .name = "ARGB8888, 32 bpp",
190 .fourcc = V4L2_PIX_FMT_RGB32,
195 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
196 SJPEG_FMT_FLAG_DEC_CAPTURE |
197 SJPEG_FMT_FLAG_EXYNOS4 |
199 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
202 .name = "ARGB8888, 32 bpp",
203 .fourcc = V4L2_PIX_FMT_RGB32,
208 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
209 SJPEG_FMT_FLAG_DEC_CAPTURE |
210 SJPEG_FMT_FLAG_EXYNOS3250 |
212 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
215 .name = "YUV 4:4:4 planar, Y/CbCr",
216 .fourcc = V4L2_PIX_FMT_NV24,
221 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
222 SJPEG_FMT_FLAG_DEC_CAPTURE |
223 SJPEG_FMT_FLAG_EXYNOS4 |
225 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
228 .name = "YUV 4:4:4 planar, Y/CrCb",
229 .fourcc = V4L2_PIX_FMT_NV42,
234 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
235 SJPEG_FMT_FLAG_DEC_CAPTURE |
236 SJPEG_FMT_FLAG_EXYNOS4 |
238 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
241 .name = "YUV 4:2:2 planar, Y/CrCb",
242 .fourcc = V4L2_PIX_FMT_NV61,
247 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
248 SJPEG_FMT_FLAG_DEC_CAPTURE |
249 SJPEG_FMT_FLAG_EXYNOS4 |
251 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
254 .name = "YUV 4:2:2 planar, Y/CbCr",
255 .fourcc = V4L2_PIX_FMT_NV16,
260 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
261 SJPEG_FMT_FLAG_DEC_CAPTURE |
262 SJPEG_FMT_FLAG_EXYNOS4 |
264 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
267 .name = "YUV 4:2:0 planar, Y/CbCr",
268 .fourcc = V4L2_PIX_FMT_NV12,
273 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
274 SJPEG_FMT_FLAG_DEC_CAPTURE |
275 SJPEG_FMT_FLAG_EXYNOS4 |
277 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
280 .name = "YUV 4:2:0 planar, Y/CbCr",
281 .fourcc = V4L2_PIX_FMT_NV12,
286 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
287 SJPEG_FMT_FLAG_DEC_CAPTURE |
288 SJPEG_FMT_FLAG_EXYNOS3250 |
290 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
293 .name = "YUV 4:2:0 planar, Y/CbCr",
294 .fourcc = V4L2_PIX_FMT_NV12,
299 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
300 SJPEG_FMT_FLAG_DEC_CAPTURE |
303 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
306 .name = "YUV 4:2:0 planar, Y/CrCb",
307 .fourcc = V4L2_PIX_FMT_NV21,
312 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
313 SJPEG_FMT_FLAG_DEC_CAPTURE |
314 SJPEG_FMT_FLAG_EXYNOS3250 |
316 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
319 .name = "YUV 4:2:0 planar, Y/CrCb",
320 .fourcc = V4L2_PIX_FMT_NV21,
325 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
326 SJPEG_FMT_FLAG_DEC_CAPTURE |
327 SJPEG_FMT_FLAG_EXYNOS3250 |
328 SJPEG_FMT_FLAG_EXYNOS4 |
330 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
333 .name = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
334 .fourcc = V4L2_PIX_FMT_YUV420,
339 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
340 SJPEG_FMT_FLAG_DEC_CAPTURE |
341 SJPEG_FMT_FLAG_EXYNOS4 |
343 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
346 .name = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
347 .fourcc = V4L2_PIX_FMT_YUV420,
352 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
353 SJPEG_FMT_FLAG_DEC_CAPTURE |
354 SJPEG_FMT_FLAG_EXYNOS3250 |
356 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
360 .fourcc = V4L2_PIX_FMT_GREY,
363 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
364 SJPEG_FMT_FLAG_DEC_CAPTURE |
365 SJPEG_FMT_FLAG_EXYNOS4 |
367 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
370 #define SJPEG_NUM_FORMATS ARRAY_SIZE(sjpeg_formats)
372 static const unsigned char qtbl_luminance[4][64] = {
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
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
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
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
415 static const unsigned char qtbl_chrominance[4][64] = {
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
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
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
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
458 static const unsigned char hdctbl0[16] = {
459 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
462 static const unsigned char hdctblg0[12] = {
463 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
465 static const unsigned char hactbl0[16] = {
466 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
468 static 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,
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.
499 static const u32 subs422_fourcc_dwngrd_schema[] = {
504 static const u32 subs420_fourcc_dwngrd_schema[] = {
518 * Lookup table for translation of a fourcc to the position
519 * of its downgraded counterpart in the *fourcc_dwngrd_schema
522 static const u32 fourcc_to_dwngrd_schema_id[] = {
535 static int s5p_jpeg_get_dwngrd_sch_id_by_fourcc(u32 fourcc)
539 for (i = 0; i < ARRAY_SIZE(fourcc_to_dwngrd_schema_id); ++i) {
540 if (fourcc_to_dwngrd_schema_id[i] == fourcc)
547 static int s5p_jpeg_adjust_fourcc_to_subsampling(
548 enum v4l2_jpeg_chroma_subsampling subs,
551 struct s5p_jpeg_ctx *ctx)
555 if (ctx->subsampling != V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
557 s5p_jpeg_get_dwngrd_sch_id_by_fourcc(in_fourcc);
558 if (dwngrd_sch_id < 0)
562 switch (ctx->subsampling) {
563 case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
564 *out_fourcc = V4L2_PIX_FMT_GREY;
566 case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
568 ARRAY_SIZE(subs420_fourcc_dwngrd_schema) - 1)
570 *out_fourcc = subs420_fourcc_dwngrd_schema[dwngrd_sch_id];
572 case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
574 ARRAY_SIZE(subs422_fourcc_dwngrd_schema) - 1)
576 *out_fourcc = subs422_fourcc_dwngrd_schema[dwngrd_sch_id];
579 *out_fourcc = V4L2_PIX_FMT_GREY;
586 static 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,
593 static 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,
600 V4L2_JPEG_CHROMA_SUBSAMPLING_411,
603 static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
605 return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
608 static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
610 return container_of(fh, struct s5p_jpeg_ctx, fh);
613 static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
615 switch (ctx->jpeg->variant->version) {
617 WARN_ON(ctx->subsampling > 3);
618 if (ctx->subsampling > 2)
619 return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
620 return ctx->subsampling;
621 case SJPEG_EXYNOS3250:
622 case SJPEG_EXYNOS5420:
623 WARN_ON(ctx->subsampling > 6);
624 if (ctx->subsampling > 3)
625 return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
626 return exynos3250_decoded_subsampling[ctx->subsampling];
628 WARN_ON(ctx->subsampling > 3);
629 if (ctx->subsampling > 2)
630 return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
631 return exynos4x12_decoded_subsampling[ctx->subsampling];
632 case SJPEG_EXYNOS5433:
633 return ctx->subsampling; /* parsed from header */
635 WARN_ON(ctx->subsampling > 3);
636 return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
640 static inline void s5p_jpeg_set_qtbl(void __iomem *regs,
641 const unsigned char *qtbl,
642 unsigned long tab, int len)
646 for (i = 0; i < len; i++)
647 writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
650 static inline void s5p_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
652 /* this driver fills quantisation table 0 with data for luma */
653 s5p_jpeg_set_qtbl(regs, qtbl_luminance[quality],
654 S5P_JPG_QTBL_CONTENT(0),
655 ARRAY_SIZE(qtbl_luminance[quality]));
658 static inline void s5p_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
660 /* this driver fills quantisation table 1 with data for chroma */
661 s5p_jpeg_set_qtbl(regs, qtbl_chrominance[quality],
662 S5P_JPG_QTBL_CONTENT(1),
663 ARRAY_SIZE(qtbl_chrominance[quality]));
666 static inline void s5p_jpeg_set_htbl(void __iomem *regs,
667 const unsigned char *htbl,
668 unsigned long tab, int len)
672 for (i = 0; i < len; i++)
673 writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
676 static inline void s5p_jpeg_set_hdctbl(void __iomem *regs)
678 /* this driver fills table 0 for this component */
679 s5p_jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0),
680 ARRAY_SIZE(hdctbl0));
683 static inline void s5p_jpeg_set_hdctblg(void __iomem *regs)
685 /* this driver fills table 0 for this component */
686 s5p_jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0),
687 ARRAY_SIZE(hdctblg0));
690 static inline void s5p_jpeg_set_hactbl(void __iomem *regs)
692 /* this driver fills table 0 for this component */
693 s5p_jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0),
694 ARRAY_SIZE(hactbl0));
697 static inline void s5p_jpeg_set_hactblg(void __iomem *regs)
699 /* this driver fills table 0 for this component */
700 s5p_jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0),
701 ARRAY_SIZE(hactblg0));
704 static inline void exynos4_jpeg_set_tbl(void __iomem *regs,
705 const unsigned char *tbl,
706 unsigned long tab, int len)
711 for (i = 0; i < len; i += 4) {
716 writel(dword, regs + tab + i);
720 static inline void exynos4_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
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]));
728 static inline void exynos4_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
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]));
736 static void exynos4_jpeg_set_huff_tbl(void __iomem *base)
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));
756 static inline int __exynos4_huff_tbl(int class, int id, bool lenval)
759 * class: 0 - DC, 1 - AC
760 * id: 0 - Y, 1 - Cb/Cr
764 return lenval ? EXYNOS4_HUFF_TBL_HACCL :
765 EXYNOS4_HUFF_TBL_HACCV;
766 return lenval ? EXYNOS4_HUFF_TBL_HACLL : EXYNOS4_HUFF_TBL_HACLV;
771 return lenval ? EXYNOS4_HUFF_TBL_HDCCL : EXYNOS4_HUFF_TBL_HDCCV;
773 return lenval ? EXYNOS4_HUFF_TBL_HDCLL : EXYNOS4_HUFF_TBL_HDCLV;
776 static inline int exynos4_huff_tbl_len(int class, int id)
778 return __exynos4_huff_tbl(class, id, true);
781 static inline int exynos4_huff_tbl_val(int class, int id)
783 return __exynos4_huff_tbl(class, id, false);
786 static int get_byte(struct s5p_jpeg_buffer *buf);
787 static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word);
788 static void skip(struct s5p_jpeg_buffer *buf, long len);
790 static void exynos4_jpeg_parse_decode_h_tbl(struct s5p_jpeg_ctx *ctx)
792 struct s5p_jpeg *jpeg = ctx->jpeg;
793 struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
794 struct s5p_jpeg_buffer jpeg_buffer;
796 int c, x, components;
798 jpeg_buffer.size = 2; /* Ls */
800 (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + ctx->out_q.sos + 2;
801 jpeg_buffer.curr = 0;
805 if (get_word_be(&jpeg_buffer, &word))
807 jpeg_buffer.size = (long)word - 2;
808 jpeg_buffer.data += 2;
809 jpeg_buffer.curr = 0;
811 components = get_byte(&jpeg_buffer);
812 if (components == -1)
814 while (components--) {
815 c = get_byte(&jpeg_buffer);
818 x = get_byte(&jpeg_buffer);
821 exynos4_jpeg_select_dec_h_tbl(jpeg->regs, c,
822 (((x >> 4) & 0x1) << 1) | (x & 0x1));
827 static void exynos4_jpeg_parse_huff_tbl(struct s5p_jpeg_ctx *ctx)
829 struct s5p_jpeg *jpeg = ctx->jpeg;
830 struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
831 struct s5p_jpeg_buffer jpeg_buffer;
835 for (j = 0; j < ctx->out_q.dht.n; ++j) {
836 jpeg_buffer.size = ctx->out_q.dht.len[j];
837 jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) +
838 ctx->out_q.dht.marker[j];
839 jpeg_buffer.curr = 0;
842 while (jpeg_buffer.curr < jpeg_buffer.size) {
845 c = get_byte(&jpeg_buffer);
849 class = (c >> 4) & 0xf;
851 for (i = 0; i < 16; ++i) {
852 c = get_byte(&jpeg_buffer);
855 word |= c << ((i % 4) * 8);
856 if ((i + 1) % 4 == 0) {
857 writel(word, jpeg->regs +
858 exynos4_huff_tbl_len(class, id) +
865 for (i = 0; i < n; ++i) {
866 c = get_byte(&jpeg_buffer);
869 word |= c << ((i % 4) * 8);
870 if ((i + 1) % 4 == 0) {
871 writel(word, jpeg->regs +
872 exynos4_huff_tbl_val(class, id) +
878 writel(word, jpeg->regs +
879 exynos4_huff_tbl_val(class, id) + (i / 4) * 4);
886 static void exynos4_jpeg_parse_decode_q_tbl(struct s5p_jpeg_ctx *ctx)
888 struct s5p_jpeg *jpeg = ctx->jpeg;
889 struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
890 struct s5p_jpeg_buffer jpeg_buffer;
891 int c, x, components;
893 jpeg_buffer.size = ctx->out_q.sof_len;
895 (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) + ctx->out_q.sof;
896 jpeg_buffer.curr = 0;
898 skip(&jpeg_buffer, 5); /* P, Y, X */
899 components = get_byte(&jpeg_buffer);
900 if (components == -1)
903 exynos4_jpeg_set_dec_components(jpeg->regs, components);
905 while (components--) {
906 c = get_byte(&jpeg_buffer);
909 skip(&jpeg_buffer, 1);
910 x = get_byte(&jpeg_buffer);
913 exynos4_jpeg_select_dec_q_tbl(jpeg->regs, c, x);
917 static void exynos4_jpeg_parse_q_tbl(struct s5p_jpeg_ctx *ctx)
919 struct s5p_jpeg *jpeg = ctx->jpeg;
920 struct vb2_v4l2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
921 struct s5p_jpeg_buffer jpeg_buffer;
925 for (j = 0; j < ctx->out_q.dqt.n; ++j) {
926 jpeg_buffer.size = ctx->out_q.dqt.len[j];
927 jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(&vb->vb2_buf, 0) +
928 ctx->out_q.dqt.marker[j];
929 jpeg_buffer.curr = 0;
932 while (jpeg_buffer.size - jpeg_buffer.curr >= 65) {
935 c = get_byte(&jpeg_buffer);
939 /* nonzero means extended mode - not supported */
942 for (i = 0; i < 64; ++i) {
943 c = get_byte(&jpeg_buffer);
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);
959 * ============================================================================
960 * Device file operations
961 * ============================================================================
964 static int queue_init(void *priv, struct vb2_queue *src_vq,
965 struct vb2_queue *dst_vq);
966 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
967 __u32 pixelformat, unsigned int fmt_type);
968 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
970 static int s5p_jpeg_open(struct file *file)
972 struct s5p_jpeg *jpeg = video_drvdata(file);
973 struct video_device *vfd = video_devdata(file);
974 struct s5p_jpeg_ctx *ctx;
975 struct s5p_jpeg_fmt *out_fmt, *cap_fmt;
978 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
982 if (mutex_lock_interruptible(&jpeg->lock)) {
987 v4l2_fh_init(&ctx->fh, vfd);
988 /* Use separate control handler per file handle */
989 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
990 file->private_data = &ctx->fh;
991 v4l2_fh_add(&ctx->fh);
994 if (vfd == jpeg->vfd_encoder) {
995 ctx->mode = S5P_JPEG_ENCODE;
996 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB565,
998 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
1001 ctx->mode = S5P_JPEG_DECODE;
1002 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
1004 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV,
1006 ctx->scale_factor = EXYNOS3250_DEC_SCALE_FACTOR_8_8;
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);
1015 ctx->out_q.fmt = out_fmt;
1016 ctx->cap_q.fmt = cap_fmt;
1018 ret = s5p_jpeg_controls_create(ctx);
1022 mutex_unlock(&jpeg->lock);
1026 v4l2_fh_del(&ctx->fh);
1027 v4l2_fh_exit(&ctx->fh);
1028 mutex_unlock(&jpeg->lock);
1034 static int s5p_jpeg_release(struct file *file)
1036 struct s5p_jpeg *jpeg = video_drvdata(file);
1037 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
1039 mutex_lock(&jpeg->lock);
1040 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1041 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1042 v4l2_fh_del(&ctx->fh);
1043 v4l2_fh_exit(&ctx->fh);
1045 mutex_unlock(&jpeg->lock);
1050 static const struct v4l2_file_operations s5p_jpeg_fops = {
1051 .owner = THIS_MODULE,
1052 .open = s5p_jpeg_open,
1053 .release = s5p_jpeg_release,
1054 .poll = v4l2_m2m_fop_poll,
1055 .unlocked_ioctl = video_ioctl2,
1056 .mmap = v4l2_m2m_fop_mmap,
1060 * ============================================================================
1061 * video ioctl operations
1062 * ============================================================================
1065 static int get_byte(struct s5p_jpeg_buffer *buf)
1067 if (buf->curr >= buf->size)
1070 return ((unsigned char *)buf->data)[buf->curr++];
1073 static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
1078 byte = get_byte(buf);
1082 byte = get_byte(buf);
1085 *word = (unsigned int)byte | temp;
1089 static void skip(struct s5p_jpeg_buffer *buf, long len)
1098 static bool s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx *ctx,
1099 unsigned int subsampling)
1101 unsigned int version;
1103 switch (subsampling) {
1105 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
1108 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
1111 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
1114 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
1118 * 4:1:1 subsampling only supported by 3250, 5420, and 5433
1121 version = ctx->jpeg->variant->version;
1122 if (version != SJPEG_EXYNOS3250 &&
1123 version != SJPEG_EXYNOS5420 &&
1124 version != SJPEG_EXYNOS5433)
1127 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_411;
1136 static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
1137 unsigned long buffer, unsigned long size,
1138 struct s5p_jpeg_ctx *ctx)
1140 int c, components = 0, notfound, n_dht = 0, n_dqt = 0;
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];
1146 struct s5p_jpeg_buffer jpeg_buffer;
1148 jpeg_buffer.size = size;
1149 jpeg_buffer.data = buffer;
1150 jpeg_buffer.curr = 0;
1153 while (notfound || !sos) {
1154 c = get_byte(&jpeg_buffer);
1160 c = get_byte(&jpeg_buffer);
1168 /* SOF0: baseline JPEG */
1170 if (get_word_be(&jpeg_buffer, &word))
1172 length = (long)word - 2;
1175 sof = jpeg_buffer.curr; /* after 0xffc0 */
1177 if (get_byte(&jpeg_buffer) == -1)
1179 if (get_word_be(&jpeg_buffer, &height))
1181 if (get_word_be(&jpeg_buffer, &width))
1183 components = get_byte(&jpeg_buffer);
1184 if (components == -1)
1187 if (components == 1) {
1190 skip(&jpeg_buffer, 1);
1191 subsampling = get_byte(&jpeg_buffer);
1192 skip(&jpeg_buffer, 1);
1196 skip(&jpeg_buffer, components * 2);
1201 if (get_word_be(&jpeg_buffer, &word))
1203 length = (long)word - 2;
1206 if (n_dqt >= S5P_JPEG_MAX_MARKER)
1208 dqt[n_dqt] = jpeg_buffer.curr; /* after 0xffdb */
1209 dqt_len[n_dqt++] = length;
1210 skip(&jpeg_buffer, length);
1214 if (get_word_be(&jpeg_buffer, &word))
1216 length = (long)word - 2;
1219 if (n_dht >= S5P_JPEG_MAX_MARKER)
1221 dht[n_dht] = jpeg_buffer.curr; /* after 0xffc4 */
1222 dht_len[n_dht++] = length;
1223 skip(&jpeg_buffer, length);
1227 sos = jpeg_buffer.curr - 2; /* 0xffda */
1230 /* skip payload-less markers */
1231 case RST ... RST + 7:
1237 /* skip uninteresting payload markers */
1239 if (get_word_be(&jpeg_buffer, &word))
1241 length = (long)word - 2;
1242 skip(&jpeg_buffer, length);
1247 if (notfound || !sos || !s5p_jpeg_subsampling_decode(ctx, subsampling))
1253 result->dht.n = n_dht;
1255 result->dht.marker[n_dht] = dht[n_dht];
1256 result->dht.len[n_dht] = dht_len[n_dht];
1258 result->dqt.n = n_dqt;
1260 result->dqt.marker[n_dqt] = dqt[n_dqt];
1261 result->dqt.len[n_dqt] = dqt_len[n_dqt];
1264 result->sof_len = sof_len;
1265 result->components = components;
1270 static int s5p_jpeg_querycap(struct file *file, void *priv,
1271 struct v4l2_capability *cap)
1273 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1275 if (ctx->mode == S5P_JPEG_ENCODE) {
1276 strscpy(cap->driver, S5P_JPEG_M2M_NAME,
1277 sizeof(cap->driver));
1278 strscpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
1281 strscpy(cap->driver, S5P_JPEG_M2M_NAME,
1282 sizeof(cap->driver));
1283 strscpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
1286 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
1287 dev_name(ctx->jpeg->dev));
1288 cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
1289 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1293 static int enum_fmt(struct s5p_jpeg_ctx *ctx,
1294 struct s5p_jpeg_fmt *sjpeg_formats, int n,
1295 struct v4l2_fmtdesc *f, u32 type)
1298 unsigned int fmt_ver_flag = ctx->jpeg->variant->fmt_ver_flag;
1300 for (i = 0; i < n; ++i) {
1301 if (sjpeg_formats[i].flags & type &&
1302 sjpeg_formats[i].flags & fmt_ver_flag) {
1303 /* index-th format of type type found ? */
1304 if (num == f->index)
1306 /* Correct type but haven't reached our index yet,
1307 * just increment per-type index
1313 /* Format not found */
1317 strscpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
1318 f->pixelformat = sjpeg_formats[i].fourcc;
1323 static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
1324 struct v4l2_fmtdesc *f)
1326 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1328 if (ctx->mode == S5P_JPEG_ENCODE)
1329 return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f,
1330 SJPEG_FMT_FLAG_ENC_CAPTURE);
1332 return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f,
1333 SJPEG_FMT_FLAG_DEC_CAPTURE);
1336 static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
1337 struct v4l2_fmtdesc *f)
1339 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1341 if (ctx->mode == S5P_JPEG_ENCODE)
1342 return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f,
1343 SJPEG_FMT_FLAG_ENC_OUTPUT);
1345 return enum_fmt(ctx, sjpeg_formats, SJPEG_NUM_FORMATS, f,
1346 SJPEG_FMT_FLAG_DEC_OUTPUT);
1349 static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
1350 enum v4l2_buf_type type)
1352 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1354 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1360 static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
1362 struct vb2_queue *vq;
1363 struct s5p_jpeg_q_data *q_data = NULL;
1364 struct v4l2_pix_format *pix = &f->fmt.pix;
1365 struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
1367 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1371 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1372 ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
1374 q_data = get_q_data(ct, f->type);
1375 BUG_ON(q_data == NULL);
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;
1385 if (q_data->fmt->colplanes == 1)
1386 bpl = (bpl * q_data->fmt->depth) >> 3;
1387 pix->bytesperline = bpl;
1389 pix->sizeimage = q_data->size;
1394 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
1395 u32 pixelformat, unsigned int fmt_type)
1397 unsigned int k, fmt_flag;
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;
1404 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
1405 SJPEG_FMT_FLAG_DEC_OUTPUT :
1406 SJPEG_FMT_FLAG_DEC_CAPTURE;
1408 for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
1409 struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
1411 if (fmt->fourcc == pixelformat &&
1412 fmt->flags & fmt_flag &&
1413 fmt->flags & ctx->jpeg->variant->fmt_ver_flag) {
1421 static void jpeg_bound_align_image(struct s5p_jpeg_ctx *ctx,
1422 u32 *w, unsigned int wmin, unsigned int wmax,
1423 unsigned int walign,
1424 u32 *h, unsigned int hmin, unsigned int hmax,
1425 unsigned int halign)
1427 int width, height, w_step, h_step;
1432 w_step = 1 << walign;
1433 h_step = 1 << halign;
1435 if (ctx->jpeg->variant->hw3250_compat) {
1437 * Rightmost and bottommost pixels are cropped by the
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.
1443 if (w_step == 4 && ((width & 3) == 1)) {
1449 v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
1451 if (*w < width && (*w + w_step) < wmax)
1453 if (*h < height && (*h + h_step) < hmax)
1457 static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
1458 struct s5p_jpeg_ctx *ctx, int q_type)
1460 struct v4l2_pix_format *pix = &f->fmt.pix;
1462 if (pix->field == V4L2_FIELD_ANY)
1463 pix->field = V4L2_FIELD_NONE;
1464 else if (pix->field != V4L2_FIELD_NONE)
1467 /* V4L2 specification suggests the driver corrects the format struct
1468 * if any of the dimensions is unsupported
1470 if (q_type == FMT_TYPE_OUTPUT)
1471 jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
1472 S5P_JPEG_MAX_WIDTH, 0,
1473 &pix->height, S5P_JPEG_MIN_HEIGHT,
1474 S5P_JPEG_MAX_HEIGHT, 0);
1476 jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
1477 S5P_JPEG_MAX_WIDTH, fmt->h_align,
1478 &pix->height, S5P_JPEG_MIN_HEIGHT,
1479 S5P_JPEG_MAX_HEIGHT, fmt->v_align);
1481 if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1482 if (pix->sizeimage <= 0)
1483 pix->sizeimage = PAGE_SIZE;
1484 pix->bytesperline = 0;
1486 u32 bpl = pix->bytesperline;
1488 if (fmt->colplanes > 1 && bpl < pix->width)
1489 bpl = pix->width; /* planar */
1491 if (fmt->colplanes == 1 && /* packed */
1492 (bpl << 3) / fmt->depth < pix->width)
1493 bpl = (pix->width * fmt->depth) >> 3;
1495 pix->bytesperline = bpl;
1496 pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
1502 static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
1503 struct v4l2_format *f)
1505 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1506 struct v4l2_pix_format *pix = &f->fmt.pix;
1507 struct s5p_jpeg_fmt *fmt;
1510 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1513 v4l2_err(&ctx->jpeg->v4l2_dev,
1514 "Fourcc format (0x%08x) invalid.\n",
1515 f->fmt.pix.pixelformat);
1519 if (!ctx->jpeg->variant->hw_ex4_compat || ctx->mode != S5P_JPEG_DECODE)
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.
1528 if ((fmt->flags & SJPEG_FMT_NON_RGB) &&
1529 (fmt->subsampling < ctx->subsampling)) {
1530 ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling,
1535 pix->pixelformat = V4L2_PIX_FMT_GREY;
1537 fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
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
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,
1558 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
1561 static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
1562 struct v4l2_format *f)
1564 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1565 struct s5p_jpeg_fmt *fmt;
1567 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1570 v4l2_err(&ctx->jpeg->v4l2_dev,
1571 "Fourcc format (0x%08x) invalid.\n",
1572 f->fmt.pix.pixelformat);
1576 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
1579 static int exynos4_jpeg_get_output_buffer_size(struct s5p_jpeg_ctx *ctx,
1580 struct v4l2_format *f,
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;
1588 if (pix_fmt == V4L2_PIX_FMT_RGB32 ||
1589 pix_fmt == V4L2_PIX_FMT_RGB565 ||
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)
1599 jpeg_bound_align_image(ctx, &w, S5P_JPEG_MIN_WIDTH,
1600 S5P_JPEG_MAX_WIDTH, wh_align,
1601 &h, S5P_JPEG_MIN_HEIGHT,
1602 S5P_JPEG_MAX_HEIGHT, wh_align);
1604 if (ctx->jpeg->variant->version == SJPEG_EXYNOS4)
1605 padding = PAGE_SIZE;
1607 return (w * h * fmt_depth >> 3) + padding;
1610 static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1611 struct v4l2_rect *r);
1613 static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
1615 struct vb2_queue *vq;
1616 struct s5p_jpeg_q_data *q_data = NULL;
1617 struct v4l2_pix_format *pix = &f->fmt.pix;
1618 struct v4l2_ctrl *ctrl_subs;
1619 struct v4l2_rect scale_rect;
1620 unsigned int f_type;
1622 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1626 q_data = get_q_data(ct, f->type);
1627 BUG_ON(q_data == NULL);
1629 if (vb2_is_busy(vq)) {
1630 v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
1634 f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
1635 FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
1637 q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
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;
1644 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
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.
1651 if (ct->jpeg->variant->hw_ex4_compat &&
1652 f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE)
1653 q_data->size = exynos4_jpeg_get_output_buffer_size(ct,
1655 q_data->fmt->depth);
1657 q_data->size = q_data->w * q_data->h *
1658 q_data->fmt->depth >> 3;
1660 q_data->size = pix->sizeimage;
1663 if (f_type == FMT_TYPE_OUTPUT) {
1664 ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler,
1665 V4L2_CID_JPEG_CHROMA_SUBSAMPLING);
1667 v4l2_ctrl_s_ctrl(ctrl_subs, q_data->fmt->subsampling);
1668 ct->crop_altered = false;
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.
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;
1685 * Prevent downscaling to YUV420 format by more than 2
1686 * for Exynos3250/compatible SoC as it produces broken raw image
1689 if (ct->mode == S5P_JPEG_DECODE &&
1690 f_type == FMT_TYPE_CAPTURE &&
1691 ct->jpeg->variant->hw3250_compat &&
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);
1702 static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
1703 struct v4l2_format *f)
1707 ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
1711 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1714 static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
1715 struct v4l2_format *f)
1719 ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
1723 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1726 static int s5p_jpeg_subscribe_event(struct v4l2_fh *fh,
1727 const struct v4l2_event_subscription *sub)
1729 if (sub->type == V4L2_EVENT_SOURCE_CHANGE)
1730 return v4l2_src_change_event_subscribe(fh, sub);
1735 static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1736 struct v4l2_rect *r)
1738 int w_ratio, h_ratio, scale_factor, cur_ratio, i;
1740 w_ratio = ctx->out_q.w / r->width;
1741 h_ratio = ctx->out_q.h / r->height;
1743 scale_factor = w_ratio > h_ratio ? w_ratio : h_ratio;
1744 scale_factor = clamp_val(scale_factor, 1, 8);
1746 /* Align scale ratio to the nearest power of 2 */
1747 for (i = 0; i <= 3; ++i) {
1749 if (scale_factor <= cur_ratio) {
1750 ctx->scale_factor = cur_ratio;
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);
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;
1763 ctx->crop_altered = true;
1768 /* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
1769 static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
1771 if (a->left < b->left || a->top < b->top)
1773 if (a->left + a->width > b->left + b->width)
1775 if (a->top + a->height > b->top + b->height)
1781 static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx,
1782 struct v4l2_rect *r)
1784 struct v4l2_rect base_rect;
1787 switch (ctx->cap_q.fmt->fourcc) {
1788 case V4L2_PIX_FMT_NV12:
1789 case V4L2_PIX_FMT_NV21:
1793 case V4L2_PIX_FMT_YUV420:
1805 base_rect.width = ctx->out_q.w;
1806 base_rect.height = ctx->out_q.h;
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);
1813 if (!enclosed_rectangle(r, &base_rect))
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;
1821 ctx->crop_altered = true;
1830 static int s5p_jpeg_g_selection(struct file *file, void *priv,
1831 struct v4l2_selection *s)
1833 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1835 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
1836 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1839 /* For JPEG blob active == default == bounds */
1840 switch (s->target) {
1841 case V4L2_SEL_TGT_CROP:
1842 case V4L2_SEL_TGT_CROP_BOUNDS:
1843 case V4L2_SEL_TGT_CROP_DEFAULT:
1844 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1845 s->r.width = ctx->out_q.w;
1846 s->r.height = ctx->out_q.h;
1850 case V4L2_SEL_TGT_COMPOSE:
1851 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1852 case V4L2_SEL_TGT_COMPOSE_PADDED:
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;
1867 static int s5p_jpeg_s_selection(struct file *file, void *fh,
1868 struct v4l2_selection *s)
1870 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
1871 struct v4l2_rect *rect = &s->r;
1874 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1877 if (s->target == V4L2_SEL_TGT_COMPOSE) {
1878 if (ctx->mode != S5P_JPEG_DECODE)
1880 if (ctx->jpeg->variant->hw3250_compat)
1881 ret = exynos3250_jpeg_try_downscale(ctx, rect);
1882 } else if (s->target == V4L2_SEL_TGT_CROP) {
1883 if (ctx->mode != S5P_JPEG_ENCODE)
1885 if (ctx->jpeg->variant->hw3250_compat)
1886 ret = exynos3250_jpeg_try_crop(ctx, rect);
1892 static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1894 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1895 struct s5p_jpeg *jpeg = ctx->jpeg;
1896 unsigned long flags;
1899 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1900 spin_lock_irqsave(&jpeg->slock, flags);
1901 ctrl->val = s5p_jpeg_to_user_subsampling(ctx);
1902 spin_unlock_irqrestore(&jpeg->slock, flags);
1909 static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val)
1911 switch (ctx->jpeg->variant->version) {
1914 case SJPEG_EXYNOS3250:
1915 case SJPEG_EXYNOS5420:
1917 * The exynos3250/compatible device can produce JPEG image only
1918 * of 4:4:4 subsampling when given RGB32 source image.
1920 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
1925 * The exynos4x12 device requires input raw image fourcc
1926 * to be V4L2_PIX_FMT_GREY if gray jpeg format
1929 if (ctx->out_q.fmt->fourcc != V4L2_PIX_FMT_GREY &&
1930 *ctrl_val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY)
1936 * The exynos4x12 and exynos3250/compatible devices require resulting
1937 * jpeg subsampling not to be lower than the input raw image
1940 if (ctx->out_q.fmt->subsampling > *ctrl_val)
1941 *ctrl_val = ctx->out_q.fmt->subsampling;
1946 static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl)
1948 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1949 unsigned long flags;
1952 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1954 if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING)
1955 ret = s5p_jpeg_adjust_subs_ctrl(ctx, &ctrl->val);
1957 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1961 static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
1963 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1964 unsigned long flags;
1966 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1969 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1970 ctx->compr_quality = ctrl->val;
1972 case V4L2_CID_JPEG_RESTART_INTERVAL:
1973 ctx->restart_interval = ctrl->val;
1975 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1976 ctx->subsampling = ctrl->val;
1980 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1984 static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
1985 .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl,
1986 .try_ctrl = s5p_jpeg_try_ctrl,
1987 .s_ctrl = s5p_jpeg_s_ctrl,
1990 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
1992 unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
1993 struct v4l2_ctrl *ctrl;
1996 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
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,
2001 0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
2003 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
2004 V4L2_CID_JPEG_RESTART_INTERVAL,
2006 if (ctx->jpeg->variant->version == SJPEG_S5P)
2007 mask = ~0x06; /* 422, 420 */
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);
2015 if (ctx->ctrl_handler.error) {
2016 ret = ctx->ctrl_handler.error;
2020 if (ctx->mode == S5P_JPEG_DECODE)
2021 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
2022 V4L2_CTRL_FLAG_READ_ONLY;
2024 ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
2031 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
2035 static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
2036 .vidioc_querycap = s5p_jpeg_querycap,
2038 .vidioc_enum_fmt_vid_cap = s5p_jpeg_enum_fmt_vid_cap,
2039 .vidioc_enum_fmt_vid_out = s5p_jpeg_enum_fmt_vid_out,
2041 .vidioc_g_fmt_vid_cap = s5p_jpeg_g_fmt,
2042 .vidioc_g_fmt_vid_out = s5p_jpeg_g_fmt,
2044 .vidioc_try_fmt_vid_cap = s5p_jpeg_try_fmt_vid_cap,
2045 .vidioc_try_fmt_vid_out = s5p_jpeg_try_fmt_vid_out,
2047 .vidioc_s_fmt_vid_cap = s5p_jpeg_s_fmt_vid_cap,
2048 .vidioc_s_fmt_vid_out = s5p_jpeg_s_fmt_vid_out,
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,
2055 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
2056 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
2058 .vidioc_g_selection = s5p_jpeg_g_selection,
2059 .vidioc_s_selection = s5p_jpeg_s_selection,
2061 .vidioc_subscribe_event = s5p_jpeg_subscribe_event,
2062 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
2066 * ============================================================================
2068 * ============================================================================
2071 static void s5p_jpeg_device_run(void *priv)
2073 struct s5p_jpeg_ctx *ctx = priv;
2074 struct s5p_jpeg *jpeg = ctx->jpeg;
2075 struct vb2_v4l2_buffer *src_buf, *dst_buf;
2076 unsigned long src_addr, dst_addr, flags;
2078 spin_lock_irqsave(&ctx->jpeg->slock, flags);
2080 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2081 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
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);
2085 s5p_jpeg_reset(jpeg->regs);
2086 s5p_jpeg_poweron(jpeg->regs);
2087 s5p_jpeg_proc_mode(jpeg->regs, ctx->mode);
2088 if (ctx->mode == S5P_JPEG_ENCODE) {
2089 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
2090 s5p_jpeg_input_raw_mode(jpeg->regs,
2091 S5P_JPEG_RAW_IN_565);
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);
2102 /* ultimately comes from sizeimage from userspace */
2103 s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
2105 /* JPEG RGB to YCbCr conversion matrix */
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);
2117 * JPEG IP allows storing 4 quantization tables
2118 * We fill table 0 for luma and table 1 for chroma
2120 s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2121 s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2122 /* use table 0 for Y */
2123 s5p_jpeg_qtbl(jpeg->regs, 1, 0);
2124 /* use table 1 for Cb and Cr*/
2125 s5p_jpeg_qtbl(jpeg->regs, 2, 1);
2126 s5p_jpeg_qtbl(jpeg->regs, 3, 1);
2128 /* Y, Cb, Cr use Huffman table 0 */
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);
2135 } else { /* S5P_JPEG_DECODE */
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);
2139 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
2140 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
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);
2147 s5p_jpeg_start(jpeg->regs);
2149 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
2152 static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
2154 struct s5p_jpeg *jpeg = ctx->jpeg;
2155 struct s5p_jpeg_fmt *fmt;
2156 struct vb2_v4l2_buffer *vb;
2157 struct s5p_jpeg_addr jpeg_addr = {};
2158 u32 pix_size, padding_bytes = 0;
2163 pix_size = ctx->cap_q.w * ctx->cap_q.h;
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;
2171 fmt = ctx->cap_q.fmt;
2172 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2175 jpeg_addr.y = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0);
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;
2184 jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
2187 exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr);
2190 static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
2192 struct s5p_jpeg *jpeg = ctx->jpeg;
2193 struct vb2_v4l2_buffer *vb;
2194 unsigned int jpeg_addr = 0;
2196 if (ctx->mode == S5P_JPEG_ENCODE)
2197 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2199 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2201 jpeg_addr = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0);
2202 if (jpeg->variant->version == SJPEG_EXYNOS5433 &&
2203 ctx->mode == S5P_JPEG_DECODE)
2204 jpeg_addr += ctx->out_q.sos;
2205 exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
2208 static inline void exynos4_jpeg_set_img_fmt(void __iomem *base,
2209 unsigned int img_fmt)
2211 __exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS4);
2214 static inline void exynos5433_jpeg_set_img_fmt(void __iomem *base,
2215 unsigned int img_fmt)
2217 __exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS5433);
2220 static inline void exynos4_jpeg_set_enc_out_fmt(void __iomem *base,
2221 unsigned int out_fmt)
2223 __exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS4);
2226 static inline void exynos5433_jpeg_set_enc_out_fmt(void __iomem *base,
2227 unsigned int out_fmt)
2229 __exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS5433);
2232 static void exynos4_jpeg_device_run(void *priv)
2234 struct s5p_jpeg_ctx *ctx = priv;
2235 struct s5p_jpeg *jpeg = ctx->jpeg;
2236 unsigned int bitstream_size;
2237 unsigned long flags;
2239 spin_lock_irqsave(&jpeg->slock, flags);
2241 if (ctx->mode == S5P_JPEG_ENCODE) {
2242 exynos4_jpeg_sw_reset(jpeg->regs);
2243 exynos4_jpeg_set_interrupt(jpeg->regs, jpeg->variant->version);
2244 exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
2246 exynos4_jpeg_set_huff_tbl(jpeg->regs);
2249 * JPEG IP allows storing 4 quantization tables
2250 * We fill table 0 for luma and table 1 for chroma
2252 exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2253 exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
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,
2260 if (ctx->jpeg->variant->version == SJPEG_EXYNOS4) {
2261 exynos4_jpeg_set_enc_out_fmt(jpeg->regs,
2263 exynos4_jpeg_set_img_fmt(jpeg->regs,
2264 ctx->out_q.fmt->fourcc);
2266 exynos5433_jpeg_set_enc_out_fmt(jpeg->regs,
2268 exynos5433_jpeg_set_img_fmt(jpeg->regs,
2269 ctx->out_q.fmt->fourcc);
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);
2276 exynos4_jpeg_sw_reset(jpeg->regs);
2277 exynos4_jpeg_set_interrupt(jpeg->regs,
2278 jpeg->variant->version);
2279 exynos4_jpeg_set_img_addr(ctx);
2280 exynos4_jpeg_set_jpeg_addr(ctx);
2282 if (jpeg->variant->version == SJPEG_EXYNOS5433) {
2283 exynos4_jpeg_parse_huff_tbl(ctx);
2284 exynos4_jpeg_parse_decode_h_tbl(ctx);
2286 exynos4_jpeg_parse_q_tbl(ctx);
2287 exynos4_jpeg_parse_decode_q_tbl(ctx);
2289 exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
2291 exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
2293 exynos5433_jpeg_set_enc_out_fmt(jpeg->regs,
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);
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);
2304 exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
2307 exynos4_jpeg_set_sys_int_enable(jpeg->regs, 1);
2308 exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
2310 spin_unlock_irqrestore(&jpeg->slock, flags);
2313 static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
2315 struct s5p_jpeg *jpeg = ctx->jpeg;
2316 struct s5p_jpeg_fmt *fmt;
2317 struct vb2_v4l2_buffer *vb;
2318 struct s5p_jpeg_addr jpeg_addr = {};
2321 pix_size = ctx->cap_q.w * ctx->cap_q.h;
2323 if (ctx->mode == S5P_JPEG_ENCODE) {
2324 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2325 fmt = ctx->out_q.fmt;
2327 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2328 fmt = ctx->cap_q.fmt;
2331 jpeg_addr.y = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0);
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;
2340 jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
2343 exynos3250_jpeg_imgadr(jpeg->regs, &jpeg_addr);
2346 static void exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
2348 struct s5p_jpeg *jpeg = ctx->jpeg;
2349 struct vb2_v4l2_buffer *vb;
2350 unsigned int jpeg_addr = 0;
2352 if (ctx->mode == S5P_JPEG_ENCODE)
2353 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2355 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2357 jpeg_addr = vb2_dma_contig_plane_dma_addr(&vb->vb2_buf, 0);
2358 exynos3250_jpeg_jpgadr(jpeg->regs, jpeg_addr);
2361 static void exynos3250_jpeg_device_run(void *priv)
2363 struct s5p_jpeg_ctx *ctx = priv;
2364 struct s5p_jpeg *jpeg = ctx->jpeg;
2365 unsigned long flags;
2367 spin_lock_irqsave(&ctx->jpeg->slock, flags);
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);
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);
2381 * JPEG IP allows storing 4 quantization tables
2382 * We fill table 0 for luma and table 1 for chroma
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);
2393 * Some SoCs require setting Huffman tables before each run
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);
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);
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,
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);
2420 /* ultimately comes from sizeimage from userspace */
2421 exynos3250_jpeg_enc_stream_bound(jpeg->regs, ctx->cap_q.size);
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);
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,
2432 exynos3250_jpeg_offset(jpeg->regs, 0, 0);
2433 exynos3250_jpeg_dec_scaling_ratio(jpeg->regs,
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);
2440 exynos3250_jpeg_interrupts_enable(jpeg->regs);
2442 /* JPEG RGB to YCbCr conversion matrix */
2443 exynos3250_jpeg_coef(jpeg->regs, ctx->mode);
2445 exynos3250_jpeg_set_timer(jpeg->regs, EXYNOS3250_IRQ_TIMEOUT);
2446 jpeg->irq_status = 0;
2447 exynos3250_jpeg_start(jpeg->regs);
2449 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
2452 static int s5p_jpeg_job_ready(void *priv)
2454 struct s5p_jpeg_ctx *ctx = priv;
2456 if (ctx->mode == S5P_JPEG_DECODE) {
2458 * We have only one input buffer and one output buffer. If there
2459 * is a resolution change event, no need to continue decoding.
2461 if (ctx->state == JPEGCTX_RESOLUTION_CHANGE)
2464 return ctx->hdr_parsed;
2470 static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
2471 .device_run = s5p_jpeg_device_run,
2472 .job_ready = s5p_jpeg_job_ready,
2475 static struct v4l2_m2m_ops exynos3250_jpeg_m2m_ops = {
2476 .device_run = exynos3250_jpeg_device_run,
2477 .job_ready = s5p_jpeg_job_ready,
2480 static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = {
2481 .device_run = exynos4_jpeg_device_run,
2482 .job_ready = s5p_jpeg_job_ready,
2486 * ============================================================================
2488 * ============================================================================
2491 static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
2492 unsigned int *nbuffers, unsigned int *nplanes,
2493 unsigned int sizes[], struct device *alloc_devs[])
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;
2499 q_data = get_q_data(ctx, vq->type);
2500 BUG_ON(q_data == NULL);
2502 size = q_data->size;
2505 * header is parsed during decoding and parsed information stored
2506 * in the context so we do not allow another buffer to overwrite it
2508 if (ctx->mode == S5P_JPEG_DECODE)
2518 static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
2520 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2521 struct s5p_jpeg_q_data *q_data = NULL;
2523 q_data = get_q_data(ctx, vb->vb2_queue->type);
2524 BUG_ON(q_data == NULL);
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);
2533 vb2_set_plane_payload(vb, 0, q_data->size);
2538 static void s5p_jpeg_set_capture_queue_data(struct s5p_jpeg_ctx *ctx)
2540 struct s5p_jpeg_q_data *q_data = &ctx->cap_q;
2542 q_data->w = ctx->out_q.w;
2543 q_data->h = ctx->out_q.h;
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
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);
2559 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
2562 static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
2564 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
2565 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2567 if (ctx->mode == S5P_JPEG_DECODE &&
2568 vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
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,
2573 struct vb2_queue *dst_vq;
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;
2582 ctx->hdr_parsed = s5p_jpeg_parse_hdr(&ctx->out_q,
2583 (unsigned long)vb2_plane_vaddr(vb, 0),
2584 min((unsigned long)ctx->out_q.size,
2585 vb2_get_plane_payload(vb, 0)), ctx);
2586 if (!ctx->hdr_parsed) {
2587 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
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.
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;
2601 s5p_jpeg_set_capture_queue_data(ctx);
2605 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
2608 static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
2610 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
2613 ret = pm_runtime_get_sync(ctx->jpeg->dev);
2615 return ret > 0 ? 0 : ret;
2618 static void s5p_jpeg_stop_streaming(struct vb2_queue *q)
2620 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
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.
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;
2633 pm_runtime_put(ctx->jpeg->dev);
2636 static const struct vb2_ops s5p_jpeg_qops = {
2637 .queue_setup = s5p_jpeg_queue_setup,
2638 .buf_prepare = s5p_jpeg_buf_prepare,
2639 .buf_queue = s5p_jpeg_buf_queue,
2640 .wait_prepare = vb2_ops_wait_prepare,
2641 .wait_finish = vb2_ops_wait_finish,
2642 .start_streaming = s5p_jpeg_start_streaming,
2643 .stop_streaming = s5p_jpeg_stop_streaming,
2646 static int queue_init(void *priv, struct vb2_queue *src_vq,
2647 struct vb2_queue *dst_vq)
2649 struct s5p_jpeg_ctx *ctx = priv;
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;
2658 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2659 src_vq->lock = &ctx->jpeg->lock;
2660 src_vq->dev = ctx->jpeg->dev;
2662 ret = vb2_queue_init(src_vq);
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;
2672 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2673 dst_vq->lock = &ctx->jpeg->lock;
2674 dst_vq->dev = ctx->jpeg->dev;
2676 return vb2_queue_init(dst_vq);
2680 * ============================================================================
2682 * ============================================================================
2685 static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
2687 struct s5p_jpeg *jpeg = dev_id;
2688 struct s5p_jpeg_ctx *curr_ctx;
2689 struct vb2_v4l2_buffer *src_buf, *dst_buf;
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;
2696 spin_lock(&jpeg->slock);
2698 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
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);
2703 if (curr_ctx->mode == S5P_JPEG_ENCODE)
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);
2707 if (curr_ctx->mode == S5P_JPEG_DECODE)
2708 op_completed = op_completed &&
2709 s5p_jpeg_stream_stat_ok(jpeg->regs);
2711 if (enc_jpeg_too_large) {
2712 state = VB2_BUF_STATE_ERROR;
2713 s5p_jpeg_clear_enc_stream_stat(jpeg->regs);
2714 } else if (timer_elapsed) {
2715 state = VB2_BUF_STATE_ERROR;
2716 s5p_jpeg_clear_timer_stat(jpeg->regs);
2717 } else if (!op_completed) {
2718 state = VB2_BUF_STATE_ERROR;
2720 payload_size = s5p_jpeg_compressed_size(jpeg->regs);
2723 dst_buf->timecode = src_buf->timecode;
2724 dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
2725 dst_buf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
2727 src_buf->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
2729 v4l2_m2m_buf_done(src_buf, state);
2730 if (curr_ctx->mode == S5P_JPEG_ENCODE)
2731 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size);
2732 v4l2_m2m_buf_done(dst_buf, state);
2734 curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs);
2735 spin_unlock(&jpeg->slock);
2737 s5p_jpeg_clear_int(jpeg->regs);
2739 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2743 static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
2745 unsigned int int_status;
2746 struct vb2_v4l2_buffer *src_vb, *dst_vb;
2747 struct s5p_jpeg *jpeg = priv;
2748 struct s5p_jpeg_ctx *curr_ctx;
2749 unsigned long payload_size = 0;
2751 spin_lock(&jpeg->slock);
2753 exynos4_jpeg_set_sys_int_enable(jpeg->regs, 0);
2755 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
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);
2760 int_status = exynos4_jpeg_get_int_status(jpeg->regs);
2763 switch (int_status & 0x1f) {
2765 jpeg->irq_ret = ERR_PROT;
2768 jpeg->irq_ret = OK_ENC_OR_DEC;
2771 jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
2774 jpeg->irq_ret = ERR_MULTI_SCAN;
2777 jpeg->irq_ret = ERR_FRAME;
2780 jpeg->irq_ret = ERR_UNKNOWN;
2784 jpeg->irq_ret = ERR_UNKNOWN;
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);
2790 vb2_set_plane_payload(&dst_vb->vb2_buf,
2793 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
2794 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
2796 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
2797 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
2800 if (jpeg->variant->version == SJPEG_EXYNOS4)
2801 curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
2803 exynos4_jpeg_set_enc_dec_mode(jpeg->regs, S5P_JPEG_DISABLE);
2805 spin_unlock(&jpeg->slock);
2807 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2811 static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id)
2813 struct s5p_jpeg *jpeg = dev_id;
2814 struct s5p_jpeg_ctx *curr_ctx;
2815 struct vb2_v4l2_buffer *src_buf, *dst_buf;
2816 unsigned long payload_size = 0;
2817 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
2818 bool interrupt_timeout = false;
2819 bool stream_error = false;
2822 spin_lock(&jpeg->slock);
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");
2831 irq_status = exynos3250_jpeg_get_int_status(jpeg->regs);
2832 exynos3250_jpeg_clear_int_status(jpeg->regs, irq_status);
2834 jpeg->irq_status |= irq_status;
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");
2842 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2847 if ((irq_status & EXYNOS3250_HEADER_STAT) &&
2848 (curr_ctx->mode == S5P_JPEG_DECODE)) {
2849 exynos3250_jpeg_rstart(jpeg->regs);
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);
2858 else if (interrupt_timeout || stream_error)
2859 state = VB2_BUF_STATE_ERROR;
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);
2866 dst_buf->timecode = src_buf->timecode;
2867 dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
2869 v4l2_m2m_buf_done(src_buf, state);
2870 if (curr_ctx->mode == S5P_JPEG_ENCODE)
2871 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size);
2872 v4l2_m2m_buf_done(dst_buf, state);
2874 curr_ctx->subsampling =
2875 exynos3250_jpeg_get_subsampling_mode(jpeg->regs);
2877 spin_unlock(&jpeg->slock);
2879 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2883 spin_unlock(&jpeg->slock);
2887 static void *jpeg_get_drv_data(struct device *dev);
2890 * ============================================================================
2891 * Driver basic infrastructure
2892 * ============================================================================
2895 static int s5p_jpeg_probe(struct platform_device *pdev)
2897 struct s5p_jpeg *jpeg;
2898 struct resource *res;
2901 /* JPEG IP abstraction struct */
2902 jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
2906 jpeg->variant = jpeg_get_drv_data(&pdev->dev);
2908 mutex_init(&jpeg->lock);
2909 spin_lock_init(&jpeg->slock);
2910 jpeg->dev = &pdev->dev;
2912 /* memory-mapped registers */
2913 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2915 jpeg->regs = devm_ioremap_resource(&pdev->dev, res);
2916 if (IS_ERR(jpeg->regs))
2917 return PTR_ERR(jpeg->regs);
2919 /* interrupt service routine registration */
2920 jpeg->irq = ret = platform_get_irq(pdev, 0);
2922 dev_err(&pdev->dev, "cannot find IRQ\n");
2926 ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
2927 0, dev_name(&pdev->dev), jpeg);
2929 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
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]);
2945 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
2947 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
2951 /* mem2mem device */
2952 jpeg->m2m_dev = v4l2_m2m_init(jpeg->variant->m2m_ops);
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;
2959 vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
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");
2966 goto m2m_init_rollback;
2968 snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name),
2969 "%s-enc", S5P_JPEG_M2M_NAME);
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;
2976 jpeg->vfd_encoder->vfl_dir = VFL_DIR_M2M;
2978 ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
2980 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
2981 video_device_release(jpeg->vfd_encoder);
2982 goto m2m_init_rollback;
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);
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");
2995 goto enc_vdev_register_rollback;
2997 snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name),
2998 "%s-dec", S5P_JPEG_M2M_NAME);
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;
3005 jpeg->vfd_decoder->vfl_dir = VFL_DIR_M2M;
3007 ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
3009 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
3010 video_device_release(jpeg->vfd_decoder);
3011 goto enc_vdev_register_rollback;
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);
3019 /* final statements & power management */
3020 platform_set_drvdata(pdev, jpeg);
3022 pm_runtime_enable(&pdev->dev);
3024 v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
3028 enc_vdev_register_rollback:
3029 video_unregister_device(jpeg->vfd_encoder);
3032 v4l2_m2m_release(jpeg->m2m_dev);
3034 device_register_rollback:
3035 v4l2_device_unregister(&jpeg->v4l2_dev);
3040 static int s5p_jpeg_remove(struct platform_device *pdev)
3042 struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
3045 pm_runtime_disable(jpeg->dev);
3047 video_unregister_device(jpeg->vfd_decoder);
3048 video_unregister_device(jpeg->vfd_encoder);
3049 vb2_dma_contig_clear_max_seg_size(&pdev->dev);
3050 v4l2_m2m_release(jpeg->m2m_dev);
3051 v4l2_device_unregister(&jpeg->v4l2_dev);
3053 if (!pm_runtime_status_suspended(&pdev->dev)) {
3054 for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
3055 clk_disable_unprepare(jpeg->clocks[i]);
3062 static int s5p_jpeg_runtime_suspend(struct device *dev)
3064 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
3067 for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
3068 clk_disable_unprepare(jpeg->clocks[i]);
3073 static int s5p_jpeg_runtime_resume(struct device *dev)
3075 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
3076 unsigned long flags;
3079 for (i = 0; i < jpeg->variant->num_clocks; i++) {
3080 ret = clk_prepare_enable(jpeg->clocks[i]);
3083 clk_disable_unprepare(jpeg->clocks[i]);
3088 spin_lock_irqsave(&jpeg->slock, flags);
3091 * JPEG IP allows storing two Huffman tables for each component.
3092 * We fill table 0 for each component and do this here only
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.
3098 if (!jpeg->variant->htbl_reinit) {
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);
3105 spin_unlock_irqrestore(&jpeg->slock, flags);
3109 #endif /* CONFIG_PM */
3111 static const struct dev_pm_ops s5p_jpeg_pm_ops = {
3112 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
3113 pm_runtime_force_resume)
3114 SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume,
3118 static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
3119 .version = SJPEG_S5P,
3120 .jpeg_irq = s5p_jpeg_irq,
3121 .m2m_ops = &s5p_jpeg_m2m_ops,
3122 .fmt_ver_flag = SJPEG_FMT_FLAG_S5P,
3123 .clk_names = {"jpeg"},
3127 static 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,
3133 .clk_names = {"jpeg", "sclk"},
3137 static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
3138 .version = SJPEG_EXYNOS4,
3139 .jpeg_irq = exynos4_jpeg_irq,
3140 .m2m_ops = &exynos4_jpeg_m2m_ops,
3141 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4,
3143 .clk_names = {"jpeg"},
3148 static 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 */
3155 .clk_names = {"jpeg"},
3159 static 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,
3165 .clk_names = {"pclk", "aclk", "aclk_xiu", "sclk"},
3170 static const struct of_device_id samsung_jpeg_match[] = {
3172 .compatible = "samsung,s5pv210-jpeg",
3173 .data = &s5p_jpeg_drvdata,
3175 .compatible = "samsung,exynos3250-jpeg",
3176 .data = &exynos3250_jpeg_drvdata,
3178 .compatible = "samsung,exynos4210-jpeg",
3179 .data = &exynos4_jpeg_drvdata,
3181 .compatible = "samsung,exynos4212-jpeg",
3182 .data = &exynos4_jpeg_drvdata,
3184 .compatible = "samsung,exynos5420-jpeg",
3185 .data = &exynos5420_jpeg_drvdata,
3187 .compatible = "samsung,exynos5433-jpeg",
3188 .data = &exynos5433_jpeg_drvdata,
3193 MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
3195 static void *jpeg_get_drv_data(struct device *dev)
3197 struct s5p_jpeg_variant *driver_data = NULL;
3198 const struct of_device_id *match;
3200 if (!IS_ENABLED(CONFIG_OF) || !dev->of_node)
3201 return &s5p_jpeg_drvdata;
3203 match = of_match_node(samsung_jpeg_match, dev->of_node);
3206 driver_data = (struct s5p_jpeg_variant *)match->data;
3211 static struct platform_driver s5p_jpeg_driver = {
3212 .probe = s5p_jpeg_probe,
3213 .remove = s5p_jpeg_remove,
3215 .of_match_table = of_match_ptr(samsung_jpeg_match),
3216 .name = S5P_JPEG_M2M_NAME,
3217 .pm = &s5p_jpeg_pm_ops,
3221 module_platform_driver(s5p_jpeg_driver);
3223 MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>");
3224 MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
3225 MODULE_DESCRIPTION("Samsung JPEG codec driver");
3226 MODULE_LICENSE("GPL");