Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Jacek Anaszewski and committed by
Mauro Carvalho Chehab
3246fdaa 1774afe7

+1338 -22
+3 -2
drivers/media/platform/Kconfig
··· 167 167 2d graphics accelerator. 168 168 169 169 config VIDEO_SAMSUNG_S5P_JPEG 170 - tristate "Samsung S5P/Exynos4 JPEG codec driver" 170 + tristate "Samsung S5P/Exynos3250/Exynos4 JPEG codec driver" 171 171 depends on VIDEO_DEV && VIDEO_V4L2 && (PLAT_S5P || ARCH_EXYNOS) 172 172 select VIDEOBUF2_DMA_CONTIG 173 173 select V4L2_MEM2MEM_DEV 174 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 178 config VIDEO_SAMSUNG_S5P_MFC 178 179 tristate "Samsung S5P MFC Video Codec"
+1 -1
drivers/media/platform/s5p-jpeg/Makefile
··· 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 2 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) += s5p-jpeg.o
+515 -12
drivers/media/platform/s5p-jpeg/jpeg-core.c
··· 1 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 4 * http://www.samsung.com 5 5 * 6 6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> ··· 32 32 #include "jpeg-core.h" 33 33 #include "jpeg-hw-s5p.h" 34 34 #include "jpeg-hw-exynos4.h" 35 + #include "jpeg-hw-exynos3250.h" 35 36 #include "jpeg-regs.h" 36 37 37 38 static struct s5p_jpeg_fmt sjpeg_formats[] = { ··· 42 41 .flags = SJPEG_FMT_FLAG_ENC_CAPTURE | 43 42 SJPEG_FMT_FLAG_DEC_OUTPUT | 44 43 SJPEG_FMT_FLAG_S5P | 44 + SJPEG_FMT_FLAG_EXYNOS3250 | 45 45 SJPEG_FMT_FLAG_EXYNOS4, 46 46 }, 47 47 { ··· 72 70 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, 73 71 }, 74 72 { 73 + .name = "YUV 4:2:2 packed, YCbYCr", 74 + .fourcc = V4L2_PIX_FMT_YUYV, 75 + .depth = 16, 76 + .colplanes = 1, 77 + .h_align = 2, 78 + .v_align = 0, 79 + .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | 80 + SJPEG_FMT_FLAG_DEC_CAPTURE | 81 + SJPEG_FMT_FLAG_EXYNOS3250 | 82 + SJPEG_FMT_NON_RGB, 83 + .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, 84 + }, 85 + { 75 86 .name = "YUV 4:2:2 packed, YCrYCb", 76 87 .fourcc = V4L2_PIX_FMT_YVYU, 77 88 .depth = 16, ··· 98 83 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, 99 84 }, 100 85 { 86 + .name = "YUV 4:2:2 packed, YCrYCb", 87 + .fourcc = V4L2_PIX_FMT_YVYU, 88 + .depth = 16, 89 + .colplanes = 1, 90 + .h_align = 2, 91 + .v_align = 0, 92 + .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | 93 + SJPEG_FMT_FLAG_DEC_CAPTURE | 94 + SJPEG_FMT_FLAG_EXYNOS3250 | 95 + SJPEG_FMT_NON_RGB, 96 + .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, 97 + }, 98 + { 99 + .name = "YUV 4:2:2 packed, YCrYCb", 100 + .fourcc = V4L2_PIX_FMT_UYVY, 101 + .depth = 16, 102 + .colplanes = 1, 103 + .h_align = 2, 104 + .v_align = 0, 105 + .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | 106 + SJPEG_FMT_FLAG_DEC_CAPTURE | 107 + SJPEG_FMT_FLAG_EXYNOS3250 | 108 + SJPEG_FMT_NON_RGB, 109 + .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, 110 + }, 111 + { 112 + .name = "YUV 4:2:2 packed, YCrYCb", 113 + .fourcc = V4L2_PIX_FMT_VYUY, 114 + .depth = 16, 115 + .colplanes = 1, 116 + .h_align = 2, 117 + .v_align = 0, 118 + .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | 119 + SJPEG_FMT_FLAG_DEC_CAPTURE | 120 + SJPEG_FMT_FLAG_EXYNOS3250 | 121 + SJPEG_FMT_NON_RGB, 122 + .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_422, 123 + }, 124 + { 101 125 .name = "RGB565", 102 126 .fourcc = V4L2_PIX_FMT_RGB565, 103 127 .depth = 16, ··· 146 92 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | 147 93 SJPEG_FMT_FLAG_DEC_CAPTURE | 148 94 SJPEG_FMT_FLAG_EXYNOS4 | 95 + SJPEG_FMT_RGB, 96 + .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, 97 + }, 98 + { 99 + .name = "RGB565", 100 + .fourcc = V4L2_PIX_FMT_RGB565, 101 + .depth = 16, 102 + .colplanes = 1, 103 + .h_align = 2, 104 + .v_align = 0, 105 + .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | 106 + SJPEG_FMT_FLAG_DEC_CAPTURE | 107 + SJPEG_FMT_FLAG_EXYNOS3250 | 108 + SJPEG_FMT_RGB, 109 + .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, 110 + }, 111 + { 112 + .name = "RGB565X", 113 + .fourcc = V4L2_PIX_FMT_RGB565X, 114 + .depth = 16, 115 + .colplanes = 1, 116 + .h_align = 2, 117 + .v_align = 0, 118 + .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | 119 + SJPEG_FMT_FLAG_DEC_CAPTURE | 120 + SJPEG_FMT_FLAG_EXYNOS3250 | 149 121 SJPEG_FMT_RGB, 150 122 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, 151 123 }, ··· 197 117 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | 198 118 SJPEG_FMT_FLAG_DEC_CAPTURE | 199 119 SJPEG_FMT_FLAG_EXYNOS4 | 120 + SJPEG_FMT_RGB, 121 + .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, 122 + }, 123 + { 124 + .name = "ARGB8888, 32 bpp", 125 + .fourcc = V4L2_PIX_FMT_RGB32, 126 + .depth = 32, 127 + .colplanes = 1, 128 + .h_align = 2, 129 + .v_align = 0, 130 + .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | 131 + SJPEG_FMT_FLAG_DEC_CAPTURE | 132 + SJPEG_FMT_FLAG_EXYNOS3250 | 200 133 SJPEG_FMT_RGB, 201 134 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_444, 202 135 }, ··· 283 190 .fourcc = V4L2_PIX_FMT_NV12, 284 191 .depth = 12, 285 192 .colplanes = 2, 193 + .h_align = 3, 194 + .v_align = 3, 195 + .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | 196 + SJPEG_FMT_FLAG_DEC_CAPTURE | 197 + SJPEG_FMT_FLAG_EXYNOS3250 | 198 + SJPEG_FMT_NON_RGB, 199 + .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, 200 + }, 201 + { 202 + .name = "YUV 4:2:0 planar, Y/CbCr", 203 + .fourcc = V4L2_PIX_FMT_NV12, 204 + .depth = 12, 205 + .colplanes = 2, 286 206 .h_align = 4, 287 207 .v_align = 4, 288 - .flags = SJPEG_FMT_FLAG_DEC_CAPTURE | 208 + .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | 209 + SJPEG_FMT_FLAG_DEC_CAPTURE | 289 210 SJPEG_FMT_FLAG_S5P | 211 + SJPEG_FMT_NON_RGB, 212 + .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, 213 + }, 214 + { 215 + .name = "YUV 4:2:0 planar, Y/CrCb", 216 + .fourcc = V4L2_PIX_FMT_NV21, 217 + .depth = 12, 218 + .colplanes = 2, 219 + .h_align = 3, 220 + .v_align = 3, 221 + .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | 222 + SJPEG_FMT_FLAG_DEC_CAPTURE | 223 + SJPEG_FMT_FLAG_EXYNOS3250 | 290 224 SJPEG_FMT_NON_RGB, 291 225 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, 292 226 }, ··· 326 206 .v_align = 1, 327 207 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | 328 208 SJPEG_FMT_FLAG_DEC_CAPTURE | 209 + SJPEG_FMT_FLAG_EXYNOS3250 | 329 210 SJPEG_FMT_FLAG_EXYNOS4 | 330 211 SJPEG_FMT_NON_RGB, 331 212 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, ··· 341 220 .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | 342 221 SJPEG_FMT_FLAG_DEC_CAPTURE | 343 222 SJPEG_FMT_FLAG_EXYNOS4 | 223 + SJPEG_FMT_NON_RGB, 224 + .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, 225 + }, 226 + { 227 + .name = "YUV 4:2:0 contiguous 3-planar, Y/Cb/Cr", 228 + .fourcc = V4L2_PIX_FMT_YUV420, 229 + .depth = 12, 230 + .colplanes = 3, 231 + .h_align = 4, 232 + .v_align = 4, 233 + .flags = SJPEG_FMT_FLAG_ENC_OUTPUT | 234 + SJPEG_FMT_FLAG_DEC_CAPTURE | 235 + SJPEG_FMT_FLAG_EXYNOS3250 | 344 236 SJPEG_FMT_NON_RGB, 345 237 .subsampling = V4L2_JPEG_CHROMA_SUBSAMPLING_420, 346 238 }, ··· 591 457 V4L2_JPEG_CHROMA_SUBSAMPLING_420, 592 458 }; 593 459 460 + static int exynos3250_decoded_subsampling[] = { 461 + V4L2_JPEG_CHROMA_SUBSAMPLING_444, 462 + V4L2_JPEG_CHROMA_SUBSAMPLING_422, 463 + V4L2_JPEG_CHROMA_SUBSAMPLING_420, 464 + V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY, 465 + -1, 466 + -1, 467 + V4L2_JPEG_CHROMA_SUBSAMPLING_411, 468 + }; 469 + 594 470 static inline struct s5p_jpeg_ctx *ctrl_to_ctx(struct v4l2_ctrl *c) 595 471 { 596 472 return container_of(c->handler, struct s5p_jpeg_ctx, ctrl_handler); ··· 615 471 { 616 472 WARN_ON(ctx->subsampling > 3); 617 473 618 - if (ctx->jpeg->variant->version == SJPEG_S5P) { 474 + switch (ctx->jpeg->variant->version) { 475 + case SJPEG_S5P: 619 476 if (ctx->subsampling > 2) 620 477 return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; 621 478 return ctx->subsampling; 622 - } else { 479 + case SJPEG_EXYNOS3250: 480 + if (ctx->subsampling > 3) 481 + return V4L2_JPEG_CHROMA_SUBSAMPLING_411; 482 + return exynos3250_decoded_subsampling[ctx->subsampling]; 483 + case SJPEG_EXYNOS4: 623 484 if (ctx->subsampling > 2) 624 485 return V4L2_JPEG_CHROMA_SUBSAMPLING_420; 625 486 return exynos4x12_decoded_subsampling[ctx->subsampling]; 487 + default: 488 + return V4L2_JPEG_CHROMA_SUBSAMPLING_GRAY; 626 489 } 627 490 } 628 491 ··· 797 646 FMT_TYPE_OUTPUT); 798 647 cap_fmt = s5p_jpeg_find_format(ctx, V4L2_PIX_FMT_YUYV, 799 648 FMT_TYPE_CAPTURE); 649 + ctx->scale_factor = EXYNOS3250_DEC_SCALE_FACTOR_8_8; 800 650 } 801 651 802 652 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, queue_init); ··· 1381 1229 return s5p_jpeg_s_fmt(fh_to_ctx(priv), f); 1382 1230 } 1383 1231 1232 + static int exynos3250_jpeg_try_downscale(struct s5p_jpeg_ctx *ctx, 1233 + struct v4l2_rect *r) 1234 + { 1235 + int w_ratio, h_ratio, scale_factor, cur_ratio, i; 1236 + 1237 + w_ratio = ctx->out_q.w / r->width; 1238 + h_ratio = ctx->out_q.h / r->height; 1239 + 1240 + scale_factor = w_ratio > h_ratio ? w_ratio : h_ratio; 1241 + scale_factor = clamp_val(scale_factor, 1, 8); 1242 + 1243 + /* Align scale ratio to the nearest power of 2 */ 1244 + for (i = 0; i <= 3; ++i) { 1245 + cur_ratio = 1 << i; 1246 + if (scale_factor <= cur_ratio) { 1247 + ctx->scale_factor = cur_ratio; 1248 + break; 1249 + } 1250 + } 1251 + 1252 + r->width = round_down(ctx->out_q.w / ctx->scale_factor, 2); 1253 + r->height = round_down(ctx->out_q.h / ctx->scale_factor, 2); 1254 + 1255 + ctx->crop_rect.width = r->width; 1256 + ctx->crop_rect.height = r->height; 1257 + ctx->crop_rect.left = 0; 1258 + ctx->crop_rect.top = 0; 1259 + 1260 + ctx->crop_altered = true; 1261 + 1262 + return 0; 1263 + } 1264 + 1265 + /* Return 1 if rectangle a is enclosed in rectangle b, or 0 otherwise. */ 1266 + static int enclosed_rectangle(struct v4l2_rect *a, struct v4l2_rect *b) 1267 + { 1268 + if (a->left < b->left || a->top < b->top) 1269 + return 0; 1270 + if (a->left + a->width > b->left + b->width) 1271 + return 0; 1272 + if (a->top + a->height > b->top + b->height) 1273 + return 0; 1274 + 1275 + return 1; 1276 + } 1277 + 1278 + static int exynos3250_jpeg_try_crop(struct s5p_jpeg_ctx *ctx, 1279 + struct v4l2_rect *r) 1280 + { 1281 + struct v4l2_rect base_rect; 1282 + int w_step, h_step; 1283 + 1284 + switch (ctx->cap_q.fmt->fourcc) { 1285 + case V4L2_PIX_FMT_NV12: 1286 + case V4L2_PIX_FMT_NV21: 1287 + w_step = 1; 1288 + h_step = 2; 1289 + break; 1290 + case V4L2_PIX_FMT_YUV420: 1291 + w_step = 2; 1292 + h_step = 2; 1293 + break; 1294 + default: 1295 + w_step = 1; 1296 + h_step = 1; 1297 + break; 1298 + } 1299 + 1300 + base_rect.top = 0; 1301 + base_rect.left = 0; 1302 + base_rect.width = ctx->out_q.w; 1303 + base_rect.height = ctx->out_q.h; 1304 + 1305 + r->width = round_down(r->width, w_step); 1306 + r->height = round_down(r->height, h_step); 1307 + r->left = round_down(r->left, 2); 1308 + r->top = round_down(r->top, 2); 1309 + 1310 + if (!enclosed_rectangle(r, &base_rect)) 1311 + return -EINVAL; 1312 + 1313 + ctx->crop_rect.left = r->left; 1314 + ctx->crop_rect.top = r->top; 1315 + ctx->crop_rect.width = r->width; 1316 + ctx->crop_rect.height = r->height; 1317 + 1318 + ctx->crop_altered = true; 1319 + 1320 + return 0; 1321 + } 1322 + 1323 + /* 1324 + * V4L2 controls 1325 + */ 1326 + 1384 1327 static int s5p_jpeg_g_selection(struct file *file, void *priv, 1385 1328 struct v4l2_selection *s) 1386 1329 { ··· 1511 1264 /* 1512 1265 * V4L2 controls 1513 1266 */ 1267 + static int s5p_jpeg_s_selection(struct file *file, void *fh, 1268 + struct v4l2_selection *s) 1269 + { 1270 + struct s5p_jpeg_ctx *ctx = fh_to_ctx(file->private_data); 1271 + struct v4l2_rect *rect = &s->r; 1272 + int ret = -EINVAL; 1273 + 1274 + if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1275 + return -EINVAL; 1276 + 1277 + if (s->target == V4L2_SEL_TGT_COMPOSE) { 1278 + if (ctx->mode != S5P_JPEG_DECODE) 1279 + return -EINVAL; 1280 + if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250) 1281 + ret = exynos3250_jpeg_try_downscale(ctx, rect); 1282 + } else if (s->target == V4L2_SEL_TGT_CROP) { 1283 + if (ctx->mode != S5P_JPEG_ENCODE) 1284 + return -EINVAL; 1285 + if (ctx->jpeg->variant->version == SJPEG_EXYNOS3250) 1286 + ret = exynos3250_jpeg_try_crop(ctx, rect); 1287 + } 1288 + 1289 + return ret; 1290 + } 1514 1291 1515 1292 static int s5p_jpeg_g_volatile_ctrl(struct v4l2_ctrl *ctrl) 1516 1293 { ··· 1685 1414 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff, 1686 1415 1687 1416 .vidioc_g_selection = s5p_jpeg_g_selection, 1417 + .vidioc_s_selection = s5p_jpeg_s_selection, 1688 1418 }; 1689 1419 1690 1420 /* ··· 1876 1604 spin_unlock_irqrestore(&ctx->jpeg->slock, flags); 1877 1605 } 1878 1606 1607 + static void exynos3250_jpeg_set_img_addr(struct s5p_jpeg_ctx *ctx) 1608 + { 1609 + struct s5p_jpeg *jpeg = ctx->jpeg; 1610 + struct s5p_jpeg_fmt *fmt; 1611 + struct vb2_buffer *vb; 1612 + struct s5p_jpeg_addr jpeg_addr; 1613 + u32 pix_size; 1614 + 1615 + pix_size = ctx->cap_q.w * ctx->cap_q.h; 1616 + 1617 + if (ctx->mode == S5P_JPEG_ENCODE) { 1618 + vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); 1619 + fmt = ctx->out_q.fmt; 1620 + } else { 1621 + vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); 1622 + fmt = ctx->cap_q.fmt; 1623 + } 1624 + 1625 + jpeg_addr.y = vb2_dma_contig_plane_dma_addr(vb, 0); 1626 + 1627 + if (fmt->colplanes == 2) { 1628 + jpeg_addr.cb = jpeg_addr.y + pix_size; 1629 + } else if (fmt->colplanes == 3) { 1630 + jpeg_addr.cb = jpeg_addr.y + pix_size; 1631 + if (fmt->fourcc == V4L2_PIX_FMT_YUV420) 1632 + jpeg_addr.cr = jpeg_addr.cb + pix_size / 4; 1633 + else 1634 + jpeg_addr.cr = jpeg_addr.cb + pix_size / 2; 1635 + } 1636 + 1637 + exynos3250_jpeg_imgadr(jpeg->regs, &jpeg_addr); 1638 + } 1639 + 1640 + static void exynos3250_jpeg_set_jpeg_addr(struct s5p_jpeg_ctx *ctx) 1641 + { 1642 + struct s5p_jpeg *jpeg = ctx->jpeg; 1643 + struct vb2_buffer *vb; 1644 + unsigned int jpeg_addr = 0; 1645 + 1646 + if (ctx->mode == S5P_JPEG_ENCODE) 1647 + vb = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); 1648 + else 1649 + vb = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); 1650 + 1651 + jpeg_addr = vb2_dma_contig_plane_dma_addr(vb, 0); 1652 + exynos3250_jpeg_jpgadr(jpeg->regs, jpeg_addr); 1653 + } 1654 + 1655 + static void exynos3250_jpeg_device_run(void *priv) 1656 + { 1657 + struct s5p_jpeg_ctx *ctx = priv; 1658 + struct s5p_jpeg *jpeg = ctx->jpeg; 1659 + unsigned long flags; 1660 + 1661 + spin_lock_irqsave(&ctx->jpeg->slock, flags); 1662 + 1663 + exynos3250_jpeg_reset(jpeg->regs); 1664 + exynos3250_jpeg_set_dma_num(jpeg->regs); 1665 + exynos3250_jpeg_poweron(jpeg->regs); 1666 + exynos3250_jpeg_clk_set(jpeg->regs); 1667 + exynos3250_jpeg_proc_mode(jpeg->regs, ctx->mode); 1668 + 1669 + if (ctx->mode == S5P_JPEG_ENCODE) { 1670 + exynos3250_jpeg_input_raw_fmt(jpeg->regs, 1671 + ctx->out_q.fmt->fourcc); 1672 + exynos3250_jpeg_dri(jpeg->regs, ctx->restart_interval); 1673 + 1674 + /* 1675 + * JPEG IP allows storing 4 quantization tables 1676 + * We fill table 0 for luma and table 1 for chroma 1677 + */ 1678 + s5p_jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality); 1679 + s5p_jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality); 1680 + /* use table 0 for Y */ 1681 + exynos3250_jpeg_qtbl(jpeg->regs, 1, 0); 1682 + /* use table 1 for Cb and Cr*/ 1683 + exynos3250_jpeg_qtbl(jpeg->regs, 2, 1); 1684 + exynos3250_jpeg_qtbl(jpeg->regs, 3, 1); 1685 + 1686 + /* Y, Cb, Cr use Huffman table 0 */ 1687 + exynos3250_jpeg_htbl_ac(jpeg->regs, 1); 1688 + exynos3250_jpeg_htbl_dc(jpeg->regs, 1); 1689 + exynos3250_jpeg_htbl_ac(jpeg->regs, 2); 1690 + exynos3250_jpeg_htbl_dc(jpeg->regs, 2); 1691 + exynos3250_jpeg_htbl_ac(jpeg->regs, 3); 1692 + exynos3250_jpeg_htbl_dc(jpeg->regs, 3); 1693 + 1694 + exynos3250_jpeg_set_x(jpeg->regs, ctx->crop_rect.width); 1695 + exynos3250_jpeg_set_y(jpeg->regs, ctx->crop_rect.height); 1696 + exynos3250_jpeg_stride(jpeg->regs, ctx->out_q.fmt->fourcc, 1697 + ctx->out_q.w); 1698 + exynos3250_jpeg_offset(jpeg->regs, ctx->crop_rect.left, 1699 + ctx->crop_rect.top); 1700 + exynos3250_jpeg_set_img_addr(ctx); 1701 + exynos3250_jpeg_set_jpeg_addr(ctx); 1702 + exynos3250_jpeg_subsampling_mode(jpeg->regs, ctx->subsampling); 1703 + 1704 + /* ultimately comes from sizeimage from userspace */ 1705 + exynos3250_jpeg_enc_stream_bound(jpeg->regs, ctx->cap_q.size); 1706 + 1707 + if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565 || 1708 + ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565X || 1709 + ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB32) 1710 + exynos3250_jpeg_set_y16(jpeg->regs, true); 1711 + } else { 1712 + exynos3250_jpeg_set_img_addr(ctx); 1713 + exynos3250_jpeg_set_jpeg_addr(ctx); 1714 + exynos3250_jpeg_stride(jpeg->regs, ctx->cap_q.fmt->fourcc, 1715 + ctx->cap_q.w); 1716 + exynos3250_jpeg_offset(jpeg->regs, 0, 0); 1717 + exynos3250_jpeg_dec_scaling_ratio(jpeg->regs, 1718 + ctx->scale_factor); 1719 + exynos3250_jpeg_dec_stream_size(jpeg->regs, ctx->out_q.size); 1720 + exynos3250_jpeg_output_raw_fmt(jpeg->regs, 1721 + ctx->cap_q.fmt->fourcc); 1722 + } 1723 + 1724 + exynos3250_jpeg_interrupts_enable(jpeg->regs); 1725 + 1726 + /* JPEG RGB to YCbCr conversion matrix */ 1727 + exynos3250_jpeg_coef(jpeg->regs, ctx->mode); 1728 + 1729 + exynos3250_jpeg_set_timer(jpeg->regs, EXYNOS3250_IRQ_TIMEOUT); 1730 + jpeg->irq_status = 0; 1731 + exynos3250_jpeg_start(jpeg->regs); 1732 + 1733 + spin_unlock_irqrestore(&ctx->jpeg->slock, flags); 1734 + } 1735 + 1879 1736 static int s5p_jpeg_job_ready(void *priv) 1880 1737 { 1881 1738 struct s5p_jpeg_ctx *ctx = priv; ··· 2022 1621 .device_run = s5p_jpeg_device_run, 2023 1622 .job_ready = s5p_jpeg_job_ready, 2024 1623 .job_abort = s5p_jpeg_job_abort, 2025 - } 2026 - ; 1624 + }; 1625 + 1626 + static struct v4l2_m2m_ops exynos3250_jpeg_m2m_ops = { 1627 + .device_run = exynos3250_jpeg_device_run, 1628 + .job_ready = s5p_jpeg_job_ready, 1629 + .job_abort = s5p_jpeg_job_abort, 1630 + }; 1631 + 2027 1632 static struct v4l2_m2m_ops exynos4_jpeg_m2m_ops = { 2028 1633 .device_run = exynos4_jpeg_device_run, 2029 1634 .job_ready = s5p_jpeg_job_ready, ··· 2302 1895 return IRQ_HANDLED; 2303 1896 } 2304 1897 1898 + static irqreturn_t exynos3250_jpeg_irq(int irq, void *dev_id) 1899 + { 1900 + struct s5p_jpeg *jpeg = dev_id; 1901 + struct s5p_jpeg_ctx *curr_ctx; 1902 + struct vb2_buffer *src_buf, *dst_buf; 1903 + unsigned long payload_size = 0; 1904 + enum vb2_buffer_state state = VB2_BUF_STATE_DONE; 1905 + bool interrupt_timeout = false; 1906 + u32 irq_status; 1907 + 1908 + spin_lock(&jpeg->slock); 1909 + 1910 + irq_status = exynos3250_jpeg_get_timer_status(jpeg->regs); 1911 + if (irq_status & EXYNOS3250_TIMER_INT_STAT) { 1912 + exynos3250_jpeg_clear_timer_status(jpeg->regs); 1913 + interrupt_timeout = true; 1914 + dev_err(jpeg->dev, "Interrupt timeout occurred.\n"); 1915 + } 1916 + 1917 + irq_status = exynos3250_jpeg_get_int_status(jpeg->regs); 1918 + exynos3250_jpeg_clear_int_status(jpeg->regs, irq_status); 1919 + 1920 + jpeg->irq_status |= irq_status; 1921 + 1922 + curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); 1923 + 1924 + if (!curr_ctx) 1925 + goto exit_unlock; 1926 + 1927 + if ((irq_status & EXYNOS3250_HEADER_STAT) && 1928 + (curr_ctx->mode == S5P_JPEG_DECODE)) { 1929 + exynos3250_jpeg_rstart(jpeg->regs); 1930 + goto exit_unlock; 1931 + } 1932 + 1933 + if (jpeg->irq_status & (EXYNOS3250_JPEG_DONE | 1934 + EXYNOS3250_WDMA_DONE | 1935 + EXYNOS3250_RDMA_DONE | 1936 + EXYNOS3250_RESULT_STAT)) 1937 + payload_size = exynos3250_jpeg_compressed_size(jpeg->regs); 1938 + else if (interrupt_timeout) 1939 + state = VB2_BUF_STATE_ERROR; 1940 + else 1941 + goto exit_unlock; 1942 + 1943 + src_buf = v4l2_m2m_src_buf_remove(curr_ctx->fh.m2m_ctx); 1944 + dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->fh.m2m_ctx); 1945 + 1946 + dst_buf->v4l2_buf.timecode = src_buf->v4l2_buf.timecode; 1947 + dst_buf->v4l2_buf.timestamp = src_buf->v4l2_buf.timestamp; 1948 + 1949 + v4l2_m2m_buf_done(src_buf, state); 1950 + if (curr_ctx->mode == S5P_JPEG_ENCODE) 1951 + vb2_set_plane_payload(dst_buf, 0, payload_size); 1952 + v4l2_m2m_buf_done(dst_buf, state); 1953 + v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->fh.m2m_ctx); 1954 + 1955 + curr_ctx->subsampling = 1956 + exynos3250_jpeg_get_subsampling_mode(jpeg->regs); 1957 + exit_unlock: 1958 + spin_unlock(&jpeg->slock); 1959 + return IRQ_HANDLED; 1960 + } 1961 + 2305 1962 static void *jpeg_get_drv_data(struct device *dev); 2306 1963 2307 1964 /* ··· 2420 1949 return ret; 2421 1950 } 2422 1951 dev_dbg(&pdev->dev, "clock source %p\n", jpeg->clk); 1952 + 1953 + jpeg->sclk = clk_get(&pdev->dev, "sclk"); 1954 + if (IS_ERR(jpeg->sclk)) 1955 + dev_info(&pdev->dev, "sclk clock not available\n"); 2423 1956 2424 1957 /* v4l2 device */ 2425 1958 ret = v4l2_device_register(&pdev->dev, &jpeg->v4l2_dev); ··· 2532 2057 2533 2058 clk_get_rollback: 2534 2059 clk_put(jpeg->clk); 2060 + if (!IS_ERR(jpeg->sclk)) 2061 + clk_put(jpeg->sclk); 2535 2062 2536 2063 return ret; 2537 2064 } ··· 2552 2075 v4l2_m2m_release(jpeg->m2m_dev); 2553 2076 v4l2_device_unregister(&jpeg->v4l2_dev); 2554 2077 2555 - if (!pm_runtime_status_suspended(&pdev->dev)) 2078 + if (!pm_runtime_status_suspended(&pdev->dev)) { 2556 2079 clk_disable_unprepare(jpeg->clk); 2080 + if (!IS_ERR(jpeg->sclk)) 2081 + clk_disable_unprepare(jpeg->sclk); 2082 + } 2557 2083 2558 2084 clk_put(jpeg->clk); 2085 + if (!IS_ERR(jpeg->sclk)) 2086 + clk_put(jpeg->sclk); 2559 2087 2560 2088 return 0; 2561 2089 } ··· 2570 2088 struct s5p_jpeg *jpeg = dev_get_drvdata(dev); 2571 2089 2572 2090 clk_disable_unprepare(jpeg->clk); 2091 + if (!IS_ERR(jpeg->sclk)) 2092 + clk_disable_unprepare(jpeg->sclk); 2573 2093 2574 2094 return 0; 2575 2095 } ··· 2586 2102 if (ret < 0) 2587 2103 return ret; 2588 2104 2105 + if (!IS_ERR(jpeg->sclk)) { 2106 + ret = clk_prepare_enable(jpeg->sclk); 2107 + if (ret < 0) 2108 + return ret; 2109 + } 2110 + 2589 2111 spin_lock_irqsave(&jpeg->slock, flags); 2590 2112 2591 2113 /* 2592 - * JPEG IP allows storing two Huffman tables for each component 2114 + * JPEG IP allows storing two Huffman tables for each component. 2593 2115 * We fill table 0 for each component and do this here only 2594 - * for S5PC210 device as Exynos4x12 requires programming its 2595 - * Huffman tables each time the encoding process is initialized. 2116 + * for S5PC210 and Exynos3250 SoCs. Exynos4x12 SoC requires 2117 + * programming its Huffman tables each time the encoding process 2118 + * is initialized, and thus it is accomplished in the device_run 2119 + * callback of m2m_ops. 2596 2120 */ 2597 - if (jpeg->variant->version == SJPEG_S5P) { 2121 + if (jpeg->variant->version == SJPEG_S5P || 2122 + jpeg->variant->version == SJPEG_EXYNOS3250) { 2598 2123 s5p_jpeg_set_hdctbl(jpeg->regs); 2599 2124 s5p_jpeg_set_hdctblg(jpeg->regs); 2600 2125 s5p_jpeg_set_hactbl(jpeg->regs); ··· 2643 2150 .fmt_ver_flag = SJPEG_FMT_FLAG_S5P, 2644 2151 }; 2645 2152 2153 + static struct s5p_jpeg_variant exynos3250_jpeg_drvdata = { 2154 + .version = SJPEG_EXYNOS3250, 2155 + .jpeg_irq = exynos3250_jpeg_irq, 2156 + .m2m_ops = &exynos3250_jpeg_m2m_ops, 2157 + .fmt_ver_flag = SJPEG_FMT_FLAG_EXYNOS3250, 2158 + }; 2159 + 2646 2160 static struct s5p_jpeg_variant exynos4_jpeg_drvdata = { 2647 2161 .version = SJPEG_EXYNOS4, 2648 2162 .jpeg_irq = exynos4_jpeg_irq, ··· 2662 2162 .compatible = "samsung,s5pv210-jpeg", 2663 2163 .data = &s5p_jpeg_drvdata, 2664 2164 }, { 2165 + .compatible = "samsung,exynos3250-jpeg", 2166 + .data = &exynos3250_jpeg_drvdata, 2167 + }, { 2665 2168 .compatible = "samsung,exynos4210-jpeg", 2666 - .data = &s5p_jpeg_drvdata, 2169 + .data = &exynos4_jpeg_drvdata, 2667 2170 }, { 2668 2171 .compatible = "samsung,exynos4212-jpeg", 2669 2172 .data = &exynos4_jpeg_drvdata,
+26 -6
drivers/media/platform/s5p-jpeg/jpeg-core.h
··· 35 35 #define S5P_JPEG_COEF32 0x6e 36 36 #define S5P_JPEG_COEF33 0x13 37 37 38 + #define EXYNOS3250_IRQ_TIMEOUT 0x10000000 39 + 38 40 /* a selection of JPEG markers */ 39 41 #define TEM 0x01 40 42 #define SOF0 0xc0 ··· 51 49 #define SJPEG_FMT_FLAG_DEC_CAPTURE (1 << 2) 52 50 #define SJPEG_FMT_FLAG_DEC_OUTPUT (1 << 3) 53 51 #define SJPEG_FMT_FLAG_S5P (1 << 4) 54 - #define SJPEG_FMT_FLAG_EXYNOS4 (1 << 5) 55 - #define SJPEG_FMT_RGB (1 << 6) 56 - #define SJPEG_FMT_NON_RGB (1 << 7) 52 + #define SJPEG_FMT_FLAG_EXYNOS3250 (1 << 5) 53 + #define SJPEG_FMT_FLAG_EXYNOS4 (1 << 6) 54 + #define SJPEG_FMT_RGB (1 << 7) 55 + #define SJPEG_FMT_NON_RGB (1 << 8) 57 56 58 57 #define S5P_JPEG_ENCODE 0 59 58 #define S5P_JPEG_DECODE 1 ··· 68 65 69 66 /* Version numbers */ 70 67 71 - #define SJPEG_S5P 1 72 - #define SJPEG_EXYNOS4 2 68 + #define SJPEG_S5P 1 69 + #define SJPEG_EXYNOS3250 2 70 + #define SJPEG_EXYNOS4 3 73 71 74 72 enum exynos4_jpeg_result { 75 73 OK_ENC_OR_DEC, ··· 99 95 * @regs: JPEG IP registers mapping 100 96 * @irq: JPEG IP irq 101 97 * @clk: JPEG IP clock 98 + * @sclk: Exynos3250 JPEG IP special clock 102 99 * @dev: JPEG IP struct device 103 100 * @alloc_ctx: videobuf2 memory allocator's context 101 + * @variant: driver variant to be used 102 + * @irq_status interrupt flags set during single encode/decode 103 + operation 104 + 104 105 */ 105 106 struct s5p_jpeg { 106 107 struct mutex lock; ··· 120 111 unsigned int irq; 121 112 enum exynos4_jpeg_result irq_ret; 122 113 struct clk *clk; 114 + struct clk *sclk; 123 115 struct device *dev; 124 116 void *alloc_ctx; 125 117 struct s5p_jpeg_variant *variant; 118 + u32 irq_status; 126 119 }; 127 120 128 121 struct s5p_jpeg_variant { ··· 175 164 * @jpeg: JPEG IP device for this context 176 165 * @mode: compression (encode) operation or decompression (decode) 177 166 * @compr_quality: destination image quality in compression (encode) mode 167 + * @restart_interval: JPEG restart interval for JPEG encoding 168 + * @subsampling: subsampling of a raw format or a JPEG 178 169 * @out_q: source (output) queue information 179 - * @cap_fmt: destination (capture) queue queue information 170 + * @cap_q: destination (capture) queue queue information 171 + * @scale_factor: scale factor for JPEG decoding 172 + * @crop_rect: a rectangle representing crop area of the output buffer 173 + * @fh: V4L2 file handle 180 174 * @hdr_parsed: set if header has been parsed during decompression 175 + * @crop_altered: set if crop rectangle has been altered by the user space 181 176 * @ctrl_handler: controls handler 182 177 */ 183 178 struct s5p_jpeg_ctx { ··· 194 177 unsigned short subsampling; 195 178 struct s5p_jpeg_q_data out_q; 196 179 struct s5p_jpeg_q_data cap_q; 180 + unsigned int scale_factor; 181 + struct v4l2_rect crop_rect; 197 182 struct v4l2_fh fh; 198 183 bool hdr_parsed; 184 + bool crop_altered; 199 185 struct v4l2_ctrl_handler ctrl_handler; 200 186 }; 201 187
+487
drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.c
··· 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 + }
+60
drivers/media/platform/s5p-jpeg/jpeg-hw-exynos3250.h
··· 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_ */
+246 -1
drivers/media/platform/s5p-jpeg/jpeg-regs.h
··· 2 2 * 3 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 6 * http://www.samsung.com 7 7 * 8 8 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com> ··· 372 372 373 373 /* JPEG AC chrominance (values) Huffman table register */ 374 374 #define EXYNOS4_HUFF_TBL_HACCV 0x310 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 375 620 376 621 #endif /* JPEG_REGS_H_ */ 377 622