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-mem2mem.h>
28 #include <media/v4l2-ioctl.h>
29 #include <media/videobuf2-core.h>
30 #include <media/videobuf2-dma-contig.h>
32 #include "jpeg-core.h"
33 #include "jpeg-hw-s5p.h"
34 #include "jpeg-hw-exynos4.h"
35 #include "jpeg-hw-exynos3250.h"
36 #include "jpeg-regs.h"
38 static struct s5p_jpeg_fmt sjpeg_formats[] = {
41 .fourcc = V4L2_PIX_FMT_JPEG,
42 .flags = SJPEG_FMT_FLAG_ENC_CAPTURE |
43 SJPEG_FMT_FLAG_DEC_OUTPUT |
45 SJPEG_FMT_FLAG_EXYNOS3250 |
46 SJPEG_FMT_FLAG_EXYNOS4,
49 .name = "YUV 4:2:2 packed, YCbYCr",
50 .fourcc = V4L2_PIX_FMT_YUYV,
55 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
56 SJPEG_FMT_FLAG_DEC_CAPTURE |
59 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
62 .name = "YUV 4:2:2 packed, YCbYCr",
63 .fourcc = V4L2_PIX_FMT_YUYV,
68 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
69 SJPEG_FMT_FLAG_DEC_CAPTURE |
70 SJPEG_FMT_FLAG_EXYNOS4 |
72 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
75 .name = "YUV 4:2:2 packed, YCbYCr",
76 .fourcc = V4L2_PIX_FMT_YUYV,
81 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
82 SJPEG_FMT_FLAG_DEC_CAPTURE |
83 SJPEG_FMT_FLAG_EXYNOS3250 |
85 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
88 .name = "YUV 4:2:2 packed, YCrYCb",
89 .fourcc = V4L2_PIX_FMT_YVYU,
94 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
95 SJPEG_FMT_FLAG_DEC_CAPTURE |
96 SJPEG_FMT_FLAG_EXYNOS4 |
98 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
101 .name = "YUV 4:2:2 packed, YCrYCb",
102 .fourcc = V4L2_PIX_FMT_YVYU,
107 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
108 SJPEG_FMT_FLAG_DEC_CAPTURE |
109 SJPEG_FMT_FLAG_EXYNOS3250 |
111 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
114 .name = "YUV 4:2:2 packed, YCrYCb",
115 .fourcc = V4L2_PIX_FMT_UYVY,
120 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
121 SJPEG_FMT_FLAG_DEC_CAPTURE |
122 SJPEG_FMT_FLAG_EXYNOS3250 |
124 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
127 .name = "YUV 4:2:2 packed, YCrYCb",
128 .fourcc = V4L2_PIX_FMT_VYUY,
133 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
134 SJPEG_FMT_FLAG_DEC_CAPTURE |
135 SJPEG_FMT_FLAG_EXYNOS3250 |
137 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
141 .fourcc = V4L2_PIX_FMT_RGB565,
146 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
147 SJPEG_FMT_FLAG_DEC_CAPTURE |
148 SJPEG_FMT_FLAG_EXYNOS4 |
150 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
154 .fourcc = V4L2_PIX_FMT_RGB565,
159 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
160 SJPEG_FMT_FLAG_DEC_CAPTURE |
161 SJPEG_FMT_FLAG_EXYNOS3250 |
163 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
167 .fourcc = V4L2_PIX_FMT_RGB565X,
172 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
173 SJPEG_FMT_FLAG_DEC_CAPTURE |
174 SJPEG_FMT_FLAG_EXYNOS3250 |
176 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
180 .fourcc = V4L2_PIX_FMT_RGB565,
185 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
188 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
191 .name = "ARGB8888, 32 bpp",
192 .fourcc = V4L2_PIX_FMT_RGB32,
197 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
198 SJPEG_FMT_FLAG_DEC_CAPTURE |
199 SJPEG_FMT_FLAG_EXYNOS4 |
201 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
204 .name = "ARGB8888, 32 bpp",
205 .fourcc = V4L2_PIX_FMT_RGB32,
210 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
211 SJPEG_FMT_FLAG_DEC_CAPTURE |
212 SJPEG_FMT_FLAG_EXYNOS3250 |
214 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
217 .name = "YUV 4:4:4 planar, Y/CbCr",
218 .fourcc = V4L2_PIX_FMT_NV24,
223 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
224 SJPEG_FMT_FLAG_DEC_CAPTURE |
225 SJPEG_FMT_FLAG_EXYNOS4 |
227 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
230 .name = "YUV 4:4:4 planar, Y/CrCb",
231 .fourcc = V4L2_PIX_FMT_NV42,
236 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
237 SJPEG_FMT_FLAG_DEC_CAPTURE |
238 SJPEG_FMT_FLAG_EXYNOS4 |
240 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444,
243 .name = "YUV 4:2:2 planar, Y/CrCb",
244 .fourcc = V4L2_PIX_FMT_NV61,
249 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
250 SJPEG_FMT_FLAG_DEC_CAPTURE |
251 SJPEG_FMT_FLAG_EXYNOS4 |
253 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
256 .name = "YUV 4:2:2 planar, Y/CbCr",
257 .fourcc = V4L2_PIX_FMT_NV16,
262 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
263 SJPEG_FMT_FLAG_DEC_CAPTURE |
264 SJPEG_FMT_FLAG_EXYNOS4 |
266 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422,
269 .name = "YUV 4:2:0 planar, Y/CbCr",
270 .fourcc = V4L2_PIX_FMT_NV12,
275 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
276 SJPEG_FMT_FLAG_DEC_CAPTURE |
277 SJPEG_FMT_FLAG_EXYNOS4 |
279 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
282 .name = "YUV 4:2:0 planar, Y/CbCr",
283 .fourcc = V4L2_PIX_FMT_NV12,
288 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
289 SJPEG_FMT_FLAG_DEC_CAPTURE |
290 SJPEG_FMT_FLAG_EXYNOS3250 |
292 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
295 .name = "YUV 4:2:0 planar, Y/CbCr",
296 .fourcc = V4L2_PIX_FMT_NV12,
301 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
302 SJPEG_FMT_FLAG_DEC_CAPTURE |
305 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
308 .name = "YUV 4:2:0 planar, Y/CrCb",
309 .fourcc = V4L2_PIX_FMT_NV21,
314 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
315 SJPEG_FMT_FLAG_DEC_CAPTURE |
316 SJPEG_FMT_FLAG_EXYNOS3250 |
318 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
321 .name = "YUV 4:2:0 planar, Y/CrCb",
322 .fourcc = V4L2_PIX_FMT_NV21,
327 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
328 SJPEG_FMT_FLAG_DEC_CAPTURE |
329 SJPEG_FMT_FLAG_EXYNOS3250 |
330 SJPEG_FMT_FLAG_EXYNOS4 |
332 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
335 .name = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
336 .fourcc = V4L2_PIX_FMT_YUV420,
341 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
342 SJPEG_FMT_FLAG_DEC_CAPTURE |
343 SJPEG_FMT_FLAG_EXYNOS4 |
345 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
348 .name = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr",
349 .fourcc = V4L2_PIX_FMT_YUV420,
354 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
355 SJPEG_FMT_FLAG_DEC_CAPTURE |
356 SJPEG_FMT_FLAG_EXYNOS3250 |
358 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420,
362 .fourcc = V4L2_PIX_FMT_GREY,
365 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT |
366 SJPEG_FMT_FLAG_DEC_CAPTURE |
367 SJPEG_FMT_FLAG_EXYNOS4 |
369 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
372 #define SJPEG_NUM_FORMATS ARRAY_SIZE(sjpeg_formats)
374 static const unsigned char qtbl_luminance[4][64] = {
375 {/*level 0 - high compression quality */
376 20, 16, 25, 39, 50, 46, 62, 68,
377 16, 18, 23, 38, 38, 53, 65, 68,
378 25, 23, 31, 38, 53, 65, 68, 68,
379 39, 38, 38, 53, 65, 68, 68, 68,
380 50, 38, 53, 65, 68, 68, 68, 68,
381 46, 53, 65, 68, 68, 68, 68, 68,
382 62, 65, 68, 68, 68, 68, 68, 68,
383 68, 68, 68, 68, 68, 68, 68, 68
386 16, 11, 11, 16, 23, 27, 31, 30,
387 11, 12, 12, 15, 20, 23, 23, 30,
388 11, 12, 13, 16, 23, 26, 35, 47,
389 16, 15, 16, 23, 26, 37, 47, 64,
390 23, 20, 23, 26, 39, 51, 64, 64,
391 27, 23, 26, 37, 51, 64, 64, 64,
392 31, 23, 35, 47, 64, 64, 64, 64,
393 30, 30, 47, 64, 64, 64, 64, 64
396 12, 8, 8, 12, 17, 21, 24, 23,
397 8, 9, 9, 11, 15, 19, 18, 23,
398 8, 9, 10, 12, 19, 20, 27, 36,
399 12, 11, 12, 21, 20, 28, 36, 53,
400 17, 15, 19, 20, 30, 39, 51, 59,
401 21, 19, 20, 28, 39, 51, 59, 59,
402 24, 18, 27, 36, 51, 59, 59, 59,
403 23, 23, 36, 53, 59, 59, 59, 59
405 {/* level 3 - low compression quality */
406 8, 6, 6, 8, 12, 14, 16, 17,
407 6, 6, 6, 8, 10, 13, 12, 15,
408 6, 6, 7, 8, 13, 14, 18, 24,
409 8, 8, 8, 14, 13, 19, 24, 35,
410 12, 10, 13, 13, 20, 26, 34, 39,
411 14, 13, 14, 19, 26, 34, 39, 39,
412 16, 12, 18, 24, 34, 39, 39, 39,
413 17, 15, 24, 35, 39, 39, 39, 39
417 static const unsigned char qtbl_chrominance[4][64] = {
418 {/*level 0 - high compression quality */
419 21, 25, 32, 38, 54, 68, 68, 68,
420 25, 28, 24, 38, 54, 68, 68, 68,
421 32, 24, 32, 43, 66, 68, 68, 68,
422 38, 38, 43, 53, 68, 68, 68, 68,
423 54, 54, 66, 68, 68, 68, 68, 68,
424 68, 68, 68, 68, 68, 68, 68, 68,
425 68, 68, 68, 68, 68, 68, 68, 68,
426 68, 68, 68, 68, 68, 68, 68, 68
429 17, 15, 17, 21, 20, 26, 38, 48,
430 15, 19, 18, 17, 20, 26, 35, 43,
431 17, 18, 20, 22, 26, 30, 46, 53,
432 21, 17, 22, 28, 30, 39, 53, 64,
433 20, 20, 26, 30, 39, 48, 64, 64,
434 26, 26, 30, 39, 48, 63, 64, 64,
435 38, 35, 46, 53, 64, 64, 64, 64,
436 48, 43, 53, 64, 64, 64, 64, 64
439 13, 11, 13, 16, 20, 20, 29, 37,
440 11, 14, 14, 14, 16, 20, 26, 32,
441 13, 14, 15, 17, 20, 23, 35, 40,
442 16, 14, 17, 21, 23, 30, 40, 50,
443 20, 16, 20, 23, 30, 37, 50, 59,
444 20, 20, 23, 30, 37, 48, 59, 59,
445 29, 26, 35, 40, 50, 59, 59, 59,
446 37, 32, 40, 50, 59, 59, 59, 59
448 {/* level 3 - low compression quality */
449 9, 8, 9, 11, 14, 17, 19, 24,
450 8, 10, 9, 11, 14, 13, 17, 22,
451 9, 9, 13, 14, 13, 15, 23, 26,
452 11, 11, 14, 14, 15, 20, 26, 33,
453 14, 14, 13, 15, 20, 24, 33, 39,
454 17, 13, 15, 20, 24, 32, 39, 39,
455 19, 17, 23, 26, 33, 39, 39, 39,
456 24, 22, 26, 33, 39, 39, 39, 39
460 static const unsigned char hdctbl0[16] = {
461 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
464 static const unsigned char hdctblg0[12] = {
465 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
467 static const unsigned char hactbl0[16] = {
468 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
470 static const unsigned char hactblg0[162] = {
471 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
472 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
473 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
474 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
475 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
476 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
477 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
478 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
479 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
480 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
481 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
482 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
483 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
484 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
485 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
486 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
487 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
488 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
489 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
490 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
495 * Fourcc downgrade schema lookup tables for 422 and 420
496 * chroma subsampling - fourcc on each position maps on the
497 * fourcc from the table fourcc_to_dwngrd_schema_id which allows
498 * to get the most suitable fourcc counterpart for the given
499 * downgraded subsampling property.
501 static const u32 subs422_fourcc_dwngrd_schema[] = {
506 static const u32 subs420_fourcc_dwngrd_schema[] = {
520 * Lookup table for translation of a fourcc to the position
521 * of its downgraded counterpart in the *fourcc_dwngrd_schema
524 static const u32 fourcc_to_dwngrd_schema_id[] = {
537 static int s5p_jpeg_get_dwngrd_sch_id_by_fourcc(u32 fourcc)
540 for (i = 0; i < ARRAY_SIZE(fourcc_to_dwngrd_schema_id); ++i) {
541 if (fourcc_to_dwngrd_schema_id[i] == fourcc)
548 static int s5p_jpeg_adjust_fourcc_to_subsampling(
549 enum v4l2_jpeg_chroma_subsampling subs,
552 struct s5p_jpeg_ctx *ctx)
556 if (ctx->subsampling != V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY) {
558 s5p_jpeg_get_dwngrd_sch_id_by_fourcc(in_fourcc);
559 if (dwngrd_sch_id < 0)
563 switch (ctx->subsampling) {
564 case V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY:
565 *out_fourcc = V4L2_PIX_FMT_GREY;
567 case V4L2_JPEG_CHROMA_SUBSAMPLING_420:
569 ARRAY_SIZE(subs420_fourcc_dwngrd_schema) - 1)
571 *out_fourcc = subs420_fourcc_dwngrd_schema[dwngrd_sch_id];
573 case V4L2_JPEG_CHROMA_SUBSAMPLING_422:
575 ARRAY_SIZE(subs422_fourcc_dwngrd_schema) - 1)
577 *out_fourcc = subs422_fourcc_dwngrd_schema[dwngrd_sch_id];
580 *out_fourcc = V4L2_PIX_FMT_GREY;
587 static int exynos4x12_decoded_subsampling[] = {
588 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
589 V4L2_JPEG_CHROMA_SUBSAMPLING_444,
590 V4L2_JPEG_CHROMA_SUBSAMPLING_422,
591 V4L2_JPEG_CHROMA_SUBSAMPLING_420,
594 static int exynos3250_decoded_subsampling[] = {
595 V4L2_JPEG_CHROMA_SUBSAMPLING_444,
596 V4L2_JPEG_CHROMA_SUBSAMPLING_422,
597 V4L2_JPEG_CHROMA_SUBSAMPLING_420,
598 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY,
601 V4L2_JPEG_CHROMA_SUBSAMPLING_411,
604 static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c)
606 return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler);
609 static inline struct s5p_jpeg_ctx *fh_to_ctx(struct v4l2_fh *fh)
611 return container_of(fh, struct s5p_jpeg_ctx, fh);
614 static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx)
616 WARN_ON(ctx->subsampling > 3);
618 switch (ctx->jpeg->variant->version) {
620 if (ctx->subsampling > 2)
621 return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
622 return ctx->subsampling;
623 case SJPEG_EXYNOS3250:
624 case SJPEG_EXYNOS5420:
625 if (ctx->subsampling > 3)
626 return V4L2_JPEG_CHROMA_SUBSAMPLING_411;
627 return exynos3250_decoded_subsampling[ctx->subsampling];
629 if (ctx->subsampling > 2)
630 return V4L2_JPEG_CHROMA_SUBSAMPLING_420;
631 return exynos4x12_decoded_subsampling[ctx->subsampling];
633 return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
637 static inline void s5p_jpeg_set_qtbl(void __iomem *regs,
638 const unsigned char *qtbl,
639 unsigned long tab, int len)
643 for (i = 0; i < len; i++)
644 writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
647 static inline void s5p_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
649 /* this driver fills quantisation table 0 with data for luma */
650 s5p_jpeg_set_qtbl(regs, qtbl_luminance[quality],
651 S5P_JPG_QTBL_CONTENT(0),
652 ARRAY_SIZE(qtbl_luminance[quality]));
655 static inline void s5p_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
657 /* this driver fills quantisation table 1 with data for chroma */
658 s5p_jpeg_set_qtbl(regs, qtbl_chrominance[quality],
659 S5P_JPG_QTBL_CONTENT(1),
660 ARRAY_SIZE(qtbl_chrominance[quality]));
663 static inline void s5p_jpeg_set_htbl(void __iomem *regs,
664 const unsigned char *htbl,
665 unsigned long tab, int len)
669 for (i = 0; i < len; i++)
670 writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
673 static inline void s5p_jpeg_set_hdctbl(void __iomem *regs)
675 /* this driver fills table 0 for this component */
676 s5p_jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0),
677 ARRAY_SIZE(hdctbl0));
680 static inline void s5p_jpeg_set_hdctblg(void __iomem *regs)
682 /* this driver fills table 0 for this component */
683 s5p_jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0),
684 ARRAY_SIZE(hdctblg0));
687 static inline void s5p_jpeg_set_hactbl(void __iomem *regs)
689 /* this driver fills table 0 for this component */
690 s5p_jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0),
691 ARRAY_SIZE(hactbl0));
694 static inline void s5p_jpeg_set_hactblg(void __iomem *regs)
696 /* this driver fills table 0 for this component */
697 s5p_jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0),
698 ARRAY_SIZE(hactblg0));
701 static inline void exynos4_jpeg_set_tbl(void __iomem *regs,
702 const unsigned char *tbl,
703 unsigned long tab, int len)
708 for (i = 0; i < len; i += 4) {
713 writel(dword, regs + tab + i);
717 static inline void exynos4_jpeg_set_qtbl_lum(void __iomem *regs, int quality)
719 /* this driver fills quantisation table 0 with data for luma */
720 exynos4_jpeg_set_tbl(regs, qtbl_luminance[quality],
721 EXYNOS4_QTBL_CONTENT(0),
722 ARRAY_SIZE(qtbl_luminance[quality]));
725 static inline void exynos4_jpeg_set_qtbl_chr(void __iomem *regs, int quality)
727 /* this driver fills quantisation table 1 with data for chroma */
728 exynos4_jpeg_set_tbl(regs, qtbl_chrominance[quality],
729 EXYNOS4_QTBL_CONTENT(1),
730 ARRAY_SIZE(qtbl_chrominance[quality]));
733 static void exynos4_jpeg_set_huff_tbl(void __iomem *base)
735 exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCLL,
736 ARRAY_SIZE(hdctbl0));
737 exynos4_jpeg_set_tbl(base, hdctbl0, EXYNOS4_HUFF_TBL_HDCCL,
738 ARRAY_SIZE(hdctbl0));
739 exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCLV,
740 ARRAY_SIZE(hdctblg0));
741 exynos4_jpeg_set_tbl(base, hdctblg0, EXYNOS4_HUFF_TBL_HDCCV,
742 ARRAY_SIZE(hdctblg0));
743 exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACLL,
744 ARRAY_SIZE(hactbl0));
745 exynos4_jpeg_set_tbl(base, hactbl0, EXYNOS4_HUFF_TBL_HACCL,
746 ARRAY_SIZE(hactbl0));
747 exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACLV,
748 ARRAY_SIZE(hactblg0));
749 exynos4_jpeg_set_tbl(base, hactblg0, EXYNOS4_HUFF_TBL_HACCV,
750 ARRAY_SIZE(hactblg0));
754 * ============================================================================
755 * Device file operations
756 * ============================================================================
759 static int queue_init(void *priv, struct vb2_queue *src_vq,
760 struct vb2_queue *dst_vq);
761 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
762 __u32 pixelformat, unsigned int fmt_type);
763 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx);
765 static int s5p_jpeg_open(struct file *file)
767 struct s5p_jpeg *jpeg = video_drvdata(file);
768 struct video_device *vfd = video_devdata(file);
769 struct s5p_jpeg_ctx *ctx;
770 struct s5p_jpeg_fmt *out_fmt, *cap_fmt;
773 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
777 if (mutex_lock_interruptible(&jpeg->lock)) {
782 v4l2_fh_init(&ctx->fh, vfd);
783 /* Use separate control handler per file handle */
784 ctx->fh.ctrl_handler = &ctx->ctrl_handler;
785 file->private_data = &ctx->fh;
786 v4l2_fh_add(&ctx->fh);
789 if (vfd == jpeg->vfd_encoder) {
790 ctx->mode = S5P_JPEG_ENCODE;
791 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_RGB565,
793 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
796 ctx->mode = S5P_JPEG_DECODE;
797 out_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG,
799 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV,
801 ctx->scale_factor = EXYNOS3250_DEC_SCALE_FACTOR_8_8;
804 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init);
805 if (IS_ERR(ctx->fh.m2m_ctx)) {
806 ret = PTR_ERR(ctx->fh.m2m_ctx);
810 ctx->out_q.fmt = out_fmt;
811 ctx->cap_q.fmt = cap_fmt;
813 ret = s5p_jpeg_controls_create(ctx);
817 mutex_unlock(&jpeg->lock);
821 v4l2_fh_del(&ctx->fh);
822 v4l2_fh_exit(&ctx->fh);
823 mutex_unlock(&jpeg->lock);
829 static int s5p_jpeg_release(struct file *file)
831 struct s5p_jpeg *jpeg = video_drvdata(file);
832 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
834 mutex_lock(&jpeg->lock);
835 v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
836 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
837 v4l2_fh_del(&ctx->fh);
838 v4l2_fh_exit(&ctx->fh);
840 mutex_unlock(&jpeg->lock);
845 static const struct v4l2_file_operations s5p_jpeg_fops = {
846 .owner = THIS_MODULE,
847 .open = s5p_jpeg_open,
848 .release = s5p_jpeg_release,
849 .poll = v4l2_m2m_fop_poll,
850 .unlocked_ioctl = video_ioctl2,
851 .mmap = v4l2_m2m_fop_mmap,
855 * ============================================================================
856 * video ioctl operations
857 * ============================================================================
860 static int get_byte(struct s5p_jpeg_buffer *buf)
862 if (buf->curr >= buf->size)
865 return ((unsigned char *)buf->data)[buf->curr++];
868 static int get_word_be(struct s5p_jpeg_buffer *buf, unsigned int *word)
873 byte = get_byte(buf);
877 byte = get_byte(buf);
880 *word = (unsigned int)byte | temp;
884 static void skip(struct s5p_jpeg_buffer *buf, long len)
893 static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data *result,
894 unsigned long buffer, unsigned long size,
895 struct s5p_jpeg_ctx *ctx)
897 int c, components = 0, notfound;
898 unsigned int height, width, word, subsampling = 0;
900 struct s5p_jpeg_buffer jpeg_buffer;
902 jpeg_buffer.size = size;
903 jpeg_buffer.data = buffer;
904 jpeg_buffer.curr = 0;
908 c = get_byte(&jpeg_buffer);
914 c = get_byte(&jpeg_buffer);
922 /* SOF0: baseline JPEG */
924 if (get_word_be(&jpeg_buffer, &word))
926 if (get_byte(&jpeg_buffer) == -1)
928 if (get_word_be(&jpeg_buffer, &height))
930 if (get_word_be(&jpeg_buffer, &width))
932 components = get_byte(&jpeg_buffer);
933 if (components == -1)
937 if (components == 1) {
940 skip(&jpeg_buffer, 1);
941 subsampling = get_byte(&jpeg_buffer);
942 skip(&jpeg_buffer, 1);
945 skip(&jpeg_buffer, components * 2);
948 /* skip payload-less markers */
949 case RST ... RST + 7:
955 /* skip uninteresting payload markers */
957 if (get_word_be(&jpeg_buffer, &word))
959 length = (long)word - 2;
960 skip(&jpeg_buffer, length);
966 result->size = components;
968 switch (subsampling) {
970 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444;
973 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422;
976 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420;
979 ctx->subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY;
988 static int s5p_jpeg_querycap(struct file *file, void *priv,
989 struct v4l2_capability *cap)
991 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
993 if (ctx->mode == S5P_JPEG_ENCODE) {
994 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " encoder",
995 sizeof(cap->driver));
996 strlcpy(cap->card, S5P_JPEG_M2M_NAME " encoder",
999 strlcpy(cap->driver, S5P_JPEG_M2M_NAME " decoder",
1000 sizeof(cap->driver));
1001 strlcpy(cap->card, S5P_JPEG_M2M_NAME " decoder",
1004 cap->bus_info[0] = 0;
1005 cap->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M;
1006 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1010 static int enum_fmt(struct s5p_jpeg_fmt *sjpeg_formats, int n,
1011 struct v4l2_fmtdesc *f, u32 type)
1015 for (i = 0; i < n; ++i) {
1016 if (sjpeg_formats[i].flags & type) {
1017 /* index-th format of type type found ? */
1018 if (num == f->index)
1020 /* Correct type but haven't reached our index yet,
1021 * just increment per-type index */
1026 /* Format not found */
1030 strlcpy(f->description, sjpeg_formats[i].name, sizeof(f->description));
1031 f->pixelformat = sjpeg_formats[i].fourcc;
1036 static int s5p_jpeg_enum_fmt_vid_cap(struct file *file, void *priv,
1037 struct v4l2_fmtdesc *f)
1039 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1041 if (ctx->mode == S5P_JPEG_ENCODE)
1042 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1043 SJPEG_FMT_FLAG_ENC_CAPTURE);
1045 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1046 SJPEG_FMT_FLAG_DEC_CAPTURE);
1049 static int s5p_jpeg_enum_fmt_vid_out(struct file *file, void *priv,
1050 struct v4l2_fmtdesc *f)
1052 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1054 if (ctx->mode == S5P_JPEG_ENCODE)
1055 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1056 SJPEG_FMT_FLAG_ENC_OUTPUT);
1058 return enum_fmt(sjpeg_formats, SJPEG_NUM_FORMATS, f,
1059 SJPEG_FMT_FLAG_DEC_OUTPUT);
1062 static struct s5p_jpeg_q_data *get_q_data(struct s5p_jpeg_ctx *ctx,
1063 enum v4l2_buf_type type)
1065 if (type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1067 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1073 static int s5p_jpeg_g_fmt(struct file *file, void *priv, struct v4l2_format *f)
1075 struct vb2_queue *vq;
1076 struct s5p_jpeg_q_data *q_data = NULL;
1077 struct v4l2_pix_format *pix = &f->fmt.pix;
1078 struct s5p_jpeg_ctx *ct = fh_to_ctx(priv);
1080 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1084 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1085 ct->mode == S5P_JPEG_DECODE && !ct->hdr_parsed)
1087 q_data = get_q_data(ct, f->type);
1088 BUG_ON(q_data == NULL);
1090 pix->width = q_data->w;
1091 pix->height = q_data->h;
1092 pix->field = V4L2_FIELD_NONE;
1093 pix->pixelformat = q_data->fmt->fourcc;
1094 pix->bytesperline = 0;
1095 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
1096 u32 bpl = q_data->w;
1097 if (q_data->fmt->colplanes == 1)
1098 bpl = (bpl * q_data->fmt->depth) >> 3;
1099 pix->bytesperline = bpl;
1101 pix->sizeimage = q_data->size;
1106 static struct s5p_jpeg_fmt *s5p_jpeg_find_format(struct s5p_jpeg_ctx *ctx,
1107 u32 pixelformat, unsigned int fmt_type)
1109 unsigned int k, fmt_flag;
1111 if (ctx->mode == S5P_JPEG_ENCODE)
1112 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
1113 SJPEG_FMT_FLAG_ENC_OUTPUT :
1114 SJPEG_FMT_FLAG_ENC_CAPTURE;
1116 fmt_flag = (fmt_type == FMT_TYPE_OUTPUT) ?
1117 SJPEG_FMT_FLAG_DEC_OUTPUT :
1118 SJPEG_FMT_FLAG_DEC_CAPTURE;
1120 for (k = 0; k < ARRAY_SIZE(sjpeg_formats); k++) {
1121 struct s5p_jpeg_fmt *fmt = &sjpeg_formats[k];
1122 if (fmt->fourcc == pixelformat &&
1123 fmt->flags & fmt_flag &&
1124 fmt->flags & ctx->jpeg->variant->fmt_ver_flag) {
1132 static void jpeg_bound_align_image(struct s5p_jpeg_ctx *ctx,
1133 u32 *w, unsigned int wmin, unsigned int wmax,
1134 unsigned int walign,
1135 u32 *h, unsigned int hmin, unsigned int hmax,
1136 unsigned int halign)
1138 int width, height, w_step, h_step;
1143 w_step = 1 << walign;
1144 h_step = 1 << halign;
1146 if (ctx->jpeg->variant->hw3250_compat) {
1148 * Rightmost and bottommost pixels are cropped by the
1149 * Exynos3250/compatible JPEG IP for RGB formats, for the
1150 * specific width and height values respectively. This
1151 * assignment will result in v4l_bound_align_image returning
1152 * dimensions reduced by 1 for the aforementioned cases.
1154 if (w_step == 4 && ((width & 3) == 1)) {
1160 v4l_bound_align_image(w, wmin, wmax, walign, h, hmin, hmax, halign, 0);
1162 if (*w < width && (*w + w_step) < wmax)
1164 if (*h < height && (*h + h_step) < hmax)
1168 static int vidioc_try_fmt(struct v4l2_format *f, struct s5p_jpeg_fmt *fmt,
1169 struct s5p_jpeg_ctx *ctx, int q_type)
1171 struct v4l2_pix_format *pix = &f->fmt.pix;
1173 if (pix->field == V4L2_FIELD_ANY)
1174 pix->field = V4L2_FIELD_NONE;
1175 else if (pix->field != V4L2_FIELD_NONE)
1178 /* V4L2 specification suggests the driver corrects the format struct
1179 * if any of the dimensions is unsupported */
1180 if (q_type == FMT_TYPE_OUTPUT)
1181 jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
1182 S5P_JPEG_MAX_WIDTH, 0,
1183 &pix->height, S5P_JPEG_MIN_HEIGHT,
1184 S5P_JPEG_MAX_HEIGHT, 0);
1186 jpeg_bound_align_image(ctx, &pix->width, S5P_JPEG_MIN_WIDTH,
1187 S5P_JPEG_MAX_WIDTH, fmt->h_align,
1188 &pix->height, S5P_JPEG_MIN_HEIGHT,
1189 S5P_JPEG_MAX_HEIGHT, fmt->v_align);
1191 if (fmt->fourcc == V4L2_PIX_FMT_JPEG) {
1192 if (pix->sizeimage <= 0)
1193 pix->sizeimage = PAGE_SIZE;
1194 pix->bytesperline = 0;
1196 u32 bpl = pix->bytesperline;
1198 if (fmt->colplanes > 1 && bpl < pix->width)
1199 bpl = pix->width; /* planar */
1201 if (fmt->colplanes == 1 && /* packed */
1202 (bpl << 3) / fmt->depth < pix->width)
1203 bpl = (pix->width * fmt->depth) >> 3;
1205 pix->bytesperline = bpl;
1206 pix->sizeimage = (pix->width * pix->height * fmt->depth) >> 3;
1212 static int s5p_jpeg_try_fmt_vid_cap(struct file *file, void *priv,
1213 struct v4l2_format *f)
1215 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1216 struct v4l2_pix_format *pix = &f->fmt.pix;
1217 struct s5p_jpeg_fmt *fmt;
1220 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1223 v4l2_err(&ctx->jpeg->v4l2_dev,
1224 "Fourcc format (0x%08x) invalid.\n",
1225 f->fmt.pix.pixelformat);
1229 if ((ctx->jpeg->variant->version != SJPEG_EXYNOS4) ||
1230 (ctx->mode != S5P_JPEG_DECODE))
1234 * The exynos4x12 device requires resulting YUV image
1235 * subsampling not to be lower than the input jpeg subsampling.
1236 * If this requirement is not met then downgrade the requested
1237 * capture format to the one with subsampling equal to the input jpeg.
1239 if ((fmt->flags & SJPEG_FMT_NON_RGB) &&
1240 (fmt->subsampling < ctx->subsampling)) {
1241 ret = s5p_jpeg_adjust_fourcc_to_subsampling(ctx->subsampling,
1246 pix->pixelformat = V4L2_PIX_FMT_GREY;
1248 fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1253 * Decompression of a JPEG file with 4:2:0 subsampling and odd
1254 * width to the YUV 4:2:0 compliant formats produces a raw image
1255 * with broken luma component. Adjust capture format to RGB565
1258 if (ctx->subsampling == V4L2_JPEG_CHROMA_SUBSAMPLING_420 &&
1259 (ctx->out_q.w & 1) &&
1260 (pix->pixelformat == V4L2_PIX_FMT_NV12 ||
1261 pix->pixelformat == V4L2_PIX_FMT_NV21 ||
1262 pix->pixelformat == V4L2_PIX_FMT_YUV420)) {
1263 pix->pixelformat = V4L2_PIX_FMT_RGB565;
1264 fmt = s5p_jpeg_find_format(ctx, pix->pixelformat,
1269 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_CAPTURE);
1272 static int s5p_jpeg_try_fmt_vid_out(struct file *file, void *priv,
1273 struct v4l2_format *f)
1275 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1276 struct s5p_jpeg_fmt *fmt;
1278 fmt = s5p_jpeg_find_format(ctx, f->fmt.pix.pixelformat,
1281 v4l2_err(&ctx->jpeg->v4l2_dev,
1282 "Fourcc format (0x%08x) invalid.\n",
1283 f->fmt.pix.pixelformat);
1287 return vidioc_try_fmt(f, fmt, ctx, FMT_TYPE_OUTPUT);
1290 static int exynos4_jpeg_get_output_buffer_size(struct s5p_jpeg_ctx *ctx,
1291 struct v4l2_format *f,
1294 struct v4l2_pix_format *pix = &f->fmt.pix;
1295 u32 pix_fmt = f->fmt.pix.pixelformat;
1296 int w = pix->width, h = pix->height, wh_align;
1298 if (pix_fmt == V4L2_PIX_FMT_RGB32 ||
1299 pix_fmt == V4L2_PIX_FMT_NV24 ||
1300 pix_fmt == V4L2_PIX_FMT_NV42 ||
1301 pix_fmt == V4L2_PIX_FMT_NV12 ||
1302 pix_fmt == V4L2_PIX_FMT_NV21 ||
1303 pix_fmt == V4L2_PIX_FMT_YUV420)
1308 jpeg_bound_align_image(ctx, &w, S5P_JPEG_MIN_WIDTH,
1309 S5P_JPEG_MAX_WIDTH, wh_align,
1310 &h, S5P_JPEG_MIN_HEIGHT,
1311 S5P_JPEG_MAX_HEIGHT, wh_align);
1313 return w * h * fmt_depth >> 3;
1316 static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1317 struct v4l2_rect *r);
1319 static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx *ct, struct v4l2_format *f)
1321 struct vb2_queue *vq;
1322 struct s5p_jpeg_q_data *q_data = NULL;
1323 struct v4l2_pix_format *pix = &f->fmt.pix;
1324 struct v4l2_ctrl *ctrl_subs;
1325 struct v4l2_rect scale_rect;
1326 unsigned int f_type;
1328 vq = v4l2_m2m_get_vq(ct->fh.m2m_ctx, f->type);
1332 q_data = get_q_data(ct, f->type);
1333 BUG_ON(q_data == NULL);
1335 if (vb2_is_busy(vq)) {
1336 v4l2_err(&ct->jpeg->v4l2_dev, "%s queue busy\n", __func__);
1340 f_type = V4L2_TYPE_IS_OUTPUT(f->type) ?
1341 FMT_TYPE_OUTPUT : FMT_TYPE_CAPTURE;
1343 q_data->fmt = s5p_jpeg_find_format(ct, pix->pixelformat, f_type);
1344 q_data->w = pix->width;
1345 q_data->h = pix->height;
1346 if (q_data->fmt->fourcc != V4L2_PIX_FMT_JPEG) {
1348 * During encoding Exynos4x12 SoCs access wider memory area
1349 * than it results from Image_x and Image_y values written to
1350 * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu
1351 * page fault calculate proper buffer size in such a case.
1353 if (ct->jpeg->variant->version == SJPEG_EXYNOS4 &&
1354 f_type == FMT_TYPE_OUTPUT && ct->mode == S5P_JPEG_ENCODE)
1355 q_data->size = exynos4_jpeg_get_output_buffer_size(ct,
1357 q_data->fmt->depth);
1359 q_data->size = q_data->w * q_data->h *
1360 q_data->fmt->depth >> 3;
1362 q_data->size = pix->sizeimage;
1365 if (f_type == FMT_TYPE_OUTPUT) {
1366 ctrl_subs = v4l2_ctrl_find(&ct->ctrl_handler,
1367 V4L2_CID_JPEG_CHROMA_SUBSAMPLING);
1369 v4l2_ctrl_s_ctrl(ctrl_subs, q_data->fmt->subsampling);
1370 ct->crop_altered = false;
1374 * For decoding init crop_rect with capture buffer dimmensions which
1375 * contain aligned dimensions of the input JPEG image and do it only
1376 * if crop rectangle hasn't been altered by the user space e.g. with
1377 * S_SELECTION ioctl. For encoding assign output buffer dimensions.
1379 if (!ct->crop_altered &&
1380 ((ct->mode == S5P_JPEG_DECODE && f_type == FMT_TYPE_CAPTURE) ||
1381 (ct->mode == S5P_JPEG_ENCODE && f_type == FMT_TYPE_OUTPUT))) {
1382 ct->crop_rect.width = pix->width;
1383 ct->crop_rect.height = pix->height;
1387 * Prevent downscaling to YUV420 format by more than 2
1388 * for Exynos3250/compatible SoC as it produces broken raw image
1391 if (ct->mode == S5P_JPEG_DECODE &&
1392 f_type == FMT_TYPE_CAPTURE &&
1393 ct->jpeg->variant->hw3250_compat &&
1394 pix->pixelformat == V4L2_PIX_FMT_YUV420 &&
1395 ct->scale_factor > 2) {
1396 scale_rect.width = ct->out_q.w / 2;
1397 scale_rect.height = ct->out_q.h / 2;
1398 exynos3250_jpeg_try_downscale(ct, &scale_rect);
1404 static int s5p_jpeg_s_fmt_vid_cap(struct file *file, void *priv,
1405 struct v4l2_format *f)
1409 ret = s5p_jpeg_try_fmt_vid_cap(file, priv, f);
1413 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1416 static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv,
1417 struct v4l2_format *f)
1421 ret = s5p_jpeg_try_fmt_vid_out(file, priv, f);
1425 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f);
1428 static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx,
1429 struct v4l2_rect *r)
1431 int w_ratio, h_ratio, scale_factor, cur_ratio, i;
1433 w_ratio = ctx->out_q.w / r->width;
1434 h_ratio = ctx->out_q.h / r->height;
1436 scale_factor = w_ratio > h_ratio ? w_ratio : h_ratio;
1437 scale_factor = clamp_val(scale_factor, 1, 8);
1439 /* Align scale ratio to the nearest power of 2 */
1440 for (i = 0; i <= 3; ++i) {
1442 if (scale_factor <= cur_ratio) {
1443 ctx->scale_factor = cur_ratio;
1448 r->width = round_down(ctx->out_q.w / ctx->scale_factor, 2);
1449 r->height = round_down(ctx->out_q.h / ctx->scale_factor, 2);
1451 ctx->crop_rect.width = r->width;
1452 ctx->crop_rect.height = r->height;
1453 ctx->crop_rect.left = 0;
1454 ctx->crop_rect.top = 0;
1456 ctx->crop_altered = true;
1461 /* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
1462 static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b)
1464 if (a->left < b->left || a->top < b->top)
1466 if (a->left + a->width > b->left + b->width)
1468 if (a->top + a->height > b->top + b->height)
1474 static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx,
1475 struct v4l2_rect *r)
1477 struct v4l2_rect base_rect;
1480 switch (ctx->cap_q.fmt->fourcc) {
1481 case V4L2_PIX_FMT_NV12:
1482 case V4L2_PIX_FMT_NV21:
1486 case V4L2_PIX_FMT_YUV420:
1498 base_rect.width = ctx->out_q.w;
1499 base_rect.height = ctx->out_q.h;
1501 r->width = round_down(r->width, w_step);
1502 r->height = round_down(r->height, h_step);
1503 r->left = round_down(r->left, 2);
1504 r->top = round_down(r->top, 2);
1506 if (!enclosed_rectangle(r, &base_rect))
1509 ctx->crop_rect.left = r->left;
1510 ctx->crop_rect.top = r->top;
1511 ctx->crop_rect.width = r->width;
1512 ctx->crop_rect.height = r->height;
1514 ctx->crop_altered = true;
1523 static int s5p_jpeg_g_selection(struct file *file, void *priv,
1524 struct v4l2_selection *s)
1526 struct s5p_jpeg_ctx *ctx = fh_to_ctx(priv);
1528 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT &&
1529 s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1532 /* For JPEG blob active == default == bounds */
1533 switch (s->target) {
1534 case V4L2_SEL_TGT_CROP:
1535 case V4L2_SEL_TGT_CROP_BOUNDS:
1536 case V4L2_SEL_TGT_CROP_DEFAULT:
1537 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1538 s->r.width = ctx->out_q.w;
1539 s->r.height = ctx->out_q.h;
1543 case V4L2_SEL_TGT_COMPOSE:
1544 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1545 case V4L2_SEL_TGT_COMPOSE_PADDED:
1546 s->r.width = ctx->crop_rect.width;
1547 s->r.height = ctx->crop_rect.height;
1548 s->r.left = ctx->crop_rect.left;
1549 s->r.top = ctx->crop_rect.top;
1560 static int s5p_jpeg_s_selection(struct file *file, void *fh,
1561 struct v4l2_selection *s)
1563 struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data);
1564 struct v4l2_rect *rect = &s->r;
1567 if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1570 if (s->target == V4L2_SEL_TGT_COMPOSE) {
1571 if (ctx->mode != S5P_JPEG_DECODE)
1573 if (ctx->jpeg->variant->hw3250_compat)
1574 ret = exynos3250_jpeg_try_downscale(ctx, rect);
1575 } else if (s->target == V4L2_SEL_TGT_CROP) {
1576 if (ctx->mode != S5P_JPEG_ENCODE)
1578 if (ctx->jpeg->variant->hw3250_compat)
1579 ret = exynos3250_jpeg_try_crop(ctx, rect);
1585 static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
1587 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1588 struct s5p_jpeg *jpeg = ctx->jpeg;
1589 unsigned long flags;
1592 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1593 spin_lock_irqsave(&jpeg->slock, flags);
1594 ctrl->val = s5p_jpeg_to_user_subsampling(ctx);
1595 spin_unlock_irqrestore(&jpeg->slock, flags);
1602 static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx *ctx, int *ctrl_val)
1604 switch (ctx->jpeg->variant->version) {
1607 case SJPEG_EXYNOS3250:
1608 case SJPEG_EXYNOS5420:
1610 * The exynos3250/compatible device can produce JPEG image only
1611 * of 4:4:4 subsampling when given RGB32 source image.
1613 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
1618 * The exynos4x12 device requires input raw image fourcc
1619 * to be V4L2_PIX_FMT_GREY if gray jpeg format
1622 if (ctx->out_q.fmt->fourcc != V4L2_PIX_FMT_GREY &&
1623 *ctrl_val == V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY)
1629 * The exynos4x12 and exynos3250/compatible devices require resulting
1630 * jpeg subsampling not to be lower than the input raw image
1633 if (ctx->out_q.fmt->subsampling > *ctrl_val)
1634 *ctrl_val = ctx->out_q.fmt->subsampling;
1639 static int s5p_jpeg_try_ctrl(struct v4l2_ctrl *ctrl)
1641 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1642 unsigned long flags;
1645 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1647 if (ctrl->id == V4L2_CID_JPEG_CHROMA_SUBSAMPLING)
1648 ret = s5p_jpeg_adjust_subs_ctrl(ctx, &ctrl->val);
1650 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1654 static int s5p_jpeg_s_ctrl(struct v4l2_ctrl *ctrl)
1656 struct s5p_jpeg_ctx *ctx = ctrl_to_ctx(ctrl);
1657 unsigned long flags;
1659 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1662 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
1663 ctx->compr_quality = ctrl->val;
1665 case V4L2_CID_JPEG_RESTART_INTERVAL:
1666 ctx->restart_interval = ctrl->val;
1668 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING:
1669 ctx->subsampling = ctrl->val;
1673 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1677 static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops = {
1678 .g_volatile_ctrl = s5p_jpeg_g_volatile_ctrl,
1679 .try_ctrl = s5p_jpeg_try_ctrl,
1680 .s_ctrl = s5p_jpeg_s_ctrl,
1683 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx *ctx)
1685 unsigned int mask = ~0x27; /* 444, 422, 420, GRAY */
1686 struct v4l2_ctrl *ctrl;
1689 v4l2_ctrl_handler_init(&ctx->ctrl_handler, 3);
1691 if (ctx->mode == S5P_JPEG_ENCODE) {
1692 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1693 V4L2_CID_JPEG_COMPRESSION_QUALITY,
1694 0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST);
1696 v4l2_ctrl_new_std(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1697 V4L2_CID_JPEG_RESTART_INTERVAL,
1699 if (ctx->jpeg->variant->version == SJPEG_S5P)
1700 mask = ~0x06; /* 422, 420 */
1703 ctrl = v4l2_ctrl_new_std_menu(&ctx->ctrl_handler, &s5p_jpeg_ctrl_ops,
1704 V4L2_CID_JPEG_CHROMA_SUBSAMPLING,
1705 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, mask,
1706 V4L2_JPEG_CHROMA_SUBSAMPLING_422);
1708 if (ctx->ctrl_handler.error) {
1709 ret = ctx->ctrl_handler.error;
1713 if (ctx->mode == S5P_JPEG_DECODE)
1714 ctrl->flags |= V4L2_CTRL_FLAG_VOLATILE |
1715 V4L2_CTRL_FLAG_READ_ONLY;
1717 ret = v4l2_ctrl_handler_setup(&ctx->ctrl_handler);
1724 v4l2_ctrl_handler_free(&ctx->ctrl_handler);
1728 static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
1729 .vidioc_querycap = s5p_jpeg_querycap,
1731 .vidioc_enum_fmt_vid_cap = s5p_jpeg_enum_fmt_vid_cap,
1732 .vidioc_enum_fmt_vid_out = s5p_jpeg_enum_fmt_vid_out,
1734 .vidioc_g_fmt_vid_cap = s5p_jpeg_g_fmt,
1735 .vidioc_g_fmt_vid_out = s5p_jpeg_g_fmt,
1737 .vidioc_try_fmt_vid_cap = s5p_jpeg_try_fmt_vid_cap,
1738 .vidioc_try_fmt_vid_out = s5p_jpeg_try_fmt_vid_out,
1740 .vidioc_s_fmt_vid_cap = s5p_jpeg_s_fmt_vid_cap,
1741 .vidioc_s_fmt_vid_out = s5p_jpeg_s_fmt_vid_out,
1743 .vidioc_reqbufs = v4l2_m2m_ioctl_reqbufs,
1744 .vidioc_querybuf = v4l2_m2m_ioctl_querybuf,
1745 .vidioc_qbuf = v4l2_m2m_ioctl_qbuf,
1746 .vidioc_dqbuf = v4l2_m2m_ioctl_dqbuf,
1748 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
1749 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
1751 .vidioc_g_selection = s5p_jpeg_g_selection,
1752 .vidioc_s_selection = s5p_jpeg_s_selection,
1756 * ============================================================================
1758 * ============================================================================
1761 static void s5p_jpeg_device_run(void *priv)
1763 struct s5p_jpeg_ctx *ctx = priv;
1764 struct s5p_jpeg *jpeg = ctx->jpeg;
1765 struct vb2_buffer *src_buf, *dst_buf;
1766 unsigned long src_addr, dst_addr, flags;
1768 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1770 src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1771 dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1772 src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
1773 dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
1775 s5p_jpeg_reset(jpeg->regs);
1776 s5p_jpeg_poweron(jpeg->regs);
1777 s5p_jpeg_proc_mode(jpeg->regs, ctx->mode);
1778 if (ctx->mode == S5P_JPEG_ENCODE) {
1779 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
1780 s5p_jpeg_input_raw_mode(jpeg->regs,
1781 S5P_JPEG_RAW_IN_565);
1783 s5p_jpeg_input_raw_mode(jpeg->regs,
1784 S5P_JPEG_RAW_IN_422);
1785 s5p_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
1786 s5p_jpeg_dri(jpeg->regs, ctx->restart_interval);
1787 s5p_jpeg_x(jpeg->regs, ctx->out_q.w);
1788 s5p_jpeg_y(jpeg->regs, ctx->out_q.h);
1789 s5p_jpeg_imgadr(jpeg->regs, src_addr);
1790 s5p_jpeg_jpgadr(jpeg->regs, dst_addr);
1792 /* ultimately comes from sizeimage from userspace */
1793 s5p_jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
1795 /* JPEG RGB to YCbCr conversion matrix */
1796 s5p_jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
1797 s5p_jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
1798 s5p_jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
1799 s5p_jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
1800 s5p_jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
1801 s5p_jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
1802 s5p_jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
1803 s5p_jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
1804 s5p_jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
1807 * JPEG IP allows storing 4 quantization tables
1808 * We fill table 0 for luma and table 1 for chroma
1810 s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1811 s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1812 /* use table 0 for Y */
1813 s5p_jpeg_qtbl(jpeg->regs, 1, 0);
1814 /* use table 1 for Cb and Cr*/
1815 s5p_jpeg_qtbl(jpeg->regs, 2, 1);
1816 s5p_jpeg_qtbl(jpeg->regs, 3, 1);
1818 /* Y, Cb, Cr use Huffman table 0 */
1819 s5p_jpeg_htbl_ac(jpeg->regs, 1);
1820 s5p_jpeg_htbl_dc(jpeg->regs, 1);
1821 s5p_jpeg_htbl_ac(jpeg->regs, 2);
1822 s5p_jpeg_htbl_dc(jpeg->regs, 2);
1823 s5p_jpeg_htbl_ac(jpeg->regs, 3);
1824 s5p_jpeg_htbl_dc(jpeg->regs, 3);
1825 } else { /* S5P_JPEG_DECODE */
1826 s5p_jpeg_rst_int_enable(jpeg->regs, true);
1827 s5p_jpeg_data_num_int_enable(jpeg->regs, true);
1828 s5p_jpeg_final_mcu_num_int_enable(jpeg->regs, true);
1829 if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
1830 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
1832 s5p_jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
1833 s5p_jpeg_jpgadr(jpeg->regs, src_addr);
1834 s5p_jpeg_imgadr(jpeg->regs, dst_addr);
1837 s5p_jpeg_start(jpeg->regs);
1839 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1842 static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
1844 struct s5p_jpeg *jpeg = ctx->jpeg;
1845 struct s5p_jpeg_fmt *fmt;
1846 struct vb2_buffer *vb;
1847 struct s5p_jpeg_addr jpeg_addr;
1848 u32 pix_size, padding_bytes = 0;
1850 pix_size = ctx->cap_q.w * ctx->cap_q.h;
1852 if (ctx->mode == S5P_JPEG_ENCODE) {
1853 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1854 fmt = ctx->out_q.fmt;
1855 if (ctx->out_q.w % 2 && fmt->h_align > 0)
1856 padding_bytes = ctx->out_q.h;
1858 fmt = ctx->cap_q.fmt;
1859 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1862 jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
1864 if (fmt->colplanes == 2) {
1865 jpeg_addr.cb = jpeg_addr.y + pix_size - padding_bytes;
1866 } else if (fmt->colplanes == 3) {
1867 jpeg_addr.cb = jpeg_addr.y + pix_size;
1868 if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
1869 jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
1871 jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
1874 exynos4_jpeg_set_frame_buf_address(jpeg->regs, &jpeg_addr);
1877 static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
1879 struct s5p_jpeg *jpeg = ctx->jpeg;
1880 struct vb2_buffer *vb;
1881 unsigned int jpeg_addr = 0;
1883 if (ctx->mode == S5P_JPEG_ENCODE)
1884 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1886 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1888 jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1889 exynos4_jpeg_set_stream_buf_address(jpeg->regs, jpeg_addr);
1892 static void exynos4_jpeg_device_run(void *priv)
1894 struct s5p_jpeg_ctx *ctx = priv;
1895 struct s5p_jpeg *jpeg = ctx->jpeg;
1896 unsigned int bitstream_size;
1897 unsigned long flags;
1899 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1901 if (ctx->mode == S5P_JPEG_ENCODE) {
1902 exynos4_jpeg_sw_reset(jpeg->regs);
1903 exynos4_jpeg_set_interrupt(jpeg->regs);
1904 exynos4_jpeg_set_huf_table_enable(jpeg->regs, 1);
1906 exynos4_jpeg_set_huff_tbl(jpeg->regs);
1909 * JPEG IP allows storing 4 quantization tables
1910 * We fill table 0 for luma and table 1 for chroma
1912 exynos4_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
1913 exynos4_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
1915 exynos4_jpeg_set_encode_tbl_select(jpeg->regs,
1916 ctx->compr_quality);
1917 exynos4_jpeg_set_stream_size(jpeg->regs, ctx->cap_q.w,
1920 exynos4_jpeg_set_enc_out_fmt(jpeg->regs, ctx->subsampling);
1921 exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->out_q.fmt->fourcc);
1922 exynos4_jpeg_set_img_addr(ctx);
1923 exynos4_jpeg_set_jpeg_addr(ctx);
1924 exynos4_jpeg_set_encode_hoff_cnt(jpeg->regs,
1925 ctx->out_q.fmt->fourcc);
1927 exynos4_jpeg_sw_reset(jpeg->regs);
1928 exynos4_jpeg_set_interrupt(jpeg->regs);
1929 exynos4_jpeg_set_img_addr(ctx);
1930 exynos4_jpeg_set_jpeg_addr(ctx);
1931 exynos4_jpeg_set_img_fmt(jpeg->regs, ctx->cap_q.fmt->fourcc);
1933 bitstream_size = DIV_ROUND_UP(ctx->out_q.size, 32);
1935 exynos4_jpeg_set_dec_bitstream_size(jpeg->regs, bitstream_size);
1938 exynos4_jpeg_set_enc_dec_mode(jpeg->regs, ctx->mode);
1940 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
1943 static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx)
1945 struct s5p_jpeg *jpeg = ctx->jpeg;
1946 struct s5p_jpeg_fmt *fmt;
1947 struct vb2_buffer *vb;
1948 struct s5p_jpeg_addr jpeg_addr;
1951 pix_size = ctx->cap_q.w * ctx->cap_q.h;
1953 if (ctx->mode == S5P_JPEG_ENCODE) {
1954 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1955 fmt = ctx->out_q.fmt;
1957 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1958 fmt = ctx->cap_q.fmt;
1961 jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0);
1963 if (fmt->colplanes == 2) {
1964 jpeg_addr.cb = jpeg_addr.y + pix_size;
1965 } else if (fmt->colplanes == 3) {
1966 jpeg_addr.cb = jpeg_addr.y + pix_size;
1967 if (fmt->fourcc == V4L2_PIX_FMT_YUV420)
1968 jpeg_addr.cr = jpeg_addr.cb + pix_size / 4;
1970 jpeg_addr.cr = jpeg_addr.cb + pix_size / 2;
1973 exynos3250_jpeg_imgadr(jpeg->regs, &jpeg_addr);
1976 static void exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx)
1978 struct s5p_jpeg *jpeg = ctx->jpeg;
1979 struct vb2_buffer *vb;
1980 unsigned int jpeg_addr = 0;
1982 if (ctx->mode == S5P_JPEG_ENCODE)
1983 vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx);
1985 vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
1987 jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
1988 exynos3250_jpeg_jpgadr(jpeg->regs, jpeg_addr);
1991 static void exynos3250_jpeg_device_run(void *priv)
1993 struct s5p_jpeg_ctx *ctx = priv;
1994 struct s5p_jpeg *jpeg = ctx->jpeg;
1995 unsigned long flags;
1997 spin_lock_irqsave(&ctx->jpeg->slock, flags);
1999 exynos3250_jpeg_reset(jpeg->regs);
2000 exynos3250_jpeg_set_dma_num(jpeg->regs);
2001 exynos3250_jpeg_poweron(jpeg->regs);
2002 exynos3250_jpeg_clk_set(jpeg->regs);
2003 exynos3250_jpeg_proc_mode(jpeg->regs, ctx->mode);
2005 if (ctx->mode == S5P_JPEG_ENCODE) {
2006 exynos3250_jpeg_input_raw_fmt(jpeg->regs,
2007 ctx->out_q.fmt->fourcc);
2008 exynos3250_jpeg_dri(jpeg->regs, ctx->restart_interval);
2011 * JPEG IP allows storing 4 quantization tables
2012 * We fill table 0 for luma and table 1 for chroma
2014 s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
2015 s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
2016 /* use table 0 for Y */
2017 exynos3250_jpeg_qtbl(jpeg->regs, 1, 0);
2018 /* use table 1 for Cb and Cr*/
2019 exynos3250_jpeg_qtbl(jpeg->regs, 2, 1);
2020 exynos3250_jpeg_qtbl(jpeg->regs, 3, 1);
2023 * Some SoCs require setting Huffman tables before each run
2025 if (jpeg->variant->htbl_reinit) {
2026 s5p_jpeg_set_hdctbl(jpeg->regs);
2027 s5p_jpeg_set_hdctblg(jpeg->regs);
2028 s5p_jpeg_set_hactbl(jpeg->regs);
2029 s5p_jpeg_set_hactblg(jpeg->regs);
2032 /* Y, Cb, Cr use Huffman table 0 */
2033 exynos3250_jpeg_htbl_ac(jpeg->regs, 1);
2034 exynos3250_jpeg_htbl_dc(jpeg->regs, 1);
2035 exynos3250_jpeg_htbl_ac(jpeg->regs, 2);
2036 exynos3250_jpeg_htbl_dc(jpeg->regs, 2);
2037 exynos3250_jpeg_htbl_ac(jpeg->regs, 3);
2038 exynos3250_jpeg_htbl_dc(jpeg->regs, 3);
2040 exynos3250_jpeg_set_x(jpeg->regs, ctx->crop_rect.width);
2041 exynos3250_jpeg_set_y(jpeg->regs, ctx->crop_rect.height);
2042 exynos3250_jpeg_stride(jpeg->regs, ctx->out_q.fmt->fourcc,
2044 exynos3250_jpeg_offset(jpeg->regs, ctx->crop_rect.left,
2045 ctx->crop_rect.top);
2046 exynos3250_jpeg_set_img_addr(ctx);
2047 exynos3250_jpeg_set_jpeg_addr(ctx);
2048 exynos3250_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling);
2050 /* ultimately comes from sizeimage from userspace */
2051 exynos3250_jpeg_enc_stream_bound(jpeg->regs, ctx->cap_q.size);
2053 if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565 ||
2054 ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565X ||
2055 ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32)
2056 exynos3250_jpeg_set_y16(jpeg->regs, true);
2058 exynos3250_jpeg_set_img_addr(ctx);
2059 exynos3250_jpeg_set_jpeg_addr(ctx);
2060 exynos3250_jpeg_stride(jpeg->regs, ctx->cap_q.fmt->fourcc,
2062 exynos3250_jpeg_offset(jpeg->regs, 0, 0);
2063 exynos3250_jpeg_dec_scaling_ratio(jpeg->regs,
2065 exynos3250_jpeg_dec_stream_size(jpeg->regs, ctx->out_q.size);
2066 exynos3250_jpeg_output_raw_fmt(jpeg->regs,
2067 ctx->cap_q.fmt->fourcc);
2070 exynos3250_jpeg_interrupts_enable(jpeg->regs);
2072 /* JPEG RGB to YCbCr conversion matrix */
2073 exynos3250_jpeg_coef(jpeg->regs, ctx->mode);
2075 exynos3250_jpeg_set_timer(jpeg->regs, EXYNOS3250_IRQ_TIMEOUT);
2076 jpeg->irq_status = 0;
2077 exynos3250_jpeg_start(jpeg->regs);
2079 spin_unlock_irqrestore(&ctx->jpeg->slock, flags);
2082 static int s5p_jpeg_job_ready(void *priv)
2084 struct s5p_jpeg_ctx *ctx = priv;
2086 if (ctx->mode == S5P_JPEG_DECODE)
2087 return ctx->hdr_parsed;
2091 static void s5p_jpeg_job_abort(void *priv)
2095 static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = {
2096 .device_run = s5p_jpeg_device_run,
2097 .job_ready = s5p_jpeg_job_ready,
2098 .job_abort = s5p_jpeg_job_abort,
2101 static struct v4l2_m2m_ops exynos3250_jpeg_m2m_ops = {
2102 .device_run = exynos3250_jpeg_device_run,
2103 .job_ready = s5p_jpeg_job_ready,
2104 .job_abort = s5p_jpeg_job_abort,
2107 static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = {
2108 .device_run = exynos4_jpeg_device_run,
2109 .job_ready = s5p_jpeg_job_ready,
2110 .job_abort = s5p_jpeg_job_abort,
2114 * ============================================================================
2116 * ============================================================================
2119 static int s5p_jpeg_queue_setup(struct vb2_queue *vq,
2120 const struct v4l2_format *fmt,
2121 unsigned int *nbuffers, unsigned int *nplanes,
2122 unsigned int sizes[], void *alloc_ctxs[])
2124 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vq);
2125 struct s5p_jpeg_q_data *q_data = NULL;
2126 unsigned int size, count = *nbuffers;
2128 q_data = get_q_data(ctx, vq->type);
2129 BUG_ON(q_data == NULL);
2131 size = q_data->size;
2134 * header is parsed during decoding and parsed information stored
2135 * in the context so we do not allow another buffer to overwrite it
2137 if (ctx->mode == S5P_JPEG_DECODE)
2143 alloc_ctxs[0] = ctx->jpeg->alloc_ctx;
2148 static int s5p_jpeg_buf_prepare(struct vb2_buffer *vb)
2150 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2151 struct s5p_jpeg_q_data *q_data = NULL;
2153 q_data = get_q_data(ctx, vb->vb2_queue->type);
2154 BUG_ON(q_data == NULL);
2156 if (vb2_plane_size(vb, 0) < q_data->size) {
2157 pr_err("%s data will not fit into plane (%lu < %lu)\n",
2158 __func__, vb2_plane_size(vb, 0),
2159 (long)q_data->size);
2163 vb2_set_plane_payload(vb, 0, q_data->size);
2168 static void s5p_jpeg_buf_queue(struct vb2_buffer *vb)
2170 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
2172 if (ctx->mode == S5P_JPEG_DECODE &&
2173 vb->vb2_queue->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
2174 struct s5p_jpeg_q_data tmp, *q_data;
2175 ctx->hdr_parsed = s5p_jpeg_parse_hdr(&tmp,
2176 (unsigned long)vb2_plane_vaddr(vb, 0),
2177 min((unsigned long)ctx->out_q.size,
2178 vb2_get_plane_payload(vb, 0)), ctx);
2179 if (!ctx->hdr_parsed) {
2180 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
2184 q_data = &ctx->out_q;
2188 q_data = &ctx->cap_q;
2193 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vb);
2196 static int s5p_jpeg_start_streaming(struct vb2_queue *q, unsigned int count)
2198 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
2201 ret = pm_runtime_get_sync(ctx->jpeg->dev);
2203 return ret > 0 ? 0 : ret;
2206 static void s5p_jpeg_stop_streaming(struct vb2_queue *q)
2208 struct s5p_jpeg_ctx *ctx = vb2_get_drv_priv(q);
2210 pm_runtime_put(ctx->jpeg->dev);
2213 static struct vb2_ops s5p_jpeg_qops = {
2214 .queue_setup = s5p_jpeg_queue_setup,
2215 .buf_prepare = s5p_jpeg_buf_prepare,
2216 .buf_queue = s5p_jpeg_buf_queue,
2217 .wait_prepare = vb2_ops_wait_prepare,
2218 .wait_finish = vb2_ops_wait_finish,
2219 .start_streaming = s5p_jpeg_start_streaming,
2220 .stop_streaming = s5p_jpeg_stop_streaming,
2223 static int queue_init(void *priv, struct vb2_queue *src_vq,
2224 struct vb2_queue *dst_vq)
2226 struct s5p_jpeg_ctx *ctx = priv;
2229 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2230 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
2231 src_vq->drv_priv = ctx;
2232 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2233 src_vq->ops = &s5p_jpeg_qops;
2234 src_vq->mem_ops = &vb2_dma_contig_memops;
2235 src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2236 src_vq->lock = &ctx->jpeg->lock;
2238 ret = vb2_queue_init(src_vq);
2242 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2243 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
2244 dst_vq->drv_priv = ctx;
2245 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
2246 dst_vq->ops = &s5p_jpeg_qops;
2247 dst_vq->mem_ops = &vb2_dma_contig_memops;
2248 dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
2249 dst_vq->lock = &ctx->jpeg->lock;
2251 return vb2_queue_init(dst_vq);
2255 * ============================================================================
2257 * ============================================================================
2260 static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
2262 struct s5p_jpeg *jpeg = dev_id;
2263 struct s5p_jpeg_ctx *curr_ctx;
2264 struct vb2_buffer *src_buf, *dst_buf;
2265 unsigned long payload_size = 0;
2266 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
2267 bool enc_jpeg_too_large = false;
2268 bool timer_elapsed = false;
2269 bool op_completed = false;
2271 spin_lock(&jpeg->slock);
2273 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2275 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2276 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2278 if (curr_ctx->mode == S5P_JPEG_ENCODE)
2279 enc_jpeg_too_large = s5p_jpeg_enc_stream_stat(jpeg->regs);
2280 timer_elapsed = s5p_jpeg_timer_stat(jpeg->regs);
2281 op_completed = s5p_jpeg_result_stat_ok(jpeg->regs);
2282 if (curr_ctx->mode == S5P_JPEG_DECODE)
2283 op_completed = op_completed &&
2284 s5p_jpeg_stream_stat_ok(jpeg->regs);
2286 if (enc_jpeg_too_large) {
2287 state = VB2_BUF_STATE_ERROR;
2288 s5p_jpeg_clear_enc_stream_stat(jpeg->regs);
2289 } else if (timer_elapsed) {
2290 state = VB2_BUF_STATE_ERROR;
2291 s5p_jpeg_clear_timer_stat(jpeg->regs);
2292 } else if (!op_completed) {
2293 state = VB2_BUF_STATE_ERROR;
2295 payload_size = s5p_jpeg_compressed_size(jpeg->regs);
2298 dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
2299 dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
2300 dst_buf->v4l2_buf.flags &= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
2301 dst_buf->v4l2_buf.flags |=
2302 src_buf->v4l2_buf.flags & V4L2_BUF_FLAG_TSTAMP_SRC_MASK;
2304 v4l2_m2m_buf_done(src_buf, state);
2305 if (curr_ctx->mode == S5P_JPEG_ENCODE)
2306 vb2_set_plane_payload(dst_buf, 0, payload_size);
2307 v4l2_m2m_buf_done(dst_buf, state);
2308 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2310 curr_ctx->subsampling = s5p_jpeg_get_subsampling_mode(jpeg->regs);
2311 spin_unlock(&jpeg->slock);
2313 s5p_jpeg_clear_int(jpeg->regs);
2318 static irqreturn_t exynos4_jpeg_irq(int irq, void *priv)
2320 unsigned int int_status;
2321 struct vb2_buffer *src_vb, *dst_vb;
2322 struct s5p_jpeg *jpeg = priv;
2323 struct s5p_jpeg_ctx *curr_ctx;
2324 unsigned long payload_size = 0;
2326 spin_lock(&jpeg->slock);
2328 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2330 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2331 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2333 int_status = exynos4_jpeg_get_int_status(jpeg->regs);
2336 switch (int_status & 0x1f) {
2338 jpeg->irq_ret = ERR_PROT;
2341 jpeg->irq_ret = OK_ENC_OR_DEC;
2344 jpeg->irq_ret = ERR_DEC_INVALID_FORMAT;
2347 jpeg->irq_ret = ERR_MULTI_SCAN;
2350 jpeg->irq_ret = ERR_FRAME;
2353 jpeg->irq_ret = ERR_UNKNOWN;
2357 jpeg->irq_ret = ERR_UNKNOWN;
2360 if (jpeg->irq_ret == OK_ENC_OR_DEC) {
2361 if (curr_ctx->mode == S5P_JPEG_ENCODE) {
2362 payload_size = exynos4_jpeg_get_stream_size(jpeg->regs);
2363 vb2_set_plane_payload(dst_vb, 0, payload_size);
2365 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
2366 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
2368 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_ERROR);
2369 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_ERROR);
2372 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2373 curr_ctx->subsampling = exynos4_jpeg_get_frame_fmt(jpeg->regs);
2375 spin_unlock(&jpeg->slock);
2379 static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id)
2381 struct s5p_jpeg *jpeg = dev_id;
2382 struct s5p_jpeg_ctx *curr_ctx;
2383 struct vb2_buffer *src_buf, *dst_buf;
2384 unsigned long payload_size = 0;
2385 enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
2386 bool interrupt_timeout = false;
2389 spin_lock(&jpeg->slock);
2391 irq_status = exynos3250_jpeg_get_timer_status(jpeg->regs);
2392 if (irq_status & EXYNOS3250_TIMER_INT_STAT) {
2393 exynos3250_jpeg_clear_timer_status(jpeg->regs);
2394 interrupt_timeout = true;
2395 dev_err(jpeg->dev, "Interrupt timeout occurred.\n");
2398 irq_status = exynos3250_jpeg_get_int_status(jpeg->regs);
2399 exynos3250_jpeg_clear_int_status(jpeg->regs, irq_status);
2401 jpeg->irq_status |= irq_status;
2403 curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
2408 if ((irq_status & EXYNOS3250_HEADER_STAT) &&
2409 (curr_ctx->mode == S5P_JPEG_DECODE)) {
2410 exynos3250_jpeg_rstart(jpeg->regs);
2414 if (jpeg->irq_status & (EXYNOS3250_JPEG_DONE |
2415 EXYNOS3250_WDMA_DONE |
2416 EXYNOS3250_RDMA_DONE |
2417 EXYNOS3250_RESULT_STAT))
2418 payload_size = exynos3250_jpeg_compressed_size(jpeg->regs);
2419 else if (interrupt_timeout)
2420 state = VB2_BUF_STATE_ERROR;
2424 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx);
2425 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx);
2427 dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode;
2428 dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp;
2430 v4l2_m2m_buf_done(src_buf, state);
2431 if (curr_ctx->mode == S5P_JPEG_ENCODE)
2432 vb2_set_plane_payload(dst_buf, 0, payload_size);
2433 v4l2_m2m_buf_done(dst_buf, state);
2434 v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx);
2436 curr_ctx->subsampling =
2437 exynos3250_jpeg_get_subsampling_mode(jpeg->regs);
2439 spin_unlock(&jpeg->slock);
2443 static void *jpeg_get_drv_data(struct device *dev);
2446 * ============================================================================
2447 * Driver basic infrastructure
2448 * ============================================================================
2451 static int s5p_jpeg_probe(struct platform_device *pdev)
2453 struct s5p_jpeg *jpeg;
2454 struct resource *res;
2457 /* JPEG IP abstraction struct */
2458 jpeg = devm_kzalloc(&pdev->dev, sizeof(struct s5p_jpeg), GFP_KERNEL);
2462 jpeg->variant = jpeg_get_drv_data(&pdev->dev);
2464 mutex_init(&jpeg->lock);
2465 spin_lock_init(&jpeg->slock);
2466 jpeg->dev = &pdev->dev;
2468 /* memory-mapped registers */
2469 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2471 jpeg->regs = devm_ioremap_resource(&pdev->dev, res);
2472 if (IS_ERR(jpeg->regs))
2473 return PTR_ERR(jpeg->regs);
2475 /* interrupt service routine registration */
2476 jpeg->irq = ret = platform_get_irq(pdev, 0);
2478 dev_err(&pdev->dev, "cannot find IRQ\n");
2482 ret = devm_request_irq(&pdev->dev, jpeg->irq, jpeg->variant->jpeg_irq,
2483 0, dev_name(&pdev->dev), jpeg);
2485 dev_err(&pdev->dev, "cannot claim IRQ %d\n", jpeg->irq);
2490 jpeg->clk = clk_get(&pdev->dev, "jpeg");
2491 if (IS_ERR(jpeg->clk)) {
2492 dev_err(&pdev->dev, "cannot get clock\n");
2493 ret = PTR_ERR(jpeg->clk);
2496 dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk);
2498 jpeg->sclk = clk_get(&pdev->dev, "sclk");
2499 if (IS_ERR(jpeg->sclk))
2500 dev_info(&pdev->dev, "sclk clock not available\n");
2503 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev);
2505 dev_err(&pdev->dev, "Failed to register v4l2 device\n");
2506 goto clk_get_rollback;
2509 /* mem2mem device */
2510 jpeg->m2m_dev = v4l2_m2m_init(jpeg->variant->m2m_ops);
2511 if (IS_ERR(jpeg->m2m_dev)) {
2512 v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n");
2513 ret = PTR_ERR(jpeg->m2m_dev);
2514 goto device_register_rollback;
2517 jpeg->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
2518 if (IS_ERR(jpeg->alloc_ctx)) {
2519 v4l2_err(&jpeg->v4l2_dev, "Failed to init memory allocator\n");
2520 ret = PTR_ERR(jpeg->alloc_ctx);
2521 goto m2m_init_rollback;
2524 /* JPEG encoder /dev/videoX node */
2525 jpeg->vfd_encoder = video_device_alloc();
2526 if (!jpeg->vfd_encoder) {
2527 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
2529 goto vb2_allocator_rollback;
2531 snprintf(jpeg->vfd_encoder->name, sizeof(jpeg->vfd_encoder->name),
2532 "%s-enc", S5P_JPEG_M2M_NAME);
2533 jpeg->vfd_encoder->fops = &s5p_jpeg_fops;
2534 jpeg->vfd_encoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
2535 jpeg->vfd_encoder->minor = -1;
2536 jpeg->vfd_encoder->release = video_device_release;
2537 jpeg->vfd_encoder->lock = &jpeg->lock;
2538 jpeg->vfd_encoder->v4l2_dev = &jpeg->v4l2_dev;
2539 jpeg->vfd_encoder->vfl_dir = VFL_DIR_M2M;
2541 ret = video_register_device(jpeg->vfd_encoder, VFL_TYPE_GRABBER, -1);
2543 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
2544 goto enc_vdev_alloc_rollback;
2547 video_set_drvdata(jpeg->vfd_encoder, jpeg);
2548 v4l2_info(&jpeg->v4l2_dev,
2549 "encoder device registered as /dev/video%d\n",
2550 jpeg->vfd_encoder->num);
2552 /* JPEG decoder /dev/videoX node */
2553 jpeg->vfd_decoder = video_device_alloc();
2554 if (!jpeg->vfd_decoder) {
2555 v4l2_err(&jpeg->v4l2_dev, "Failed to allocate video device\n");
2557 goto enc_vdev_register_rollback;
2559 snprintf(jpeg->vfd_decoder->name, sizeof(jpeg->vfd_decoder->name),
2560 "%s-dec", S5P_JPEG_M2M_NAME);
2561 jpeg->vfd_decoder->fops = &s5p_jpeg_fops;
2562 jpeg->vfd_decoder->ioctl_ops = &s5p_jpeg_ioctl_ops;
2563 jpeg->vfd_decoder->minor = -1;
2564 jpeg->vfd_decoder->release = video_device_release;
2565 jpeg->vfd_decoder->lock = &jpeg->lock;
2566 jpeg->vfd_decoder->v4l2_dev = &jpeg->v4l2_dev;
2567 jpeg->vfd_decoder->vfl_dir = VFL_DIR_M2M;
2569 ret = video_register_device(jpeg->vfd_decoder, VFL_TYPE_GRABBER, -1);
2571 v4l2_err(&jpeg->v4l2_dev, "Failed to register video device\n");
2572 goto dec_vdev_alloc_rollback;
2575 video_set_drvdata(jpeg->vfd_decoder, jpeg);
2576 v4l2_info(&jpeg->v4l2_dev,
2577 "decoder device registered as /dev/video%d\n",
2578 jpeg->vfd_decoder->num);
2580 /* final statements & power management */
2581 platform_set_drvdata(pdev, jpeg);
2583 pm_runtime_enable(&pdev->dev);
2585 v4l2_info(&jpeg->v4l2_dev, "Samsung S5P JPEG codec\n");
2589 dec_vdev_alloc_rollback:
2590 video_device_release(jpeg->vfd_decoder);
2592 enc_vdev_register_rollback:
2593 video_unregister_device(jpeg->vfd_encoder);
2595 enc_vdev_alloc_rollback:
2596 video_device_release(jpeg->vfd_encoder);
2598 vb2_allocator_rollback:
2599 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
2602 v4l2_m2m_release(jpeg->m2m_dev);
2604 device_register_rollback:
2605 v4l2_device_unregister(&jpeg->v4l2_dev);
2609 if (!IS_ERR(jpeg->sclk))
2610 clk_put(jpeg->sclk);
2615 static int s5p_jpeg_remove(struct platform_device *pdev)
2617 struct s5p_jpeg *jpeg = platform_get_drvdata(pdev);
2619 pm_runtime_disable(jpeg->dev);
2621 video_unregister_device(jpeg->vfd_decoder);
2622 video_device_release(jpeg->vfd_decoder);
2623 video_unregister_device(jpeg->vfd_encoder);
2624 video_device_release(jpeg->vfd_encoder);
2625 vb2_dma_contig_cleanup_ctx(jpeg->alloc_ctx);
2626 v4l2_m2m_release(jpeg->m2m_dev);
2627 v4l2_device_unregister(&jpeg->v4l2_dev);
2629 if (!pm_runtime_status_suspended(&pdev->dev)) {
2630 clk_disable_unprepare(jpeg->clk);
2631 if (!IS_ERR(jpeg->sclk))
2632 clk_disable_unprepare(jpeg->sclk);
2636 if (!IS_ERR(jpeg->sclk))
2637 clk_put(jpeg->sclk);
2643 static int s5p_jpeg_runtime_suspend(struct device *dev)
2645 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2647 clk_disable_unprepare(jpeg->clk);
2648 if (!IS_ERR(jpeg->sclk))
2649 clk_disable_unprepare(jpeg->sclk);
2654 static int s5p_jpeg_runtime_resume(struct device *dev)
2656 struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
2657 unsigned long flags;
2660 ret = clk_prepare_enable(jpeg->clk);
2664 if (!IS_ERR(jpeg->sclk)) {
2665 ret = clk_prepare_enable(jpeg->sclk);
2670 spin_lock_irqsave(&jpeg->slock, flags);
2673 * JPEG IP allows storing two Huffman tables for each component.
2674 * We fill table 0 for each component and do this here only
2675 * for S5PC210 and Exynos3250 SoCs. Exynos4x12 and Exynos542x SoC
2676 * require programming their Huffman tables each time the encoding
2677 * process is initialized, and thus it is accomplished in the
2678 * device_run callback of m2m_ops.
2680 if (!jpeg->variant->htbl_reinit) {
2681 s5p_jpeg_set_hdctbl(jpeg->regs);
2682 s5p_jpeg_set_hdctblg(jpeg->regs);
2683 s5p_jpeg_set_hactbl(jpeg->regs);
2684 s5p_jpeg_set_hactblg(jpeg->regs);
2687 spin_unlock_irqrestore(&jpeg->slock, flags);
2691 #endif /* CONFIG_PM */
2693 #ifdef CONFIG_PM_SLEEP
2694 static int s5p_jpeg_suspend(struct device *dev)
2696 if (pm_runtime_suspended(dev))
2699 return s5p_jpeg_runtime_suspend(dev);
2702 static int s5p_jpeg_resume(struct device *dev)
2704 if (pm_runtime_suspended(dev))
2707 return s5p_jpeg_runtime_resume(dev);
2711 static const struct dev_pm_ops s5p_jpeg_pm_ops = {
2712 SET_SYSTEM_SLEEP_PM_OPS(s5p_jpeg_suspend, s5p_jpeg_resume)
2713 SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend, s5p_jpeg_runtime_resume, NULL)
2716 static struct s5p_jpeg_variant s5p_jpeg_drvdata = {
2717 .version = SJPEG_S5P,
2718 .jpeg_irq = s5p_jpeg_irq,
2719 .m2m_ops = &s5p_jpeg_m2m_ops,
2720 .fmt_ver_flag = SJPEG_FMT_FLAG_S5P,
2723 static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = {
2724 .version = SJPEG_EXYNOS3250,
2725 .jpeg_irq = exynos3250_jpeg_irq,
2726 .m2m_ops = &exynos3250_jpeg_m2m_ops,
2727 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250,
2731 static struct s5p_jpeg_variant exynos4_jpeg_drvdata = {
2732 .version = SJPEG_EXYNOS4,
2733 .jpeg_irq = exynos4_jpeg_irq,
2734 .m2m_ops = &exynos4_jpeg_m2m_ops,
2735 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS4,
2739 static struct s5p_jpeg_variant exynos5420_jpeg_drvdata = {
2740 .version = SJPEG_EXYNOS5420,
2741 .jpeg_irq = exynos3250_jpeg_irq, /* intentionally 3250 */
2742 .m2m_ops = &exynos3250_jpeg_m2m_ops, /* intentionally 3250 */
2743 .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250, /* intentionally 3250 */
2748 static const struct of_device_id samsung_jpeg_match[] = {
2750 .compatible = "samsung,s5pv210-jpeg",
2751 .data = &s5p_jpeg_drvdata,
2753 .compatible = "samsung,exynos3250-jpeg",
2754 .data = &exynos3250_jpeg_drvdata,
2756 .compatible = "samsung,exynos4210-jpeg",
2757 .data = &exynos4_jpeg_drvdata,
2759 .compatible = "samsung,exynos4212-jpeg",
2760 .data = &exynos4_jpeg_drvdata,
2762 .compatible = "samsung,exynos5420-jpeg",
2763 .data = &exynos5420_jpeg_drvdata,
2768 MODULE_DEVICE_TABLE(of, samsung_jpeg_match);
2770 static void *jpeg_get_drv_data(struct device *dev)
2772 struct s5p_jpeg_variant *driver_data = NULL;
2773 const struct of_device_id *match;
2775 if (!IS_ENABLED(CONFIG_OF) || !dev->of_node)
2776 return &s5p_jpeg_drvdata;
2778 match = of_match_node(samsung_jpeg_match, dev->of_node);
2781 driver_data = (struct s5p_jpeg_variant *)match->data;
2786 static struct platform_driver s5p_jpeg_driver = {
2787 .probe = s5p_jpeg_probe,
2788 .remove = s5p_jpeg_remove,
2790 .of_match_table = of_match_ptr(samsung_jpeg_match),
2791 .name = S5P_JPEG_M2M_NAME,
2792 .pm = &s5p_jpeg_pm_ops,
2796 module_platform_driver(s5p_jpeg_driver);
2798 MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
2799 MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
2800 MODULE_DESCRIPTION("Samsung JPEG codec driver");
2801 MODULE_LICENSE("GPL");