aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorJacek Anaszewski <j.anaszewski@samsung.com>2014-07-11 11:19:42 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-07-30 18:15:06 -0400
commit3246fdaa0ac2d936b1838589b76fd5aaff02e46d (patch)
tree4fb9ead2b7950a0cb335974b6ed2e475842ceff3 /drivers/media
parent1774afe7d98d8cfcb57327d2ced2d95c48de8c72 (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/Kconfig5
-rw-r--r--drivers/media/platform/s5p-jpeg/Makefile2
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.c527
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-core.h32
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c487
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h60
-rw-r--r--drivers/media/platform/s5p-jpeg/jpeg-regs.h247
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
169config VIDEO_SAMSUNG_S5P_JPEG 169config 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
177config VIDEO_SAMSUNG_S5P_MFC 178config 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 @@
1s5p-jpeg-objs := jpeg-core.o jpeg-hw-exynos4.o jpeg-hw-s5p.o 1s5p-jpeg-objs := jpeg-core.o jpeg-hw-exynos3250.o jpeg-hw-exynos4.o jpeg-hw-s5p.o
2obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg.o 2obj-$(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
37static struct s5p_jpeg_fmt sjpeg_formats[] = { 38static 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
594static 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
460static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c) 604static 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
1384static 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. */
1418static 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
1430static 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
1232static int s5p_jpeg_g_selection(struct file *file, void *priv, 1479static 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 */
1514static 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
1268static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl) 1539static 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
1879static 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
1912static 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
1927static 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
1607static int s5p_jpeg_job_ready(void *priv) 2008static 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
2027static 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
1626static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = { 2033static 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
2305static 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);
2364exit_unlock:
2365 spin_unlock(&jpeg->slock);
2366 return IRQ_HANDLED;
2367}
2368
1898static void *jpeg_get_drv_data(struct device *dev); 2369static 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
2058clk_get_rollback: 2533clk_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
2646static 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
2153static struct s5p_jpeg_variant exynos4_jpeg_drvdata = { 2653static 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
71enum exynos4_jpeg_result { 75enum 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 */
101struct s5p_jpeg { 110struct 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
119struct s5p_jpeg_variant { 130struct 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 */
172struct s5p_jpeg_ctx { 189struct 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
21void 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
47void exynos3250_jpeg_poweron(void __iomem *regs)
48{
49 writel(EXYNOS3250_POWER_ON, regs + EXYNOS3250_JPGCLKCON);
50}
51
52void 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
63void 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
72void 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
123void 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
135void 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
149void 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
171unsigned int exynos3250_jpeg_get_subsampling_mode(void __iomem *regs)
172{
173 return readl(regs + EXYNOS3250_JPGMOD) &
174 EXYNOS3250_SUBSAMPLING_MODE_MASK;
175}
176
177void 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
185void 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
196void 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
208void 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
220void 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
228void 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
236unsigned int exynos3250_jpeg_get_y(void __iomem *regs)
237{
238 return readl(regs + EXYNOS3250_JPGY);
239}
240
241unsigned int exynos3250_jpeg_get_x(void __iomem *regs)
242{
243 return readl(regs + EXYNOS3250_JPGX);
244}
245
246void 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
261void 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
269void 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
317void exynos3250_jpeg_jpgadr(void __iomem *regs, unsigned int addr)
318{
319 writel(addr, regs + EXYNOS3250_JPG_JPGADR);
320}
321
322void 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
329void 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
364void 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
391void 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
410void exynos3250_jpeg_start(void __iomem *regs)
411{
412 writel(1, regs + EXYNOS3250_JSTART);
413}
414
415void exynos3250_jpeg_rstart(void __iomem *regs)
416{
417 writel(1, regs + EXYNOS3250_JRSTART);
418}
419
420unsigned int exynos3250_jpeg_get_int_status(void __iomem *regs)
421{
422 return readl(regs + EXYNOS3250_JPGINTST);
423}
424
425void exynos3250_jpeg_clear_int_status(void __iomem *regs,
426 unsigned int value)
427{
428 return writel(value, regs + EXYNOS3250_JPGINTST);
429}
430
431unsigned int exynos3250_jpeg_operating(void __iomem *regs)
432{
433 return readl(regs + S5P_JPGOPR) & EXYNOS3250_JPGOPR_MASK;
434}
435
436unsigned int exynos3250_jpeg_compressed_size(void __iomem *regs)
437{
438 return readl(regs + EXYNOS3250_JPGCNT) & EXYNOS3250_JPGCNT_MASK;
439}
440
441void 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
448void 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
471void 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
479unsigned int exynos3250_jpeg_get_timer_status(void __iomem *regs)
480{
481 return readl(regs + EXYNOS3250_TIMER_ST);
482}
483
484void 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
20void exynos3250_jpeg_reset(void __iomem *regs);
21void exynos3250_jpeg_poweron(void __iomem *regs);
22void exynos3250_jpeg_set_dma_num(void __iomem *regs);
23void exynos3250_jpeg_clk_set(void __iomem *base);
24void exynos3250_jpeg_input_raw_fmt(void __iomem *regs, unsigned int fmt);
25void exynos3250_jpeg_output_raw_fmt(void __iomem *regs, unsigned int fmt);
26void exynos3250_jpeg_set_y16(void __iomem *regs, bool y16);
27void exynos3250_jpeg_proc_mode(void __iomem *regs, unsigned int mode);
28void exynos3250_jpeg_subsampling_mode(void __iomem *regs, unsigned int mode);
29unsigned int exynos3250_jpeg_get_subsampling_mode(void __iomem *regs);
30void exynos3250_jpeg_dri(void __iomem *regs, unsigned int dri);
31void exynos3250_jpeg_qtbl(void __iomem *regs, unsigned int t, unsigned int n);
32void exynos3250_jpeg_htbl_ac(void __iomem *regs, unsigned int t);
33void exynos3250_jpeg_htbl_dc(void __iomem *regs, unsigned int t);
34void exynos3250_jpeg_set_y(void __iomem *regs, unsigned int y);
35void exynos3250_jpeg_set_x(void __iomem *regs, unsigned int x);
36void exynos3250_jpeg_interrupts_enable(void __iomem *regs);
37void exynos3250_jpeg_enc_stream_bound(void __iomem *regs, unsigned int size);
38void exynos3250_jpeg_outform_raw(void __iomem *regs, unsigned long format);
39void exynos3250_jpeg_jpgadr(void __iomem *regs, unsigned int addr);
40void exynos3250_jpeg_imgadr(void __iomem *regs, struct s5p_jpeg_addr *img_addr);
41void exynos3250_jpeg_stride(void __iomem *regs, unsigned int img_fmt,
42 unsigned int width);
43void exynos3250_jpeg_offset(void __iomem *regs, unsigned int x_offset,
44 unsigned int y_offset);
45void exynos3250_jpeg_coef(void __iomem *base, unsigned int mode);
46void exynos3250_jpeg_start(void __iomem *regs);
47void exynos3250_jpeg_rstart(void __iomem *regs);
48unsigned int exynos3250_jpeg_get_int_status(void __iomem *regs);
49void exynos3250_jpeg_clear_int_status(void __iomem *regs,
50 unsigned int value);
51unsigned int exynos3250_jpeg_operating(void __iomem *regs);
52unsigned int exynos3250_jpeg_compressed_size(void __iomem *regs);
53void exynos3250_jpeg_dec_stream_size(void __iomem *regs, unsigned int size);
54void exynos3250_jpeg_dec_scaling_ratio(void __iomem *regs, unsigned int sratio);
55void exynos3250_jpeg_set_timer(void __iomem *regs, unsigned int time_value);
56unsigned int exynos3250_jpeg_get_timer_status(void __iomem *regs);
57void exynos3250_jpeg_set_timer_status(void __iomem *regs);
58void 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