[PATCH] media: jpeg: add driver for a version 2.x of jpeg H/W

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch add a driver for a version 2.x of jpeg H/W
in ths Samsung Exynos5 Soc.
A jpeg H/W version of Exynos4 SoC is 3.0

1. Encoding
 - input format : V4L2_PIX_FMT_RGB565X and V4L2_PIX_FMT_YUYV

2. Decoding
 - output format : V4L2_PIX_FMT_YUYV and V4L2_PIX_FMT_YUV420

Signed-off-by: youngmok song <ym.song@xxxxxxxxxxx>
---
 drivers/media/video/Kconfig                   |   17 +
 drivers/media/video/s5p-jpeg/Makefile         |    5 +-
 drivers/media/video/s5p-jpeg/jpeg-core.c      |  303 +-------------------
 drivers/media/video/s5p-jpeg/jpeg-hw-common.h |   34 +++
 drivers/media/video/s5p-jpeg/jpeg-hw-v2x.h    |  387 +++++++++++++++++++++++++
 drivers/media/video/s5p-jpeg/jpeg-regs-v2x.h  |  150 ++++++++++
 drivers/media/video/s5p-jpeg/jpeg-v2x.c       |  129 ++++++++
 drivers/media/video/s5p-jpeg/jpeg-v3.c        |  340 ++++++++++++++++++++++
 8 files changed, 1066 insertions(+), 299 deletions(-)
 create mode 100644 drivers/media/video/s5p-jpeg/jpeg-hw-common.h
 create mode 100644 drivers/media/video/s5p-jpeg/jpeg-hw-v2x.h
 create mode 100644 drivers/media/video/s5p-jpeg/jpeg-regs-v2x.h
 create mode 100644 drivers/media/video/s5p-jpeg/jpeg-v2x.c
 create mode 100644 drivers/media/video/s5p-jpeg/jpeg-v3.c

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 9adada0..551f925 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -1167,6 +1167,23 @@ config VIDEO_SAMSUNG_S5P_JPEG
 	select V4L2_MEM2MEM_DEV
 	---help---
 	  This is a v4l2 driver for Samsung S5P and EXYNOS4 JPEG codec
+choice
+	prompt "JPEG V4L2 Driver"
+	default S5P_JPEG_V3
+	depends on VIDEO_SAMSUNG_S5P_JPEG
+	---help---
+	  Select version of MFC driver
+
+config S5P_JPEG_V3
+	bool "JPEG 3.x"
+	---help---
+	  Use JPEG 3.x V4L2 Driver
+
+config S5P_JPEG_V2
+	bool "JPEG 2.x"
+	---help---
+	  Use JPEG 2.x V4L2 Driver
+endchoice
 
 config VIDEO_SAMSUNG_S5P_MFC
 	tristate "Samsung S5P MFC 5.1 Video Codec"
diff --git a/drivers/media/video/s5p-jpeg/Makefile b/drivers/media/video/s5p-jpeg/Makefile
index ddc2900..446d07f 100644
--- a/drivers/media/video/s5p-jpeg/Makefile
+++ b/drivers/media/video/s5p-jpeg/Makefile
@@ -1,2 +1,5 @@
-s5p-jpeg-objs := jpeg-core.o
 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_JPEG) := s5p-jpeg.o
+
+s5p-jpeg-objs := jpeg-core.o
+obj-$(CONFIG_S5P_JPEG_V3) += jpeg-v3.o
+obj-$(CONFIG_S5P_JPEG_V2) += jpeg-v2x.o
diff --git a/drivers/media/video/s5p-jpeg/jpeg-core.c b/drivers/media/video/s5p-jpeg/jpeg-core.c
index 1105a87..cf917cd 100644
--- a/drivers/media/video/s5p-jpeg/jpeg-core.c
+++ b/drivers/media/video/s5p-jpeg/jpeg-core.c
@@ -28,7 +28,7 @@
 #include <media/videobuf2-dma-contig.h>
 
 #include "jpeg-core.h"
-#include "jpeg-hw.h"
+#include "jpeg-hw-common.h"
 
 static struct s5p_jpeg_fmt formats_enc[] = {
 	{
@@ -83,182 +83,6 @@ static struct s5p_jpeg_fmt formats_dec[] = {
 };
 #define NUM_FORMATS_DEC ARRAY_SIZE(formats_dec)
 
-static const unsigned char qtbl_luminance[4][64] = {
-	{/* level 1 - high quality */
-		 8,  6,  6,  8, 12, 14, 16, 17,
-		 6,  6,  6,  8, 10, 13, 12, 15,
-		 6,  6,  7,  8, 13, 14, 18, 24,
-		 8,  8,  8, 14, 13, 19, 24, 35,
-		12, 10, 13, 13, 20, 26, 34, 39,
-		14, 13, 14, 19, 26, 34, 39, 39,
-		16, 12, 18, 24, 34, 39, 39, 39,
-		17, 15, 24, 35, 39, 39, 39, 39
-	},
-	{/* level 2 */
-		12,  8,  8, 12, 17, 21, 24, 23,
-		 8,  9,  9, 11, 15, 19, 18, 23,
-		 8,  9, 10, 12, 19, 20, 27, 36,
-		12, 11, 12, 21, 20, 28, 36, 53,
-		17, 15, 19, 20, 30, 39, 51, 59,
-		21, 19, 20, 28, 39, 51, 59, 59,
-		24, 18, 27, 36, 51, 59, 59, 59,
-		23, 23, 36, 53, 59, 59, 59, 59
-	},
-	{/* level 3 */
-		16, 11, 11, 16, 23, 27, 31, 30,
-		11, 12, 12, 15, 20, 23, 23, 30,
-		11, 12, 13, 16, 23, 26, 35, 47,
-		16, 15, 16, 23, 26, 37, 47, 64,
-		23, 20, 23, 26, 39, 51, 64, 64,
-		27, 23, 26, 37, 51, 64, 64, 64,
-		31, 23, 35, 47, 64, 64, 64, 64,
-		30, 30, 47, 64, 64, 64, 64, 64
-	},
-	{/*level 4 - low quality */
-		20, 16, 25, 39, 50, 46, 62, 68,
-		16, 18, 23, 38, 38, 53, 65, 68,
-		25, 23, 31, 38, 53, 65, 68, 68,
-		39, 38, 38, 53, 65, 68, 68, 68,
-		50, 38, 53, 65, 68, 68, 68, 68,
-		46, 53, 65, 68, 68, 68, 68, 68,
-		62, 65, 68, 68, 68, 68, 68, 68,
-		68, 68, 68, 68, 68, 68, 68, 68
-	}
-};
-
-static const unsigned char qtbl_chrominance[4][64] = {
-	{/* level 1 - high quality */
-		 9,  8,  9, 11, 14, 17, 19, 24,
-		 8, 10,  9, 11, 14, 13, 17, 22,
-		 9,  9, 13, 14, 13, 15, 23, 26,
-		11, 11, 14, 14, 15, 20, 26, 33,
-		14, 14, 13, 15, 20, 24, 33, 39,
-		17, 13, 15, 20, 24, 32, 39, 39,
-		19, 17, 23, 26, 33, 39, 39, 39,
-		24, 22, 26, 33, 39, 39, 39, 39
-	},
-	{/* level 2 */
-		13, 11, 13, 16, 20, 20, 29, 37,
-		11, 14, 14, 14, 16, 20, 26, 32,
-		13, 14, 15, 17, 20, 23, 35, 40,
-		16, 14, 17, 21, 23, 30, 40, 50,
-		20, 16, 20, 23, 30, 37, 50, 59,
-		20, 20, 23, 30, 37, 48, 59, 59,
-		29, 26, 35, 40, 50, 59, 59, 59,
-		37, 32, 40, 50, 59, 59, 59, 59
-	},
-	{/* level 3 */
-		17, 15, 17, 21, 20, 26, 38, 48,
-		15, 19, 18, 17, 20, 26, 35, 43,
-		17, 18, 20, 22, 26, 30, 46, 53,
-		21, 17, 22, 28, 30, 39, 53, 64,
-		20, 20, 26, 30, 39, 48, 64, 64,
-		26, 26, 30, 39, 48, 63, 64, 64,
-		38, 35, 46, 53, 64, 64, 64, 64,
-		48, 43, 53, 64, 64, 64, 64, 64
-	},
-	{/*level 4 - low quality */
-		21, 25, 32, 38, 54, 68, 68, 68,
-		25, 28, 24, 38, 54, 68, 68, 68,
-		32, 24, 32, 43, 66, 68, 68, 68,
-		38, 38, 43, 53, 68, 68, 68, 68,
-		54, 54, 66, 68, 68, 68, 68, 68,
-		68, 68, 68, 68, 68, 68, 68, 68,
-		68, 68, 68, 68, 68, 68, 68, 68,
-		68, 68, 68, 68, 68, 68, 68, 68
-	}
-};
-
-static const unsigned char hdctbl0[16] = {
-	0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
-};
-
-static const unsigned char hdctblg0[12] = {
-	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
-};
-static const unsigned char hactbl0[16] = {
-	0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
-};
-static const unsigned char hactblg0[162] = {
-	0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
-	0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
-	0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
-	0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
-	0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
-	0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
-	0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
-	0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
-	0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
-	0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
-	0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
-	0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
-	0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
-	0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
-	0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
-	0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
-	0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
-	0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
-	0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
-	0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
-	0xf9, 0xfa
-};
-
-static inline void jpeg_set_qtbl(void __iomem *regs, const unsigned char *qtbl,
-		   unsigned long tab, int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++)
-		writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
-}
-
-static inline void jpeg_set_qtbl_lum(void __iomem *regs, int quality)
-{
-	/* this driver fills quantisation table 0 with data for luma */
-	jpeg_set_qtbl(regs, qtbl_luminance[quality], S5P_JPG_QTBL_CONTENT(0),
-		      ARRAY_SIZE(qtbl_luminance[quality]));
-}
-
-static inline void jpeg_set_qtbl_chr(void __iomem *regs, int quality)
-{
-	/* this driver fills quantisation table 1 with data for chroma */
-	jpeg_set_qtbl(regs, qtbl_chrominance[quality], S5P_JPG_QTBL_CONTENT(1),
-		      ARRAY_SIZE(qtbl_chrominance[quality]));
-}
-
-static inline void jpeg_set_htbl(void __iomem *regs, const unsigned char *htbl,
-		   unsigned long tab, int len)
-{
-	int i;
-
-	for (i = 0; i < len; i++)
-		writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
-}
-
-static inline void jpeg_set_hdctbl(void __iomem *regs)
-{
-	/* this driver fills table 0 for this component */
-	jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0), ARRAY_SIZE(hdctbl0));
-}
-
-static inline void jpeg_set_hdctblg(void __iomem *regs)
-{
-	/* this driver fills table 0 for this component */
-	jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0), ARRAY_SIZE(hdctblg0));
-}
-
-static inline void jpeg_set_hactbl(void __iomem *regs)
-{
-	/* this driver fills table 0 for this component */
-	jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0), ARRAY_SIZE(hactbl0));
-}
-
-static inline void jpeg_set_hactblg(void __iomem *regs)
-{
-	/* this driver fills table 0 for this component */
-	jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0), ARRAY_SIZE(hactblg0));
-}
-
 /*
  * ============================================================================
  * Device file operations
@@ -890,78 +714,7 @@ static const struct v4l2_ioctl_ops s5p_jpeg_ioctl_ops = {
 
 static void s5p_jpeg_device_run(void *priv)
 {
-	struct s5p_jpeg_ctx *ctx = priv;
-	struct s5p_jpeg *jpeg = ctx->jpeg;
-	struct vb2_buffer *src_buf, *dst_buf;
-	unsigned long src_addr, dst_addr;
-
-	src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
-	dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
-	src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
-	dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
-
-	jpeg_reset(jpeg->regs);
-	jpeg_poweron(jpeg->regs);
-	jpeg_proc_mode(jpeg->regs, ctx->mode);
-	if (ctx->mode == S5P_JPEG_ENCODE) {
-		if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
-			jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_565);
-		else
-			jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_422);
-		if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
-			jpeg_subsampling_mode(jpeg->regs,
-					      S5P_JPEG_SUBSAMPLING_422);
-		else
-			jpeg_subsampling_mode(jpeg->regs,
-					      S5P_JPEG_SUBSAMPLING_420);
-		jpeg_dri(jpeg->regs, 0);
-		jpeg_x(jpeg->regs, ctx->out_q.w);
-		jpeg_y(jpeg->regs, ctx->out_q.h);
-		jpeg_imgadr(jpeg->regs, src_addr);
-		jpeg_jpgadr(jpeg->regs, dst_addr);
-
-		/* ultimately comes from sizeimage from userspace */
-		jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
-
-		/* JPEG RGB to YCbCr conversion matrix */
-		jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
-		jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
-		jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
-		jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
-		jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
-		jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
-		jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
-		jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
-		jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
-
-		/*
-		 * JPEG IP allows storing 4 quantization tables
-		 * We fill table 0 for luma and table 1 for chroma
-		 */
-		jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
-		jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
-		/* use table 0 for Y */
-		jpeg_qtbl(jpeg->regs, 1, 0);
-		/* use table 1 for Cb and Cr*/
-		jpeg_qtbl(jpeg->regs, 2, 1);
-		jpeg_qtbl(jpeg->regs, 3, 1);
-
-		/* Y, Cb, Cr use Huffman table 0 */
-		jpeg_htbl_ac(jpeg->regs, 1);
-		jpeg_htbl_dc(jpeg->regs, 1);
-		jpeg_htbl_ac(jpeg->regs, 2);
-		jpeg_htbl_dc(jpeg->regs, 2);
-		jpeg_htbl_ac(jpeg->regs, 3);
-		jpeg_htbl_dc(jpeg->regs, 3);
-	} else {
-		jpeg_rst_int_enable(jpeg->regs, true);
-		jpeg_data_num_int_enable(jpeg->regs, true);
-		jpeg_final_mcu_num_int_enable(jpeg->regs, true);
-		jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
-		jpeg_jpgadr(jpeg->regs, src_addr);
-		jpeg_imgadr(jpeg->regs, dst_addr);
-	}
-	jpeg_start(jpeg->regs);
+	s5p_jpeg_execute(priv);
 }
 
 static int s5p_jpeg_job_ready(void *priv)
@@ -1153,46 +906,7 @@ static int queue_init(void *priv, struct vb2_queue *src_vq,
 
 static irqreturn_t s5p_jpeg_irq(int irq, void *dev_id)
 {
-	struct s5p_jpeg *jpeg = dev_id;
-	struct s5p_jpeg_ctx *curr_ctx;
-	struct vb2_buffer *src_buf, *dst_buf;
-	unsigned long payload_size = 0;
-	enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
-	bool enc_jpeg_too_large = false;
-	bool timer_elapsed = false;
-	bool op_completed = false;
-
-	curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
-
-	src_buf = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
-	dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
-
-	if (curr_ctx->mode == S5P_JPEG_ENCODE)
-		enc_jpeg_too_large = jpeg_enc_stream_stat(jpeg->regs);
-	timer_elapsed = jpeg_timer_stat(jpeg->regs);
-	op_completed = jpeg_result_stat_ok(jpeg->regs);
-	if (curr_ctx->mode == S5P_JPEG_DECODE)
-		op_completed = op_completed && jpeg_stream_stat_ok(jpeg->regs);
-
-	if (enc_jpeg_too_large) {
-		state = VB2_BUF_STATE_ERROR;
-		jpeg_clear_enc_stream_stat(jpeg->regs);
-	} else if (timer_elapsed) {
-		state = VB2_BUF_STATE_ERROR;
-		jpeg_clear_timer_stat(jpeg->regs);
-	} else if (!op_completed) {
-		state = VB2_BUF_STATE_ERROR;
-	} else {
-		payload_size = jpeg_compressed_size(jpeg->regs);
-	}
-
-	v4l2_m2m_buf_done(src_buf, state);
-	if (curr_ctx->mode == S5P_JPEG_ENCODE)
-		vb2_set_plane_payload(dst_buf, 0, payload_size);
-	v4l2_m2m_buf_done(dst_buf, state);
-	v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->m2m_ctx);
-
-	jpeg_clear_int(jpeg->regs);
+	s5p_jpeg_irq_execute(dev_id);
 
 	return IRQ_HANDLED;
 }
@@ -1425,15 +1139,8 @@ static int s5p_jpeg_runtime_suspend(struct device *dev)
 
 static int s5p_jpeg_runtime_resume(struct device *dev)
 {
-	struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
-	/*
-	 * JPEG IP allows storing two Huffman tables for each component
-	 * We fill table 0 for each component
-	 */
-	jpeg_set_hdctbl(jpeg->regs);
-	jpeg_set_hdctblg(jpeg->regs);
-	jpeg_set_hactbl(jpeg->regs);
-	jpeg_set_hactblg(jpeg->regs);
+	s5p_jpeg_runtime_resume_execute(dev);
+
 	return 0;
 }
 
diff --git a/drivers/media/video/s5p-jpeg/jpeg-hw-common.h b/drivers/media/video/s5p-jpeg/jpeg-hw-common.h
new file mode 100644
index 0000000..c649598
--- /dev/null
+++ b/drivers/media/video/s5p-jpeg/jpeg-hw-common.h
@@ -0,0 +1,34 @@
+/* linux/drivers/media/video/s5p-jpeg/jpeg-hw.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Author: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef JPEG_HW_COMMON_H_
+#define JPEG_HW_COMMON_H_
+
+#include <linux/io.h>
+#include <linux/delay.h>
+
+void s5p_jpeg_execute(void *priv);
+void s5p_jpeg_irq_execute(void *dev_id);
+void s5p_jpeg_runtime_resume_execute(struct device *dev);
+
+#define S5P_JPEG_MIN_WIDTH		32
+#define S5P_JPEG_MIN_HEIGHT		32
+#define S5P_JPEG_MAX_WIDTH		8192
+#define S5P_JPEG_MAX_HEIGHT		8192
+#define S5P_JPEG_ENCODE			0
+#define S5P_JPEG_DECODE			1
+#define S5P_JPEG_RAW_IN_565		0
+#define S5P_JPEG_RAW_IN_422		1
+#define S5P_JPEG_SUBSAMPLING_422	0
+#define S5P_JPEG_SUBSAMPLING_420	1
+#define S5P_JPEG_RAW_OUT_422		0
+#define S5P_JPEG_RAW_OUT_420		1
+#endif /* JPEG_HW_COMMON_H_ */
diff --git a/drivers/media/video/s5p-jpeg/jpeg-hw-v2x.h b/drivers/media/video/s5p-jpeg/jpeg-hw-v2x.h
new file mode 100644
index 0000000..90bd60b
--- /dev/null
+++ b/drivers/media/video/s5p-jpeg/jpeg-hw-v2x.h
@@ -0,0 +1,387 @@
+/* linux/drivers/media/video/s5p-jpeg/jpeg-hw-v2x.h
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef JPEG_HW_V2X_H_
+#define JPEG_HW_V2X_H_
+
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include "jpeg-regs-v2x.h"
+
+#define S5P_JPEG_MIN_WIDTH		32
+#define S5P_JPEG_MIN_HEIGHT		32
+#define S5P_JPEG_MAX_WIDTH		8192
+#define S5P_JPEG_MAX_HEIGHT		8192
+#define S5P_JPEG_ENCODE			0
+#define S5P_JPEG_DECODE			1
+#define S5P_JPEG_RAW_IN_565		0
+#define S5P_JPEG_RAW_IN_422		1
+#define S5P_JPEG_SUBSAMPLING_422	0
+#define S5P_JPEG_SUBSAMPLING_420	1
+#define S5P_JPEG_RAW_OUT_422		0
+#define S5P_JPEG_RAW_OUT_420		1
+
+/* Q-table for JPEG */
+/*  ITU standard Q-table */
+static unsigned int ITU_Q_tbl[4][16] = {
+	{
+	0x01010101, 0x01020303, 0x01010101, 0x01030303, /* Y */
+	0x01010101, 0x02030303, 0x01010101, 0x03040403,
+	0x01010203, 0x03050504, 0x01020303, 0x04050605,
+	0x02030404, 0x05060605, 0x04050505, 0x06050505
+	} , {
+	0x01010102, 0x05050505, 0x01010103, 0x05050505, /* CbCr */
+	0x01010503, 0x05050505, 0x02030505, 0x05050505,
+	0x05050505, 0x05050505, 0x05050505, 0x05050505,
+	0x05050505, 0x05050505, 0x05050505, 0x05050505
+	} , {
+	0x05020205, 0x0a161e25, 0x02020307, 0x0c232521, /* Y */
+	0x0302050a, 0x16222b22, 0x0305090e, 0x1e393326,
+	0x06091422, 0x2a384431, 0x0a122118, 0x34454b3c,
+	0x1d283238, 0x44525142, 0x2d3c3e40, 0x4a424441
+	} , {
+	0x05020205, 0x251e160a, 0x07030202, 0x2125230c, /* CbCr */
+	0x0a050203, 0x222b2216, 0x0e090503, 0x2633391e,
+	0x22140906, 0x3144382a, 0x1821120a, 0x3c4b4534,
+	0x3832281d, 0x42515244, 0x403e3c2d, 0x4144424a
+	}
+};
+
+/* ITU Luminace Huffman Table */
+static unsigned int ITU_H_tbl_len_DC_luminance[4] = {
+	0x01050100, 0x01010101, 0x00000001, 0x00000000
+};
+static unsigned int ITU_H_tbl_val_DC_luminance[3] = {
+	0x03020100, 0x07060504, 0x0b0a0908
+};
+
+/* ITU Chrominace Huffman Table */
+static unsigned int ITU_H_tbl_len_DC_chrominance[4] = {
+	0x01010300, 0x01010101, 0x00010101, 0x00000000
+};
+static unsigned int ITU_H_tbl_val_DC_chrominance[3] = {
+	0x03020100, 0x07060504, 0x0b0a0908
+};
+
+static unsigned int ITU_H_tbl_len_AC_luminance[4] = {
+	0x03010200, 0x03040203, 0x04040505, 0x7d010000
+};
+
+static unsigned int ITU_H_tbl_val_AC_luminance[41] = {
+	0x00030201, 0x12051104, 0x06413121, 0x07615113,
+	0x32147122, 0x08a19181, 0xc1b14223, 0xf0d15215,
+	0x72623324, 0x160a0982, 0x1a191817, 0x28272625,
+	0x35342a29, 0x39383736, 0x4544433a, 0x49484746,
+	0x5554534a, 0x59585756, 0x6564635a, 0x69686766,
+	0x7574736a, 0x79787776, 0x8584837a, 0x89888786,
+	0x9493928a, 0x98979695, 0xa3a29a99, 0xa7a6a5a4,
+	0xb2aaa9a8, 0xb6b5b4b3, 0xbab9b8b7, 0xc5c4c3c2,
+	0xc9c8c7c6, 0xd4d3d2ca, 0xd8d7d6d5, 0xe2e1dad9,
+	0xe6e5e4e3, 0xeae9e8e7, 0xf4f3f2f1, 0xf8f7f6f5,
+	0x0000faf9
+};
+
+static u32 ITU_H_tbl_len_AC_chrominance[4] = {
+	0x02010200, 0x04030404, 0x04040507, 0x77020100
+};
+static u32 ITU_H_tbl_val_AC_chrominance[41] = {
+	0x03020100, 0x21050411, 0x41120631, 0x71610751,
+	0x81322213, 0x91421408, 0x09c1b1a1, 0xf0523323,
+	0xd1726215, 0x3424160a, 0x17f125e1, 0x261a1918,
+	0x2a292827, 0x38373635, 0x44433a39, 0x48474645,
+	0x54534a49, 0x58575655, 0x64635a59, 0x68676665,
+	0x74736a69, 0x78777675, 0x83827a79, 0x87868584,
+	0x928a8988, 0x96959493, 0x9a999897, 0xa5a4a3a2,
+	0xa9a8a7a6, 0xb4b3b2aa, 0xb8b7b6b5, 0xc3c2bab9,
+	0xc7c6c5c4, 0xd2cac9c8, 0xd6d5d4d3, 0xdad9d8d7,
+	0xe5e4e3e2, 0xe9e8e7e6, 0xf4f3f2ea, 0xf8f7f6f5,
+	0x0000faf9
+};
+
+static inline void jpeg_reset(void __iomem *regs)
+{
+	unsigned long reg;
+
+	reg = readl(regs + S5P_JPEG_CNTL_REG);
+	writel(reg & ~S5P_JPEG_SOFT_RESET_HI,
+			regs + S5P_JPEG_CNTL_REG);
+
+	ndelay(100000);
+
+	writel(reg | S5P_JPEG_SOFT_RESET_HI,
+			regs + S5P_JPEG_CNTL_REG);
+
+}
+
+static inline void jpeg_input_raw_mode(void __iomem *regs, unsigned long mode)
+{
+	unsigned long reg, m;
+
+	if (mode == S5P_JPEG_RAW_IN_565)
+		m = S5P_JPEG_ENC_RGB_IMG |
+				S5P_JPEG_RGB_IP_RGB_16BIT_IMG;
+	else if (mode == S5P_JPEG_RAW_IN_422)
+		m = S5P_JPEG_ENC_YUV_422_IMG |
+				S5P_JPEG_YUV_422_IP_YUV_422_1P_IMG;
+
+	reg = readl(regs + S5P_JPEG_IMG_FMT_REG) &
+			S5P_JPEG_ENC_IN_FMT_MASK; /* clear except enc format */
+	reg |= m;
+
+	writel(reg, regs + S5P_JPEG_IMG_FMT_REG);
+}
+
+static inline void jpeg_proc_mode(void __iomem *regs, unsigned long mode)
+{
+	unsigned int reg, m;
+
+	m = S5P_JPEG_DEC_MODE;
+	if (mode == S5P_JPEG_ENCODE)
+		m = S5P_JPEG_ENC_MODE;
+	else
+		m = S5P_JPEG_DEC_MODE;
+
+	reg = readl(regs + S5P_JPEG_CNTL_REG);
+	reg &= S5P_JPEG_ENC_DEC_MODE_MASK;
+	reg |= m;
+
+	writel(reg, regs + S5P_JPEG_CNTL_REG);
+}
+
+static inline void jpeg_set_dec_bitstream_size(void __iomem *regs, u32 size)
+{
+	writel(size, regs + S5P_JPEG_BITSTREAM_SIZE_REG);
+}
+
+static inline void jpeg_subsampling_mode(void __iomem *regs, unsigned long mode)
+{
+	unsigned long reg, m;
+
+	m = S5P_JPEG_ENC_FMT_YUV_422;
+	if (mode == S5P_JPEG_SUBSAMPLING_422)
+		m = S5P_JPEG_ENC_FMT_YUV_422;
+	else if (mode == S5P_JPEG_SUBSAMPLING_420)
+		m = S5P_JPEG_ENC_FMT_YUV_420;
+
+	reg = readl(regs + S5P_JPEG_IMG_FMT_REG);
+	reg &= ~S5P_JPEG_ENC_FMT_MASK;
+	reg |= m;
+
+	writel(reg, regs + S5P_JPEG_IMG_FMT_REG);
+}
+
+static void jpeg_set_encode_tbl_select(void __iomem *regs,
+		int quality)
+{
+	unsigned int	reg;
+
+	switch (quality) {
+	case 0:
+		reg = S5P_JPEG_Q_TBL_COMP1_0 | S5P_JPEG_Q_TBL_COMP2_1 |
+			S5P_JPEG_Q_TBL_COMP3_1 |
+			S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_0 |
+			S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_0 |
+			S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_1;
+		break;
+	case 1:
+		reg = S5P_JPEG_Q_TBL_COMP1_0 | S5P_JPEG_Q_TBL_COMP2_3 |
+			S5P_JPEG_Q_TBL_COMP3_3 |
+			S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_0 |
+			S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_0 |
+			S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_1;
+		break;
+	case 2:
+		reg = S5P_JPEG_Q_TBL_COMP1_2 | S5P_JPEG_Q_TBL_COMP2_1 |
+			S5P_JPEG_Q_TBL_COMP3_1 |
+			S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_0 |
+			S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_0 |
+			S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_1;
+		break;
+	case 3:
+		reg = S5P_JPEG_Q_TBL_COMP1_2 | S5P_JPEG_Q_TBL_COMP2_3 |
+			S5P_JPEG_Q_TBL_COMP3_3 |
+			S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_0 |
+			S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_0 |
+			S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_1;
+		break;
+	default:
+		reg = S5P_JPEG_Q_TBL_COMP1_0 | S5P_JPEG_Q_TBL_COMP2_1 |
+			S5P_JPEG_Q_TBL_COMP3_1 |
+			S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_0 |
+			S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_0 |
+			S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_1;
+		break;
+	}
+	writel(reg, regs + S5P_JPEG_TBL_SEL_REG);
+}
+
+static inline void jpeg_x_y(void __iomem *regs, unsigned int x, unsigned int y)
+{
+	writel(0x0, regs + S5P_JPEG_IMG_SIZE_REG); /* clear */
+	writel(S5P_JPEG_X_SIZE(x) | S5P_JPEG_Y_SIZE(y),
+			regs + S5P_JPEG_IMG_SIZE_REG);
+}
+
+static inline void jpeg_set_dec_scaling(void __iomem *regs,
+		int x_value, int y_value)
+{
+	unsigned int	reg;
+
+	reg = readl(regs + S5P_JPEG_CNTL_REG) &
+			~(S5P_JPEG_HOR_SCALING_MASK |
+				S5P_JPEG_VER_SCALING_MASK);
+
+	writel(reg | S5P_JPEG_HOR_SCALING(x_value) |
+			S5P_JPEG_VER_SCALING(y_value),
+				regs + S5P_JPEG_CNTL_REG);
+}
+
+static inline void jpeg_outform_raw(void __iomem *regs, unsigned long format)
+{
+	unsigned long reg;
+
+	writel(0, regs + S5P_JPEG_IMG_FMT_REG); /* clear */
+
+	if (format == S5P_JPEG_RAW_OUT_422)
+		reg = S5P_JPEG_DEC_YUV_422_IMG |
+				S5P_JPEG_YUV_422_IP_YUV_422_1P_IMG;
+	else if (format == S5P_JPEG_RAW_OUT_420)
+		reg = S5P_JPEG_DEC_YUV_420_IMG |
+				S5P_JPEG_YUV_420_IP_YUV_420_3P_IMG;
+
+	writel(reg, regs + S5P_JPEG_IMG_FMT_REG);
+}
+
+static inline void jpeg_jpgadr(void __iomem *regs, unsigned long addr)
+{
+	writel(addr, regs + S5P_JPEG_OUT_MEM_BASE_REG);
+}
+
+static inline void jpeg_dec_imgadr(void __iomem *regs, unsigned long addr,
+			unsigned long format, u32 width, u32 height)
+{
+	if (format == S5P_JPEG_RAW_OUT_422) {
+		writel(addr, regs + S5P_JPEG_IMG_BA_PLANE_1_REG);
+		writel(0, regs + S5P_JPEG_IMG_BA_PLANE_2_REG);
+		writel(0, regs + S5P_JPEG_IMG_BA_PLANE_3_REG);
+	} else if (format == S5P_JPEG_RAW_OUT_420) {
+		writel(addr, regs + S5P_JPEG_IMG_BA_PLANE_1_REG);
+		writel(addr + width * height,
+			regs + S5P_JPEG_IMG_BA_PLANE_2_REG);
+		writel(addr + width * height + (width * height / 4),
+			regs + S5P_JPEG_IMG_BA_PLANE_3_REG);
+	}
+}
+
+static inline void jpeg_enc_imgadr(void __iomem *regs, unsigned long addr)
+{
+	writel(addr, regs + S5P_JPEG_IMG_BA_PLANE_1_REG);
+}
+
+static unsigned int jpeg_get_int_status(void __iomem *regs)
+{
+	return readl(regs + S5P_JPEG_INT_STATUS_REG);
+}
+
+static void jpeg_set_interrupt(void __iomem *regs)
+{
+	unsigned long reg;
+
+	reg = readl(regs + S5P_JPEG_INT_EN_REG) & ~S5P_JPEG_INT_EN_MASK;
+	writel(S5P_JPEG_INT_EN_ALL, regs + S5P_JPEG_INT_EN_REG);
+}
+
+static void jpeg_set_huf_table_enable(void __iomem *regs, int value)
+{
+	unsigned long	reg;
+
+	reg = readl(regs + S5P_JPEG_CNTL_REG) & ~S5P_JPEG_HUF_TBL_EN;
+
+	if (value == 1)
+		writel(reg | S5P_JPEG_HUF_TBL_EN, regs + S5P_JPEG_CNTL_REG);
+	else
+		writel(reg | ~S5P_JPEG_HUF_TBL_EN, regs + S5P_JPEG_CNTL_REG);
+}
+
+static inline void jpeg_qtbl(void __iomem *regs)
+{
+	int i;
+
+	for (i = 0; i < 16; i++)
+		writel((unsigned int)ITU_Q_tbl[0][i],
+			regs + S5P_JPEG_QUAN_TBL_ENTRY_REG + (i*0x04));
+
+	for (i = 0; i < 16; i++)
+		writel((unsigned int)ITU_Q_tbl[1][i],
+			regs + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x40 + (i*0x04));
+
+	for (i = 0; i < 16; i++)
+		writel((unsigned int)ITU_Q_tbl[2][i],
+			regs + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x80 + (i*0x04));
+
+	for (i = 0; i < 16; i++)
+		writel((unsigned int)ITU_Q_tbl[3][i],
+			regs + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0xc0 + (i*0x04));
+}
+
+static inline void jpeg_htbl_ac(void __iomem *regs)
+{
+	int i;
+
+	for (i = 0; i < 4; i++)
+		writel((unsigned int)ITU_H_tbl_len_AC_luminance[i],
+			regs + S5P_JPEG_HUFF_TBL_ENTRY_REG + 0x40 + (i*0x04));
+
+	for (i = 0; i < 41; i++)
+		writel((unsigned int)ITU_H_tbl_val_AC_luminance[i],
+			regs + S5P_JPEG_HUFF_TBL_ENTRY_REG + 0x50 + (i*0x04));
+
+	for (i = 0; i < 4; i++)
+		writel((unsigned int)ITU_H_tbl_len_AC_chrominance[i],
+			regs + S5P_JPEG_HUFF_TBL_ENTRY_REG + 0x100 + (i*0x04));
+
+	for (i = 0; i < 41; i++)
+		writel((unsigned int)ITU_H_tbl_val_AC_chrominance[i],
+			regs + S5P_JPEG_HUFF_TBL_ENTRY_REG + 0x110 + (i*0x04));
+}
+
+static inline void jpeg_htbl_dc(void __iomem *regs)
+{
+	int i;
+
+	for (i = 0; i < 4; i++)
+		writel((unsigned int)ITU_H_tbl_len_DC_luminance[i],
+			regs + S5P_JPEG_HUFF_TBL_ENTRY_REG + (i*0x04));
+
+	for (i = 0; i < 3; i++)
+		writel((unsigned int)ITU_H_tbl_val_DC_luminance[i],
+			regs + S5P_JPEG_HUFF_TBL_ENTRY_REG + 0x10 + (i*0x04));
+
+	for (i = 0; i < 4; i++)
+		writel((unsigned int)ITU_H_tbl_len_DC_chrominance[i],
+			regs + S5P_JPEG_HUFF_TBL_ENTRY_REG + 0x20 + (i*0x04));
+
+	for (i = 0; i < 3; i++)
+		writel((unsigned int)ITU_H_tbl_val_DC_chrominance[i],
+			regs + S5P_JPEG_HUFF_TBL_ENTRY_REG + 0x30 + (i*0x04));
+}
+
+static void jpeg_set_encode_hoff_cnt(void __iomem *regs)
+{
+	writel(0x1a2, regs + S5P_JPEG_HUFF_CNT_REG);
+}
+
+static unsigned int jpeg_compressed_size(void __iomem *regs)
+{
+	return readl(regs + S5P_JPEG_BITSTREAM_SIZE_REG);
+}
+
+#endif /* JPEG_HW_V2X_H_ */
diff --git a/drivers/media/video/s5p-jpeg/jpeg-regs-v2x.h b/drivers/media/video/s5p-jpeg/jpeg-regs-v2x.h
new file mode 100644
index 0000000..8305475
--- /dev/null
+++ b/drivers/media/video/s5p-jpeg/jpeg-regs-v2x.h
@@ -0,0 +1,150 @@
+/* linux/drivers/media/video/s5p-jpeg/jpeg-regs-v2x.h
+ *
+ * Register definition file for Samsung JPEG codec driver
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http:www.samsung.com
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef JPEG_REGS_H_
+#define JPEG_REGS_H_
+
+/* JPEG Codec Control Registers */
+#define S5P_JPEG_CNTL_REG		0x00
+#define S5P_JPEG_INT_EN_REG		0x04
+#define S5P_JPEG_INT_STATUS_REG		0x0c
+#define S5P_JPEG_OUT_MEM_BASE_REG		0x10
+#define S5P_JPEG_IMG_SIZE_REG		0x14
+#define S5P_JPEG_IMG_BA_PLANE_1_REG		0x18
+#define S5P_JPEG_IMG_BA_PLANE_2_REG		0x24
+#define S5P_JPEG_IMG_BA_PLANE_3_REG		0x30
+
+#define S5P_JPEG_TBL_SEL_REG		0x3c
+
+#define S5P_JPEG_IMG_FMT_REG		0x40
+
+#define S5P_JPEG_BITSTREAM_SIZE_REG		0x44
+#define S5P_JPEG_HUFF_CNT_REG		0x4c
+
+#define S5P_JPEG_QUAN_TBL_ENTRY_REG		0x100
+#define S5P_JPEG_HUFF_TBL_ENTRY_REG		0x200
+
+
+/****************************************************************/
+/* Bit definition part												*/
+/****************************************************************/
+
+/* JPEG CNTL Register bit */
+#define S5P_JPEG_ENC_DEC_MODE_MASK			(0xfffffffc << 0)
+#define S5P_JPEG_DEC_MODE			(1 << 0)
+#define S5P_JPEG_ENC_MODE			(1 << 1)
+#define S5P_JPEG_HUF_TBL_EN			(1 << 19)
+#define S5P_JPEG_HOR_SCALING_SHIFT		20
+#define S5P_JPEG_HOR_SCALING_MASK		\
+			(3 << S5P_JPEG_HOR_SCALING_SHIFT)
+#define S5P_JPEG_HOR_SCALING(x)			\
+			(((x) & 0x3) << S5P_JPEG_HOR_SCALING_SHIFT)
+#define S5P_JPEG_VER_SCALING_SHIFT		22
+#define S5P_JPEG_VER_SCALING_MASK		\
+			(3 << S5P_JPEG_VER_SCALING_SHIFT)
+#define S5P_JPEG_VER_SCALING(x)			\
+			(((x) & 0x3) << S5P_JPEG_VER_SCALING_SHIFT)
+#define S5P_JPEG_SOFT_RESET_HI			(1 << 29)
+
+/* JPEG INT Register bit */
+#define S5P_JPEG_INT_EN_MASK			(0x1f << 0)
+#define S5P_JPEG_INT_EN_ALL			(0x1f << 0)
+
+/* JPEG IMAGE SIZE Register bit */
+#define S5P_JPEG_X_SIZE_SHIFT		0
+#define S5P_JPEG_X_SIZE_MASK		(0xffff << S5P_JPEG_X_SIZE_SHIFT)
+#define S5P_JPEG_X_SIZE(x)			\
+			(((x) & 0xffff) << S5P_JPEG_X_SIZE_SHIFT)
+#define S5P_JPEG_Y_SIZE_SHIFT		16
+#define S5P_JPEG_Y_SIZE_MASK		(0xffff << S5P_JPEG_Y_SIZE_SHIFT)
+#define S5P_JPEG_Y_SIZE(x)			\
+			(((x) & 0xffff) << S5P_JPEG_Y_SIZE_SHIFT)
+
+/* JPEG IMAGE FORMAT Register bit */
+#define S5P_JPEG_ENC_IN_FMT_MASK		0xffff0000
+#define S5P_JPEG_ENC_RGB_IMG		(1 << 0)
+#define S5P_JPEG_RGB_IP_SHIFT		6
+#define S5P_JPEG_RGB_IP_RGB_16BIT_IMG		(4 << S5P_JPEG_RGB_IP_SHIFT)
+#define S5P_JPEG_ENC_YUV_422_IMG		(3 << 0)
+
+/* JPEG IMAGE FORMAT Register bit */
+#define S5P_JPEG_ENC_IN_FMT_MASK		0xffff0000
+#define S5P_JPEG_DEC_YUV_422_IMG		(3 << 0)
+#define S5P_JPEG_DEC_YUV_420_IMG		(4 << 0)
+
+#define S5P_JPEG_YUV_422_IP_SHIFT		12
+#define S5P_JPEG_YUV_422_IP_MASK		(7 << S5P_JPEG_YUV_422_IP_SHIFT)
+#define S5P_JPEG_YUV_422_IP_YUV_422_1P_IMG		\
+			(4 << S5P_JPEG_YUV_422_IP_SHIFT)
+
+#define S5P_JPEG_YUV_420_IP_SHIFT		15
+#define S5P_JPEG_YUV_420_IP_MASK		(7 << S5P_JPEG_YUV_420_IP_SHIFT)
+#define S5P_JPEG_YUV_420_IP_YUV_420_3P_IMG		\
+			(5 << S5P_JPEG_YUV_420_IP_SHIFT)
+
+#define S5P_JPEG_ENC_FMT_SHIFT		24
+#define S5P_JPEG_ENC_FMT_MASK		(3 << S5P_JPEG_ENC_FMT_SHIFT)
+#define S5P_JPEG_ENC_FMT_YUV_444		(1 << S5P_JPEG_ENC_FMT_SHIFT)
+#define S5P_JPEG_ENC_FMT_YUV_422		(2 << S5P_JPEG_ENC_FMT_SHIFT)
+#define S5P_JPEG_ENC_FMT_YUV_420		(3 << S5P_JPEG_ENC_FMT_SHIFT)
+
+/* JPEG TBL SEL Register bit */
+#define S5P_JPEG_Q_TBL_COMP1_SHIFT	0
+#define S5P_JPEG_Q_TBL_COMP1_0		(0 << S5P_JPEG_Q_TBL_COMP1_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP1_1		(1 << S5P_JPEG_Q_TBL_COMP1_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP1_2		(2 << S5P_JPEG_Q_TBL_COMP1_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP1_3		(3 << S5P_JPEG_Q_TBL_COMP1_SHIFT)
+
+#define S5P_JPEG_Q_TBL_COMP2_SHIFT	2
+#define S5P_JPEG_Q_TBL_COMP2_0		(0 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP2_1		(1 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP2_2		(2 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP2_3		(3 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
+
+#define S5P_JPEG_Q_TBL_COMP3_SHIFT	4
+#define S5P_JPEG_Q_TBL_COMP3_0		(0 << S5P_JPEG_Q_TBL_COMP3_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP3_1		(1 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP3_2		(2 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
+#define S5P_JPEG_Q_TBL_COMP3_3		(3 << S5P_JPEG_Q_TBL_COMP2_SHIFT)
+
+#define S5P_JPEG_HUFF_TBL_COMP1_SHIFT			6
+#define S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_0		\
+			(0 << S5P_JPEG_HUFF_TBL_COMP1_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP1_AC_0_DC_1		\
+			(1 << S5P_JPEG_HUFF_TBL_COMP1_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP1_AC_1_DC_0		\
+			(2 << S5P_JPEG_HUFF_TBL_COMP1_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP1_AC_1_DC_1		\
+			(3 << S5P_JPEG_HUFF_TBL_COMP1_SHIFT)
+
+#define S5P_JPEG_HUFF_TBL_COMP2_SHIFT			8
+#define S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_0		\
+			(0 << S5P_JPEG_HUFF_TBL_COMP2_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP2_AC_0_DC_1		\
+			(1 << S5P_JPEG_HUFF_TBL_COMP2_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP2_AC_1_DC_0		\
+			(2 << S5P_JPEG_HUFF_TBL_COMP2_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP2_AC_1_DC_1		\
+			(3 << S5P_JPEG_HUFF_TBL_COMP2_SHIFT)
+
+#define S5P_JPEG_HUFF_TBL_COMP3_SHIFT			10
+#define S5P_JPEG_HUFF_TBL_COMP3_AC_0_DC_0		\
+			(0 << S5P_JPEG_HUFF_TBL_COMP3_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP3_AC_0_DC_1		\
+			(1 << S5P_JPEG_HUFF_TBL_COMP3_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_0		\
+			(2 << S5P_JPEG_HUFF_TBL_COMP3_SHIFT)
+#define S5P_JPEG_HUFF_TBL_COMP3_AC_1_DC_1		\
+			(3 << S5P_JPEG_HUFF_TBL_COMP3_SHIFT)
+
+#endif /* JPEG_REGS_H_ */
diff --git a/drivers/media/video/s5p-jpeg/jpeg-v2x.c b/drivers/media/video/s5p-jpeg/jpeg-v2x.c
new file mode 100644
index 0000000..71bd38b
--- /dev/null
+++ b/drivers/media/video/s5p-jpeg/jpeg-v2x.c
@@ -0,0 +1,129 @@
+/* linux/drivers/media/video/s5p-jpeg/jpeg-v2x.c
+ *
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/gfp.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "jpeg-core.h"
+#include "jpeg-hw-v2x.h"
+
+/*
+ * ============================================================================
+ * mem2mem callbacks
+ * ============================================================================
+ */
+
+void s5p_jpeg_irq_execute(void *dev_id)
+{
+	struct s5p_jpeg *jpeg = dev_id;
+	struct s5p_jpeg_ctx *curr_ctx;
+	struct vb2_buffer *src_buf, *dst_buf;
+	unsigned long payload_size = 0;
+	enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
+
+	unsigned int int_status;
+
+	curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
+
+	src_buf = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
+	dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
+
+	int_status = jpeg_get_int_status(jpeg->regs);
+
+	if (int_status != 0x2)
+		state = VB2_BUF_STATE_ERROR;
+
+	v4l2_m2m_buf_done(src_buf, state);
+	if (curr_ctx->mode == S5P_JPEG_ENCODE && int_status == 0x2) {
+		payload_size = jpeg_compressed_size(jpeg->regs);
+		vb2_set_plane_payload(dst_buf, 0, payload_size);
+	}
+	v4l2_m2m_buf_done(dst_buf, state);
+	v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->m2m_ctx);
+}
+
+void s5p_jpeg_execute(void *priv)
+{
+	struct s5p_jpeg_ctx *ctx = priv;
+	struct s5p_jpeg *jpeg = ctx->jpeg;
+	struct vb2_buffer *src_buf, *dst_buf;
+	unsigned long src_addr, dst_addr;
+
+	src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+	dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+
+	src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
+	dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+
+	jpeg_reset(jpeg->regs);
+	jpeg_set_interrupt(jpeg->regs);
+
+	if (ctx->mode == S5P_JPEG_ENCODE) {
+		jpeg_set_huf_table_enable(jpeg->regs, 1);
+		jpeg_qtbl(jpeg->regs);
+		jpeg_htbl_ac(jpeg->regs);
+		jpeg_htbl_dc(jpeg->regs);
+		jpeg_set_encode_tbl_select(jpeg->regs, ctx->compr_quality);
+		jpeg_x_y(jpeg->regs, ctx->out_q.w, ctx->out_q.h);
+
+		if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
+			jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_565);
+		else
+			jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_422);
+		if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
+			jpeg_subsampling_mode(jpeg->regs,
+					      S5P_JPEG_SUBSAMPLING_422);
+		else
+			jpeg_subsampling_mode(jpeg->regs,
+					      S5P_JPEG_SUBSAMPLING_420);
+
+		jpeg_enc_imgadr(jpeg->regs, src_addr);
+		jpeg_jpgadr(jpeg->regs, dst_addr);
+		jpeg_set_encode_hoff_cnt(jpeg->regs);
+	} else {
+		jpeg_set_encode_tbl_select(jpeg->regs, 0);
+		jpeg_set_dec_scaling(jpeg->regs, 0, 0);
+		jpeg_jpgadr(jpeg->regs, src_addr);
+		if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV) {
+			jpeg_dec_imgadr(jpeg->regs, dst_addr,
+						S5P_JPEG_RAW_OUT_422,
+						ctx->out_q.w, ctx->out_q.h);
+			jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
+		} else {
+			jpeg_dec_imgadr(jpeg->regs, dst_addr,
+						S5P_JPEG_RAW_OUT_420,
+						ctx->out_q.w, ctx->out_q.h);
+			jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_420);
+		}
+		jpeg_set_dec_bitstream_size(jpeg->regs,
+						ctx->out_q.size / 32 + 1);
+	}
+	jpeg_proc_mode(jpeg->regs, ctx->mode);
+}
+
+void s5p_jpeg_runtime_resume_execute(struct device *dev)
+{
+
+}
diff --git a/drivers/media/video/s5p-jpeg/jpeg-v3.c b/drivers/media/video/s5p-jpeg/jpeg-v3.c
new file mode 100644
index 0000000..41a5038
--- /dev/null
+++ b/drivers/media/video/s5p-jpeg/jpeg-v3.c
@@ -0,0 +1,340 @@
+/* linux/drivers/media/video/s5p-jpeg/jpeg-v3.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd.
+ *		http://www.samsung.com
+ *
+ * Author: Andrzej Pietrasiewicz <andrzej.p@xxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/gfp.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <media/v4l2-mem2mem.h>
+#include <media/v4l2-ioctl.h>
+#include <media/videobuf2-core.h>
+#include <media/videobuf2-dma-contig.h>
+
+#include "jpeg-core.h"
+#include "jpeg-hw.h"
+
+static const unsigned char qtbl_luminance[4][64] = {
+	{/* level 1 - high quality */
+		 8,  6,  6,  8, 12, 14, 16, 17,
+		 6,  6,  6,  8, 10, 13, 12, 15,
+		 6,  6,  7,  8, 13, 14, 18, 24,
+		 8,  8,  8, 14, 13, 19, 24, 35,
+		12, 10, 13, 13, 20, 26, 34, 39,
+		14, 13, 14, 19, 26, 34, 39, 39,
+		16, 12, 18, 24, 34, 39, 39, 39,
+		17, 15, 24, 35, 39, 39, 39, 39
+	},
+	{/* level 2 */
+		12,  8,  8, 12, 17, 21, 24, 23,
+		 8,  9,  9, 11, 15, 19, 18, 23,
+		 8,  9, 10, 12, 19, 20, 27, 36,
+		12, 11, 12, 21, 20, 28, 36, 53,
+		17, 15, 19, 20, 30, 39, 51, 59,
+		21, 19, 20, 28, 39, 51, 59, 59,
+		24, 18, 27, 36, 51, 59, 59, 59,
+		23, 23, 36, 53, 59, 59, 59, 59
+	},
+	{/* level 3 */
+		16, 11, 11, 16, 23, 27, 31, 30,
+		11, 12, 12, 15, 20, 23, 23, 30,
+		11, 12, 13, 16, 23, 26, 35, 47,
+		16, 15, 16, 23, 26, 37, 47, 64,
+		23, 20, 23, 26, 39, 51, 64, 64,
+		27, 23, 26, 37, 51, 64, 64, 64,
+		31, 23, 35, 47, 64, 64, 64, 64,
+		30, 30, 47, 64, 64, 64, 64, 64
+	},
+	{/*level 4 - low quality */
+		20, 16, 25, 39, 50, 46, 62, 68,
+		16, 18, 23, 38, 38, 53, 65, 68,
+		25, 23, 31, 38, 53, 65, 68, 68,
+		39, 38, 38, 53, 65, 68, 68, 68,
+		50, 38, 53, 65, 68, 68, 68, 68,
+		46, 53, 65, 68, 68, 68, 68, 68,
+		62, 65, 68, 68, 68, 68, 68, 68,
+		68, 68, 68, 68, 68, 68, 68, 68
+	}
+};
+
+static const unsigned char qtbl_chrominance[4][64] = {
+	{/* level 1 - high quality */
+		 9,  8,  9, 11, 14, 17, 19, 24,
+		 8, 10,  9, 11, 14, 13, 17, 22,
+		 9,  9, 13, 14, 13, 15, 23, 26,
+		11, 11, 14, 14, 15, 20, 26, 33,
+		14, 14, 13, 15, 20, 24, 33, 39,
+		17, 13, 15, 20, 24, 32, 39, 39,
+		19, 17, 23, 26, 33, 39, 39, 39,
+		24, 22, 26, 33, 39, 39, 39, 39
+	},
+	{/* level 2 */
+		13, 11, 13, 16, 20, 20, 29, 37,
+		11, 14, 14, 14, 16, 20, 26, 32,
+		13, 14, 15, 17, 20, 23, 35, 40,
+		16, 14, 17, 21, 23, 30, 40, 50,
+		20, 16, 20, 23, 30, 37, 50, 59,
+		20, 20, 23, 30, 37, 48, 59, 59,
+		29, 26, 35, 40, 50, 59, 59, 59,
+		37, 32, 40, 50, 59, 59, 59, 59
+	},
+	{/* level 3 */
+		17, 15, 17, 21, 20, 26, 38, 48,
+		15, 19, 18, 17, 20, 26, 35, 43,
+		17, 18, 20, 22, 26, 30, 46, 53,
+		21, 17, 22, 28, 30, 39, 53, 64,
+		20, 20, 26, 30, 39, 48, 64, 64,
+		26, 26, 30, 39, 48, 63, 64, 64,
+		38, 35, 46, 53, 64, 64, 64, 64,
+		48, 43, 53, 64, 64, 64, 64, 64
+	},
+	{/*level 4 - low quality */
+		21, 25, 32, 38, 54, 68, 68, 68,
+		25, 28, 24, 38, 54, 68, 68, 68,
+		32, 24, 32, 43, 66, 68, 68, 68,
+		38, 38, 43, 53, 68, 68, 68, 68,
+		54, 54, 66, 68, 68, 68, 68, 68,
+		68, 68, 68, 68, 68, 68, 68, 68,
+		68, 68, 68, 68, 68, 68, 68, 68,
+		68, 68, 68, 68, 68, 68, 68, 68
+	}
+};
+
+static const unsigned char hdctbl0[16] = {
+	0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
+};
+
+static const unsigned char hdctblg0[12] = {
+	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb
+};
+static const unsigned char hactbl0[16] = {
+	0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d
+};
+static const unsigned char hactblg0[162] = {
+	0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
+	0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
+	0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
+	0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
+	0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
+	0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
+	0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+	0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+	0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+	0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+	0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+	0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+	0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
+	0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+	0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
+	0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
+	0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+	0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
+	0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
+	0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
+	0xf9, 0xfa
+};
+
+static inline void jpeg_set_qtbl(void __iomem *regs, const unsigned char *qtbl,
+		   unsigned long tab, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		writel((unsigned int)qtbl[i], regs + tab + (i * 0x04));
+}
+
+static inline void jpeg_set_qtbl_lum(void __iomem *regs, int quality)
+{
+	/* this driver fills quantisation table 0 with data for luma */
+	jpeg_set_qtbl(regs, qtbl_luminance[quality], S5P_JPG_QTBL_CONTENT(0),
+		      ARRAY_SIZE(qtbl_luminance[quality]));
+}
+
+static inline void jpeg_set_qtbl_chr(void __iomem *regs, int quality)
+{
+	/* this driver fills quantisation table 1 with data for chroma */
+	jpeg_set_qtbl(regs, qtbl_chrominance[quality], S5P_JPG_QTBL_CONTENT(1),
+		      ARRAY_SIZE(qtbl_chrominance[quality]));
+}
+
+static inline void jpeg_set_htbl(void __iomem *regs, const unsigned char *htbl,
+		   unsigned long tab, int len)
+{
+	int i;
+
+	for (i = 0; i < len; i++)
+		writel((unsigned int)htbl[i], regs + tab + (i * 0x04));
+}
+
+static inline void jpeg_set_hdctbl(void __iomem *regs)
+{
+	/* this driver fills table 0 for this component */
+	jpeg_set_htbl(regs, hdctbl0, S5P_JPG_HDCTBL(0), ARRAY_SIZE(hdctbl0));
+}
+
+static inline void jpeg_set_hdctblg(void __iomem *regs)
+{
+	/* this driver fills table 0 for this component */
+	jpeg_set_htbl(regs, hdctblg0, S5P_JPG_HDCTBLG(0), ARRAY_SIZE(hdctblg0));
+}
+
+static inline void jpeg_set_hactbl(void __iomem *regs)
+{
+	/* this driver fills table 0 for this component */
+	jpeg_set_htbl(regs, hactbl0, S5P_JPG_HACTBL(0), ARRAY_SIZE(hactbl0));
+}
+
+static inline void jpeg_set_hactblg(void __iomem *regs)
+{
+	/* this driver fills table 0 for this component */
+	jpeg_set_htbl(regs, hactblg0, S5P_JPG_HACTBLG(0), ARRAY_SIZE(hactblg0));
+}
+
+void s5p_jpeg_irq_execute(void *dev_id)
+{
+	struct s5p_jpeg *jpeg = dev_id;
+	struct s5p_jpeg_ctx *curr_ctx;
+	struct vb2_buffer *src_buf, *dst_buf;
+	unsigned long payload_size = 0;
+	enum vb2_buffer_state state = VB2_BUF_STATE_DONE;
+	bool enc_jpeg_too_large = false;
+	bool timer_elapsed = false;
+	bool op_completed = false;
+
+	curr_ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev);
+
+	src_buf = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
+	dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
+
+	if (curr_ctx->mode == S5P_JPEG_ENCODE)
+		enc_jpeg_too_large = jpeg_enc_stream_stat(jpeg->regs);
+	timer_elapsed = jpeg_timer_stat(jpeg->regs);
+	op_completed = jpeg_result_stat_ok(jpeg->regs);
+	if (curr_ctx->mode == S5P_JPEG_DECODE)
+		op_completed = op_completed && jpeg_stream_stat_ok(jpeg->regs);
+
+	if (enc_jpeg_too_large) {
+		state = VB2_BUF_STATE_ERROR;
+		jpeg_clear_enc_stream_stat(jpeg->regs);
+	} else if (timer_elapsed) {
+		state = VB2_BUF_STATE_ERROR;
+		jpeg_clear_timer_stat(jpeg->regs);
+	} else if (!op_completed) {
+		state = VB2_BUF_STATE_ERROR;
+	} else {
+		payload_size = jpeg_compressed_size(jpeg->regs);
+	}
+
+	v4l2_m2m_buf_done(src_buf, state);
+	if (curr_ctx->mode == S5P_JPEG_ENCODE)
+		vb2_set_plane_payload(dst_buf, 0, payload_size);
+	v4l2_m2m_buf_done(dst_buf, state);
+	v4l2_m2m_job_finish(jpeg->m2m_dev, curr_ctx->m2m_ctx);
+
+	jpeg_clear_int(jpeg->regs);
+}
+
+void s5p_jpeg_execute(void *priv)
+{
+	struct s5p_jpeg_ctx *ctx = priv;
+	struct s5p_jpeg *jpeg = ctx->jpeg;
+	struct vb2_buffer *src_buf, *dst_buf;
+	unsigned long src_addr, dst_addr;
+
+	src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
+	dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
+	src_addr = vb2_dma_contig_plane_dma_addr(src_buf, 0);
+	dst_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0);
+
+	jpeg_reset(jpeg->regs);
+	jpeg_poweron(jpeg->regs);
+	jpeg_proc_mode(jpeg->regs, ctx->mode);
+	if (ctx->mode == S5P_JPEG_ENCODE) {
+		if (ctx->out_q.fmt->fourcc == V4L2_PIX_FMT_RGB565)
+			jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_565);
+		else
+			jpeg_input_raw_mode(jpeg->regs, S5P_JPEG_RAW_IN_422);
+		if (ctx->cap_q.fmt->fourcc == V4L2_PIX_FMT_YUYV)
+			jpeg_subsampling_mode(jpeg->regs,
+					      S5P_JPEG_SUBSAMPLING_422);
+		else
+			jpeg_subsampling_mode(jpeg->regs,
+					      S5P_JPEG_SUBSAMPLING_420);
+		jpeg_dri(jpeg->regs, 0);
+		jpeg_x(jpeg->regs, ctx->out_q.w);
+		jpeg_y(jpeg->regs, ctx->out_q.h);
+		jpeg_imgadr(jpeg->regs, src_addr);
+		jpeg_jpgadr(jpeg->regs, dst_addr);
+
+		/* ultimately comes from sizeimage from userspace */
+		jpeg_enc_stream_int(jpeg->regs, ctx->cap_q.size);
+
+		/* JPEG RGB to YCbCr conversion matrix */
+		jpeg_coef(jpeg->regs, 1, 1, S5P_JPEG_COEF11);
+		jpeg_coef(jpeg->regs, 1, 2, S5P_JPEG_COEF12);
+		jpeg_coef(jpeg->regs, 1, 3, S5P_JPEG_COEF13);
+		jpeg_coef(jpeg->regs, 2, 1, S5P_JPEG_COEF21);
+		jpeg_coef(jpeg->regs, 2, 2, S5P_JPEG_COEF22);
+		jpeg_coef(jpeg->regs, 2, 3, S5P_JPEG_COEF23);
+		jpeg_coef(jpeg->regs, 3, 1, S5P_JPEG_COEF31);
+		jpeg_coef(jpeg->regs, 3, 2, S5P_JPEG_COEF32);
+		jpeg_coef(jpeg->regs, 3, 3, S5P_JPEG_COEF33);
+
+		/*
+		 * JPEG IP allows storing 4 quantization tables
+		 * We fill table 0 for luma and table 1 for chroma
+		 */
+		jpeg_set_qtbl_lum(jpeg->regs, ctx->compr_quality);
+		jpeg_set_qtbl_chr(jpeg->regs, ctx->compr_quality);
+		/* use table 0 for Y */
+		jpeg_qtbl(jpeg->regs, 1, 0);
+		/* use table 1 for Cb and Cr*/
+		jpeg_qtbl(jpeg->regs, 2, 1);
+		jpeg_qtbl(jpeg->regs, 3, 1);
+
+		/* Y, Cb, Cr use Huffman table 0 */
+		jpeg_htbl_ac(jpeg->regs, 1);
+		jpeg_htbl_dc(jpeg->regs, 1);
+		jpeg_htbl_ac(jpeg->regs, 2);
+		jpeg_htbl_dc(jpeg->regs, 2);
+		jpeg_htbl_ac(jpeg->regs, 3);
+		jpeg_htbl_dc(jpeg->regs, 3);
+	} else {
+		jpeg_rst_int_enable(jpeg->regs, true);
+		jpeg_data_num_int_enable(jpeg->regs, true);
+		jpeg_final_mcu_num_int_enable(jpeg->regs, true);
+		jpeg_outform_raw(jpeg->regs, S5P_JPEG_RAW_OUT_422);
+		jpeg_jpgadr(jpeg->regs, src_addr);
+		jpeg_imgadr(jpeg->regs, dst_addr);
+	}
+	jpeg_start(jpeg->regs);
+}
+
+void s5p_jpeg_runtime_resume_execute(struct device *dev)
+{
+	struct s5p_jpeg *jpeg = dev_get_drvdata(dev);
+	/*
+	 * JPEG IP allows storing two Huffman tables for each component
+	 * We fill table 0 for each component
+	 */
+	jpeg_set_hdctbl(jpeg->regs);
+	jpeg_set_hdctblg(jpeg->regs);
+	jpeg_set_hactbl(jpeg->regs);
+	jpeg_set_hactblg(jpeg->regs);
+}
-- 
1.7.1


--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux