1 /* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c
3 * Copyright (c) 2011-2014 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>
19 #include <linux/kernel.h>
20 #include <linux/module.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-event.h>
28 #include <media/v4l2-mem2mem.h>
29 #include <media/v4l2-ioctl.h>
30 #include <media/videobuf2-v4l2.h>
31 #include <media/videobuf2-dma-contig.h>
33 #include "jpeg-core.h"
34 #include "jpeg-hw-s5p.h"
35 #include "jpeg-hw-exynos4.h"
36 #include "jpeg-hw-exynos3250.h"
37 #include "jpeg-regs.h"
39 static struct s5p_jpeg_fmt sjpeg_formats[] = {
42 .fourcc = V4L2_PIX_FMT_JPEG,
43 .flags = SJPEG_FMT_FLAG_ENC_CAPTURE |
44 SJPEG_FMT_FLAG_DEC_OUTPUT |
46 SJPEG_FMT_FLAG_EXYNOS3250 |
47 SJPEG_FMT_FLAG_EXYNOS4,
50 .name = "YUV 4:2:2 packed, YCbYCr",
51 .fourcc = V4L2_PIX_FMT_YUYV,
56 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
57 SJPEG_FMT_FLAG_DEC_CAPTURE |
60 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
63 .name = "YUV 4:2:2 packed, YCbYCr",
64 .fourcc = V4L2_PIX_FMT_YUYV,
69 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
70 SJPEG_FMT_FLAG_DEC_CAPTURE |
71 SJPEG_FMT_FLAG_EXYNOS4 |
73 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
76 .name = "YUV 4:2:2 packed, YCbYCr",
77 .fourcc = V4L2_PIX_FMT_YUYV,
82 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
83 SJPEG_FMT_FLAG_DEC_CAPTURE |
84 SJPEG_FMT_FLAG_EXYNOS3250 |
86 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
89 .name = "YUV 4:2:2 packed, YCrYCb",
90 .fourcc = V4L2_PIX_FMT_YVYU,
95 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
96 SJPEG_FMT_FLAG_DEC_CAPTURE |
97 SJPEG_FMT_FLAG_EXYNOS4 |
99 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
102 .name = "YUV 4:2:2 packed, YCrYCb",
103 .fourcc = V4L2_PIX_FMT_YVYU,
108 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
109 SJPEG_FMT_FLAG_DEC_CAPTURE |
110 SJPEG_FMT_FLAG_EXYNOS3250 |
112 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
115 .name = "YUV 4:2:2 packed, YCrYCb",
116 .fourcc = V4L2_PIX_FMT_UYVY,
121 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
122 SJPEG_FMT_FLAG_DEC_CAPTURE |
123 SJPEG_FMT_FLAG_EXYNOS3250 |
125 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
128 .name = "YUV 4:2:2 packed, YCrYCb",
129 .fourcc = V4L2_PIX_FMT_VYUY,
134 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
135 SJPEG_FMT_FLAG_DEC_CAPTURE |
136 SJPEG_FMT_FLAG_EXYNOS3250 |
138 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
142 .fourcc = V4L2_PIX_FMT_RGB565,
147 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
148 SJPEG_FMT_FLAG_DEC_CAPTURE |
149 SJPEG_FMT_FLAG_EXYNOS4 |
151 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
155 .fourcc = V4L2_PIX_FMT_RGB565,
160 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
161 SJPEG_FMT_FLAG_DEC_CAPTURE |
162 SJPEG_FMT_FLAG_EXYNOS3250 |
164 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
168 .fourcc = V4L2_PIX_FMT_RGB565X,
173 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
174 SJPEG_FMT_FLAG_DEC_CAPTURE |
175 SJPEG_FMT_FLAG_EXYNOS3250 |
177 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
181 .fourcc = V4L2_PIX_FMT_RGB565,
186 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
189 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
192 .name = "ARGB8888, 32 bpp",
193 .fourcc = V4L2_PIX_FMT_RGB32,
198 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
199 SJPEG_FMT_FLAG_DEC_CAPTURE |
200 SJPEG_FMT_FLAG_EXYNOS4 |
202 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
205 .name = "ARGB8888, 32 bpp",
206 .fourcc = V4L2_PIX_FMT_RGB32,
211 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
212 SJPEG_FMT_FLAG_DEC_CAPTURE |
213 SJPEG_FMT_FLAG_EXYNOS3250 |
215 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
218 .name = "YUV 4:4:4 planar, Y/CbCr",
219 .fourcc = V4L2_PIX_FMT_NV24,
224 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
225 SJPEG_FMT_FLAG_DEC_CAPTURE |
226 SJPEG_FMT_FLAG_EXYNOS4 |
228 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
231 .name = "YUV 4:4:4 planar, Y/CrCb",
232 .fourcc = V4L2_PIX_FMT_NV42,
237 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
238 SJPEG_FMT_FLAG_DEC_CAPTURE |
239 SJPEG_FMT_FLAG_EXYNOS4 |
241 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
244 .name = "YUV 4:2:2 planar, Y/CrCb",
245 .fourcc = V4L2_PIX_FMT_NV61,
250 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
251 SJPEG_FMT_FLAG_DEC_CAPTURE |
252 SJPEG_FMT_FLAG_EXYNOS4 |
254 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
257 .name = "YUV 4:2:2 planar, Y/CbCr",
258 .fourcc = V4L2_PIX_FMT_NV16,
263 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
264 SJPEG_FMT_FLAG_DEC_CAPTURE |
265 SJPEG_FMT_FLAG_EXYNOS4 |
267 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
270 .name = "YUV 4:2:0 planar, Y/CbCr",
271 .fourcc = V4L2_PIX_FMT_NV12,
276 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
277 SJPEG_FMT_FLAG_DEC_CAPTURE |
278 SJPEG_FMT_FLAG_EXYNOS4 |
280 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
283 .name = "YUV 4:2:0 planar, Y/CbCr",
284 .fourcc = V4L2_PIX_FMT_NV12,
289 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
290 SJPEG_FMT_FLAG_DEC_CAPTURE |
291 SJPEG_FMT_FLAG_EXYNOS3250 |
293 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
296 .name = "YUV 4:2:0 planar, Y/CbCr",
297 .fourcc = V4L2_PIX_FMT_NV12,
302 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
303 SJPEG_FMT_FLAG_DEC_CAPTURE |
306 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
309 .name = "YUV 4:2:0 planar, Y/CrCb",
310 .fourcc = V4L2_PIX_FMT_NV21,
315 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
316 SJPEG_FMT_FLAG_DEC_CAPTURE |
317 SJPEG_FMT_FLAG_EXYNOS3250 |
319 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
322 .name = "YUV 4:2:0 planar, Y/CrCb",
323 .fourcc = V4L2_PIX_FMT_NV21,
328 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
329 SJPEG_FMT_FLAG_DEC_CAPTURE |
330 SJPEG_FMT_FLAG_EXYNOS3250 |
331 SJPEG_FMT_FLAG_EXYNOS4 |
333 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
336 .name = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
337 .fourcc = V4L2_PIX_FMT_YUV420,
342 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
343 SJPEG_FMT_FLAG_DEC_CAPTURE |
344 SJPEG_FMT_FLAG_EXYNOS4 |
346 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
349 .name = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
350 .fourcc = V4L2_PIX_FMT_YUV420,
355 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
356 SJPEG_FMT_FLAG_DEC_CAPTURE |
357 SJPEG_FMT_FLAG_EXYNOS3250 |
359 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
363 .fourcc = V4L2_PIX_FMT_GREY,
366 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
367 SJPEG_FMT_FLAG_DEC_CAPTURE |
368 SJPEG_FMT_FLAG_EXYNOS4 |
370 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
373 #define SJPEG_NUM_FORMATS ARRAY_SIZE(sjpeg_formats)
375 static const unsigned char qtbl_luminance[4][64] = {
376 {/*level 0 - high compression quality */
377 20, 16, 25, 39, 50, 46, 62, 68,
378 16, 18, 23, 38, 38, 53, 65, 68,
379 25, 23, 31, 38, 53, 65, 68, 68,
380 39, 38, 38, 53, 65, 68, 68, 68,
381 50, 38, 53, 65, 68, 68, 68, 68,
382 46, 53, 65, 68, 68, 68, 68, 68,
383 62, 65, 68, 68, 68, 68, 68, 68,
384 68, 68, 68, 68, 68, 68, 68, 68
387 16, 11, 11, 16, 23, 27, 31, 30,
388 11, 12, 12, 15, 20, 23, 23, 30,
389 11, 12, 13, 16, 23, 26, 35, 47,
390 16, 15, 16, 23, 26, 37, 47, 64,
391 23, 20, 23, 26, 39, 51, 64, 64,
392 27, 23, 26, 37, 51, 64, 64, 64,
393 31, 23, 35, 47, 64, 64, 64, 64,
394 30, 30, 47, 64, 64, 64, 64, 64
397 12, 8, 8, 12, 17, 21, 24, 23,
398 8, 9, 9, 11, 15, 19, 18, 23,
399 8, 9, 10, 12, 19, 20, 27, 36,
400 12, 11, 12, 21, 20, 28, 36, 53,
401 17, 15, 19, 20, 30, 39, 51, 59,
402 21, 19, 20, 28, 39, 51, 59, 59,
403 24, 18, 27, 36, 51, 59, 59, 59,
404 23, 23, 36, 53, 59, 59, 59, 59
406 {/* level 3 - low compression quality */
407 8, 6, 6, 8, 12, 14, 16, 17,
408 6, 6, 6, 8, 10, 13, 12, 15,
409 6, 6, 7, 8, 13, 14, 18, 24,
410 8, 8, 8, 14, 13, 19, 24, 35,
411 12, 10, 13, 13, 20, 26, 34, 39,
412 14, 13, 14, 19, 26, 34, 39, 39,
413 16, 12, 18, 24, 34, 39, 39, 39,
414 17, 15, 24, 35, 39, 39, 39, 39
418 static const unsigned char qtbl_chrominance[4][64] = {
419 {/*level 0 - high compression quality */
420 21, 25, 32, 38, 54, 68, 68, 68,
421 25, 28, 24, 38, 54, 68, 68, 68,
422 32, 24, 32, 43, 66, 68, 68, 68,
423 38, 38, 43, 53, 68, 68, 68, 68,
424 54, 54, 66, 68, 68, 68, 68, 68,
425 68, 68, 68, 68, 68, 68, 68, 68,
426 68, 68, 68, 68, 68, 68, 68, 68,
427 68, 68, 68, 68, 68, 68, 68, 68
430 17, 15, 17, 21, 20, 26, 38, 48,
431 15, 19, 18, 17, 20, 26, 35, 43,
432 17, 18, 20, 22, 26, 30, 46, 53,
433 21, 17, 22, 28, 30, 39, 53, 64,
434 20, 20, 26, 30, 39, 48, 64, 64,
435 26, 26, 30, 39, 48, 63, 64, 64,
436 38, 35, 46, 53, 64, 64, 64, 64,
437 48, 43, 53, 64, 64, 64, 64, 64
440 13, 11, 13, 16, 20, 20, 29, 37,
441 11, 14, 14, 14, 16, 20, 26, 32,
442 13, 14, 15, 17, 20, 23, 35, 40,
443 16, 14, 17, 21, 23, 30, 40, 50,
444 20, 16, 20, 23, 30, 37, 50, 59,
445 20, 20, 23, 30, 37, 48, 59, 59,
446 29, 26, 35, 40, 50, 59, 59, 59,
447 37, 32, 40, 50, 59, 59, 59, 59
449 {/* level 3 - low compression quality */
450 9, 8, 9, 11, 14, 17, 19, 24,
451 8, 10, 9, 11, 14, 13, 17, 22,
452 9, 9, 13, 14, 13, 15, 23, 26,
453 11, 11, 14, 14, 15, 20, 26, 33,
454 14, 14, 13, 15, 20, 24, 33, 39,
455 17, 13, 15, 20, 24, 32, 39, 39,
456 19, 17, 23, 26, 33, 39, 39, 39,
457 24, 22, 26, 33, 39, 39, 39, 39
461 static const unsigned char hdctbl0[16] = {
462 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
465 static const unsigned char hdctblg0[12] = {
466 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
468 static const unsigned char hactbl0[16] = {
469 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
471 static const unsigned char hactblg0[162] = {
472 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
473 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
474 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
475 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
476 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
477 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
478 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
479 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
480 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
481 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
482 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
483 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
484 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
485 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
486 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
487 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
488 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
489 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
490 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
491 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
496 * Fourcc downgrade schema lookup tables for 422 and 420
497 * chroma subsampling - fourcc on each position maps on the
498 * fourcc from the table fourcc_to_dwngrd_schema_id which allows
499 * to get the most suitable fourcc counterpart for the given
500 * downgraded subsampling property.
502 static const u32 subs422_fourcc_dwngrd_schema[] = {
507 static const u32 subs420_fourcc_dwngrd_schema[] = {
521 * Lookup table for translation of a fourcc to the position
522 * of its downgraded counterpart in the *fourcc_dwngrd_schema
525 static const u32 fourcc_to_dwngrd_schema_id[] = {
538 static int s5p_jpeg_get_dwngrd_sch_id_by_fourcc(u32 fourcc)
542 for (i = 0; i < ARRAY_SIZE(fourcc_to_dwngrd_schema_id); ++i) {
543 if (fourcc_to_dwngrd_schema_id[i] == fourcc)
550 static int s5p_jpeg_adjust_fourcc_to_subsampling(
551 enum v4l2_jpeg_chroma_subsampling subs,
554 struct s5p_jpeg_ctx *ctx)
558 if (ctx->subsampling != V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
560 s5p_jpeg_get_dwngrd_sch_id_by_fourcc(in_fourcc);
561 if (dwngrd_sch_id < 0)
565 switch (ctx->subsampling) {
566 case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
567 *out_fourcc = V4L2_PIX_FMT_GREY;
569 case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
571 ARRAY_SIZE(subs420_fourcc_dwngrd_schema) - 1)
573 *out_fourcc = subs420_fourcc_dwngrd_schema[dwngrd_sch_id];
575 case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
577 ARRAY_SIZE(subs422_fourcc_dwngrd_schema) - 1)
579 *out_fourcc = subs422_fourcc_dwngrd_schema[dwngrd_sch_id];
582 *out_fourcc = V4L2_PIX_FMT_GREY;
589 static int exynos4x12_decoded_subsampling[] = {
590 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
591 V4L2_JPEG_CHROMA_SUBSAMPLING_444,
592 V4L2_JPEG_CHROMA_SUBSAMPLING_422,
593 V4L2_JPEG_CHROMA_SUBSAMPLING_420,
596 static int exynos3250_decoded_subsampling[] = {
597 V4L2_JPEG_CHROMA_SUBSAMPLING_444,
598 V4L2_JPEG_CHROMA_SUBSAMPLING_422,
599 V4L2_JPEG_CHROMA_SUBSAMPLING_420,
600 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
603 V4L2_JPEG_CHROMA_SUBSAMPLING_411,
606 static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
608 return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
611 static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
613 return container_of(fh, struct s5p_jpeg_ctx, fh);
616 static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
618 switch (ctx->jpeg->variant->version) {
620 WARN_ON(ctx->subsampling > 3);
621 if (ctx->subsampling > 2)
622 return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
623 return ctx->subsampling;
624 case SJPEG_EXYNOS3250:
625 case SJPEG_EXYNOS5420:
626 WARN_ON(ctx->subsampling > 6);
627 if (ctx->subsampling > 3)
628 return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
629 return exynos3250_decoded_subsampling[ctx->subsampling];
631 case SJPEG_EXYNOS5433:
632 WARN_ON(ctx->subsampling > 3);
633 if (ctx->subsampling > 2)
634 return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
635 return exynos4x12_decoded_subsampling[ctx->subsampling];
637 WARN_ON(ctx->subsampling > 3);
638 return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
642 static inline void s5p_jpeg_set_qtbl(void __iomem *regs,
643 const unsigned char *qtbl,
644 unsigned long tab, int len)
648 for (i = 0; i < len; i++)
649 writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
652 static inline void s5p_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
654 /* this driver fills quantisation table 0 with data for luma */
655 s5p_jpeg_set_qtbl(regs, qtbl_luminance[quality],
656 S5P_JPG_QTBL_CONTENT(0),
657 ARRAY_SIZE(qtbl_luminance[quality]));
660 static inline void s5p_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
662 /* this driver fills quantisation table 1 with data for chroma */
663 s5p_jpeg_set_qtbl(regs, qtbl_chrominance[quality],
664 S5P_JPG_QTBL_CONTENT(1),
665 ARRAY_SIZE(qtbl_chrominance[quality]));
668 static inline void s5p_jpeg_set_htbl(void __iomem *regs,
669 const unsigned char *htbl,
670 unsigned long tab, int len)
674 for (i = 0; i < len; i++)
675 writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
678 static inline void s5p_jpeg_set_hdctbl(void __iomem *regs)
680 /* this driver fills table 0 for this component */
681 s5p_jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0),
682 ARRAY_SIZE(hdctbl0));
685 static inline void s5p_jpeg_set_hdctblg(void __iomem *regs)
687 /* this driver fills table 0 for this component */
688 s5p_jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0),
689 ARRAY_SIZE(hdctblg0));
692 static inline void s5p_jpeg_set_hactbl(void __iomem *regs)
694 /* this driver fills table 0 for this component */
695 s5p_jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0),
696 ARRAY_SIZE(hactbl0));
699 static inline void s5p_jpeg_set_hactblg(void __iomem *regs)
701 /* this driver fills table 0 for this component */
702 s5p_jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0),
703 ARRAY_SIZE(hactblg0));
706 static inline void exynos4_jpeg_set_tbl(void __iomem *regs,
707 const unsigned char *tbl,
708 unsigned long tab, int len)
713 for (i = 0; i < len; i += 4) {
718 writel(dword, regs + tab + i);
722 static inline void exynos4_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
724 /* this driver fills quantisation table 0 with data for luma */
725 exynos4_jpeg_set_tbl(regs, qtbl_luminance[quality],
726 EXYNOS4_QTBL_CONTENT(0),
727 ARRAY_SIZE(qtbl_luminance[quality]));
730 static inline void exynos4_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
732 /* this driver fills quantisation table 1 with data for chroma */
733 exynos4_jpeg_set_tbl(regs, qtbl_chrominance[quality],
734 EXYNOS4_QTBL_CONTENT(1),
735 ARRAY_SIZE(qtbl_chrominance[quality]));
738 static void exynos4_jpeg_set_huff_tbl(void __iomem *base)
740 exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCLL,
741 ARRAY_SIZE(hdctbl0));
742 exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCCL,
743 ARRAY_SIZE(hdctbl0));
744 exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCLV,
745 ARRAY_SIZE(hdctblg0));
746 exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCCV,
747 ARRAY_SIZE(hdctblg0));
748 exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACLL,
749 ARRAY_SIZE(hactbl0));
750 exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACCL,
751 ARRAY_SIZE(hactbl0));
752 exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACLV,
753 ARRAY_SIZE(hactblg0));
754 exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACCV,
755 ARRAY_SIZE(hactblg0));
758 static inline int __exynos4_huff_tbl(int class, int id, bool lenval)
761 * class: 0 - DC, 1 - AC
762 * id: 0 - Y, 1 - Cb/Cr
766 return lenval ? EXYNOS4_HUFF_TBL_HACCL :
767 EXYNOS4_HUFF_TBL_HACCV;
768 return lenval ? EXYNOS4_HUFF_TBL_HACLL : EXYNOS4_HUFF_TBL_HACLV;
773 return lenval ? EXYNOS4_HUFF_TBL_HDCCL : EXYNOS4_HUFF_TBL_HDCCV;
775 return lenval ? EXYNOS4_HUFF_TBL_HDCLL : EXYNOS4_HUFF_TBL_HDCLV;
778 static inline int exynos4_huff_tbl_len(int class, int id)
780 return __exynos4_huff_tbl(class, id, true);
783 static inline int exynos4_huff_tbl_val(int class, int id)
785 return __exynos4_huff_tbl(class, id, false);
788 static int get_byte(struct s5p_jpeg_buffer *buf);
789 static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word);
790 static void skip(struct s5p_jpeg_buffer *buf, long len);
792 static void exynos4_jpeg_parse_decode_h_tbl(struct s5p_jpeg_ctx *ctx)
794 struct s5p_jpeg *jpeg = ctx->jpeg;
795 struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
796 struct s5p_jpeg_buffer jpeg_buffer;
798 int c, x, components;
800 jpeg_buffer.size = 2; /* Ls */
802 (unsigned long)vb2_plane_vaddr(vb, 0) + ctx->out_q.sos + 2;
803 jpeg_buffer.curr = 0;
807 if (get_word_be(&jpeg_buffer, &word))
809 jpeg_buffer.size = (long)word - 2;
810 jpeg_buffer.data += 2;
811 jpeg_buffer.curr = 0;
813 components = get_byte(&jpeg_buffer);
814 if (components == -1)
816 while (components--) {
817 c = get_byte(&jpeg_buffer);
820 x = get_byte(&jpeg_buffer);
823 exynos4_jpeg_select_dec_h_tbl(jpeg->regs, c,
824 (((x >> 4) & 0x1) << 1) | (x & 0x1));
829 static void exynos4_jpeg_parse_huff_tbl(struct s5p_jpeg_ctx *ctx)
831 struct s5p_jpeg *jpeg = ctx->jpeg;
832 struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
833 struct s5p_jpeg_buffer jpeg_buffer;
837 for (j = 0; j < ctx->out_q.dht.n; ++j) {
838 jpeg_buffer.size = ctx->out_q.dht.len[j];
839 jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(vb, 0) +
840 ctx->out_q.dht.marker[j];
841 jpeg_buffer.curr = 0;
844 while (jpeg_buffer.curr < jpeg_buffer.size) {
847 c = get_byte(&jpeg_buffer);
851 class = (c >> 4) & 0xf;
853 for (i = 0; i < 16; ++i) {
854 c = get_byte(&jpeg_buffer);
857 word |= c << ((i % 4) * 8);
858 if ((i + 1) % 4 == 0) {
859 writel(word, jpeg->regs +
860 exynos4_huff_tbl_len(class, id) +
867 for (i = 0; i < n; ++i) {
868 c = get_byte(&jpeg_buffer);
871 word |= c << ((i % 4) * 8);
872 if ((i + 1) % 4 == 0) {
873 writel(word, jpeg->regs +
874 exynos4_huff_tbl_val(class, id) +
880 writel(word, jpeg->regs +
881 exynos4_huff_tbl_val(class, id) + (i / 4) * 4);
888 static void exynos4_jpeg_parse_decode_q_tbl(struct s5p_jpeg_ctx *ctx)
890 struct s5p_jpeg *jpeg = ctx->jpeg;
891 struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
892 struct s5p_jpeg_buffer jpeg_buffer;
893 int c, x, components;
895 jpeg_buffer.size = ctx->out_q.sof_len;
897 (unsigned long)vb2_plane_vaddr(vb, 0) + ctx->out_q.sof;
898 jpeg_buffer.curr = 0;
900 skip(&jpeg_buffer, 5); /* P, Y, X */
901 components = get_byte(&jpeg_buffer);
902 if (components == -1)
905 exynos4_jpeg_set_dec_components(jpeg->regs, components);
907 while (components--) {
908 c = get_byte(&jpeg_buffer);
911 skip(&jpeg_buffer, 1);
912 x = get_byte(&jpeg_buffer);
915 exynos4_jpeg_select_dec_q_tbl(jpeg->regs, c, x);
919 static void exynos4_jpeg_parse_q_tbl(struct s5p_jpeg_ctx *ctx)
921 struct s5p_jpeg *jpeg = ctx->jpeg;
922 struct vb2_buffer *vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
923 struct s5p_jpeg_buffer jpeg_buffer;
927 for (j = 0; j < ctx->out_q.dqt.n; ++j) {
928 jpeg_buffer.size = ctx->out_q.dqt.len[j];
929 jpeg_buffer.data = (unsigned long)vb2_plane_vaddr(vb, 0) +
930 ctx->out_q.dqt.marker[j];
931 jpeg_buffer.curr = 0;
934 while (jpeg_buffer.size - jpeg_buffer.curr >= 65) {
937 c = get_byte(&jpeg_buffer);
941 /* nonzero means extended mode - not supported */
944 for (i = 0; i < 64; ++i) {
945 c = get_byte(&jpeg_buffer);
948 word |= c << ((i % 4) * 8);
949 if ((i + 1) % 4 == 0) {
950 writel(word, jpeg->regs +
951 EXYNOS4_QTBL_CONTENT(id) + (i / 4) * 4);
961 * ============================================================================
962 * Device file operations
963 * ============================================================================
966 static int queue_init(void *priv, struct vb2_queue *src_vq,
967 struct vb2_queue *dst_vq);
968 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
969 __u32 pixelformat, unsigned int fmt_type);
970 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
972 static int s5p_jpeg_open(struct file *file)
974 struct s5p_jpeg *jpeg = video_drvdata(file);
975 struct video_device *vfd = video_devdata(file);
976 struct s5p_jpeg_ctx *ctx;
977 struct s5p_jpeg_fmt *out_fmt, *cap_fmt;
980 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
984 if (mutex_lock_interruptible(&jpeg->lock)) {
989 v4l2_fh_init(&ctx->fh, vfd);
990 /* Use separate control handler per file handle */
991 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
992 file->private_data = &ctx->fh;
993 v4l2_fh_add(&ctx->fh);
996 if (vfd == jpeg->vfd_encoder) {
997 ctx->mode = S5P_JPEG_ENCODE;
998 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB565,
1000 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
1003 ctx->mode = S5P_JPEG_DECODE;
1004 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
1006 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV,
1008 ctx->scale_factor = EXYNOS3250_DEC_SCALE_FACTOR_8_8;
1011 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
1012 if (IS_ERR(ctx->fh.m2m_ctx)) {
1013 ret = PTR_ERR(ctx->fh.m2m_ctx);
1017 ctx->out_q.fmt = out_fmt;
1018 ctx->cap_q.fmt = cap_fmt;
1020 ret = s5p_jpeg_controls_create(ctx);
1024 mutex_unlock(&jpeg->lock);
1028 v4l2_fh_del(&ctx->fh);
1029 v4l2_fh_exit(&ctx->fh);
1030 mutex_unlock(&jpeg->lock);
1036 static int s5p_jpeg_release(struct file *file)
1038 struct s5p_jpeg *jpeg = video_drvdata(file);
1039 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
1041 mutex_lock(&jpeg->lock);
1042 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1043 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1044 v4l2_fh_del(&ctx->fh);
1045 v4l2_fh_exit(&ctx->fh);
1047 mutex_unlock(&jpeg->lock);
1052 static const struct v4l2_file_operations s5p_jpeg_fops = {
1053 .owner = THIS_MODULE,
1054 .open = s5p_jpeg_open,
1055 .release = s5p_jpeg_release,
1056 .poll = v4l2_m2m_fop_poll,
1057 .unlocked_ioctl = video_ioctl2,
1058 .mmap = v4l2_m2m_fop_mmap,
1062 * ============================================================================
1063 * video ioctl operations
1064 * ============================================================================
1067 static int get_byte(struct s5p_jpeg_buffer *buf)
1069 if (buf->curr >= buf->size)
1072 return ((unsigned char *)buf->data)[buf->curr++];
1075 static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
1080 byte = get_byte(buf);
1084 byte = get_byte(buf);
1087 *word = (unsigned int)byte | temp;
1091 static void skip(struct s5p_jpeg_buffer *buf, long len)
1100 static bool s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx *ctx,
1101 unsigned int subsampling)
1103 unsigned int version;
1105 switch (subsampling) {
1107 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
1110 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
1113 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
1116 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
1120 * 4:1:1 subsampling only supported by 3250, 5420, and 5433
1123 version = ctx->jpeg->variant->version;
1124 if (version != SJPEG_EXYNOS3250 &&
1125 version != SJPEG_EXYNOS5420 &&
1126 version != SJPEG_EXYNOS5433)
1129 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_411;
1138 static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
1139 unsigned long buffer, unsigned long size,
1140 struct s5p_jpeg_ctx *ctx)
1142 int c, components = 0, notfound, n_dht = 0, n_dqt = 0;
1143 unsigned int height = 0, width = 0, word, subsampling = 0;
1144 unsigned int sos = 0, sof = 0, sof_len = 0;
1145 unsigned int dht[S5P_JPEG_MAX_MARKER], dht_len[S5P_JPEG_MAX_MARKER];
1146 unsigned int dqt[S5P_JPEG_MAX_MARKER], dqt_len[S5P_JPEG_MAX_MARKER];
1148 struct s5p_jpeg_buffer jpeg_buffer;
1150 jpeg_buffer.size = size;
1151 jpeg_buffer.data = buffer;
1152 jpeg_buffer.curr = 0;
1155 while (notfound || !sos) {
1156 c = get_byte(&jpeg_buffer);
1162 c = get_byte(&jpeg_buffer);
1170 /* SOF0: baseline JPEG */
1172 if (get_word_be(&jpeg_buffer, &word))
1174 length = (long)word - 2;
1177 sof = jpeg_buffer.curr; /* after 0xffc0 */
1179 if (get_byte(&jpeg_buffer) == -1)
1181 if (get_word_be(&jpeg_buffer, &height))
1183 if (get_word_be(&jpeg_buffer, &width))
1185 components = get_byte(&jpeg_buffer);
1186 if (components == -1)
1189 if (components == 1) {
1192 skip(&jpeg_buffer, 1);
1193 subsampling = get_byte(&jpeg_buffer);
1194 skip(&jpeg_buffer, 1);
1198 skip(&jpeg_buffer, components * 2);
1203 if (get_word_be(&jpeg_buffer, &word))
1205 length = (long)word - 2;
1208 if (n_dqt >= S5P_JPEG_MAX_MARKER)
1210 dqt[n_dqt] = jpeg_buffer.curr; /* after 0xffdb */
1211 dqt_len[n_dqt++] = length;
1212 skip(&jpeg_buffer, length);
1216 if (get_word_be(&jpeg_buffer, &word))
1218 length = (long)word - 2;
1221 if (n_dht >= S5P_JPEG_MAX_MARKER)
1223 dht[n_dht] = jpeg_buffer.curr; /* after 0xffc4 */
1224 dht_len[n_dht++] = length;
1225 skip(&jpeg_buffer, length);
1229 sos = jpeg_buffer.curr - 2; /* 0xffda */
1232 /* skip payload-less markers */
1233 case RST ... RST + 7:
1239 /* skip uninteresting payload markers */
1241 if (get_word_be(&jpeg_buffer, &word))
1243 length = (long)word - 2;
1244 skip(&jpeg_buffer, length);
1249 if (notfound || !sos || !s5p_jpeg_subsampling_decode(ctx, subsampling))
1255 result->dht.n = n_dht;
1257 result->dht.marker[n_dht] = dht[n_dht];
1258 result->dht.len[n_dht] = dht_len[n_dht];
1260 result->dqt.n = n_dqt;
1262 result->dqt.marker[n_dqt] = dqt[n_dqt];
1263 result->dqt.len[n_dqt] = dqt_len[n_dqt];
1266 result->sof_len = sof_len;
1267 result->components = components;
1272 static int s5p_jpeg_querycap(struct file *file, void *priv,
1273 struct v4l2_capability *cap)
1275 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1277 if (ctx->mode == S5P_JPEG_ENCODE) {
1278 strlcpy(cap->driver, S5P_JPEG_M2M_NAME,
1279 sizeof(cap->driver));
1280 strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
1283 strlcpy(cap->driver, S5P_JPEG_M2M_NAME,
1284 sizeof(cap->driver));
1285 strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
1288 snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s",
1289 dev_name(ctx->jpeg->dev));
1290 cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
1291 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1295 static int enum_fmt(struct s5p_jpeg_fmt *sjpeg_formats, int n,
1296 struct v4l2_fmtdesc *f, u32 type)
1300 for (i = 0; i < n; ++i) {
1301 if (sjpeg_formats[i].flags & type) {
1302 /* index-th format of type type found ? */
1303 if (num == f->index)
1305 /* Correct type but haven't reached our index yet,
1306 * just increment per-type index
1312 /* Format not found */
1316 strlcpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
1317 f->pixelformat = sjpeg_formats[i].fourcc;
1322 static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
1323 struct v4l2_fmtdesc *f)
1325 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1327 if (ctx->mode == S5P_JPEG_ENCODE)
1328 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1329 SJPEG_FMT_FLAG_ENC_CAPTURE);
1331 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1332 SJPEG_FMT_FLAG_DEC_CAPTURE);
1335 static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
1336 struct v4l2_fmtdesc *f)
1338 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1340 if (ctx->mode == S5P_JPEG_ENCODE)
1341 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1342 SJPEG_FMT_FLAG_ENC_OUTPUT);
1344 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1345 SJPEG_FMT_FLAG_DEC_OUTPUT);
1348 static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
1349 enum v4l2_buf_type type)
1351 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1353 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1359 static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
1361 struct vb2_queue *vq;
1362 struct s5p_jpeg_q_data *q_data = NULL;
1363 struct v4l2_pix_format *pix = &f->fmt.pix;
1364 struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
1366 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1370 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1371 ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
1373 q_data = get_q_data(ct, f->type);
1374 BUG_ON(q_data == NULL);
1376 pix->width = q_data->w;
1377 pix->height = q_data->h;
1378 pix->field = V4L2_FIELD_NONE;
1379 pix->pixelformat = q_data->fmt->fourcc;
1380 pix->bytesperline = 0;
1381 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
1382 u32 bpl = q_data->w;
1384 if (q_data->fmt->colplanes == 1)
1385 bpl = (bpl * q_data->fmt->depth) >> 3;
1386 pix->bytesperline = bpl;
1388 pix->sizeimage = q_data->size;
1393 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
1394 u32 pixelformat, unsigned int fmt_type)
1396 unsigned int k, fmt_flag;
1398 if (ctx->mode == S5P_JPEG_ENCODE)
1399 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
1400 SJPEG_FMT_FLAG_ENC_OUTPUT :
1401 SJPEG_FMT_FLAG_ENC_CAPTURE;
1403 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
1404 SJPEG_FMT_FLAG_DEC_OUTPUT :
1405 SJPEG_FMT_FLAG_DEC_CAPTURE;
1407 for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
1408 struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
1410 if (fmt->fourcc == pixelformat &&
1411 fmt->flags & fmt_flag &&
1412 fmt->flags & ctx->jpeg->variant->fmt_ver_flag) {
1420 static void jpeg_bound_align_image(struct s5p_jpeg_ctx *ctx,
1421 u32 *w, unsigned int wmin, unsigned int wmax,
1422 unsigned int walign,
1423 u32 *h, unsigned int hmin, unsigned int hmax,
1424 unsigned int halign)
1426 int width, height, w_step, h_step;
1431 w_step = 1 << walign;
1432 h_step = 1 << halign;
1434 if (ctx->jpeg->variant->hw3250_compat) {
1436 * Rightmost and bottommost pixels are cropped by the
1437 * Exynos3250/compatible JPEG IP for RGB formats, for the
1438 * specific width and height values respectively. This
1439 * assignment will result in v4l_bound_align_image returning
1440 * dimensions reduced by 1 for the aforementioned cases.
1442 if (w_step == 4 && ((width & 3) == 1)) {
1448 v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
1450 if (*w < width && (*w + w_step) < wmax)
1452 if (*h < height && (*h + h_step) < hmax)
1456 static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
1457 struct s5p_jpeg_ctx *ctx, int q_type)
1459 struct v4l2_pix_format *pix = &f->fmt.pix;
1461 if (pix->field == V4L2_FIELD_ANY)
1462 pix->field = V4L2_FIELD_NONE;
1463 else if (pix->field != V4L2_FIELD_NONE)
1466 /* V4L2 specification suggests the driver corrects the format struct
1467 * if any of the dimensions is unsupported
1469 if (q_type == FMT_TYPE_OUTPUT)
1470 jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
1471 S5P_JPEG_MAX_WIDTH, 0,
1472 &pix->height, S5P_JPEG_MIN_HEIGHT,
1473 S5P_JPEG_MAX_HEIGHT, 0);
1475 jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
1476 S5P_JPEG_MAX_WIDTH, fmt->h_align,
1477 &pix->height, S5P_JPEG_MIN_HEIGHT,
1478 S5P_JPEG_MAX_HEIGHT, fmt->v_align);
1480 if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1481 if (pix->sizeimage <= 0)
1482 pix->sizeimage = PAGE_SIZE;
1483 pix->bytesperline = 0;
1485 u32 bpl = pix->bytesperline;
1487 if (fmt->colplanes > 1 && bpl < pix->width)
1488 bpl = pix->width; /* planar */
1490 if (fmt->colplanes == 1 && /* packed */
1491 (bpl << 3) / fmt->depth < pix->width)
1492 bpl = (pix->width * fmt->depth) >> 3;
1494 pix->bytesperline = bpl;
1495 pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
1501 static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
1502 struct v4l2_format *f)
1504 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1505 struct v4l2_pix_format *pix = &f->fmt.pix;
1506 struct s5p_jpeg_fmt *fmt;
1509 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1512 v4l2_err(&ctx->jpeg->v4l2_dev,
1513 "Fourcc format (0x%08x) invalid.\n",
1514 f->fmt.pix.pixelformat);
1518 if (!ctx->jpeg->variant->hw_ex4_compat || ctx->mode != S5P_JPEG_DECODE)
1522 * The exynos4x12 device requires resulting YUV image
1523 * subsampling not to be lower than the input jpeg subsampling.
1524 * If this requirement is not met then downgrade the requested
1525 * capture format to the one with subsampling equal to the input jpeg.
1527 if ((fmt->flags & SJPEG_FMT_NON_RGB) &&
1528 (fmt->subsampling < ctx->subsampling)) {
1529 ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling,
1534 pix->pixelformat = V4L2_PIX_FMT_GREY;
1536 fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1541 * Decompression of a JPEG file with 4:2:0 subsampling and odd
1542 * width to the YUV 4:2:0 compliant formats produces a raw image
1543 * with broken luma component. Adjust capture format to RGB565
1546 if (ctx->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420 &&
1547 (ctx->out_q.w & 1) &&
1548 (pix->pixelformat == V4L2_PIX_FMT_NV12 ||
1549 pix->pixelformat == V4L2_PIX_FMT_NV21 ||
1550 pix->pixelformat == V4L2_PIX_FMT_YUV420)) {
1551 pix->pixelformat = V4L2_PIX_FMT_RGB565;
1552 fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1557 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
1560 static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
1561 struct v4l2_format *f)
1563 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1564 struct s5p_jpeg_fmt *fmt;
1566 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1569 v4l2_err(&ctx->jpeg->v4l2_dev,
1570 "Fourcc format (0x%08x) invalid.\n",
1571 f->fmt.pix.pixelformat);
1575 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
1578 static int exynos4_jpeg_get_output_buffer_size(struct s5p_jpeg_ctx *ctx,
1579 struct v4l2_format *f,
1582 struct v4l2_pix_format *pix = &f->fmt.pix;
1583 u32 pix_fmt = f->fmt.pix.pixelformat;
1584 int w = pix->width, h = pix->height, wh_align;
1587 if (pix_fmt == V4L2_PIX_FMT_RGB32 ||
1588 pix_fmt == V4L2_PIX_FMT_RGB565 ||
1589 pix_fmt == V4L2_PIX_FMT_NV24 ||
1590 pix_fmt == V4L2_PIX_FMT_NV42 ||
1591 pix_fmt == V4L2_PIX_FMT_NV12 ||
1592 pix_fmt == V4L2_PIX_FMT_NV21 ||
1593 pix_fmt == V4L2_PIX_FMT_YUV420)
1598 jpeg_bound_align_image(ctx, &w, S5P_JPEG_MIN_WIDTH,
1599 S5P_JPEG_MAX_WIDTH, wh_align,
1600 &h, S5P_JPEG_MIN_HEIGHT,
1601 S5P_JPEG_MAX_HEIGHT, wh_align);
1603 if (ctx->jpeg->variant->version == SJPEG_EXYNOS4)
1604 padding = PAGE_SIZE;
1606 return (w * h * fmt_depth >> 3) + padding;
1609 static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1610 struct v4l2_rect *r);
1612 static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
1614 struct vb2_queue *vq;
1615 struct s5p_jpeg_q_data *q_data = NULL;
1616 struct v4l2_pix_format *pix = &f->fmt.pix;
1617 struct v4l2_ctrl *ctrl_subs;
1618 struct v4l2_rect scale_rect;
1619 unsigned int f_type;
1621 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1625 q_data = get_q_data(ct, f->type);
1626 BUG_ON(q_data == NULL);
1628 if (vb2_is_busy(vq)) {
1629 v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
1633 f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
1634 FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
1636 q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
1637 if (ct->mode == S5P_JPEG_ENCODE ||
1638 (ct->mode == S5P_JPEG_DECODE &&
1639 q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG)) {
1640 q_data->w = pix->width;
1641 q_data->h = pix->height;
1643 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
1645 * During encoding Exynos4x12 SoCs access wider memory area
1646 * than it results from Image_x and Image_y values written to
1647 * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu
1648 * page fault calculate proper buffer size in such a case.
1650 if (ct->jpeg->variant->hw_ex4_compat &&
1651 f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE)
1652 q_data->size = exynos4_jpeg_get_output_buffer_size(ct,
1654 q_data->fmt->depth);
1656 q_data->size = q_data->w * q_data->h *
1657 q_data->fmt->depth >> 3;
1659 q_data->size = pix->sizeimage;
1662 if (f_type == FMT_TYPE_OUTPUT) {
1663 ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler,
1664 V4L2_CID_JPEG_CHROMA_SUBSAMPLING);
1666 v4l2_ctrl_s_ctrl(ctrl_subs, q_data->fmt->subsampling);
1667 ct->crop_altered = false;
1671 * For decoding init crop_rect with capture buffer dimmensions which
1672 * contain aligned dimensions of the input JPEG image and do it only
1673 * if crop rectangle hasn't been altered by the user space e.g. with
1674 * S_SELECTION ioctl. For encoding assign output buffer dimensions.
1676 if (!ct->crop_altered &&
1677 ((ct->mode == S5P_JPEG_DECODE && f_type == FMT_TYPE_CAPTURE) ||
1678 (ct->mode == S5P_JPEG_ENCODE && f_type == FMT_TYPE_OUTPUT))) {
1679 ct->crop_rect.width = pix->width;
1680 ct->crop_rect.height = pix->height;
1684 * Prevent downscaling to YUV420 format by more than 2
1685 * for Exynos3250/compatible SoC as it produces broken raw image
1688 if (ct->mode == S5P_JPEG_DECODE &&
1689 f_type == FMT_TYPE_CAPTURE &&
1690 ct->jpeg->variant->hw3250_compat &&
1691 pix->pixelformat == V4L2_PIX_FMT_YUV420 &&
1692 ct->scale_factor > 2) {
1693 scale_rect.width = ct->out_q.w / 2;
1694 scale_rect.height = ct->out_q.h / 2;
1695 exynos3250_jpeg_try_downscale(ct, &scale_rect);
1701 static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
1702 struct v4l2_format *f)
1706 ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
1710 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1713 static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
1714 struct v4l2_format *f)
1718 ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
1722 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1725 static int s5p_jpeg_subscribe_event(struct v4l2_fh *fh,
1726 const struct v4l2_event_subscription *sub)
1728 if (sub->type == V4L2_EVENT_SOURCE_CHANGE)
1729 return v4l2_src_change_event_subscribe(fh, sub);
1734 static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1735 struct v4l2_rect *r)
1737 int w_ratio, h_ratio, scale_factor, cur_ratio, i;
1739 w_ratio = ctx->out_q.w / r->width;
1740 h_ratio = ctx->out_q.h / r->height;
1742 scale_factor = w_ratio > h_ratio ? w_ratio : h_ratio;
1743 scale_factor = clamp_val(scale_factor, 1, 8);
1745 /* Align scale ratio to the nearest power of 2 */
1746 for (i = 0; i <= 3; ++i) {
1748 if (scale_factor <= cur_ratio) {
1749 ctx->scale_factor = cur_ratio;
1754 r->width = round_down(ctx->out_q.w / ctx->scale_factor, 2);
1755 r->height = round_down(ctx->out_q.h / ctx->scale_factor, 2);
1757 ctx->crop_rect.width = r->width;
1758 ctx->crop_rect.height = r->height;
1759 ctx->crop_rect.left = 0;
1760 ctx->crop_rect.top = 0;
1762 ctx->crop_altered = true;
1767 /* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
1768 static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
1770 if (a->left < b->left || a->top < b->top)
1772 if (a->left + a->width > b->left + b->width)
1774 if (a->top + a->height > b->top + b->height)
1780 static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx,
1781 struct v4l2_rect *r)
1783 struct v4l2_rect base_rect;
1786 switch (ctx->cap_q.fmt->fourcc) {
1787 case V4L2_PIX_FMT_NV12:
1788 case V4L2_PIX_FMT_NV21:
1792 case V4L2_PIX_FMT_YUV420:
1804 base_rect.width = ctx->out_q.w;
1805 base_rect.height = ctx->out_q.h;
1807 r->width = round_down(r->width, w_step);
1808 r->height = round_down(r->height, h_step);
1809 r->left = round_down(r->left, 2);
1810 r->top = round_down(r->top, 2);
1812 if (!enclosed_rectangle(r, &base_rect))
1815 ctx->crop_rect.left = r->left;
1816 ctx->crop_rect.top = r->top;
1817 ctx->crop_rect.width = r->width;
1818 ctx->crop_rect.height = r->height;
1820 ctx->crop_altered = true;
1829 static int s5p_jpeg_g_selection(struct file *file, void *priv,
1830 struct v4l2_selection *s)
1832 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1834 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
1835 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1838 /* For JPEG blob active == default == bounds */
1839 switch (s->target) {
1840 case V4L2_SEL_TGT_CROP:
1841 case V4L2_SEL_TGT_CROP_BOUNDS:
1842 case V4L2_SEL_TGT_CROP_DEFAULT:
1843 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1844 s->r.width = ctx->out_q.w;
1845 s->r.height = ctx->out_q.h;
1849 case V4L2_SEL_TGT_COMPOSE:
1850 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1851 case V4L2_SEL_TGT_COMPOSE_PADDED:
1852 s->r.width = ctx->crop_rect.width;
1853 s->r.height = ctx->crop_rect.height;
1854 s->r.left = ctx->crop_rect.left;
1855 s->r.top = ctx->crop_rect.top;
1866 static int s5p_jpeg_s_selection(struct file *file, void *fh,
1867 struct v4l2_selection *s)
1869 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
1870 struct v4l2_rect *rect = &s->r;
1873 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1876 if (s->target == V4L2_SEL_TGT_COMPOSE) {
1877 if (ctx->mode != S5P_JPEG_DECODE)
1879 if (ctx->jpeg->variant->hw3250_compat)
1880 ret = exynos3250_jpeg_try_downscale(ctx, rect);
1881 } else if (s->target == V4L2_SEL_TGT_CROP) {
1882 if (ctx->mode != S5P_JPEG_ENCODE)
1884 if (ctx->jpeg->variant->hw3250_compat)
1885 ret = exynos3250_jpeg_try_crop(ctx, rect);
1891 static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1893 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1894 struct s5p_jpeg *jpeg = ctx->jpeg;
1895 unsigned long flags;
1898 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1899 spin_lock_irqsave(&jpeg->slock, flags);
1900 ctrl->val = s5p_jpeg_to_user_subsampling(ctx);
1901 spin_unlock_irqrestore(&jpeg->slock, flags);
1908 static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val)
1910 switch (ctx->jpeg->variant->version) {
1913 case SJPEG_EXYNOS3250:
1914 case SJPEG_EXYNOS5420:
1916 * The exynos3250/compatible device can produce JPEG image only
1917 * of 4:4:4 subsampling when given RGB32 source image.
1919 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
1924 * The exynos4x12 device requires input raw image fourcc
1925 * to be V4L2_PIX_FMT_GREY if gray jpeg format
1928 if (ctx->out_q.fmt->fourcc != V4L2_PIX_FMT_GREY &&
1929 *ctrl_val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY)
1935 * The exynos4x12 and exynos3250/compatible devices require resulting
1936 * jpeg subsampling not to be lower than the input raw image
1939 if (ctx->out_q.fmt->subsampling > *ctrl_val)
1940 *ctrl_val = ctx->out_q.fmt->subsampling;
1945 static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl)
1947 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1948 unsigned long flags;
1951 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1953 if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING)
1954 ret = s5p_jpeg_adjust_subs_ctrl(ctx, &ctrl->val);
1956 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1960 static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
1962 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1963 unsigned long flags;
1965 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1968 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1969 ctx->compr_quality = ctrl->val;
1971 case V4L2_CID_JPEG_RESTART_INTERVAL:
1972 ctx->restart_interval = ctrl->val;
1974 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1975 ctx->subsampling = ctrl->val;
1979 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1983 static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
1984 .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl,
1985 .try_ctrl = s5p_jpeg_try_ctrl,
1986 .s_ctrl = s5p_jpeg_s_ctrl,
1989 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
1991 unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
1992 struct v4l2_ctrl *ctrl;
1995 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
1997 if (ctx->mode == S5P_JPEG_ENCODE) {
1998 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1999 V4L2_CID_JPEG_COMPRESSION_QUALITY,
2000 0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
2002 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
2003 V4L2_CID_JPEG_RESTART_INTERVAL,
2005 if (ctx->jpeg->variant->version == SJPEG_S5P)
2006 mask = ~0x06; /* 422, 420 */
2009 ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
2010 V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
2011 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
2012 V4L2_JPEG_CHROMA_SUBSAMPLING_422);
2014 if (ctx->ctrl_handler.error) {
2015 ret = ctx->ctrl_handler.error;
2019 if (ctx->mode == S5P_JPEG_DECODE)
2020 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
2021 V4L2_CTRL_FLAG_READ_ONLY;
2023 ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
2030 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
2034 static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
2035 .vidioc_querycap = s5p_jpeg_querycap,
2037 .vidioc_enum_fmt_vid_cap = s5p_jpeg_enum_fmt_vid_cap,
2038 .vidioc_enum_fmt_vid_out = s5p_jpeg_enum_fmt_vid_out,
2040 .vidioc_g_fmt_vid_cap = s5p_jpeg_g_fmt,
2041 .vidioc_g_fmt_vid_out = s5p_jpeg_g_fmt,
2043 .vidioc_try_fmt_vid_cap = s5p_jpeg_try_fmt_vid_cap,
2044 .vidioc_try_fmt_vid_out = s5p_jpeg_try_fmt_vid_out,
2046 .vidioc_s_fmt_vid_cap = s5p_jpeg_s_fmt_vid_cap,
2047 .vidioc_s_fmt_vid_out = s5p_jpeg_s_fmt_vid_out,
2049 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
2050 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
2051 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
2052 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
2054 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
2055 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
2057 .vidioc_g_selection = s5p_jpeg_g_selection,
2058 .vidioc_s_selection = s5p_jpeg_s_selection,
2060 .vidioc_subscribe_event = s5p_jpeg_subscribe_event,
2061 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
2065 * ============================================================================
2067 * ============================================================================
2070 static void s5p_jpeg_device_run(void *priv)
2072 struct s5p_jpeg_ctx *ctx = priv;
2073 struct s5p_jpeg *jpeg = ctx->jpeg;
2074 struct vb2_buffer *src_buf, *dst_buf;
2075 unsigned long src_addr, dst_addr, flags;
2077 spin_lock_irqsave(&ctx->jpeg->slock, flags);
2079 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2080 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2081 src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
2082 dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
2084 s5p_jpeg_reset(jpeg->regs);
2085 s5p_jpeg_poweron(jpeg->regs);
2086 s5p_jpeg_proc_mode(jpeg->regs, ctx->mode);
2087 if (ctx->mode == S5P_JPEG_ENCODE) {
2088 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
2089 s5p_jpeg_input_raw_mode(jpeg->regs,
2090 S5P_JPEG_RAW_IN_565);
2092 s5p_jpeg_input_raw_mode(jpeg->regs,
2093 S5P_JPEG_RAW_IN_422);
2094 s5p_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
2095 s5p_jpeg_dri(jpeg->regs, ctx->restart_interval);
2096 s5p_jpeg_x(jpeg->regs, ctx->out_q.w);
2097 s5p_jpeg_y(jpeg->regs, ctx->out_q.h);
2098 s5p_jpeg_imgadr(jpeg->regs, src_addr);
2099 s5p_jpeg_jpgadr(jpeg->regs, dst_addr);
2101 /* ultimately comes from sizeimage from userspace */
2102 s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
2104 /* JPEG RGB to YCbCr conversion matrix */
2105 s5p_jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
2106 s5p_jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
2107 s5p_jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
2108 s5p_jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
2109 s5p_jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
2110 s5p_jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
2111 s5p_jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
2112 s5p_jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
2113 s5p_jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
2116 * JPEG IP allows storing 4 quantization tables
2117 * We fill table 0 for luma and table 1 for chroma
2119 s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2120 s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2121 /* use table 0 for Y */
2122 s5p_jpeg_qtbl(jpeg->regs, 1, 0);
2123 /* use table 1 for Cb and Cr*/
2124 s5p_jpeg_qtbl(jpeg->regs, 2, 1);
2125 s5p_jpeg_qtbl(jpeg->regs, 3, 1);
2127 /* Y, Cb, Cr use Huffman table 0 */
2128 s5p_jpeg_htbl_ac(jpeg->regs, 1);
2129 s5p_jpeg_htbl_dc(jpeg->regs, 1);
2130 s5p_jpeg_htbl_ac(jpeg->regs, 2);
2131 s5p_jpeg_htbl_dc(jpeg->regs, 2);
2132 s5p_jpeg_htbl_ac(jpeg->regs, 3);
2133 s5p_jpeg_htbl_dc(jpeg->regs, 3);
2134 } else { /* S5P_JPEG_DECODE */
2135 s5p_jpeg_rst_int_enable(jpeg->regs, true);
2136 s5p_jpeg_data_num_int_enable(jpeg->regs, true);
2137 s5p_jpeg_final_mcu_num_int_enable(jpeg->regs, true);
2138 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
2139 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
2141 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
2142 s5p_jpeg_jpgadr(jpeg->regs, src_addr);
2143 s5p_jpeg_imgadr(jpeg->regs, dst_addr);
2146 s5p_jpeg_start(jpeg->regs);
2148 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
2151 static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
2153 struct s5p_jpeg *jpeg = ctx->jpeg;
2154 struct s5p_jpeg_fmt *fmt;
2155 struct vb2_buffer *vb;
2156 struct s5p_jpeg_addr jpeg_addr = {};
2157 u32 pix_size, padding_bytes = 0;
2162 pix_size = ctx->cap_q.w * ctx->cap_q.h;
2164 if (ctx->mode == S5P_JPEG_ENCODE) {
2165 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2166 fmt = ctx->out_q.fmt;
2167 if (ctx->out_q.w % 2 && fmt->h_align > 0)
2168 padding_bytes = ctx->out_q.h;
2170 fmt = ctx->cap_q.fmt;
2171 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2174 jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
2176 if (fmt->colplanes == 2) {
2177 jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes;
2178 } else if (fmt->colplanes == 3) {
2179 jpeg_addr.cb = jpeg_addr.y + pix_size;
2180 if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
2181 jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
2183 jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
2186 exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr);
2189 static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
2191 struct s5p_jpeg *jpeg = ctx->jpeg;
2192 struct vb2_buffer *vb;
2193 unsigned int jpeg_addr = 0;
2195 if (ctx->mode == S5P_JPEG_ENCODE)
2196 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2198 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2200 jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
2201 if (jpeg->variant->version == SJPEG_EXYNOS5433 &&
2202 ctx->mode == S5P_JPEG_DECODE)
2203 jpeg_addr += ctx->out_q.sos;
2204 exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
2207 static inline void exynos4_jpeg_set_img_fmt(void __iomem *base,
2208 unsigned int img_fmt)
2210 __exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS4);
2213 static inline void exynos5433_jpeg_set_img_fmt(void __iomem *base,
2214 unsigned int img_fmt)
2216 __exynos4_jpeg_set_img_fmt(base, img_fmt, SJPEG_EXYNOS5433);
2219 static inline void exynos4_jpeg_set_enc_out_fmt(void __iomem *base,
2220 unsigned int out_fmt)
2222 __exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS4);
2225 static inline void exynos5433_jpeg_set_enc_out_fmt(void __iomem *base,
2226 unsigned int out_fmt)
2228 __exynos4_jpeg_set_enc_out_fmt(base, out_fmt, SJPEG_EXYNOS5433);
2231 static void exynos4_jpeg_device_run(void *priv)
2233 struct s5p_jpeg_ctx *ctx = priv;
2234 struct s5p_jpeg *jpeg = ctx->jpeg;
2235 unsigned int bitstream_size;
2236 unsigned long flags;
2238 spin_lock_irqsave(&jpeg->slock, flags);
2240 if (ctx->mode == S5P_JPEG_ENCODE) {
2241 exynos4_jpeg_sw_reset(jpeg->regs);
2242 exynos4_jpeg_set_interrupt(jpeg->regs, jpeg->variant->version);
2243 exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
2245 exynos4_jpeg_set_huff_tbl(jpeg->regs);
2248 * JPEG IP allows storing 4 quantization tables
2249 * We fill table 0 for luma and table 1 for chroma
2251 exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2252 exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2254 exynos4_jpeg_set_encode_tbl_select(jpeg->regs,
2255 ctx->compr_quality);
2256 exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
2259 if (ctx->jpeg->variant->version == SJPEG_EXYNOS4) {
2260 exynos4_jpeg_set_enc_out_fmt(jpeg->regs,
2262 exynos4_jpeg_set_img_fmt(jpeg->regs,
2263 ctx->out_q.fmt->fourcc);
2265 exynos5433_jpeg_set_enc_out_fmt(jpeg->regs,
2267 exynos5433_jpeg_set_img_fmt(jpeg->regs,
2268 ctx->out_q.fmt->fourcc);
2270 exynos4_jpeg_set_img_addr(ctx);
2271 exynos4_jpeg_set_jpeg_addr(ctx);
2272 exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs,
2273 ctx->out_q.fmt->fourcc);
2275 exynos4_jpeg_sw_reset(jpeg->regs);
2276 exynos4_jpeg_set_interrupt(jpeg->regs,
2277 jpeg->variant->version);
2278 exynos4_jpeg_set_img_addr(ctx);
2279 exynos4_jpeg_set_jpeg_addr(ctx);
2281 if (jpeg->variant->version == SJPEG_EXYNOS5433) {
2282 exynos4_jpeg_parse_huff_tbl(ctx);
2283 exynos4_jpeg_parse_decode_h_tbl(ctx);
2285 exynos4_jpeg_parse_q_tbl(ctx);
2286 exynos4_jpeg_parse_decode_q_tbl(ctx);
2288 exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
2290 exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
2292 exynos5433_jpeg_set_enc_out_fmt(jpeg->regs,
2294 exynos5433_jpeg_set_img_fmt(jpeg->regs,
2295 ctx->cap_q.fmt->fourcc);
2296 bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 16);
2298 exynos4_jpeg_set_img_fmt(jpeg->regs,
2299 ctx->cap_q.fmt->fourcc);
2300 bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
2303 exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
2306 exynos4_jpeg_set_sys_int_enable(jpeg->regs, 1);
2307 exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
2309 spin_unlock_irqrestore(&jpeg->slock, flags);
2312 static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
2314 struct s5p_jpeg *jpeg = ctx->jpeg;
2315 struct s5p_jpeg_fmt *fmt;
2316 struct vb2_buffer *vb;
2317 struct s5p_jpeg_addr jpeg_addr = {};
2320 pix_size = ctx->cap_q.w * ctx->cap_q.h;
2322 if (ctx->mode == S5P_JPEG_ENCODE) {
2323 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2324 fmt = ctx->out_q.fmt;
2326 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2327 fmt = ctx->cap_q.fmt;
2330 jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
2332 if (fmt->colplanes == 2) {
2333 jpeg_addr.cb = jpeg_addr.y + pix_size;
2334 } else if (fmt->colplanes == 3) {
2335 jpeg_addr.cb = jpeg_addr.y + pix_size;
2336 if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
2337 jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
2339 jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
2342 exynos3250_jpeg_imgadr(jpeg->regs, &jpeg_addr);
2345 static void exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
2347 struct s5p_jpeg *jpeg = ctx->jpeg;
2348 struct vb2_buffer *vb;
2349 unsigned int jpeg_addr = 0;
2351 if (ctx->mode == S5P_JPEG_ENCODE)
2352 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
2354 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
2356 jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
2357 exynos3250_jpeg_jpgadr(jpeg->regs, jpeg_addr);
2360 static void exynos3250_jpeg_device_run(void *priv)
2362 struct s5p_jpeg_ctx *ctx = priv;
2363 struct s5p_jpeg *jpeg = ctx->jpeg;
2364 unsigned long flags;
2366 spin_lock_irqsave(&ctx->jpeg->slock, flags);
2368 exynos3250_jpeg_reset(jpeg->regs);
2369 exynos3250_jpeg_set_dma_num(jpeg->regs);
2370 exynos3250_jpeg_poweron(jpeg->regs);
2371 exynos3250_jpeg_clk_set(jpeg->regs);
2372 exynos3250_jpeg_proc_mode(jpeg->regs, ctx->mode);
2374 if (ctx->mode == S5P_JPEG_ENCODE) {
2375 exynos3250_jpeg_input_raw_fmt(jpeg->regs,
2376 ctx->out_q.fmt->fourcc);
2377 exynos3250_jpeg_dri(jpeg->regs, ctx->restart_interval);
2380 * JPEG IP allows storing 4 quantization tables
2381 * We fill table 0 for luma and table 1 for chroma
2383 s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2384 s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2385 /* use table 0 for Y */
2386 exynos3250_jpeg_qtbl(jpeg->regs, 1, 0);
2387 /* use table 1 for Cb and Cr*/
2388 exynos3250_jpeg_qtbl(jpeg->regs, 2, 1);
2389 exynos3250_jpeg_qtbl(jpeg->regs, 3, 1);
2392 * Some SoCs require setting Huffman tables before each run
2394 if (jpeg->variant->htbl_reinit) {
2395 s5p_jpeg_set_hdctbl(jpeg->regs);
2396 s5p_jpeg_set_hdctblg(jpeg->regs);
2397 s5p_jpeg_set_hactbl(jpeg->regs);
2398 s5p_jpeg_set_hactblg(jpeg->regs);
2401 /* Y, Cb, Cr use Huffman table 0 */
2402 exynos3250_jpeg_htbl_ac(jpeg->regs, 1);
2403 exynos3250_jpeg_htbl_dc(jpeg->regs, 1);
2404 exynos3250_jpeg_htbl_ac(jpeg->regs, 2);
2405 exynos3250_jpeg_htbl_dc(jpeg->regs, 2);
2406 exynos3250_jpeg_htbl_ac(jpeg->regs, 3);
2407 exynos3250_jpeg_htbl_dc(jpeg->regs, 3);
2409 exynos3250_jpeg_set_x(jpeg->regs, ctx->crop_rect.width);
2410 exynos3250_jpeg_set_y(jpeg->regs, ctx->crop_rect.height);
2411 exynos3250_jpeg_stride(jpeg->regs, ctx->out_q.fmt->fourcc,
2413 exynos3250_jpeg_offset(jpeg->regs, ctx->crop_rect.left,
2414 ctx->crop_rect.top);
2415 exynos3250_jpeg_set_img_addr(ctx);
2416 exynos3250_jpeg_set_jpeg_addr(ctx);
2417 exynos3250_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
2419 /* ultimately comes from sizeimage from userspace */
2420 exynos3250_jpeg_enc_stream_bound(jpeg->regs, ctx->cap_q.size);
2422 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565 ||
2423 ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565X ||
2424 ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
2425 exynos3250_jpeg_set_y16(jpeg->regs, true);
2427 exynos3250_jpeg_set_img_addr(ctx);
2428 exynos3250_jpeg_set_jpeg_addr(ctx);
2429 exynos3250_jpeg_stride(jpeg->regs, ctx->cap_q.fmt->fourcc,
2431 exynos3250_jpeg_offset(jpeg->regs, 0, 0);
2432 exynos3250_jpeg_dec_scaling_ratio(jpeg->regs,
2434 exynos3250_jpeg_dec_stream_size(jpeg->regs, ctx->out_q.size);
2435 exynos3250_jpeg_output_raw_fmt(jpeg->regs,
2436 ctx->cap_q.fmt->fourcc);
2439 exynos3250_jpeg_interrupts_enable(jpeg->regs);
2441 /* JPEG RGB to YCbCr conversion matrix */
2442 exynos3250_jpeg_coef(jpeg->regs, ctx->mode);
2444 exynos3250_jpeg_set_timer(jpeg->regs, EXYNOS3250_IRQ_TIMEOUT);
2445 jpeg->irq_status = 0;
2446 exynos3250_jpeg_start(jpeg->regs);
2448 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
2451 static int s5p_jpeg_job_ready(void *priv)
2453 struct s5p_jpeg_ctx *ctx = priv;
2455 if (ctx->mode == S5P_JPEG_DECODE) {
2457 * We have only one input buffer and one output buffer. If there
2458 * is a resolution change event, no need to continue decoding.
2460 if (ctx->state == JPEGCTX_RESOLUTION_CHANGE)
2463 return ctx->hdr_parsed;
2469 static void s5p_jpeg_job_abort(void *priv)
2473 static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
2474 .device_run = s5p_jpeg_device_run,
2475 .job_ready = s5p_jpeg_job_ready,
2476 .job_abort = s5p_jpeg_job_abort,
2479 static struct v4l2_m2m_ops exynos3250_jpeg_m2m_ops = {
2480 .device_run = exynos3250_jpeg_device_run,
2481 .job_ready = s5p_jpeg_job_ready,
2482 .job_abort = s5p_jpeg_job_abort,
2485 static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = {
2486 .device_run = exynos4_jpeg_device_run,
2487 .job_ready = s5p_jpeg_job_ready,
2488 .job_abort = s5p_jpeg_job_abort,
2492 * ============================================================================
2494 * ============================================================================
2497 static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
2498 unsigned int *nbuffers, unsigned int *nplanes,
2499 unsigned int sizes[], struct device *alloc_devs[])
2501 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
2502 struct s5p_jpeg_q_data *q_data = NULL;
2503 unsigned int size, count = *nbuffers;
2505 q_data = get_q_data(ctx, vq->type);
2506 BUG_ON(q_data == NULL);
2508 size = q_data->size;
2511 * header is parsed during decoding and parsed information stored
2512 * in the context so we do not allow another buffer to overwrite it
2514 if (ctx->mode == S5P_JPEG_DECODE)
2524 static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
2526 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2527 struct s5p_jpeg_q_data *q_data = NULL;
2529 q_data = get_q_data(ctx, vb->vb2_queue->type);
2530 BUG_ON(q_data == NULL);
2532 if (vb2_plane_size(vb, 0) < q_data->size) {
2533 pr_err("%s data will not fit into plane (%lu < %lu)\n",
2534 __func__, vb2_plane_size(vb, 0),
2535 (long)q_data->size);
2539 vb2_set_plane_payload(vb, 0, q_data->size);
2544 static void s5p_jpeg_set_capture_queue_data(struct s5p_jpeg_ctx *ctx)
2546 struct s5p_jpeg_q_data *q_data = &ctx->cap_q;
2548 q_data->w = ctx->out_q.w;
2549 q_data->h = ctx->out_q.h;
2552 * This call to jpeg_bound_align_image() takes care of width and
2553 * height values alignment when user space calls the QBUF of
2554 * OUTPUT buffer after the S_FMT of CAPTURE buffer.
2555 * Please note that on Exynos4x12 SoCs, resigning from executing
2556 * S_FMT on capture buffer for each JPEG image can result in a
2557 * hardware hangup if subsampling is lower than the one of input
2560 jpeg_bound_align_image(ctx, &q_data->w, S5P_JPEG_MIN_WIDTH,
2561 S5P_JPEG_MAX_WIDTH, q_data->fmt->h_align,
2562 &q_data->h, S5P_JPEG_MIN_HEIGHT,
2563 S5P_JPEG_MAX_HEIGHT, q_data->fmt->v_align);
2565 q_data->size = q_data->w * q_data->h * q_data->fmt->depth >> 3;
2568 static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
2570 struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
2571 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2573 if (ctx->mode == S5P_JPEG_DECODE &&
2574 vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
2575 static const struct v4l2_event ev_src_ch = {
2576 .type = V4L2_EVENT_SOURCE_CHANGE,
2577 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
2579 struct vb2_queue *dst_vq;
2583 dst_vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
2584 V4L2_BUF_TYPE_VIDEO_CAPTURE);
2585 ori_w = ctx->out_q.w;
2586 ori_h = ctx->out_q.h;
2588 ctx->hdr_parsed = s5p_jpeg_parse_hdr(&ctx->out_q,
2589 (unsigned long)vb2_plane_vaddr(vb, 0),
2590 min((unsigned long)ctx->out_q.size,
2591 vb2_get_plane_payload(vb, 0)), ctx);
2592 if (!ctx->hdr_parsed) {
2593 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
2598 * If there is a resolution change event, only update capture
2599 * queue when it is not streaming. Otherwise, update it in
2600 * STREAMOFF. See s5p_jpeg_stop_streaming for detail.
2602 if (ctx->out_q.w != ori_w || ctx->out_q.h != ori_h) {
2603 v4l2_event_queue_fh(&ctx->fh, &ev_src_ch);
2604 if (vb2_is_streaming(dst_vq))
2605 ctx->state = JPEGCTX_RESOLUTION_CHANGE;
2607 s5p_jpeg_set_capture_queue_data(ctx);
2611 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
2614 static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
2616 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
2619 ret = pm_runtime_get_sync(ctx->jpeg->dev);
2621 return ret > 0 ? 0 : ret;
2624 static void s5p_jpeg_stop_streaming(struct vb2_queue *q)
2626 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
2629 * STREAMOFF is an acknowledgment for resolution change event.
2630 * Before STREAMOFF, we still have to return the old resolution and
2631 * subsampling. Update capture queue when the stream is off.
2633 if (ctx->state == JPEGCTX_RESOLUTION_CHANGE &&
2634 q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
2635 s5p_jpeg_set_capture_queue_data(ctx);
2636 ctx->state = JPEGCTX_RUNNING;
2639 pm_runtime_put(ctx->jpeg->dev);
2642 static const struct vb2_ops s5p_jpeg_qops = {
2643 .queue_setup = s5p_jpeg_queue_setup,
2644 .buf_prepare = s5p_jpeg_buf_prepare,
2645 .buf_queue = s5p_jpeg_buf_queue,
2646 .wait_prepare = vb2_ops_wait_prepare,
2647 .wait_finish = vb2_ops_wait_finish,
2648 .start_streaming = s5p_jpeg_start_streaming,
2649 .stop_streaming = s5p_jpeg_stop_streaming,
2652 static int queue_init(void *priv, struct vb2_queue *src_vq,
2653 struct vb2_queue *dst_vq)
2655 struct s5p_jpeg_ctx *ctx = priv;
2658 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2659 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
2660 src_vq->drv_priv = ctx;
2661 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2662 src_vq->ops = &s5p_jpeg_qops;
2663 src_vq->mem_ops = &vb2_dma_contig_memops;
2664 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2665 src_vq->lock = &ctx->jpeg->lock;
2666 src_vq->dev = ctx->jpeg->dev;
2668 ret = vb2_queue_init(src_vq);
2672 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2673 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
2674 dst_vq->drv_priv = ctx;
2675 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2676 dst_vq->ops = &s5p_jpeg_qops;
2677 dst_vq->mem_ops = &vb2_dma_contig_memops;
2678 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2679 dst_vq->lock = &ctx->jpeg->lock;
2680 dst_vq->dev = ctx->jpeg->dev;
2682 return vb2_queue_init(dst_vq);
2686 * ============================================================================
2688 * ============================================================================
2691 static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
2693 struct s5p_jpeg *jpeg = dev_id;
2694 struct s5p_jpeg_ctx *curr_ctx;
2695 struct vb2_v4l2_buffer *src_buf, *dst_buf;
2696 unsigned long payload_size = 0;
2697 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
2698 bool enc_jpeg_too_large = false;
2699 bool timer_elapsed = false;
2700 bool op_completed = false;
2702 spin_lock(&jpeg->slock);
2704 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2706 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2707 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2709 if (curr_ctx->mode == S5P_JPEG_ENCODE)
2710 enc_jpeg_too_large = s5p_jpeg_enc_stream_stat(jpeg->regs);
2711 timer_elapsed = s5p_jpeg_timer_stat(jpeg->regs);
2712 op_completed = s5p_jpeg_result_stat_ok(jpeg->regs);
2713 if (curr_ctx->mode == S5P_JPEG_DECODE)
2714 op_completed = op_completed &&
2715 s5p_jpeg_stream_stat_ok(jpeg->regs);
2717 if (enc_jpeg_too_large) {
2718 state = VB2_BUF_STATE_ERROR;
2719 s5p_jpeg_clear_enc_stream_stat(jpeg->regs);
2720 } else if (timer_elapsed) {
2721 state = VB2_BUF_STATE_ERROR;
2722 s5p_jpeg_clear_timer_stat(jpeg->regs);
2723 } else if (!op_completed) {
2724 state = VB2_BUF_STATE_ERROR;
2726 payload_size = s5p_jpeg_compressed_size(jpeg->regs);
2729 dst_buf->timecode = src_buf->timecode;
2730 dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
2731 dst_buf->flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
2733 src_buf->flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
2735 v4l2_m2m_buf_done(src_buf, state);
2736 if (curr_ctx->mode == S5P_JPEG_ENCODE)
2737 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size);
2738 v4l2_m2m_buf_done(dst_buf, state);
2740 curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs);
2741 spin_unlock(&jpeg->slock);
2743 s5p_jpeg_clear_int(jpeg->regs);
2745 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2749 static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
2751 unsigned int int_status;
2752 struct vb2_v4l2_buffer *src_vb, *dst_vb;
2753 struct s5p_jpeg *jpeg = priv;
2754 struct s5p_jpeg_ctx *curr_ctx;
2755 unsigned long payload_size = 0;
2757 spin_lock(&jpeg->slock);
2759 exynos4_jpeg_set_sys_int_enable(jpeg->regs, 0);
2761 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2763 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2764 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2766 int_status = exynos4_jpeg_get_int_status(jpeg->regs);
2769 switch (int_status & 0x1f) {
2771 jpeg->irq_ret = ERR_PROT;
2774 jpeg->irq_ret = OK_ENC_OR_DEC;
2777 jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
2780 jpeg->irq_ret = ERR_MULTI_SCAN;
2783 jpeg->irq_ret = ERR_FRAME;
2786 jpeg->irq_ret = ERR_UNKNOWN;
2790 jpeg->irq_ret = ERR_UNKNOWN;
2793 if (jpeg->irq_ret == OK_ENC_OR_DEC) {
2794 if (curr_ctx->mode == S5P_JPEG_ENCODE) {
2795 payload_size = exynos4_jpeg_get_stream_size(jpeg->regs);
2796 vb2_set_plane_payload(&dst_vb->vb2_buf,
2799 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
2800 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
2802 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
2803 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
2806 if (jpeg->variant->version == SJPEG_EXYNOS4)
2807 curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
2809 exynos4_jpeg_set_enc_dec_mode(jpeg->regs, S5P_JPEG_DISABLE);
2811 spin_unlock(&jpeg->slock);
2813 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2817 static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id)
2819 struct s5p_jpeg *jpeg = dev_id;
2820 struct s5p_jpeg_ctx *curr_ctx;
2821 struct vb2_v4l2_buffer *src_buf, *dst_buf;
2822 unsigned long payload_size = 0;
2823 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
2824 bool interrupt_timeout = false;
2825 bool stream_error = false;
2828 spin_lock(&jpeg->slock);
2830 irq_status = exynos3250_jpeg_get_timer_status(jpeg->regs);
2831 if (irq_status & EXYNOS3250_TIMER_INT_STAT) {
2832 exynos3250_jpeg_clear_timer_status(jpeg->regs);
2833 interrupt_timeout = true;
2834 dev_err(jpeg->dev, "Interrupt timeout occurred.\n");
2837 irq_status = exynos3250_jpeg_get_int_status(jpeg->regs);
2838 exynos3250_jpeg_clear_int_status(jpeg->regs, irq_status);
2840 jpeg->irq_status |= irq_status;
2842 if (jpeg->variant->version == SJPEG_EXYNOS5420 &&
2843 irq_status & EXYNOS3250_STREAM_STAT) {
2844 stream_error = true;
2845 dev_err(jpeg->dev, "Syntax error or unrecoverable error occurred.\n");
2848 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2853 if ((irq_status & EXYNOS3250_HEADER_STAT) &&
2854 (curr_ctx->mode == S5P_JPEG_DECODE)) {
2855 exynos3250_jpeg_rstart(jpeg->regs);
2859 if (jpeg->irq_status & (EXYNOS3250_JPEG_DONE |
2860 EXYNOS3250_WDMA_DONE |
2861 EXYNOS3250_RDMA_DONE |
2862 EXYNOS3250_RESULT_STAT))
2863 payload_size = exynos3250_jpeg_compressed_size(jpeg->regs);
2864 else if (interrupt_timeout || stream_error)
2865 state = VB2_BUF_STATE_ERROR;
2869 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2870 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2872 dst_buf->timecode = src_buf->timecode;
2873 dst_buf->vb2_buf.timestamp = src_buf->vb2_buf.timestamp;
2875 v4l2_m2m_buf_done(src_buf, state);
2876 if (curr_ctx->mode == S5P_JPEG_ENCODE)
2877 vb2_set_plane_payload(&dst_buf->vb2_buf, 0, payload_size);
2878 v4l2_m2m_buf_done(dst_buf, state);
2880 curr_ctx->subsampling =
2881 exynos3250_jpeg_get_subsampling_mode(jpeg->regs);
2883 spin_unlock(&jpeg->slock);
2885 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2889 spin_unlock(&jpeg->slock);
2893 static void *jpeg_get_drv_data(struct device *dev);
2896 * ============================================================================
2897 * Driver basic infrastructure
2898 * ============================================================================
2901 static int s5p_jpeg_probe(struct platform_device *pdev)
2903 struct s5p_jpeg *jpeg;
2904 struct resource *res;
2907 /* JPEG IP abstraction struct */
2908 jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
2912 jpeg->variant = jpeg_get_drv_data(&pdev->dev);
2914 mutex_init(&jpeg->lock);
2915 spin_lock_init(&jpeg->slock);
2916 jpeg->dev = &pdev->dev;
2918 /* memory-mapped registers */
2919 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2921 jpeg->regs = devm_ioremap_resource(&pdev->dev, res);
2922 if (IS_ERR(jpeg->regs))
2923 return PTR_ERR(jpeg->regs);
2925 /* interrupt service routine registration */
2926 jpeg->irq = ret = platform_get_irq(pdev, 0);
2928 dev_err(&pdev->dev, "cannot find IRQ\n");
2932 ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
2933 0, dev_name(&pdev->dev), jpeg);
2935 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
2940 for (i = 0; i < jpeg->variant->num_clocks; i++) {
2941 jpeg->clocks[i] = devm_clk_get(&pdev->dev,
2942 jpeg->variant->clk_names[i]);
2943 if (IS_ERR(jpeg->clocks[i])) {
2944 dev_err(&pdev->dev, "failed to get clock: %s\n",
2945 jpeg->variant->clk_names[i]);
2946 return PTR_ERR(jpeg->clocks[i]);
2951 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
2953 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
2957 /* mem2mem device */
2958 jpeg->m2m_dev = v4l2_m2m_init(jpeg->variant->m2m_ops);
2959 if (IS_ERR(jpeg->m2m_dev)) {
2960 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
2961 ret = PTR_ERR(jpeg->m2m_dev);
2962 goto device_register_rollback;
2965 vb2_dma_contig_set_max_seg_size(&pdev->dev, DMA_BIT_MASK(32));
2967 /* JPEG encoder /dev/videoX node */
2968 jpeg->vfd_encoder = video_device_alloc();
2969 if (!jpeg->vfd_encoder) {
2970 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
2972 goto m2m_init_rollback;
2974 snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name),
2975 "%s-enc", S5P_JPEG_M2M_NAME);
2976 jpeg->vfd_encoder->fops = &s5p_jpeg_fops;
2977 jpeg->vfd_encoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
2978 jpeg->vfd_encoder->minor = -1;
2979 jpeg->vfd_encoder->release = video_device_release;
2980 jpeg->vfd_encoder->lock = &jpeg->lock;
2981 jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev;
2982 jpeg->vfd_encoder->vfl_dir = VFL_DIR_M2M;
2984 ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
2986 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
2987 video_device_release(jpeg->vfd_encoder);
2988 goto m2m_init_rollback;
2991 video_set_drvdata(jpeg->vfd_encoder, jpeg);
2992 v4l2_info(&jpeg->v4l2_dev,
2993 "encoder device registered as /dev/video%d\n",
2994 jpeg->vfd_encoder->num);
2996 /* JPEG decoder /dev/videoX node */
2997 jpeg->vfd_decoder = video_device_alloc();
2998 if (!jpeg->vfd_decoder) {
2999 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
3001 goto enc_vdev_register_rollback;
3003 snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name),
3004 "%s-dec", S5P_JPEG_M2M_NAME);
3005 jpeg->vfd_decoder->fops = &s5p_jpeg_fops;
3006 jpeg->vfd_decoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
3007 jpeg->vfd_decoder->minor = -1;
3008 jpeg->vfd_decoder->release = video_device_release;
3009 jpeg->vfd_decoder->lock = &jpeg->lock;
3010 jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev;
3011 jpeg->vfd_decoder->vfl_dir = VFL_DIR_M2M;
3013 ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
3015 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
3016 video_device_release(jpeg->vfd_decoder);
3017 goto enc_vdev_register_rollback;
3020 video_set_drvdata(jpeg->vfd_decoder, jpeg);
3021 v4l2_info(&jpeg->v4l2_dev,
3022 "decoder device registered as /dev/video%d\n",
3023 jpeg->vfd_decoder->num);
3025 /* final statements & power management */
3026 platform_set_drvdata(pdev, jpeg);
3028 pm_runtime_enable(&pdev->dev);
3030 v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
3034 enc_vdev_register_rollback:
3035 video_unregister_device(jpeg->vfd_encoder);
3038 v4l2_m2m_release(jpeg->m2m_dev);
3040 device_register_rollback:
3041 v4l2_device_unregister(&jpeg->v4l2_dev);
3046 static int s5p_jpeg_remove(struct platform_device *pdev)
3048 struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
3051 pm_runtime_disable(jpeg->dev);
3053 video_unregister_device(jpeg->vfd_decoder);
3054 video_unregister_device(jpeg->vfd_encoder);
3055 vb2_dma_contig_clear_max_seg_size(&pdev->dev);
3056 v4l2_m2m_release(jpeg->m2m_dev);
3057 v4l2_device_unregister(&jpeg->v4l2_dev);
3059 if (!pm_runtime_status_suspended(&pdev->dev)) {
3060 for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
3061 clk_disable_unprepare(jpeg->clocks[i]);
3068 static int s5p_jpeg_runtime_suspend(struct device *dev)
3070 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
3073 for (i = jpeg->variant->num_clocks - 1; i >= 0; i--)
3074 clk_disable_unprepare(jpeg->clocks[i]);
3079 static int s5p_jpeg_runtime_resume(struct device *dev)
3081 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
3082 unsigned long flags;
3085 for (i = 0; i < jpeg->variant->num_clocks; i++) {
3086 ret = clk_prepare_enable(jpeg->clocks[i]);
3089 clk_disable_unprepare(jpeg->clocks[i]);
3094 spin_lock_irqsave(&jpeg->slock, flags);
3097 * JPEG IP allows storing two Huffman tables for each component.
3098 * We fill table 0 for each component and do this here only
3099 * for S5PC210 and Exynos3250 SoCs. Exynos4x12 and Exynos542x SoC
3100 * require programming their Huffman tables each time the encoding
3101 * process is initialized, and thus it is accomplished in the
3102 * device_run callback of m2m_ops.
3104 if (!jpeg->variant->htbl_reinit) {
3105 s5p_jpeg_set_hdctbl(jpeg->regs);
3106 s5p_jpeg_set_hdctblg(jpeg->regs);
3107 s5p_jpeg_set_hactbl(jpeg->regs);
3108 s5p_jpeg_set_hactblg(jpeg->regs);
3111 spin_unlock_irqrestore(&jpeg->slock, flags);
3115 #endif /* CONFIG_PM */
3117 static const struct dev_pm_ops s5p_jpeg_pm_ops = {
3118 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
3119 pm_runtime_force_resume)
3120 SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume,
3124 static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
3125 .version = SJPEG_S5P,
3126 .jpeg_irq = s5p_jpeg_irq,
3127 .m2m_ops = &s5p_jpeg_m2m_ops,
3128 .fmt_ver_flag = SJPEG_FMT_FLAG_S5P,
3129 .clk_names = {"jpeg"},
3133 static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = {
3134 .version = SJPEG_EXYNOS3250,
3135 .jpeg_irq = exynos3250_jpeg_irq,
3136 .m2m_ops = &exynos3250_jpeg_m2m_ops,
3137 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250,
3139 .clk_names = {"jpeg", "sclk"},
3143 static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
3144 .version = SJPEG_EXYNOS4,
3145 .jpeg_irq = exynos4_jpeg_irq,
3146 .m2m_ops = &exynos4_jpeg_m2m_ops,
3147 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4,
3149 .clk_names = {"jpeg"},
3154 static struct s5p_jpeg_variant exynos5420_jpeg_drvdata = {
3155 .version = SJPEG_EXYNOS5420,
3156 .jpeg_irq = exynos3250_jpeg_irq, /* intentionally 3250 */
3157 .m2m_ops = &exynos3250_jpeg_m2m_ops, /* intentionally 3250 */
3158 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250, /* intentionally 3250 */
3161 .clk_names = {"jpeg"},
3165 static struct s5p_jpeg_variant exynos5433_jpeg_drvdata = {
3166 .version = SJPEG_EXYNOS5433,
3167 .jpeg_irq = exynos4_jpeg_irq,
3168 .m2m_ops = &exynos4_jpeg_m2m_ops,
3169 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4,
3171 .clk_names = {"pclk", "aclk", "aclk_xiu", "sclk"},
3176 static const struct of_device_id samsung_jpeg_match[] = {
3178 .compatible = "samsung,s5pv210-jpeg",
3179 .data = &s5p_jpeg_drvdata,
3181 .compatible = "samsung,exynos3250-jpeg",
3182 .data = &exynos3250_jpeg_drvdata,
3184 .compatible = "samsung,exynos4210-jpeg",
3185 .data = &exynos4_jpeg_drvdata,
3187 .compatible = "samsung,exynos4212-jpeg",
3188 .data = &exynos4_jpeg_drvdata,
3190 .compatible = "samsung,exynos5420-jpeg",
3191 .data = &exynos5420_jpeg_drvdata,
3193 .compatible = "samsung,exynos5433-jpeg",
3194 .data = &exynos5433_jpeg_drvdata,
3199 MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
3201 static void *jpeg_get_drv_data(struct device *dev)
3203 struct s5p_jpeg_variant *driver_data = NULL;
3204 const struct of_device_id *match;
3206 if (!IS_ENABLED(CONFIG_OF) || !dev->of_node)
3207 return &s5p_jpeg_drvdata;
3209 match = of_match_node(samsung_jpeg_match, dev->of_node);
3212 driver_data = (struct s5p_jpeg_variant *)match->data;
3217 static struct platform_driver s5p_jpeg_driver = {
3218 .probe = s5p_jpeg_probe,
3219 .remove = s5p_jpeg_remove,
3221 .of_match_table = of_match_ptr(samsung_jpeg_match),
3222 .name = S5P_JPEG_M2M_NAME,
3223 .pm = &s5p_jpeg_pm_ops,
3227 module_platform_driver(s5p_jpeg_driver);
3229 MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
3230 MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
3231 MODULE_DESCRIPTION("Samsung JPEG codec driver");
3232 MODULE_LICENSE("GPL");