diff options
author | Jacek Anaszewski <j.anaszewski@samsung.com> | 2014-07-11 11:19:42 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <m.chehab@samsung.com> | 2014-07-30 18:15:06 -0400 |
commit | 3246fdaa0ac2d936b1838589b76fd5aaff02e46d (patch) | |
tree | 4fb9ead2b7950a0cb335974b6ed2e475842ceff3 /drivers/media | |
parent | 1774afe7d98d8cfcb57327d2ced2d95c48de8c72 (diff) |
[media] s5p-jpeg: Add support for Exynos3250 SoC
This patch adds support for jpeg codec on Exynos3250 SoC to
the s5p-jpeg driver. Supported raw formats are: YUYV, YVYU, UYVY,
VYUY, RGB565, RGB565X, RGB32, NV12, NV21. The support includes
also scaling and cropping features.
Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/platform/Kconfig | 5 | ||||
-rw-r--r-- | drivers/media/platform/s5p-jpeg/Makefile | 2 | ||||
-rw-r--r-- | drivers/media/platform/s5p-jpeg/jpeg-core.c | 527 | ||||
-rw-r--r-- | drivers/media/platform/s5p-jpeg/jpeg-core.h | 32 | ||||
-rw-r--r-- | drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c | 487 | ||||
-rw-r--r-- | drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h | 60 | ||||
-rw-r--r-- | drivers/media/platform/s5p-jpeg/jpeg-regs.h | 247 |
7 files changed, 1338 insertions, 22 deletions
diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 433f0bf2ed60..6d86646d9743 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig | |||
@@ -167,12 +167,13 @@ config VIDEO_SAMSUNG_S5P_G2D | |||
167 | 2d graphics accelerator. | 167 | 2d graphics accelerator. |
168 | 168 | ||
169 | config VIDEO_SAMSUNG_S5P_JPEG | 169 | config VIDEO_SAMSUNG_S5P_JPEG |
170 | tristate "Samsung S5P/Exynos4 JPEG codec driver" | 170 | tristate "Samsung S5P/Exynos3250/Exynos4 JPEG codec driver" |
171 | depends on VIDEO_DEV && VIDEO_V4L2 && (PLAT_S5P || ARCH_EXYNOS) | 171 | depends on VIDEO_DEV && VIDEO_V4L2 && (PLAT_S5P || ARCH_EXYNOS) |
172 | select VIDEOBUF2_DMA_CONTIG | 172 | select VIDEOBUF2_DMA_CONTIG |
173 | select V4L2_MEM2MEM_DEV | 173 | select V4L2_MEM2MEM_DEV |
174 | ---help--- | 174 | ---help--- |
175 | This is a v4l2 driver for Samsung S5P and EXYNOS4 JPEG codec | 175 | This is a v4l2 driver for Samsung S5P, EXYNOS3250 |
176 | and EXYNOS4 JPEG codec | ||
176 | 177 | ||
177 | config VIDEO_SAMSUNG_S5P_MFC | 178 | config VIDEO_SAMSUNG_S5P_MFC |
178 | tristate "Samsung S5P MFC Video Codec" | 179 | tristate "Samsung S5P MFC Video Codec" |
diff --git a/drivers/media/platform/s5p-jpeg/Makefile b/drivers/media/platform/s5p-jpeg/Makefile index a1a9169254c3..9e5f214c4667 100644 --- a/drivers/media/platform/s5p-jpeg/Makefile +++ b/drivers/media/platform/s5p-jpeg/Makefile | |||
@@ -1,2 +1,2 @@ | |||
1 | s5p-jpeg-objs := jpeg-core.o jpeg-hw-exynos4.o jpeg-hw-s5p.o | 1 | s5p-jpeg-objs := jpeg-core.o jpeg-hw-exynos3250.o jpeg-hw-exynos4.o jpeg-hw-s5p.o |
2 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg.o | 2 | obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg.o |
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.c b/drivers/media/platform/s5p-jpeg/jpeg-core.c index 0dcb796ecad9..126199e010c7 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.c +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c | 1 | /* linux/drivers/media/platform/s5p-jpeg/jpeg-core.c |
2 | * | 2 | * |
3 | * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. | 3 | * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. |
4 | * http://www.samsung.com | 4 | * http://www.samsung.com |
5 | * | 5 | * |
6 | * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> | 6 | * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> |
@@ -32,6 +32,7 @@ | |||
32 | #include "jpeg-core.h" | 32 | #include "jpeg-core.h" |
33 | #include "jpeg-hw-s5p.h" | 33 | #include "jpeg-hw-s5p.h" |
34 | #include "jpeg-hw-exynos4.h" | 34 | #include "jpeg-hw-exynos4.h" |
35 | #include "jpeg-hw-exynos3250.h" | ||
35 | #include "jpeg-regs.h" | 36 | #include "jpeg-regs.h" |
36 | 37 | ||
37 | static struct s5p_jpeg_fmt sjpeg_formats[] = { | 38 | static struct s5p_jpeg_fmt sjpeg_formats[] = { |
@@ -41,6 +42,7 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { | |||
41 | .flags = SJPEG_FMT_FLAG_ENC_CAPTURE | | 42 | .flags = SJPEG_FMT_FLAG_ENC_CAPTURE | |
42 | SJPEG_FMT_FLAG_DEC_OUTPUT | | 43 | SJPEG_FMT_FLAG_DEC_OUTPUT | |
43 | SJPEG_FMT_FLAG_S5P | | 44 | SJPEG_FMT_FLAG_S5P | |
45 | SJPEG_FMT_FLAG_EXYNOS3250 | | ||
44 | SJPEG_FMT_FLAG_EXYNOS4, | 46 | SJPEG_FMT_FLAG_EXYNOS4, |
45 | }, | 47 | }, |
46 | { | 48 | { |
@@ -70,6 +72,19 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { | |||
70 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, | 72 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, |
71 | }, | 73 | }, |
72 | { | 74 | { |
75 | .name = "YUV 4:2:2 packed, YCbYCr", | ||
76 | .fourcc = V4L2_PIX_FMT_YUYV, | ||
77 | .depth = 16, | ||
78 | .colplanes = 1, | ||
79 | .h_align = 2, | ||
80 | .v_align = 0, | ||
81 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | | ||
82 | SJPEG_FMT_FLAG_DEC_CAPTURE | | ||
83 | SJPEG_FMT_FLAG_EXYNOS3250 | | ||
84 | SJPEG_FMT_NON_RGB, | ||
85 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, | ||
86 | }, | ||
87 | { | ||
73 | .name = "YUV 4:2:2 packed, YCrYCb", | 88 | .name = "YUV 4:2:2 packed, YCrYCb", |
74 | .fourcc = V4L2_PIX_FMT_YVYU, | 89 | .fourcc = V4L2_PIX_FMT_YVYU, |
75 | .depth = 16, | 90 | .depth = 16, |
@@ -83,6 +98,45 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { | |||
83 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, | 98 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, |
84 | }, | 99 | }, |
85 | { | 100 | { |
101 | .name = "YUV 4:2:2 packed, YCrYCb", | ||
102 | .fourcc = V4L2_PIX_FMT_YVYU, | ||
103 | .depth = 16, | ||
104 | .colplanes = 1, | ||
105 | .h_align = 2, | ||
106 | .v_align = 0, | ||
107 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | | ||
108 | SJPEG_FMT_FLAG_DEC_CAPTURE | | ||
109 | SJPEG_FMT_FLAG_EXYNOS3250 | | ||
110 | SJPEG_FMT_NON_RGB, | ||
111 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, | ||
112 | }, | ||
113 | { | ||
114 | .name = "YUV 4:2:2 packed, YCrYCb", | ||
115 | .fourcc = V4L2_PIX_FMT_UYVY, | ||
116 | .depth = 16, | ||
117 | .colplanes = 1, | ||
118 | .h_align = 2, | ||
119 | .v_align = 0, | ||
120 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | | ||
121 | SJPEG_FMT_FLAG_DEC_CAPTURE | | ||
122 | SJPEG_FMT_FLAG_EXYNOS3250 | | ||
123 | SJPEG_FMT_NON_RGB, | ||
124 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, | ||
125 | }, | ||
126 | { | ||
127 | .name = "YUV 4:2:2 packed, YCrYCb", | ||
128 | .fourcc = V4L2_PIX_FMT_VYUY, | ||
129 | .depth = 16, | ||
130 | .colplanes = 1, | ||
131 | .h_align = 2, | ||
132 | .v_align = 0, | ||
133 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | | ||
134 | SJPEG_FMT_FLAG_DEC_CAPTURE | | ||
135 | SJPEG_FMT_FLAG_EXYNOS3250 | | ||
136 | SJPEG_FMT_NON_RGB, | ||
137 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, | ||
138 | }, | ||
139 | { | ||
86 | .name = "RGB565", | 140 | .name = "RGB565", |
87 | .fourcc = V4L2_PIX_FMT_RGB565, | 141 | .fourcc = V4L2_PIX_FMT_RGB565, |
88 | .depth = 16, | 142 | .depth = 16, |
@@ -100,6 +154,32 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { | |||
100 | .fourcc = V4L2_PIX_FMT_RGB565, | 154 | .fourcc = V4L2_PIX_FMT_RGB565, |
101 | .depth = 16, | 155 | .depth = 16, |
102 | .colplanes = 1, | 156 | .colplanes = 1, |
157 | .h_align = 2, | ||
158 | .v_align = 0, | ||
159 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | | ||
160 | SJPEG_FMT_FLAG_DEC_CAPTURE | | ||
161 | SJPEG_FMT_FLAG_EXYNOS3250 | | ||
162 | SJPEG_FMT_RGB, | ||
163 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, | ||
164 | }, | ||
165 | { | ||
166 | .name = "RGB565X", | ||
167 | .fourcc = V4L2_PIX_FMT_RGB565X, | ||
168 | .depth = 16, | ||
169 | .colplanes = 1, | ||
170 | .h_align = 2, | ||
171 | .v_align = 0, | ||
172 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | | ||
173 | SJPEG_FMT_FLAG_DEC_CAPTURE | | ||
174 | SJPEG_FMT_FLAG_EXYNOS3250 | | ||
175 | SJPEG_FMT_RGB, | ||
176 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, | ||
177 | }, | ||
178 | { | ||
179 | .name = "RGB565", | ||
180 | .fourcc = V4L2_PIX_FMT_RGB565, | ||
181 | .depth = 16, | ||
182 | .colplanes = 1, | ||
103 | .h_align = 0, | 183 | .h_align = 0, |
104 | .v_align = 0, | 184 | .v_align = 0, |
105 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | | 185 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | |
@@ -121,6 +201,19 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { | |||
121 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, | 201 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, |
122 | }, | 202 | }, |
123 | { | 203 | { |
204 | .name = "ARGB8888, 32 bpp", | ||
205 | .fourcc = V4L2_PIX_FMT_RGB32, | ||
206 | .depth = 32, | ||
207 | .colplanes = 1, | ||
208 | .h_align = 2, | ||
209 | .v_align = 0, | ||
210 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | | ||
211 | SJPEG_FMT_FLAG_DEC_CAPTURE | | ||
212 | SJPEG_FMT_FLAG_EXYNOS3250 | | ||
213 | SJPEG_FMT_RGB, | ||
214 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, | ||
215 | }, | ||
216 | { | ||
124 | .name = "YUV 4:4:4 planar, Y/CbCr", | 217 | .name = "YUV 4:4:4 planar, Y/CbCr", |
125 | .fourcc = V4L2_PIX_FMT_NV24, | 218 | .fourcc = V4L2_PIX_FMT_NV24, |
126 | .depth = 24, | 219 | .depth = 24, |
@@ -190,9 +283,23 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { | |||
190 | .fourcc = V4L2_PIX_FMT_NV12, | 283 | .fourcc = V4L2_PIX_FMT_NV12, |
191 | .depth = 12, | 284 | .depth = 12, |
192 | .colplanes = 2, | 285 | .colplanes = 2, |
286 | .h_align = 3, | ||
287 | .v_align = 3, | ||
288 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | | ||
289 | SJPEG_FMT_FLAG_DEC_CAPTURE | | ||
290 | SJPEG_FMT_FLAG_EXYNOS3250 | | ||
291 | SJPEG_FMT_NON_RGB, | ||
292 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, | ||
293 | }, | ||
294 | { | ||
295 | .name = "YUV 4:2:0 planar, Y/CbCr", | ||
296 | .fourcc = V4L2_PIX_FMT_NV12, | ||
297 | .depth = 12, | ||
298 | .colplanes = 2, | ||
193 | .h_align = 4, | 299 | .h_align = 4, |
194 | .v_align = 4, | 300 | .v_align = 4, |
195 | .flags = SJPEG_FMT_FLAG_DEC_CAPTURE | | 301 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | |
302 | SJPEG_FMT_FLAG_DEC_CAPTURE | | ||
196 | SJPEG_FMT_FLAG_S5P | | 303 | SJPEG_FMT_FLAG_S5P | |
197 | SJPEG_FMT_NON_RGB, | 304 | SJPEG_FMT_NON_RGB, |
198 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, | 305 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, |
@@ -202,10 +309,24 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { | |||
202 | .fourcc = V4L2_PIX_FMT_NV21, | 309 | .fourcc = V4L2_PIX_FMT_NV21, |
203 | .depth = 12, | 310 | .depth = 12, |
204 | .colplanes = 2, | 311 | .colplanes = 2, |
312 | .h_align = 3, | ||
313 | .v_align = 3, | ||
314 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | | ||
315 | SJPEG_FMT_FLAG_DEC_CAPTURE | | ||
316 | SJPEG_FMT_FLAG_EXYNOS3250 | | ||
317 | SJPEG_FMT_NON_RGB, | ||
318 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, | ||
319 | }, | ||
320 | { | ||
321 | .name = "YUV 4:2:0 planar, Y/CrCb", | ||
322 | .fourcc = V4L2_PIX_FMT_NV21, | ||
323 | .depth = 12, | ||
324 | .colplanes = 2, | ||
205 | .h_align = 1, | 325 | .h_align = 1, |
206 | .v_align = 1, | 326 | .v_align = 1, |
207 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | | 327 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | |
208 | SJPEG_FMT_FLAG_DEC_CAPTURE | | 328 | SJPEG_FMT_FLAG_DEC_CAPTURE | |
329 | SJPEG_FMT_FLAG_EXYNOS3250 | | ||
209 | SJPEG_FMT_FLAG_EXYNOS4 | | 330 | SJPEG_FMT_FLAG_EXYNOS4 | |
210 | SJPEG_FMT_NON_RGB, | 331 | SJPEG_FMT_NON_RGB, |
211 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, | 332 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, |
@@ -224,6 +345,19 @@ static struct s5p_jpeg_fmt sjpeg_formats[] = { | |||
224 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, | 345 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, |
225 | }, | 346 | }, |
226 | { | 347 | { |
348 | .name = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr", | ||
349 | .fourcc = V4L2_PIX_FMT_YUV420, | ||
350 | .depth = 12, | ||
351 | .colplanes = 3, | ||
352 | .h_align = 4, | ||
353 | .v_align = 4, | ||
354 | .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | | ||
355 | SJPEG_FMT_FLAG_DEC_CAPTURE | | ||
356 | SJPEG_FMT_FLAG_EXYNOS3250 | | ||
357 | SJPEG_FMT_NON_RGB, | ||
358 | .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, | ||
359 | }, | ||
360 | { | ||
227 | .name = "Gray", | 361 | .name = "Gray", |
228 | .fourcc = V4L2_PIX_FMT_GREY, | 362 | .fourcc = V4L2_PIX_FMT_GREY, |
229 | .depth = 8, | 363 | .depth = 8, |
@@ -457,6 +591,16 @@ static int exynos4x12_decoded_subsampling[] = { | |||
457 | V4L2_JPEG_CHROMA_SUBSAMPLING_420, | 591 | V4L2_JPEG_CHROMA_SUBSAMPLING_420, |
458 | }; | 592 | }; |
459 | 593 | ||
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, | ||
599 | -1, | ||
600 | -1, | ||
601 | V4L2_JPEG_CHROMA_SUBSAMPLING_411, | ||
602 | }; | ||
603 | |||
460 | static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c) | 604 | static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c) |
461 | { | 605 | { |
462 | return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler); | 606 | return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler); |
@@ -471,14 +615,21 @@ static int s5p_jpeg_to_user_subsampling(struct s5p_jpeg_ctx *ctx) | |||
471 | { | 615 | { |
472 | WARN_ON(ctx->subsampling > 3); | 616 | WARN_ON(ctx->subsampling > 3); |
473 | 617 | ||
474 | if (ctx->jpeg->variant->version == SJPEG_S5P) { | 618 | switch (ctx->jpeg->variant->version) { |
619 | case SJPEG_S5P: | ||
475 | if (ctx->subsampling > 2) | 620 | if (ctx->subsampling > 2) |
476 | return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; | 621 | return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; |
477 | return ctx->subsampling; | 622 | return ctx->subsampling; |
478 | } else { | 623 | case SJPEG_EXYNOS3250: |
624 | if (ctx->subsampling > 3) | ||
625 | return V4L2_JPEG_CHROMA_SUBSAMPLING_411; | ||
626 | return exynos3250_decoded_subsampling[ctx->subsampling]; | ||
627 | case SJPEG_EXYNOS4: | ||
479 | if (ctx->subsampling > 2) | 628 | if (ctx->subsampling > 2) |
480 | return V4L2_JPEG_CHROMA_SUBSAMPLING_420; | 629 | return V4L2_JPEG_CHROMA_SUBSAMPLING_420; |
481 | return exynos4x12_decoded_subsampling[ctx->subsampling]; | 630 | return exynos4x12_decoded_subsampling[ctx->subsampling]; |
631 | default: | ||
632 | return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; | ||
482 | } | 633 | } |
483 | } | 634 | } |
484 | 635 | ||
@@ -646,6 +797,7 @@ static int s5p_jpeg_open(struct file *file) | |||
646 | FMT_TYPE_OUTPUT); | 797 | FMT_TYPE_OUTPUT); |
647 | cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV, | 798 | cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV, |
648 | FMT_TYPE_CAPTURE); | 799 | FMT_TYPE_CAPTURE); |
800 | ctx->scale_factor = EXYNOS3250_DEC_SCALE_FACTOR_8_8; | ||
649 | } | 801 | } |
650 | 802 | ||
651 | ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init); | 803 | ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init); |
@@ -1229,6 +1381,101 @@ static int s5p_jpeg_s_fmt_vid_out(struct file *file, void *priv, | |||
1229 | return s5p_jpeg_s_fmt(fh_to_ctx(priv), f); | 1381 | return s5p_jpeg_s_fmt(fh_to_ctx(priv), f); |
1230 | } | 1382 | } |
1231 | 1383 | ||
1384 | static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx, | ||
1385 | struct v4l2_rect *r) | ||
1386 | { | ||
1387 | int w_ratio, h_ratio, scale_factor, cur_ratio, i; | ||
1388 | |||
1389 | w_ratio = ctx->out_q.w / r->width; | ||
1390 | h_ratio = ctx->out_q.h / r->height; | ||
1391 | |||
1392 | scale_factor = w_ratio > h_ratio ? w_ratio : h_ratio; | ||
1393 | scale_factor = clamp_val(scale_factor, 1, 8); | ||
1394 | |||
1395 | /* Align scale ratio to the nearest power of 2 */ | ||
1396 | for (i = 0; i <= 3; ++i) { | ||
1397 | cur_ratio = 1 << i; | ||
1398 | if (scale_factor <= cur_ratio) { | ||
1399 | ctx->scale_factor = cur_ratio; | ||
1400 | break; | ||
1401 | } | ||
1402 | } | ||
1403 | |||
1404 | r->width = round_down(ctx->out_q.w / ctx->scale_factor, 2); | ||
1405 | r->height = round_down(ctx->out_q.h / ctx->scale_factor, 2); | ||
1406 | |||
1407 | ctx->crop_rect.width = r->width; | ||
1408 | ctx->crop_rect.height = r->height; | ||
1409 | ctx->crop_rect.left = 0; | ||
1410 | ctx->crop_rect.top = 0; | ||
1411 | |||
1412 | ctx->crop_altered = true; | ||
1413 | |||
1414 | return 0; | ||
1415 | } | ||
1416 | |||
1417 | /* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */ | ||
1418 | static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b) | ||
1419 | { | ||
1420 | if (a->left < b->left || a->top < b->top) | ||
1421 | return 0; | ||
1422 | if (a->left + a->width > b->left + b->width) | ||
1423 | return 0; | ||
1424 | if (a->top + a->height > b->top + b->height) | ||
1425 | return 0; | ||
1426 | |||
1427 | return 1; | ||
1428 | } | ||
1429 | |||
1430 | static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx, | ||
1431 | struct v4l2_rect *r) | ||
1432 | { | ||
1433 | struct v4l2_rect base_rect; | ||
1434 | int w_step, h_step; | ||
1435 | |||
1436 | switch (ctx->cap_q.fmt->fourcc) { | ||
1437 | case V4L2_PIX_FMT_NV12: | ||
1438 | case V4L2_PIX_FMT_NV21: | ||
1439 | w_step = 1; | ||
1440 | h_step = 2; | ||
1441 | break; | ||
1442 | case V4L2_PIX_FMT_YUV420: | ||
1443 | w_step = 2; | ||
1444 | h_step = 2; | ||
1445 | break; | ||
1446 | default: | ||
1447 | w_step = 1; | ||
1448 | h_step = 1; | ||
1449 | break; | ||
1450 | } | ||
1451 | |||
1452 | base_rect.top = 0; | ||
1453 | base_rect.left = 0; | ||
1454 | base_rect.width = ctx->out_q.w; | ||
1455 | base_rect.height = ctx->out_q.h; | ||
1456 | |||
1457 | r->width = round_down(r->width, w_step); | ||
1458 | r->height = round_down(r->height, h_step); | ||
1459 | r->left = round_down(r->left, 2); | ||
1460 | r->top = round_down(r->top, 2); | ||
1461 | |||
1462 | if (!enclosed_rectangle(r, &base_rect)) | ||
1463 | return -EINVAL; | ||
1464 | |||
1465 | ctx->crop_rect.left = r->left; | ||
1466 | ctx->crop_rect.top = r->top; | ||
1467 | ctx->crop_rect.width = r->width; | ||
1468 | ctx->crop_rect.height = r->height; | ||
1469 | |||
1470 | ctx->crop_altered = true; | ||
1471 | |||
1472 | return 0; | ||
1473 | } | ||
1474 | |||
1475 | /* | ||
1476 | * V4L2 controls | ||
1477 | */ | ||
1478 | |||
1232 | static int s5p_jpeg_g_selection(struct file *file, void *priv, | 1479 | static int s5p_jpeg_g_selection(struct file *file, void *priv, |
1233 | struct v4l2_selection *s) | 1480 | struct v4l2_selection *s) |
1234 | { | 1481 | { |
@@ -1264,6 +1511,30 @@ static int s5p_jpeg_g_selection(struct file *file, void *priv, | |||
1264 | /* | 1511 | /* |
1265 | * V4L2 controls | 1512 | * V4L2 controls |
1266 | */ | 1513 | */ |
1514 | static int s5p_jpeg_s_selection(struct file *file, void *fh, | ||
1515 | struct v4l2_selection *s) | ||
1516 | { | ||
1517 | struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data); | ||
1518 | struct v4l2_rect *rect = &s->r; | ||
1519 | int ret = -EINVAL; | ||
1520 | |||
1521 | if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1522 | return -EINVAL; | ||
1523 | |||
1524 | if (s->target == V4L2_SEL_TGT_COMPOSE) { | ||
1525 | if (ctx->mode != S5P_JPEG_DECODE) | ||
1526 | return -EINVAL; | ||
1527 | if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250) | ||
1528 | ret = exynos3250_jpeg_try_downscale(ctx, rect); | ||
1529 | } else if (s->target == V4L2_SEL_TGT_CROP) { | ||
1530 | if (ctx->mode != S5P_JPEG_ENCODE) | ||
1531 | return -EINVAL; | ||
1532 | if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250) | ||
1533 | ret = exynos3250_jpeg_try_crop(ctx, rect); | ||
1534 | } | ||
1535 | |||
1536 | return ret; | ||
1537 | } | ||
1267 | 1538 | ||
1268 | static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl) | 1539 | static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl) |
1269 | { | 1540 | { |
@@ -1414,6 +1685,7 @@ static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = { | |||
1414 | .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, | 1685 | .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, |
1415 | 1686 | ||
1416 | .vidioc_g_selection = s5p_jpeg_g_selection, | 1687 | .vidioc_g_selection = s5p_jpeg_g_selection, |
1688 | .vidioc_s_selection = s5p_jpeg_s_selection, | ||
1417 | }; | 1689 | }; |
1418 | 1690 | ||
1419 | /* | 1691 | /* |
@@ -1604,6 +1876,135 @@ static void exynos4_jpeg_device_run(void *priv) | |||
1604 | spin_unlock_irqrestore(&ctx->jpeg->slock, flags); | 1876 | spin_unlock_irqrestore(&ctx->jpeg->slock, flags); |
1605 | } | 1877 | } |
1606 | 1878 | ||
1879 | static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx) | ||
1880 | { | ||
1881 | struct s5p_jpeg *jpeg = ctx->jpeg; | ||
1882 | struct s5p_jpeg_fmt *fmt; | ||
1883 | struct vb2_buffer *vb; | ||
1884 | struct s5p_jpeg_addr jpeg_addr; | ||
1885 | u32 pix_size; | ||
1886 | |||
1887 | pix_size = ctx->cap_q.w * ctx->cap_q.h; | ||
1888 | |||
1889 | if (ctx->mode == S5P_JPEG_ENCODE) { | ||
1890 | vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); | ||
1891 | fmt = ctx->out_q.fmt; | ||
1892 | } else { | ||
1893 | vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); | ||
1894 | fmt = ctx->cap_q.fmt; | ||
1895 | } | ||
1896 | |||
1897 | jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0); | ||
1898 | |||
1899 | if (fmt->colplanes == 2) { | ||
1900 | jpeg_addr.cb = jpeg_addr.y + pix_size; | ||
1901 | } else if (fmt->colplanes == 3) { | ||
1902 | jpeg_addr.cb = jpeg_addr.y + pix_size; | ||
1903 | if (fmt->fourcc == V4L2_PIX_FMT_YUV420) | ||
1904 | jpeg_addr.cr = jpeg_addr.cb + pix_size / 4; | ||
1905 | else | ||
1906 | jpeg_addr.cr = jpeg_addr.cb + pix_size / 2; | ||
1907 | } | ||
1908 | |||
1909 | exynos3250_jpeg_imgadr(jpeg->regs, &jpeg_addr); | ||
1910 | } | ||
1911 | |||
1912 | static void exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx) | ||
1913 | { | ||
1914 | struct s5p_jpeg *jpeg = ctx->jpeg; | ||
1915 | struct vb2_buffer *vb; | ||
1916 | unsigned int jpeg_addr = 0; | ||
1917 | |||
1918 | if (ctx->mode == S5P_JPEG_ENCODE) | ||
1919 | vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); | ||
1920 | else | ||
1921 | vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); | ||
1922 | |||
1923 | jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0); | ||
1924 | exynos3250_jpeg_jpgadr(jpeg->regs, jpeg_addr); | ||
1925 | } | ||
1926 | |||
1927 | static void exynos3250_jpeg_device_run(void *priv) | ||
1928 | { | ||
1929 | struct s5p_jpeg_ctx *ctx = priv; | ||
1930 | struct s5p_jpeg *jpeg = ctx->jpeg; | ||
1931 | unsigned long flags; | ||
1932 | |||
1933 | spin_lock_irqsave(&ctx->jpeg->slock, flags); | ||
1934 | |||
1935 | exynos3250_jpeg_reset(jpeg->regs); | ||
1936 | exynos3250_jpeg_set_dma_num(jpeg->regs); | ||
1937 | exynos3250_jpeg_poweron(jpeg->regs); | ||
1938 | exynos3250_jpeg_clk_set(jpeg->regs); | ||
1939 | exynos3250_jpeg_proc_mode(jpeg->regs, ctx->mode); | ||
1940 | |||
1941 | if (ctx->mode == S5P_JPEG_ENCODE) { | ||
1942 | exynos3250_jpeg_input_raw_fmt(jpeg->regs, | ||
1943 | ctx->out_q.fmt->fourcc); | ||
1944 | exynos3250_jpeg_dri(jpeg->regs, ctx->restart_interval); | ||
1945 | |||
1946 | /* | ||
1947 | * JPEG IP allows storing 4 quantization tables | ||
1948 | * We fill table 0 for luma and table 1 for chroma | ||
1949 | */ | ||
1950 | s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality); | ||
1951 | s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality); | ||
1952 | /* use table 0 for Y */ | ||
1953 | exynos3250_jpeg_qtbl(jpeg->regs, 1, 0); | ||
1954 | /* use table 1 for Cb and Cr*/ | ||
1955 | exynos3250_jpeg_qtbl(jpeg->regs, 2, 1); | ||
1956 | exynos3250_jpeg_qtbl(jpeg->regs, 3, 1); | ||
1957 | |||
1958 | /* Y, Cb, Cr use Huffman table 0 */ | ||
1959 | exynos3250_jpeg_htbl_ac(jpeg->regs, 1); | ||
1960 | exynos3250_jpeg_htbl_dc(jpeg->regs, 1); | ||
1961 | exynos3250_jpeg_htbl_ac(jpeg->regs, 2); | ||
1962 | exynos3250_jpeg_htbl_dc(jpeg->regs, 2); | ||
1963 | exynos3250_jpeg_htbl_ac(jpeg->regs, 3); | ||
1964 | exynos3250_jpeg_htbl_dc(jpeg->regs, 3); | ||
1965 | |||
1966 | exynos3250_jpeg_set_x(jpeg->regs, ctx->crop_rect.width); | ||
1967 | exynos3250_jpeg_set_y(jpeg->regs, ctx->crop_rect.height); | ||
1968 | exynos3250_jpeg_stride(jpeg->regs, ctx->out_q.fmt->fourcc, | ||
1969 | ctx->out_q.w); | ||
1970 | exynos3250_jpeg_offset(jpeg->regs, ctx->crop_rect.left, | ||
1971 | ctx->crop_rect.top); | ||
1972 | exynos3250_jpeg_set_img_addr(ctx); | ||
1973 | exynos3250_jpeg_set_jpeg_addr(ctx); | ||
1974 | exynos3250_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling); | ||
1975 | |||
1976 | /* ultimately comes from sizeimage from userspace */ | ||
1977 | exynos3250_jpeg_enc_stream_bound(jpeg->regs, ctx->cap_q.size); | ||
1978 | |||
1979 | if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565 || | ||
1980 | ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565X || | ||
1981 | ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32) | ||
1982 | exynos3250_jpeg_set_y16(jpeg->regs, true); | ||
1983 | } else { | ||
1984 | exynos3250_jpeg_set_img_addr(ctx); | ||
1985 | exynos3250_jpeg_set_jpeg_addr(ctx); | ||
1986 | exynos3250_jpeg_stride(jpeg->regs, ctx->cap_q.fmt->fourcc, | ||
1987 | ctx->cap_q.w); | ||
1988 | exynos3250_jpeg_offset(jpeg->regs, 0, 0); | ||
1989 | exynos3250_jpeg_dec_scaling_ratio(jpeg->regs, | ||
1990 | ctx->scale_factor); | ||
1991 | exynos3250_jpeg_dec_stream_size(jpeg->regs, ctx->out_q.size); | ||
1992 | exynos3250_jpeg_output_raw_fmt(jpeg->regs, | ||
1993 | ctx->cap_q.fmt->fourcc); | ||
1994 | } | ||
1995 | |||
1996 | exynos3250_jpeg_interrupts_enable(jpeg->regs); | ||
1997 | |||
1998 | /* JPEG RGB to YCbCr conversion matrix */ | ||
1999 | exynos3250_jpeg_coef(jpeg->regs, ctx->mode); | ||
2000 | |||
2001 | exynos3250_jpeg_set_timer(jpeg->regs, EXYNOS3250_IRQ_TIMEOUT); | ||
2002 | jpeg->irq_status = 0; | ||
2003 | exynos3250_jpeg_start(jpeg->regs); | ||
2004 | |||
2005 | spin_unlock_irqrestore(&ctx->jpeg->slock, flags); | ||
2006 | } | ||
2007 | |||
1607 | static int s5p_jpeg_job_ready(void *priv) | 2008 | static int s5p_jpeg_job_ready(void *priv) |
1608 | { | 2009 | { |
1609 | struct s5p_jpeg_ctx *ctx = priv; | 2010 | struct s5p_jpeg_ctx *ctx = priv; |
@@ -1621,8 +2022,14 @@ static struct v4l2_m2m_ops s5p_jpeg_m2m_ops = { | |||
1621 | .device_run = s5p_jpeg_device_run, | 2022 | .device_run = s5p_jpeg_device_run, |
1622 | .job_ready = s5p_jpeg_job_ready, | 2023 | .job_ready = s5p_jpeg_job_ready, |
1623 | .job_abort = s5p_jpeg_job_abort, | 2024 | .job_abort = s5p_jpeg_job_abort, |
1624 | } | 2025 | }; |
1625 | ; | 2026 | |
2027 | static struct v4l2_m2m_ops exynos3250_jpeg_m2m_ops = { | ||
2028 | .device_run = exynos3250_jpeg_device_run, | ||
2029 | .job_ready = s5p_jpeg_job_ready, | ||
2030 | .job_abort = s5p_jpeg_job_abort, | ||
2031 | }; | ||
2032 | |||
1626 | static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = { | 2033 | static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = { |
1627 | .device_run = exynos4_jpeg_device_run, | 2034 | .device_run = exynos4_jpeg_device_run, |
1628 | .job_ready = s5p_jpeg_job_ready, | 2035 | .job_ready = s5p_jpeg_job_ready, |
@@ -1895,6 +2302,70 @@ static irqreturn_t exynos4_jpeg_irq(int irq, void *priv) | |||
1895 | return IRQ_HANDLED; | 2302 | return IRQ_HANDLED; |
1896 | } | 2303 | } |
1897 | 2304 | ||
2305 | static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id) | ||
2306 | { | ||
2307 | struct s5p_jpeg *jpeg = dev_id; | ||
2308 | struct s5p_jpeg_ctx *curr_ctx; | ||
2309 | struct vb2_buffer *src_buf, *dst_buf; | ||
2310 | unsigned long payload_size = 0; | ||
2311 | enum vb2_buffer_state state = VB2_BUF_STATE_DONE; | ||
2312 | bool interrupt_timeout = false; | ||
2313 | u32 irq_status; | ||
2314 | |||
2315 | spin_lock(&jpeg->slock); | ||
2316 | |||
2317 | irq_status = exynos3250_jpeg_get_timer_status(jpeg->regs); | ||
2318 | if (irq_status & EXYNOS3250_TIMER_INT_STAT) { | ||
2319 | exynos3250_jpeg_clear_timer_status(jpeg->regs); | ||
2320 | interrupt_timeout = true; | ||
2321 | dev_err(jpeg->dev, "Interrupt timeout occurred.\n"); | ||
2322 | } | ||
2323 | |||
2324 | irq_status = exynos3250_jpeg_get_int_status(jpeg->regs); | ||
2325 | exynos3250_jpeg_clear_int_status(jpeg->regs, irq_status); | ||
2326 | |||
2327 | jpeg->irq_status |= irq_status; | ||
2328 | |||
2329 | curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); | ||
2330 | |||
2331 | if (!curr_ctx) | ||
2332 | goto exit_unlock; | ||
2333 | |||
2334 | if ((irq_status & EXYNOS3250_HEADER_STAT) && | ||
2335 | (curr_ctx->mode == S5P_JPEG_DECODE)) { | ||
2336 | exynos3250_jpeg_rstart(jpeg->regs); | ||
2337 | goto exit_unlock; | ||
2338 | } | ||
2339 | |||
2340 | if (jpeg->irq_status & (EXYNOS3250_JPEG_DONE | | ||
2341 | EXYNOS3250_WDMA_DONE | | ||
2342 | EXYNOS3250_RDMA_DONE | | ||
2343 | EXYNOS3250_RESULT_STAT)) | ||
2344 | payload_size = exynos3250_jpeg_compressed_size(jpeg->regs); | ||
2345 | else if (interrupt_timeout) | ||
2346 | state = VB2_BUF_STATE_ERROR; | ||
2347 | else | ||
2348 | goto exit_unlock; | ||
2349 | |||
2350 | src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx); | ||
2351 | dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx); | ||
2352 | |||
2353 | dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode; | ||
2354 | dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp; | ||
2355 | |||
2356 | v4l2_m2m_buf_done(src_buf, state); | ||
2357 | if (curr_ctx->mode == S5P_JPEG_ENCODE) | ||
2358 | vb2_set_plane_payload(dst_buf, 0, payload_size); | ||
2359 | v4l2_m2m_buf_done(dst_buf, state); | ||
2360 | v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); | ||
2361 | |||
2362 | curr_ctx->subsampling = | ||
2363 | exynos3250_jpeg_get_subsampling_mode(jpeg->regs); | ||
2364 | exit_unlock: | ||
2365 | spin_unlock(&jpeg->slock); | ||
2366 | return IRQ_HANDLED; | ||
2367 | } | ||
2368 | |||
1898 | static void *jpeg_get_drv_data(struct device *dev); | 2369 | static void *jpeg_get_drv_data(struct device *dev); |
1899 | 2370 | ||
1900 | /* | 2371 | /* |
@@ -1950,6 +2421,10 @@ static int s5p_jpeg_probe(struct platform_device *pdev) | |||
1950 | } | 2421 | } |
1951 | dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk); | 2422 | dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk); |
1952 | 2423 | ||
2424 | jpeg->sclk = clk_get(&pdev->dev, "sclk"); | ||
2425 | if (IS_ERR(jpeg->sclk)) | ||
2426 | dev_info(&pdev->dev, "sclk clock not available\n"); | ||
2427 | |||
1953 | /* v4l2 device */ | 2428 | /* v4l2 device */ |
1954 | ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev); | 2429 | ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev); |
1955 | if (ret) { | 2430 | if (ret) { |
@@ -2057,6 +2532,8 @@ device_register_rollback: | |||
2057 | 2532 | ||
2058 | clk_get_rollback: | 2533 | clk_get_rollback: |
2059 | clk_put(jpeg->clk); | 2534 | clk_put(jpeg->clk); |
2535 | if (!IS_ERR(jpeg->sclk)) | ||
2536 | clk_put(jpeg->sclk); | ||
2060 | 2537 | ||
2061 | return ret; | 2538 | return ret; |
2062 | } | 2539 | } |
@@ -2075,10 +2552,15 @@ static int s5p_jpeg_remove(struct platform_device *pdev) | |||
2075 | v4l2_m2m_release(jpeg->m2m_dev); | 2552 | v4l2_m2m_release(jpeg->m2m_dev); |
2076 | v4l2_device_unregister(&jpeg->v4l2_dev); | 2553 | v4l2_device_unregister(&jpeg->v4l2_dev); |
2077 | 2554 | ||
2078 | if (!pm_runtime_status_suspended(&pdev->dev)) | 2555 | if (!pm_runtime_status_suspended(&pdev->dev)) { |
2079 | clk_disable_unprepare(jpeg->clk); | 2556 | clk_disable_unprepare(jpeg->clk); |
2557 | if (!IS_ERR(jpeg->sclk)) | ||
2558 | clk_disable_unprepare(jpeg->sclk); | ||
2559 | } | ||
2080 | 2560 | ||
2081 | clk_put(jpeg->clk); | 2561 | clk_put(jpeg->clk); |
2562 | if (!IS_ERR(jpeg->sclk)) | ||
2563 | clk_put(jpeg->sclk); | ||
2082 | 2564 | ||
2083 | return 0; | 2565 | return 0; |
2084 | } | 2566 | } |
@@ -2088,6 +2570,8 @@ static int s5p_jpeg_runtime_suspend(struct device *dev) | |||
2088 | struct s5p_jpeg *jpeg = dev_get_drvdata(dev); | 2570 | struct s5p_jpeg *jpeg = dev_get_drvdata(dev); |
2089 | 2571 | ||
2090 | clk_disable_unprepare(jpeg->clk); | 2572 | clk_disable_unprepare(jpeg->clk); |
2573 | if (!IS_ERR(jpeg->sclk)) | ||
2574 | clk_disable_unprepare(jpeg->sclk); | ||
2091 | 2575 | ||
2092 | return 0; | 2576 | return 0; |
2093 | } | 2577 | } |
@@ -2102,15 +2586,24 @@ static int s5p_jpeg_runtime_resume(struct device *dev) | |||
2102 | if (ret < 0) | 2586 | if (ret < 0) |
2103 | return ret; | 2587 | return ret; |
2104 | 2588 | ||
2589 | if (!IS_ERR(jpeg->sclk)) { | ||
2590 | ret = clk_prepare_enable(jpeg->sclk); | ||
2591 | if (ret < 0) | ||
2592 | return ret; | ||
2593 | } | ||
2594 | |||
2105 | spin_lock_irqsave(&jpeg->slock, flags); | 2595 | spin_lock_irqsave(&jpeg->slock, flags); |
2106 | 2596 | ||
2107 | /* | 2597 | /* |
2108 | * JPEG IP allows storing two Huffman tables for each component | 2598 | * JPEG IP allows storing two Huffman tables for each component. |
2109 | * We fill table 0 for each component and do this here only | 2599 | * We fill table 0 for each component and do this here only |
2110 | * for S5PC210 device as Exynos4x12 requires programming its | 2600 | * for S5PC210 and Exynos3250 SoCs. Exynos4x12 SoC requires |
2111 | * Huffman tables each time the encoding process is initialized. | 2601 | * programming its Huffman tables each time the encoding process |
2602 | * is initialized, and thus it is accomplished in the device_run | ||
2603 | * callback of m2m_ops. | ||
2112 | */ | 2604 | */ |
2113 | if (jpeg->variant->version == SJPEG_S5P) { | 2605 | if (jpeg->variant->version == SJPEG_S5P || |
2606 | jpeg->variant->version == SJPEG_EXYNOS3250) { | ||
2114 | s5p_jpeg_set_hdctbl(jpeg->regs); | 2607 | s5p_jpeg_set_hdctbl(jpeg->regs); |
2115 | s5p_jpeg_set_hdctblg(jpeg->regs); | 2608 | s5p_jpeg_set_hdctblg(jpeg->regs); |
2116 | s5p_jpeg_set_hactbl(jpeg->regs); | 2609 | s5p_jpeg_set_hactbl(jpeg->regs); |
@@ -2150,6 +2643,13 @@ static struct s5p_jpeg_variant s5p_jpeg_drvdata = { | |||
2150 | .fmt_ver_flag = SJPEG_FMT_FLAG_S5P, | 2643 | .fmt_ver_flag = SJPEG_FMT_FLAG_S5P, |
2151 | }; | 2644 | }; |
2152 | 2645 | ||
2646 | static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = { | ||
2647 | .version = SJPEG_EXYNOS3250, | ||
2648 | .jpeg_irq = exynos3250_jpeg_irq, | ||
2649 | .m2m_ops = &exynos3250_jpeg_m2m_ops, | ||
2650 | .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250, | ||
2651 | }; | ||
2652 | |||
2153 | static struct s5p_jpeg_variant exynos4_jpeg_drvdata = { | 2653 | static struct s5p_jpeg_variant exynos4_jpeg_drvdata = { |
2154 | .version = SJPEG_EXYNOS4, | 2654 | .version = SJPEG_EXYNOS4, |
2155 | .jpeg_irq = exynos4_jpeg_irq, | 2655 | .jpeg_irq = exynos4_jpeg_irq, |
@@ -2162,8 +2662,11 @@ static const struct of_device_id samsung_jpeg_match[] = { | |||
2162 | .compatible = "samsung,s5pv210-jpeg", | 2662 | .compatible = "samsung,s5pv210-jpeg", |
2163 | .data = &s5p_jpeg_drvdata, | 2663 | .data = &s5p_jpeg_drvdata, |
2164 | }, { | 2664 | }, { |
2665 | .compatible = "samsung,exynos3250-jpeg", | ||
2666 | .data = &exynos3250_jpeg_drvdata, | ||
2667 | }, { | ||
2165 | .compatible = "samsung,exynos4210-jpeg", | 2668 | .compatible = "samsung,exynos4210-jpeg", |
2166 | .data = &s5p_jpeg_drvdata, | 2669 | .data = &exynos4_jpeg_drvdata, |
2167 | }, { | 2670 | }, { |
2168 | .compatible = "samsung,exynos4212-jpeg", | 2671 | .compatible = "samsung,exynos4212-jpeg", |
2169 | .data = &exynos4_jpeg_drvdata, | 2672 | .data = &exynos4_jpeg_drvdata, |
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-core.h b/drivers/media/platform/s5p-jpeg/jpeg-core.h index 3e4786329727..764b32de326b 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-core.h +++ b/drivers/media/platform/s5p-jpeg/jpeg-core.h | |||
@@ -35,6 +35,8 @@ | |||
35 | #define S5P_JPEG_COEF32 0x6e | 35 | #define S5P_JPEG_COEF32 0x6e |
36 | #define S5P_JPEG_COEF33 0x13 | 36 | #define S5P_JPEG_COEF33 0x13 |
37 | 37 | ||
38 | #define EXYNOS3250_IRQ_TIMEOUT 0x10000000 | ||
39 | |||
38 | /* a selection of JPEG markers */ | 40 | /* a selection of JPEG markers */ |
39 | #define TEM 0x01 | 41 | #define TEM 0x01 |
40 | #define SOF0 0xc0 | 42 | #define SOF0 0xc0 |
@@ -49,9 +51,10 @@ | |||
49 | #define SJPEG_FMT_FLAG_DEC_CAPTURE (1 << 2) | 51 | #define SJPEG_FMT_FLAG_DEC_CAPTURE (1 << 2) |
50 | #define SJPEG_FMT_FLAG_DEC_OUTPUT (1 << 3) | 52 | #define SJPEG_FMT_FLAG_DEC_OUTPUT (1 << 3) |
51 | #define SJPEG_FMT_FLAG_S5P (1 << 4) | 53 | #define SJPEG_FMT_FLAG_S5P (1 << 4) |
52 | #define SJPEG_FMT_FLAG_EXYNOS4 (1 << 5) | 54 | #define SJPEG_FMT_FLAG_EXYNOS3250 (1 << 5) |
53 | #define SJPEG_FMT_RGB (1 << 6) | 55 | #define SJPEG_FMT_FLAG_EXYNOS4 (1 << 6) |
54 | #define SJPEG_FMT_NON_RGB (1 << 7) | 56 | #define SJPEG_FMT_RGB (1 << 7) |
57 | #define SJPEG_FMT_NON_RGB (1 << 8) | ||
55 | 58 | ||
56 | #define S5P_JPEG_ENCODE 0 | 59 | #define S5P_JPEG_ENCODE 0 |
57 | #define S5P_JPEG_DECODE 1 | 60 | #define S5P_JPEG_DECODE 1 |
@@ -65,8 +68,9 @@ | |||
65 | 68 | ||
66 | /* Version numbers */ | 69 | /* Version numbers */ |
67 | 70 | ||
68 | #define SJPEG_S5P 1 | 71 | #define SJPEG_S5P 1 |
69 | #define SJPEG_EXYNOS4 2 | 72 | #define SJPEG_EXYNOS3250 2 |
73 | #define SJPEG_EXYNOS4 3 | ||
70 | 74 | ||
71 | enum exynos4_jpeg_result { | 75 | enum exynos4_jpeg_result { |
72 | OK_ENC_OR_DEC, | 76 | OK_ENC_OR_DEC, |
@@ -95,8 +99,13 @@ enum exynos4_jpeg_img_quality_level { | |||
95 | * @regs: JPEG IP registers mapping | 99 | * @regs: JPEG IP registers mapping |
96 | * @irq: JPEG IP irq | 100 | * @irq: JPEG IP irq |
97 | * @clk: JPEG IP clock | 101 | * @clk: JPEG IP clock |
102 | * @sclk: Exynos3250 JPEG IP special clock | ||
98 | * @dev: JPEG IP struct device | 103 | * @dev: JPEG IP struct device |
99 | * @alloc_ctx: videobuf2 memory allocator's context | 104 | * @alloc_ctx: videobuf2 memory allocator's context |
105 | * @variant: driver variant to be used | ||
106 | * @irq_status interrupt flags set during single encode/decode | ||
107 | operation | ||
108 | |||
100 | */ | 109 | */ |
101 | struct s5p_jpeg { | 110 | struct s5p_jpeg { |
102 | struct mutex lock; | 111 | struct mutex lock; |
@@ -111,9 +120,11 @@ struct s5p_jpeg { | |||
111 | unsigned int irq; | 120 | unsigned int irq; |
112 | enum exynos4_jpeg_result irq_ret; | 121 | enum exynos4_jpeg_result irq_ret; |
113 | struct clk *clk; | 122 | struct clk *clk; |
123 | struct clk *sclk; | ||
114 | struct device *dev; | 124 | struct device *dev; |
115 | void *alloc_ctx; | 125 | void *alloc_ctx; |
116 | struct s5p_jpeg_variant *variant; | 126 | struct s5p_jpeg_variant *variant; |
127 | u32 irq_status; | ||
117 | }; | 128 | }; |
118 | 129 | ||
119 | struct s5p_jpeg_variant { | 130 | struct s5p_jpeg_variant { |
@@ -164,9 +175,15 @@ struct s5p_jpeg_q_data { | |||
164 | * @jpeg: JPEG IP device for this context | 175 | * @jpeg: JPEG IP device for this context |
165 | * @mode: compression (encode) operation or decompression (decode) | 176 | * @mode: compression (encode) operation or decompression (decode) |
166 | * @compr_quality: destination image quality in compression (encode) mode | 177 | * @compr_quality: destination image quality in compression (encode) mode |
178 | * @restart_interval: JPEG restart interval for JPEG encoding | ||
179 | * @subsampling: subsampling of a raw format or a JPEG | ||
167 | * @out_q: source (output) queue information | 180 | * @out_q: source (output) queue information |
168 | * @cap_fmt: destination (capture) queue queue information | 181 | * @cap_q: destination (capture) queue queue information |
182 | * @scale_factor: scale factor for JPEG decoding | ||
183 | * @crop_rect: a rectangle representing crop area of the output buffer | ||
184 | * @fh: V4L2 file handle | ||
169 | * @hdr_parsed: set if header has been parsed during decompression | 185 | * @hdr_parsed: set if header has been parsed during decompression |
186 | * @crop_altered: set if crop rectangle has been altered by the user space | ||
170 | * @ctrl_handler: controls handler | 187 | * @ctrl_handler: controls handler |
171 | */ | 188 | */ |
172 | struct s5p_jpeg_ctx { | 189 | struct s5p_jpeg_ctx { |
@@ -177,8 +194,11 @@ struct s5p_jpeg_ctx { | |||
177 | unsigned short subsampling; | 194 | unsigned short subsampling; |
178 | struct s5p_jpeg_q_data out_q; | 195 | struct s5p_jpeg_q_data out_q; |
179 | struct s5p_jpeg_q_data cap_q; | 196 | struct s5p_jpeg_q_data cap_q; |
197 | unsigned int scale_factor; | ||
198 | struct v4l2_rect crop_rect; | ||
180 | struct v4l2_fh fh; | 199 | struct v4l2_fh fh; |
181 | bool hdr_parsed; | 200 | bool hdr_parsed; |
201 | bool crop_altered; | ||
182 | struct v4l2_ctrl_handler ctrl_handler; | 202 | struct v4l2_ctrl_handler ctrl_handler; |
183 | }; | 203 | }; |
184 | 204 | ||
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c new file mode 100644 index 000000000000..d26e1f846553 --- /dev/null +++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c | |||
@@ -0,0 +1,487 @@ | |||
1 | /* linux/drivers/media/platform/exynos3250-jpeg/jpeg-hw.h | ||
2 | * | ||
3 | * Copyright (c) 2014 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com | ||
5 | * | ||
6 | * Author: Jacek Anaszewski <j.anaszewski@samsung.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #include <linux/io.h> | ||
14 | #include <linux/videodev2.h> | ||
15 | #include <linux/delay.h> | ||
16 | |||
17 | #include "jpeg-core.h" | ||
18 | #include "jpeg-regs.h" | ||
19 | #include "jpeg-hw-exynos3250.h" | ||
20 | |||
21 | void exynos3250_jpeg_reset(void __iomem *regs) | ||
22 | { | ||
23 | u32 reg = 0; | ||
24 | int count = 1000; | ||
25 | |||
26 | writel(1, regs + EXYNOS3250_SW_RESET); | ||
27 | /* no other way but polling for when JPEG IP becomes operational */ | ||
28 | while (reg != 0 && --count > 0) { | ||
29 | udelay(1); | ||
30 | cpu_relax(); | ||
31 | reg = readl(regs + EXYNOS3250_SW_RESET); | ||
32 | } | ||
33 | |||
34 | reg = 0; | ||
35 | count = 1000; | ||
36 | |||
37 | while (reg != 1 && --count > 0) { | ||
38 | writel(1, regs + EXYNOS3250_JPGDRI); | ||
39 | udelay(1); | ||
40 | cpu_relax(); | ||
41 | reg = readl(regs + EXYNOS3250_JPGDRI); | ||
42 | } | ||
43 | |||
44 | writel(0, regs + EXYNOS3250_JPGDRI); | ||
45 | } | ||
46 | |||
47 | void exynos3250_jpeg_poweron(void __iomem *regs) | ||
48 | { | ||
49 | writel(EXYNOS3250_POWER_ON, regs + EXYNOS3250_JPGCLKCON); | ||
50 | } | ||
51 | |||
52 | void exynos3250_jpeg_set_dma_num(void __iomem *regs) | ||
53 | { | ||
54 | writel(((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_WDMA_ISSUE_NUM_SHIFT) & | ||
55 | EXYNOS3250_WDMA_ISSUE_NUM_MASK) | | ||
56 | ((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_RDMA_ISSUE_NUM_SHIFT) & | ||
57 | EXYNOS3250_RDMA_ISSUE_NUM_MASK) | | ||
58 | ((EXYNOS3250_DMA_MO_COUNT << EXYNOS3250_ISSUE_GATHER_NUM_SHIFT) & | ||
59 | EXYNOS3250_ISSUE_GATHER_NUM_MASK), | ||
60 | regs + EXYNOS3250_DMA_ISSUE_NUM); | ||
61 | } | ||
62 | |||
63 | void exynos3250_jpeg_clk_set(void __iomem *base) | ||
64 | { | ||
65 | u32 reg; | ||
66 | |||
67 | reg = readl(base + EXYNOS3250_JPGCMOD) & ~EXYNOS3250_HALF_EN_MASK; | ||
68 | |||
69 | writel(reg | EXYNOS3250_HALF_EN, base + EXYNOS3250_JPGCMOD); | ||
70 | } | ||
71 | |||
72 | void exynos3250_jpeg_input_raw_fmt(void __iomem *regs, unsigned int fmt) | ||
73 | { | ||
74 | u32 reg; | ||
75 | |||
76 | reg = readl(regs + EXYNOS3250_JPGCMOD) & | ||
77 | EXYNOS3250_MODE_Y16_MASK; | ||
78 | |||
79 | switch (fmt) { | ||
80 | case V4L2_PIX_FMT_RGB32: | ||
81 | reg |= EXYNOS3250_MODE_SEL_ARGB8888; | ||
82 | break; | ||
83 | case V4L2_PIX_FMT_BGR32: | ||
84 | reg |= EXYNOS3250_MODE_SEL_ARGB8888 | EXYNOS3250_SRC_SWAP_RGB; | ||
85 | break; | ||
86 | case V4L2_PIX_FMT_RGB565: | ||
87 | reg |= EXYNOS3250_MODE_SEL_RGB565; | ||
88 | break; | ||
89 | case V4L2_PIX_FMT_RGB565X: | ||
90 | reg |= EXYNOS3250_MODE_SEL_RGB565 | EXYNOS3250_SRC_SWAP_RGB; | ||
91 | break; | ||
92 | case V4L2_PIX_FMT_YUYV: | ||
93 | reg |= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR; | ||
94 | break; | ||
95 | case V4L2_PIX_FMT_YVYU: | ||
96 | reg |= EXYNOS3250_MODE_SEL_422_1P_LUM_CHR | | ||
97 | EXYNOS3250_SRC_SWAP_UV; | ||
98 | break; | ||
99 | case V4L2_PIX_FMT_UYVY: | ||
100 | reg |= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM; | ||
101 | break; | ||
102 | case V4L2_PIX_FMT_VYUY: | ||
103 | reg |= EXYNOS3250_MODE_SEL_422_1P_CHR_LUM | | ||
104 | EXYNOS3250_SRC_SWAP_UV; | ||
105 | break; | ||
106 | case V4L2_PIX_FMT_NV12: | ||
107 | reg |= EXYNOS3250_MODE_SEL_420_2P | EXYNOS3250_SRC_NV12; | ||
108 | break; | ||
109 | case V4L2_PIX_FMT_NV21: | ||
110 | reg |= EXYNOS3250_MODE_SEL_420_2P | EXYNOS3250_SRC_NV21; | ||
111 | break; | ||
112 | case V4L2_PIX_FMT_YUV420: | ||
113 | reg |= EXYNOS3250_MODE_SEL_420_3P; | ||
114 | break; | ||
115 | default: | ||
116 | break; | ||
117 | |||
118 | } | ||
119 | |||
120 | writel(reg, regs + EXYNOS3250_JPGCMOD); | ||
121 | } | ||
122 | |||
123 | void exynos3250_jpeg_set_y16(void __iomem *regs, bool y16) | ||
124 | { | ||
125 | u32 reg; | ||
126 | |||
127 | reg = readl(regs + EXYNOS3250_JPGCMOD); | ||
128 | if (y16) | ||
129 | reg |= EXYNOS3250_MODE_Y16; | ||
130 | else | ||
131 | reg &= ~EXYNOS3250_MODE_Y16_MASK; | ||
132 | writel(reg, regs + EXYNOS3250_JPGCMOD); | ||
133 | } | ||
134 | |||
135 | void exynos3250_jpeg_proc_mode(void __iomem *regs, unsigned int mode) | ||
136 | { | ||
137 | u32 reg, m; | ||
138 | |||
139 | if (mode == S5P_JPEG_ENCODE) | ||
140 | m = EXYNOS3250_PROC_MODE_COMPR; | ||
141 | else | ||
142 | m = EXYNOS3250_PROC_MODE_DECOMPR; | ||
143 | reg = readl(regs + EXYNOS3250_JPGMOD); | ||
144 | reg &= ~EXYNOS3250_PROC_MODE_MASK; | ||
145 | reg |= m; | ||
146 | writel(reg, regs + EXYNOS3250_JPGMOD); | ||
147 | } | ||
148 | |||
149 | void exynos3250_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode) | ||
150 | { | ||
151 | u32 reg, m = 0; | ||
152 | |||
153 | switch (mode) { | ||
154 | case V4L2_JPEG_CHROMA_SUBSAMPLING_444: | ||
155 | m = EXYNOS3250_SUBSAMPLING_MODE_444; | ||
156 | break; | ||
157 | case V4L2_JPEG_CHROMA_SUBSAMPLING_422: | ||
158 | m = EXYNOS3250_SUBSAMPLING_MODE_422; | ||
159 | break; | ||
160 | case V4L2_JPEG_CHROMA_SUBSAMPLING_420: | ||
161 | m = EXYNOS3250_SUBSAMPLING_MODE_420; | ||
162 | break; | ||
163 | } | ||
164 | |||
165 | reg = readl(regs + EXYNOS3250_JPGMOD); | ||
166 | reg &= ~EXYNOS3250_SUBSAMPLING_MODE_MASK; | ||
167 | reg |= m; | ||
168 | writel(reg, regs + EXYNOS3250_JPGMOD); | ||
169 | } | ||
170 | |||
171 | unsigned int exynos3250_jpeg_get_subsampling_mode(void __iomem *regs) | ||
172 | { | ||
173 | return readl(regs + EXYNOS3250_JPGMOD) & | ||
174 | EXYNOS3250_SUBSAMPLING_MODE_MASK; | ||
175 | } | ||
176 | |||
177 | void exynos3250_jpeg_dri(void __iomem *regs, unsigned int dri) | ||
178 | { | ||
179 | u32 reg; | ||
180 | |||
181 | reg = dri & EXYNOS3250_JPGDRI_MASK; | ||
182 | writel(reg, regs + EXYNOS3250_JPGDRI); | ||
183 | } | ||
184 | |||
185 | void exynos3250_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n) | ||
186 | { | ||
187 | unsigned long reg; | ||
188 | |||
189 | reg = readl(regs + EXYNOS3250_QHTBL); | ||
190 | reg &= ~EXYNOS3250_QT_NUM_MASK(t); | ||
191 | reg |= (n << EXYNOS3250_QT_NUM_SHIFT(t)) & | ||
192 | EXYNOS3250_QT_NUM_MASK(t); | ||
193 | writel(reg, regs + EXYNOS3250_QHTBL); | ||
194 | } | ||
195 | |||
196 | void exynos3250_jpeg_htbl_ac(void __iomem *regs, unsigned int t) | ||
197 | { | ||
198 | unsigned long reg; | ||
199 | |||
200 | reg = readl(regs + EXYNOS3250_QHTBL); | ||
201 | reg &= ~EXYNOS3250_HT_NUM_AC_MASK(t); | ||
202 | /* this driver uses table 0 for all color components */ | ||
203 | reg |= (0 << EXYNOS3250_HT_NUM_AC_SHIFT(t)) & | ||
204 | EXYNOS3250_HT_NUM_AC_MASK(t); | ||
205 | writel(reg, regs + EXYNOS3250_QHTBL); | ||
206 | } | ||
207 | |||
208 | void exynos3250_jpeg_htbl_dc(void __iomem *regs, unsigned int t) | ||
209 | { | ||
210 | unsigned long reg; | ||
211 | |||
212 | reg = readl(regs + EXYNOS3250_QHTBL); | ||
213 | reg &= ~EXYNOS3250_HT_NUM_DC_MASK(t); | ||
214 | /* this driver uses table 0 for all color components */ | ||
215 | reg |= (0 << EXYNOS3250_HT_NUM_DC_SHIFT(t)) & | ||
216 | EXYNOS3250_HT_NUM_DC_MASK(t); | ||
217 | writel(reg, regs + EXYNOS3250_QHTBL); | ||
218 | } | ||
219 | |||
220 | void exynos3250_jpeg_set_y(void __iomem *regs, unsigned int y) | ||
221 | { | ||
222 | u32 reg; | ||
223 | |||
224 | reg = y & EXYNOS3250_JPGY_MASK; | ||
225 | writel(reg, regs + EXYNOS3250_JPGY); | ||
226 | } | ||
227 | |||
228 | void exynos3250_jpeg_set_x(void __iomem *regs, unsigned int x) | ||
229 | { | ||
230 | u32 reg; | ||
231 | |||
232 | reg = x & EXYNOS3250_JPGX_MASK; | ||
233 | writel(reg, regs + EXYNOS3250_JPGX); | ||
234 | } | ||
235 | |||
236 | unsigned int exynos3250_jpeg_get_y(void __iomem *regs) | ||
237 | { | ||
238 | return readl(regs + EXYNOS3250_JPGY); | ||
239 | } | ||
240 | |||
241 | unsigned int exynos3250_jpeg_get_x(void __iomem *regs) | ||
242 | { | ||
243 | return readl(regs + EXYNOS3250_JPGX); | ||
244 | } | ||
245 | |||
246 | void exynos3250_jpeg_interrupts_enable(void __iomem *regs) | ||
247 | { | ||
248 | u32 reg; | ||
249 | |||
250 | reg = readl(regs + EXYNOS3250_JPGINTSE); | ||
251 | reg |= (EXYNOS3250_JPEG_DONE_EN | | ||
252 | EXYNOS3250_WDMA_DONE_EN | | ||
253 | EXYNOS3250_RDMA_DONE_EN | | ||
254 | EXYNOS3250_ENC_STREAM_INT_EN | | ||
255 | EXYNOS3250_CORE_DONE_EN | | ||
256 | EXYNOS3250_ERR_INT_EN | | ||
257 | EXYNOS3250_HEAD_INT_EN); | ||
258 | writel(reg, regs + EXYNOS3250_JPGINTSE); | ||
259 | } | ||
260 | |||
261 | void exynos3250_jpeg_enc_stream_bound(void __iomem *regs, unsigned int size) | ||
262 | { | ||
263 | u32 reg; | ||
264 | |||
265 | reg = size & EXYNOS3250_ENC_STREAM_BOUND_MASK; | ||
266 | writel(reg, regs + EXYNOS3250_ENC_STREAM_BOUND); | ||
267 | } | ||
268 | |||
269 | void exynos3250_jpeg_output_raw_fmt(void __iomem *regs, unsigned int fmt) | ||
270 | { | ||
271 | u32 reg; | ||
272 | |||
273 | switch (fmt) { | ||
274 | case V4L2_PIX_FMT_RGB32: | ||
275 | reg = EXYNOS3250_OUT_FMT_ARGB8888; | ||
276 | break; | ||
277 | case V4L2_PIX_FMT_BGR32: | ||
278 | reg = EXYNOS3250_OUT_FMT_ARGB8888 | EXYNOS3250_OUT_SWAP_RGB; | ||
279 | break; | ||
280 | case V4L2_PIX_FMT_RGB565: | ||
281 | reg = EXYNOS3250_OUT_FMT_RGB565; | ||
282 | break; | ||
283 | case V4L2_PIX_FMT_RGB565X: | ||
284 | reg = EXYNOS3250_OUT_FMT_RGB565 | EXYNOS3250_OUT_SWAP_RGB; | ||
285 | break; | ||
286 | case V4L2_PIX_FMT_YUYV: | ||
287 | reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR; | ||
288 | break; | ||
289 | case V4L2_PIX_FMT_YVYU: | ||
290 | reg = EXYNOS3250_OUT_FMT_422_1P_LUM_CHR | | ||
291 | EXYNOS3250_OUT_SWAP_UV; | ||
292 | break; | ||
293 | case V4L2_PIX_FMT_UYVY: | ||
294 | reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM; | ||
295 | break; | ||
296 | case V4L2_PIX_FMT_VYUY: | ||
297 | reg = EXYNOS3250_OUT_FMT_422_1P_CHR_LUM | | ||
298 | EXYNOS3250_OUT_SWAP_UV; | ||
299 | break; | ||
300 | case V4L2_PIX_FMT_NV12: | ||
301 | reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV12; | ||
302 | break; | ||
303 | case V4L2_PIX_FMT_NV21: | ||
304 | reg = EXYNOS3250_OUT_FMT_420_2P | EXYNOS3250_OUT_NV21; | ||
305 | break; | ||
306 | case V4L2_PIX_FMT_YUV420: | ||
307 | reg = EXYNOS3250_OUT_FMT_420_3P; | ||
308 | break; | ||
309 | default: | ||
310 | reg = 0; | ||
311 | break; | ||
312 | } | ||
313 | |||
314 | writel(reg, regs + EXYNOS3250_OUTFORM); | ||
315 | } | ||
316 | |||
317 | void exynos3250_jpeg_jpgadr(void __iomem *regs, unsigned int addr) | ||
318 | { | ||
319 | writel(addr, regs + EXYNOS3250_JPG_JPGADR); | ||
320 | } | ||
321 | |||
322 | void exynos3250_jpeg_imgadr(void __iomem *regs, struct s5p_jpeg_addr *img_addr) | ||
323 | { | ||
324 | writel(img_addr->y, regs + EXYNOS3250_LUMA_BASE); | ||
325 | writel(img_addr->cb, regs + EXYNOS3250_CHROMA_BASE); | ||
326 | writel(img_addr->cr, regs + EXYNOS3250_CHROMA_CR_BASE); | ||
327 | } | ||
328 | |||
329 | void exynos3250_jpeg_stride(void __iomem *regs, unsigned int img_fmt, | ||
330 | unsigned int width) | ||
331 | { | ||
332 | u32 reg_luma = 0, reg_cr = 0, reg_cb = 0; | ||
333 | |||
334 | switch (img_fmt) { | ||
335 | case V4L2_PIX_FMT_RGB32: | ||
336 | reg_luma = 4 * width; | ||
337 | break; | ||
338 | case V4L2_PIX_FMT_RGB565: | ||
339 | case V4L2_PIX_FMT_RGB565X: | ||
340 | case V4L2_PIX_FMT_YUYV: | ||
341 | case V4L2_PIX_FMT_YVYU: | ||
342 | case V4L2_PIX_FMT_UYVY: | ||
343 | case V4L2_PIX_FMT_VYUY: | ||
344 | reg_luma = 2 * width; | ||
345 | break; | ||
346 | case V4L2_PIX_FMT_NV12: | ||
347 | case V4L2_PIX_FMT_NV21: | ||
348 | reg_luma = width; | ||
349 | reg_cb = reg_luma; | ||
350 | break; | ||
351 | case V4L2_PIX_FMT_YUV420: | ||
352 | reg_luma = width; | ||
353 | reg_cb = reg_cr = reg_luma / 2; | ||
354 | break; | ||
355 | default: | ||
356 | break; | ||
357 | } | ||
358 | |||
359 | writel(reg_luma, regs + EXYNOS3250_LUMA_STRIDE); | ||
360 | writel(reg_cb, regs + EXYNOS3250_CHROMA_STRIDE); | ||
361 | writel(reg_cr, regs + EXYNOS3250_CHROMA_CR_STRIDE); | ||
362 | } | ||
363 | |||
364 | void exynos3250_jpeg_offset(void __iomem *regs, unsigned int x_offset, | ||
365 | unsigned int y_offset) | ||
366 | { | ||
367 | u32 reg; | ||
368 | |||
369 | reg = (y_offset << EXYNOS3250_LUMA_YY_OFFSET_SHIFT) & | ||
370 | EXYNOS3250_LUMA_YY_OFFSET_MASK; | ||
371 | reg |= (x_offset << EXYNOS3250_LUMA_YX_OFFSET_SHIFT) & | ||
372 | EXYNOS3250_LUMA_YX_OFFSET_MASK; | ||
373 | |||
374 | writel(reg, regs + EXYNOS3250_LUMA_XY_OFFSET); | ||
375 | |||
376 | reg = (y_offset << EXYNOS3250_CHROMA_YY_OFFSET_SHIFT) & | ||
377 | EXYNOS3250_CHROMA_YY_OFFSET_MASK; | ||
378 | reg |= (x_offset << EXYNOS3250_CHROMA_YX_OFFSET_SHIFT) & | ||
379 | EXYNOS3250_CHROMA_YX_OFFSET_MASK; | ||
380 | |||
381 | writel(reg, regs + EXYNOS3250_CHROMA_XY_OFFSET); | ||
382 | |||
383 | reg = (y_offset << EXYNOS3250_CHROMA_CR_YY_OFFSET_SHIFT) & | ||
384 | EXYNOS3250_CHROMA_CR_YY_OFFSET_MASK; | ||
385 | reg |= (x_offset << EXYNOS3250_CHROMA_CR_YX_OFFSET_SHIFT) & | ||
386 | EXYNOS3250_CHROMA_CR_YX_OFFSET_MASK; | ||
387 | |||
388 | writel(reg, regs + EXYNOS3250_CHROMA_CR_XY_OFFSET); | ||
389 | } | ||
390 | |||
391 | void exynos3250_jpeg_coef(void __iomem *base, unsigned int mode) | ||
392 | { | ||
393 | if (mode == S5P_JPEG_ENCODE) { | ||
394 | writel(EXYNOS3250_JPEG_ENC_COEF1, | ||
395 | base + EXYNOS3250_JPG_COEF(1)); | ||
396 | writel(EXYNOS3250_JPEG_ENC_COEF2, | ||
397 | base + EXYNOS3250_JPG_COEF(2)); | ||
398 | writel(EXYNOS3250_JPEG_ENC_COEF3, | ||
399 | base + EXYNOS3250_JPG_COEF(3)); | ||
400 | } else { | ||
401 | writel(EXYNOS3250_JPEG_DEC_COEF1, | ||
402 | base + EXYNOS3250_JPG_COEF(1)); | ||
403 | writel(EXYNOS3250_JPEG_DEC_COEF2, | ||
404 | base + EXYNOS3250_JPG_COEF(2)); | ||
405 | writel(EXYNOS3250_JPEG_DEC_COEF3, | ||
406 | base + EXYNOS3250_JPG_COEF(3)); | ||
407 | } | ||
408 | } | ||
409 | |||
410 | void exynos3250_jpeg_start(void __iomem *regs) | ||
411 | { | ||
412 | writel(1, regs + EXYNOS3250_JSTART); | ||
413 | } | ||
414 | |||
415 | void exynos3250_jpeg_rstart(void __iomem *regs) | ||
416 | { | ||
417 | writel(1, regs + EXYNOS3250_JRSTART); | ||
418 | } | ||
419 | |||
420 | unsigned int exynos3250_jpeg_get_int_status(void __iomem *regs) | ||
421 | { | ||
422 | return readl(regs + EXYNOS3250_JPGINTST); | ||
423 | } | ||
424 | |||
425 | void exynos3250_jpeg_clear_int_status(void __iomem *regs, | ||
426 | unsigned int value) | ||
427 | { | ||
428 | return writel(value, regs + EXYNOS3250_JPGINTST); | ||
429 | } | ||
430 | |||
431 | unsigned int exynos3250_jpeg_operating(void __iomem *regs) | ||
432 | { | ||
433 | return readl(regs + S5P_JPGOPR) & EXYNOS3250_JPGOPR_MASK; | ||
434 | } | ||
435 | |||
436 | unsigned int exynos3250_jpeg_compressed_size(void __iomem *regs) | ||
437 | { | ||
438 | return readl(regs + EXYNOS3250_JPGCNT) & EXYNOS3250_JPGCNT_MASK; | ||
439 | } | ||
440 | |||
441 | void exynos3250_jpeg_dec_stream_size(void __iomem *regs, | ||
442 | unsigned int size) | ||
443 | { | ||
444 | writel(size & EXYNOS3250_DEC_STREAM_MASK, | ||
445 | regs + EXYNOS3250_DEC_STREAM_SIZE); | ||
446 | } | ||
447 | |||
448 | void exynos3250_jpeg_dec_scaling_ratio(void __iomem *regs, | ||
449 | unsigned int sratio) | ||
450 | { | ||
451 | switch (sratio) { | ||
452 | case 1: | ||
453 | default: | ||
454 | sratio = EXYNOS3250_DEC_SCALE_FACTOR_8_8; | ||
455 | break; | ||
456 | case 2: | ||
457 | sratio = EXYNOS3250_DEC_SCALE_FACTOR_4_8; | ||
458 | break; | ||
459 | case 4: | ||
460 | sratio = EXYNOS3250_DEC_SCALE_FACTOR_2_8; | ||
461 | break; | ||
462 | case 8: | ||
463 | sratio = EXYNOS3250_DEC_SCALE_FACTOR_1_8; | ||
464 | break; | ||
465 | } | ||
466 | |||
467 | writel(sratio & EXYNOS3250_DEC_SCALE_FACTOR_MASK, | ||
468 | regs + EXYNOS3250_DEC_SCALING_RATIO); | ||
469 | } | ||
470 | |||
471 | void exynos3250_jpeg_set_timer(void __iomem *regs, unsigned int time_value) | ||
472 | { | ||
473 | time_value &= EXYNOS3250_TIMER_INIT_MASK; | ||
474 | |||
475 | writel(EXYNOS3250_TIMER_INT_STAT | time_value, | ||
476 | regs + EXYNOS3250_TIMER_SE); | ||
477 | } | ||
478 | |||
479 | unsigned int exynos3250_jpeg_get_timer_status(void __iomem *regs) | ||
480 | { | ||
481 | return readl(regs + EXYNOS3250_TIMER_ST); | ||
482 | } | ||
483 | |||
484 | void exynos3250_jpeg_clear_timer_status(void __iomem *regs) | ||
485 | { | ||
486 | writel(EXYNOS3250_TIMER_INT_STAT, regs + EXYNOS3250_TIMER_ST); | ||
487 | } | ||
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h new file mode 100644 index 000000000000..b6e3be8b5008 --- /dev/null +++ b/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h | |||
@@ -0,0 +1,60 @@ | |||
1 | /* linux/drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h | ||
2 | * | ||
3 | * Copyright (c) 2014 Samsung Electronics Co., Ltd. | ||
4 | * http://www.samsung.com | ||
5 | * | ||
6 | * Author: Jacek Anaszewski <j.anaszewski@samsung.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | */ | ||
12 | #ifndef JPEG_HW_EXYNOS3250_H_ | ||
13 | #define JPEG_HW_EXYNOS3250_H_ | ||
14 | |||
15 | #include <linux/io.h> | ||
16 | #include <linux/videodev2.h> | ||
17 | |||
18 | #include "jpeg-regs.h" | ||
19 | |||
20 | void exynos3250_jpeg_reset(void __iomem *regs); | ||
21 | void exynos3250_jpeg_poweron(void __iomem *regs); | ||
22 | void exynos3250_jpeg_set_dma_num(void __iomem *regs); | ||
23 | void exynos3250_jpeg_clk_set(void __iomem *base); | ||
24 | void exynos3250_jpeg_input_raw_fmt(void __iomem *regs, unsigned int fmt); | ||
25 | void exynos3250_jpeg_output_raw_fmt(void __iomem *regs, unsigned int fmt); | ||
26 | void exynos3250_jpeg_set_y16(void __iomem *regs, bool y16); | ||
27 | void exynos3250_jpeg_proc_mode(void __iomem *regs, unsigned int mode); | ||
28 | void exynos3250_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode); | ||
29 | unsigned int exynos3250_jpeg_get_subsampling_mode(void __iomem *regs); | ||
30 | void exynos3250_jpeg_dri(void __iomem *regs, unsigned int dri); | ||
31 | void exynos3250_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n); | ||
32 | void exynos3250_jpeg_htbl_ac(void __iomem *regs, unsigned int t); | ||
33 | void exynos3250_jpeg_htbl_dc(void __iomem *regs, unsigned int t); | ||
34 | void exynos3250_jpeg_set_y(void __iomem *regs, unsigned int y); | ||
35 | void exynos3250_jpeg_set_x(void __iomem *regs, unsigned int x); | ||
36 | void exynos3250_jpeg_interrupts_enable(void __iomem *regs); | ||
37 | void exynos3250_jpeg_enc_stream_bound(void __iomem *regs, unsigned int size); | ||
38 | void exynos3250_jpeg_outform_raw(void __iomem *regs, unsigned long format); | ||
39 | void exynos3250_jpeg_jpgadr(void __iomem *regs, unsigned int addr); | ||
40 | void exynos3250_jpeg_imgadr(void __iomem *regs, struct s5p_jpeg_addr *img_addr); | ||
41 | void exynos3250_jpeg_stride(void __iomem *regs, unsigned int img_fmt, | ||
42 | unsigned int width); | ||
43 | void exynos3250_jpeg_offset(void __iomem *regs, unsigned int x_offset, | ||
44 | unsigned int y_offset); | ||
45 | void exynos3250_jpeg_coef(void __iomem *base, unsigned int mode); | ||
46 | void exynos3250_jpeg_start(void __iomem *regs); | ||
47 | void exynos3250_jpeg_rstart(void __iomem *regs); | ||
48 | unsigned int exynos3250_jpeg_get_int_status(void __iomem *regs); | ||
49 | void exynos3250_jpeg_clear_int_status(void __iomem *regs, | ||
50 | unsigned int value); | ||
51 | unsigned int exynos3250_jpeg_operating(void __iomem *regs); | ||
52 | unsigned int exynos3250_jpeg_compressed_size(void __iomem *regs); | ||
53 | void exynos3250_jpeg_dec_stream_size(void __iomem *regs, unsigned int size); | ||
54 | void exynos3250_jpeg_dec_scaling_ratio(void __iomem *regs, unsigned int sratio); | ||
55 | void exynos3250_jpeg_set_timer(void __iomem *regs, unsigned int time_value); | ||
56 | unsigned int exynos3250_jpeg_get_timer_status(void __iomem *regs); | ||
57 | void exynos3250_jpeg_set_timer_status(void __iomem *regs); | ||
58 | void exynos3250_jpeg_clear_timer_status(void __iomem *regs); | ||
59 | |||
60 | #endif /* JPEG_HW_EXYNOS3250_H_ */ | ||
diff --git a/drivers/media/platform/s5p-jpeg/jpeg-regs.h b/drivers/media/platform/s5p-jpeg/jpeg-regs.h index 57fb05bb8c77..050fc440248f 100644 --- a/drivers/media/platform/s5p-jpeg/jpeg-regs.h +++ b/drivers/media/platform/s5p-jpeg/jpeg-regs.h | |||
@@ -2,7 +2,7 @@ | |||
2 | * | 2 | * |
3 | * Register definition file for Samsung JPEG codec driver | 3 | * Register definition file for Samsung JPEG codec driver |
4 | * | 4 | * |
5 | * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd. | 5 | * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd. |
6 | * http://www.samsung.com | 6 | * http://www.samsung.com |
7 | * | 7 | * |
8 | * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> | 8 | * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> |
@@ -373,5 +373,250 @@ | |||
373 | /* JPEG AC chrominance (values) Huffman table register */ | 373 | /* JPEG AC chrominance (values) Huffman table register */ |
374 | #define EXYNOS4_HUFF_TBL_HACCV 0x310 | 374 | #define EXYNOS4_HUFF_TBL_HACCV 0x310 |
375 | 375 | ||
376 | /* Register and bit definitions for Exynos 3250 */ | ||
377 | |||
378 | /* JPEG mode register */ | ||
379 | #define EXYNOS3250_JPGMOD 0x00 | ||
380 | #define EXYNOS3250_PROC_MODE_MASK (0x1 << 3) | ||
381 | #define EXYNOS3250_PROC_MODE_DECOMPR (0x1 << 3) | ||
382 | #define EXYNOS3250_PROC_MODE_COMPR (0x0 << 3) | ||
383 | #define EXYNOS3250_SUBSAMPLING_MODE_MASK (0x7 << 0) | ||
384 | #define EXYNOS3250_SUBSAMPLING_MODE_444 (0x0 << 0) | ||
385 | #define EXYNOS3250_SUBSAMPLING_MODE_422 (0x1 << 0) | ||
386 | #define EXYNOS3250_SUBSAMPLING_MODE_420 (0x2 << 0) | ||
387 | #define EXYNOS3250_SUBSAMPLING_MODE_411 (0x6 << 0) | ||
388 | #define EXYNOS3250_SUBSAMPLING_MODE_GRAY (0x3 << 0) | ||
389 | |||
390 | /* JPEG operation status register */ | ||
391 | #define EXYNOS3250_JPGOPR 0x04 | ||
392 | #define EXYNOS3250_JPGOPR_MASK 0x01 | ||
393 | |||
394 | /* Quantization and Huffman tables register */ | ||
395 | #define EXYNOS3250_QHTBL 0x08 | ||
396 | #define EXYNOS3250_QT_NUM_SHIFT(t) ((((t) - 1) << 1) + 8) | ||
397 | #define EXYNOS3250_QT_NUM_MASK(t) (0x3 << EXYNOS3250_QT_NUM_SHIFT(t)) | ||
398 | |||
399 | /* Huffman tables */ | ||
400 | #define EXYNOS3250_HT_NUM_AC_SHIFT(t) (((t) << 1) - 1) | ||
401 | #define EXYNOS3250_HT_NUM_AC_MASK(t) (0x1 << EXYNOS3250_HT_NUM_AC_SHIFT(t)) | ||
402 | |||
403 | #define EXYNOS3250_HT_NUM_DC_SHIFT(t) (((t) - 1) << 1) | ||
404 | #define EXYNOS3250_HT_NUM_DC_MASK(t) (0x1 << EXYNOS3250_HT_NUM_DC_SHIFT(t)) | ||
405 | |||
406 | /* JPEG restart interval register */ | ||
407 | #define EXYNOS3250_JPGDRI 0x0c | ||
408 | #define EXYNOS3250_JPGDRI_MASK 0xffff | ||
409 | |||
410 | /* JPEG vertical resolution register */ | ||
411 | #define EXYNOS3250_JPGY 0x10 | ||
412 | #define EXYNOS3250_JPGY_MASK 0xffff | ||
413 | |||
414 | /* JPEG horizontal resolution register */ | ||
415 | #define EXYNOS3250_JPGX 0x14 | ||
416 | #define EXYNOS3250_JPGX_MASK 0xffff | ||
417 | |||
418 | /* JPEG byte count register */ | ||
419 | #define EXYNOS3250_JPGCNT 0x18 | ||
420 | #define EXYNOS3250_JPGCNT_MASK 0xffffff | ||
421 | |||
422 | /* JPEG interrupt mask register */ | ||
423 | #define EXYNOS3250_JPGINTSE 0x1c | ||
424 | #define EXYNOS3250_JPEG_DONE_EN (1 << 11) | ||
425 | #define EXYNOS3250_WDMA_DONE_EN (1 << 10) | ||
426 | #define EXYNOS3250_RDMA_DONE_EN (1 << 9) | ||
427 | #define EXYNOS3250_ENC_STREAM_INT_EN (1 << 8) | ||
428 | #define EXYNOS3250_CORE_DONE_EN (1 << 5) | ||
429 | #define EXYNOS3250_ERR_INT_EN (1 << 4) | ||
430 | #define EXYNOS3250_HEAD_INT_EN (1 << 3) | ||
431 | |||
432 | /* JPEG interrupt status register */ | ||
433 | #define EXYNOS3250_JPGINTST 0x20 | ||
434 | #define EXYNOS3250_JPEG_DONE (1 << 11) | ||
435 | #define EXYNOS3250_WDMA_DONE (1 << 10) | ||
436 | #define EXYNOS3250_RDMA_DONE (1 << 9) | ||
437 | #define EXYNOS3250_ENC_STREAM_STAT (1 << 8) | ||
438 | #define EXYNOS3250_RESULT_STAT (1 << 5) | ||
439 | #define EXYNOS3250_STREAM_STAT (1 << 4) | ||
440 | #define EXYNOS3250_HEADER_STAT (1 << 3) | ||
441 | |||
442 | /* | ||
443 | * Base address of the luma component DMA buffer | ||
444 | * of the raw input or output image. | ||
445 | */ | ||
446 | #define EXYNOS3250_LUMA_BASE 0x100 | ||
447 | #define EXYNOS3250_SRC_TILE_EN_MASK 0x100 | ||
448 | |||
449 | /* Stride of source or destination luma raw image buffer */ | ||
450 | #define EXYNOS3250_LUMA_STRIDE 0x104 | ||
451 | |||
452 | /* Horizontal/vertical offset of active region in luma raw image buffer */ | ||
453 | #define EXYNOS3250_LUMA_XY_OFFSET 0x108 | ||
454 | #define EXYNOS3250_LUMA_YY_OFFSET_SHIFT 18 | ||
455 | #define EXYNOS3250_LUMA_YY_OFFSET_MASK (0x1fff << EXYNOS3250_LUMA_YY_OFFSET_SHIFT) | ||
456 | #define EXYNOS3250_LUMA_YX_OFFSET_SHIFT 2 | ||
457 | #define EXYNOS3250_LUMA_YX_OFFSET_MASK (0x1fff << EXYNOS3250_LUMA_YX_OFFSET_SHIFT) | ||
458 | |||
459 | /* | ||
460 | * Base address of the chroma(Cb) component DMA buffer | ||
461 | * of the raw input or output image. | ||
462 | */ | ||
463 | #define EXYNOS3250_CHROMA_BASE 0x10c | ||
464 | |||
465 | /* Stride of source or destination chroma(Cb) raw image buffer */ | ||
466 | #define EXYNOS3250_CHROMA_STRIDE 0x110 | ||
467 | |||
468 | /* Horizontal/vertical offset of active region in chroma(Cb) raw image buffer */ | ||
469 | #define EXYNOS3250_CHROMA_XY_OFFSET 0x114 | ||
470 | #define EXYNOS3250_CHROMA_YY_OFFSET_SHIFT 18 | ||
471 | #define EXYNOS3250_CHROMA_YY_OFFSET_MASK (0x1fff << EXYNOS3250_CHROMA_YY_OFFSET_SHIFT) | ||
472 | #define EXYNOS3250_CHROMA_YX_OFFSET_SHIFT 2 | ||
473 | #define EXYNOS3250_CHROMA_YX_OFFSET_MASK (0x1fff << EXYNOS3250_CHROMA_YX_OFFSET_SHIFT) | ||
474 | |||
475 | /* | ||
476 | * Base address of the chroma(Cr) component DMA buffer | ||
477 | * of the raw input or output image. | ||
478 | */ | ||
479 | #define EXYNOS3250_CHROMA_CR_BASE 0x118 | ||
480 | |||
481 | /* Stride of source or destination chroma(Cr) raw image buffer */ | ||
482 | #define EXYNOS3250_CHROMA_CR_STRIDE 0x11c | ||
483 | |||
484 | /* Horizontal/vertical offset of active region in chroma(Cb) raw image buffer */ | ||
485 | #define EXYNOS3250_CHROMA_CR_XY_OFFSET 0x120 | ||
486 | #define EXYNOS3250_CHROMA_CR_YY_OFFSET_SHIFT 18 | ||
487 | #define EXYNOS3250_CHROMA_CR_YY_OFFSET_MASK (0x1fff << EXYNOS3250_CHROMA_CR_YY_OFFSET_SHIFT) | ||
488 | #define EXYNOS3250_CHROMA_CR_YX_OFFSET_SHIFT 2 | ||
489 | #define EXYNOS3250_CHROMA_CR_YX_OFFSET_MASK (0x1fff << EXYNOS3250_CHROMA_CR_YX_OFFSET_SHIFT) | ||
490 | |||
491 | /* Raw image data r/w address register */ | ||
492 | #define EXYNOS3250_JPG_IMGADR 0x50 | ||
493 | |||
494 | /* Source or destination JPEG file DMA buffer address */ | ||
495 | #define EXYNOS3250_JPG_JPGADR 0x124 | ||
496 | |||
497 | /* Coefficients for RGB-to-YCbCr converter register */ | ||
498 | #define EXYNOS3250_JPG_COEF(n) (0x128 + (((n) - 1) << 2)) | ||
499 | #define EXYNOS3250_COEF_SHIFT(j) ((3 - (j)) << 3) | ||
500 | #define EXYNOS3250_COEF_MASK(j) (0xff << EXYNOS3250_COEF_SHIFT(j)) | ||
501 | |||
502 | /* Raw input format setting */ | ||
503 | #define EXYNOS3250_JPGCMOD 0x134 | ||
504 | #define EXYNOS3250_SRC_TILE_EN (0x1 << 10) | ||
505 | #define EXYNOS3250_SRC_NV_MASK (0x1 << 9) | ||
506 | #define EXYNOS3250_SRC_NV12 (0x0 << 9) | ||
507 | #define EXYNOS3250_SRC_NV21 (0x1 << 9) | ||
508 | #define EXYNOS3250_SRC_BIG_ENDIAN_MASK (0x1 << 8) | ||
509 | #define EXYNOS3250_SRC_BIG_ENDIAN (0x1 << 8) | ||
510 | #define EXYNOS3250_MODE_SEL_MASK (0x7 << 5) | ||
511 | #define EXYNOS3250_MODE_SEL_420_2P (0x0 << 5) | ||
512 | #define EXYNOS3250_MODE_SEL_422_1P_LUM_CHR (0x1 << 5) | ||
513 | #define EXYNOS3250_MODE_SEL_RGB565 (0x2 << 5) | ||
514 | #define EXYNOS3250_MODE_SEL_422_1P_CHR_LUM (0x3 << 5) | ||
515 | #define EXYNOS3250_MODE_SEL_ARGB8888 (0x4 << 5) | ||
516 | #define EXYNOS3250_MODE_SEL_420_3P (0x5 << 5) | ||
517 | #define EXYNOS3250_SRC_SWAP_RGB (0x1 << 3) | ||
518 | #define EXYNOS3250_SRC_SWAP_UV (0x1 << 2) | ||
519 | #define EXYNOS3250_MODE_Y16_MASK (0x1 << 1) | ||
520 | #define EXYNOS3250_MODE_Y16 (0x1 << 1) | ||
521 | #define EXYNOS3250_HALF_EN_MASK (0x1 << 0) | ||
522 | #define EXYNOS3250_HALF_EN (0x1 << 0) | ||
523 | |||
524 | /* Power on/off and clock down control */ | ||
525 | #define EXYNOS3250_JPGCLKCON 0x138 | ||
526 | #define EXYNOS3250_CLK_DOWN_READY (0x1 << 1) | ||
527 | #define EXYNOS3250_POWER_ON (0x1 << 0) | ||
528 | |||
529 | /* Start compression or decompression */ | ||
530 | #define EXYNOS3250_JSTART 0x13c | ||
531 | |||
532 | /* Restart decompression after header analysis */ | ||
533 | #define EXYNOS3250_JRSTART 0x140 | ||
534 | |||
535 | /* JPEG SW reset register */ | ||
536 | #define EXYNOS3250_SW_RESET 0x144 | ||
537 | |||
538 | /* JPEG timer setting register */ | ||
539 | #define EXYNOS3250_TIMER_SE 0x148 | ||
540 | #define EXYNOS3250_TIMER_INT_EN_SHIFT 31 | ||
541 | #define EXYNOS3250_TIMER_INT_EN (1 << EXYNOS3250_TIMER_INT_EN_SHIFT) | ||
542 | #define EXYNOS3250_TIMER_INIT_MASK 0x7fffffff | ||
543 | |||
544 | /* JPEG timer status register */ | ||
545 | #define EXYNOS3250_TIMER_ST 0x14c | ||
546 | #define EXYNOS3250_TIMER_INT_STAT_SHIFT 31 | ||
547 | #define EXYNOS3250_TIMER_INT_STAT (1 << EXYNOS3250_TIMER_INT_STAT_SHIFT) | ||
548 | #define EXYNOS3250_TIMER_CNT_SHIFT 0 | ||
549 | #define EXYNOS3250_TIMER_CNT_MASK 0x7fffffff | ||
550 | |||
551 | /* Command status register */ | ||
552 | #define EXYNOS3250_COMSTAT 0x150 | ||
553 | #define EXYNOS3250_CUR_PROC_MODE (0x1 << 1) | ||
554 | #define EXYNOS3250_CUR_COM_MODE (0x1 << 0) | ||
555 | |||
556 | /* JPEG decompression output format register */ | ||
557 | #define EXYNOS3250_OUTFORM 0x154 | ||
558 | #define EXYNOS3250_OUT_ALPHA_MASK (0xff << 24) | ||
559 | #define EXYNOS3250_OUT_TILE_EN (0x1 << 10) | ||
560 | #define EXYNOS3250_OUT_NV_MASK (0x1 << 9) | ||
561 | #define EXYNOS3250_OUT_NV12 (0x0 << 9) | ||
562 | #define EXYNOS3250_OUT_NV21 (0x1 << 9) | ||
563 | #define EXYNOS3250_OUT_BIG_ENDIAN_MASK (0x1 << 8) | ||
564 | #define EXYNOS3250_OUT_BIG_ENDIAN (0x1 << 8) | ||
565 | #define EXYNOS3250_OUT_SWAP_RGB (0x1 << 7) | ||
566 | #define EXYNOS3250_OUT_SWAP_UV (0x1 << 6) | ||
567 | #define EXYNOS3250_OUT_FMT_MASK (0x7 << 0) | ||
568 | #define EXYNOS3250_OUT_FMT_420_2P (0x0 << 0) | ||
569 | #define EXYNOS3250_OUT_FMT_422_1P_LUM_CHR (0x1 << 0) | ||
570 | #define EXYNOS3250_OUT_FMT_422_1P_CHR_LUM (0x3 << 0) | ||
571 | #define EXYNOS3250_OUT_FMT_420_3P (0x4 << 0) | ||
572 | #define EXYNOS3250_OUT_FMT_RGB565 (0x5 << 0) | ||
573 | #define EXYNOS3250_OUT_FMT_ARGB8888 (0x6 << 0) | ||
574 | |||
575 | /* Input JPEG stream byte size for decompression */ | ||
576 | #define EXYNOS3250_DEC_STREAM_SIZE 0x158 | ||
577 | #define EXYNOS3250_DEC_STREAM_MASK 0x1fffffff | ||
578 | |||
579 | /* The upper bound of the byte size of output compressed stream */ | ||
580 | #define EXYNOS3250_ENC_STREAM_BOUND 0x15c | ||
581 | #define EXYNOS3250_ENC_STREAM_BOUND_MASK 0xffffc0 | ||
582 | |||
583 | /* Scale-down ratio when decoding */ | ||
584 | #define EXYNOS3250_DEC_SCALING_RATIO 0x160 | ||
585 | #define EXYNOS3250_DEC_SCALE_FACTOR_MASK 0x3 | ||
586 | #define EXYNOS3250_DEC_SCALE_FACTOR_8_8 0x0 | ||
587 | #define EXYNOS3250_DEC_SCALE_FACTOR_4_8 0x1 | ||
588 | #define EXYNOS3250_DEC_SCALE_FACTOR_2_8 0x2 | ||
589 | #define EXYNOS3250_DEC_SCALE_FACTOR_1_8 0x3 | ||
590 | |||
591 | /* Error check */ | ||
592 | #define EXYNOS3250_CRC_RESULT 0x164 | ||
593 | |||
594 | /* RDMA and WDMA operation status register */ | ||
595 | #define EXYNOS3250_DMA_OPER_STATUS 0x168 | ||
596 | #define EXYNOS3250_WDMA_OPER_STATUS (0x1 << 1) | ||
597 | #define EXYNOS3250_RDMA_OPER_STATUS (0x1 << 0) | ||
598 | |||
599 | /* DMA issue gathering number and issue number settings */ | ||
600 | #define EXYNOS3250_DMA_ISSUE_NUM 0x16c | ||
601 | #define EXYNOS3250_WDMA_ISSUE_NUM_SHIFT 16 | ||
602 | #define EXYNOS3250_WDMA_ISSUE_NUM_MASK (0x7 << EXYNOS3250_WDMA_ISSUE_NUM_SHIFT) | ||
603 | #define EXYNOS3250_RDMA_ISSUE_NUM_SHIFT 8 | ||
604 | #define EXYNOS3250_RDMA_ISSUE_NUM_MASK (0x7 << EXYNOS3250_RDMA_ISSUE_NUM_SHIFT) | ||
605 | #define EXYNOS3250_ISSUE_GATHER_NUM_SHIFT 0 | ||
606 | #define EXYNOS3250_ISSUE_GATHER_NUM_MASK (0x7 << EXYNOS3250_ISSUE_GATHER_NUM_SHIFT) | ||
607 | #define EXYNOS3250_DMA_MO_COUNT 0x7 | ||
608 | |||
609 | /* Version register */ | ||
610 | #define EXYNOS3250_VERSION 0x1fc | ||
611 | |||
612 | /* RGB <-> YUV conversion coefficients */ | ||
613 | #define EXYNOS3250_JPEG_ENC_COEF1 0x01352e1e | ||
614 | #define EXYNOS3250_JPEG_ENC_COEF2 0x00b0ae83 | ||
615 | #define EXYNOS3250_JPEG_ENC_COEF3 0x020cdc13 | ||
616 | |||
617 | #define EXYNOS3250_JPEG_DEC_COEF1 0x04a80199 | ||
618 | #define EXYNOS3250_JPEG_DEC_COEF2 0x04a9a064 | ||
619 | #define EXYNOS3250_JPEG_DEC_COEF3 0x04a80102 | ||
620 | |||
376 | #endif /* JPEG_REGS_H_ */ | 621 | #endif /* JPEG_REGS_H_ */ |
377 | 622 | ||