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 WARN_ON(ctx
->subsampling
> 3);
632 if (ctx
->subsampling
> 2)
633 return V4L2_JPEG_CHROMA_SUBSAMPLING_420
;
634 return exynos4x12_decoded_subsampling
[ctx
->subsampling
];
635 case SJPEG_EXYNOS5433
:
636 return ctx
->subsampling
; /* parsed from header */
638 WARN_ON(ctx
->subsampling
> 3);
639 return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY
;
643 static inline void s5p_jpeg_set_qtbl(void __iomem
*regs
,
644 const unsigned char *qtbl
,
645 unsigned long tab
, int len
)
649 for (i
= 0; i
< len
; i
++)
650 writel((unsigned int)qtbl
[i
], regs
+ tab
+ (i
* 0x04));
653 static inline void s5p_jpeg_set_qtbl_lum(void __iomem
*regs
, int quality
)
655 /* this driver fills quantisation table 0 with data for luma */
656 s5p_jpeg_set_qtbl(regs
, qtbl_luminance
[quality
],
657 S5P_JPG_QTBL_CONTENT(0),
658 ARRAY_SIZE(qtbl_luminance
[quality
]));
661 static inline void s5p_jpeg_set_qtbl_chr(void __iomem
*regs
, int quality
)
663 /* this driver fills quantisation table 1 with data for chroma */
664 s5p_jpeg_set_qtbl(regs
, qtbl_chrominance
[quality
],
665 S5P_JPG_QTBL_CONTENT(1),
666 ARRAY_SIZE(qtbl_chrominance
[quality
]));
669 static inline void s5p_jpeg_set_htbl(void __iomem
*regs
,
670 const unsigned char *htbl
,
671 unsigned long tab
, int len
)
675 for (i
= 0; i
< len
; i
++)
676 writel((unsigned int)htbl
[i
], regs
+ tab
+ (i
* 0x04));
679 static inline void s5p_jpeg_set_hdctbl(void __iomem
*regs
)
681 /* this driver fills table 0 for this component */
682 s5p_jpeg_set_htbl(regs
, hdctbl0
, S5P_JPG_HDCTBL(0),
683 ARRAY_SIZE(hdctbl0
));
686 static inline void s5p_jpeg_set_hdctblg(void __iomem
*regs
)
688 /* this driver fills table 0 for this component */
689 s5p_jpeg_set_htbl(regs
, hdctblg0
, S5P_JPG_HDCTBLG(0),
690 ARRAY_SIZE(hdctblg0
));
693 static inline void s5p_jpeg_set_hactbl(void __iomem
*regs
)
695 /* this driver fills table 0 for this component */
696 s5p_jpeg_set_htbl(regs
, hactbl0
, S5P_JPG_HACTBL(0),
697 ARRAY_SIZE(hactbl0
));
700 static inline void s5p_jpeg_set_hactblg(void __iomem
*regs
)
702 /* this driver fills table 0 for this component */
703 s5p_jpeg_set_htbl(regs
, hactblg0
, S5P_JPG_HACTBLG(0),
704 ARRAY_SIZE(hactblg0
));
707 static inline void exynos4_jpeg_set_tbl(void __iomem
*regs
,
708 const unsigned char *tbl
,
709 unsigned long tab
, int len
)
714 for (i
= 0; i
< len
; i
+= 4) {
719 writel(dword
, regs
+ tab
+ i
);
723 static inline void exynos4_jpeg_set_qtbl_lum(void __iomem
*regs
, int quality
)
725 /* this driver fills quantisation table 0 with data for luma */
726 exynos4_jpeg_set_tbl(regs
, qtbl_luminance
[quality
],
727 EXYNOS4_QTBL_CONTENT(0),
728 ARRAY_SIZE(qtbl_luminance
[quality
]));
731 static inline void exynos4_jpeg_set_qtbl_chr(void __iomem
*regs
, int quality
)
733 /* this driver fills quantisation table 1 with data for chroma */
734 exynos4_jpeg_set_tbl(regs
, qtbl_chrominance
[quality
],
735 EXYNOS4_QTBL_CONTENT(1),
736 ARRAY_SIZE(qtbl_chrominance
[quality
]));
739 static void exynos4_jpeg_set_huff_tbl(void __iomem
*base
)
741 exynos4_jpeg_set_tbl(base
, hdctbl0
, EXYNOS4_HUFF_TBL_HDCLL
,
742 ARRAY_SIZE(hdctbl0
));
743 exynos4_jpeg_set_tbl(base
, hdctbl0
, EXYNOS4_HUFF_TBL_HDCCL
,
744 ARRAY_SIZE(hdctbl0
));
745 exynos4_jpeg_set_tbl(base
, hdctblg0
, EXYNOS4_HUFF_TBL_HDCLV
,
746 ARRAY_SIZE(hdctblg0
));
747 exynos4_jpeg_set_tbl(base
, hdctblg0
, EXYNOS4_HUFF_TBL_HDCCV
,
748 ARRAY_SIZE(hdctblg0
));
749 exynos4_jpeg_set_tbl(base
, hactbl0
, EXYNOS4_HUFF_TBL_HACLL
,
750 ARRAY_SIZE(hactbl0
));
751 exynos4_jpeg_set_tbl(base
, hactbl0
, EXYNOS4_HUFF_TBL_HACCL
,
752 ARRAY_SIZE(hactbl0
));
753 exynos4_jpeg_set_tbl(base
, hactblg0
, EXYNOS4_HUFF_TBL_HACLV
,
754 ARRAY_SIZE(hactblg0
));
755 exynos4_jpeg_set_tbl(base
, hactblg0
, EXYNOS4_HUFF_TBL_HACCV
,
756 ARRAY_SIZE(hactblg0
));
759 static inline int __exynos4_huff_tbl(int class, int id
, bool lenval
)
762 * class: 0 - DC, 1 - AC
763 * id: 0 - Y, 1 - Cb/Cr
767 return lenval
? EXYNOS4_HUFF_TBL_HACCL
:
768 EXYNOS4_HUFF_TBL_HACCV
;
769 return lenval
? EXYNOS4_HUFF_TBL_HACLL
: EXYNOS4_HUFF_TBL_HACLV
;
774 return lenval
? EXYNOS4_HUFF_TBL_HDCCL
: EXYNOS4_HUFF_TBL_HDCCV
;
776 return lenval
? EXYNOS4_HUFF_TBL_HDCLL
: EXYNOS4_HUFF_TBL_HDCLV
;
779 static inline int exynos4_huff_tbl_len(int class, int id
)
781 return __exynos4_huff_tbl(class, id
, true);
784 static inline int exynos4_huff_tbl_val(int class, int id
)
786 return __exynos4_huff_tbl(class, id
, false);
789 static int get_byte(struct s5p_jpeg_buffer
*buf
);
790 static int get_word_be(struct s5p_jpeg_buffer
*buf
, unsigned int *word
);
791 static void skip(struct s5p_jpeg_buffer
*buf
, long len
);
793 static void exynos4_jpeg_parse_decode_h_tbl(struct s5p_jpeg_ctx
*ctx
)
795 struct s5p_jpeg
*jpeg
= ctx
->jpeg
;
796 struct vb2_v4l2_buffer
*vb
= v4l2_m2m_next_src_buf(ctx
->fh
.m2m_ctx
);
797 struct s5p_jpeg_buffer jpeg_buffer
;
799 int c
, x
, components
;
801 jpeg_buffer
.size
= 2; /* Ls */
803 (unsigned long)vb2_plane_vaddr(&vb
->vb2_buf
, 0) + ctx
->out_q
.sos
+ 2;
804 jpeg_buffer
.curr
= 0;
808 if (get_word_be(&jpeg_buffer
, &word
))
810 jpeg_buffer
.size
= (long)word
- 2;
811 jpeg_buffer
.data
+= 2;
812 jpeg_buffer
.curr
= 0;
814 components
= get_byte(&jpeg_buffer
);
815 if (components
== -1)
817 while (components
--) {
818 c
= get_byte(&jpeg_buffer
);
821 x
= get_byte(&jpeg_buffer
);
824 exynos4_jpeg_select_dec_h_tbl(jpeg
->regs
, c
,
825 (((x
>> 4) & 0x1) << 1) | (x
& 0x1));
830 static void exynos4_jpeg_parse_huff_tbl(struct s5p_jpeg_ctx
*ctx
)
832 struct s5p_jpeg
*jpeg
= ctx
->jpeg
;
833 struct vb2_v4l2_buffer
*vb
= v4l2_m2m_next_src_buf(ctx
->fh
.m2m_ctx
);
834 struct s5p_jpeg_buffer jpeg_buffer
;
838 for (j
= 0; j
< ctx
->out_q
.dht
.n
; ++j
) {
839 jpeg_buffer
.size
= ctx
->out_q
.dht
.len
[j
];
840 jpeg_buffer
.data
= (unsigned long)vb2_plane_vaddr(&vb
->vb2_buf
, 0) +
841 ctx
->out_q
.dht
.marker
[j
];
842 jpeg_buffer
.curr
= 0;
845 while (jpeg_buffer
.curr
< jpeg_buffer
.size
) {
848 c
= get_byte(&jpeg_buffer
);
852 class = (c
>> 4) & 0xf;
854 for (i
= 0; i
< 16; ++i
) {
855 c
= get_byte(&jpeg_buffer
);
858 word
|= c
<< ((i
% 4) * 8);
859 if ((i
+ 1) % 4 == 0) {
860 writel(word
, jpeg
->regs
+
861 exynos4_huff_tbl_len(class, id
) +
868 for (i
= 0; i
< n
; ++i
) {
869 c
= get_byte(&jpeg_buffer
);
872 word
|= c
<< ((i
% 4) * 8);
873 if ((i
+ 1) % 4 == 0) {
874 writel(word
, jpeg
->regs
+
875 exynos4_huff_tbl_val(class, id
) +
881 writel(word
, jpeg
->regs
+
882 exynos4_huff_tbl_val(class, id
) + (i
/ 4) * 4);
889 static void exynos4_jpeg_parse_decode_q_tbl(struct s5p_jpeg_ctx
*ctx
)
891 struct s5p_jpeg
*jpeg
= ctx
->jpeg
;
892 struct vb2_v4l2_buffer
*vb
= v4l2_m2m_next_src_buf(ctx
->fh
.m2m_ctx
);
893 struct s5p_jpeg_buffer jpeg_buffer
;
894 int c
, x
, components
;
896 jpeg_buffer
.size
= ctx
->out_q
.sof_len
;
898 (unsigned long)vb2_plane_vaddr(&vb
->vb2_buf
, 0) + ctx
->out_q
.sof
;
899 jpeg_buffer
.curr
= 0;
901 skip(&jpeg_buffer
, 5); /* P, Y, X */
902 components
= get_byte(&jpeg_buffer
);
903 if (components
== -1)
906 exynos4_jpeg_set_dec_components(jpeg
->regs
, components
);
908 while (components
--) {
909 c
= get_byte(&jpeg_buffer
);
912 skip(&jpeg_buffer
, 1);
913 x
= get_byte(&jpeg_buffer
);
916 exynos4_jpeg_select_dec_q_tbl(jpeg
->regs
, c
, x
);
920 static void exynos4_jpeg_parse_q_tbl(struct s5p_jpeg_ctx
*ctx
)
922 struct s5p_jpeg
*jpeg
= ctx
->jpeg
;
923 struct vb2_v4l2_buffer
*vb
= v4l2_m2m_next_src_buf(ctx
->fh
.m2m_ctx
);
924 struct s5p_jpeg_buffer jpeg_buffer
;
928 for (j
= 0; j
< ctx
->out_q
.dqt
.n
; ++j
) {
929 jpeg_buffer
.size
= ctx
->out_q
.dqt
.len
[j
];
930 jpeg_buffer
.data
= (unsigned long)vb2_plane_vaddr(&vb
->vb2_buf
, 0) +
931 ctx
->out_q
.dqt
.marker
[j
];
932 jpeg_buffer
.curr
= 0;
935 while (jpeg_buffer
.size
- jpeg_buffer
.curr
>= 65) {
938 c
= get_byte(&jpeg_buffer
);
942 /* nonzero means extended mode - not supported */
945 for (i
= 0; i
< 64; ++i
) {
946 c
= get_byte(&jpeg_buffer
);
949 word
|= c
<< ((i
% 4) * 8);
950 if ((i
+ 1) % 4 == 0) {
951 writel(word
, jpeg
->regs
+
952 EXYNOS4_QTBL_CONTENT(id
) + (i
/ 4) * 4);
962 * ============================================================================
963 * Device file operations
964 * ============================================================================
967 static int queue_init(void *priv
, struct vb2_queue
*src_vq
,
968 struct vb2_queue
*dst_vq
);
969 static struct s5p_jpeg_fmt
*s5p_jpeg_find_format(struct s5p_jpeg_ctx
*ctx
,
970 __u32 pixelformat
, unsigned int fmt_type
);
971 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx
*ctx
);
973 static int s5p_jpeg_open(struct file
*file
)
975 struct s5p_jpeg
*jpeg
= video_drvdata(file
);
976 struct video_device
*vfd
= video_devdata(file
);
977 struct s5p_jpeg_ctx
*ctx
;
978 struct s5p_jpeg_fmt
*out_fmt
, *cap_fmt
;
981 ctx
= kzalloc(sizeof(*ctx
), GFP_KERNEL
);
985 if (mutex_lock_interruptible(&jpeg
->lock
)) {
990 v4l2_fh_init(&ctx
->fh
, vfd
);
991 /* Use separate control handler per file handle */
992 ctx
->fh
.ctrl_handler
= &ctx
->ctrl_handler
;
993 file
->private_data
= &ctx
->fh
;
994 v4l2_fh_add(&ctx
->fh
);
997 if (vfd
== jpeg
->vfd_encoder
) {
998 ctx
->mode
= S5P_JPEG_ENCODE
;
999 out_fmt
= s5p_jpeg_find_format(ctx
, V4L2_PIX_FMT_RGB565
,
1001 cap_fmt
= s5p_jpeg_find_format(ctx
, V4L2_PIX_FMT_JPEG
,
1004 ctx
->mode
= S5P_JPEG_DECODE
;
1005 out_fmt
= s5p_jpeg_find_format(ctx
, V4L2_PIX_FMT_JPEG
,
1007 cap_fmt
= s5p_jpeg_find_format(ctx
, V4L2_PIX_FMT_YUYV
,
1009 ctx
->scale_factor
= EXYNOS3250_DEC_SCALE_FACTOR_8_8
;
1012 ctx
->fh
.m2m_ctx
= v4l2_m2m_ctx_init(jpeg
->m2m_dev
, ctx
, queue_init
);
1013 if (IS_ERR(ctx
->fh
.m2m_ctx
)) {
1014 ret
= PTR_ERR(ctx
->fh
.m2m_ctx
);
1018 ctx
->out_q
.fmt
= out_fmt
;
1019 ctx
->cap_q
.fmt
= cap_fmt
;
1021 ret
= s5p_jpeg_controls_create(ctx
);
1025 mutex_unlock(&jpeg
->lock
);
1029 v4l2_fh_del(&ctx
->fh
);
1030 v4l2_fh_exit(&ctx
->fh
);
1031 mutex_unlock(&jpeg
->lock
);
1037 static int s5p_jpeg_release(struct file
*file
)
1039 struct s5p_jpeg
*jpeg
= video_drvdata(file
);
1040 struct s5p_jpeg_ctx
*ctx
= fh_to_ctx(file
->private_data
);
1042 mutex_lock(&jpeg
->lock
);
1043 v4l2_m2m_ctx_release(ctx
->fh
.m2m_ctx
);
1044 v4l2_ctrl_handler_free(&ctx
->ctrl_handler
);
1045 v4l2_fh_del(&ctx
->fh
);
1046 v4l2_fh_exit(&ctx
->fh
);
1048 mutex_unlock(&jpeg
->lock
);
1053 static const struct v4l2_file_operations s5p_jpeg_fops
= {
1054 .owner
= THIS_MODULE
,
1055 .open
= s5p_jpeg_open
,
1056 .release
= s5p_jpeg_release
,
1057 .poll
= v4l2_m2m_fop_poll
,
1058 .unlocked_ioctl
= video_ioctl2
,
1059 .mmap
= v4l2_m2m_fop_mmap
,
1063 * ============================================================================
1064 * video ioctl operations
1065 * ============================================================================
1068 static int get_byte(struct s5p_jpeg_buffer
*buf
)
1070 if (buf
->curr
>= buf
->size
)
1073 return ((unsigned char *)buf
->data
)[buf
->curr
++];
1076 static int get_word_be(struct s5p_jpeg_buffer
*buf
, unsigned int *word
)
1081 byte
= get_byte(buf
);
1085 byte
= get_byte(buf
);
1088 *word
= (unsigned int)byte
| temp
;
1092 static void skip(struct s5p_jpeg_buffer
*buf
, long len
)
1101 static bool s5p_jpeg_subsampling_decode(struct s5p_jpeg_ctx
*ctx
,
1102 unsigned int subsampling
)
1104 unsigned int version
;
1106 switch (subsampling
) {
1108 ctx
->subsampling
= V4L2_JPEG_CHROMA_SUBSAMPLING_444
;
1111 ctx
->subsampling
= V4L2_JPEG_CHROMA_SUBSAMPLING_422
;
1114 ctx
->subsampling
= V4L2_JPEG_CHROMA_SUBSAMPLING_420
;
1117 ctx
->subsampling
= V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY
;
1121 * 4:1:1 subsampling only supported by 3250, 5420, and 5433
1124 version
= ctx
->jpeg
->variant
->version
;
1125 if (version
!= SJPEG_EXYNOS3250
&&
1126 version
!= SJPEG_EXYNOS5420
&&
1127 version
!= SJPEG_EXYNOS5433
)
1130 ctx
->subsampling
= V4L2_JPEG_CHROMA_SUBSAMPLING_411
;
1139 static bool s5p_jpeg_parse_hdr(struct s5p_jpeg_q_data
*result
,
1140 unsigned long buffer
, unsigned long size
,
1141 struct s5p_jpeg_ctx
*ctx
)
1143 int c
, components
= 0, notfound
, n_dht
= 0, n_dqt
= 0;
1144 unsigned int height
= 0, width
= 0, word
, subsampling
= 0;
1145 unsigned int sos
= 0, sof
= 0, sof_len
= 0;
1146 unsigned int dht
[S5P_JPEG_MAX_MARKER
], dht_len
[S5P_JPEG_MAX_MARKER
];
1147 unsigned int dqt
[S5P_JPEG_MAX_MARKER
], dqt_len
[S5P_JPEG_MAX_MARKER
];
1149 struct s5p_jpeg_buffer jpeg_buffer
;
1151 jpeg_buffer
.size
= size
;
1152 jpeg_buffer
.data
= buffer
;
1153 jpeg_buffer
.curr
= 0;
1156 while (notfound
|| !sos
) {
1157 c
= get_byte(&jpeg_buffer
);
1163 c
= get_byte(&jpeg_buffer
);
1171 /* SOF0: baseline JPEG */
1173 if (get_word_be(&jpeg_buffer
, &word
))
1175 length
= (long)word
- 2;
1178 sof
= jpeg_buffer
.curr
; /* after 0xffc0 */
1180 if (get_byte(&jpeg_buffer
) == -1)
1182 if (get_word_be(&jpeg_buffer
, &height
))
1184 if (get_word_be(&jpeg_buffer
, &width
))
1186 components
= get_byte(&jpeg_buffer
);
1187 if (components
== -1)
1190 if (components
== 1) {
1193 skip(&jpeg_buffer
, 1);
1194 subsampling
= get_byte(&jpeg_buffer
);
1195 skip(&jpeg_buffer
, 1);
1199 skip(&jpeg_buffer
, components
* 2);
1204 if (get_word_be(&jpeg_buffer
, &word
))
1206 length
= (long)word
- 2;
1209 if (n_dqt
>= S5P_JPEG_MAX_MARKER
)
1211 dqt
[n_dqt
] = jpeg_buffer
.curr
; /* after 0xffdb */
1212 dqt_len
[n_dqt
++] = length
;
1213 skip(&jpeg_buffer
, length
);
1217 if (get_word_be(&jpeg_buffer
, &word
))
1219 length
= (long)word
- 2;
1222 if (n_dht
>= S5P_JPEG_MAX_MARKER
)
1224 dht
[n_dht
] = jpeg_buffer
.curr
; /* after 0xffc4 */
1225 dht_len
[n_dht
++] = length
;
1226 skip(&jpeg_buffer
, length
);
1230 sos
= jpeg_buffer
.curr
- 2; /* 0xffda */
1233 /* skip payload-less markers */
1234 case RST
... RST
+ 7:
1240 /* skip uninteresting payload markers */
1242 if (get_word_be(&jpeg_buffer
, &word
))
1244 length
= (long)word
- 2;
1245 skip(&jpeg_buffer
, length
);
1250 if (notfound
|| !sos
|| !s5p_jpeg_subsampling_decode(ctx
, subsampling
))
1256 result
->dht
.n
= n_dht
;
1258 result
->dht
.marker
[n_dht
] = dht
[n_dht
];
1259 result
->dht
.len
[n_dht
] = dht_len
[n_dht
];
1261 result
->dqt
.n
= n_dqt
;
1263 result
->dqt
.marker
[n_dqt
] = dqt
[n_dqt
];
1264 result
->dqt
.len
[n_dqt
] = dqt_len
[n_dqt
];
1267 result
->sof_len
= sof_len
;
1268 result
->components
= components
;
1273 static int s5p_jpeg_querycap(struct file
*file
, void *priv
,
1274 struct v4l2_capability
*cap
)
1276 struct s5p_jpeg_ctx
*ctx
= fh_to_ctx(priv
);
1278 if (ctx
->mode
== S5P_JPEG_ENCODE
) {
1279 strlcpy(cap
->driver
, S5P_JPEG_M2M_NAME
,
1280 sizeof(cap
->driver
));
1281 strlcpy(cap
->card
, S5P_JPEG_M2M_NAME
" encoder",
1284 strlcpy(cap
->driver
, S5P_JPEG_M2M_NAME
,
1285 sizeof(cap
->driver
));
1286 strlcpy(cap
->card
, S5P_JPEG_M2M_NAME
" decoder",
1289 snprintf(cap
->bus_info
, sizeof(cap
->bus_info
), "platform:%s",
1290 dev_name(ctx
->jpeg
->dev
));
1291 cap
->device_caps
= V4L2_CAP_STREAMING
| V4L2_CAP_VIDEO_M2M
;
1292 cap
->capabilities
= cap
->device_caps
| V4L2_CAP_DEVICE_CAPS
;
1296 static int enum_fmt(struct s5p_jpeg_ctx
*ctx
,
1297 struct s5p_jpeg_fmt
*sjpeg_formats
, int n
,
1298 struct v4l2_fmtdesc
*f
, u32 type
)
1301 unsigned int fmt_ver_flag
= ctx
->jpeg
->variant
->fmt_ver_flag
;
1303 for (i
= 0; i
< n
; ++i
) {
1304 if (sjpeg_formats
[i
].flags
& type
&&
1305 sjpeg_formats
[i
].flags
& fmt_ver_flag
) {
1306 /* index-th format of type type found ? */
1307 if (num
== f
->index
)
1309 /* Correct type but haven't reached our index yet,
1310 * just increment per-type index
1316 /* Format not found */
1320 strlcpy(f
->description
, sjpeg_formats
[i
].name
, sizeof(f
->description
));
1321 f
->pixelformat
= sjpeg_formats
[i
].fourcc
;
1326 static int s5p_jpeg_enum_fmt_vid_cap(struct file
*file
, void *priv
,
1327 struct v4l2_fmtdesc
*f
)
1329 struct s5p_jpeg_ctx
*ctx
= fh_to_ctx(priv
);
1331 if (ctx
->mode
== S5P_JPEG_ENCODE
)
1332 return enum_fmt(ctx
, sjpeg_formats
, SJPEG_NUM_FORMATS
, f
,
1333 SJPEG_FMT_FLAG_ENC_CAPTURE
);
1335 return enum_fmt(ctx
, sjpeg_formats
, SJPEG_NUM_FORMATS
, f
,
1336 SJPEG_FMT_FLAG_DEC_CAPTURE
);
1339 static int s5p_jpeg_enum_fmt_vid_out(struct file
*file
, void *priv
,
1340 struct v4l2_fmtdesc
*f
)
1342 struct s5p_jpeg_ctx
*ctx
= fh_to_ctx(priv
);
1344 if (ctx
->mode
== S5P_JPEG_ENCODE
)
1345 return enum_fmt(ctx
, sjpeg_formats
, SJPEG_NUM_FORMATS
, f
,
1346 SJPEG_FMT_FLAG_ENC_OUTPUT
);
1348 return enum_fmt(ctx
, sjpeg_formats
, SJPEG_NUM_FORMATS
, f
,
1349 SJPEG_FMT_FLAG_DEC_OUTPUT
);
1352 static struct s5p_jpeg_q_data
*get_q_data(struct s5p_jpeg_ctx
*ctx
,
1353 enum v4l2_buf_type type
)
1355 if (type
== V4L2_BUF_TYPE_VIDEO_OUTPUT
)
1357 if (type
== V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1363 static int s5p_jpeg_g_fmt(struct file
*file
, void *priv
, struct v4l2_format
*f
)
1365 struct vb2_queue
*vq
;
1366 struct s5p_jpeg_q_data
*q_data
= NULL
;
1367 struct v4l2_pix_format
*pix
= &f
->fmt
.pix
;
1368 struct s5p_jpeg_ctx
*ct
= fh_to_ctx(priv
);
1370 vq
= v4l2_m2m_get_vq(ct
->fh
.m2m_ctx
, f
->type
);
1374 if (f
->type
== V4L2_BUF_TYPE_VIDEO_CAPTURE
&&
1375 ct
->mode
== S5P_JPEG_DECODE
&& !ct
->hdr_parsed
)
1377 q_data
= get_q_data(ct
, f
->type
);
1378 BUG_ON(q_data
== NULL
);
1380 pix
->width
= q_data
->w
;
1381 pix
->height
= q_data
->h
;
1382 pix
->field
= V4L2_FIELD_NONE
;
1383 pix
->pixelformat
= q_data
->fmt
->fourcc
;
1384 pix
->bytesperline
= 0;
1385 if (q_data
->fmt
->fourcc
!= V4L2_PIX_FMT_JPEG
) {
1386 u32 bpl
= q_data
->w
;
1388 if (q_data
->fmt
->colplanes
== 1)
1389 bpl
= (bpl
* q_data
->fmt
->depth
) >> 3;
1390 pix
->bytesperline
= bpl
;
1392 pix
->sizeimage
= q_data
->size
;
1397 static struct s5p_jpeg_fmt
*s5p_jpeg_find_format(struct s5p_jpeg_ctx
*ctx
,
1398 u32 pixelformat
, unsigned int fmt_type
)
1400 unsigned int k
, fmt_flag
;
1402 if (ctx
->mode
== S5P_JPEG_ENCODE
)
1403 fmt_flag
= (fmt_type
== FMT_TYPE_OUTPUT
) ?
1404 SJPEG_FMT_FLAG_ENC_OUTPUT
:
1405 SJPEG_FMT_FLAG_ENC_CAPTURE
;
1407 fmt_flag
= (fmt_type
== FMT_TYPE_OUTPUT
) ?
1408 SJPEG_FMT_FLAG_DEC_OUTPUT
:
1409 SJPEG_FMT_FLAG_DEC_CAPTURE
;
1411 for (k
= 0; k
< ARRAY_SIZE(sjpeg_formats
); k
++) {
1412 struct s5p_jpeg_fmt
*fmt
= &sjpeg_formats
[k
];
1414 if (fmt
->fourcc
== pixelformat
&&
1415 fmt
->flags
& fmt_flag
&&
1416 fmt
->flags
& ctx
->jpeg
->variant
->fmt_ver_flag
) {
1424 static void jpeg_bound_align_image(struct s5p_jpeg_ctx
*ctx
,
1425 u32
*w
, unsigned int wmin
, unsigned int wmax
,
1426 unsigned int walign
,
1427 u32
*h
, unsigned int hmin
, unsigned int hmax
,
1428 unsigned int halign
)
1430 int width
, height
, w_step
, h_step
;
1435 w_step
= 1 << walign
;
1436 h_step
= 1 << halign
;
1438 if (ctx
->jpeg
->variant
->hw3250_compat
) {
1440 * Rightmost and bottommost pixels are cropped by the
1441 * Exynos3250/compatible JPEG IP for RGB formats, for the
1442 * specific width and height values respectively. This
1443 * assignment will result in v4l_bound_align_image returning
1444 * dimensions reduced by 1 for the aforementioned cases.
1446 if (w_step
== 4 && ((width
& 3) == 1)) {
1452 v4l_bound_align_image(w
, wmin
, wmax
, walign
, h
, hmin
, hmax
, halign
, 0);
1454 if (*w
< width
&& (*w
+ w_step
) < wmax
)
1456 if (*h
< height
&& (*h
+ h_step
) < hmax
)
1460 static int vidioc_try_fmt(struct v4l2_format
*f
, struct s5p_jpeg_fmt
*fmt
,
1461 struct s5p_jpeg_ctx
*ctx
, int q_type
)
1463 struct v4l2_pix_format
*pix
= &f
->fmt
.pix
;
1465 if (pix
->field
== V4L2_FIELD_ANY
)
1466 pix
->field
= V4L2_FIELD_NONE
;
1467 else if (pix
->field
!= V4L2_FIELD_NONE
)
1470 /* V4L2 specification suggests the driver corrects the format struct
1471 * if any of the dimensions is unsupported
1473 if (q_type
== FMT_TYPE_OUTPUT
)
1474 jpeg_bound_align_image(ctx
, &pix
->width
, S5P_JPEG_MIN_WIDTH
,
1475 S5P_JPEG_MAX_WIDTH
, 0,
1476 &pix
->height
, S5P_JPEG_MIN_HEIGHT
,
1477 S5P_JPEG_MAX_HEIGHT
, 0);
1479 jpeg_bound_align_image(ctx
, &pix
->width
, S5P_JPEG_MIN_WIDTH
,
1480 S5P_JPEG_MAX_WIDTH
, fmt
->h_align
,
1481 &pix
->height
, S5P_JPEG_MIN_HEIGHT
,
1482 S5P_JPEG_MAX_HEIGHT
, fmt
->v_align
);
1484 if (fmt
->fourcc
== V4L2_PIX_FMT_JPEG
) {
1485 if (pix
->sizeimage
<= 0)
1486 pix
->sizeimage
= PAGE_SIZE
;
1487 pix
->bytesperline
= 0;
1489 u32 bpl
= pix
->bytesperline
;
1491 if (fmt
->colplanes
> 1 && bpl
< pix
->width
)
1492 bpl
= pix
->width
; /* planar */
1494 if (fmt
->colplanes
== 1 && /* packed */
1495 (bpl
<< 3) / fmt
->depth
< pix
->width
)
1496 bpl
= (pix
->width
* fmt
->depth
) >> 3;
1498 pix
->bytesperline
= bpl
;
1499 pix
->sizeimage
= (pix
->width
* pix
->height
* fmt
->depth
) >> 3;
1505 static int s5p_jpeg_try_fmt_vid_cap(struct file
*file
, void *priv
,
1506 struct v4l2_format
*f
)
1508 struct s5p_jpeg_ctx
*ctx
= fh_to_ctx(priv
);
1509 struct v4l2_pix_format
*pix
= &f
->fmt
.pix
;
1510 struct s5p_jpeg_fmt
*fmt
;
1513 fmt
= s5p_jpeg_find_format(ctx
, f
->fmt
.pix
.pixelformat
,
1516 v4l2_err(&ctx
->jpeg
->v4l2_dev
,
1517 "Fourcc format (0x%08x) invalid.\n",
1518 f
->fmt
.pix
.pixelformat
);
1522 if (!ctx
->jpeg
->variant
->hw_ex4_compat
|| ctx
->mode
!= S5P_JPEG_DECODE
)
1526 * The exynos4x12 device requires resulting YUV image
1527 * subsampling not to be lower than the input jpeg subsampling.
1528 * If this requirement is not met then downgrade the requested
1529 * capture format to the one with subsampling equal to the input jpeg.
1531 if ((fmt
->flags
& SJPEG_FMT_NON_RGB
) &&
1532 (fmt
->subsampling
< ctx
->subsampling
)) {
1533 ret
= s5p_jpeg_adjust_fourcc_to_subsampling(ctx
->subsampling
,
1538 pix
->pixelformat
= V4L2_PIX_FMT_GREY
;
1540 fmt
= s5p_jpeg_find_format(ctx
, pix
->pixelformat
,
1545 * Decompression of a JPEG file with 4:2:0 subsampling and odd
1546 * width to the YUV 4:2:0 compliant formats produces a raw image
1547 * with broken luma component. Adjust capture format to RGB565
1550 if (ctx
->subsampling
== V4L2_JPEG_CHROMA_SUBSAMPLING_420
&&
1551 (ctx
->out_q
.w
& 1) &&
1552 (pix
->pixelformat
== V4L2_PIX_FMT_NV12
||
1553 pix
->pixelformat
== V4L2_PIX_FMT_NV21
||
1554 pix
->pixelformat
== V4L2_PIX_FMT_YUV420
)) {
1555 pix
->pixelformat
= V4L2_PIX_FMT_RGB565
;
1556 fmt
= s5p_jpeg_find_format(ctx
, pix
->pixelformat
,
1561 return vidioc_try_fmt(f
, fmt
, ctx
, FMT_TYPE_CAPTURE
);
1564 static int s5p_jpeg_try_fmt_vid_out(struct file
*file
, void *priv
,
1565 struct v4l2_format
*f
)
1567 struct s5p_jpeg_ctx
*ctx
= fh_to_ctx(priv
);
1568 struct s5p_jpeg_fmt
*fmt
;
1570 fmt
= s5p_jpeg_find_format(ctx
, f
->fmt
.pix
.pixelformat
,
1573 v4l2_err(&ctx
->jpeg
->v4l2_dev
,
1574 "Fourcc format (0x%08x) invalid.\n",
1575 f
->fmt
.pix
.pixelformat
);
1579 return vidioc_try_fmt(f
, fmt
, ctx
, FMT_TYPE_OUTPUT
);
1582 static int exynos4_jpeg_get_output_buffer_size(struct s5p_jpeg_ctx
*ctx
,
1583 struct v4l2_format
*f
,
1586 struct v4l2_pix_format
*pix
= &f
->fmt
.pix
;
1587 u32 pix_fmt
= f
->fmt
.pix
.pixelformat
;
1588 int w
= pix
->width
, h
= pix
->height
, wh_align
;
1591 if (pix_fmt
== V4L2_PIX_FMT_RGB32
||
1592 pix_fmt
== V4L2_PIX_FMT_RGB565
||
1593 pix_fmt
== V4L2_PIX_FMT_NV24
||
1594 pix_fmt
== V4L2_PIX_FMT_NV42
||
1595 pix_fmt
== V4L2_PIX_FMT_NV12
||
1596 pix_fmt
== V4L2_PIX_FMT_NV21
||
1597 pix_fmt
== V4L2_PIX_FMT_YUV420
)
1602 jpeg_bound_align_image(ctx
, &w
, S5P_JPEG_MIN_WIDTH
,
1603 S5P_JPEG_MAX_WIDTH
, wh_align
,
1604 &h
, S5P_JPEG_MIN_HEIGHT
,
1605 S5P_JPEG_MAX_HEIGHT
, wh_align
);
1607 if (ctx
->jpeg
->variant
->version
== SJPEG_EXYNOS4
)
1608 padding
= PAGE_SIZE
;
1610 return (w
* h
* fmt_depth
>> 3) + padding
;
1613 static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx
*ctx
,
1614 struct v4l2_rect
*r
);
1616 static int s5p_jpeg_s_fmt(struct s5p_jpeg_ctx
*ct
, struct v4l2_format
*f
)
1618 struct vb2_queue
*vq
;
1619 struct s5p_jpeg_q_data
*q_data
= NULL
;
1620 struct v4l2_pix_format
*pix
= &f
->fmt
.pix
;
1621 struct v4l2_ctrl
*ctrl_subs
;
1622 struct v4l2_rect scale_rect
;
1623 unsigned int f_type
;
1625 vq
= v4l2_m2m_get_vq(ct
->fh
.m2m_ctx
, f
->type
);
1629 q_data
= get_q_data(ct
, f
->type
);
1630 BUG_ON(q_data
== NULL
);
1632 if (vb2_is_busy(vq
)) {
1633 v4l2_err(&ct
->jpeg
->v4l2_dev
, "%s queue busy\n", __func__
);
1637 f_type
= V4L2_TYPE_IS_OUTPUT(f
->type
) ?
1638 FMT_TYPE_OUTPUT
: FMT_TYPE_CAPTURE
;
1640 q_data
->fmt
= s5p_jpeg_find_format(ct
, pix
->pixelformat
, f_type
);
1641 if (ct
->mode
== S5P_JPEG_ENCODE
||
1642 (ct
->mode
== S5P_JPEG_DECODE
&&
1643 q_data
->fmt
->fourcc
!= V4L2_PIX_FMT_JPEG
)) {
1644 q_data
->w
= pix
->width
;
1645 q_data
->h
= pix
->height
;
1647 if (q_data
->fmt
->fourcc
!= V4L2_PIX_FMT_JPEG
) {
1649 * During encoding Exynos4x12 SoCs access wider memory area
1650 * than it results from Image_x and Image_y values written to
1651 * the JPEG_IMAGE_SIZE register. In order to avoid sysmmu
1652 * page fault calculate proper buffer size in such a case.
1654 if (ct
->jpeg
->variant
->hw_ex4_compat
&&
1655 f_type
== FMT_TYPE_OUTPUT
&& ct
->mode
== S5P_JPEG_ENCODE
)
1656 q_data
->size
= exynos4_jpeg_get_output_buffer_size(ct
,
1658 q_data
->fmt
->depth
);
1660 q_data
->size
= q_data
->w
* q_data
->h
*
1661 q_data
->fmt
->depth
>> 3;
1663 q_data
->size
= pix
->sizeimage
;
1666 if (f_type
== FMT_TYPE_OUTPUT
) {
1667 ctrl_subs
= v4l2_ctrl_find(&ct
->ctrl_handler
,
1668 V4L2_CID_JPEG_CHROMA_SUBSAMPLING
);
1670 v4l2_ctrl_s_ctrl(ctrl_subs
, q_data
->fmt
->subsampling
);
1671 ct
->crop_altered
= false;
1675 * For decoding init crop_rect with capture buffer dimmensions which
1676 * contain aligned dimensions of the input JPEG image and do it only
1677 * if crop rectangle hasn't been altered by the user space e.g. with
1678 * S_SELECTION ioctl. For encoding assign output buffer dimensions.
1680 if (!ct
->crop_altered
&&
1681 ((ct
->mode
== S5P_JPEG_DECODE
&& f_type
== FMT_TYPE_CAPTURE
) ||
1682 (ct
->mode
== S5P_JPEG_ENCODE
&& f_type
== FMT_TYPE_OUTPUT
))) {
1683 ct
->crop_rect
.width
= pix
->width
;
1684 ct
->crop_rect
.height
= pix
->height
;
1688 * Prevent downscaling to YUV420 format by more than 2
1689 * for Exynos3250/compatible SoC as it produces broken raw image
1692 if (ct
->mode
== S5P_JPEG_DECODE
&&
1693 f_type
== FMT_TYPE_CAPTURE
&&
1694 ct
->jpeg
->variant
->hw3250_compat
&&
1695 pix
->pixelformat
== V4L2_PIX_FMT_YUV420
&&
1696 ct
->scale_factor
> 2) {
1697 scale_rect
.width
= ct
->out_q
.w
/ 2;
1698 scale_rect
.height
= ct
->out_q
.h
/ 2;
1699 exynos3250_jpeg_try_downscale(ct
, &scale_rect
);
1705 static int s5p_jpeg_s_fmt_vid_cap(struct file
*file
, void *priv
,
1706 struct v4l2_format
*f
)
1710 ret
= s5p_jpeg_try_fmt_vid_cap(file
, priv
, f
);
1714 return s5p_jpeg_s_fmt(fh_to_ctx(priv
), f
);
1717 static int s5p_jpeg_s_fmt_vid_out(struct file
*file
, void *priv
,
1718 struct v4l2_format
*f
)
1722 ret
= s5p_jpeg_try_fmt_vid_out(file
, priv
, f
);
1726 return s5p_jpeg_s_fmt(fh_to_ctx(priv
), f
);
1729 static int s5p_jpeg_subscribe_event(struct v4l2_fh
*fh
,
1730 const struct v4l2_event_subscription
*sub
)
1732 if (sub
->type
== V4L2_EVENT_SOURCE_CHANGE
)
1733 return v4l2_src_change_event_subscribe(fh
, sub
);
1738 static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx
*ctx
,
1739 struct v4l2_rect
*r
)
1741 int w_ratio
, h_ratio
, scale_factor
, cur_ratio
, i
;
1743 w_ratio
= ctx
->out_q
.w
/ r
->width
;
1744 h_ratio
= ctx
->out_q
.h
/ r
->height
;
1746 scale_factor
= w_ratio
> h_ratio
? w_ratio
: h_ratio
;
1747 scale_factor
= clamp_val(scale_factor
, 1, 8);
1749 /* Align scale ratio to the nearest power of 2 */
1750 for (i
= 0; i
<= 3; ++i
) {
1752 if (scale_factor
<= cur_ratio
) {
1753 ctx
->scale_factor
= cur_ratio
;
1758 r
->width
= round_down(ctx
->out_q
.w
/ ctx
->scale_factor
, 2);
1759 r
->height
= round_down(ctx
->out_q
.h
/ ctx
->scale_factor
, 2);
1761 ctx
->crop_rect
.width
= r
->width
;
1762 ctx
->crop_rect
.height
= r
->height
;
1763 ctx
->crop_rect
.left
= 0;
1764 ctx
->crop_rect
.top
= 0;
1766 ctx
->crop_altered
= true;
1771 /* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */
1772 static int enclosed_rectangle(struct v4l2_rect
*a
, struct v4l2_rect
*b
)
1774 if (a
->left
< b
->left
|| a
->top
< b
->top
)
1776 if (a
->left
+ a
->width
> b
->left
+ b
->width
)
1778 if (a
->top
+ a
->height
> b
->top
+ b
->height
)
1784 static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx
*ctx
,
1785 struct v4l2_rect
*r
)
1787 struct v4l2_rect base_rect
;
1790 switch (ctx
->cap_q
.fmt
->fourcc
) {
1791 case V4L2_PIX_FMT_NV12
:
1792 case V4L2_PIX_FMT_NV21
:
1796 case V4L2_PIX_FMT_YUV420
:
1808 base_rect
.width
= ctx
->out_q
.w
;
1809 base_rect
.height
= ctx
->out_q
.h
;
1811 r
->width
= round_down(r
->width
, w_step
);
1812 r
->height
= round_down(r
->height
, h_step
);
1813 r
->left
= round_down(r
->left
, 2);
1814 r
->top
= round_down(r
->top
, 2);
1816 if (!enclosed_rectangle(r
, &base_rect
))
1819 ctx
->crop_rect
.left
= r
->left
;
1820 ctx
->crop_rect
.top
= r
->top
;
1821 ctx
->crop_rect
.width
= r
->width
;
1822 ctx
->crop_rect
.height
= r
->height
;
1824 ctx
->crop_altered
= true;
1833 static int s5p_jpeg_g_selection(struct file
*file
, void *priv
,
1834 struct v4l2_selection
*s
)
1836 struct s5p_jpeg_ctx
*ctx
= fh_to_ctx(priv
);
1838 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
&&
1839 s
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1842 /* For JPEG blob active == default == bounds */
1843 switch (s
->target
) {
1844 case V4L2_SEL_TGT_CROP
:
1845 case V4L2_SEL_TGT_CROP_BOUNDS
:
1846 case V4L2_SEL_TGT_CROP_DEFAULT
:
1847 case V4L2_SEL_TGT_COMPOSE_DEFAULT
:
1848 s
->r
.width
= ctx
->out_q
.w
;
1849 s
->r
.height
= ctx
->out_q
.h
;
1853 case V4L2_SEL_TGT_COMPOSE
:
1854 case V4L2_SEL_TGT_COMPOSE_BOUNDS
:
1855 case V4L2_SEL_TGT_COMPOSE_PADDED
:
1856 s
->r
.width
= ctx
->crop_rect
.width
;
1857 s
->r
.height
= ctx
->crop_rect
.height
;
1858 s
->r
.left
= ctx
->crop_rect
.left
;
1859 s
->r
.top
= ctx
->crop_rect
.top
;
1870 static int s5p_jpeg_s_selection(struct file
*file
, void *fh
,
1871 struct v4l2_selection
*s
)
1873 struct s5p_jpeg_ctx
*ctx
= fh_to_ctx(file
->private_data
);
1874 struct v4l2_rect
*rect
= &s
->r
;
1877 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1880 if (s
->target
== V4L2_SEL_TGT_COMPOSE
) {
1881 if (ctx
->mode
!= S5P_JPEG_DECODE
)
1883 if (ctx
->jpeg
->variant
->hw3250_compat
)
1884 ret
= exynos3250_jpeg_try_downscale(ctx
, rect
);
1885 } else if (s
->target
== V4L2_SEL_TGT_CROP
) {
1886 if (ctx
->mode
!= S5P_JPEG_ENCODE
)
1888 if (ctx
->jpeg
->variant
->hw3250_compat
)
1889 ret
= exynos3250_jpeg_try_crop(ctx
, rect
);
1895 static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl
*ctrl
)
1897 struct s5p_jpeg_ctx
*ctx
= ctrl_to_ctx(ctrl
);
1898 struct s5p_jpeg
*jpeg
= ctx
->jpeg
;
1899 unsigned long flags
;
1902 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING
:
1903 spin_lock_irqsave(&jpeg
->slock
, flags
);
1904 ctrl
->val
= s5p_jpeg_to_user_subsampling(ctx
);
1905 spin_unlock_irqrestore(&jpeg
->slock
, flags
);
1912 static int s5p_jpeg_adjust_subs_ctrl(struct s5p_jpeg_ctx
*ctx
, int *ctrl_val
)
1914 switch (ctx
->jpeg
->variant
->version
) {
1917 case SJPEG_EXYNOS3250
:
1918 case SJPEG_EXYNOS5420
:
1920 * The exynos3250/compatible device can produce JPEG image only
1921 * of 4:4:4 subsampling when given RGB32 source image.
1923 if (ctx
->out_q
.fmt
->fourcc
== V4L2_PIX_FMT_RGB32
)
1928 * The exynos4x12 device requires input raw image fourcc
1929 * to be V4L2_PIX_FMT_GREY if gray jpeg format
1932 if (ctx
->out_q
.fmt
->fourcc
!= V4L2_PIX_FMT_GREY
&&
1933 *ctrl_val
== V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY
)
1939 * The exynos4x12 and exynos3250/compatible devices require resulting
1940 * jpeg subsampling not to be lower than the input raw image
1943 if (ctx
->out_q
.fmt
->subsampling
> *ctrl_val
)
1944 *ctrl_val
= ctx
->out_q
.fmt
->subsampling
;
1949 static int s5p_jpeg_try_ctrl(struct v4l2_ctrl
*ctrl
)
1951 struct s5p_jpeg_ctx
*ctx
= ctrl_to_ctx(ctrl
);
1952 unsigned long flags
;
1955 spin_lock_irqsave(&ctx
->jpeg
->slock
, flags
);
1957 if (ctrl
->id
== V4L2_CID_JPEG_CHROMA_SUBSAMPLING
)
1958 ret
= s5p_jpeg_adjust_subs_ctrl(ctx
, &ctrl
->val
);
1960 spin_unlock_irqrestore(&ctx
->jpeg
->slock
, flags
);
1964 static int s5p_jpeg_s_ctrl(struct v4l2_ctrl
*ctrl
)
1966 struct s5p_jpeg_ctx
*ctx
= ctrl_to_ctx(ctrl
);
1967 unsigned long flags
;
1969 spin_lock_irqsave(&ctx
->jpeg
->slock
, flags
);
1972 case V4L2_CID_JPEG_COMPRESSION_QUALITY
:
1973 ctx
->compr_quality
= ctrl
->val
;
1975 case V4L2_CID_JPEG_RESTART_INTERVAL
:
1976 ctx
->restart_interval
= ctrl
->val
;
1978 case V4L2_CID_JPEG_CHROMA_SUBSAMPLING
:
1979 ctx
->subsampling
= ctrl
->val
;
1983 spin_unlock_irqrestore(&ctx
->jpeg
->slock
, flags
);
1987 static const struct v4l2_ctrl_ops s5p_jpeg_ctrl_ops
= {
1988 .g_volatile_ctrl
= s5p_jpeg_g_volatile_ctrl
,
1989 .try_ctrl
= s5p_jpeg_try_ctrl
,
1990 .s_ctrl
= s5p_jpeg_s_ctrl
,
1993 static int s5p_jpeg_controls_create(struct s5p_jpeg_ctx
*ctx
)
1995 unsigned int mask
= ~0x27; /* 444, 422, 420, GRAY */
1996 struct v4l2_ctrl
*ctrl
;
1999 v4l2_ctrl_handler_init(&ctx
->ctrl_handler
, 3);
2001 if (ctx
->mode
== S5P_JPEG_ENCODE
) {
2002 v4l2_ctrl_new_std(&ctx
->ctrl_handler
, &s5p_jpeg_ctrl_ops
,
2003 V4L2_CID_JPEG_COMPRESSION_QUALITY
,
2004 0, 3, 1, S5P_JPEG_COMPR_QUAL_WORST
);
2006 v4l2_ctrl_new_std(&ctx
->ctrl_handler
, &s5p_jpeg_ctrl_ops
,
2007 V4L2_CID_JPEG_RESTART_INTERVAL
,
2009 if (ctx
->jpeg
->variant
->version
== SJPEG_S5P
)
2010 mask
= ~0x06; /* 422, 420 */
2013 ctrl
= v4l2_ctrl_new_std_menu(&ctx
->ctrl_handler
, &s5p_jpeg_ctrl_ops
,
2014 V4L2_CID_JPEG_CHROMA_SUBSAMPLING
,
2015 V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY
, mask
,
2016 V4L2_JPEG_CHROMA_SUBSAMPLING_422
);
2018 if (ctx
->ctrl_handler
.error
) {
2019 ret
= ctx
->ctrl_handler
.error
;
2023 if (ctx
->mode
== S5P_JPEG_DECODE
)
2024 ctrl
->flags
|= V4L2_CTRL_FLAG_VOLATILE
|
2025 V4L2_CTRL_FLAG_READ_ONLY
;
2027 ret
= v4l2_ctrl_handler_setup(&ctx
->ctrl_handler
);
2034 v4l2_ctrl_handler_free(&ctx
->ctrl_handler
);
2038 static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops
= {
2039 .vidioc_querycap
= s5p_jpeg_querycap
,
2041 .vidioc_enum_fmt_vid_cap
= s5p_jpeg_enum_fmt_vid_cap
,
2042 .vidioc_enum_fmt_vid_out
= s5p_jpeg_enum_fmt_vid_out
,
2044 .vidioc_g_fmt_vid_cap
= s5p_jpeg_g_fmt
,
2045 .vidioc_g_fmt_vid_out
= s5p_jpeg_g_fmt
,
2047 .vidioc_try_fmt_vid_cap
= s5p_jpeg_try_fmt_vid_cap
,
2048 .vidioc_try_fmt_vid_out
= s5p_jpeg_try_fmt_vid_out
,
2050 .vidioc_s_fmt_vid_cap
= s5p_jpeg_s_fmt_vid_cap
,
2051 .vidioc_s_fmt_vid_out
= s5p_jpeg_s_fmt_vid_out
,
2053 .vidioc_reqbufs
= v4l2_m2m_ioctl_reqbufs
,
2054 .vidioc_querybuf
= v4l2_m2m_ioctl_querybuf
,
2055 .vidioc_qbuf
= v4l2_m2m_ioctl_qbuf
,
2056 .vidioc_dqbuf
= v4l2_m2m_ioctl_dqbuf
,
2058 .vidioc_streamon
= v4l2_m2m_ioctl_streamon
,
2059 .vidioc_streamoff
= v4l2_m2m_ioctl_streamoff
,
2061 .vidioc_g_selection
= s5p_jpeg_g_selection
,
2062 .vidioc_s_selection
= s5p_jpeg_s_selection
,
2064 .vidioc_subscribe_event
= s5p_jpeg_subscribe_event
,
2065 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
2069 * ============================================================================
2071 * ============================================================================
2074 static void s5p_jpeg_device_run(void *priv
)
2076 struct s5p_jpeg_ctx
*ctx
= priv
;
2077 struct s5p_jpeg
*jpeg
= ctx
->jpeg
;
2078 struct vb2_v4l2_buffer
*src_buf
, *dst_buf
;
2079 unsigned long src_addr
, dst_addr
, flags
;
2081 spin_lock_irqsave(&ctx
->jpeg
->slock
, flags
);
2083 src_buf
= v4l2_m2m_next_src_buf(ctx
->fh
.m2m_ctx
);
2084 dst_buf
= v4l2_m2m_next_dst_buf(ctx
->fh
.m2m_ctx
);
2085 src_addr
= vb2_dma_contig_plane_dma_addr(&src_buf
->vb2_buf
, 0);
2086 dst_addr
= vb2_dma_contig_plane_dma_addr(&dst_buf
->vb2_buf
, 0);
2088 s5p_jpeg_reset(jpeg
->regs
);
2089 s5p_jpeg_poweron(jpeg
->regs
);
2090 s5p_jpeg_proc_mode(jpeg
->regs
, ctx
->mode
);
2091 if (ctx
->mode
== S5P_JPEG_ENCODE
) {
2092 if (ctx
->out_q
.fmt
->fourcc
== V4L2_PIX_FMT_RGB565
)
2093 s5p_jpeg_input_raw_mode(jpeg
->regs
,
2094 S5P_JPEG_RAW_IN_565
);
2096 s5p_jpeg_input_raw_mode(jpeg
->regs
,
2097 S5P_JPEG_RAW_IN_422
);
2098 s5p_jpeg_subsampling_mode(jpeg
->regs
, ctx
->subsampling
);
2099 s5p_jpeg_dri(jpeg
->regs
, ctx
->restart_interval
);
2100 s5p_jpeg_x(jpeg
->regs
, ctx
->out_q
.w
);
2101 s5p_jpeg_y(jpeg
->regs
, ctx
->out_q
.h
);
2102 s5p_jpeg_imgadr(jpeg
->regs
, src_addr
);
2103 s5p_jpeg_jpgadr(jpeg
->regs
, dst_addr
);
2105 /* ultimately comes from sizeimage from userspace */
2106 s5p_jpeg_enc_stream_int(jpeg
->regs
, ctx
->cap_q
.size
);
2108 /* JPEG RGB to YCbCr conversion matrix */
2109 s5p_jpeg_coef(jpeg
->regs
, 1, 1, S5P_JPEG_COEF11
);
2110 s5p_jpeg_coef(jpeg
->regs
, 1, 2, S5P_JPEG_COEF12
);
2111 s5p_jpeg_coef(jpeg
->regs
, 1, 3, S5P_JPEG_COEF13
);
2112 s5p_jpeg_coef(jpeg
->regs
, 2, 1, S5P_JPEG_COEF21
);
2113 s5p_jpeg_coef(jpeg
->regs
, 2, 2, S5P_JPEG_COEF22
);
2114 s5p_jpeg_coef(jpeg
->regs
, 2, 3, S5P_JPEG_COEF23
);
2115 s5p_jpeg_coef(jpeg
->regs
, 3, 1, S5P_JPEG_COEF31
);
2116 s5p_jpeg_coef(jpeg
->regs
, 3, 2, S5P_JPEG_COEF32
);
2117 s5p_jpeg_coef(jpeg
->regs
, 3, 3, S5P_JPEG_COEF33
);
2120 * JPEG IP allows storing 4 quantization tables
2121 * We fill table 0 for luma and table 1 for chroma
2123 s5p_jpeg_set_qtbl_lum(jpeg
->regs
, ctx
->compr_quality
);
2124 s5p_jpeg_set_qtbl_chr(jpeg
->regs
, ctx
->compr_quality
);
2125 /* use table 0 for Y */
2126 s5p_jpeg_qtbl(jpeg
->regs
, 1, 0);
2127 /* use table 1 for Cb and Cr*/
2128 s5p_jpeg_qtbl(jpeg
->regs
, 2, 1);
2129 s5p_jpeg_qtbl(jpeg
->regs
, 3, 1);
2131 /* Y, Cb, Cr use Huffman table 0 */
2132 s5p_jpeg_htbl_ac(jpeg
->regs
, 1);
2133 s5p_jpeg_htbl_dc(jpeg
->regs
, 1);
2134 s5p_jpeg_htbl_ac(jpeg
->regs
, 2);
2135 s5p_jpeg_htbl_dc(jpeg
->regs
, 2);
2136 s5p_jpeg_htbl_ac(jpeg
->regs
, 3);
2137 s5p_jpeg_htbl_dc(jpeg
->regs
, 3);
2138 } else { /* S5P_JPEG_DECODE */
2139 s5p_jpeg_rst_int_enable(jpeg
->regs
, true);
2140 s5p_jpeg_data_num_int_enable(jpeg
->regs
, true);
2141 s5p_jpeg_final_mcu_num_int_enable(jpeg
->regs
, true);
2142 if (ctx
->cap_q
.fmt
->fourcc
== V4L2_PIX_FMT_YUYV
)
2143 s5p_jpeg_outform_raw(jpeg
->regs
, S5P_JPEG_RAW_OUT_422
);
2145 s5p_jpeg_outform_raw(jpeg
->regs
, S5P_JPEG_RAW_OUT_420
);
2146 s5p_jpeg_jpgadr(jpeg
->regs
, src_addr
);
2147 s5p_jpeg_imgadr(jpeg
->regs
, dst_addr
);
2150 s5p_jpeg_start(jpeg
->regs
);
2152 spin_unlock_irqrestore(&ctx
->jpeg
->slock
, flags
);
2155 static void exynos4_jpeg_set_img_addr(struct s5p_jpeg_ctx
*ctx
)
2157 struct s5p_jpeg
*jpeg
= ctx
->jpeg
;
2158 struct s5p_jpeg_fmt
*fmt
;
2159 struct vb2_v4l2_buffer
*vb
;
2160 struct s5p_jpeg_addr jpeg_addr
= {};
2161 u32 pix_size
, padding_bytes
= 0;
2166 pix_size
= ctx
->cap_q
.w
* ctx
->cap_q
.h
;
2168 if (ctx
->mode
== S5P_JPEG_ENCODE
) {
2169 vb
= v4l2_m2m_next_src_buf(ctx
->fh
.m2m_ctx
);
2170 fmt
= ctx
->out_q
.fmt
;
2171 if (ctx
->out_q
.w
% 2 && fmt
->h_align
> 0)
2172 padding_bytes
= ctx
->out_q
.h
;
2174 fmt
= ctx
->cap_q
.fmt
;
2175 vb
= v4l2_m2m_next_dst_buf(ctx
->fh
.m2m_ctx
);
2178 jpeg_addr
.y
= vb2_dma_contig_plane_dma_addr(&vb
->vb2_buf
, 0);
2180 if (fmt
->colplanes
== 2) {
2181 jpeg_addr
.cb
= jpeg_addr
.y
+ pix_size
- padding_bytes
;
2182 } else if (fmt
->colplanes
== 3) {
2183 jpeg_addr
.cb
= jpeg_addr
.y
+ pix_size
;
2184 if (fmt
->fourcc
== V4L2_PIX_FMT_YUV420
)
2185 jpeg_addr
.cr
= jpeg_addr
.cb
+ pix_size
/ 4;
2187 jpeg_addr
.cr
= jpeg_addr
.cb
+ pix_size
/ 2;
2190 exynos4_jpeg_set_frame_buf_address(jpeg
->regs
, &jpeg_addr
);
2193 static void exynos4_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx
*ctx
)
2195 struct s5p_jpeg
*jpeg
= ctx
->jpeg
;
2196 struct vb2_v4l2_buffer
*vb
;
2197 unsigned int jpeg_addr
= 0;
2199 if (ctx
->mode
== S5P_JPEG_ENCODE
)
2200 vb
= v4l2_m2m_next_dst_buf(ctx
->fh
.m2m_ctx
);
2202 vb
= v4l2_m2m_next_src_buf(ctx
->fh
.m2m_ctx
);
2204 jpeg_addr
= vb2_dma_contig_plane_dma_addr(&vb
->vb2_buf
, 0);
2205 if (jpeg
->variant
->version
== SJPEG_EXYNOS5433
&&
2206 ctx
->mode
== S5P_JPEG_DECODE
)
2207 jpeg_addr
+= ctx
->out_q
.sos
;
2208 exynos4_jpeg_set_stream_buf_address(jpeg
->regs
, jpeg_addr
);
2211 static inline void exynos4_jpeg_set_img_fmt(void __iomem
*base
,
2212 unsigned int img_fmt
)
2214 __exynos4_jpeg_set_img_fmt(base
, img_fmt
, SJPEG_EXYNOS4
);
2217 static inline void exynos5433_jpeg_set_img_fmt(void __iomem
*base
,
2218 unsigned int img_fmt
)
2220 __exynos4_jpeg_set_img_fmt(base
, img_fmt
, SJPEG_EXYNOS5433
);
2223 static inline void exynos4_jpeg_set_enc_out_fmt(void __iomem
*base
,
2224 unsigned int out_fmt
)
2226 __exynos4_jpeg_set_enc_out_fmt(base
, out_fmt
, SJPEG_EXYNOS4
);
2229 static inline void exynos5433_jpeg_set_enc_out_fmt(void __iomem
*base
,
2230 unsigned int out_fmt
)
2232 __exynos4_jpeg_set_enc_out_fmt(base
, out_fmt
, SJPEG_EXYNOS5433
);
2235 static void exynos4_jpeg_device_run(void *priv
)
2237 struct s5p_jpeg_ctx
*ctx
= priv
;
2238 struct s5p_jpeg
*jpeg
= ctx
->jpeg
;
2239 unsigned int bitstream_size
;
2240 unsigned long flags
;
2242 spin_lock_irqsave(&jpeg
->slock
, flags
);
2244 if (ctx
->mode
== S5P_JPEG_ENCODE
) {
2245 exynos4_jpeg_sw_reset(jpeg
->regs
);
2246 exynos4_jpeg_set_interrupt(jpeg
->regs
, jpeg
->variant
->version
);
2247 exynos4_jpeg_set_huf_table_enable(jpeg
->regs
, 1);
2249 exynos4_jpeg_set_huff_tbl(jpeg
->regs
);
2252 * JPEG IP allows storing 4 quantization tables
2253 * We fill table 0 for luma and table 1 for chroma
2255 exynos4_jpeg_set_qtbl_lum(jpeg
->regs
, ctx
->compr_quality
);
2256 exynos4_jpeg_set_qtbl_chr(jpeg
->regs
, ctx
->compr_quality
);
2258 exynos4_jpeg_set_encode_tbl_select(jpeg
->regs
,
2259 ctx
->compr_quality
);
2260 exynos4_jpeg_set_stream_size(jpeg
->regs
, ctx
->cap_q
.w
,
2263 if (ctx
->jpeg
->variant
->version
== SJPEG_EXYNOS4
) {
2264 exynos4_jpeg_set_enc_out_fmt(jpeg
->regs
,
2266 exynos4_jpeg_set_img_fmt(jpeg
->regs
,
2267 ctx
->out_q
.fmt
->fourcc
);
2269 exynos5433_jpeg_set_enc_out_fmt(jpeg
->regs
,
2271 exynos5433_jpeg_set_img_fmt(jpeg
->regs
,
2272 ctx
->out_q
.fmt
->fourcc
);
2274 exynos4_jpeg_set_img_addr(ctx
);
2275 exynos4_jpeg_set_jpeg_addr(ctx
);
2276 exynos4_jpeg_set_encode_hoff_cnt(jpeg
->regs
,
2277 ctx
->out_q
.fmt
->fourcc
);
2279 exynos4_jpeg_sw_reset(jpeg
->regs
);
2280 exynos4_jpeg_set_interrupt(jpeg
->regs
,
2281 jpeg
->variant
->version
);
2282 exynos4_jpeg_set_img_addr(ctx
);
2283 exynos4_jpeg_set_jpeg_addr(ctx
);
2285 if (jpeg
->variant
->version
== SJPEG_EXYNOS5433
) {
2286 exynos4_jpeg_parse_huff_tbl(ctx
);
2287 exynos4_jpeg_parse_decode_h_tbl(ctx
);
2289 exynos4_jpeg_parse_q_tbl(ctx
);
2290 exynos4_jpeg_parse_decode_q_tbl(ctx
);
2292 exynos4_jpeg_set_huf_table_enable(jpeg
->regs
, 1);
2294 exynos4_jpeg_set_stream_size(jpeg
->regs
, ctx
->cap_q
.w
,
2296 exynos5433_jpeg_set_enc_out_fmt(jpeg
->regs
,
2298 exynos5433_jpeg_set_img_fmt(jpeg
->regs
,
2299 ctx
->cap_q
.fmt
->fourcc
);
2300 bitstream_size
= DIV_ROUND_UP(ctx
->out_q
.size
, 16);
2302 exynos4_jpeg_set_img_fmt(jpeg
->regs
,
2303 ctx
->cap_q
.fmt
->fourcc
);
2304 bitstream_size
= DIV_ROUND_UP(ctx
->out_q
.size
, 32);
2307 exynos4_jpeg_set_dec_bitstream_size(jpeg
->regs
, bitstream_size
);
2310 exynos4_jpeg_set_sys_int_enable(jpeg
->regs
, 1);
2311 exynos4_jpeg_set_enc_dec_mode(jpeg
->regs
, ctx
->mode
);
2313 spin_unlock_irqrestore(&jpeg
->slock
, flags
);
2316 static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx
*ctx
)
2318 struct s5p_jpeg
*jpeg
= ctx
->jpeg
;
2319 struct s5p_jpeg_fmt
*fmt
;
2320 struct vb2_v4l2_buffer
*vb
;
2321 struct s5p_jpeg_addr jpeg_addr
= {};
2324 pix_size
= ctx
->cap_q
.w
* ctx
->cap_q
.h
;
2326 if (ctx
->mode
== S5P_JPEG_ENCODE
) {
2327 vb
= v4l2_m2m_next_src_buf(ctx
->fh
.m2m_ctx
);
2328 fmt
= ctx
->out_q
.fmt
;
2330 vb
= v4l2_m2m_next_dst_buf(ctx
->fh
.m2m_ctx
);
2331 fmt
= ctx
->cap_q
.fmt
;
2334 jpeg_addr
.y
= vb2_dma_contig_plane_dma_addr(&vb
->vb2_buf
, 0);
2336 if (fmt
->colplanes
== 2) {
2337 jpeg_addr
.cb
= jpeg_addr
.y
+ pix_size
;
2338 } else if (fmt
->colplanes
== 3) {
2339 jpeg_addr
.cb
= jpeg_addr
.y
+ pix_size
;
2340 if (fmt
->fourcc
== V4L2_PIX_FMT_YUV420
)
2341 jpeg_addr
.cr
= jpeg_addr
.cb
+ pix_size
/ 4;
2343 jpeg_addr
.cr
= jpeg_addr
.cb
+ pix_size
/ 2;
2346 exynos3250_jpeg_imgadr(jpeg
->regs
, &jpeg_addr
);
2349 static void exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx
*ctx
)
2351 struct s5p_jpeg
*jpeg
= ctx
->jpeg
;
2352 struct vb2_v4l2_buffer
*vb
;
2353 unsigned int jpeg_addr
= 0;
2355 if (ctx
->mode
== S5P_JPEG_ENCODE
)
2356 vb
= v4l2_m2m_next_dst_buf(ctx
->fh
.m2m_ctx
);
2358 vb
= v4l2_m2m_next_src_buf(ctx
->fh
.m2m_ctx
);
2360 jpeg_addr
= vb2_dma_contig_plane_dma_addr(&vb
->vb2_buf
, 0);
2361 exynos3250_jpeg_jpgadr(jpeg
->regs
, jpeg_addr
);
2364 static void exynos3250_jpeg_device_run(void *priv
)
2366 struct s5p_jpeg_ctx
*ctx
= priv
;
2367 struct s5p_jpeg
*jpeg
= ctx
->jpeg
;
2368 unsigned long flags
;
2370 spin_lock_irqsave(&ctx
->jpeg
->slock
, flags
);
2372 exynos3250_jpeg_reset(jpeg
->regs
);
2373 exynos3250_jpeg_set_dma_num(jpeg
->regs
);
2374 exynos3250_jpeg_poweron(jpeg
->regs
);
2375 exynos3250_jpeg_clk_set(jpeg
->regs
);
2376 exynos3250_jpeg_proc_mode(jpeg
->regs
, ctx
->mode
);
2378 if (ctx
->mode
== S5P_JPEG_ENCODE
) {
2379 exynos3250_jpeg_input_raw_fmt(jpeg
->regs
,
2380 ctx
->out_q
.fmt
->fourcc
);
2381 exynos3250_jpeg_dri(jpeg
->regs
, ctx
->restart_interval
);
2384 * JPEG IP allows storing 4 quantization tables
2385 * We fill table 0 for luma and table 1 for chroma
2387 s5p_jpeg_set_qtbl_lum(jpeg
->regs
, ctx
->compr_quality
);
2388 s5p_jpeg_set_qtbl_chr(jpeg
->regs
, ctx
->compr_quality
);
2389 /* use table 0 for Y */
2390 exynos3250_jpeg_qtbl(jpeg
->regs
, 1, 0);
2391 /* use table 1 for Cb and Cr*/
2392 exynos3250_jpeg_qtbl(jpeg
->regs
, 2, 1);
2393 exynos3250_jpeg_qtbl(jpeg
->regs
, 3, 1);
2396 * Some SoCs require setting Huffman tables before each run
2398 if (jpeg
->variant
->htbl_reinit
) {
2399 s5p_jpeg_set_hdctbl(jpeg
->regs
);
2400 s5p_jpeg_set_hdctblg(jpeg
->regs
);
2401 s5p_jpeg_set_hactbl(jpeg
->regs
);
2402 s5p_jpeg_set_hactblg(jpeg
->regs
);
2405 /* Y, Cb, Cr use Huffman table 0 */
2406 exynos3250_jpeg_htbl_ac(jpeg
->regs
, 1);
2407 exynos3250_jpeg_htbl_dc(jpeg
->regs
, 1);
2408 exynos3250_jpeg_htbl_ac(jpeg
->regs
, 2);
2409 exynos3250_jpeg_htbl_dc(jpeg
->regs
, 2);
2410 exynos3250_jpeg_htbl_ac(jpeg
->regs
, 3);
2411 exynos3250_jpeg_htbl_dc(jpeg
->regs
, 3);
2413 exynos3250_jpeg_set_x(jpeg
->regs
, ctx
->crop_rect
.width
);
2414 exynos3250_jpeg_set_y(jpeg
->regs
, ctx
->crop_rect
.height
);
2415 exynos3250_jpeg_stride(jpeg
->regs
, ctx
->out_q
.fmt
->fourcc
,
2417 exynos3250_jpeg_offset(jpeg
->regs
, ctx
->crop_rect
.left
,
2418 ctx
->crop_rect
.top
);
2419 exynos3250_jpeg_set_img_addr(ctx
);
2420 exynos3250_jpeg_set_jpeg_addr(ctx
);
2421 exynos3250_jpeg_subsampling_mode(jpeg
->regs
, ctx
->subsampling
);
2423 /* ultimately comes from sizeimage from userspace */
2424 exynos3250_jpeg_enc_stream_bound(jpeg
->regs
, ctx
->cap_q
.size
);
2426 if (ctx
->out_q
.fmt
->fourcc
== V4L2_PIX_FMT_RGB565
||
2427 ctx
->out_q
.fmt
->fourcc
== V4L2_PIX_FMT_RGB565X
||
2428 ctx
->out_q
.fmt
->fourcc
== V4L2_PIX_FMT_RGB32
)
2429 exynos3250_jpeg_set_y16(jpeg
->regs
, true);
2431 exynos3250_jpeg_set_img_addr(ctx
);
2432 exynos3250_jpeg_set_jpeg_addr(ctx
);
2433 exynos3250_jpeg_stride(jpeg
->regs
, ctx
->cap_q
.fmt
->fourcc
,
2435 exynos3250_jpeg_offset(jpeg
->regs
, 0, 0);
2436 exynos3250_jpeg_dec_scaling_ratio(jpeg
->regs
,
2438 exynos3250_jpeg_dec_stream_size(jpeg
->regs
, ctx
->out_q
.size
);
2439 exynos3250_jpeg_output_raw_fmt(jpeg
->regs
,
2440 ctx
->cap_q
.fmt
->fourcc
);
2443 exynos3250_jpeg_interrupts_enable(jpeg
->regs
);
2445 /* JPEG RGB to YCbCr conversion matrix */
2446 exynos3250_jpeg_coef(jpeg
->regs
, ctx
->mode
);
2448 exynos3250_jpeg_set_timer(jpeg
->regs
, EXYNOS3250_IRQ_TIMEOUT
);
2449 jpeg
->irq_status
= 0;
2450 exynos3250_jpeg_start(jpeg
->regs
);
2452 spin_unlock_irqrestore(&ctx
->jpeg
->slock
, flags
);
2455 static int s5p_jpeg_job_ready(void *priv
)
2457 struct s5p_jpeg_ctx
*ctx
= priv
;
2459 if (ctx
->mode
== S5P_JPEG_DECODE
) {
2461 * We have only one input buffer and one output buffer. If there
2462 * is a resolution change event, no need to continue decoding.
2464 if (ctx
->state
== JPEGCTX_RESOLUTION_CHANGE
)
2467 return ctx
->hdr_parsed
;
2473 static struct v4l2_m2m_ops s5p_jpeg_m2m_ops
= {
2474 .device_run
= s5p_jpeg_device_run
,
2475 .job_ready
= s5p_jpeg_job_ready
,
2478 static struct v4l2_m2m_ops exynos3250_jpeg_m2m_ops
= {
2479 .device_run
= exynos3250_jpeg_device_run
,
2480 .job_ready
= s5p_jpeg_job_ready
,
2483 static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops
= {
2484 .device_run
= exynos4_jpeg_device_run
,
2485 .job_ready
= s5p_jpeg_job_ready
,
2489 * ============================================================================
2491 * ============================================================================
2494 static int s5p_jpeg_queue_setup(struct vb2_queue
*vq
,
2495 unsigned int *nbuffers
, unsigned int *nplanes
,
2496 unsigned int sizes
[], struct device
*alloc_devs
[])
2498 struct s5p_jpeg_ctx
*ctx
= vb2_get_drv_priv(vq
);
2499 struct s5p_jpeg_q_data
*q_data
= NULL
;
2500 unsigned int size
, count
= *nbuffers
;
2502 q_data
= get_q_data(ctx
, vq
->type
);
2503 BUG_ON(q_data
== NULL
);
2505 size
= q_data
->size
;
2508 * header is parsed during decoding and parsed information stored
2509 * in the context so we do not allow another buffer to overwrite it
2511 if (ctx
->mode
== S5P_JPEG_DECODE
)
2521 static int s5p_jpeg_buf_prepare(struct vb2_buffer
*vb
)
2523 struct s5p_jpeg_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
2524 struct s5p_jpeg_q_data
*q_data
= NULL
;
2526 q_data
= get_q_data(ctx
, vb
->vb2_queue
->type
);
2527 BUG_ON(q_data
== NULL
);
2529 if (vb2_plane_size(vb
, 0) < q_data
->size
) {
2530 pr_err("%s data will not fit into plane (%lu < %lu)\n",
2531 __func__
, vb2_plane_size(vb
, 0),
2532 (long)q_data
->size
);
2536 vb2_set_plane_payload(vb
, 0, q_data
->size
);
2541 static void s5p_jpeg_set_capture_queue_data(struct s5p_jpeg_ctx
*ctx
)
2543 struct s5p_jpeg_q_data
*q_data
= &ctx
->cap_q
;
2545 q_data
->w
= ctx
->out_q
.w
;
2546 q_data
->h
= ctx
->out_q
.h
;
2549 * This call to jpeg_bound_align_image() takes care of width and
2550 * height values alignment when user space calls the QBUF of
2551 * OUTPUT buffer after the S_FMT of CAPTURE buffer.
2552 * Please note that on Exynos4x12 SoCs, resigning from executing
2553 * S_FMT on capture buffer for each JPEG image can result in a
2554 * hardware hangup if subsampling is lower than the one of input
2557 jpeg_bound_align_image(ctx
, &q_data
->w
, S5P_JPEG_MIN_WIDTH
,
2558 S5P_JPEG_MAX_WIDTH
, q_data
->fmt
->h_align
,
2559 &q_data
->h
, S5P_JPEG_MIN_HEIGHT
,
2560 S5P_JPEG_MAX_HEIGHT
, q_data
->fmt
->v_align
);
2562 q_data
->size
= q_data
->w
* q_data
->h
* q_data
->fmt
->depth
>> 3;
2565 static void s5p_jpeg_buf_queue(struct vb2_buffer
*vb
)
2567 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
2568 struct s5p_jpeg_ctx
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
2570 if (ctx
->mode
== S5P_JPEG_DECODE
&&
2571 vb
->vb2_queue
->type
== V4L2_BUF_TYPE_VIDEO_OUTPUT
) {
2572 static const struct v4l2_event ev_src_ch
= {
2573 .type
= V4L2_EVENT_SOURCE_CHANGE
,
2574 .u
.src_change
.changes
= V4L2_EVENT_SRC_CH_RESOLUTION
,
2576 struct vb2_queue
*dst_vq
;
2580 dst_vq
= v4l2_m2m_get_vq(ctx
->fh
.m2m_ctx
,
2581 V4L2_BUF_TYPE_VIDEO_CAPTURE
);
2582 ori_w
= ctx
->out_q
.w
;
2583 ori_h
= ctx
->out_q
.h
;
2585 ctx
->hdr_parsed
= s5p_jpeg_parse_hdr(&ctx
->out_q
,
2586 (unsigned long)vb2_plane_vaddr(vb
, 0),
2587 min((unsigned long)ctx
->out_q
.size
,
2588 vb2_get_plane_payload(vb
, 0)), ctx
);
2589 if (!ctx
->hdr_parsed
) {
2590 vb2_buffer_done(vb
, VB2_BUF_STATE_ERROR
);
2595 * If there is a resolution change event, only update capture
2596 * queue when it is not streaming. Otherwise, update it in
2597 * STREAMOFF. See s5p_jpeg_stop_streaming for detail.
2599 if (ctx
->out_q
.w
!= ori_w
|| ctx
->out_q
.h
!= ori_h
) {
2600 v4l2_event_queue_fh(&ctx
->fh
, &ev_src_ch
);
2601 if (vb2_is_streaming(dst_vq
))
2602 ctx
->state
= JPEGCTX_RESOLUTION_CHANGE
;
2604 s5p_jpeg_set_capture_queue_data(ctx
);
2608 v4l2_m2m_buf_queue(ctx
->fh
.m2m_ctx
, vbuf
);
2611 static int s5p_jpeg_start_streaming(struct vb2_queue
*q
, unsigned int count
)
2613 struct s5p_jpeg_ctx
*ctx
= vb2_get_drv_priv(q
);
2616 ret
= pm_runtime_get_sync(ctx
->jpeg
->dev
);
2618 return ret
> 0 ? 0 : ret
;
2621 static void s5p_jpeg_stop_streaming(struct vb2_queue
*q
)
2623 struct s5p_jpeg_ctx
*ctx
= vb2_get_drv_priv(q
);
2626 * STREAMOFF is an acknowledgment for resolution change event.
2627 * Before STREAMOFF, we still have to return the old resolution and
2628 * subsampling. Update capture queue when the stream is off.
2630 if (ctx
->state
== JPEGCTX_RESOLUTION_CHANGE
&&
2631 q
->type
== V4L2_BUF_TYPE_VIDEO_CAPTURE
) {
2632 s5p_jpeg_set_capture_queue_data(ctx
);
2633 ctx
->state
= JPEGCTX_RUNNING
;
2636 pm_runtime_put(ctx
->jpeg
->dev
);
2639 static const struct vb2_ops s5p_jpeg_qops
= {
2640 .queue_setup
= s5p_jpeg_queue_setup
,
2641 .buf_prepare
= s5p_jpeg_buf_prepare
,
2642 .buf_queue
= s5p_jpeg_buf_queue
,
2643 .wait_prepare
= vb2_ops_wait_prepare
,
2644 .wait_finish
= vb2_ops_wait_finish
,
2645 .start_streaming
= s5p_jpeg_start_streaming
,
2646 .stop_streaming
= s5p_jpeg_stop_streaming
,
2649 static int queue_init(void *priv
, struct vb2_queue
*src_vq
,
2650 struct vb2_queue
*dst_vq
)
2652 struct s5p_jpeg_ctx
*ctx
= priv
;
2655 src_vq
->type
= V4L2_BUF_TYPE_VIDEO_OUTPUT
;
2656 src_vq
->io_modes
= VB2_MMAP
| VB2_USERPTR
;
2657 src_vq
->drv_priv
= ctx
;
2658 src_vq
->buf_struct_size
= sizeof(struct v4l2_m2m_buffer
);
2659 src_vq
->ops
= &s5p_jpeg_qops
;
2660 src_vq
->mem_ops
= &vb2_dma_contig_memops
;
2661 src_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
2662 src_vq
->lock
= &ctx
->jpeg
->lock
;
2663 src_vq
->dev
= ctx
->jpeg
->dev
;
2665 ret
= vb2_queue_init(src_vq
);
2669 dst_vq
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE
;
2670 dst_vq
->io_modes
= VB2_MMAP
| VB2_USERPTR
;
2671 dst_vq
->drv_priv
= ctx
;
2672 dst_vq
->buf_struct_size
= sizeof(struct v4l2_m2m_buffer
);
2673 dst_vq
->ops
= &s5p_jpeg_qops
;
2674 dst_vq
->mem_ops
= &vb2_dma_contig_memops
;
2675 dst_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
2676 dst_vq
->lock
= &ctx
->jpeg
->lock
;
2677 dst_vq
->dev
= ctx
->jpeg
->dev
;
2679 return vb2_queue_init(dst_vq
);
2683 * ============================================================================
2685 * ============================================================================
2688 static irqreturn_t
s5p_jpeg_irq(int irq
, void *dev_id
)
2690 struct s5p_jpeg
*jpeg
= dev_id
;
2691 struct s5p_jpeg_ctx
*curr_ctx
;
2692 struct vb2_v4l2_buffer
*src_buf
, *dst_buf
;
2693 unsigned long payload_size
= 0;
2694 enum vb2_buffer_state state
= VB2_BUF_STATE_DONE
;
2695 bool enc_jpeg_too_large
= false;
2696 bool timer_elapsed
= false;
2697 bool op_completed
= false;
2699 spin_lock(&jpeg
->slock
);
2701 curr_ctx
= v4l2_m2m_get_curr_priv(jpeg
->m2m_dev
);
2703 src_buf
= v4l2_m2m_src_buf_remove(curr_ctx
->fh
.m2m_ctx
);
2704 dst_buf
= v4l2_m2m_dst_buf_remove(curr_ctx
->fh
.m2m_ctx
);
2706 if (curr_ctx
->mode
== S5P_JPEG_ENCODE
)
2707 enc_jpeg_too_large
= s5p_jpeg_enc_stream_stat(jpeg
->regs
);
2708 timer_elapsed
= s5p_jpeg_timer_stat(jpeg
->regs
);
2709 op_completed
= s5p_jpeg_result_stat_ok(jpeg
->regs
);
2710 if (curr_ctx
->mode
== S5P_JPEG_DECODE
)
2711 op_completed
= op_completed
&&
2712 s5p_jpeg_stream_stat_ok(jpeg
->regs
);
2714 if (enc_jpeg_too_large
) {
2715 state
= VB2_BUF_STATE_ERROR
;
2716 s5p_jpeg_clear_enc_stream_stat(jpeg
->regs
);
2717 } else if (timer_elapsed
) {
2718 state
= VB2_BUF_STATE_ERROR
;
2719 s5p_jpeg_clear_timer_stat(jpeg
->regs
);
2720 } else if (!op_completed
) {
2721 state
= VB2_BUF_STATE_ERROR
;
2723 payload_size
= s5p_jpeg_compressed_size(jpeg
->regs
);
2726 dst_buf
->timecode
= src_buf
->timecode
;
2727 dst_buf
->vb2_buf
.timestamp
= src_buf
->vb2_buf
.timestamp
;
2728 dst_buf
->flags
&= ~V4L2_BUF_FLAG_TSTAMP_SRC_MASK
;
2730 src_buf
->flags
& V4L2_BUF_FLAG_TSTAMP_SRC_MASK
;
2732 v4l2_m2m_buf_done(src_buf
, state
);
2733 if (curr_ctx
->mode
== S5P_JPEG_ENCODE
)
2734 vb2_set_plane_payload(&dst_buf
->vb2_buf
, 0, payload_size
);
2735 v4l2_m2m_buf_done(dst_buf
, state
);
2737 curr_ctx
->subsampling
= s5p_jpeg_get_subsampling_mode(jpeg
->regs
);
2738 spin_unlock(&jpeg
->slock
);
2740 s5p_jpeg_clear_int(jpeg
->regs
);
2742 v4l2_m2m_job_finish(jpeg
->m2m_dev
, curr_ctx
->fh
.m2m_ctx
);
2746 static irqreturn_t
exynos4_jpeg_irq(int irq
, void *priv
)
2748 unsigned int int_status
;
2749 struct vb2_v4l2_buffer
*src_vb
, *dst_vb
;
2750 struct s5p_jpeg
*jpeg
= priv
;
2751 struct s5p_jpeg_ctx
*curr_ctx
;
2752 unsigned long payload_size
= 0;
2754 spin_lock(&jpeg
->slock
);
2756 exynos4_jpeg_set_sys_int_enable(jpeg
->regs
, 0);
2758 curr_ctx
= v4l2_m2m_get_curr_priv(jpeg
->m2m_dev
);
2760 src_vb
= v4l2_m2m_src_buf_remove(curr_ctx
->fh
.m2m_ctx
);
2761 dst_vb
= v4l2_m2m_dst_buf_remove(curr_ctx
->fh
.m2m_ctx
);
2763 int_status
= exynos4_jpeg_get_int_status(jpeg
->regs
);
2766 switch (int_status
& 0x1f) {
2768 jpeg
->irq_ret
= ERR_PROT
;
2771 jpeg
->irq_ret
= OK_ENC_OR_DEC
;
2774 jpeg
->irq_ret
= ERR_DEC_INVALID_FORMAT
;
2777 jpeg
->irq_ret
= ERR_MULTI_SCAN
;
2780 jpeg
->irq_ret
= ERR_FRAME
;
2783 jpeg
->irq_ret
= ERR_UNKNOWN
;
2787 jpeg
->irq_ret
= ERR_UNKNOWN
;
2790 if (jpeg
->irq_ret
== OK_ENC_OR_DEC
) {
2791 if (curr_ctx
->mode
== S5P_JPEG_ENCODE
) {
2792 payload_size
= exynos4_jpeg_get_stream_size(jpeg
->regs
);
2793 vb2_set_plane_payload(&dst_vb
->vb2_buf
,
2796 v4l2_m2m_buf_done(src_vb
, VB2_BUF_STATE_DONE
);
2797 v4l2_m2m_buf_done(dst_vb
, VB2_BUF_STATE_DONE
);
2799 v4l2_m2m_buf_done(src_vb
, VB2_BUF_STATE_ERROR
);
2800 v4l2_m2m_buf_done(dst_vb
, VB2_BUF_STATE_ERROR
);
2803 if (jpeg
->variant
->version
== SJPEG_EXYNOS4
)
2804 curr_ctx
->subsampling
= exynos4_jpeg_get_frame_fmt(jpeg
->regs
);
2806 exynos4_jpeg_set_enc_dec_mode(jpeg
->regs
, S5P_JPEG_DISABLE
);
2808 spin_unlock(&jpeg
->slock
);
2810 v4l2_m2m_job_finish(jpeg
->m2m_dev
, curr_ctx
->fh
.m2m_ctx
);
2814 static irqreturn_t
exynos3250_jpeg_irq(int irq
, void *dev_id
)
2816 struct s5p_jpeg
*jpeg
= dev_id
;
2817 struct s5p_jpeg_ctx
*curr_ctx
;
2818 struct vb2_v4l2_buffer
*src_buf
, *dst_buf
;
2819 unsigned long payload_size
= 0;
2820 enum vb2_buffer_state state
= VB2_BUF_STATE_DONE
;
2821 bool interrupt_timeout
= false;
2822 bool stream_error
= false;
2825 spin_lock(&jpeg
->slock
);
2827 irq_status
= exynos3250_jpeg_get_timer_status(jpeg
->regs
);
2828 if (irq_status
& EXYNOS3250_TIMER_INT_STAT
) {
2829 exynos3250_jpeg_clear_timer_status(jpeg
->regs
);
2830 interrupt_timeout
= true;
2831 dev_err(jpeg
->dev
, "Interrupt timeout occurred.\n");
2834 irq_status
= exynos3250_jpeg_get_int_status(jpeg
->regs
);
2835 exynos3250_jpeg_clear_int_status(jpeg
->regs
, irq_status
);
2837 jpeg
->irq_status
|= irq_status
;
2839 if (jpeg
->variant
->version
== SJPEG_EXYNOS5420
&&
2840 irq_status
& EXYNOS3250_STREAM_STAT
) {
2841 stream_error
= true;
2842 dev_err(jpeg
->dev
, "Syntax error or unrecoverable error occurred.\n");
2845 curr_ctx
= v4l2_m2m_get_curr_priv(jpeg
->m2m_dev
);
2850 if ((irq_status
& EXYNOS3250_HEADER_STAT
) &&
2851 (curr_ctx
->mode
== S5P_JPEG_DECODE
)) {
2852 exynos3250_jpeg_rstart(jpeg
->regs
);
2856 if (jpeg
->irq_status
& (EXYNOS3250_JPEG_DONE
|
2857 EXYNOS3250_WDMA_DONE
|
2858 EXYNOS3250_RDMA_DONE
|
2859 EXYNOS3250_RESULT_STAT
))
2860 payload_size
= exynos3250_jpeg_compressed_size(jpeg
->regs
);
2861 else if (interrupt_timeout
|| stream_error
)
2862 state
= VB2_BUF_STATE_ERROR
;
2866 src_buf
= v4l2_m2m_src_buf_remove(curr_ctx
->fh
.m2m_ctx
);
2867 dst_buf
= v4l2_m2m_dst_buf_remove(curr_ctx
->fh
.m2m_ctx
);
2869 dst_buf
->timecode
= src_buf
->timecode
;
2870 dst_buf
->vb2_buf
.timestamp
= src_buf
->vb2_buf
.timestamp
;
2872 v4l2_m2m_buf_done(src_buf
, state
);
2873 if (curr_ctx
->mode
== S5P_JPEG_ENCODE
)
2874 vb2_set_plane_payload(&dst_buf
->vb2_buf
, 0, payload_size
);
2875 v4l2_m2m_buf_done(dst_buf
, state
);
2877 curr_ctx
->subsampling
=
2878 exynos3250_jpeg_get_subsampling_mode(jpeg
->regs
);
2880 spin_unlock(&jpeg
->slock
);
2882 v4l2_m2m_job_finish(jpeg
->m2m_dev
, curr_ctx
->fh
.m2m_ctx
);
2886 spin_unlock(&jpeg
->slock
);
2890 static void *jpeg_get_drv_data(struct device
*dev
);
2893 * ============================================================================
2894 * Driver basic infrastructure
2895 * ============================================================================
2898 static int s5p_jpeg_probe(struct platform_device
*pdev
)
2900 struct s5p_jpeg
*jpeg
;
2901 struct resource
*res
;
2904 /* JPEG IP abstraction struct */
2905 jpeg
= devm_kzalloc(&pdev
->dev
, sizeof(struct s5p_jpeg
), GFP_KERNEL
);
2909 jpeg
->variant
= jpeg_get_drv_data(&pdev
->dev
);
2911 mutex_init(&jpeg
->lock
);
2912 spin_lock_init(&jpeg
->slock
);
2913 jpeg
->dev
= &pdev
->dev
;
2915 /* memory-mapped registers */
2916 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
2918 jpeg
->regs
= devm_ioremap_resource(&pdev
->dev
, res
);
2919 if (IS_ERR(jpeg
->regs
))
2920 return PTR_ERR(jpeg
->regs
);
2922 /* interrupt service routine registration */
2923 jpeg
->irq
= ret
= platform_get_irq(pdev
, 0);
2925 dev_err(&pdev
->dev
, "cannot find IRQ\n");
2929 ret
= devm_request_irq(&pdev
->dev
, jpeg
->irq
, jpeg
->variant
->jpeg_irq
,
2930 0, dev_name(&pdev
->dev
), jpeg
);
2932 dev_err(&pdev
->dev
, "cannot claim IRQ %d\n", jpeg
->irq
);
2937 for (i
= 0; i
< jpeg
->variant
->num_clocks
; i
++) {
2938 jpeg
->clocks
[i
] = devm_clk_get(&pdev
->dev
,
2939 jpeg
->variant
->clk_names
[i
]);
2940 if (IS_ERR(jpeg
->clocks
[i
])) {
2941 dev_err(&pdev
->dev
, "failed to get clock: %s\n",
2942 jpeg
->variant
->clk_names
[i
]);
2943 return PTR_ERR(jpeg
->clocks
[i
]);
2948 ret
= v4l2_device_register(&pdev
->dev
, &jpeg
->v4l2_dev
);
2950 dev_err(&pdev
->dev
, "Failed to register v4l2 device\n");
2954 /* mem2mem device */
2955 jpeg
->m2m_dev
= v4l2_m2m_init(jpeg
->variant
->m2m_ops
);
2956 if (IS_ERR(jpeg
->m2m_dev
)) {
2957 v4l2_err(&jpeg
->v4l2_dev
, "Failed to init mem2mem device\n");
2958 ret
= PTR_ERR(jpeg
->m2m_dev
);
2959 goto device_register_rollback
;
2962 vb2_dma_contig_set_max_seg_size(&pdev
->dev
, DMA_BIT_MASK(32));
2964 /* JPEG encoder /dev/videoX node */
2965 jpeg
->vfd_encoder
= video_device_alloc();
2966 if (!jpeg
->vfd_encoder
) {
2967 v4l2_err(&jpeg
->v4l2_dev
, "Failed to allocate video device\n");
2969 goto m2m_init_rollback
;
2971 snprintf(jpeg
->vfd_encoder
->name
, sizeof(jpeg
->vfd_encoder
->name
),
2972 "%s-enc", S5P_JPEG_M2M_NAME
);
2973 jpeg
->vfd_encoder
->fops
= &s5p_jpeg_fops
;
2974 jpeg
->vfd_encoder
->ioctl_ops
= &s5p_jpeg_ioctl_ops
;
2975 jpeg
->vfd_encoder
->minor
= -1;
2976 jpeg
->vfd_encoder
->release
= video_device_release
;
2977 jpeg
->vfd_encoder
->lock
= &jpeg
->lock
;
2978 jpeg
->vfd_encoder
->v4l2_dev
= &jpeg
->v4l2_dev
;
2979 jpeg
->vfd_encoder
->vfl_dir
= VFL_DIR_M2M
;
2981 ret
= video_register_device(jpeg
->vfd_encoder
, VFL_TYPE_GRABBER
, -1);
2983 v4l2_err(&jpeg
->v4l2_dev
, "Failed to register video device\n");
2984 video_device_release(jpeg
->vfd_encoder
);
2985 goto m2m_init_rollback
;
2988 video_set_drvdata(jpeg
->vfd_encoder
, jpeg
);
2989 v4l2_info(&jpeg
->v4l2_dev
,
2990 "encoder device registered as /dev/video%d\n",
2991 jpeg
->vfd_encoder
->num
);
2993 /* JPEG decoder /dev/videoX node */
2994 jpeg
->vfd_decoder
= video_device_alloc();
2995 if (!jpeg
->vfd_decoder
) {
2996 v4l2_err(&jpeg
->v4l2_dev
, "Failed to allocate video device\n");
2998 goto enc_vdev_register_rollback
;
3000 snprintf(jpeg
->vfd_decoder
->name
, sizeof(jpeg
->vfd_decoder
->name
),
3001 "%s-dec", S5P_JPEG_M2M_NAME
);
3002 jpeg
->vfd_decoder
->fops
= &s5p_jpeg_fops
;
3003 jpeg
->vfd_decoder
->ioctl_ops
= &s5p_jpeg_ioctl_ops
;
3004 jpeg
->vfd_decoder
->minor
= -1;
3005 jpeg
->vfd_decoder
->release
= video_device_release
;
3006 jpeg
->vfd_decoder
->lock
= &jpeg
->lock
;
3007 jpeg
->vfd_decoder
->v4l2_dev
= &jpeg
->v4l2_dev
;
3008 jpeg
->vfd_decoder
->vfl_dir
= VFL_DIR_M2M
;
3010 ret
= video_register_device(jpeg
->vfd_decoder
, VFL_TYPE_GRABBER
, -1);
3012 v4l2_err(&jpeg
->v4l2_dev
, "Failed to register video device\n");
3013 video_device_release(jpeg
->vfd_decoder
);
3014 goto enc_vdev_register_rollback
;
3017 video_set_drvdata(jpeg
->vfd_decoder
, jpeg
);
3018 v4l2_info(&jpeg
->v4l2_dev
,
3019 "decoder device registered as /dev/video%d\n",
3020 jpeg
->vfd_decoder
->num
);
3022 /* final statements & power management */
3023 platform_set_drvdata(pdev
, jpeg
);
3025 pm_runtime_enable(&pdev
->dev
);
3027 v4l2_info(&jpeg
->v4l2_dev
, "Samsung S5P JPEG codec\n");
3031 enc_vdev_register_rollback
:
3032 video_unregister_device(jpeg
->vfd_encoder
);
3035 v4l2_m2m_release(jpeg
->m2m_dev
);
3037 device_register_rollback
:
3038 v4l2_device_unregister(&jpeg
->v4l2_dev
);
3043 static int s5p_jpeg_remove(struct platform_device
*pdev
)
3045 struct s5p_jpeg
*jpeg
= platform_get_drvdata(pdev
);
3048 pm_runtime_disable(jpeg
->dev
);
3050 video_unregister_device(jpeg
->vfd_decoder
);
3051 video_unregister_device(jpeg
->vfd_encoder
);
3052 vb2_dma_contig_clear_max_seg_size(&pdev
->dev
);
3053 v4l2_m2m_release(jpeg
->m2m_dev
);
3054 v4l2_device_unregister(&jpeg
->v4l2_dev
);
3056 if (!pm_runtime_status_suspended(&pdev
->dev
)) {
3057 for (i
= jpeg
->variant
->num_clocks
- 1; i
>= 0; i
--)
3058 clk_disable_unprepare(jpeg
->clocks
[i
]);
3065 static int s5p_jpeg_runtime_suspend(struct device
*dev
)
3067 struct s5p_jpeg
*jpeg
= dev_get_drvdata(dev
);
3070 for (i
= jpeg
->variant
->num_clocks
- 1; i
>= 0; i
--)
3071 clk_disable_unprepare(jpeg
->clocks
[i
]);
3076 static int s5p_jpeg_runtime_resume(struct device
*dev
)
3078 struct s5p_jpeg
*jpeg
= dev_get_drvdata(dev
);
3079 unsigned long flags
;
3082 for (i
= 0; i
< jpeg
->variant
->num_clocks
; i
++) {
3083 ret
= clk_prepare_enable(jpeg
->clocks
[i
]);
3086 clk_disable_unprepare(jpeg
->clocks
[i
]);
3091 spin_lock_irqsave(&jpeg
->slock
, flags
);
3094 * JPEG IP allows storing two Huffman tables for each component.
3095 * We fill table 0 for each component and do this here only
3096 * for S5PC210 and Exynos3250 SoCs. Exynos4x12 and Exynos542x SoC
3097 * require programming their Huffman tables each time the encoding
3098 * process is initialized, and thus it is accomplished in the
3099 * device_run callback of m2m_ops.
3101 if (!jpeg
->variant
->htbl_reinit
) {
3102 s5p_jpeg_set_hdctbl(jpeg
->regs
);
3103 s5p_jpeg_set_hdctblg(jpeg
->regs
);
3104 s5p_jpeg_set_hactbl(jpeg
->regs
);
3105 s5p_jpeg_set_hactblg(jpeg
->regs
);
3108 spin_unlock_irqrestore(&jpeg
->slock
, flags
);
3112 #endif /* CONFIG_PM */
3114 static const struct dev_pm_ops s5p_jpeg_pm_ops
= {
3115 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend
,
3116 pm_runtime_force_resume
)
3117 SET_RUNTIME_PM_OPS(s5p_jpeg_runtime_suspend
, s5p_jpeg_runtime_resume
,
3121 static struct s5p_jpeg_variant s5p_jpeg_drvdata
= {
3122 .version
= SJPEG_S5P
,
3123 .jpeg_irq
= s5p_jpeg_irq
,
3124 .m2m_ops
= &s5p_jpeg_m2m_ops
,
3125 .fmt_ver_flag
= SJPEG_FMT_FLAG_S5P
,
3126 .clk_names
= {"jpeg"},
3130 static struct s5p_jpeg_variant exynos3250_jpeg_drvdata
= {
3131 .version
= SJPEG_EXYNOS3250
,
3132 .jpeg_irq
= exynos3250_jpeg_irq
,
3133 .m2m_ops
= &exynos3250_jpeg_m2m_ops
,
3134 .fmt_ver_flag
= SJPEG_FMT_FLAG_EXYNOS3250
,
3136 .clk_names
= {"jpeg", "sclk"},
3140 static struct s5p_jpeg_variant exynos4_jpeg_drvdata
= {
3141 .version
= SJPEG_EXYNOS4
,
3142 .jpeg_irq
= exynos4_jpeg_irq
,
3143 .m2m_ops
= &exynos4_jpeg_m2m_ops
,
3144 .fmt_ver_flag
= SJPEG_FMT_FLAG_EXYNOS4
,
3146 .clk_names
= {"jpeg"},
3151 static struct s5p_jpeg_variant exynos5420_jpeg_drvdata
= {
3152 .version
= SJPEG_EXYNOS5420
,
3153 .jpeg_irq
= exynos3250_jpeg_irq
, /* intentionally 3250 */
3154 .m2m_ops
= &exynos3250_jpeg_m2m_ops
, /* intentionally 3250 */
3155 .fmt_ver_flag
= SJPEG_FMT_FLAG_EXYNOS3250
, /* intentionally 3250 */
3158 .clk_names
= {"jpeg"},
3162 static struct s5p_jpeg_variant exynos5433_jpeg_drvdata
= {
3163 .version
= SJPEG_EXYNOS5433
,
3164 .jpeg_irq
= exynos4_jpeg_irq
,
3165 .m2m_ops
= &exynos4_jpeg_m2m_ops
,
3166 .fmt_ver_flag
= SJPEG_FMT_FLAG_EXYNOS4
,
3168 .clk_names
= {"pclk", "aclk", "aclk_xiu", "sclk"},
3173 static const struct of_device_id samsung_jpeg_match
[] = {
3175 .compatible
= "samsung,s5pv210-jpeg",
3176 .data
= &s5p_jpeg_drvdata
,
3178 .compatible
= "samsung,exynos3250-jpeg",
3179 .data
= &exynos3250_jpeg_drvdata
,
3181 .compatible
= "samsung,exynos4210-jpeg",
3182 .data
= &exynos4_jpeg_drvdata
,
3184 .compatible
= "samsung,exynos4212-jpeg",
3185 .data
= &exynos4_jpeg_drvdata
,
3187 .compatible
= "samsung,exynos5420-jpeg",
3188 .data
= &exynos5420_jpeg_drvdata
,
3190 .compatible
= "samsung,exynos5433-jpeg",
3191 .data
= &exynos5433_jpeg_drvdata
,
3196 MODULE_DEVICE_TABLE(of
, samsung_jpeg_match
);
3198 static void *jpeg_get_drv_data(struct device
*dev
)
3200 struct s5p_jpeg_variant
*driver_data
= NULL
;
3201 const struct of_device_id
*match
;
3203 if (!IS_ENABLED(CONFIG_OF
) || !dev
->of_node
)
3204 return &s5p_jpeg_drvdata
;
3206 match
= of_match_node(samsung_jpeg_match
, dev
->of_node
);
3209 driver_data
= (struct s5p_jpeg_variant
*)match
->data
;
3214 static struct platform_driver s5p_jpeg_driver
= {
3215 .probe
= s5p_jpeg_probe
,
3216 .remove
= s5p_jpeg_remove
,
3218 .of_match_table
= of_match_ptr(samsung_jpeg_match
),
3219 .name
= S5P_JPEG_M2M_NAME
,
3220 .pm
= &s5p_jpeg_pm_ops
,
3224 module_platform_driver(s5p_jpeg_driver
);
3226 MODULE_AUTHOR("Andrzej Pietrasiewicz <andrzej.p@samsung.com>");
3227 MODULE_AUTHOR("Jacek Anaszewski <j.anaszewski@samsung.com>");
3228 MODULE_DESCRIPTION("Samsung JPEG codec driver");
3229 MODULE_LICENSE("GPL");