All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/3] TV driver for Samsung S5P platform (media part)
@ 2011-05-24 13:09 Tomasz Stanislawski
  2011-05-24 13:09 ` [PATCH 1/3] v4l: add macro for 1080p59_54 preset Tomasz Stanislawski
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Tomasz Stanislawski @ 2011-05-24 13:09 UTC (permalink / raw)
  To: linux-media; +Cc: m.szyprowski, t.stanislaws, kyungmin.park, hverkuil

Hello,

I would like to present the 4th version of TV drivers for Samsung S5P platform.
The most recent changes are:

1. Configuration of TV is promoted to platform level.
- setup of resources is moved to plat-s5p
- support for EXYNOS4 and S5PV210 machine.
- support for universal-c210 board
- support for Goni board

2. Runtime PM for SDO driver.

3. Moved back to dma-contig allocator.
- dma-contig is a generic interface for a device
- dma-contig use iommu if sysmmu is enabled for a platform

4. Revision of mixer's output handling
- list of to be registered outputs is kept in the mixer driver
- output is not registered if it is not avaliable

4. Bugs and other fixes:
- fixed power domain hang-up
- fixed dead-lock caused by request_module called from probe
- formatting and typos
- fixed VSYNC handling in interrupt
- hdmi: applying driver variant to select proper I2C bus

Updated RFC for TV driver:

==============
 Introduction
==============

The purpose of this RFC is to discuss the driver for a TV output interface
available in upcoming Samsung SoC. The HW is able to generate digital and
analog signals. Current version of the driver supports only digital output.

Internally the driver uses videobuf2 framework, and DMA-CONTIG memory allocator.
Not all of them are merged by now, but I decided to post the sources to start
discussion driver's design.

======================
 Hardware description
======================

The SoC contains a few HW sub-blocks:

1. Video Processor (VP). It is used for processing of NV12 data.  An image
stored in RAM is accessed by DMA. Pixels are cropped, scaled. Additionally,
post processing operations like brightness, sharpness and contrast adjustments
could be performed. The output in YCbCr444 format is send to Mixer.

2. Mixer (MXR). The piece of hardware responsible for mixing and blending
multiple data inputs before passing it to an output device.  The MXR is capable
of handling up to three image layers. One is the output of VP.  Other two are
images in RGB format (multiple variants are supported).  The layers are scaled,
cropped and blended with background color.  The blending factor, and layers'
priority are controlled by MXR's registers. The output is passed either to HDMI
or SDO.

3. HDMI. The piece of HW responsible for generation of HDMI packets. It takes
pixel data from mixer and transforms it into data frames. The output is send
to HDMIPHY interface.

4. HDMIPHY. Physical interface for HDMI. Its duties are sending HDMI packets to
HDMI connector. Basically, it contains a PLL that produces source clock for
Mixer, VP and HDMI during streaming.

5. SDO. Generation of TV analog signal. The alternative output for the Mixer.
It receives data and passes it to VideoDAC. The SDO is responsible for timing
generation of analog TV signal. It supports multiple standards.

6. VideoDAC. Modulator for TVOUT signal. Receives data from SDO. Converts
it to analog domain. Next, the signal is modulated to CVBS format, amplified
and sent to Comosite Connector.

The diagram below depicts connection between all HW pieces.
                    +-----------+
NV12 data ---dma--->|   Video   |
                    | Processor |
                    +-----------+
                          |
                          V
                    +-----------+
RGB data  ---dma--->|           |
                    |   Mixer   |
RGB data  ---dma--->|           |
                    +-----------+
                          |
                          * dmux
                         /
                  +-----*   *------+
                  |                |
                  V                V
            +-----------+    +-----------+
            |    HDMI   |    |    SDO    |
            +-----------+    +-----------+
                  |                |
                  V                V
            +-----------+    +-----------+
            |  HDMIPHY  |    |  VideoDAC |
            +-----------+    +-----------+
                  |                |
                  V                V
                HDMI           Composite
             connector         connector


==================
 Driver interface
==================

The posted driver implements three V4L2 nodes. Every video node implements V4L2
output buffer. One of nodes corresponds to input of Video Processor. The other
two nodes correspond to RGB inputs of Mixer. All nodes share the same output.
It is one of the Mixer's outputs: SDO or HDMI. Changing output in one layer
using S_OUTPUT would change outputs of all other video nodes. The same thing
happens if one try to reconfigure output i.e. by calling S_DV_PRESET. However
it not possible to change or reconfigure the output while streaming. To sum up,
all features in posted version of driver goes as follows:

1. QUERYCAP
2. S_FMT, G_FMT - single and multiplanar API
  a) node named video0 supports formats NV12, NV12, NV12T (tiled version of
NV12), NV12MT (multiplane version of NV12T).
  b) nodes named graph0 and graph1 support formats RGB565, ARGB1555, ARGB4444,
ARGB8888.
3. Buffer with USERPTR and MMAP memory.
4. Streaming and buffer control. (STREAMON, STREAMOFF, REQBUF, QBUF, DQBUF)
5. OUTPUT configurations and enumeration using VIDIOC_{ENUM/S/G}_OUTPUT.
6. DV preset control (SET, GET, ENUM). Currently modes 480P59_94, 720P59_94,
1080P30, 1080P59_94 and 1080P60 work.
7. Analog standards using VIDIOC_S_STD.
8. Positioning layer's window on output display using S_CROP, G_GROP, CROPCAP.
9. Positioning and cropping data in buffer using S_CROP, G_GROP, CROPCAP with
buffer type OVERLAY. *

TODOs:
- add control of alpha blending / chroma keying via V4L2 controls
- add controls for luminance curve and sharpness in VP
- consider exporting all output functionalities to separate video node
- consider media controller framework
- fix dependency between all TV drivers
- move all subroutines for power management to PM runtime callbacks

* The need of cropping in source buffers came from problem with MFC driver for
S5P. The MFC supports only width divisible by 64. If a width of a decoded movie
is not aligned do 64 then padding pixels are filled with zeros. This is an ugly
green color in YCbCr colorspace. Filling it with zeros by a CPU is a waste of
resources since an image can be cropped in VP. Is it possible to set crops for
user data for M2M devices. V4L2 lacks such functionality of non-M2M devices.
Therefore cropping in buffer V4L2_BUF_TYPE_VIDEO_OVERLAY was used as an work
around.

=====================
 Device Architecture
=====================

Three drivers are added in this patch.

1. HDMIPHY. It is an I2C driver for HDMIPHY interface. It exports following
callback by V4L2 subdevice:
- s_power: currently stub
- s_stream: configures and starts/stops HDMIPHY
- s_dv_preset: used to choose proper frequency of clock for other TV devices

2. HDMI. The auxiliary driver used to control HDMI interface. It exports its
subdev in its private data for use by other drivers. The following callbacks are
implemented:
- s_power: runs HDMI hardware, regulators and clocks.
- s_stream: runs HDMIPHY and starts generation of video frames.
- enum_dv_presets
- s_dv_preset
- g_mbus_format: returns information on data format expected by on HDMI input
  The driver supports an interrupt. It is used to detect plug/unplug events in
kernel debugs.  The API for detection of such an events in V4L2 API is to be
defined.

3. SDO. The auxiliary driver used to control analog TV. It also exports its
subdev for other drivers. The following callbacks are implemented.
- s_power: runs TV hardware, regulators and clocks.
- s_stream: runs TV clock and starts generation of video signal.
- s_std: configuration of TV standard from one of PAL/NTSC family
- g_tvnorms: used by Mixer to obtain tv standards supported by SDO
- g_mbus_format: returns information on data format expected by on SDO input

5. Mixer & Video Processor driver. It is called 's5p-mixer' because of
historical reasons. It was decided combine VP and MXR drivers into one because
of shared interrupt and very similar interface via V4L2 nodes. The driver is a
realization of many-to-many relation between multiple input layers and multiple
outputs. All shared resources are kept in struct mxr_device. It provides
utilities for management and synchronization of access to resources and
reference counting. The outputs are obtained from HDMI/SDO private data.  One
layer is a single video node. Simple inheritance is applied because there only
little difference between layer's types. Every layer type implements set of
ops.  There are different ops for Mixer layers and other for VP layer.

The videobuf2 framework was used for the management of buffers and streaming.
All other V4L2 ioctls are processed in layers common interface. The DMA-IOMMU
was used as memory allocator for Mixer's buffers. It could be easily exchanged
with any other allocator integrated with videobuf2 framework.

===============
 Usage summary
===============

Follow steps below to display double-buffered animation on SDO output.
In order to use other output please use VIDIOC_S_OUTPUT.

01. Open video node named graph0.
02. S_FMT(type = OUTPUT, pixelformat = V4L2_PIX_FMT_RGB*, width, height, ...)
03. REQ_BUFS(type = OUTPUT, memory = MMAP, count = 2)
04. MMAP(type = OUTPUT, index = 0)
05. MMAP(type = OUTPUT, index = 1)
06. Fill buffer 0 with data
07. QBUF(type = OUTPUT, index = 0)
08. STREAM_ON(type = OUTPUT)
09. Fill buffer 1 with data
10. QBUF(type = OUTPUT, index = 1)
11. DQBUF(type = OUTPUT)
12. QBUF(type = OUTPUT, index = 0)
13. DQBUF(type = OUTPUT)
14. Goto 09

===============
 Patch Summary
===============

Tomasz Stanislawski (3):
  v4l: add macro for 1080p59_54 preset
  v4l: add g_tvnorms callback to V4L2 subdev
  s5p-tv: add drivers for TV on Samsung S5P platform

 drivers/media/video/Kconfig                  |    8 +
 drivers/media/video/Makefile                 |    1 +
 drivers/media/video/s5p-tv/Kconfig           |   68 +
 drivers/media/video/s5p-tv/Makefile          |   17 +
 drivers/media/video/s5p-tv/hdmi.h            |   74 +
 drivers/media/video/s5p-tv/hdmi_drv.c        | 1008 ++++++++++++++
 drivers/media/video/s5p-tv/hdmiphy_drv.c     |  250 ++++
 drivers/media/video/s5p-tv/mixer.h           |  336 +++++
 drivers/media/video/s5p-tv/mixer_drv.c       |  488 +++++++
 drivers/media/video/s5p-tv/mixer_grp_layer.c |  180 +++
 drivers/media/video/s5p-tv/mixer_reg.c       |  566 ++++++++
 drivers/media/video/s5p-tv/mixer_reg.h       |   46 +
 drivers/media/video/s5p-tv/mixer_video.c     |  957 +++++++++++++
 drivers/media/video/s5p-tv/mixer_vp_layer.c  |  206 +++
 drivers/media/video/s5p-tv/regs-hdmi.h       | 1849 ++++++++++++++++++++++++++
 drivers/media/video/s5p-tv/regs-sdo.h        |  453 +++++++
 drivers/media/video/s5p-tv/regs-vmx.h        |  197 +++
 drivers/media/video/s5p-tv/regs-vp.h         |  277 ++++
 drivers/media/video/s5p-tv/sdo_drv.c         |  530 ++++++++
 drivers/media/video/v4l2-common.c            |    1 +
 include/linux/videodev2.h                    |    1 +
 include/media/v4l2-subdev.h                  |    1 +
 22 files changed, 7514 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/s5p-tv/Kconfig
 create mode 100644 drivers/media/video/s5p-tv/Makefile
 create mode 100644 drivers/media/video/s5p-tv/hdmi.h
 create mode 100644 drivers/media/video/s5p-tv/hdmi_drv.c
 create mode 100644 drivers/media/video/s5p-tv/hdmiphy_drv.c
 create mode 100644 drivers/media/video/s5p-tv/mixer.h
 create mode 100644 drivers/media/video/s5p-tv/mixer_drv.c
 create mode 100644 drivers/media/video/s5p-tv/mixer_grp_layer.c
 create mode 100644 drivers/media/video/s5p-tv/mixer_reg.c
 create mode 100644 drivers/media/video/s5p-tv/mixer_reg.h
 create mode 100644 drivers/media/video/s5p-tv/mixer_video.c
 create mode 100644 drivers/media/video/s5p-tv/mixer_vp_layer.c
 create mode 100644 drivers/media/video/s5p-tv/regs-hdmi.h
 create mode 100644 drivers/media/video/s5p-tv/regs-sdo.h
 create mode 100644 drivers/media/video/s5p-tv/regs-vmx.h
 create mode 100644 drivers/media/video/s5p-tv/regs-vp.h
 create mode 100644 drivers/media/video/s5p-tv/sdo_drv.c

-- 
1.7.5.1


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/3] v4l: add macro for 1080p59_54 preset
  2011-05-24 13:09 [PATCH v4 0/3] TV driver for Samsung S5P platform (media part) Tomasz Stanislawski
@ 2011-05-24 13:09 ` Tomasz Stanislawski
  2011-05-24 13:09 ` [PATCH 2/3] v4l: add g_tvnorms callback to V4L2 subdev Tomasz Stanislawski
  2011-05-24 13:09 ` [PATCH 3/3] s5p-tv: add drivers for TV on Samsung S5P platform Tomasz Stanislawski
  2 siblings, 0 replies; 7+ messages in thread
From: Tomasz Stanislawski @ 2011-05-24 13:09 UTC (permalink / raw)
  To: linux-media; +Cc: m.szyprowski, t.stanislaws, kyungmin.park, hverkuil

The 1080p59_94 is supported in latest Samusng SoC.

Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 drivers/media/video/v4l2-common.c |    1 +
 include/linux/videodev2.h         |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 06b9f9f..003e648 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -582,6 +582,7 @@ int v4l_fill_dv_preset_info(u32 preset, struct v4l2_dv_enum_preset *info)
 		{ 1920, 1080, "1080p@30" },	/* V4L2_DV_1080P30 */
 		{ 1920, 1080, "1080p@50" },	/* V4L2_DV_1080P50 */
 		{ 1920, 1080, "1080p@60" },	/* V4L2_DV_1080P60 */
+		{ 1920, 1080, "1080p@59.94" },	/* V4L2_DV_1080P59_94 */
 	};
 
 	if (info == NULL || preset >= ARRAY_SIZE(dv_presets))
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 38575ae..4d58cfc 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -870,6 +870,7 @@ struct v4l2_dv_enum_preset {
 #define		V4L2_DV_1080P30		16 /* SMPTE 296M */
 #define		V4L2_DV_1080P50		17 /* BT.1120 */
 #define		V4L2_DV_1080P60		18 /* BT.1120 */
+#define		V4L2_DV_1080P59_94	19
 
 /*
  *	D V 	B T	T I M I N G S
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/3] v4l: add g_tvnorms callback to V4L2 subdev
  2011-05-24 13:09 [PATCH v4 0/3] TV driver for Samsung S5P platform (media part) Tomasz Stanislawski
  2011-05-24 13:09 ` [PATCH 1/3] v4l: add macro for 1080p59_54 preset Tomasz Stanislawski
@ 2011-05-24 13:09 ` Tomasz Stanislawski
  2011-05-24 13:09 ` [PATCH 3/3] s5p-tv: add drivers for TV on Samsung S5P platform Tomasz Stanislawski
  2 siblings, 0 replies; 7+ messages in thread
From: Tomasz Stanislawski @ 2011-05-24 13:09 UTC (permalink / raw)
  To: linux-media; +Cc: m.szyprowski, t.stanislaws, kyungmin.park, hverkuil

Callback is used to acquire TV norms supported by a subdev.
It is used to avoid having standards in top-level driver.

Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 include/media/v4l2-subdev.h |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index 1562c4f..4206e97 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -261,6 +261,7 @@ struct v4l2_subdev_video_ops {
 	int (*s_crystal_freq)(struct v4l2_subdev *sd, u32 freq, u32 flags);
 	int (*s_std_output)(struct v4l2_subdev *sd, v4l2_std_id std);
 	int (*querystd)(struct v4l2_subdev *sd, v4l2_std_id *std);
+	int (*g_tvnorms)(struct v4l2_subdev *sd, v4l2_std_id *std);
 	int (*g_input_status)(struct v4l2_subdev *sd, u32 *status);
 	int (*s_stream)(struct v4l2_subdev *sd, int enable);
 	int (*cropcap)(struct v4l2_subdev *sd, struct v4l2_cropcap *cc);
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/3] s5p-tv: add drivers for TV on Samsung S5P platform
  2011-05-24 13:09 [PATCH v4 0/3] TV driver for Samsung S5P platform (media part) Tomasz Stanislawski
  2011-05-24 13:09 ` [PATCH 1/3] v4l: add macro for 1080p59_54 preset Tomasz Stanislawski
  2011-05-24 13:09 ` [PATCH 2/3] v4l: add g_tvnorms callback to V4L2 subdev Tomasz Stanislawski
@ 2011-05-24 13:09 ` Tomasz Stanislawski
  2 siblings, 0 replies; 7+ messages in thread
From: Tomasz Stanislawski @ 2011-05-24 13:09 UTC (permalink / raw)
  To: linux-media; +Cc: m.szyprowski, t.stanislaws, kyungmin.park, hverkuil

Add drivers for TV outputs on Samsung platforms from S5P family.
- HDMIPHY - auxiliary I2C driver need by TV driver
- HDMI    - generation and control of streaming by HDMI output
- SDO     - streaming analog TV by Composite connector
- MIXER   - merging images from three layers and passing result to the output

Interface:
- 3 video nodes with output queues
- support for multi plane API
- each nodes has up to 2 outputs (HDMI and SDO)
- outputs are controlled by S_STD and S_DV_PRESET ioctls

Drivers are using:
- v4l2 framework
- videobuf2
- videobuf2-dma-contig as memory allocator
- runtime PM

Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Reviewed-by: Marek Szyprowski <m.szyprowski@samsung.com>
---
 drivers/media/video/Kconfig                  |    8 +
 drivers/media/video/Makefile                 |    1 +
 drivers/media/video/s5p-tv/Kconfig           |   68 +
 drivers/media/video/s5p-tv/Makefile          |   17 +
 drivers/media/video/s5p-tv/hdmi.h            |   74 +
 drivers/media/video/s5p-tv/hdmi_drv.c        | 1008 ++++++++++++++
 drivers/media/video/s5p-tv/hdmiphy_drv.c     |  250 ++++
 drivers/media/video/s5p-tv/mixer.h           |  336 +++++
 drivers/media/video/s5p-tv/mixer_drv.c       |  488 +++++++
 drivers/media/video/s5p-tv/mixer_grp_layer.c |  180 +++
 drivers/media/video/s5p-tv/mixer_reg.c       |  566 ++++++++
 drivers/media/video/s5p-tv/mixer_reg.h       |   46 +
 drivers/media/video/s5p-tv/mixer_video.c     |  957 +++++++++++++
 drivers/media/video/s5p-tv/mixer_vp_layer.c  |  206 +++
 drivers/media/video/s5p-tv/regs-hdmi.h       | 1849 ++++++++++++++++++++++++++
 drivers/media/video/s5p-tv/regs-sdo.h        |  453 +++++++
 drivers/media/video/s5p-tv/regs-vmx.h        |  197 +++
 drivers/media/video/s5p-tv/regs-vp.h         |  277 ++++
 drivers/media/video/s5p-tv/sdo_drv.c         |  530 ++++++++
 19 files changed, 7511 insertions(+), 0 deletions(-)
 create mode 100644 drivers/media/video/s5p-tv/Kconfig
 create mode 100644 drivers/media/video/s5p-tv/Makefile
 create mode 100644 drivers/media/video/s5p-tv/hdmi.h
 create mode 100644 drivers/media/video/s5p-tv/hdmi_drv.c
 create mode 100644 drivers/media/video/s5p-tv/hdmiphy_drv.c
 create mode 100644 drivers/media/video/s5p-tv/mixer.h
 create mode 100644 drivers/media/video/s5p-tv/mixer_drv.c
 create mode 100644 drivers/media/video/s5p-tv/mixer_grp_layer.c
 create mode 100644 drivers/media/video/s5p-tv/mixer_reg.c
 create mode 100644 drivers/media/video/s5p-tv/mixer_reg.h
 create mode 100644 drivers/media/video/s5p-tv/mixer_video.c
 create mode 100644 drivers/media/video/s5p-tv/mixer_vp_layer.c
 create mode 100644 drivers/media/video/s5p-tv/regs-hdmi.h
 create mode 100644 drivers/media/video/s5p-tv/regs-sdo.h
 create mode 100644 drivers/media/video/s5p-tv/regs-vmx.h
 create mode 100644 drivers/media/video/s5p-tv/regs-vp.h
 create mode 100644 drivers/media/video/s5p-tv/sdo_drv.c

diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 4498b94..def88e1 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -1032,3 +1032,11 @@ config  VIDEO_SAMSUNG_S5P_FIMC
 	  (video postprocessor)
 
 endif # V4L_MEM2MEM_DRIVERS
+
+menuconfig VIDEO_SAMSUNG_S5P_TV
+	bool "Digital/analog TV output interfaces"
+	default y
+if VIDEO_SAMSUNG_S5P_TV
+source "drivers/media/video/s5p-tv/Kconfig"
+endif # VIDEO_SAMSUNG_S5P_TV
+
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index ace5d8b..63ff65b 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -165,6 +165,7 @@ obj-$(CONFIG_VIDEO_SH_MOBILE_CSI2)	+= sh_mobile_csi2.o
 obj-$(CONFIG_VIDEO_SH_MOBILE_CEU)	+= sh_mobile_ceu_camera.o
 obj-$(CONFIG_VIDEO_OMAP1)		+= omap1_camera.o
 obj-$(CONFIG_VIDEO_SAMSUNG_S5P_FIMC) 	+= s5p-fimc/
+obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV)	+= s5p-tv/
 
 obj-$(CONFIG_ARCH_DAVINCI)		+= davinci/
 
diff --git a/drivers/media/video/s5p-tv/Kconfig b/drivers/media/video/s5p-tv/Kconfig
new file mode 100644
index 0000000..970fcbf
--- /dev/null
+++ b/drivers/media/video/s5p-tv/Kconfig
@@ -0,0 +1,68 @@
+# drivers/media/video/samsung/tvout/Kconfig
+#
+# Copyright (c) 2010 Samsung Electronics Co., Ltd.
+#	http://www.samsung.com/
+# Tomasz Stanislawski <t.stanislaws@samsung.com>
+#
+# Licensed under GPLv2
+
+comment "HDMI output drivers"
+
+config VIDEO_SAMSUNG_S5P_HDMIPHY
+	tristate "Samsung HDMIPHY Driver"
+	depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
+	default y
+	help
+	  Say Y here if you want support for the physical HDMI
+	  interface in S5P Samsung SoC. The driver can be compiled
+	  as module. It is an I2C driver, that produce a V4L2
+	  subdev for use by other drivers.
+
+config VIDEO_SAMSUNG_S5P_HDMI
+	tristate "Samsung HDMI Driver"
+	depends on VIDEO_SAMSUNG_S5P_HDMIPHY
+	help
+	  Say Y here if you want support for the HDMI
+	  interface in S5P Samsung SoC. The driver can be compiled
+	  as module. It is an auxliary driver, that produce a V4L2
+	  subdev for use by other drivers. This driver requires
+	  hdmiphy driver to work correctly.
+
+comment "Analog TV output drivers"
+
+config VIDEO_SAMSUNG_S5P_SDO
+	tristate "Samsung Analog TV Driver"
+	depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
+	help
+	  Say Y here if you want support for the analog TV
+	  interface in S5P Samsung SoC. The driver can be compiled
+	  as module. It is an auxliary driver, that produce a V4L2
+	  subdev for use by other drivers. This driver requires
+	  hdmiphy driver to work correctly.
+
+comment "Mixer drivers"
+
+config VIDEO_SAMSUNG_S5P_MIXER
+	tristate "Samsung Mixer and Video Processor Driver"
+	depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
+	default y
+	select VIDEOBUF2_DMA_CONTIG
+	help
+	  Mixer driver for Samsung ARM based SoC.
+
+config VIDEO_SAMSUNG_S5P_MIXER_LOG_LEVEL
+	int "Log level for Samsung Mixer/Video Processor Driver"
+	depends on VIDEO_SAMSUNG_S5P_MIXER
+	range 0 7
+	default 6
+	help
+	  Select driver log level.
+	  Examples:
+		0 - emerg
+		1 - alert
+		2 - crit
+		3 - err
+		4 - warning
+		5 - notice
+		6 - info (default)
+		7 - debug
diff --git a/drivers/media/video/s5p-tv/Makefile b/drivers/media/video/s5p-tv/Makefile
new file mode 100644
index 0000000..8616ef3
--- /dev/null
+++ b/drivers/media/video/s5p-tv/Makefile
@@ -0,0 +1,17 @@
+# drivers/media/video/samsung/tvout/Makefile
+#
+# Copyright (c) 2010 Samsung Electronics Co., Ltd.
+#	http://www.samsung.com/
+# Tomasz Stanislawski <t.stanislaws@samsung.com>
+#
+# Licensed under GPLv2
+
+obj-$(CONFIG_VIDEO_SAMSUNG_S5P_HDMIPHY) += s5p-hdmiphy.o
+s5p-hdmiphy-y += hdmiphy_drv.o
+obj-$(CONFIG_VIDEO_SAMSUNG_S5P_HDMI) += s5p-hdmi.o
+s5p-hdmi-y += hdmi_drv.o
+obj-$(CONFIG_VIDEO_SAMSUNG_S5P_SDO) += s5p-sdo.o
+s5p-sdo-y += sdo_drv.o
+obj-$(CONFIG_VIDEO_SAMSUNG_S5P_MIXER) += s5p-mixer.o
+s5p-mixer-y += mixer_drv.o mixer_video.o mixer_reg.o mixer_grp_layer.o mixer_vp_layer.o
+
diff --git a/drivers/media/video/s5p-tv/hdmi.h b/drivers/media/video/s5p-tv/hdmi.h
new file mode 100644
index 0000000..a2c6073
--- /dev/null
+++ b/drivers/media/video/s5p-tv/hdmi.h
@@ -0,0 +1,74 @@
+/*
+ * Samsung HDMI interface driver
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Tomasz Stanislawski, t.stanislaws@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundiation. either version 2 of the License,
+ * or (at your option) any later version
+ */
+
+#ifndef _SAMSUNG_HDMI_H_
+#define _SAMSUNG_HDMI_H_ __FILE__
+
+#include <linux/kernel.h>
+#include <linux/videodev2.h>
+#include <media/v4l2-mediabus.h>
+
+struct hdmi_tg_regs {
+	u8 cmd;
+	u8 h_fsz_l;
+	u8 h_fsz_h;
+	u8 hact_st_l;
+	u8 hact_st_h;
+	u8 hact_sz_l;
+	u8 hact_sz_h;
+	u8 v_fsz_l;
+	u8 v_fsz_h;
+	u8 vsync_l;
+	u8 vsync_h;
+	u8 vsync2_l;
+	u8 vsync2_h;
+	u8 vact_st_l;
+	u8 vact_st_h;
+	u8 vact_sz_l;
+	u8 vact_sz_h;
+	u8 field_chg_l;
+	u8 field_chg_h;
+	u8 vact_st2_l;
+	u8 vact_st2_h;
+	u8 vsync_top_hdmi_l;
+	u8 vsync_top_hdmi_h;
+	u8 vsync_bot_hdmi_l;
+	u8 vsync_bot_hdmi_h;
+	u8 field_top_hdmi_l;
+	u8 field_top_hdmi_h;
+	u8 field_bot_hdmi_l;
+	u8 field_bot_hdmi_h;
+};
+
+struct hdmi_core_regs {
+	u8 h_blank[2];
+	u8 v_blank[3];
+	u8 h_v_line[3];
+	u8 vsync_pol[1];
+	u8 int_pro_mode[1];
+	u8 v_blank_f[3];
+	u8 h_sync_gen[3];
+	u8 v_sync_gen1[3];
+	u8 v_sync_gen2[3];
+	u8 v_sync_gen3[3];
+};
+
+struct hdmi_preset_conf {
+	struct hdmi_core_regs core;
+	/* u8 tg[29]; */
+	struct hdmi_tg_regs tg;
+	struct v4l2_mbus_framefmt mbus_fmt;
+};
+
+#endif /* _SAMSUNG_HDMI_H_ */
+
diff --git a/drivers/media/video/s5p-tv/hdmi_drv.c b/drivers/media/video/s5p-tv/hdmi_drv.c
new file mode 100644
index 0000000..49c7a8e
--- /dev/null
+++ b/drivers/media/video/s5p-tv/hdmi_drv.c
@@ -0,0 +1,1008 @@
+/*
+ * Samsung HDMI interface driver
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Tomasz Stanislawski, t.stanislaws@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundiation. either version 2 of the License,
+ * or (at your option) any later version
+ */
+
+#include "hdmi.h"
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <media/v4l2-subdev.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/bug.h>
+#include <linux/pm_runtime.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-dev.h>
+#include <media/v4l2-device.h>
+
+#include "regs-hdmi.h"
+
+MODULE_AUTHOR("Tomasz Stanislawski, t.stanislaws@samsung.com");
+MODULE_DESCRIPTION("Samsung HDMI");
+MODULE_LICENSE("GPL");
+
+/* #define HDMI_DEFAULT_PRESET V4L2_DV_480P59_94 */
+/* #define HDMI_DEFAULT_PRESET V4L2_DV_720P59_94 */
+#define HDMI_DEFAULT_PRESET V4L2_DV_1080P60
+/* #define HDMI_DEFAULT_PRESET V4L2_DV_1080P59_94 */
+
+/* D R I V E R   I N I T I A L I Z A T I O N */
+
+static struct platform_driver hdmi_driver;
+
+static int __init hdmi_init(void)
+{
+	int ret;
+	static const char banner[] __initdata = KERN_INFO \
+		"Samsung HDMI output driver, "
+		"(c) 2010 Samsung Electronics\n";
+	printk(banner);
+
+	ret = platform_driver_register(&hdmi_driver);
+	if (ret)
+		printk(KERN_ERR "HDMI platform driver register failed\n");
+
+	return ret;
+}
+module_init(hdmi_init);
+
+static void __exit hdmi_exit(void)
+{
+	platform_driver_unregister(&hdmi_driver);
+}
+module_exit(hdmi_exit);
+
+struct hdmi_resources {
+	struct clk *hdmi;
+	struct clk *sclk_hdmi;
+	struct clk *sclk_pixel;
+	struct clk *sclk_hdmiphy;
+	struct clk *hdmiphy;
+	struct regulator_bulk_data *regul_bulk;
+	int regul_count;
+};
+
+struct hdmi_device {
+	/** base address of HDMI registers */
+	void __iomem *regs;
+	/** HDMI interrupt */
+	unsigned int irq;
+	/** pointer to device parent */
+	struct device *dev;
+	/** subdev generated by HDMI device */
+	struct v4l2_subdev sd;
+	/** V4L2 device structure */
+	struct v4l2_device vdev;
+	/** subdev of HDMIPHY interface */
+	struct v4l2_subdev *phy_sd;
+	/** configuration of current graphic mode */
+	const struct hdmi_preset_conf *cur_conf;
+	/** current preset */
+	u32 cur_preset;
+	/** other resources */
+	struct hdmi_resources res;
+};
+
+struct hdmi_driver_data {
+	int hdmiphy_bus;
+};
+
+/* FIXME: this parameters should be acquired from platform data */
+static struct i2c_board_info hdmiphy_info = {
+	I2C_BOARD_INFO("hdmiphy", 0x38),
+	/* .irq = IRQ_HDMI_I2C, */
+};
+
+static struct hdmi_driver_data hdmi_driver_data[] = {
+	{ .hdmiphy_bus = 3 },
+	{ .hdmiphy_bus = 8 },
+};
+
+static struct platform_device_id hdmi_driver_types[] = {
+	{
+		.name		= "s5pv210-hdmi",
+		.driver_data	= (unsigned long)&hdmi_driver_data[0],
+	}, {
+		.name		= "exynos4-hdmi",
+		.driver_data	= (unsigned long)&hdmi_driver_data[1],
+	}, {
+		/* end node */
+	}
+};
+
+static irqreturn_t hdmi_irq_handler(int irq, void *dev_data);
+
+static const struct v4l2_subdev_ops hdmi_sd_ops;
+
+static const struct hdmi_preset_conf *hdmi_preset2conf(u32 preset);
+
+#define CHECK_POINT dev_err(dev, "%s:%d\n", __func__, __LINE__)
+
+static struct hdmi_device *sd_to_hdmi_dev(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct hdmi_device, sd);
+}
+
+static int hdmi_resources_init(struct hdmi_device *hdev);
+static void hdmi_resources_cleanup(struct hdmi_device *hdev);
+
+static int __devinit hdmi_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct resource *res;
+	struct i2c_adapter *phy_adapter;
+	struct v4l2_subdev *sd;
+	struct hdmi_device *hdmi_dev = NULL;
+	struct hdmi_driver_data *drv_data;
+
+	int ret;
+
+	dev_info(dev, "probe start\n");
+
+	hdmi_dev = kzalloc(sizeof(*hdmi_dev), GFP_KERNEL);
+	if (!hdmi_dev) {
+		dev_err(dev, "not enough memory.\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	hdmi_dev->dev = dev;
+
+	ret = hdmi_resources_init(hdmi_dev);
+	if (ret)
+		goto fail_hdev;
+
+	/* mapping HDMI registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(dev, "get memory resource failed.\n");
+		ret = -ENXIO;
+		goto fail_init;
+	}
+
+	/* TODO: add request_mem_region */
+	hdmi_dev->regs = ioremap(res->start, resource_size(res));
+	if (hdmi_dev->regs == NULL) {
+		dev_err(dev, "register mapping failed.\n");
+		ret = -ENXIO;
+		goto fail_hdev;
+	}
+
+	/* acquiring HDMI interrupt */
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (res == NULL) {
+		dev_err(dev, "get interrupt resource failed.\n");
+		ret = -ENXIO;
+		goto fail_regs;
+	}
+
+	ret = request_irq(res->start, hdmi_irq_handler, 0, "hdmi", hdmi_dev);
+	if (ret) {
+		dev_err(dev, "request interrupt failed.\n");
+		goto fail_regs;
+	}
+	hdmi_dev->irq = res->start;
+
+	ret = v4l2_device_register(dev, &hdmi_dev->vdev);
+	if (ret) {
+		dev_err(dev, "could not register v4l2 device.\n");
+		goto fail_irq;
+	}
+
+	drv_data = (struct hdmi_driver_data *)
+		platform_get_device_id(pdev)->driver_data;
+	phy_adapter = i2c_get_adapter(drv_data->hdmiphy_bus);
+	if (phy_adapter == NULL) {
+		dev_err(dev, "adapter request failed\n");
+		ret = -ENXIO;
+		goto fail_vdev;
+	}
+
+	hdmi_dev->phy_sd = v4l2_i2c_new_subdev_board(&hdmi_dev->vdev,
+		phy_adapter, &hdmiphy_info, NULL);
+	/* on failure or not adapter is no longer useful */
+	i2c_put_adapter(phy_adapter);
+	if (hdmi_dev->phy_sd == NULL) {
+		dev_err(dev, "missing subdev for hdmiphy\n");
+		ret = -ENODEV;
+		goto fail_vdev;
+	}
+
+	pm_runtime_enable(dev);
+
+	sd = &hdmi_dev->sd;
+	v4l2_subdev_init(sd, &hdmi_sd_ops);
+	sd->owner = THIS_MODULE;
+
+	strlcpy(sd->name, hdmi_driver.driver.name, sizeof sd->name);
+	hdmi_dev->cur_preset = HDMI_DEFAULT_PRESET;
+	/* FIXME: missing fail preset is not supported */
+	hdmi_dev->cur_conf = hdmi_preset2conf(hdmi_dev->cur_preset);
+
+	/* storing subdev for call that have only access to struct device */
+	dev_set_drvdata(dev, sd);
+
+	dev_info(dev, "probe sucessful\n");
+
+	return 0;
+
+fail_vdev:
+	v4l2_device_unregister(&hdmi_dev->vdev);
+
+fail_irq:
+	free_irq(hdmi_dev->irq, hdmi_dev);
+
+fail_regs:
+	iounmap(hdmi_dev->regs);
+
+fail_init:
+	hdmi_resources_cleanup(hdmi_dev);
+
+fail_hdev:
+	kfree(hdmi_dev);
+
+fail:
+	dev_info(dev, "probe failed\n");
+	return ret;
+}
+
+static int __devexit hdmi_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct hdmi_device *hdmi_dev = sd_to_hdmi_dev(sd);
+
+	pm_runtime_disable(dev);
+	v4l2_device_unregister(&hdmi_dev->vdev);
+	disable_irq(hdmi_dev->irq);
+	free_irq(hdmi_dev->irq, hdmi_dev);
+	iounmap(hdmi_dev->regs);
+	hdmi_resources_cleanup(hdmi_dev);
+	kfree(hdmi_dev);
+	dev_info(dev, "remove sucessful\n");
+
+	return 0;
+}
+
+static void hdmi_resource_poweron(struct hdmi_resources *res);
+static void hdmi_resource_poweroff(struct hdmi_resources *res);
+static int hdmi_conf_apply(struct hdmi_device *hdmi_dev);
+
+static int hdmi_runtime_suspend(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
+
+	dev_info(dev, "%s\n", __func__);
+	hdmi_resource_poweroff(&hdev->res);
+	return 0;
+}
+
+static int hdmi_runtime_resume(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
+	int ret = 0;
+
+	dev_info(dev, "%s\n", __func__);
+
+	hdmi_resource_poweron(&hdev->res);
+
+	ret = hdmi_conf_apply(hdev);
+	if (ret)
+		goto fail;
+
+	dev_info(dev, "poweron succeed\n");
+
+	return 0;
+
+fail:
+	/* turn power off */
+	hdmi_resource_poweroff(&hdev->res);
+	dev_info(dev, "poweron failed\n");
+
+	return ret;
+}
+
+static const struct dev_pm_ops hdmi_pm_ops = {
+	.runtime_suspend = hdmi_runtime_suspend,
+	.runtime_resume	 = hdmi_runtime_resume,
+};
+
+static struct platform_driver hdmi_driver __refdata = {
+	.probe = hdmi_probe,
+	.remove = __devexit_p(hdmi_remove),
+	.id_table = hdmi_driver_types,
+	.driver = {
+		.name = "s5p-hdmi",
+		.owner = THIS_MODULE,
+		.pm = &hdmi_pm_ops,
+	}
+};
+
+static int hdmi_resources_init(struct hdmi_device *hdev)
+{
+	struct device *dev = hdev->dev;
+	struct hdmi_resources *res = &hdev->res;
+	static char *supply[] = {
+		"hdmi-en",
+		"vdd",
+		"vdd_osc",
+		"vdd_pll",
+	};
+	int i, ret;
+
+	dev_info(dev, "HDMI resource init\n");
+
+	memset(res, 0, sizeof *res);
+	/* get clocks, power */
+
+	/* move this names somewhere */
+	res->hdmi = clk_get(dev, "hdmi");
+	if (IS_ERR_OR_NULL(res->hdmi)) {
+		dev_err(dev, "failed to get clock 'hdmi'\n");
+		goto fail;
+	}
+	res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
+	if (IS_ERR_OR_NULL(res->sclk_hdmi)) {
+		dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
+		goto fail;
+	}
+	res->sclk_pixel = clk_get(dev, "sclk_pixel");
+	if (IS_ERR_OR_NULL(res->sclk_pixel)) {
+		dev_err(dev, "failed to get clock 'sclk_pixel'\n");
+		goto fail;
+	}
+	res->sclk_hdmiphy = clk_get(dev, "sclk_hdmiphy");
+	if (IS_ERR_OR_NULL(res->sclk_hdmiphy)) {
+		dev_err(dev, "failed to get clock 'sclk_hdmiphy'\n");
+		goto fail;
+	}
+	res->hdmiphy = clk_get(dev, "hdmiphy");
+	if (IS_ERR_OR_NULL(res->hdmiphy)) {
+		dev_err(dev, "failed to get clock 'hdmiphy'\n");
+		goto fail;
+	}
+	res->regul_bulk = kzalloc(ARRAY_SIZE(supply) *
+		sizeof res->regul_bulk[0], GFP_KERNEL);
+	if (!res->regul_bulk) {
+		dev_err(dev, "failed to get memory for regulators\n");
+		goto fail;
+	}
+	for (i = 0; i < ARRAY_SIZE(supply); ++i) {
+		res->regul_bulk[i].supply = supply[i];
+		res->regul_bulk[i].consumer = NULL;
+	}
+
+	ret = regulator_bulk_get(dev, ARRAY_SIZE(supply), res->regul_bulk);
+	if (ret) {
+		dev_err(dev, "failed to get regulators\n");
+		goto fail;
+	}
+	res->regul_count = ARRAY_SIZE(supply);
+
+	return 0;
+fail:
+	dev_err(dev, "HDMI resource init - failed\n");
+	hdmi_resources_cleanup(hdev);
+	return -ENODEV;
+}
+
+static void hdmi_resources_cleanup(struct hdmi_device *hdev)
+{
+	struct hdmi_resources *res = &hdev->res;
+
+	dev_info(hdev->dev, "HDMI resource deinit\n");
+	/* put clocks, power */
+	if (res->regul_count)
+		regulator_bulk_free(res->regul_count, res->regul_bulk);
+	/* kfree is NULL-safe */
+	kfree(res->regul_bulk);
+	if (!IS_ERR_OR_NULL(res->hdmiphy))
+		clk_put(res->hdmiphy);
+	if (!IS_ERR_OR_NULL(res->sclk_hdmiphy))
+		clk_put(res->sclk_hdmiphy);
+	if (!IS_ERR_OR_NULL(res->sclk_pixel))
+		clk_put(res->sclk_pixel);
+	if (!IS_ERR_OR_NULL(res->sclk_hdmi))
+		clk_put(res->sclk_hdmi);
+	if (!IS_ERR_OR_NULL(res->hdmi))
+		clk_put(res->hdmi);
+	memset(res, 0, sizeof *res);
+}
+
+static inline
+void hdmi_write(struct hdmi_device *hdev, u32 reg_id, u32 value)
+{
+	writel(value, hdev->regs + reg_id);
+}
+
+static inline
+void hdmi_write_mask(struct hdmi_device *hdev, u32 reg_id, u32 value, u32 mask)
+{
+	u32 old = readl(hdev->regs + reg_id);
+	value = (value & mask) | (old & ~mask);
+	writel(value, hdev->regs + reg_id);
+}
+
+static inline
+void hdmi_writeb(struct hdmi_device *hdev, u32 reg_id, u8 value)
+{
+	writeb(value, hdev->regs + reg_id);
+}
+
+static inline u32 hdmi_read(struct hdmi_device *hdev, u32 reg_id)
+{
+	return readl(hdev->regs + reg_id);
+}
+
+static irqreturn_t hdmi_irq_handler(int irq, void *dev_data)
+{
+	struct hdmi_device *hdev = dev_data;
+	u32 intc_flag;
+	(void)irq;
+	/* TODO: add V4L2 event generation */
+
+	intc_flag = hdmi_read(hdev, HDMI_INTC_FLAG);
+	/* clearing flags for HPD plug/unplug */
+	if (intc_flag & HDMI_INTC_FLAG_HPD_UNPLUG) {
+		printk(KERN_INFO "unplugged\n");
+		hdmi_write_mask(hdev, HDMI_INTC_FLAG, ~0,
+			HDMI_INTC_FLAG_HPD_UNPLUG);
+	}
+	if (intc_flag & HDMI_INTC_FLAG_HPD_PLUG) {
+		printk(KERN_INFO "plugged\n");
+		hdmi_write_mask(hdev, HDMI_INTC_FLAG, ~0,
+			HDMI_INTC_FLAG_HPD_PLUG);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static int hdmi_s_dv_preset(struct v4l2_subdev *sd,
+	struct v4l2_dv_preset *preset);
+
+static void hdmi_resource_poweron(struct hdmi_resources *res)
+{
+	/* turn HDMI power on */
+	regulator_bulk_enable(res->regul_count, res->regul_bulk);
+	/* power-on hdmi physical interface */
+	clk_enable(res->hdmiphy);
+	/* use VPP as parent clock; HDMIPHY is not working yet */
+	clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
+	/* turn clocks on */
+	clk_enable(res->hdmi);
+	clk_enable(res->sclk_hdmi);
+}
+
+static void hdmi_resource_poweroff(struct hdmi_resources *res)
+{
+	/* turn clocks off */
+	clk_disable(res->sclk_hdmi);
+	clk_disable(res->hdmi);
+	/* power-off hdmiphy */
+	clk_disable(res->hdmiphy);
+	/* turn HDMI power off */
+	regulator_bulk_disable(res->regul_count, res->regul_bulk);
+}
+
+static int hdmi_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
+	int ret;
+	if (on)
+		ret = pm_runtime_get_sync(hdev->dev);
+	else
+		ret = pm_runtime_put_sync(hdev->dev);
+	/* only values < 0 indicate errors */
+	return IS_ERR_VALUE(ret) ? ret : 0;
+}
+
+static void hdmi_timing_apply(struct hdmi_device *hdev,
+	const struct hdmi_preset_conf *conf);
+static void hdmi_dumpregs(struct hdmi_device *hdev, char *prefix);
+
+static void hdmi_reg_init(struct hdmi_device *hdev)
+{
+	/* enable HPD interrupts */
+	hdmi_write_mask(hdev, HDMI_INTC_CON, ~0, HDMI_INTC_EN_GLOBAL |
+		HDMI_INTC_EN_HPD_PLUG | HDMI_INTC_EN_HPD_UNPLUG);
+	/* choose HDMI mode */
+	hdmi_write_mask(hdev, HDMI_MODE_SEL,
+		HDMI_MODE_HDMI_EN | HDMI_MODE_DVI_DIS, HDMI_MODE_MASK);
+	/* XXX: choose bluescreen */
+	hdmi_write_mask(hdev, HDMI_CON_0, 0, HDMI_BLUE_SCR_EN);
+	/* choose bluescreen (fecal) color */
+	hdmi_writeb(hdev, HDMI_BLUE_SCREEN_0, 0x12);
+	hdmi_writeb(hdev, HDMI_BLUE_SCREEN_1, 0x34);
+	hdmi_writeb(hdev, HDMI_BLUE_SCREEN_2, 0x56);
+	/* enable AVI packet every vsync, fixes purple line problem */
+	hdmi_writeb(hdev, HDMI_AVI_CON, 0x02);
+	/* force YUV444, look to CEA-861-D, table 7 for more detail */
+	hdmi_writeb(hdev, HDMI_AVI_BYTE1, 2 << 5);
+	hdmi_write_mask(hdev, HDMI_CON_1, 2, 3 << 5);
+}
+
+static int hdmi_conf_apply(struct hdmi_device *hdmi_dev)
+{
+	struct device *dev = hdmi_dev->dev;
+	const struct hdmi_preset_conf *conf = hdmi_dev->cur_conf;
+	struct v4l2_dv_preset preset;
+	int ret;
+	dev_info(dev, "%s\n", __func__);
+
+	/* reset hdmiphy */
+	hdmi_write_mask(hdmi_dev, HDMI_PHY_RSTOUT, ~0, HDMI_PHY_SW_RSTOUT);
+	mdelay(10);
+	hdmi_write_mask(hdmi_dev, HDMI_PHY_RSTOUT,  0, HDMI_PHY_SW_RSTOUT);
+	mdelay(10);
+
+	/* configure presets */
+	preset.preset = hdmi_dev->cur_preset;
+	ret = v4l2_subdev_call(hdmi_dev->phy_sd, video, s_dv_preset, &preset);
+	if (ret) {
+		dev_err(dev, "failed to set preset (%u)\n", preset.preset);
+		return ret;
+	}
+
+	/* resetting HDMI core */
+	hdmi_write_mask(hdmi_dev, HDMI_CORE_RSTOUT,  0, HDMI_CORE_SW_RSTOUT);
+	mdelay(10);
+	hdmi_write_mask(hdmi_dev, HDMI_CORE_RSTOUT, ~0, HDMI_CORE_SW_RSTOUT);
+	mdelay(10);
+
+	hdmi_reg_init(hdmi_dev);
+
+	/* setting core registers */
+	hdmi_timing_apply(hdmi_dev, conf);
+
+	return 0;
+}
+
+static int hdmi_s_dv_preset(struct v4l2_subdev *sd,
+	struct v4l2_dv_preset *preset)
+{
+	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
+	struct device *dev = hdev->dev;
+	const struct hdmi_preset_conf *conf;
+
+	conf = hdmi_preset2conf(preset->preset);
+	if (conf == NULL) {
+		dev_err(dev, "preset (%u) not supported\n", preset->preset);
+		return -ENXIO;
+	}
+	hdev->cur_conf = conf;
+	hdev->cur_preset = preset->preset;
+	return 0;
+}
+
+static int hdmi_enum_dv_presets(struct v4l2_subdev *sd,
+	struct v4l2_dv_enum_preset *preset);
+
+static int hdmi_g_mbus_fmt(struct v4l2_subdev *sd,
+	  struct v4l2_mbus_framefmt *fmt)
+{
+	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
+	struct device *dev = hdev->dev;
+	dev_info(dev, "%s\n", __func__);
+	if (!hdev->cur_conf)
+		return -ENXIO;
+	*fmt = hdev->cur_conf->mbus_fmt;
+	return 0;
+}
+
+static int hdmi_streamon(struct hdmi_device *hdev)
+{
+	struct device *dev = hdev->dev;
+	struct hdmi_resources *res = &hdev->res;
+	int ret, tries;
+
+	dev_info(dev, "%s\n", __func__);
+
+	ret = v4l2_subdev_call(hdev->phy_sd, video, s_stream, 1);
+	if (ret)
+		return ret;
+
+	/* waiting for HDMIPHY's PLL to get to steady state */
+	for (tries = 100; tries; --tries) {
+		u32 val = hdmi_read(hdev, HDMI_PHY_STATUS);
+		if (val & HDMI_PHY_STATUS_READY)
+			break;
+		mdelay(1);
+	}
+	/* steady state not achieved */
+	if (tries == 0) {
+		dev_err(dev, "hdmiphy's pll could not reach steady state.\n");
+		v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0);
+		hdmi_dumpregs(hdev, "s_stream");
+		return -EIO;
+	}
+
+	/* hdmiphy clock is used for HDMI in streaming mode */
+	clk_disable(res->sclk_hdmi);
+	clk_set_parent(res->sclk_hdmi, res->sclk_hdmiphy);
+	clk_enable(res->sclk_hdmi);
+
+	hdmi_write_mask(hdev, HDMI_CON_0, ~0, HDMI_EN);
+	/* XXX: enable VSYNC and BT656 synchro */
+	/* dmi_write(hdev, S5P_HDMI_TG_CMD, ~0, (1 << 3) | (1 << 4)); */
+	hdmi_write_mask(hdev, HDMI_TG_CMD, ~0, HDMI_TG_EN);
+	hdmi_dumpregs(hdev, "streamon");
+	return 0;
+}
+
+static int hdmi_streamoff(struct hdmi_device *hdev)
+{
+	struct device *dev = hdev->dev;
+	struct hdmi_resources *res = &hdev->res;
+
+	dev_info(dev, "%s\n", __func__);
+
+	hdmi_write_mask(hdev, HDMI_CON_0, 0, HDMI_EN);
+	hdmi_write_mask(hdev, HDMI_TG_CMD, 0, HDMI_TG_EN);
+
+	/* pixel(vpll) clock is used for HDMI in config mode */
+	clk_disable(res->sclk_hdmi);
+	clk_set_parent(res->sclk_hdmi, res->sclk_pixel);
+	clk_enable(res->sclk_hdmi);
+
+	v4l2_subdev_call(hdev->phy_sd, video, s_stream, 0);
+
+	hdmi_dumpregs(hdev, "streamoff");
+	return 0;
+}
+
+static int hdmi_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct hdmi_device *hdev = sd_to_hdmi_dev(sd);
+	struct device *dev = hdev->dev;
+	dev_info(dev, "%s(%d)\n", __func__, enable);
+	if (enable)
+		return hdmi_streamon(hdev);
+	else
+		return hdmi_streamoff(hdev);
+	/* call stream_setup from pdata (it changes clocks) */
+	/* set bit 0 in in HDMI_CON_0 */
+	/* set bits in in HDMI_TG_CMD */
+	/* enjoy your TV */
+}
+
+static const struct v4l2_subdev_core_ops hdmi_sd_core_ops = {
+	.s_power = hdmi_s_power,
+};
+
+static const struct v4l2_subdev_video_ops hdmi_sd_video_ops = {
+	.s_dv_preset = hdmi_s_dv_preset,
+	.enum_dv_presets = hdmi_enum_dv_presets,
+	.g_mbus_fmt = hdmi_g_mbus_fmt,
+	.s_stream = hdmi_s_stream,
+};
+
+static const struct v4l2_subdev_ops hdmi_sd_ops = {
+	.core = &hdmi_sd_core_ops,
+	.video = &hdmi_sd_video_ops,
+};
+
+static void hdmi_timing_apply(struct hdmi_device *hdev,
+	const struct hdmi_preset_conf *conf)
+{
+	const struct hdmi_core_regs *core = &conf->core;
+	const struct hdmi_tg_regs *tg = &conf->tg;
+	/* setting core registers */
+	hdmi_writeb(hdev, HDMI_H_BLANK_0, core->h_blank[0]);
+	hdmi_writeb(hdev, HDMI_H_BLANK_1, core->h_blank[1]);
+	hdmi_writeb(hdev, HDMI_V_BLANK_0, core->v_blank[0]);
+	hdmi_writeb(hdev, HDMI_V_BLANK_1, core->v_blank[1]);
+	hdmi_writeb(hdev, HDMI_V_BLANK_2, core->v_blank[2]);
+	hdmi_writeb(hdev, HDMI_H_V_LINE_0, core->h_v_line[0]);
+	hdmi_writeb(hdev, HDMI_H_V_LINE_1, core->h_v_line[1]);
+	hdmi_writeb(hdev, HDMI_H_V_LINE_2, core->h_v_line[2]);
+	hdmi_writeb(hdev, HDMI_VSYNC_POL, core->vsync_pol[0]);
+	hdmi_writeb(hdev, HDMI_INT_PRO_MODE, core->int_pro_mode[0]);
+	hdmi_writeb(hdev, HDMI_V_BLANK_F_0, core->v_blank_f[0]);
+	hdmi_writeb(hdev, HDMI_V_BLANK_F_1, core->v_blank_f[1]);
+	hdmi_writeb(hdev, HDMI_V_BLANK_F_2, core->v_blank_f[2]);
+	hdmi_writeb(hdev, HDMI_H_SYNC_GEN_0, core->h_sync_gen[0]);
+	hdmi_writeb(hdev, HDMI_H_SYNC_GEN_1, core->h_sync_gen[1]);
+	hdmi_writeb(hdev, HDMI_H_SYNC_GEN_2, core->h_sync_gen[2]);
+	hdmi_writeb(hdev, HDMI_V_SYNC_GEN_1_0, core->v_sync_gen1[0]);
+	hdmi_writeb(hdev, HDMI_V_SYNC_GEN_1_1, core->v_sync_gen1[1]);
+	hdmi_writeb(hdev, HDMI_V_SYNC_GEN_1_2, core->v_sync_gen1[2]);
+	hdmi_writeb(hdev, HDMI_V_SYNC_GEN_2_0, core->v_sync_gen2[0]);
+	hdmi_writeb(hdev, HDMI_V_SYNC_GEN_2_1, core->v_sync_gen2[1]);
+	hdmi_writeb(hdev, HDMI_V_SYNC_GEN_2_2, core->v_sync_gen2[2]);
+	hdmi_writeb(hdev, HDMI_V_SYNC_GEN_3_0, core->v_sync_gen3[0]);
+	hdmi_writeb(hdev, HDMI_V_SYNC_GEN_3_1, core->v_sync_gen3[1]);
+	hdmi_writeb(hdev, HDMI_V_SYNC_GEN_3_2, core->v_sync_gen3[2]);
+	/* Timing generator registers */
+	hdmi_writeb(hdev, HDMI_TG_H_FSZ_L, tg->h_fsz_l);
+	hdmi_writeb(hdev, HDMI_TG_H_FSZ_H, tg->h_fsz_h);
+	hdmi_writeb(hdev, HDMI_TG_HACT_ST_L, tg->hact_st_l);
+	hdmi_writeb(hdev, HDMI_TG_HACT_ST_H, tg->hact_st_h);
+	hdmi_writeb(hdev, HDMI_TG_HACT_SZ_L, tg->hact_sz_l);
+	hdmi_writeb(hdev, HDMI_TG_HACT_SZ_H, tg->hact_sz_h);
+	hdmi_writeb(hdev, HDMI_TG_V_FSZ_L, tg->v_fsz_l);
+	hdmi_writeb(hdev, HDMI_TG_V_FSZ_H, tg->v_fsz_h);
+	hdmi_writeb(hdev, HDMI_TG_VSYNC_L, tg->vsync_l);
+	hdmi_writeb(hdev, HDMI_TG_VSYNC_H, tg->vsync_h);
+	hdmi_writeb(hdev, HDMI_TG_VSYNC2_L, tg->vsync2_l);
+	hdmi_writeb(hdev, HDMI_TG_VSYNC2_H, tg->vsync2_h);
+	hdmi_writeb(hdev, HDMI_TG_VACT_ST_L, tg->vact_st_l);
+	hdmi_writeb(hdev, HDMI_TG_VACT_ST_H, tg->vact_st_h);
+	hdmi_writeb(hdev, HDMI_TG_VACT_SZ_L, tg->vact_sz_l);
+	hdmi_writeb(hdev, HDMI_TG_VACT_SZ_H, tg->vact_sz_h);
+	hdmi_writeb(hdev, HDMI_TG_FIELD_CHG_L, tg->field_chg_l);
+	hdmi_writeb(hdev, HDMI_TG_FIELD_CHG_H, tg->field_chg_h);
+	hdmi_writeb(hdev, HDMI_TG_VACT_ST2_L, tg->vact_st2_l);
+	hdmi_writeb(hdev, HDMI_TG_VACT_ST2_H, tg->vact_st2_h);
+	hdmi_writeb(hdev, HDMI_TG_VSYNC_TOP_HDMI_L, tg->vsync_top_hdmi_l);
+	hdmi_writeb(hdev, HDMI_TG_VSYNC_TOP_HDMI_H, tg->vsync_top_hdmi_h);
+	hdmi_writeb(hdev, HDMI_TG_VSYNC_BOT_HDMI_L, tg->vsync_bot_hdmi_l);
+	hdmi_writeb(hdev, HDMI_TG_VSYNC_BOT_HDMI_H, tg->vsync_bot_hdmi_h);
+	hdmi_writeb(hdev, HDMI_TG_FIELD_TOP_HDMI_L, tg->field_top_hdmi_l);
+	hdmi_writeb(hdev, HDMI_TG_FIELD_TOP_HDMI_H, tg->field_top_hdmi_h);
+	hdmi_writeb(hdev, HDMI_TG_FIELD_BOT_HDMI_L, tg->field_bot_hdmi_l);
+	hdmi_writeb(hdev, HDMI_TG_FIELD_BOT_HDMI_H, tg->field_bot_hdmi_h);
+}
+
+static const struct hdmi_preset_conf hdmi_conf_480p = {
+	.core = {
+		.h_blank = {0x8a, 0x00},
+		.v_blank = {0x0d, 0x6a, 0x01},
+		.h_v_line = {0x0d, 0xa2, 0x35},
+		.vsync_pol = {0x01},
+		.int_pro_mode = {0x00},
+		.v_blank_f = {0x00, 0x00, 0x00},
+		.h_sync_gen = {0x0e, 0x30, 0x11},
+		.v_sync_gen1 = {0x0f, 0x90, 0x00},
+		/* other don't care */
+	},
+	.tg = {
+		0x00, /* cmd */
+		0x5a, 0x03, /* h_fsz */
+		0x8a, 0x00, 0xd0, 0x02, /* hact */
+		0x0d, 0x02, /* v_fsz */
+		0x01, 0x00, 0x33, 0x02, /* vsync */
+		0x2d, 0x00, 0xe0, 0x01, /* vact */
+		0x33, 0x02, /* field_chg */
+		0x49, 0x02, /* vact_st2 */
+		0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
+		0x01, 0x00, 0x33, 0x02, /* field top/bot */
+	},
+	.mbus_fmt = {
+		.width = 720,
+		.height = 480,
+		.code = V4L2_MBUS_FMT_FIXED, /* means RGB888 */
+		.field = V4L2_FIELD_NONE,
+	},
+};
+
+static const struct hdmi_preset_conf hdmi_conf_720p60 = {
+	.core = {
+		.h_blank = {0x72, 0x01},
+		.v_blank = {0xee, 0xf2, 0x00},
+		.h_v_line = {0xee, 0x22, 0x67},
+		.vsync_pol = {0x00},
+		.int_pro_mode = {0x00},
+		.v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
+		.h_sync_gen = {0x6c, 0x50, 0x02},
+		.v_sync_gen1 = {0x0a, 0x50, 0x00},
+		/* other don't care */
+	},
+	.tg = {
+		0x00, /* cmd */
+		0x72, 0x06, /* h_fsz */
+		0x72, 0x01, 0x00, 0x05, /* hact */
+		0xee, 0x02, /* v_fsz */
+		0x01, 0x00, 0x33, 0x02, /* vsync */
+		0x1e, 0x00, 0xd0, 0x02, /* vact */
+		0x33, 0x02, /* field_chg */
+		0x49, 0x02, /* vact_st2 */
+		0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
+		0x01, 0x00, 0x33, 0x02, /* field top/bot */
+	},
+	.mbus_fmt = {
+		.width = 1280,
+		.height = 720,
+		.code = V4L2_MBUS_FMT_FIXED, /* means RGB888 */
+		.field = V4L2_FIELD_NONE,
+	},
+};
+
+static const struct hdmi_preset_conf hdmi_conf_1080p50 = {
+	.core = {
+		.h_blank = {0xd0, 0x02},
+		.v_blank = {0x65, 0x6c, 0x01},
+		.h_v_line = {0x65, 0x04, 0xa5},
+		.vsync_pol = {0x00},
+		.int_pro_mode = {0x00},
+		.v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
+		.h_sync_gen = {0x0e, 0xea, 0x08},
+		.v_sync_gen1 = {0x09, 0x40, 0x00},
+		/* other don't care */
+	},
+	.tg = {
+		0x00, /* cmd */
+		0x98, 0x08, /* h_fsz */
+		0x18, 0x01, 0x80, 0x07, /* hact */
+		0x65, 0x04, /* v_fsz */
+		0x01, 0x00, 0x33, 0x02, /* vsync */
+		0x2d, 0x00, 0x38, 0x04, /* vact */
+		0x33, 0x02, /* field_chg */
+		0x49, 0x02, /* vact_st2 */
+		0x01, 0x00, 0x33, 0x02, /* vsync top/bot */
+		0x01, 0x00, 0x33, 0x02, /* field top/bot */
+	},
+	.mbus_fmt = {
+		.width = 1920,
+		.height = 1080,
+		.code = V4L2_MBUS_FMT_FIXED, /* means RGB888 */
+		.field = V4L2_FIELD_NONE,
+	},
+};
+
+static const struct hdmi_preset_conf hdmi_conf_1080p60 = {
+	.core = {
+		.h_blank = {0x18, 0x01},
+		.v_blank = {0x65, 0x6c, 0x01},
+		.h_v_line = {0x65, 0x84, 0x89},
+		.vsync_pol = {0x00},
+		.int_pro_mode = {0x00},
+		.v_blank_f = {0x00, 0x00, 0x00}, /* don't care */
+		.h_sync_gen = {0x56, 0x08, 0x02},
+		.v_sync_gen1 = {0x09, 0x40, 0x00},
+		/* other don't care */
+	},
+	.tg = {
+		0x00, /* cmd */
+		0x98, 0x08, /* h_fsz */
+		0x18, 0x01, 0x80, 0x07, /* hact */
+		0x65, 0x04, /* v_fsz */
+		0x01, 0x00, 0x33, 0x02, /* vsync */
+		0x2d, 0x00, 0x38, 0x04, /* vact */
+		0x33, 0x02, /* field_chg */
+		0x48, 0x02, /* vact_st2 */
+		0x01, 0x00, 0x01, 0x00, /* vsync top/bot */
+		0x01, 0x00, 0x33, 0x02, /* field top/bot */
+	},
+	.mbus_fmt = {
+		.width = 1920,
+		.height = 1080,
+		.code = V4L2_MBUS_FMT_FIXED, /* means RGB888 */
+		.field = V4L2_FIELD_NONE,
+	},
+};
+
+static const struct {
+	u32 preset;
+	const struct hdmi_preset_conf *conf;
+} hdmi_conf[] = {
+	{ V4L2_DV_480P59_94, &hdmi_conf_480p },
+	{ V4L2_DV_720P59_94, &hdmi_conf_720p60 },
+	{ V4L2_DV_1080P50, &hdmi_conf_1080p50 },
+	{ V4L2_DV_1080P30, &hdmi_conf_1080p60 },
+	{ V4L2_DV_1080P60, &hdmi_conf_1080p60 },
+	{ V4L2_DV_1080P59_94, &hdmi_conf_1080p60 },
+};
+
+static const struct hdmi_preset_conf *hdmi_preset2conf(u32 preset)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(hdmi_conf); ++i)
+		if (hdmi_conf[i].preset == preset)
+			return  hdmi_conf[i].conf;
+	return NULL;
+}
+
+static int hdmi_enum_dv_presets(struct v4l2_subdev *sd,
+	struct v4l2_dv_enum_preset *preset)
+{
+	if (preset->index >= ARRAY_SIZE(hdmi_conf))
+		return -EINVAL;
+	return v4l_fill_dv_preset_info(hdmi_conf[preset->index].preset, preset);
+}
+
+static void hdmi_dumpregs(struct hdmi_device *hdev, char *prefix)
+{
+#define DUMPREG(reg_id) \
+	printk(KERN_DEBUG "%s:" #reg_id " = %08x\n", prefix, \
+	readl(hdev->regs + reg_id))
+	printk(KERN_ERR "%s: ---- CONTROL REGISTERS ----\n", prefix);
+	DUMPREG(HDMI_INTC_FLAG);
+	DUMPREG(HDMI_INTC_CON);
+	DUMPREG(HDMI_HPD_STATUS);
+	DUMPREG(HDMI_PHY_RSTOUT);
+	DUMPREG(HDMI_PHY_VPLL);
+	DUMPREG(HDMI_PHY_CMU);
+	DUMPREG(HDMI_CORE_RSTOUT);
+
+	printk(KERN_ERR "%s: ---- CORE REGISTERS ----\n", prefix);
+	DUMPREG(HDMI_CON_0);
+	DUMPREG(HDMI_CON_1);
+	DUMPREG(HDMI_CON_2);
+	DUMPREG(HDMI_SYS_STATUS);
+	DUMPREG(HDMI_PHY_STATUS);
+	DUMPREG(HDMI_STATUS_EN);
+	DUMPREG(HDMI_HPD);
+	DUMPREG(HDMI_MODE_SEL);
+	DUMPREG(HDMI_HPD_GEN);
+	DUMPREG(HDMI_DC_CONTROL);
+	DUMPREG(HDMI_VIDEO_PATTERN_GEN);
+
+	printk(KERN_ERR "%s: ---- CORE SYNC REGISTERS ----\n", prefix);
+	DUMPREG(HDMI_H_BLANK_0);
+	DUMPREG(HDMI_H_BLANK_1);
+	DUMPREG(HDMI_V_BLANK_0);
+	DUMPREG(HDMI_V_BLANK_1);
+	DUMPREG(HDMI_V_BLANK_2);
+	DUMPREG(HDMI_H_V_LINE_0);
+	DUMPREG(HDMI_H_V_LINE_1);
+	DUMPREG(HDMI_H_V_LINE_2);
+	DUMPREG(HDMI_VSYNC_POL);
+	DUMPREG(HDMI_INT_PRO_MODE);
+	DUMPREG(HDMI_V_BLANK_F_0);
+	DUMPREG(HDMI_V_BLANK_F_1);
+	DUMPREG(HDMI_V_BLANK_F_2);
+	DUMPREG(HDMI_H_SYNC_GEN_0);
+	DUMPREG(HDMI_H_SYNC_GEN_1);
+	DUMPREG(HDMI_H_SYNC_GEN_2);
+	DUMPREG(HDMI_V_SYNC_GEN_1_0);
+	DUMPREG(HDMI_V_SYNC_GEN_1_1);
+	DUMPREG(HDMI_V_SYNC_GEN_1_2);
+	DUMPREG(HDMI_V_SYNC_GEN_2_0);
+	DUMPREG(HDMI_V_SYNC_GEN_2_1);
+	DUMPREG(HDMI_V_SYNC_GEN_2_2);
+	DUMPREG(HDMI_V_SYNC_GEN_3_0);
+	DUMPREG(HDMI_V_SYNC_GEN_3_1);
+	DUMPREG(HDMI_V_SYNC_GEN_3_2);
+
+	printk(KERN_ERR "%s: ---- TG REGISTERS ----\n", prefix);
+	DUMPREG(HDMI_TG_CMD);
+	DUMPREG(HDMI_TG_H_FSZ_L);
+	DUMPREG(HDMI_TG_H_FSZ_H);
+	DUMPREG(HDMI_TG_HACT_ST_L);
+	DUMPREG(HDMI_TG_HACT_ST_H);
+	DUMPREG(HDMI_TG_HACT_SZ_L);
+	DUMPREG(HDMI_TG_HACT_SZ_H);
+	DUMPREG(HDMI_TG_V_FSZ_L);
+	DUMPREG(HDMI_TG_V_FSZ_H);
+	DUMPREG(HDMI_TG_VSYNC_L);
+	DUMPREG(HDMI_TG_VSYNC_H);
+	DUMPREG(HDMI_TG_VSYNC2_L);
+	DUMPREG(HDMI_TG_VSYNC2_H);
+	DUMPREG(HDMI_TG_VACT_ST_L);
+	DUMPREG(HDMI_TG_VACT_ST_H);
+	DUMPREG(HDMI_TG_VACT_SZ_L);
+	DUMPREG(HDMI_TG_VACT_SZ_H);
+	DUMPREG(HDMI_TG_FIELD_CHG_L);
+	DUMPREG(HDMI_TG_FIELD_CHG_H);
+	DUMPREG(HDMI_TG_VACT_ST2_L);
+	DUMPREG(HDMI_TG_VACT_ST2_H);
+	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_L);
+	DUMPREG(HDMI_TG_VSYNC_TOP_HDMI_H);
+	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_L);
+	DUMPREG(HDMI_TG_VSYNC_BOT_HDMI_H);
+	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_L);
+	DUMPREG(HDMI_TG_FIELD_TOP_HDMI_H);
+	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_L);
+	DUMPREG(HDMI_TG_FIELD_BOT_HDMI_H);
+#undef DUMPREG
+}
+
diff --git a/drivers/media/video/s5p-tv/hdmiphy_drv.c b/drivers/media/video/s5p-tv/hdmiphy_drv.c
new file mode 100644
index 0000000..140f7d4
--- /dev/null
+++ b/drivers/media/video/s5p-tv/hdmiphy_drv.c
@@ -0,0 +1,250 @@
+/*
+ * Samsung HDMI Physical interface driver
+ *
+ * Copyright (C) 2010 Samsung Electronics Co.Ltd
+ * Author: Tomasz Stanislawski <t.stanislaws@samsung.com>
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/err.h>
+
+#include <media/v4l2-subdev.h>
+
+/* Module information */
+MODULE_AUTHOR("Tomasz Stanislawski <t.stanislaws@samsung.com>");
+MODULE_DESCRIPTION("Samsung HDMI Physical interface driver");
+MODULE_LICENSE("GPL");
+
+struct hdmiphy_conf {
+	u32 preset;
+	const u8 *data;
+};
+
+static struct i2c_driver hdmiphy_driver;
+static const struct v4l2_subdev_ops hdmiphy_ops;
+static const struct hdmiphy_conf hdmiphy_conf[];
+
+static int __init hdmiphy_init(void)
+{
+	return i2c_add_driver(&hdmiphy_driver);
+}
+module_init(hdmiphy_init);
+
+static void __exit hdmiphy_exit(void)
+{
+	i2c_del_driver(&hdmiphy_driver);
+}
+module_exit(hdmiphy_exit);
+
+static int __devinit hdmiphy_probe(struct i2c_client *client,
+	const struct i2c_device_id *id)
+{
+	static struct v4l2_subdev sd;
+	struct device *dev = &client->dev;
+	v4l2_i2c_subdev_init(&sd, client, &hdmiphy_ops);
+	dev_info(dev, "probe successful\n");
+	return 0;
+}
+
+static int __devexit hdmiphy_remove(struct i2c_client *client)
+{
+	struct device *dev = &client->dev;
+	dev_info(dev, "remove successful\n");
+	return 0;
+}
+
+static const struct i2c_device_id hdmiphy_id[] = {
+	{ "hdmiphy", 0 },
+	{ },
+};
+MODULE_DEVICE_TABLE(i2c, hdmiphy_id);
+
+static struct i2c_driver hdmiphy_driver = {
+	.driver = {
+		.name	= "s5p-hdmiphy",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= hdmiphy_probe,
+	.remove		= __devexit_p(hdmiphy_remove),
+	.id_table = hdmiphy_id,
+};
+
+static int hdmiphy_s_power(struct v4l2_subdev *sd, int on)
+{
+	return 0;
+}
+
+const u8 *hdmiphy_preset2conf(u32 preset)
+{
+	int i;
+	for (i = 0; hdmiphy_conf[i].preset != V4L2_DV_INVALID; ++i)
+		if (hdmiphy_conf[i].preset == preset)
+			return hdmiphy_conf[i].data;
+	return NULL;
+}
+
+static int hdmiphy_s_dv_preset(struct v4l2_subdev *sd,
+	struct v4l2_dv_preset *preset)
+{
+	const u8 *data;
+	u8 buffer[32];
+	int ret;
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct device *dev = &client->dev;
+	int x, y;
+
+	dev_info(dev, "s_dv_preset(preset = %d)\n", preset->preset);
+	data = hdmiphy_preset2conf(preset->preset);
+	if (!data) {
+		dev_err(dev, "format not supported\n");
+		return -ENXIO;
+	}
+
+	/* storing configuration to the device */
+	memcpy(buffer, data, 32);
+	for (y = 0; y < 4; ++y) {
+		char txt[64], *p = txt;
+		for (x = 0; x < 8; ++x)
+			p += sprintf(p, "0x%02x, ", buffer[8 * y + x]);
+		dev_info(dev, "[%02d-%02d] = %s\n", 8 * y, 8 * y + 7, txt);
+	}
+	ret = i2c_master_send(client, buffer, 32);
+	if (ret != 32) {
+		dev_err(dev, "failed to configure HDMIPHY via I2C\n");
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int hdmiphy_s_stream(struct v4l2_subdev *sd, int enable)
+{
+	struct i2c_client *client = v4l2_get_subdevdata(sd);
+	struct device *dev = &client->dev;
+	u8 buffer[2];
+	int ret;
+
+	dev_info(dev, "s_stream(%d)\n", enable);
+	/* going to/from configuration from/to operation mode */
+	buffer[0] = 0x1f;
+	if (enable)
+		buffer[1] = 0x80;
+	else
+		buffer[1] = 0x00;
+
+	ret = i2c_master_send(client, buffer, 2);
+	if (ret != 2) {
+		dev_err(dev, "stream (%d) failed\n", enable);
+		return -EIO;
+	}
+	return 0;
+}
+
+static const struct v4l2_subdev_core_ops hdmiphy_core_ops = {
+	.s_power =  hdmiphy_s_power,
+};
+
+static const struct v4l2_subdev_video_ops hdmiphy_video_ops = {
+	.s_dv_preset = hdmiphy_s_dv_preset,
+	.s_stream =  hdmiphy_s_stream,
+};
+
+static const struct v4l2_subdev_ops hdmiphy_ops = {
+	.core = &hdmiphy_core_ops,
+	.video = &hdmiphy_video_ops,
+};
+
+static const u8 hdmiphy_conf27[32] = {
+	0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
+	0x6B, 0x10, 0x02, 0x51, 0xDf, 0xF2, 0x54, 0x87,
+	0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
+	0x22, 0x40, 0xe3, 0x26, 0x00, 0x00, 0x00, 0x00,
+};
+
+static const u8 hdmiphy_conf74_175[32] = {
+	0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
+	0x6D, 0x10, 0x01, 0x51, 0xef, 0xF3, 0x54, 0xb9,
+	0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
+	0x22, 0x40, 0xa5, 0x26, 0x01, 0x00, 0x00, 0x00,
+};
+
+static const u8 hdmiphy_conf74_25[32] = {
+	0x01, 0x05, 0x00, 0xd8, 0x10, 0x9c, 0xf8, 0x40,
+	0x6a, 0x10, 0x01, 0x51, 0xff, 0xf1, 0x54, 0xba,
+	0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xe0,
+	0x22, 0x40, 0xa4, 0x26, 0x01, 0x00, 0x00, 0x00,
+};
+
+static const u8 hdmiphy_conf148_5[32] = {
+	0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xf8, 0x40,
+	0x6A, 0x18, 0x00, 0x51, 0xff, 0xF1, 0x54, 0xba,
+	0x84, 0x00, 0x10, 0x38, 0x00, 0x08, 0x10, 0xE0,
+	0x22, 0x40, 0xa4, 0x26, 0x02, 0x00, 0x00, 0x00,
+};
+
+static const u8 hdmiphy_conf148_35[32] = {
+	0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xef, 0x5B,
+	0x6D, 0x18, 0x00, 0x51, 0xef, 0xF3, 0x54, 0xb9,
+	0x84, 0x00, 0x30, 0x38, 0x00, 0x08, 0x10, 0xE0,
+	0x22, 0x40, 0xa5, 0x26, 0x02, 0x00, 0x00, 0x00,
+};
+
+static const struct hdmiphy_conf hdmiphy_conf[] = {
+	{ V4L2_DV_480P59_94, hdmiphy_conf27 },
+	{ V4L2_DV_1080P30, hdmiphy_conf74_175 },
+	{ V4L2_DV_720P59_94, hdmiphy_conf74_175 },
+	{ V4L2_DV_720P60, hdmiphy_conf74_25 },
+	{ V4L2_DV_1080P50, hdmiphy_conf148_5 },
+	{ V4L2_DV_1080P60, hdmiphy_conf148_5 },
+	{ V4L2_DV_1080P59_94, hdmiphy_conf148_35},
+	{ V4L2_DV_INVALID, NULL },
+};
+
+#if 0 /* original tables from EXYNOS4 manual */
+/* 27 MHz */
+0x01, 0x05, 0x00, 0xD8, 0x10, 0x1C, 0x30, 0x40,
+0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
+0x84, 0x00, 0x20, 0x38, 0x00, 0x08, 0x10, 0xE0,
+0x22, 0x40, 0xE3, 0x26, 0x00, 0x00, 0x00, 0x80
+
+/* 27.03 MHz */
+0x01, 0x05, 0x00, 0xD4, 0x10, 0x9C, 0x09, 0x64,
+0x6B, 0x10, 0x02, 0x51, 0xDF, 0xF2, 0x54, 0x87,
+0x84, 0x00, 0x20, 0x38, 0x00, 0x08, 0x10, 0xE0,
+0x22, 0x40, 0xE2, 0x26, 0x00, 0x00, 0x00, 0x80
+
+/* 74.18 */
+0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xEF, 0x5B,
+0x6D, 0x10, 0x01, 0x51, 0xEF, 0xF3, 0x54, 0xB9,
+0x84, 0x00, 0x20, 0x38, 0x00, 0x08, 0x10, 0xE0,
+0x22, 0x40, 0xA5, 0x26, 0x01, 0x00, 0x00, 0x80
+
+/* 74.24 */
+0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xF8, 0x40,
+0x6A, 0x10, 0x01, 0x51, 0xFF, 0xF1, 0x54, 0xBA,
+0x84, 0x00, 0x00, 0x38, 0x00, 0x08, 0x10, 0xE0,
+0x22, 0x40, 0xA4, 0x26, 0x01, 0x00, 0x00, 0x80
+
+/* 148.35 */
+0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xEF, 0x5B,
+0x6D, 0x18, 0x00, 0x51, 0xEF, 0xF3, 0x54, 0xB9,
+0x84, 0x00, 0x20, 0x38, 0x00, 0x08, 0x10, 0xE0,
+0x22, 0x40, 0xA5, 0x26, 0x02, 0x00, 0x00, 0x80
+
+/* 148.5 */
+0x01, 0x05, 0x00, 0xD8, 0x10, 0x9C, 0xF8, 0x40,
+0x6A, 0x18, 0x00, 0x51, 0xFF, 0xF1, 0x54, 0xBA,
+0x84, 0x00, 0x00, 0x38, 0x00, 0x08, 0x10, 0xE0,
+0x22, 0x40, 0xA4, 0x26, 0x02, 0x00, 0x00, 0x80,
+#endif
diff --git a/drivers/media/video/s5p-tv/mixer.h b/drivers/media/video/s5p-tv/mixer.h
new file mode 100644
index 0000000..f2a9aa6
--- /dev/null
+++ b/drivers/media/video/s5p-tv/mixer.h
@@ -0,0 +1,336 @@
+/*
+ * Samsung TV Mixer driver
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Tomasz Stanislawski, t.stanislaws@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundiation. either version 2 of the License,
+ * or (at your option) any later version
+ */
+
+#ifndef _SAMSUNG_MIXER_H_
+#define _SAMSUNG_MIXER_H_
+
+#include <linux/fb.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+#include <media/v4l2-device.h>
+#include <media/videobuf2-core.h>
+
+#include "regs-vmx.h"
+
+/** maximum number of output interfaces */
+#define MXR_MAX_OUTPUTS 2
+/** maximum number of input interfaces (layers) */
+#define MXR_MAX_LAYERS 3
+#define MXR_DRIVER_NAME "s5p-mixer"
+/** maximal number of planes for every layer */
+#define MXR_MAX_PLANES	2
+
+#define MXR_ENABLE 1
+#define MXR_DISABLE 0
+
+/** description of a macroblock for packed formats */
+struct mxr_block {
+	/** vertical number of pixels in macroblock */
+	unsigned int pxWidth:8;
+	/** horizontal number of pixels in macroblock */
+	unsigned int pxHeight:8;
+	/** size of block in bytes */
+	unsigned int bSize:16;
+};
+
+/** description of supported format */
+struct mxr_format {
+	/** format name/mnemonic */
+	char *name;
+	/** fourcc identifier */
+	u32 fourcc;
+	/** number of planes in image data */
+	int num_planes;
+	/** description of block for each plane */
+	struct mxr_block plane[MXR_MAX_PLANES];
+	/** number of subframes in image data */
+	int num_subframes;
+	/** specifies to which subframe belong given plane */
+	int plane2subframe[MXR_MAX_PLANES];
+	/** internal code, driver dependant */
+	unsigned long hwCode;
+};
+
+/** description of crop configuration for image */
+struct mxr_crop {
+	/** width of layer in pixels */
+	unsigned int full_width;
+	/** height of layer in pixels */
+	unsigned int full_height;
+	/** horizontal offset of first pixel to be displayed */
+	unsigned int x_offset;
+	/** vertical offset of first pixel to be displayed */
+	unsigned int y_offset;
+	/** width of displayed data in pixels */
+	unsigned int width;
+	/** height of displayed data in pixels */
+	unsigned int height;
+	/** indicate which fields are present in buffer */
+	unsigned int field;
+};
+
+/** description of transformation from source to destination image */
+struct mxr_geometry {
+	/** cropping for source image */
+	struct mxr_crop src;
+	/** cropping for destination image */
+	struct mxr_crop dst;
+	/** layer-dependant description of horizontal scaling */
+	unsigned int x_ratio;
+	/** layer-dependant description of vertical scaling */
+	unsigned int y_ratio;
+};
+
+/** instance of a buffer */
+struct mxr_buffer {
+	/** common v4l buffer stuff -- must be first */
+	struct vb2_buffer	vb;
+	/** node for layer's lists */
+	struct list_head	list;
+};
+
+
+/** internal states of layer */
+enum mxr_layer_state {
+	/** layers is not shown */
+	MXR_LAYER_IDLE = 0,
+	/** state between STREAMON and hardware start */
+	MXR_LAYER_STREAMING_START,
+	/** layer is shown */
+	MXR_LAYER_STREAMING,
+	/** state before STREAMOFF is finished */
+	MXR_LAYER_STREAMING_FINISH,
+};
+
+/** forward declarations */
+struct mxr_device;
+struct mxr_layer;
+
+/** callback for layers operation */
+struct mxr_layer_ops {
+	/* TODO: try to port it to subdev API */
+	/** handler for resource release function */
+	void (*release)(struct mxr_layer *);
+	/** setting buffer to HW */
+	void (*buffer_set)(struct mxr_layer *, struct mxr_buffer *);
+	/** setting format and geometry in HW */
+	void (*format_set)(struct mxr_layer *);
+	/** streaming stop/start */
+	void (*stream_set)(struct mxr_layer *, int);
+	/** adjusting geometry */
+	void (*fix_geometry)(struct mxr_layer *);
+};
+
+/** layer instance, a single window and content displayed on output */
+struct mxr_layer {
+	/** parent mixer device */
+	struct mxr_device *mdev;
+	/** layer index (unique identifier) */
+	int idx;
+	/** callbacks for layer methods */
+	struct mxr_layer_ops ops;
+	/** format array */
+	const struct mxr_format **fmt_array;
+	/** size of format array */
+	unsigned long fmt_array_size;
+
+	/** lock for protection of list and state fields */
+	spinlock_t enq_slock;
+	/** list for enqueued buffers */
+	struct list_head enq_list;
+	/** buffer currently owned by hardware in temporary registers */
+	struct mxr_buffer *update_buf;
+	/** buffer currently owned by hardware in shadow registers */
+	struct mxr_buffer *shadow_buf;
+	/** state of layer IDLE/STREAMING */
+	enum mxr_layer_state state;
+
+	/** mutex for protection of fields below */
+	struct mutex mutex;
+	/** use count */
+	int n_user;
+	/** handler for video node */
+	struct video_device vfd;
+	/** queue for output buffers */
+	struct vb2_queue vb_queue;
+	/** current image format */
+	const struct mxr_format *fmt;
+	/** current geometry of image */
+	struct mxr_geometry geo;
+};
+
+/** description of mixers output interface */
+struct mxr_output {
+	/** name of output */
+	char name[32];
+	/** output subdev */
+	struct v4l2_subdev *sd;
+	/** cookie used for configuration of registers */
+	int cookie;
+};
+
+/** specify source of output subdevs */
+struct mxr_output_conf {
+	/** name of output (connector) */
+	char *output_name;
+	/** name of module that generates output subdev */
+	char *module_name;
+	/** cookie need for mixer HW */
+	int cookie;
+};
+
+struct clk;
+struct regulator;
+
+/** auxiliary resources used my mixer */
+struct mxr_resources {
+	/** interrupt index */
+	int irq;
+	/** pointer to Mixer registers */
+	void __iomem *mxr_regs;
+	/** pointer to Video Processor registers */
+	void __iomem *vp_regs;
+	/** other resources, should used under mxr_device.mutex */
+	struct clk *mixer;
+	struct clk *vp;
+	struct clk *sclk_mixer;
+	struct clk *sclk_hdmi;
+	struct clk *sclk_dac;
+};
+
+/*s event flags used  */
+enum mxr_devide_flags {
+	MXR_EVENT_VSYNC = 0,
+};
+
+/** drivers instance */
+struct mxr_device {
+	/** master device */
+	struct device *dev;
+	/** state of each layer */
+	struct mxr_layer *layer[MXR_MAX_LAYERS];
+	/** state of each output */
+	struct mxr_output *output[MXR_MAX_OUTPUTS];
+	/** number of registered outputs */
+	int output_cnt;
+
+	/* video resources */
+
+	/** V4L2 device */
+	struct v4l2_device v4l2_dev;
+	/** context of allocator */
+	void *alloc_ctx;
+	/** event wait queue */
+	wait_queue_head_t event_queue;
+	/** state flags */
+	unsigned long event_flags;
+
+	/** spinlock for protection of registers */
+	spinlock_t reg_slock;
+
+	/** mutex for protection of fields below */
+	struct mutex mutex;
+	/** number of entities depndant on output configuration */
+	int n_output;
+	/** number of users that do streaming */
+	int n_streamer;
+	/** index of current output */
+	int current_output;
+	/** auxiliary resources used my mixer */
+	struct mxr_resources res;
+};
+
+/** transform device structure into mixer device */
+static inline struct mxr_device *to_mdev(struct device *dev)
+{
+	struct v4l2_device *vdev = dev_get_drvdata(dev);
+	return container_of(vdev, struct mxr_device, v4l2_dev);
+}
+
+/** get current output data, should be called under mdev's mutex */
+static inline struct mxr_output *to_output(struct mxr_device *mdev)
+{
+	return mdev->output[mdev->current_output];
+}
+
+/** get current output subdev, should be called under mdev's mutex */
+static inline struct v4l2_subdev *to_outsd(struct mxr_device *mdev)
+{
+	struct mxr_output *out = to_output(mdev);
+	return out ? out->sd : NULL;
+}
+
+/** forward declaration for mixer platform data */
+struct mxr_platform_data;
+
+/** acquiring common video resources */
+int __devinit mxr_acquire_video(struct mxr_device *mdev,
+	struct mxr_output_conf *output_cont, int output_count);
+
+/** releasing common video resources */
+void __devexit mxr_release_video(struct mxr_device *mdev);
+
+struct mxr_layer *mxr_graph_layer_create(struct mxr_device *mdev, int idx);
+struct mxr_layer *mxr_vp_layer_create(struct mxr_device *mdev, int idx);
+struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev,
+	int idx, char *name, struct mxr_layer_ops *ops);
+
+void mxr_base_layer_release(struct mxr_layer *layer);
+void mxr_layer_release(struct mxr_layer *layer);
+
+int mxr_base_layer_register(struct mxr_layer *layer);
+void mxr_base_layer_unregister(struct mxr_layer *layer);
+
+unsigned long mxr_get_plane_size(const struct mxr_block *blk,
+	unsigned int width, unsigned int height);
+
+/** adds new consumer for mixer's power */
+int __must_check mxr_power_get(struct mxr_device *mdev);
+/** removes consumer for mixer's power */
+void mxr_power_put(struct mxr_device *mdev);
+/** add new client for output configuration */
+void mxr_output_get(struct mxr_device *mdev);
+/** removes new client for output configuration */
+void mxr_output_put(struct mxr_device *mdev);
+/** add new client for streaming */
+void mxr_streamer_get(struct mxr_device *mdev);
+/** removes new client for streaming */
+void mxr_streamer_put(struct mxr_device *mdev);
+/** returns format of data delivared to current output */
+void mxr_get_mbus_fmt(struct mxr_device *mdev,
+	struct v4l2_mbus_framefmt *mbus_fmt);
+
+/* Debug */
+
+#define MXR_CHECK printk(KERN_ERR "%s:%d\n", __func__, __LINE__)
+
+#define mxr_printk(mdev, level, fmt, ...)				\
+do {									\
+	extern int mxr_log_level;					\
+	(void) (mdev == (struct mxr_device *)NULL); /* type check */	\
+	if (level <= CONFIG_VIDEO_SAMSUNG_S5P_MIXER_LOG_LEVEL		\
+		&& level <= mxr_log_level) {				\
+		char prefix[4] = "<*>";					\
+		prefix[1] = '0' + level;				\
+		dev_printk(prefix, mdev->dev, fmt, ##__VA_ARGS__);	\
+	}								\
+} while (0)
+
+#define mxr_err(mdev, fmt, ...)  mxr_printk(mdev, 3, fmt, ##__VA_ARGS__)
+#define mxr_warn(mdev, fmt, ...) mxr_printk(mdev, 4, fmt, ##__VA_ARGS__)
+#define mxr_info(mdev, fmt, ...) mxr_printk(mdev, 6, fmt, ##__VA_ARGS__)
+#define mxr_dbg(mdev, fmt, ...)  mxr_printk(mdev, 7, fmt, ##__VA_ARGS__)
+
+#endif /* _SAMSUNG_MIXER_H_ */
+
diff --git a/drivers/media/video/s5p-tv/mixer_drv.c b/drivers/media/video/s5p-tv/mixer_drv.c
new file mode 100644
index 0000000..03bcc2c
--- /dev/null
+++ b/drivers/media/video/s5p-tv/mixer_drv.c
@@ -0,0 +1,488 @@
+/*
+ * Samsung TV Mixer driver
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Tomasz Stanislawski, t.stanislaws@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundiation. either version 2 of the License,
+ * or (at your option) any later version
+ */
+
+#include "mixer.h"
+#include "mixer_reg.h"
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/fb.h>
+#include <linux/delay.h>
+#include <linux/pm_runtime.h>
+#include <linux/clk.h>
+
+MODULE_AUTHOR("Tomasz Stanislawski, t.stanislaws@samsung.com");
+MODULE_DESCRIPTION("Samsung MIXER");
+MODULE_LICENSE("GPL");
+
+/* --------- DRIVER PARAMETERS ---------- */
+
+int mxr_log_level = 6;
+module_param_named(debug, mxr_log_level, int, S_IRUGO | S_IWUSR);
+
+static struct mxr_output_conf mxr_output_conf[] = {
+	{
+		.output_name = "S5P HDMI connector",
+		.module_name = "s5p-hdmi",
+		.cookie = 1,
+	},
+	{
+		.output_name = "S5P SDO connector",
+		.module_name = "s5p-sdo",
+		.cookie = 0,
+	},
+};
+
+/* --------- DRIVER INITIALIZATION ---------- */
+
+static struct platform_driver mxr_driver __refdata;
+
+static int __init mxr_init(void)
+{
+	int i, ret;
+	static const char banner[] __initdata = KERN_INFO
+		"Samsung TV Mixer driver, (c) 2010 Samsung Electronics\n";
+	printk(banner);
+
+	/* Loading auxiliary modules */
+	for (i = 0; i < ARRAY_SIZE(mxr_output_conf); ++i)
+		request_module(mxr_output_conf[i].module_name);
+
+	ret = platform_driver_register(&mxr_driver);
+	if (ret != 0) {
+		printk(KERN_ERR "registration of MIXER driver failed\n");
+		return -ENXIO;
+	}
+
+	return 0;
+}
+module_init(mxr_init);
+
+static void __exit mxr_exit(void)
+{
+	platform_driver_unregister(&mxr_driver);
+}
+module_exit(mxr_exit);
+
+static int __devinit mxr_acquire_resources(struct mxr_device *mdev,
+	struct platform_device *pdev);
+
+static void mxr_release_resources(struct mxr_device *mdev);
+
+static int __devinit mxr_acquire_layers(struct mxr_device *mdev,
+	struct mxr_platform_data *pdata);
+
+static void mxr_release_layers(struct mxr_device *mxr_dev);
+
+static int __devinit mxr_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mxr_platform_data *pdata = dev->platform_data;
+	struct mxr_device *mdev;
+	int ret;
+
+	/* mdev does not exist yet so no mxr_dbg is used */
+	dev_info(dev, "probe start\n");
+
+	mdev = kzalloc(sizeof *mdev, GFP_KERNEL);
+	if (!mdev) {
+		mxr_err(mdev, "not enough memory.\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	/* setup pointer to master device */
+	mdev->dev = dev;
+
+	mutex_init(&mdev->mutex);
+	spin_lock_init(&mdev->reg_slock);
+	init_waitqueue_head(&mdev->event_queue);
+
+	/* acquire resources: regs, irqs, clocks, regulators */
+	ret = mxr_acquire_resources(mdev, pdev);
+	if (ret)
+		goto fail_mem;
+
+	/* configure resources for video output */
+	ret = mxr_acquire_video(mdev, mxr_output_conf,
+		ARRAY_SIZE(mxr_output_conf));
+	if (ret)
+		goto fail_resources;
+
+	/* configure layers */
+	ret = mxr_acquire_layers(mdev, pdata);
+	if (ret)
+		goto fail_video;
+
+	pm_runtime_enable(dev);
+
+	mxr_info(mdev, "probe successful\n");
+	return 0;
+
+fail_video:
+	mxr_release_video(mdev);
+
+fail_resources:
+	mxr_release_resources(mdev);
+
+fail_mem:
+	kfree(mdev);
+
+fail:
+	dev_info(dev, "probe failed\n");
+	return ret;
+}
+
+static int __devexit mxr_remove(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mxr_device *mdev = to_mdev(dev);
+
+	pm_runtime_disable(dev);
+
+	mxr_release_layers(mdev);
+	mxr_release_video(mdev);
+	mxr_release_resources(mdev);
+
+	kfree(mdev);
+
+	dev_info(dev, "remove sucessful\n");
+	return 0;
+}
+
+static int mxr_runtime_resume(struct device *dev)
+{
+	struct mxr_device *mdev = to_mdev(dev);
+	struct mxr_resources *res = &mdev->res;
+
+	mxr_dbg(mdev, "resume - start\n");
+	mutex_lock(&mdev->mutex);
+	/* turn clocks on */
+	clk_enable(res->mixer);
+	clk_enable(res->vp);
+	clk_enable(res->sclk_mixer);
+	/* apply default configuration */
+	mxr_reg_reset(mdev);
+	mxr_dbg(mdev, "resume - finished\n");
+
+	mutex_unlock(&mdev->mutex);
+	return 0;
+}
+
+static int mxr_runtime_suspend(struct device *dev)
+{
+	struct mxr_device *mdev = to_mdev(dev);
+	struct mxr_resources *res = &mdev->res;
+	mxr_dbg(mdev, "suspend - start\n");
+	mutex_lock(&mdev->mutex);
+	/* turn clocks off */
+	clk_disable(res->sclk_mixer);
+	clk_disable(res->vp);
+	clk_disable(res->mixer);
+	mutex_unlock(&mdev->mutex);
+	mxr_dbg(mdev, "suspend - finished\n");
+	return 0;
+}
+
+static const struct dev_pm_ops mxr_pm_ops = {
+	.runtime_suspend = mxr_runtime_suspend,
+	.runtime_resume	 = mxr_runtime_resume,
+};
+
+static struct platform_driver mxr_driver __refdata = {
+	.probe = mxr_probe,
+	.remove = __devexit_p(mxr_remove),
+	.driver = {
+		.name = MXR_DRIVER_NAME,
+		.owner = THIS_MODULE,
+		.pm = &mxr_pm_ops,
+	}
+};
+
+static int __devinit mxr_acquire_plat_resources(struct mxr_device *mdev,
+	struct platform_device *pdev)
+{
+	struct resource *res;
+	int ret;
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mxr");
+	if (res == NULL) {
+		mxr_err(mdev, "get memory resource failed.\n");
+		ret = -ENXIO;
+		goto fail;
+	}
+
+	mdev->res.mxr_regs = ioremap(res->start, resource_size(res));
+	if (mdev->res.mxr_regs == NULL) {
+		mxr_err(mdev, "register mapping failed.\n");
+		ret = -ENXIO;
+		goto fail;
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "vp");
+	if (res == NULL) {
+		mxr_err(mdev, "get memory resource failed.\n");
+		ret = -ENXIO;
+		goto fail_mxr_regs;
+	}
+
+	mdev->res.vp_regs = ioremap(res->start, resource_size(res));
+	if (mdev->res.vp_regs == NULL) {
+		mxr_err(mdev, "register mapping failed.\n");
+		ret = -ENXIO;
+		goto fail_mxr_regs;
+	}
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "irq");
+	if (res == NULL) {
+		mxr_err(mdev, "get interrupt resource failed.\n");
+		ret = -ENXIO;
+		goto fail_vp_regs;
+	}
+
+	ret = request_irq(res->start, mxr_irq_handler, 0, "s5p-mixer", mdev);
+	if (ret) {
+		mxr_err(mdev, "request interrupt failed.\n");
+		goto fail_vp_regs;
+	}
+	mdev->res.irq = res->start;
+
+	return 0;
+
+fail_vp_regs:
+	iounmap(mdev->res.vp_regs);
+
+fail_mxr_regs:
+	iounmap(mdev->res.mxr_regs);
+
+fail:
+	return ret;
+}
+
+static void mxr_release_plat_resources(struct mxr_device *mdev)
+{
+	free_irq(mdev->res.irq, mdev);
+	iounmap(mdev->res.vp_regs);
+	iounmap(mdev->res.mxr_regs);
+}
+
+static void mxr_release_clocks(struct mxr_device *mdev)
+{
+	struct mxr_resources *res = &mdev->res;
+
+	if (!IS_ERR_OR_NULL(res->sclk_dac))
+		clk_put(res->sclk_dac);
+	if (!IS_ERR_OR_NULL(res->sclk_hdmi))
+		clk_put(res->sclk_hdmi);
+	if (!IS_ERR_OR_NULL(res->sclk_mixer))
+		clk_put(res->sclk_mixer);
+	if (!IS_ERR_OR_NULL(res->vp))
+		clk_put(res->vp);
+	if (!IS_ERR_OR_NULL(res->mixer))
+		clk_put(res->mixer);
+}
+
+static int mxr_acquire_clocks(struct mxr_device *mdev)
+{
+	struct mxr_resources *res = &mdev->res;
+	struct device *dev = mdev->dev;
+
+	res->mixer = clk_get(dev, "mixer");
+	if (IS_ERR_OR_NULL(res->mixer)) {
+		mxr_err(mdev, "failed to get clock 'mixer'\n");
+		goto fail;
+	}
+	res->vp = clk_get(dev, "vp");
+	if (IS_ERR_OR_NULL(res->vp)) {
+		mxr_err(mdev, "failed to get clock 'vp'\n");
+		goto fail;
+	}
+	res->sclk_mixer = clk_get(dev, "sclk_mixer");
+	if (IS_ERR_OR_NULL(res->sclk_mixer)) {
+		mxr_err(mdev, "failed to get clock 'sclk_mixer'\n");
+		goto fail;
+	}
+	res->sclk_hdmi = clk_get(dev, "sclk_hdmi");
+	if (IS_ERR_OR_NULL(res->sclk_hdmi)) {
+		mxr_err(mdev, "failed to get clock 'sclk_hdmi'\n");
+		goto fail;
+	}
+	res->sclk_dac = clk_get(dev, "sclk_dac");
+	if (IS_ERR_OR_NULL(res->sclk_dac)) {
+		mxr_err(mdev, "failed to get clock 'sclk_dac'\n");
+		goto fail;
+	}
+
+	return 0;
+fail:
+	mxr_release_clocks(mdev);
+	return -ENODEV;
+}
+
+static int __devinit mxr_acquire_resources(struct mxr_device *mdev,
+	struct platform_device *pdev)
+{
+	int ret;
+	ret = mxr_acquire_plat_resources(mdev, pdev);
+	if (ret)
+		goto fail;
+
+	ret = mxr_acquire_clocks(mdev);
+	if (ret)
+		goto fail_plat;
+
+	mxr_info(mdev, "resources acquired\n");
+	return 0;
+
+fail_plat:
+	mxr_release_plat_resources(mdev);
+fail:
+	mxr_err(mdev, "resources acquire failed\n");
+	return ret;
+}
+
+static void mxr_release_resources(struct mxr_device *mdev)
+{
+	mxr_release_clocks(mdev);
+	mxr_release_plat_resources(mdev);
+	memset(&mdev->res, 0, sizeof mdev->res);
+}
+
+static int __devinit mxr_acquire_layers(struct mxr_device *mdev,
+	struct mxr_platform_data *pdata)
+{
+	mdev->layer[0] = mxr_graph_layer_create(mdev, 0);
+	mdev->layer[1] = mxr_graph_layer_create(mdev, 1);
+	mdev->layer[2] = mxr_vp_layer_create(mdev, 0);
+
+	if (!mdev->layer[0] || !mdev->layer[1] || !mdev->layer[2]) {
+		mxr_err(mdev, "failed to acquire layers\n");
+		goto fail;
+	}
+
+	return 0;
+
+fail:
+	mxr_release_layers(mdev);
+	return -ENODEV;
+}
+
+static void mxr_release_layers(struct mxr_device *mdev)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(mdev->layer); ++i)
+		if (mdev->layer[i])
+			mxr_layer_release(mdev->layer[i]);
+}
+
+int mxr_power_get(struct mxr_device *mdev)
+{
+	int ret = pm_runtime_get_sync(mdev->dev);
+	/* returning 1 means that power is already enabled,
+	 * so zero success be returned */
+	if (IS_ERR_VALUE(ret))
+		return ret;
+	return 0;
+}
+
+void mxr_power_put(struct mxr_device *mdev)
+{
+	pm_runtime_put_sync(mdev->dev);
+}
+
+void mxr_get_mbus_fmt(struct mxr_device *mdev,
+	struct v4l2_mbus_framefmt *mbus_fmt)
+{
+	struct v4l2_subdev *sd;
+	int ret;
+	mutex_lock(&mdev->mutex);
+	sd = to_outsd(mdev);
+	ret = v4l2_subdev_call(sd, video, g_mbus_fmt, mbus_fmt);
+	WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name);
+	mutex_unlock(&mdev->mutex);
+}
+
+void mxr_streamer_get(struct mxr_device *mdev)
+{
+	mutex_lock(&mdev->mutex);
+	++mdev->n_streamer;
+	mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer);
+	if (mdev->n_streamer == 1) {
+		struct v4l2_subdev *sd = to_outsd(mdev);
+		struct v4l2_mbus_framefmt mbus_fmt;
+		struct mxr_resources *res = &mdev->res;
+		int ret;
+		ret = v4l2_subdev_call(sd, video, g_mbus_fmt, &mbus_fmt);
+		WARN(ret, "failed to get mbus_fmt for output %s\n", sd->name);
+		mxr_reg_set_mbus_fmt(mdev, &mbus_fmt);
+		mxr_reg_s_output(mdev, to_output(mdev)->cookie);
+		if (to_output(mdev)->cookie == 0)
+			clk_set_parent(res->sclk_mixer, res->sclk_dac);
+		else
+			clk_set_parent(res->sclk_mixer, res->sclk_hdmi);
+		mxr_reg_streamon(mdev);
+		ret = v4l2_subdev_call(sd, video, s_stream, 1);
+		WARN(ret, "starting stream failed for output %s\n", sd->name);
+	}
+	mutex_unlock(&mdev->mutex);
+	mxr_reg_dump(mdev);
+	/* FIXME: what to do when streaming fails? */
+}
+
+void mxr_streamer_put(struct mxr_device *mdev)
+{
+	mutex_lock(&mdev->mutex);
+	--mdev->n_streamer;
+	mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_streamer);
+	if (mdev->n_streamer == 0) {
+		int ret;
+		struct v4l2_subdev *sd = to_outsd(mdev);
+		mxr_reg_streamoff(mdev);
+		/* vsync applies Mixer setup */
+		ret = mxr_reg_wait4vsync(mdev);
+		WARN(ret, "failed to get vsync (%d) from output\n", ret);
+		ret = v4l2_subdev_call(sd, video, s_stream, 0);
+		WARN(ret, "stopping stream failed for output %s\n", sd->name);
+	}
+	WARN(mdev->n_streamer < 0, "negative number of streamers (%d)\n",
+		mdev->n_streamer);
+	mutex_unlock(&mdev->mutex);
+	mxr_reg_dump(mdev);
+}
+
+void mxr_output_get(struct mxr_device *mdev)
+{
+	mutex_lock(&mdev->mutex);
+	++mdev->n_output;
+	mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_output);
+	/* turn on auxliary driver */
+	if (mdev->n_output == 1)
+		v4l2_subdev_call(to_outsd(mdev), core, s_power, 1);
+	mutex_unlock(&mdev->mutex);
+}
+
+void mxr_output_put(struct mxr_device *mdev)
+{
+	mutex_lock(&mdev->mutex);
+	--mdev->n_output;
+	mxr_dbg(mdev, "%s(%d)\n", __func__, mdev->n_output);
+	/* turn on auxliary driver */
+	if (mdev->n_output == 0)
+		v4l2_subdev_call(to_outsd(mdev), core, s_power, 0);
+	WARN(mdev->n_output < 0, "negative number of output users (%d)\n",
+		mdev->n_output);
+	mutex_unlock(&mdev->mutex);
+}
+
diff --git a/drivers/media/video/s5p-tv/mixer_grp_layer.c b/drivers/media/video/s5p-tv/mixer_grp_layer.c
new file mode 100644
index 0000000..cbb9b6b
--- /dev/null
+++ b/drivers/media/video/s5p-tv/mixer_grp_layer.c
@@ -0,0 +1,180 @@
+/*
+ * Samsung TV Mixer driver
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Tomasz Stanislawski, t.stanislaws@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundiation. either version 2 of the License,
+ * or (at your option) any later version
+ */
+
+#include "mixer.h"
+#include "mixer_reg.h"
+
+#include <media/videobuf2-dma-contig.h>
+
+/* FORMAT DEFINITIONS */
+
+static const struct mxr_format mxr_fb_fmt_rgb565 = {
+	.name = "RGB565",
+	.fourcc = V4L2_PIX_FMT_RGB565,
+	.num_planes = 1,
+	.plane = {
+		{ .pxWidth = 1, .pxHeight = 1, .bSize = 2 },
+	},
+	.num_subframes = 1,
+	.hwCode = 4,
+};
+
+static const struct mxr_format mxr_fb_fmt_argb1555 = {
+	.name = "ARGB1555",
+	.num_planes = 1,
+	.fourcc = V4L2_PIX_FMT_RGB555,
+	.plane = {
+		{ .pxWidth = 1, .pxHeight = 1, .bSize = 2 },
+	},
+	.num_subframes = 1,
+	.hwCode = 5,
+};
+
+static const struct mxr_format mxr_fb_fmt_argb4444 = {
+	.name = "ARGB4444",
+	.num_planes = 1,
+	.fourcc = V4L2_PIX_FMT_RGB444,
+	.plane = {
+		{ .pxWidth = 1, .pxHeight = 1, .bSize = 2 },
+	},
+	.num_subframes = 1,
+	.hwCode = 6,
+};
+
+static const struct mxr_format mxr_fb_fmt_argb8888 = {
+	.name = "ARGB8888",
+	.fourcc = V4L2_PIX_FMT_BGR32,
+	.num_planes = 1,
+	.plane = {
+		{ .pxWidth = 1, .pxHeight = 1, .bSize = 4 },
+	},
+	.num_subframes = 1,
+	.hwCode = 7,
+};
+
+static const struct mxr_format *mxr_graph_format[] = {
+	&mxr_fb_fmt_rgb565,
+	&mxr_fb_fmt_argb1555,
+	&mxr_fb_fmt_argb4444,
+	&mxr_fb_fmt_argb8888,
+};
+
+/* AUXILIARY CALLBACKS */
+
+static void mxr_graph_layer_release(struct mxr_layer *layer)
+{
+	mxr_base_layer_unregister(layer);
+	mxr_base_layer_release(layer);
+}
+
+static void mxr_graph_buffer_set(struct mxr_layer *layer,
+	struct mxr_buffer *buf)
+{
+	dma_addr_t addr = 0;
+	if (buf)
+		addr = vb2_dma_contig_plane_paddr(&buf->vb, 0);
+	mxr_reg_graph_buffer(layer->mdev, layer->idx, addr);
+}
+
+static void mxr_graph_stream_set(struct mxr_layer *layer, int en)
+{
+	mxr_reg_graph_layer_stream(layer->mdev, layer->idx, en);
+}
+
+static void mxr_graph_format_set(struct mxr_layer *layer)
+{
+	mxr_reg_graph_format(layer->mdev, layer->idx,
+		layer->fmt, &layer->geo);
+}
+
+static void mxr_graph_fix_geometry(struct mxr_layer *layer)
+{
+	struct mxr_geometry *geo = &layer->geo;
+	/* limit to boundary size */
+	geo->src.full_width = clamp_val(geo->src.full_width, 1, 32767);
+	geo->src.full_height = clamp_val(geo->src.full_height, 1, 2047);
+	geo->src.width = clamp_val(geo->src.width, 1, geo->src.full_width);
+	geo->src.width = min(geo->src.width, 2047U);
+	/* not possible to crop of Y axis */
+	geo->src.y_offset = min(geo->src.y_offset, geo->src.full_height - 1);
+	geo->src.height = geo->src.full_height - geo->src.y_offset;
+	/* limitting offset */
+	geo->src.x_offset = min(geo->src.x_offset,
+		geo->src.full_width - geo->src.width);
+
+	/* setting position in output */
+	geo->dst.width = min(geo->dst.width, geo->dst.full_width);
+	geo->dst.height = min(geo->dst.height, geo->dst.full_height);
+
+	/* Mixer supports only 1x and 2x scaling */
+	if (geo->dst.width >= 2 * geo->src.width) {
+		geo->x_ratio = 1;
+		geo->dst.width = 2 * geo->src.width;
+	} else {
+		geo->x_ratio = 0;
+		geo->dst.width = geo->src.width;
+	}
+
+	if (geo->dst.height >= 2 * geo->src.height) {
+		geo->y_ratio = 1;
+		geo->dst.height = 2 * geo->src.height;
+	} else {
+		geo->y_ratio = 0;
+		geo->dst.height = geo->src.height;
+	}
+
+	geo->dst.x_offset = min(geo->dst.x_offset,
+		geo->dst.full_width - geo->dst.width);
+	geo->dst.y_offset = min(geo->dst.y_offset,
+		geo->dst.full_height - geo->dst.height);
+}
+
+/* PUBLIC API */
+
+struct mxr_layer *mxr_graph_layer_create(struct mxr_device *mdev, int idx)
+{
+	struct mxr_layer *layer;
+	int ret;
+	struct mxr_layer_ops ops = {
+		.release = mxr_graph_layer_release,
+		.buffer_set = mxr_graph_buffer_set,
+		.stream_set = mxr_graph_stream_set,
+		.format_set = mxr_graph_format_set,
+		.fix_geometry = mxr_graph_fix_geometry,
+	};
+	char name[32];
+
+	sprintf(name, "graph%d", idx);
+
+	layer = mxr_base_layer_create(mdev, idx, name, &ops);
+	if (layer == NULL) {
+		mxr_err(mdev, "failed to initialize layer(%d) base\n", idx);
+		goto fail;
+	}
+
+	layer->fmt_array = mxr_graph_format;
+	layer->fmt_array_size = ARRAY_SIZE(mxr_graph_format);
+
+	ret = mxr_base_layer_register(layer);
+	if (ret)
+		goto fail_layer;
+
+	return layer;
+
+fail_layer:
+	mxr_base_layer_release(layer);
+
+fail:
+	return NULL;
+}
+
diff --git a/drivers/media/video/s5p-tv/mixer_reg.c b/drivers/media/video/s5p-tv/mixer_reg.c
new file mode 100644
index 0000000..33a333f
--- /dev/null
+++ b/drivers/media/video/s5p-tv/mixer_reg.c
@@ -0,0 +1,566 @@
+/*
+ * Samsung TV Mixer driver
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Tomasz Stanislawski, t.stanislaws@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundiation. either version 2 of the License,
+ * or (at your option) any later version
+ */
+
+#include "mixer_reg.h"
+#include "regs-vmx.h"
+#include "regs-vp.h"
+
+#include <linux/delay.h>
+
+/* Register access subroutines */
+
+static inline u32 vp_read(struct mxr_device *mdev, u32 reg_id)
+{
+	return readl(mdev->res.vp_regs + reg_id);
+}
+
+static inline void vp_write(struct mxr_device *mdev, u32 reg_id, u32 val)
+{
+	writel(val, mdev->res.vp_regs + reg_id);
+}
+
+static inline void vp_write_mask(struct mxr_device *mdev, u32 reg_id,
+	u32 val, u32 mask)
+{
+	u32 old = vp_read(mdev, reg_id);
+	val = (val & mask) | (old & ~mask);
+	writel(val, mdev->res.vp_regs + reg_id);
+}
+
+static inline u32 mxr_read(struct mxr_device *mdev, u32 reg_id)
+{
+	return readl(mdev->res.mxr_regs + reg_id);
+}
+
+static inline void mxr_write(struct mxr_device *mdev, u32 reg_id, u32 val)
+{
+	writel(val, mdev->res.mxr_regs + reg_id);
+}
+
+static inline void mxr_write_mask(struct mxr_device *mdev, u32 reg_id,
+	u32 val, u32 mask)
+{
+	u32 old = mxr_read(mdev, reg_id);
+	val = (val & mask) | (old & ~mask);
+	writel(val, mdev->res.mxr_regs + reg_id);
+}
+
+void mxr_vsync_set_update(struct mxr_device *mdev, int en)
+{
+	/* block update on vsync */
+	mxr_write_mask(mdev, MXR_STATUS, en ? MXR_STATUS_SYNC_ENABLE : 0,
+		MXR_STATUS_SYNC_ENABLE);
+	vp_write(mdev, VP_SHADOW_UPDATE, en ? VP_SHADOW_UPDATE_ENABLE : 0);
+}
+
+static void __mxr_reg_vp_reset(struct mxr_device *mdev)
+{
+	int tries = 100;
+	vp_write(mdev, VP_SRESET, VP_SRESET_PROCESSING);
+	for (tries = 100; tries; --tries) {
+		/* waiting until VP_SRESET_PROCESSING is 0 */
+		if (~vp_read(mdev, VP_SRESET) & VP_SRESET_PROCESSING)
+			break;
+		mdelay(10);
+	}
+	WARN(tries == 0, "failed to reset Video Processor\n");
+}
+
+static void mxr_reg_vp_default_filter(struct mxr_device *mdev);
+
+void mxr_reg_reset(struct mxr_device *mdev)
+{
+	unsigned long flags;
+	u32 val; /* value stored to register */
+
+	spin_lock_irqsave(&mdev->reg_slock, flags);
+	mxr_vsync_set_update(mdev, MXR_DISABLE);
+
+	/* set output in RGB888 mode */
+	mxr_write(mdev, MXR_CFG, MXR_CFG_OUT_YUV444);
+
+	/* 16 beat burst in DMA */
+	mxr_write_mask(mdev, MXR_STATUS, MXR_STATUS_16_BURST,
+		MXR_STATUS_BURST_MASK);
+
+	/* setting default layer priority: layer1 > video > layer0
+	 * because typical usage scenario would be
+	 * layer0 - framebuffer
+	 * video - video overlay
+	 * layer1 - OSD
+	 */
+	val  = MXR_LAYER_CFG_GRP0_VAL(1);
+	val |= MXR_LAYER_CFG_VP_VAL(2);
+	val |= MXR_LAYER_CFG_GRP1_VAL(3);
+	mxr_write(mdev, MXR_LAYER_CFG, val);
+
+	/* use dark gray background color */
+	mxr_write(mdev, MXR_BG_COLOR0, 0x808080);
+	mxr_write(mdev, MXR_BG_COLOR1, 0x808080);
+	mxr_write(mdev, MXR_BG_COLOR2, 0x808080);
+
+	/* setting graphical layers */
+
+	val  = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
+	val |= MXR_GRP_CFG_BLEND_PRE_MUL; /* premul mode */
+	val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */
+
+	/* the same configuration for both layers */
+	mxr_write(mdev, MXR_GRAPHIC_CFG(0), val);
+	mxr_write(mdev, MXR_GRAPHIC_CFG(1), val);
+
+	/* configuration of Video Processor Registers */
+	__mxr_reg_vp_reset(mdev);
+	mxr_reg_vp_default_filter(mdev);
+
+	/* enable all interrupts */
+	mxr_write_mask(mdev, MXR_INT_EN, ~0, MXR_INT_EN_ALL);
+
+	mxr_vsync_set_update(mdev, MXR_ENABLE);
+	spin_unlock_irqrestore(&mdev->reg_slock, flags);
+}
+
+void mxr_reg_graph_format(struct mxr_device *mdev, int idx,
+	const struct mxr_format *fmt, const struct mxr_geometry *geo)
+{
+	u32 val;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mdev->reg_slock, flags);
+	mxr_vsync_set_update(mdev, MXR_DISABLE);
+
+	/* setup format */
+	mxr_write_mask(mdev, MXR_GRAPHIC_CFG(idx),
+		MXR_GRP_CFG_FORMAT_VAL(fmt->hwCode), MXR_GRP_CFG_FORMAT_MASK);
+
+	/* setup geometry */
+	mxr_write(mdev, MXR_GRAPHIC_SPAN(idx), geo->src.full_width);
+	val  = MXR_GRP_WH_WIDTH(geo->src.width);
+	val |= MXR_GRP_WH_HEIGHT(geo->src.height);
+	val |= MXR_GRP_WH_H_SCALE(geo->x_ratio);
+	val |= MXR_GRP_WH_V_SCALE(geo->y_ratio);
+	mxr_write(mdev, MXR_GRAPHIC_WH(idx), val);
+
+	/* setup offsets in source image */
+	val  = MXR_GRP_SXY_SX(geo->src.x_offset);
+	val |= MXR_GRP_SXY_SY(geo->src.y_offset);
+	mxr_write(mdev, MXR_GRAPHIC_SXY(idx), val);
+
+	/* setup offsets in display image */
+	val  = MXR_GRP_DXY_DX(geo->dst.x_offset);
+	val |= MXR_GRP_DXY_DY(geo->dst.y_offset);
+	mxr_write(mdev, MXR_GRAPHIC_DXY(idx), val);
+
+	mxr_vsync_set_update(mdev, MXR_ENABLE);
+	spin_unlock_irqrestore(&mdev->reg_slock, flags);
+}
+
+void mxr_reg_vp_format(struct mxr_device *mdev,
+	const struct mxr_format *fmt, const struct mxr_geometry *geo)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&mdev->reg_slock, flags);
+	mxr_vsync_set_update(mdev, MXR_DISABLE);
+
+	vp_write_mask(mdev, VP_MODE, fmt->hwCode, VP_MODE_FMT_MASK);
+
+	/* setting size of input image */
+	vp_write(mdev, VP_IMG_SIZE_Y, VP_IMG_HSIZE(geo->src.full_width) |
+		VP_IMG_VSIZE(geo->src.full_height));
+	/* chroma height has to reduced by 2 to avoid chroma distorions */
+	vp_write(mdev, VP_IMG_SIZE_C, VP_IMG_HSIZE(geo->src.full_width) |
+		VP_IMG_VSIZE(geo->src.full_height / 2));
+
+	vp_write(mdev, VP_SRC_WIDTH, geo->src.width);
+	vp_write(mdev, VP_SRC_HEIGHT, geo->src.height);
+	vp_write(mdev, VP_SRC_H_POSITION,
+		VP_SRC_H_POSITION_VAL(geo->src.x_offset));
+	vp_write(mdev, VP_SRC_V_POSITION, geo->src.y_offset);
+
+	vp_write(mdev, VP_DST_WIDTH, geo->dst.width);
+	vp_write(mdev, VP_DST_H_POSITION, geo->dst.x_offset);
+	if (geo->dst.field == V4L2_FIELD_INTERLACED) {
+		vp_write(mdev, VP_DST_HEIGHT, geo->dst.height / 2);
+		vp_write(mdev, VP_DST_V_POSITION, geo->dst.y_offset / 2);
+	} else {
+		vp_write(mdev, VP_DST_HEIGHT, geo->dst.height);
+		vp_write(mdev, VP_DST_V_POSITION, geo->dst.y_offset);
+	}
+
+	vp_write(mdev, VP_H_RATIO, geo->x_ratio);
+	vp_write(mdev, VP_V_RATIO, geo->y_ratio);
+
+	vp_write(mdev, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
+
+	mxr_vsync_set_update(mdev, MXR_ENABLE);
+	spin_unlock_irqrestore(&mdev->reg_slock, flags);
+
+}
+
+void mxr_reg_graph_buffer(struct mxr_device *mdev, int idx, dma_addr_t addr)
+{
+	u32 val = addr ? ~0 : 0;
+	unsigned long flags;
+	/*printk(KERN_INFO "%s(%08x)\n", __func__, addr);*/
+	spin_lock_irqsave(&mdev->reg_slock, flags);
+	mxr_vsync_set_update(mdev, MXR_DISABLE);
+
+	if (idx == 0)
+		mxr_write_mask(mdev, MXR_CFG, val, MXR_CFG_GRP0_ENABLE);
+	else
+		mxr_write_mask(mdev, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
+	mxr_write(mdev, MXR_GRAPHIC_BASE(idx), addr);
+
+	mxr_vsync_set_update(mdev, MXR_ENABLE);
+	spin_unlock_irqrestore(&mdev->reg_slock, flags);
+}
+
+void mxr_reg_vp_buffer(struct mxr_device *mdev,
+	dma_addr_t luma_addr[2], dma_addr_t chroma_addr[2])
+{
+	u32 val = luma_addr[0] ? ~0 : 0;
+	unsigned long flags;
+	/*printk(KERN_CRIT "%s(luma=%08x, chroma=%08x)\n", __func__,
+		luma_addr, chroma_addr);*/
+	spin_lock_irqsave(&mdev->reg_slock, flags);
+	mxr_vsync_set_update(mdev, MXR_DISABLE);
+
+	mxr_write_mask(mdev, MXR_CFG, val, MXR_CFG_VP_ENABLE);
+	vp_write_mask(mdev, VP_ENABLE, val, VP_ENABLE_ON);
+	/* TODO: fix tiled mode */
+	vp_write(mdev, VP_TOP_Y_PTR, luma_addr[0]);
+	vp_write(mdev, VP_TOP_C_PTR, chroma_addr[0]);
+	vp_write(mdev, VP_BOT_Y_PTR, luma_addr[1]);
+	vp_write(mdev, VP_BOT_C_PTR, chroma_addr[1]);
+
+	mxr_vsync_set_update(mdev, MXR_ENABLE);
+	spin_unlock_irqrestore(&mdev->reg_slock, flags);
+}
+
+static void mxr_irq_layer_handle(struct mxr_layer *layer)
+{
+	struct list_head *head = &layer->enq_list;
+	struct mxr_buffer *done;
+
+	/* skip non-existing layer */
+	if (layer == NULL)
+		return;
+
+	spin_lock(&layer->enq_slock);
+	if (layer->state == MXR_LAYER_IDLE)
+		goto done;
+
+	done = layer->shadow_buf;
+	layer->shadow_buf = layer->update_buf;
+
+	if (list_empty(head)) {
+		if (layer->state != MXR_LAYER_STREAMING)
+			layer->update_buf = NULL;
+	} else {
+		struct mxr_buffer *next;
+		next = list_first_entry(head, struct mxr_buffer, list);
+		list_del(&next->list);
+		layer->update_buf = next;
+	}
+
+	layer->ops.buffer_set(layer, layer->update_buf);
+
+	if (done && done != layer->shadow_buf)
+		vb2_buffer_done(&done->vb, VB2_BUF_STATE_DONE);
+
+done:
+	spin_unlock(&layer->enq_slock);
+}
+
+irqreturn_t mxr_irq_handler(int irq, void *dev_data)
+{
+	struct mxr_device *mdev = dev_data;
+	u32 i, val;
+	spin_lock(&mdev->reg_slock);
+	val = mxr_read(mdev, MXR_INT_STATUS);
+
+	/* wake up process waiting for VSYNC */
+	if (val & MXR_INT_STATUS_VSYNC) {
+		set_bit(MXR_EVENT_VSYNC, &mdev->event_flags);
+		wake_up(&mdev->event_queue);
+	}
+
+	/* clear interrupts */
+	if (~val & MXR_INT_EN_VSYNC) {
+		/* vsync interrupt use different bit for read and clear */
+		val &= ~MXR_INT_EN_VSYNC;
+		val |= MXR_INT_CLEAR_VSYNC;
+	}
+	mxr_write(mdev, MXR_INT_STATUS, val);
+
+	spin_unlock(&mdev->reg_slock);
+	/* leave on non-vsync event */
+	if (~val & MXR_INT_CLEAR_VSYNC)
+		return IRQ_HANDLED;
+	for (i = 0; i < MXR_MAX_LAYERS; ++i)
+		mxr_irq_layer_handle(mdev->layer[i]);
+	return IRQ_HANDLED;
+}
+
+void mxr_reg_s_output(struct mxr_device *mdev, int cookie)
+{
+	u32 val;
+
+	val = cookie == 0 ? MXR_CFG_DST_TV : MXR_CFG_DST_HDMI;
+	mxr_write_mask(mdev, MXR_CFG, val, MXR_CFG_DST_MASK);
+}
+
+void mxr_reg_streamon(struct mxr_device *mdev)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&mdev->reg_slock, flags);
+	/* single write -> no need to block vsync update */
+
+	/* start MIXER */
+	mxr_write_mask(mdev, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
+
+	spin_unlock_irqrestore(&mdev->reg_slock, flags);
+}
+
+void mxr_reg_streamoff(struct mxr_device *mdev)
+{
+	unsigned long flags;
+	spin_lock_irqsave(&mdev->reg_slock, flags);
+	/* single write -> no need to block vsync update */
+
+	/* stop MIXER */
+	mxr_write_mask(mdev, MXR_STATUS, 0, MXR_STATUS_REG_RUN);
+
+	spin_unlock_irqrestore(&mdev->reg_slock, flags);
+}
+
+int mxr_reg_wait4vsync(struct mxr_device *mdev)
+{
+	int ret;
+	clear_bit(MXR_EVENT_VSYNC, &mdev->event_flags);
+	/* TODO: consider adding interruptible */
+	ret = wait_event_timeout(mdev->event_queue,
+		test_bit(MXR_EVENT_VSYNC, &mdev->event_flags),
+		msecs_to_jiffies(1000));
+	if (ret > 0)
+		return 0;
+	if (ret < 0)
+		return ret;
+	return -ETIME;
+}
+
+void mxr_reg_set_mbus_fmt(struct mxr_device *mdev,
+	struct v4l2_mbus_framefmt *fmt)
+{
+	u32 val = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mdev->reg_slock, flags);
+	mxr_vsync_set_update(mdev, MXR_DISABLE);
+
+	/* choosing between interlace and progressive mode */
+	if (fmt->field == V4L2_FIELD_INTERLACED)
+		val |= MXR_CFG_SCAN_INTERLACE;
+	else
+		val |= MXR_CFG_SCAN_PROGRASSIVE;
+
+	/* choosing between porper HD and SD mode */
+	if (fmt->height == 480)
+		val |= MXR_CFG_NTSC | MXR_CFG_SD;
+	else if (fmt->height == 576)
+		val |= MXR_CFG_PAL | MXR_CFG_SD;
+	else if (fmt->height == 720)
+		val |= MXR_CFG_HD_720 | MXR_CFG_HD;
+	else if (fmt->height == 1080)
+		val |= MXR_CFG_HD_1080 | MXR_CFG_HD;
+	else
+		WARN(1, "unrecognized mbus height %u!\n", fmt->height);
+
+	mxr_write_mask(mdev, MXR_CFG, val, MXR_CFG_SCAN_MASK);
+
+	val = (fmt->field == V4L2_FIELD_INTERLACED) ? ~0 : 0;
+	vp_write_mask(mdev, VP_MODE, val,
+		VP_MODE_LINE_SKIP | VP_MODE_FIELD_ID_AUTO_TOGGLING);
+
+	mxr_vsync_set_update(mdev, MXR_ENABLE);
+	spin_unlock_irqrestore(&mdev->reg_slock, flags);
+}
+
+void mxr_reg_graph_layer_stream(struct mxr_device *mdev, int idx, int en)
+{
+	/* no extra actions need to be done */
+}
+
+void mxr_reg_vp_layer_stream(struct mxr_device *mdev, int en)
+{
+	/* no extra actions need to be done */
+}
+
+static const u8 filter_y_horiz_tap8[] = {
+	0,	-1,	-1,	-1,	-1,	-1,	-1,	-1,
+	-1,	-1,	-1,	-1,	-1,	0,	0,	0,
+	0,	2,	4,	5,	6,	6,	6,	6,
+	6,	5,	5,	4,	3,	2,	1,	1,
+	0,	-6,	-12,	-16,	-18,	-20,	-21,	-20,
+	-20,	-18,	-16,	-13,	-10,	-8,	-5,	-2,
+	127,	126,	125,	121,	114,	107,	99,	89,
+	79,	68,	57,	46,	35,	25,	16,	8,
+};
+
+static const u8 filter_y_vert_tap4[] = {
+	0,	-3,	-6,	-8,	-8,	-8,	-8,	-7,
+	-6,	-5,	-4,	-3,	-2,	-1,	-1,	0,
+	127,	126,	124,	118,	111,	102,	92,	81,
+	70,	59,	48,	37,	27,	19,	11,	5,
+	0,	5,	11,	19,	27,	37,	48,	59,
+	70,	81,	92,	102,	111,	118,	124,	126,
+	0,	0,	-1,	-1,	-2,	-3,	-4,	-5,
+	-6,	-7,	-8,	-8,	-8,	-8,	-6,	-3,
+};
+
+static const u8 filter_cr_horiz_tap4[] = {
+	0,	-3,	-6,	-8,	-8,	-8,	-8,	-7,
+	-6,	-5,	-4,	-3,	-2,	-1,	-1,	0,
+	127,	126,	124,	118,	111,	102,	92,	81,
+	70,	59,	48,	37,	27,	19,	11,	5,
+};
+
+static inline void mxr_reg_vp_filter_set(struct mxr_device *mdev,
+	int reg_id, const u8 *data, unsigned int size)
+{
+	/* assure 4-byte align */
+	BUG_ON(size & 3);
+	for (; size; size -= 4, reg_id += 4, data += 4) {
+		u32 val = (data[0] << 24) |  (data[1] << 16) |
+			(data[2] << 8) | data[3];
+		vp_write(mdev, reg_id, val);
+	}
+}
+
+static void mxr_reg_vp_default_filter(struct mxr_device *mdev)
+{
+	mxr_reg_vp_filter_set(mdev, VP_POLY8_Y0_LL,
+		filter_y_horiz_tap8, sizeof filter_y_horiz_tap8);
+	mxr_reg_vp_filter_set(mdev, VP_POLY4_Y0_LL,
+		filter_y_vert_tap4, sizeof filter_y_vert_tap4);
+	mxr_reg_vp_filter_set(mdev, VP_POLY4_C0_LL,
+		filter_cr_horiz_tap4, sizeof filter_cr_horiz_tap4);
+}
+
+static void mxr_reg_mxr_dump(struct mxr_device *mdev)
+{
+#define DUMPREG(reg_id) \
+do { \
+	u32 value = readl(mdev->res.mxr_regs + reg_id); \
+	mxr_dbg(mdev, #reg_id " = %08x\n", value); \
+} while (0)
+	DUMPREG(MXR_STATUS);
+	DUMPREG(MXR_CFG);
+	DUMPREG(MXR_INT_EN);
+	DUMPREG(MXR_INT_STATUS);
+
+	DUMPREG(MXR_LAYER_CFG);
+	DUMPREG(MXR_VIDEO_CFG);
+
+	DUMPREG(MXR_GRAPHIC0_CFG);
+	DUMPREG(MXR_GRAPHIC0_BASE);
+	DUMPREG(MXR_GRAPHIC0_SPAN);
+	DUMPREG(MXR_GRAPHIC0_WH);
+	DUMPREG(MXR_GRAPHIC0_SXY);
+	DUMPREG(MXR_GRAPHIC0_DXY);
+
+	DUMPREG(MXR_GRAPHIC1_CFG);
+	DUMPREG(MXR_GRAPHIC1_BASE);
+	DUMPREG(MXR_GRAPHIC1_SPAN);
+	DUMPREG(MXR_GRAPHIC1_WH);
+	DUMPREG(MXR_GRAPHIC1_SXY);
+	DUMPREG(MXR_GRAPHIC1_DXY);
+#undef DUMPREG
+}
+
+static void mxr_reg_vp_dump(struct mxr_device *mdev)
+{
+#define DUMPREG(reg_id) \
+do { \
+	u32 value = readl(mdev->res.vp_regs + reg_id); \
+	mxr_dbg(mdev, #reg_id " = %08x\n", value); \
+} while (0)
+
+	DUMPREG(VP_ENABLE);
+	DUMPREG(VP_SRESET);
+	DUMPREG(VP_SHADOW_UPDATE);
+	DUMPREG(VP_FIELD_ID);
+	DUMPREG(VP_MODE);
+	DUMPREG(VP_IMG_SIZE_Y);
+	DUMPREG(VP_IMG_SIZE_C);
+	DUMPREG(VP_PER_RATE_CTRL);
+	DUMPREG(VP_TOP_Y_PTR);
+	DUMPREG(VP_BOT_Y_PTR);
+	DUMPREG(VP_TOP_C_PTR);
+	DUMPREG(VP_BOT_C_PTR);
+	DUMPREG(VP_ENDIAN_MODE);
+	DUMPREG(VP_SRC_H_POSITION);
+	DUMPREG(VP_SRC_V_POSITION);
+	DUMPREG(VP_SRC_WIDTH);
+	DUMPREG(VP_SRC_HEIGHT);
+	DUMPREG(VP_DST_H_POSITION);
+	DUMPREG(VP_DST_V_POSITION);
+	DUMPREG(VP_DST_WIDTH);
+	DUMPREG(VP_DST_HEIGHT);
+	DUMPREG(VP_H_RATIO);
+	DUMPREG(VP_V_RATIO);
+
+	DUMPREG(VP_FIELD_ID_S);
+	DUMPREG(VP_MODE_S);
+	DUMPREG(VP_IMG_SIZE_Y_S);
+	DUMPREG(VP_IMG_SIZE_C_S);
+	DUMPREG(VP_TOP_Y_PTR_S);
+	DUMPREG(VP_BOT_Y_PTR_S);
+	DUMPREG(VP_TOP_C_PTR_S);
+	DUMPREG(VP_BOT_C_PTR_S);
+	DUMPREG(VP_ENDIAN_MODE_S);
+	DUMPREG(VP_SRC_H_POSITION_S);
+	DUMPREG(VP_SRC_V_POSITION_S);
+	DUMPREG(VP_SRC_WIDTH_S);
+	DUMPREG(VP_SRC_HEIGHT_S);
+	DUMPREG(VP_DST_H_POSITION_S);
+	DUMPREG(VP_DST_V_POSITION_S);
+	DUMPREG(VP_DST_WIDTH_S);
+	DUMPREG(VP_DST_HEIGHT_S);
+	DUMPREG(VP_H_RATIO_S);
+	DUMPREG(VP_V_RATIO_S);
+
+	DUMPREG(VP_PP_BYPASS);
+	DUMPREG(VP_PP_SATURATION);
+	DUMPREG(VP_PP_SHARPNESS);
+	DUMPREG(VP_PP_LINE_EQ0);
+	DUMPREG(VP_PP_LINE_EQ1);
+	DUMPREG(VP_PP_LINE_EQ2);
+	DUMPREG(VP_PP_LINE_EQ3);
+	DUMPREG(VP_PP_LINE_EQ4);
+	DUMPREG(VP_PP_LINE_EQ5);
+	DUMPREG(VP_PP_LINE_EQ6);
+	DUMPREG(VP_PP_LINE_EQ7);
+	DUMPREG(VP_PP_BRIGHT_OFFSET);
+	DUMPREG(VP_VERSION_INFO);
+
+#undef DUMPREG
+}
+
+void mxr_reg_dump(struct mxr_device *mdev)
+{
+	mxr_reg_mxr_dump(mdev);
+	mxr_reg_vp_dump(mdev);
+}
+
diff --git a/drivers/media/video/s5p-tv/mixer_reg.h b/drivers/media/video/s5p-tv/mixer_reg.h
new file mode 100644
index 0000000..e63224c1
--- /dev/null
+++ b/drivers/media/video/s5p-tv/mixer_reg.h
@@ -0,0 +1,46 @@
+/*
+ * Samsung TV Mixer driver
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Tomasz Stanislawski, t.stanislaws@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundiation. either version 2 of the License,
+ * or (at your option) any later version
+ */
+
+#ifndef _SAMSUNG_MIXER_REG_H_
+#define _SAMSUNG_MIXER_REG_H_	__FILE__
+
+#include "mixer.h"
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+
+void mxr_vsync_set_update(struct mxr_device *mdev, int en);
+void mxr_reg_reset(struct mxr_device *mdev);
+irqreturn_t mxr_irq_handler(int irq, void *dev_data);
+void mxr_reg_s_output(struct mxr_device *mdev, int cookie);
+void mxr_reg_streamon(struct mxr_device *mdev);
+void mxr_reg_streamoff(struct mxr_device *mdev);
+int mxr_reg_wait4vsync(struct mxr_device *mdev);
+void mxr_reg_set_mbus_fmt(struct mxr_device *mdev,
+	struct v4l2_mbus_framefmt *fmt);
+void mxr_reg_graph_layer_stream(struct mxr_device *mdev, int idx, int en);
+void mxr_reg_graph_buffer(struct mxr_device *mdev, int idx, dma_addr_t addr);
+void mxr_reg_graph_format(struct mxr_device *mdev, int idx,
+	const struct mxr_format *fmt, const struct mxr_geometry *geo);
+
+void mxr_reg_vp_layer_stream(struct mxr_device *mdev, int en);
+void mxr_reg_vp_buffer(struct mxr_device *mdev,
+	dma_addr_t luma_addr[2], dma_addr_t chroma_addr[2]);
+void mxr_reg_vp_format(struct mxr_device *mdev,
+	const struct mxr_format *fmt, const struct mxr_geometry *geo);
+
+void mxr_reg_dump(struct mxr_device *mdev);
+
+#endif /* _SAMSUNG_MIXER_REG_H_ */
+
diff --git a/drivers/media/video/s5p-tv/mixer_video.c b/drivers/media/video/s5p-tv/mixer_video.c
new file mode 100644
index 0000000..4b030a1
--- /dev/null
+++ b/drivers/media/video/s5p-tv/mixer_video.c
@@ -0,0 +1,957 @@
+/*
+ * Samsung TV Mixer driver
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Tomasz Stanislawski, t.stanislaws@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundiation. either version 2 of the License,
+ * or (at your option) any later version
+ */
+
+#include "mixer.h"
+
+#include <media/v4l2-ioctl.h>
+#include <linux/videodev2.h>
+#include <linux/mm.h>
+#include <linux/version.h>
+#include <linux/timer.h>
+#include <media/videobuf2-dma-contig.h>
+
+static int find_reg_callback(struct device *dev, void *p)
+{
+	struct v4l2_subdev **sd = p;
+
+	*sd = dev_get_drvdata(dev);
+	/* non-zero value stops iteration */
+	return 1;
+}
+
+static struct v4l2_subdev *find_and_register_subdev(
+	struct mxr_device *mdev, char *module_name)
+{
+	struct device_driver *drv;
+	struct v4l2_subdev *sd = NULL;
+	int ret;
+
+	/* TODO: add waiting until probe is finished */
+	drv = driver_find(module_name, &platform_bus_type);
+	if (!drv) {
+		mxr_warn(mdev, "module %s is missing\n", module_name);
+		return NULL;
+	}
+	/* driver refcnt is increased, it is safe to iterate over devices */
+	ret = driver_for_each_device(drv, NULL, &sd, find_reg_callback);
+	/* ret == 0 means that find_reg_callback was never executed */
+	if (sd == NULL) {
+		mxr_warn(mdev, "module %s provides no subdev!\n", module_name);
+		goto done;
+	}
+	/* v4l2_device_register_subdev detects if sd is NULL */
+	ret = v4l2_device_register_subdev(&mdev->v4l2_dev, sd);
+	if (ret) {
+		mxr_warn(mdev, "failed to register subdev %s\n", sd->name);
+		sd = NULL;
+	}
+
+done:
+	put_driver(drv);
+	return sd;
+}
+
+int __devinit mxr_acquire_video(struct mxr_device *mdev,
+	struct mxr_output_conf *output_conf, int output_count)
+{
+	struct device *dev = mdev->dev;
+	struct v4l2_device *vdev = &mdev->v4l2_dev;
+	int i;
+	int ret = 0;
+	struct v4l2_subdev *sd;
+
+	strlcpy(vdev->name, "s5p-tv", sizeof(vdev->name));
+	/* prepare context for V4L2 device */
+	ret = v4l2_device_register(dev, vdev);
+	if (ret) {
+		mxr_err(mdev, "could not register v4l2 device.\n");
+		goto fail;
+	}
+
+	mdev->alloc_ctx = vb2_dma_contig_init_ctx(mdev->dev);
+	if (IS_ERR_OR_NULL(mdev->alloc_ctx)) {
+		mxr_err(mdev, "could not acquire vb2 allocator\n");
+		goto fail_v4l2_dev;
+	}
+
+	/* registering outputs */
+	mdev->output_cnt = 0;
+	for (i = 0; i < output_count; ++i) {
+		struct mxr_output_conf *conf = &output_conf[i];
+		struct mxr_output *out;
+		sd = find_and_register_subdev(mdev, conf->module_name);
+		/* trying to register next output */
+		if (sd == NULL)
+			continue;
+		out = kzalloc(sizeof *out, GFP_KERNEL);
+		if (out == NULL) {
+			mxr_err(mdev, "no memory for '%s'\n",
+				conf->output_name);
+			ret = -ENOMEM;
+			/* registered subdevs are removed in fail_v4l2_dev */
+			goto fail_output;
+		}
+		strlcpy(out->name, conf->output_name, sizeof(out->name));
+		out->sd = sd;
+		out->cookie = conf->cookie;
+		mdev->output[mdev->output_cnt++] = out;
+		mxr_info(mdev, "added output '%s' from module '%s'\n",
+			conf->output_name, conf->module_name);
+		/* checking if maximal number of outputs is reached */
+		if (mdev->output_cnt >= MXR_MAX_OUTPUTS)
+			break;
+	}
+
+	if (mdev->output_cnt == 0) {
+		mxr_err(mdev, "failed to register any output\n");
+		ret = -ENODEV;
+		/* skipping fail_output because there is nothing to free */
+		goto fail_vb2_allocator;
+	}
+
+	return 0;
+
+fail_output:
+	/* kfree is NULL-safe */
+	for (i = 0; i < mdev->output_cnt; ++i)
+		kfree(mdev->output[i]);
+	memset(mdev->output, 0, sizeof mdev->output);
+
+fail_vb2_allocator:
+	/* freeing allocator context */
+	vb2_dma_contig_cleanup_ctx(mdev->alloc_ctx);
+
+fail_v4l2_dev:
+	/* NOTE: automatically unregisteres all subdevs */
+	v4l2_device_unregister(vdev);
+
+fail:
+	return ret;
+}
+
+void __devexit mxr_release_video(struct mxr_device *mdev)
+{
+	int i;
+
+	/* kfree is NULL-safe */
+	for (i = 0; i < mdev->output_cnt; ++i)
+		kfree(mdev->output[i]);
+
+	vb2_dma_contig_cleanup_ctx(mdev->alloc_ctx);
+	v4l2_device_unregister(&mdev->v4l2_dev);
+}
+
+static int mxr_querycap(struct file *file, void *priv,
+	struct v4l2_capability *cap)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
+
+	strlcpy(cap->driver, MXR_DRIVER_NAME, sizeof cap->driver);
+	strlcpy(cap->card, layer->vfd.name, sizeof cap->card);
+	sprintf(cap->bus_info, "%d", layer->idx);
+	cap->version = KERNEL_VERSION(0, 1, 0);
+	cap->capabilities = V4L2_CAP_STREAMING |
+		V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
+
+	return 0;
+}
+
+/* Geometry handling */
+static void mxr_layer_geo_fix(struct mxr_layer *layer)
+{
+	struct mxr_device *mdev = layer->mdev;
+	struct v4l2_mbus_framefmt mbus_fmt;
+
+	/* TODO: add some dirty flag */
+	mxr_get_mbus_fmt(mdev, &mbus_fmt);
+	layer->geo.dst.full_width = mbus_fmt.width;
+	layer->geo.dst.full_height = mbus_fmt.height;
+	layer->geo.dst.field = mbus_fmt.field;
+	layer->ops.fix_geometry(layer);
+}
+
+static void mxr_layer_default_geo(struct mxr_layer *layer)
+{
+	struct mxr_device *mdev = layer->mdev;
+	struct v4l2_mbus_framefmt mbus_fmt;
+
+	memset(&layer->geo, 0, sizeof layer->geo);
+
+	mxr_get_mbus_fmt(mdev, &mbus_fmt);
+
+	layer->geo.dst.full_width = mbus_fmt.width;
+	layer->geo.dst.full_height = mbus_fmt.height;
+	layer->geo.dst.width = layer->geo.dst.full_width;
+	layer->geo.dst.height = layer->geo.dst.full_height;
+	layer->geo.dst.field = mbus_fmt.field;
+
+	layer->geo.src.full_width = mbus_fmt.width;
+	layer->geo.src.full_height = mbus_fmt.height;
+	layer->geo.src.width = layer->geo.src.full_width;
+	layer->geo.src.height = layer->geo.src.full_height;
+
+	layer->ops.fix_geometry(layer);
+}
+
+static void mxr_geometry_dump(struct mxr_device *mdev, struct mxr_geometry *geo)
+{
+	mxr_dbg(mdev, "src.full_size = (%u, %u)\n",
+		geo->src.full_width, geo->src.full_height);
+	mxr_dbg(mdev, "src.size = (%u, %u)\n",
+		geo->src.width, geo->src.height);
+	mxr_dbg(mdev, "src.offset = (%u, %u)\n",
+		geo->src.x_offset, geo->src.y_offset);
+	mxr_dbg(mdev, "dst.full_size = (%u, %u)\n",
+		geo->dst.full_width, geo->dst.full_height);
+	mxr_dbg(mdev, "dst.size = (%u, %u)\n",
+		geo->dst.width, geo->dst.height);
+	mxr_dbg(mdev, "dst.offset = (%u, %u)\n",
+		geo->dst.x_offset, geo->dst.y_offset);
+	mxr_dbg(mdev, "ratio = (%u, %u)\n",
+		geo->x_ratio, geo->y_ratio);
+}
+
+
+static const struct mxr_format *find_format_by_fourcc(
+	struct mxr_layer *layer, unsigned long fourcc);
+static const struct mxr_format *find_format_by_index(
+	struct mxr_layer *layer, unsigned long index);
+
+static int mxr_enum_fmt(struct file *file, void  *priv,
+	struct v4l2_fmtdesc *f)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	const struct mxr_format *fmt;
+
+	mxr_dbg(mdev, "%s\n", __func__);
+	fmt = find_format_by_index(layer, f->index);
+	if (fmt == NULL)
+		return -EINVAL;
+
+	strlcpy(f->description, fmt->name, sizeof(f->description));
+	f->pixelformat = fmt->fourcc;
+
+	return 0;
+}
+
+static int mxr_s_fmt(struct file *file, void *priv,
+	struct v4l2_format *f)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	const struct mxr_format *fmt;
+	struct v4l2_pix_format_mplane *pix;
+	struct mxr_device *mdev = layer->mdev;
+	struct mxr_geometry *geo = &layer->geo;
+	int i;
+
+	mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
+
+	pix = &f->fmt.pix_mp;
+	fmt = find_format_by_fourcc(layer, pix->pixelformat);
+	if (fmt == NULL) {
+		mxr_warn(mdev, "not recognized fourcc: %08x\n",
+			pix->pixelformat);
+		return -EINVAL;
+	}
+	layer->fmt = fmt;
+	geo->src.full_width = pix->width;
+	geo->src.width = pix->width;
+	geo->src.full_height = pix->height;
+	geo->src.height = pix->height;
+	/* assure consistency of geometry */
+	mxr_layer_geo_fix(layer);
+
+	for (i = 0; i < fmt->num_subframes; ++i) {
+		unsigned int nPixel = fmt->plane[i].pxHeight *
+			fmt->plane[i].pxWidth;
+		pix->plane_fmt[i].bytesperline = geo->src.full_width *
+			fmt->plane[i].bSize / nPixel;
+	}
+	mxr_dbg(mdev, "width=%u height=%u bpp=%u span=%u\n",
+		geo->src.width, geo->src.height,
+		pix->plane_fmt[0].bytesperline, geo->src.full_width);
+	return 0;
+}
+
+static int mxr_g_fmt(struct file *file, void *priv,
+			     struct v4l2_format *f)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
+
+	f->fmt.pix.width	= layer->geo.src.full_width;
+	f->fmt.pix.height	= layer->geo.src.full_height;
+	f->fmt.pix.field	= V4L2_FIELD_NONE;
+	f->fmt.pix.pixelformat	= layer->fmt->fourcc;
+
+	return 0;
+}
+
+static inline struct mxr_crop *choose_crop_by_type(struct mxr_geometry *geo,
+	enum v4l2_buf_type type)
+{
+	switch (type) {
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+	case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
+		return &geo->dst;
+	case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+		return &geo->src;
+	default:
+		return NULL;
+	}
+}
+
+static int mxr_g_crop(struct file *file, void *fh, struct v4l2_crop *a)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	struct mxr_crop *crop;
+	mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
+	crop = choose_crop_by_type(&layer->geo, a->type);
+	if (crop == NULL)
+		return -EINVAL;
+	mxr_layer_geo_fix(layer);
+	a->c.left = crop->x_offset;
+	a->c.top = crop->y_offset;
+	a->c.width = crop->width;
+	a->c.height = crop->height;
+	return 0;
+}
+
+static int mxr_s_crop(struct file *file, void *fh, struct v4l2_crop *a)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	struct mxr_crop *crop;
+	mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
+	crop = choose_crop_by_type(&layer->geo, a->type);
+	if (crop == NULL)
+		return -EINVAL;
+	crop->x_offset = a->c.left;
+	crop->y_offset = a->c.top;
+	crop->width = a->c.width;
+	crop->height = a->c.height;
+	mxr_layer_geo_fix(layer);
+	return 0;
+}
+
+static int mxr_cropcap(struct file *file, void *fh, struct v4l2_cropcap *a)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	struct mxr_crop *crop;
+	mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
+	crop = choose_crop_by_type(&layer->geo, a->type);
+	if (crop == NULL)
+		return -EINVAL;
+	mxr_layer_geo_fix(layer);
+	a->bounds.left = 0;
+	a->bounds.top = 0;
+	a->bounds.width = crop->full_width;
+	a->bounds.top = crop->full_height;
+	a->defrect = a->bounds;
+	return 0;
+}
+
+static int mxr_enum_dv_presets(struct file *file, void *fh,
+	struct v4l2_dv_enum_preset *preset)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	int ret;
+
+	/* lock protects from changing sd_out */
+	mutex_lock(&mdev->mutex);
+	ret = v4l2_subdev_call(to_outsd(mdev), video, enum_dv_presets, preset);
+	mutex_unlock(&mdev->mutex);
+
+	return ret ? -EINVAL : 0;
+}
+
+static int mxr_s_dv_preset(struct file *file, void *fh,
+	struct v4l2_dv_preset *preset)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	int ret;
+
+	/* lock protects from changing sd_out */
+	mutex_lock(&mdev->mutex);
+
+	/* preset change cannot be done while there is an entity
+	 * dependant on output configuration
+	 */
+	if (mdev->n_output == 0)
+		ret = v4l2_subdev_call(to_outsd(mdev), video, s_dv_preset,
+			preset);
+	else
+		ret = -EBUSY;
+
+	mutex_unlock(&mdev->mutex);
+
+	return ret;
+}
+
+static int mxr_g_dv_preset(struct file *file, void *fh,
+	struct v4l2_dv_preset *preset)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	int ret;
+
+	/* lock protects from changing sd_out */
+	mutex_lock(&mdev->mutex);
+	ret = v4l2_subdev_call(to_outsd(mdev), video, query_dv_preset, preset);
+	mutex_unlock(&mdev->mutex);
+
+	return ret;
+}
+
+static int mxr_s_std(struct file *file, void *fh, v4l2_std_id *norm)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	int ret;
+
+	/* lock protects from changing sd_out */
+	mutex_lock(&mdev->mutex);
+
+	/* standard change cannot be done while there is an entity
+	 * dependant on output configuration
+	 */
+	if (mdev->n_output == 0)
+		ret = v4l2_subdev_call(to_outsd(mdev), video, s_std_output,
+			*norm);
+	else
+		ret = -EBUSY;
+
+	mutex_unlock(&mdev->mutex);
+
+	return ret;
+}
+
+static int mxr_enum_output(struct file *file, void *fh, struct v4l2_output *a)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	struct mxr_output *out;
+	struct v4l2_subdev *sd;
+
+	if (a->index >= mdev->output_cnt)
+		return -EINVAL;
+	out = mdev->output[a->index];
+	BUG_ON(out == NULL);
+	sd = out->sd;
+	strlcpy(a->name, out->name, sizeof(a->name));
+
+	/* try to obtain supported tv norms */
+	v4l2_subdev_call(sd, video, g_tvnorms, &a->std);
+	a->capabilities = 0;
+	if (sd->ops->video && sd->ops->video->s_dv_preset)
+		a->capabilities |= V4L2_OUT_CAP_PRESETS;
+	if (sd->ops->video && sd->ops->video->s_std_output)
+		a->capabilities |= V4L2_OUT_CAP_STD;
+
+	return 0;
+}
+
+static int mxr_s_output(struct file *file, void *fh, unsigned int i)
+{
+	struct video_device *vfd = video_devdata(file);
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	int ret = 0;
+
+	if (i >= mdev->output_cnt || mdev->output[i] == NULL)
+		return -EINVAL;
+
+	mutex_lock(&mdev->mutex);
+	if (mdev->n_output > 0) {
+		ret = -EBUSY;
+		goto done;
+	}
+	mdev->current_output = i;
+	mxr_info(mdev, "tvnorms = %08llx\n", vfd->tvnorms);
+	vfd->tvnorms = 0;
+	v4l2_subdev_call(to_outsd(mdev), video, g_tvnorms, &vfd->tvnorms);
+	mxr_info(mdev, "new tvnorms = %08llx\n", vfd->tvnorms);
+
+done:
+	mutex_unlock(&mdev->mutex);
+	return ret;
+}
+
+static int mxr_reqbufs(struct file *file, void *priv,
+			  struct v4l2_requestbuffers *p)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
+	return vb2_reqbufs(&layer->vb_queue, p);
+}
+
+static int mxr_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
+	return vb2_querybuf(&layer->vb_queue, p);
+}
+
+static int mxr_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	mxr_dbg(mdev, "%s:%d(%d)\n", __func__, __LINE__,
+		p->index);
+	return vb2_qbuf(&layer->vb_queue, p);
+}
+
+static int mxr_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
+	return vb2_dqbuf(&layer->vb_queue, p, file->f_flags & O_NONBLOCK);
+}
+
+static int mxr_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
+	return vb2_streamon(&layer->vb_queue, i);
+}
+
+static int mxr_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
+	return vb2_streamoff(&layer->vb_queue, i);
+}
+
+static const struct v4l2_ioctl_ops mxr_ioctl_ops = {
+	.vidioc_querycap = mxr_querycap,
+	.vidioc_enum_fmt_vid_out = mxr_enum_fmt,
+	.vidioc_s_fmt_vid_out_mplane = mxr_s_fmt,
+	.vidioc_g_fmt_vid_out_mplane = mxr_g_fmt,
+	.vidioc_reqbufs = mxr_reqbufs,
+	.vidioc_querybuf = mxr_querybuf,
+	.vidioc_qbuf = mxr_qbuf,
+	.vidioc_dqbuf = mxr_dqbuf,
+	.vidioc_streamon = mxr_streamon,
+	.vidioc_streamoff = mxr_streamoff,
+
+	/* Preset functions */
+	.vidioc_enum_dv_presets = mxr_enum_dv_presets,
+	.vidioc_s_dv_preset = mxr_s_dv_preset,
+	.vidioc_g_dv_preset = mxr_g_dv_preset,
+
+	/* analog TV standard functions */
+	.vidioc_s_std = mxr_s_std,
+
+	/* Output handling */
+	.vidioc_enum_output = mxr_enum_output,
+	.vidioc_s_output = mxr_s_output,
+	/* Crop ioctls */
+	.vidioc_g_crop = mxr_g_crop,
+	.vidioc_s_crop = mxr_s_crop,
+	.vidioc_cropcap = mxr_cropcap,
+};
+
+static int mxr_video_open(struct file *file)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+	int ret = 0;
+
+	mxr_dbg(mdev, "%s:%d\n", __func__, __LINE__);
+	/* assure device probe is finished */
+	wait_for_device_probe();
+	/* lock layer->mutex is already taken by video_device */
+	/* leaving if layer is already initialized */
+	if (++layer->n_user > 1)
+		return 0;
+
+	/* FIXME: should power be enabled on open? */
+	ret = mxr_power_get(mdev);
+	if (ret) {
+		mxr_err(mdev, "power on failed\n");
+		goto fail_n_user;
+	}
+
+	ret = vb2_queue_init(&layer->vb_queue);
+	if (ret != 0) {
+		mxr_err(mdev, "failed to initialize vb2 queue\n");
+		goto fail_power;
+	}
+	/* set default format, first on the list */
+	layer->fmt = layer->fmt_array[0];
+	/* setup default geometry */
+	mxr_layer_default_geo(layer);
+
+	return 0;
+
+fail_power:
+	mxr_power_put(mdev);
+
+fail_n_user:
+	--layer->n_user;
+
+	return ret;
+}
+
+static unsigned int
+mxr_video_poll(struct file *file, struct poll_table_struct *wait)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+
+	mxr_info(mdev, "%s:%d\n", __func__, __LINE__);
+
+	return vb2_poll(&layer->vb_queue, file, wait);
+}
+
+static int mxr_video_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+
+	mxr_info(mdev, "%s:%d\n", __func__, __LINE__);
+
+	return vb2_mmap(&layer->vb_queue, vma);
+}
+
+static int mxr_video_release(struct file *file)
+{
+	struct mxr_layer *layer = video_drvdata(file);
+	struct mxr_device *mdev = layer->mdev;
+
+	mxr_info(mdev, "%s:%d\n", __func__, __LINE__);
+	if (--layer->n_user == 0) {
+		vb2_queue_release(&layer->vb_queue);
+		/* TODO: move power off to timer thread */
+		mxr_power_put(mdev);
+	}
+	return 0;
+}
+
+static const struct v4l2_file_operations mxr_fops = {
+	.owner = THIS_MODULE,
+	.open = mxr_video_open,
+	.poll = mxr_video_poll,
+	.mmap = mxr_video_mmap,
+	.release = mxr_video_release,
+	.unlocked_ioctl = video_ioctl2,
+};
+
+static unsigned int divup(unsigned int divident, unsigned int divisor)
+{
+	return (divident + divisor - 1) / divisor;
+}
+
+unsigned long mxr_get_plane_size(const struct mxr_block *blk,
+	unsigned int width, unsigned int height)
+{
+	unsigned int blWidth = divup(width, blk->pxWidth);
+	unsigned int blHeight = divup(height, blk->pxHeight);
+	return blWidth * blHeight * blk->bSize;
+}
+
+static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
+	unsigned int *nplanes, unsigned long sizes[],
+	void *alloc_ctxs[])
+{
+	struct mxr_layer *layer = vb2_get_drv_priv(vq);
+	const struct mxr_format *fmt = layer->fmt;
+	int i;
+	struct mxr_device *mdev = layer->mdev;
+	mxr_dbg(mdev, "%s\n", __func__);
+	/* checking if format was configured */
+	if (fmt == NULL)
+		return -EINVAL;
+	mxr_dbg(mdev, "fmt = %s\n", fmt->name);
+
+	*nplanes = fmt->num_subframes;
+	for (i = 0; i < fmt->num_subframes; ++i) {
+		alloc_ctxs[i] = layer->mdev->alloc_ctx;
+		sizes[i] = 0;
+	}
+
+	for (i = 0; i < fmt->num_planes; ++i) {
+		int frame_idx = fmt->plane2subframe[i];
+		const struct mxr_block *blk = &fmt->plane[i];
+		unsigned long plane_size;
+		plane_size = mxr_get_plane_size(blk, layer->geo.src.full_width,
+			layer->geo.src.full_height);
+		sizes[frame_idx] += plane_size;
+		mxr_dbg(mdev, "plane_size[%d] = %08lx\n", i, plane_size);
+	}
+	for (i = 0; i < fmt->num_subframes; ++i) {
+		sizes[i] = PAGE_ALIGN(sizes[i]);
+		mxr_dbg(mdev, "size[%d] = %08lx\n", i, sizes[i]);
+	}
+
+	if (*nbuffers == 0)
+		*nbuffers = 1;
+
+	return 0;
+}
+
+static void buf_queue(struct vb2_buffer *vb)
+{
+	struct mxr_buffer *buffer = container_of(vb, struct mxr_buffer, vb);
+	struct mxr_layer *layer = vb2_get_drv_priv(vb->vb2_queue);
+	struct mxr_device *mdev = layer->mdev;
+	unsigned long flags;
+	int must_start = 0;
+
+	spin_lock_irqsave(&layer->enq_slock, flags);
+	if (layer->state == MXR_LAYER_STREAMING_START) {
+		layer->state = MXR_LAYER_STREAMING;
+		must_start = 1;
+	}
+	list_add_tail(&buffer->list, &layer->enq_list);
+	spin_unlock_irqrestore(&layer->enq_slock, flags);
+	if (must_start) {
+		layer->ops.stream_set(layer, MXR_ENABLE);
+		mxr_streamer_get(mdev);
+	}
+
+	mxr_dbg(mdev, "queuing buffer\n");
+}
+
+static void wait_lock(struct vb2_queue *vq)
+{
+	struct mxr_layer *layer = vb2_get_drv_priv(vq);
+	struct mxr_device *mdev = layer->mdev;
+	mxr_dbg(mdev, "%s\n", __func__);
+	mutex_lock(&layer->mutex);
+}
+
+static void wait_unlock(struct vb2_queue *vq)
+{
+	struct mxr_layer *layer = vb2_get_drv_priv(vq);
+	struct mxr_device *mdev = layer->mdev;
+	mxr_dbg(mdev, "%s\n", __func__);
+	mutex_unlock(&layer->mutex);
+}
+
+static int start_streaming(struct vb2_queue *vq)
+{
+	struct mxr_layer *layer = vb2_get_drv_priv(vq);
+	struct mxr_device *mdev = layer->mdev;
+	unsigned long flags;
+
+	mxr_dbg(mdev, "%s\n", __func__);
+	/* block any changes in output configuration */
+	mxr_output_get(mdev);
+
+	/* update layers geometry */
+	mxr_layer_geo_fix(layer);
+	mxr_geometry_dump(mdev, &layer->geo);
+
+	layer->ops.format_set(layer);
+	/* enabling layer in hardware */
+	spin_lock_irqsave(&layer->enq_slock, flags);
+	layer->state = MXR_LAYER_STREAMING_START;
+	spin_unlock_irqrestore(&layer->enq_slock, flags);
+
+	return 0;
+}
+
+static void mxr_watchdog(unsigned long arg)
+{
+	struct mxr_layer *layer = (struct mxr_layer *) arg;
+	struct mxr_device *mdev = layer->mdev;
+	unsigned long flags;
+
+	mxr_err(mdev, "watchdog fired for layer %s\n", layer->vfd.name);
+
+	spin_lock_irqsave(&layer->enq_slock, flags);
+
+	if (layer->update_buf == layer->shadow_buf)
+		layer->update_buf = NULL;
+	if (layer->update_buf) {
+		vb2_buffer_done(&layer->update_buf->vb, VB2_BUF_STATE_ERROR);
+		layer->update_buf = NULL;
+	}
+	if (layer->shadow_buf) {
+		vb2_buffer_done(&layer->shadow_buf->vb, VB2_BUF_STATE_ERROR);
+		layer->shadow_buf = NULL;
+	}
+	spin_unlock_irqrestore(&layer->enq_slock, flags);
+}
+
+static int stop_streaming(struct vb2_queue *vq)
+{
+	struct mxr_layer *layer = vb2_get_drv_priv(vq);
+	struct mxr_device *mdev = layer->mdev;
+	unsigned long flags;
+	struct timer_list watchdog;
+	struct mxr_buffer *buf, *buf_tmp;
+
+	mxr_dbg(mdev, "%s\n", __func__);
+
+	spin_lock_irqsave(&layer->enq_slock, flags);
+
+	/* reset list */
+	layer->state = MXR_LAYER_STREAMING_FINISH;
+
+	/* set all buffer to be done */
+	list_for_each_entry_safe(buf, buf_tmp, &layer->enq_list, list) {
+		list_del(&buf->list);
+		vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
+	}
+
+	spin_unlock_irqrestore(&layer->enq_slock, flags);
+
+	/* give 1 seconds to complete to complete last buffers */
+	setup_timer_on_stack(&watchdog, mxr_watchdog,
+		(unsigned long)layer);
+	mod_timer(&watchdog, jiffies + msecs_to_jiffies(1000));
+
+	/* wait until all buffers are goes to done state */
+	vb2_wait_for_all_buffers(vq);
+
+	/* stop timer if all synchronization is done */
+	del_timer_sync(&watchdog);
+	destroy_timer_on_stack(&watchdog);
+
+	/* stopping hardware */
+	spin_lock_irqsave(&layer->enq_slock, flags);
+	layer->state = MXR_LAYER_IDLE;
+	spin_unlock_irqrestore(&layer->enq_slock, flags);
+
+	/* disabling layer in hardware */
+	layer->ops.stream_set(layer, MXR_DISABLE);
+	/* remove one streamer */
+	mxr_streamer_put(mdev);
+	/* allow changes in output configuration */
+	mxr_output_put(mdev);
+	return 0;
+}
+
+static struct vb2_ops mxr_video_qops = {
+	.queue_setup = queue_setup,
+	.buf_queue = buf_queue,
+	.wait_prepare = wait_unlock,
+	.wait_finish = wait_lock,
+	.start_streaming = start_streaming,
+	.stop_streaming = stop_streaming,
+};
+
+/* FIXME: itry to put this functions to mxr_base_layer_create */
+int mxr_base_layer_register(struct mxr_layer *layer)
+{
+	struct mxr_device *mdev = layer->mdev;
+	int ret;
+	ret = video_register_device(&layer->vfd, VFL_TYPE_GRABBER, -1);
+	if (ret)
+		mxr_err(mdev, "failed to register video device\n");
+	else
+		mxr_info(mdev, "registered layer %s as /dev/video%d\n",
+			layer->vfd.name, layer->vfd.num);
+	return ret;
+}
+
+void mxr_base_layer_unregister(struct mxr_layer *layer)
+{
+	video_unregister_device(&layer->vfd);
+}
+
+void mxr_layer_release(struct mxr_layer *layer)
+{
+	if (layer->ops.release)
+		layer->ops.release(layer);
+}
+
+void mxr_base_layer_release(struct mxr_layer *layer)
+{
+	kfree(layer);
+}
+
+static void mxr_vfd_release(struct video_device *vdev)
+{
+	printk(KERN_INFO "video device release\n");
+}
+
+struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev,
+	int idx, char *name, struct mxr_layer_ops *ops)
+{
+	struct mxr_layer *layer;
+
+	layer = kzalloc(sizeof *layer, GFP_KERNEL);
+	if (layer == NULL) {
+		mxr_err(mdev, "not enough memory for layer.\n");
+		goto fail;
+	}
+
+	layer->mdev = mdev;
+	layer->idx = idx;
+	layer->ops = *ops;
+
+	spin_lock_init(&layer->enq_slock);
+	INIT_LIST_HEAD(&layer->enq_list);
+	mutex_init(&layer->mutex);
+
+	layer->vfd = (struct video_device) {
+		.minor = -1,
+		.release = mxr_vfd_release,
+		.fops = &mxr_fops,
+		.ioctl_ops = &mxr_ioctl_ops,
+	};
+	strlcpy(layer->vfd.name, name, sizeof(layer->vfd.name));
+
+	video_set_drvdata(&layer->vfd, layer);
+	layer->vfd.lock = &layer->mutex;
+	layer->vfd.v4l2_dev = &mdev->v4l2_dev;
+
+	layer->vb_queue = (struct vb2_queue) {
+		.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE,
+		.io_modes = VB2_MMAP | VB2_USERPTR,
+		.drv_priv = layer,
+		.buf_struct_size = sizeof(struct mxr_buffer),
+		.ops = &mxr_video_qops,
+		.mem_ops = &vb2_dma_contig_memops,
+	};
+
+	return layer;
+
+fail:
+	return NULL;
+}
+
+static const struct mxr_format *find_format_by_fourcc(
+	struct mxr_layer *layer, unsigned long fourcc)
+{
+	int i;
+	for (i = 0; i < layer->fmt_array_size; ++i)
+		if (layer->fmt_array[i]->fourcc == fourcc)
+			return layer->fmt_array[i];
+	return NULL;
+}
+
+static const struct mxr_format *find_format_by_index(
+	struct mxr_layer *layer, unsigned long index)
+{
+	if (index >= layer->fmt_array_size)
+		return NULL;
+	return layer->fmt_array[index];
+}
+
diff --git a/drivers/media/video/s5p-tv/mixer_vp_layer.c b/drivers/media/video/s5p-tv/mixer_vp_layer.c
new file mode 100644
index 0000000..8776772
--- /dev/null
+++ b/drivers/media/video/s5p-tv/mixer_vp_layer.c
@@ -0,0 +1,206 @@
+/*
+ * Samsung TV Mixer driver
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ *
+ * Tomasz Stanislawski, t.stanislaws@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundiation. either version 2 of the License,
+ * or (at your option) any later version
+ */
+
+#include "mixer.h"
+#include "mixer_reg.h"
+
+#include "regs-vp.h"
+
+#include <media/videobuf2-dma-contig.h>
+
+/* FORMAT DEFINITIONS */
+static const struct mxr_format mxr_fmt_nv12 = {
+	.name = "NV12",
+	.fourcc = V4L2_PIX_FMT_NV12,
+	.num_planes = 2,
+	.plane = {
+		{ .pxWidth = 1, .pxHeight = 1, .bSize = 1 },
+		{ .pxWidth = 2, .pxHeight = 2, .bSize = 2 },
+	},
+	.num_subframes = 1,
+	.hwCode = VP_MODE_NV12 | VP_MODE_MEM_LINEAR,
+};
+
+static const struct mxr_format mxr_fmt_nv21 = {
+	.name = "NV21",
+	.fourcc = V4L2_PIX_FMT_NV21,
+	.num_planes = 2,
+	.plane = {
+		{ .pxWidth = 1, .pxHeight = 1, .bSize = 1 },
+		{ .pxWidth = 2, .pxHeight = 2, .bSize = 2 },
+	},
+	.num_subframes = 1,
+	.hwCode = VP_MODE_NV21 | VP_MODE_MEM_LINEAR,
+};
+
+static const struct mxr_format mxr_fmt_nv12m = {
+	.name = "NV12 (mplane)",
+	.fourcc = V4L2_PIX_FMT_NV12M,
+	.num_planes = 2,
+	.plane = {
+		{ .pxWidth = 1, .pxHeight = 1, .bSize = 1 },
+		{ .pxWidth = 2, .pxHeight = 2, .bSize = 2 },
+	},
+	.num_subframes = 2,
+	.plane2subframe = {0, 1},
+	.hwCode = VP_MODE_NV12 | VP_MODE_MEM_LINEAR,
+};
+
+static const struct mxr_format mxr_fmt_nv12mt = {
+	.name = "NV12 tiled (mplane)",
+	.fourcc = V4L2_PIX_FMT_NV12MT,
+	.num_planes = 2,
+	.plane = {
+		{ .pxWidth = 128, .pxHeight = 32, .bSize = 4096 },
+		{ .pxWidth = 128, .pxHeight = 32, .bSize = 2048 },
+	},
+	.num_subframes = 2,
+	.plane2subframe = {0, 1},
+	.hwCode = VP_MODE_NV12 | VP_MODE_MEM_TILED,
+};
+
+static const struct mxr_format *mxr_video_format[] = {
+	&mxr_fmt_nv12,
+	&mxr_fmt_nv21,
+	&mxr_fmt_nv12m,
+	&mxr_fmt_nv12mt,
+};
+
+/* AUXILIARY CALLBACKS */
+
+static void mxr_vp_layer_release(struct mxr_layer *layer)
+{
+	mxr_base_layer_unregister(layer);
+	mxr_base_layer_release(layer);
+}
+
+static void mxr_vp_buffer_set(struct mxr_layer *layer,
+	struct mxr_buffer *buf)
+{
+	dma_addr_t luma_addr[2] = {0, 0};
+	dma_addr_t chroma_addr[2] = {0, 0};
+	if (buf == NULL) {
+		mxr_reg_vp_buffer(layer->mdev, luma_addr, chroma_addr);
+		return;
+	}
+	luma_addr[0] = vb2_dma_contig_plane_paddr(&buf->vb, 0);
+	if (layer->fmt->num_subframes == 2) {
+		chroma_addr[0] = vb2_dma_contig_plane_paddr(&buf->vb, 1);
+	} else {
+		/* FIXME: mxr_get_plane_size compute integer division,
+		 * which is slow and should not be performed in interrupt */
+		chroma_addr[0] = luma_addr[0] + mxr_get_plane_size(
+			&layer->fmt->plane[0], layer->geo.src.full_width,
+			layer->geo.src.full_height);
+	}
+	if (layer->fmt->hwCode & VP_MODE_MEM_TILED) {
+		luma_addr[1] = luma_addr[0] + 0x40;
+		chroma_addr[1] = chroma_addr[0] + 0x40;
+	} else {
+		luma_addr[1] = luma_addr[0] + layer->geo.src.full_width;
+		chroma_addr[1] = chroma_addr[0];
+	}
+	mxr_reg_vp_buffer(layer->mdev, luma_addr, chroma_addr);
+}
+
+static void mxr_vp_stream_set(struct mxr_layer *layer, int en)
+{
+	mxr_reg_vp_layer_stream(layer->mdev, en);
+}
+
+static void mxr_vp_format_set(struct mxr_layer *layer)
+{
+	mxr_reg_vp_format(layer->mdev, layer->fmt, &layer->geo);
+}
+
+static void mxr_vp_fix_geometry(struct mxr_layer *layer)
+{
+	struct mxr_geometry *geo = &layer->geo;
+	/* align horizontal size to 8 pixels */
+	geo->src.full_width = ALIGN(geo->src.full_width, 8);
+	/* limit to boundary size */
+	geo->src.full_width = clamp_val(geo->src.full_width, 8, 8192);
+	geo->src.full_height = clamp_val(geo->src.full_height, 1, 8192);
+	geo->src.width = clamp_val(geo->src.width, 32, geo->src.full_width);
+	geo->src.width = min(geo->src.width, 2047U);
+	geo->src.height = clamp_val(geo->src.height, 4, geo->src.full_height);
+	geo->src.height = min(geo->src.height, 2047U);
+
+	/* setting size of output window */
+	geo->dst.width = clamp_val(geo->dst.width, 8, geo->dst.full_width);
+	geo->dst.height = clamp_val(geo->dst.height, 1, geo->dst.full_height);
+
+	/* ensure that scaling is in range 1/4x to 16x */
+	if (geo->src.width >= 4 * geo->dst.width)
+		geo->src.width = 4 * geo->dst.width;
+	if (geo->dst.width >= 16 * geo->src.width)
+		geo->dst.width = 16 * geo->src.width;
+	if (geo->src.height >= 4 * geo->dst.height)
+		geo->src.height = 4 * geo->dst.height;
+	if (geo->dst.height >= 16 * geo->src.height)
+		geo->dst.height = 16 * geo->src.height;
+
+	/* setting scaling ratio */
+	geo->x_ratio = (geo->src.width << 16) / geo->dst.width;
+	geo->y_ratio = (geo->src.height << 16) / geo->dst.height;
+
+	/* adjust offsets */
+	geo->src.x_offset = min(geo->src.x_offset,
+		geo->src.full_width - geo->src.width);
+	geo->src.y_offset = min(geo->src.y_offset,
+		geo->src.full_height - geo->src.height);
+	geo->dst.x_offset = min(geo->dst.x_offset,
+		geo->dst.full_width - geo->dst.width);
+	geo->dst.y_offset = min(geo->dst.y_offset,
+		geo->dst.full_height - geo->dst.height);
+}
+
+/* PUBLIC API */
+
+struct mxr_layer *mxr_vp_layer_create(struct mxr_device *mdev, int idx)
+{
+	struct mxr_layer *layer;
+	int ret;
+	struct mxr_layer_ops ops = {
+		.release = mxr_vp_layer_release,
+		.buffer_set = mxr_vp_buffer_set,
+		.stream_set = mxr_vp_stream_set,
+		.format_set = mxr_vp_format_set,
+		.fix_geometry = mxr_vp_fix_geometry,
+	};
+	char name[32];
+
+	sprintf(name, "video%d", idx);
+
+	layer = mxr_base_layer_create(mdev, idx, name, &ops);
+	if (layer == NULL) {
+		mxr_err(mdev, "failed to initialize layer(%d) base\n", idx);
+		goto fail;
+	}
+
+	layer->fmt_array = mxr_video_format;
+	layer->fmt_array_size = ARRAY_SIZE(mxr_video_format);
+
+	ret = mxr_base_layer_register(layer);
+	if (ret)
+		goto fail_layer;
+
+	return layer;
+
+fail_layer:
+	mxr_base_layer_release(layer);
+
+fail:
+	return NULL;
+}
+
diff --git a/drivers/media/video/s5p-tv/regs-hdmi.h b/drivers/media/video/s5p-tv/regs-hdmi.h
new file mode 100644
index 0000000..eedf36d
--- /dev/null
+++ b/drivers/media/video/s5p-tv/regs-hdmi.h
@@ -0,0 +1,1849 @@
+/* linux/arch/arm/mach-exynos4/include/mach/regs-hdmi.h
+ *
+ * Copyright (c) 2010 Samsung Electronics
+ * http://www.samsung.com/
+ *
+ * HDMI register header file for Samsung TVOUT driver
+ *
+ * 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 __ASM_ARCH_REGS_HDMI_H
+
+/*
+ * Register part
+*/
+#define HDMI_CTRL_BASE(x)			(x)
+#define HDMI_BASE(x)				((x) + 0x00010000)
+#define HDMI_SPDIF_BASE(x)			((x) + 0x00030000)
+#define HDMI_I2S_BASE(x)			((x) + 0x00040000)
+#define HDMI_TG_BASE(x)				((x) + 0x00050000)
+#define HDMI_EFUSE_BASE(x)			((x) + 0x00060000)
+
+
+/* Interrupt Control Register */
+#define HDMI_INTC_CON			HDMI_CTRL_BASE(0x0000)
+/* Interrupt Flag Register */
+#define HDMI_INTC_FLAG			HDMI_CTRL_BASE(0x0004)
+/* HDCP KEY Status */
+#define HDMI_HDCP_KEY_LOAD			HDMI_CTRL_BASE(0x0008)
+/* HPD signal */
+#define HDMI_HPD_STATUS			HDMI_CTRL_BASE(0x000C)
+/* Audio system clock selection */
+#define HDMI_AUDIO_CLKSEL			HDMI_CTRL_BASE(0x0010)
+/* HDMI PHY Reset Out */
+#define HDMI_PHY_RSTOUT			HDMI_CTRL_BASE(0x0014)
+/* HDMI PHY VPLL Monitor */
+#define HDMI_PHY_VPLL			HDMI_CTRL_BASE(0x0018)
+/* HDMI PHY CMU Monitor */
+#define HDMI_PHY_CMU			HDMI_CTRL_BASE(0x001C)
+/* HDMI TX Core S/W reset */
+#define HDMI_CORE_RSTOUT			HDMI_CTRL_BASE(0x0020)
+
+/* HDMI System Control Register 0 0x00 */
+#define HDMI_CON_0				HDMI_BASE(0x0000)
+/* HDMI System Control Register 1 0x00 */
+#define HDMI_CON_1				HDMI_BASE(0x0004)
+/* HDMI System Control Register 2. 0x00 */
+#define HDMI_CON_2				HDMI_BASE(0x0008)
+/* HDMI System Status Register 0x00 */
+#define HDMI_SYS_STATUS			HDMI_BASE(0x0010)
+/* HDMI Phy Status */
+#define HDMI_PHY_STATUS			HDMI_BASE(0x0014)
+/* HDMI System Status Enable Register 0x00 */
+#define HDMI_STATUS_EN			HDMI_BASE(0x0020)
+/* Hot Plug Detection Control Register 0x00 */
+#define HDMI_HPD				HDMI_BASE(0x0030)
+/* HDMI/DVI Mode Selection 0x00 */
+#define HDMI_MODE_SEL			HDMI_BASE(0x0040)
+/* HDCP Encryption Enable Register 0x00 */
+#define HDMI_ENC_EN				HDMI_BASE(0x0044)
+
+/* Pixel Values for Blue Screen 0x00 */
+#define HDMI_BLUE_SCREEN_0			HDMI_BASE(0x0050)
+/* Pixel Values for Blue Screen 0x00 */
+#define HDMI_BLUE_SCREEN_1			HDMI_BASE(0x0054)
+/* Pixel Values for Blue Screen 0x00 */
+#define HDMI_BLUE_SCREEN_2			HDMI_BASE(0x0058)
+
+/* Maximum Y (or R,G,B) Pixel Value 0xEB */
+#define HDMI_YMAX				HDMI_BASE(0x0060)
+/* Minimum Y (or R,G,B) Pixel Value 0x10 */
+#define HDMI_YMIN				HDMI_BASE(0x0064)
+/* Maximum Cb/ Cr Pixel Value 0xF0 */
+#define HDMI_CMAX				HDMI_BASE(0x0068)
+/* Minimum Cb/ Cr Pixel Value 0x10 */
+#define HDMI_CMIN				HDMI_BASE(0x006C)
+
+/* Horizontal Blanking Setting 0x00 */
+#define HDMI_H_BLANK_0			HDMI_BASE(0x00A0)
+/* Horizontal Blanking Setting 0x00 */
+#define HDMI_H_BLANK_1			HDMI_BASE(0x00A4)
+/* Vertical Blanking Setting 0x00 */
+#define HDMI_V_BLANK_0			HDMI_BASE(0x00B0)
+/* Vertical Blanking Setting 0x00 */
+#define HDMI_V_BLANK_1			HDMI_BASE(0x00B4)
+/* Vertical Blanking Setting 0x00 */
+#define HDMI_V_BLANK_2			HDMI_BASE(0x00B8)
+/* Hori. Line and Ver. Line 0x00 */
+#define HDMI_H_V_LINE_0			HDMI_BASE(0x00C0)
+/* Hori. Line and Ver. Line 0x00 */
+#define HDMI_H_V_LINE_1			HDMI_BASE(0x00C4)
+/* Hori. Line and Ver. Line 0x00 */
+#define HDMI_H_V_LINE_2			HDMI_BASE(0x00C8)
+
+/* Vertical Sync Polarity Control Register 0x00 */
+#define HDMI_SYNC_MODE			HDMI_BASE(0x00E4)
+/* Vertical Sync Polarity Control Register 0x00 */
+#define HDMI_VSYNC_POL			HDMI_BASE(0x00E4)
+/* Interlace/ Progressive Control Register 0x00 */
+#define HDMI_INT_PRO_MODE			HDMI_BASE(0x00E8)
+
+/* Vertical Blanking Setting for Bottom Field 0x00 */
+#define HDMI_V_BLANK_F_0			HDMI_BASE(0x0110)
+/* Vertical Blanking Setting for Bottom Field 0x00 */
+#define HDMI_V_BLANK_F_1			HDMI_BASE(0x0114)
+/* Vertical Blanking Setting for Bottom Field 0x00 */
+#define HDMI_V_BLANK_F_2			HDMI_BASE(0x0118)
+/* Horizontal Sync Generation Setting 0x00 */
+#define HDMI_H_SYNC_GEN_0			HDMI_BASE(0x0120)
+/* Horizontal Sync Generation Setting 0x00 */
+#define HDMI_H_SYNC_GEN_1			HDMI_BASE(0x0124)
+/* Horizontal Sync Generation Setting 0x00 */
+#define HDMI_H_SYNC_GEN_2			HDMI_BASE(0x0128)
+/* Vertical Sync Generation for Top Field or Frame. 0x01 */
+#define HDMI_V_SYNC_GEN_1_0			HDMI_BASE(0x0130)
+/* Vertical Sync Generation for Top Field or Frame. 0x10 */
+#define HDMI_V_SYNC_GEN_1_1			HDMI_BASE(0x0134)
+/* Vertical Sync Generation for Top Field or Frame. 0x00 */
+#define HDMI_V_SYNC_GEN_1_2			HDMI_BASE(0x0138)
+/* Vertical Sync Generation for Bottom field ? Vertical position. 0x01 */
+#define HDMI_V_SYNC_GEN_2_0			HDMI_BASE(0x0140)
+/* Vertical Sync Generation for Bottom field ? Vertical position. 0x10 */
+#define HDMI_V_SYNC_GEN_2_1			HDMI_BASE(0x0144)
+/* Vertical Sync Generation for Bottom field ? Vertical position. 0x00 */
+#define HDMI_V_SYNC_GEN_2_2			HDMI_BASE(0x0148)
+/* Vertical Sync Generation for Bottom field ? Horizontal position. 0x01 */
+#define HDMI_V_SYNC_GEN_3_0			HDMI_BASE(0x0150)
+/* Vertical Sync Generation for Bottom field ? Horizontal position. 0x10 */
+#define HDMI_V_SYNC_GEN_3_1			HDMI_BASE(0x0154)
+/* Vertical Sync Generation for Bottom field ? Horizontal position. 0x00 */
+#define HDMI_V_SYNC_GEN_3_2			HDMI_BASE(0x0158)
+
+/* ASP Packet Control Register 0x00 */
+#define HDMI_ASP_CON			HDMI_BASE(0x0160)
+/* ASP Packet sp_flat Bit Control 0x00 */
+#define HDMI_ASP_SP_FLAT			HDMI_BASE(0x0164)
+/* ASP Audio Channel Configuration 0x04 */
+#define HDMI_ASP_CHCFG0			HDMI_BASE(0x0170)
+/* ASP Audio Channel Configuration 0x1A */
+#define HDMI_ASP_CHCFG1			HDMI_BASE(0x0174)
+/* ASP Audio Channel Configuration 0x2C */
+#define HDMI_ASP_CHCFG2			HDMI_BASE(0x0178)
+/* ASP Audio Channel Configuration 0x3E */
+#define HDMI_ASP_CHCFG3			HDMI_BASE(0x017C)
+
+/* ACR Packet Control Register 0x00 */
+#define HDMI_ACR_CON			HDMI_BASE(0x0180)
+/* Measured CTS Value 0x01 */
+#define HDMI_ACR_MCTS0			HDMI_BASE(0x0184)
+/* Measured CTS Value 0x00 */
+#define HDMI_ACR_MCTS1			HDMI_BASE(0x0188)
+/* Measured CTS Value 0x00 */
+#define HDMI_ACR_MCTS2			HDMI_BASE(0x018C)
+/* CTS Value for Fixed CTS Transmission Mode. 0xE8 */
+#define HDMI_ACR_CTS0			HDMI_BASE(0x0190)
+/* CTS Value for Fixed CTS Transmission Mode. 0x03 */
+#define HDMI_ACR_CTS1			HDMI_BASE(0x0194)
+/* CTS Value for Fixed CTS Transmission Mode. 0x00 */
+#define HDMI_ACR_CTS2			HDMI_BASE(0x0198)
+/* N Value for ACR Packet. 0xE8 */
+#define HDMI_ACR_N0				HDMI_BASE(0x01A0)
+/* N Value for ACR Packet. 0x03 */
+#define HDMI_ACR_N1				HDMI_BASE(0x01A4)
+/* N Value for ACR Packet. 0x00 */
+#define HDMI_ACR_N2				HDMI_BASE(0x01A8)
+/* Altenate LSB for Fixed CTS Transmission Mode 0x00 */
+#define HDMI_ACR_LSB2			HDMI_BASE(0x01B0)
+/* Number of ACR Packet Transmission per frame 0x1F */
+#define HDMI_ACR_TXCNT			HDMI_BASE(0x01B4)
+/* Interval for ACR Packet Transmission 0x63 */
+#define HDMI_ACR_TXINTERVAL			HDMI_BASE(0x01B8)
+/* CTS Offset for Measured CTS mode. 0x00 */
+#define HDMI_ACR_CTS_OFFSET			HDMI_BASE(0x01BC)
+
+/* ACR Packet Control register 0x00 */
+#define HDMI_GCP_CON			HDMI_BASE(0x01C0)
+/* GCP Packet Body 0x00 */
+#define HDMI_GCP_BYTE1			HDMI_BASE(0x01D0)
+/* GCP Packet Body 0x01 */
+#define HDMI_GCP_BYTE2			HDMI_BASE(0x01D4)
+/* GCP Packet Body 0x02 */
+#define HDMI_GCP_BYTE3			HDMI_BASE(0x01D8)
+
+/* ACP Packet Control register 0x00 */
+#define HDMI_ACP_CON			HDMI_BASE(0x01E0)
+/* ACP Packet Header 0x00 */
+#define HDMI_ACP_TYPE			HDMI_BASE(0x01E4)
+
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA0			HDMI_BASE(0x0200)
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA1			HDMI_BASE(0x0204)
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA2			HDMI_BASE(0x0208)
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA3			HDMI_BASE(0x020c)
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA4			HDMI_BASE(0x0210)
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA5			HDMI_BASE(0x0214)
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA6			HDMI_BASE(0x0218)
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA7			HDMI_BASE(0x021c)
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA8			HDMI_BASE(0x0220)
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA9			HDMI_BASE(0x0224)
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA10			HDMI_BASE(0x0228)
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA11			HDMI_BASE(0x022c)
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA12			HDMI_BASE(0x0230)
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA13			HDMI_BASE(0x0234)
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA14			HDMI_BASE(0x0238)
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA15			HDMI_BASE(0x023c)
+/* ACP Packet Body 0x00 */
+#define HDMI_ACP_DATA16			HDMI_BASE(0x0240)
+
+/* ACR Packet Control Register 0x00 */
+#define HDMI_ISRC_CON			HDMI_BASE(0x0250)
+/* ISCR1 Packet Header 0x00 */
+#define HDMI_ISRC1_HEADER1			HDMI_BASE(0x0264)
+
+/* ISRC1 Packet Body 0x00 */
+#define HDMI_ISRC1_DATA0			HDMI_BASE(0x0270)
+/* ISRC1 Packet Body 0x00 */
+#define HDMI_ISRC1_DATA1			HDMI_BASE(0x0274)
+/* ISRC1 Packet Body 0x00 */
+#define HDMI_ISRC1_DATA2			HDMI_BASE(0x0278)
+/* ISRC1 Packet Body 0x00 */
+#define HDMI_ISRC1_DATA3			HDMI_BASE(0x027c)
+/* ISRC1 Packet Body 0x00 */
+#define HDMI_ISRC1_DATA4			HDMI_BASE(0x0280)
+/* ISRC1 Packet Body 0x00 */
+#define HDMI_ISRC1_DATA5			HDMI_BASE(0x0284)
+/* ISRC1 Packet Body 0x00 */
+#define HDMI_ISRC1_DATA6			HDMI_BASE(0x0288)
+/* ISRC1 Packet Body 0x00 */
+#define HDMI_ISRC1_DATA7			HDMI_BASE(0x028c)
+/* ISRC1 Packet Body 0x00 */
+#define HDMI_ISRC1_DATA8			HDMI_BASE(0x0290)
+/* ISRC1 Packet Body 0x00 */
+#define HDMI_ISRC1_DATA9			HDMI_BASE(0x0294)
+/* ISRC1 Packet Body 0x00 */
+#define HDMI_ISRC1_DATA10			HDMI_BASE(0x0298)
+/* ISRC1 Packet Body 0x00 */
+#define HDMI_ISRC1_DATA11			HDMI_BASE(0x029c)
+/* ISRC1 Packet Body 0x00 */
+#define HDMI_ISRC1_DATA12			HDMI_BASE(0x02a0)
+/* ISRC1 Packet Body 0x00 */
+#define HDMI_ISRC1_DATA13			HDMI_BASE(0x02a4)
+/* ISRC1 Packet Body 0x00 */
+#define HDMI_ISRC1_DATA14			HDMI_BASE(0x02a8)
+/* ISRC1 Packet Body 0x00 */
+#define HDMI_ISRC1_DATA15			HDMI_BASE(0x02ac)
+
+/* ISRC2 Packet Body 0x00 */
+#define HDMI_ISRC2_DATA0			HDMI_BASE(0x02b0)
+/* ISRC2 Packet Body 0x00 */
+#define HDMI_ISRC2_DATA1			HDMI_BASE(0x02b4)
+/* ISRC2 Packet Body 0x00 */
+#define HDMI_ISRC2_DATA2			HDMI_BASE(0x02b8)
+/* ISRC2 Packet Body 0x00 */
+#define HDMI_ISRC2_DATA3			HDMI_BASE(0x02bc)
+/* ISRC2 Packet Body 0x00 */
+#define HDMI_ISRC2_DATA4			HDMI_BASE(0x02c0)
+/* ISRC2 Packet Body 0x00 */
+#define HDMI_ISRC2_DATA5			HDMI_BASE(0x02c4)
+/* ISRC2 Packet Body 0x00 */
+#define HDMI_ISRC2_DATA6			HDMI_BASE(0x02c8)
+/* ISRC2 Packet Body 0x00 */
+#define HDMI_ISRC2_DATA7			HDMI_BASE(0x02cc)
+/* ISRC2 Packet Body 0x00 */
+#define HDMI_ISRC2_DATA8			HDMI_BASE(0x02d0)
+/* ISRC2 Packet Body 0x00 */
+#define HDMI_ISRC2_DATA9			HDMI_BASE(0x02d4)
+/* ISRC2 Packet Body 0x00 */
+#define HDMI_ISRC2_DATA10			HDMI_BASE(0x02d8)
+/* ISRC2 Packet Body 0x00 */
+#define HDMI_ISRC2_DATA11			HDMI_BASE(0x02dc)
+/* ISRC2 Packet Body 0x00 */
+#define HDMI_ISRC2_DATA12			HDMI_BASE(0x02e0)
+/* ISRC2 Packet Body 0x00 */
+#define HDMI_ISRC2_DATA13			HDMI_BASE(0x02e4)
+/* ISRC2 Packet Body 0x00 */
+#define HDMI_ISRC2_DATA14			HDMI_BASE(0x02e8)
+/* ISRC2 Packet Body 0x00 */
+#define HDMI_ISRC2_DATA15			HDMI_BASE(0x02ec)
+
+/* AVI Packet Control Register 0x00 */
+#define HDMI_AVI_CON			HDMI_BASE(0x0300)
+/* AVI Packet Checksum 0x00 */
+#define HDMI_AVI_CHECK_SUM			HDMI_BASE(0x0310)
+
+/* AVI Packet Body 0x00 */
+#define HDMI_AVI_BYTE1			HDMI_BASE(0x0320)
+/* AVI Packet Body 0x00 */
+#define HDMI_AVI_BYTE2			HDMI_BASE(0x0324)
+/* AVI Packet Body 0x00 */
+#define HDMI_AVI_BYTE3			HDMI_BASE(0x0328)
+/* AVI Packet Body 0x00 */
+#define HDMI_AVI_BYTE4			HDMI_BASE(0x032c)
+/* AVI Packet Body 0x00 */
+#define HDMI_AVI_BYTE5			HDMI_BASE(0x0330)
+/* AVI Packet Body 0x00 */
+#define HDMI_AVI_BYTE6			HDMI_BASE(0x0334)
+/* AVI Packet Body 0x00 */
+#define HDMI_AVI_BYTE7			HDMI_BASE(0x0338)
+/* AVI Packet Body 0x00 */
+#define HDMI_AVI_BYTE8			HDMI_BASE(0x033c)
+/* AVI Packet Body 0x00 */
+#define HDMI_AVI_BYTE9			HDMI_BASE(0x0340)
+/* AVI Packet Body 0x00 */
+#define HDMI_AVI_BYTE10			HDMI_BASE(0x0344)
+/* AVI Packet Body 0x00 */
+#define HDMI_AVI_BYTE11			HDMI_BASE(0x0348)
+/* AVI Packet Body 0x00 */
+#define HDMI_AVI_BYTE12			HDMI_BASE(0x034c)
+/* AVI Packet Body 0x00  */
+#define HDMI_AVI_BYTE13			HDMI_BASE(0x0350)
+
+/* AUI Packet Control Register 0x00 */
+#define HDMI_AUI_CON			HDMI_BASE(0x0360)
+/* AUI Packet Checksum 0x00 */
+#define HDMI_AUI_CHECK_SUM			HDMI_BASE(0x0370)
+
+/* AUI Packet Body 0x00 */
+#define HDMI_AUI_BYTE1			HDMI_BASE(0x0380)
+/* AUI Packet Body 0x00 */
+#define HDMI_AUI_BYTE2			HDMI_BASE(0x0384)
+/* AUI Packet Body 0x00 */
+#define HDMI_AUI_BYTE3			HDMI_BASE(0x0388)
+/* AUI Packet Body 0x00 */
+#define HDMI_AUI_BYTE4			HDMI_BASE(0x038c)
+/* AUI Packet Body 0x00 */
+#define HDMI_AUI_BYTE5			HDMI_BASE(0x0390)
+
+/* ACR Packet Control Register 0x00 */
+#define HDMI_MPG_CON			HDMI_BASE(0x03A0)
+/* MPG Packet Checksum 0x00 */
+#define HDMI_MPG_CHECK_SUM			HDMI_BASE(0x03B0)
+
+/* MPEG Packet Body 0x00 */
+#define HDMI_MPEG_BYTE1			HDMI_BASE(0x03c0)
+/* MPEG Packet Body 0x00 */
+#define HDMI_MPEG_BYTE2			HDMI_BASE(0x03c4)
+/* MPEG Packet Body 0x00 */
+#define HDMI_MPEG_BYTE3			HDMI_BASE(0x03c8)
+/* MPEG Packet Body 0x00 */
+#define HDMI_MPEG_BYTE4			HDMI_BASE(0x03cc)
+/* MPEG Packet Body 0x00 */
+#define HDMI_MPEG_BYTE5			HDMI_BASE(0x03d0)
+
+/* SPD Packet Control Register 0x00 */
+#define HDMI_SPD_CON			HDMI_BASE(0x0400)
+/* SPD Packet Header 0x00 */
+#define HDMI_SPD_HEADER0			HDMI_BASE(0x0410)
+/* SPD Packet Header 0x00 */
+#define HDMI_SPD_HEADER1			HDMI_BASE(0x0414)
+/* SPD Packet Header 0x00 */
+#define HDMI_SPD_HEADER2			HDMI_BASE(0x0418)
+
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA0			HDMI_BASE(0x0420)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA1			HDMI_BASE(0x0424)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA2			HDMI_BASE(0x0428)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA3			HDMI_BASE(0x042c)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA4			HDMI_BASE(0x0430)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA5			HDMI_BASE(0x0434)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA6			HDMI_BASE(0x0438)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA7			HDMI_BASE(0x043c)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA8			HDMI_BASE(0x0440)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA9			HDMI_BASE(0x0444)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA10			HDMI_BASE(0x0448)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA11			HDMI_BASE(0x044c)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA12			HDMI_BASE(0x0450)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA13			HDMI_BASE(0x0454)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA14			HDMI_BASE(0x0458)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA15			HDMI_BASE(0x045c)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA16			HDMI_BASE(0x0460)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA17			HDMI_BASE(0x0464)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA18			HDMI_BASE(0x0468)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA19			HDMI_BASE(0x046c)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA20			HDMI_BASE(0x0470)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA21			HDMI_BASE(0x0474)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA22			HDMI_BASE(0x0478)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA23			HDMI_BASE(0x048c)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA24			HDMI_BASE(0x0480)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA25			HDMI_BASE(0x0484)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA26			HDMI_BASE(0x0488)
+/* SPD Packet Body 0x00 */
+#define HDMI_SPD_DATA27			HDMI_BASE(0x048c)
+
+/* SHA-1 Value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_0_0		HDMI_BASE(0x0600)
+/* SHA-1 Value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_0_1		HDMI_BASE(0x0604)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_0_2		HDMI_BASE(0x0608)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_0_3		HDMI_BASE(0x060C)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_1_0		HDMI_BASE(0x0610)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_1_1		HDMI_BASE(0x0614)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_1_2		HDMI_BASE(0x0618)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_1_3		HDMI_BASE(0x061C)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_2_0		HDMI_BASE(0x0620)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_2_1		HDMI_BASE(0x0624)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_2_2		HDMI_BASE(0x0628)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_2_3		HDMI_BASE(0x062C)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_3_0		HDMI_BASE(0x0630)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_3_1		HDMI_BASE(0x0634)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_3_2		HDMI_BASE(0x0638)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_3_3		HDMI_BASE(0x063C)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_4_0		HDMI_BASE(0x0640)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_4_1		HDMI_BASE(0x0644)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_4_2		HDMI_BASE(0x0648)
+/* SHA-1 value from Repeater 0x00 */
+#define HDMI_HDCP_RX_SHA1_4_3		HDMI_BASE(0x064C)
+
+/* Receiver KSV 0 0x00 */
+#define HDMI_HDCP_RX_KSV_0_0		HDMI_BASE(0x0650)
+/* Receiver KSV 0 0x00 */
+#define HDMI_HDCP_RX_KSV_0_1		HDMI_BASE(0x0654)
+/* Receiver KSV 0 0x00 */
+#define HDMI_HDCP_RX_KSV_0_2		HDMI_BASE(0x0658)
+/* Receiver KSV 0 0x00 */
+#define HDMI_HDCP_RX_KSV_0_3		HDMI_BASE(0x065C)
+/* Receiver KSV 1 0x00 */
+#define HDMI_HDCP_RX_KSV_0_4		HDMI_BASE(0x0660)
+
+/* Receiver KSV 1 0x00 */
+#define HDMI_HDCP_KSV_LIST_CON		HDMI_BASE(0x0664)
+/* 2nd authentication status 0x00 */
+#define HDMI_HDCP_SHA_RESULT		HDMI_BASE(0x0670)
+/* HDCP Control 0x00 */
+#define HDMI_HDCP_CTRL1			HDMI_BASE(0x0680)
+/* HDCP Control 0x00 */
+#define HDMI_HDCP_CTRL2			HDMI_BASE(0x0684)
+/* HDCP Ri, Pj, V result 0x00 */
+#define HDMI_HDCP_CHECK_RESULT		HDMI_BASE(0x0690)
+
+/* Receiver BKSV 0x00 */
+#define HDMI_HDCP_BKSV_0_0			HDMI_BASE(0x06A0)
+/* Receiver BKSV 0x00 */
+#define HDMI_HDCP_BKSV_0_1			HDMI_BASE(0x06A4)
+/* Receiver BKSV 0x00 */
+#define HDMI_HDCP_BKSV_0_2			HDMI_BASE(0x06A8)
+/* Receiver BKSV 0x00 */
+#define HDMI_HDCP_BKSV_0_3			HDMI_BASE(0x06AC)
+/* Receiver BKSV 0x00 */
+#define HDMI_HDCP_BKSV_1			HDMI_BASE(0x06B0)
+
+/* Transmitter AKSV 0x00 */
+#define HDMI_HDCP_AKSV_0_0			HDMI_BASE(0x06C0)
+/* Transmitter AKSV 0x00 */
+#define HDMI_HDCP_AKSV_0_1			HDMI_BASE(0x06C4)
+/* Transmitter AKSV 0x00 */
+#define HDMI_HDCP_AKSV_0_2			HDMI_BASE(0x06C8)
+/* Transmitter AKSV 0x00 */
+#define HDMI_HDCP_AKSV_0_3			HDMI_BASE(0x06CC)
+/* Transmitter AKSV 0x00 */
+#define HDMI_HDCP_AKSV_1			HDMI_BASE(0x06D0)
+
+/* Transmitter An 0x00 */
+#define HDMI_HDCP_An_0_0			HDMI_BASE(0x06E0)
+/* Transmitter An 0x00 */
+#define HDMI_HDCP_An_0_1			HDMI_BASE(0x06E4)
+/* Transmitter An 0x00 */
+#define HDMI_HDCP_An_0_2			HDMI_BASE(0x06E8)
+/* Transmitter An 0x00 */
+#define HDMI_HDCP_An_0_3			HDMI_BASE(0x06EC)
+/* Transmitter An 0x00 */
+#define HDMI_HDCP_An_1_0			HDMI_BASE(0x06F0)
+/* Transmitter An 0x00 */
+#define HDMI_HDCP_An_1_1			HDMI_BASE(0x06F4)
+/* Transmitter An 0x00 */
+#define HDMI_HDCP_An_1_2			HDMI_BASE(0x06F8)
+/* Transmitter An 0x00 */
+#define HDMI_HDCP_An_1_3			HDMI_BASE(0x06FC)
+
+/* Receiver BCAPS 0x00 */
+#define HDMI_HDCP_BCAPS			HDMI_BASE(0x0700)
+/* Receiver BSTATUS 0x00 */
+#define HDMI_HDCP_BSTATUS_0			HDMI_BASE(0x0710)
+/* Receiver BSTATUS 0x00 */
+#define HDMI_HDCP_BSTATUS_1			HDMI_BASE(0x0714)
+/* Transmitter Ri 0x00 */
+#define HDMI_HDCP_Ri_0			HDMI_BASE(0x0740)
+/* Transmitter Ri 0x00 */
+#define HDMI_HDCP_Ri_1			HDMI_BASE(0x0744)
+
+/* HDCP I2C interrupt status */
+#define HDMI_HDCP_I2C_INT			HDMI_BASE(0x0780)
+/* HDCP An interrupt status */
+#define HDMI_HDCP_AN_INT			HDMI_BASE(0x0790)
+/* HDCP Watchdog interrupt status */
+#define HDMI_HDCP_WDT_INT			HDMI_BASE(0x07a0)
+/* HDCP RI interrupt status */
+#define HDMI_HDCP_RI_INT			HDMI_BASE(0x07b0)
+
+/* HDCP Ri Interrupt Frame number index register 0 */
+#define HDMI_HDCP_RI_COMPARE_0		HDMI_BASE(0x07d0)
+/* HDCP Ri Interrupt Frame number index register 1 */
+#define HDMI_HDCP_RI_COMPARE_1		HDMI_BASE(0x07d4)
+/* Current value of the frame count index in the hardware */
+#define HDMI_HDCP_FRAME_COUNT		HDMI_BASE(0x07e0)
+
+/* Gamut Metadata packet transmission control register */
+#define HDMI_GAMUT_CON			HDMI_BASE(0x0500)
+/* Gamut metadata packet header */
+#define HDMI_GAMUT_HEADER0			HDMI_BASE(0x0504)
+/* Gamut metadata packet header */
+#define HDMI_GAMUT_HEADER1			HDMI_BASE(0x0508)
+/* Gamut metadata packet header */
+#define HDMI_GAMUT_HEADER2			HDMI_BASE(0x050c)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA00			HDMI_BASE(0x0510)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA01			HDMI_BASE(0x0514)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA02			HDMI_BASE(0x0518)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA03			HDMI_BASE(0x051c)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA04			HDMI_BASE(0x0520)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA05			HDMI_BASE(0x0524)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA06			HDMI_BASE(0x0528)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA07			HDMI_BASE(0x052c)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA08			HDMI_BASE(0x0530)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA09			HDMI_BASE(0x0534)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA10			HDMI_BASE(0x0538)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA11			HDMI_BASE(0x053c)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA12			HDMI_BASE(0x0540)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA13			HDMI_BASE(0x0544)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA14			HDMI_BASE(0x0548)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA15			HDMI_BASE(0x054c)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA16			HDMI_BASE(0x0550)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA17			HDMI_BASE(0x0554)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA18			HDMI_BASE(0x0558)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA19			HDMI_BASE(0x055c)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA20			HDMI_BASE(0x0560)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA21			HDMI_BASE(0x0564)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA22			HDMI_BASE(0x0568)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA23			HDMI_BASE(0x056c)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA24			HDMI_BASE(0x0570)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA25			HDMI_BASE(0x0574)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA26			HDMI_BASE(0x0578)
+/* Gamut Metadata packet body data */
+#define HDMI_GAMUT_DATA27			HDMI_BASE(0x057c)
+
+/* Gamut Metadata packet body data */
+#define	HDMI_DC_CONTROL			HDMI_BASE(0x05C0)
+/* Gamut Metadata packet body data */
+#define HDMI_VIDEO_PATTERN_GEN		HDMI_BASE(0x05C4)
+/* Gamut Metadata packet body data */
+#define HDMI_HPD_GEN			HDMI_BASE(0x05C8)
+
+
+/* SPDIFIN_CLK_CTRL [1:0] 0x02 */
+#define HDMI_SPDIFIN_CLK_CTRL		HDMI_SPDIF_BASE(0x0000)
+/* SPDIFIN_OP_CTRL [1:0] 0x00 */
+#define HDMI_SPDIFIN_OP_CTRL		HDMI_SPDIF_BASE(0x0004)
+/* SPDIFIN_IRQ_MASK[7:0] 0x00 */
+#define HDMI_SPDIFIN_IRQ_MASK		HDMI_SPDIF_BASE(0x0008)
+/* SPDIFIN_IRQ_STATUS [7:0] 0x00 */
+#define HDMI_SPDIFIN_IRQ_STATUS		HDMI_SPDIF_BASE(0x000C)
+/* SPDIFIN_CONFIG [7:0] 0x00 */
+#define HDMI_SPDIFIN_CONFIG_1		HDMI_SPDIF_BASE(0x0010)
+/* SPDIFIN_CONFIG [11:8] 0x00 */
+#define HDMI_SPDIFIN_CONFIG_2		HDMI_SPDIF_BASE(0x0014)
+/* SPDIFIN_USER_VALUE [7:0] 0x00 */
+#define HDMI_SPDIFIN_USER_VALUE_1		HDMI_SPDIF_BASE(0x0020)
+/* SPDIFIN_USER_VALUE [15:8] 0x00 */
+#define HDMI_SPDIFIN_USER_VALUE_2		HDMI_SPDIF_BASE(0x0024)
+/* SPDIFIN_USER_VALUE [23:16] 0x00 */
+#define HDMI_SPDIFIN_USER_VALUE_3		HDMI_SPDIF_BASE(0x0028)
+/* SPDIFIN_USER_VALUE [31:24] 0x00 */
+#define HDMI_SPDIFIN_USER_VALUE_4		HDMI_SPDIF_BASE(0x002C)
+/* SPDIFIN_CH_STATUS_0 [7:0] 0x00 */
+#define HDMI_SPDIFIN_CH_STATUS_0_1		HDMI_SPDIF_BASE(0x0030)
+/* SPDIFIN_CH_STATUS_0 [15:8] 0x00 */
+#define HDMI_SPDIFIN_CH_STATUS_0_2		HDMI_SPDIF_BASE(0x0034)
+/* SPDIFIN_CH_STATUS_0 [23:16] 0x00 */
+#define HDMI_SPDIFIN_CH_STATUS_0_3		HDMI_SPDIF_BASE(0x0038)
+/* SPDIFIN_CH_STATUS_0 [31:24] 0x00 */
+#define HDMI_SPDIFIN_CH_STATUS_0_4		HDMI_SPDIF_BASE(0x003C)
+/* SPDIFIN_CH_STATUS_1 0x00 */
+#define HDMI_SPDIFIN_CH_STATUS_1		HDMI_SPDIF_BASE(0x0040)
+/* SPDIF_FRAME_PERIOD [7:0] 0x00 */
+#define HDMI_SPDIFIN_FRAME_PERIOD_1		HDMI_SPDIF_BASE(0x0048)
+/* SPDIF_FRAME_PERIOD [15:8] 0x00 */
+#define HDMI_SPDIFIN_FRAME_PERIOD_2		HDMI_SPDIF_BASE(0x004C)
+/* SPDIFIN_Pc_INFO [7:0] 0x00 */
+#define HDMI_SPDIFIN_Pc_INFO_1		HDMI_SPDIF_BASE(0x0050)
+/* SPDIFIN_Pc_INFO [15:8] 0x00 */
+#define HDMI_SPDIFIN_Pc_INFO_2		HDMI_SPDIF_BASE(0x0054)
+/* SPDIFIN_Pd_INFO [7:0] 0x00 */
+#define HDMI_SPDIFIN_Pd_INFO_1		HDMI_SPDIF_BASE(0x0058)
+/* SPDIFIN_Pd_INFO [15:8] 0x00 */
+#define HDMI_SPDIFIN_Pd_INFO_2		HDMI_SPDIF_BASE(0x005C)
+/* SPDIFIN_DATA_BUF_0 [7:0] 0x00 */
+#define HDMI_SPDIFIN_DATA_BUF_0_1		HDMI_SPDIF_BASE(0x0060)
+/* SPDIFIN_DATA_BUF_0 [15:8] 0x00 */
+#define HDMI_SPDIFIN_DATA_BUF_0_2		HDMI_SPDIF_BASE(0x0064)
+/* SPDIFIN_DATA_BUF_0 [23:16] 0x00 */
+#define HDMI_SPDIFIN_DATA_BUF_0_3		HDMI_SPDIF_BASE(0x0068)
+/* SPDIFIN_DATA_BUF_0 [31:28] 0x00 */
+#define HDMI_SPDIFIN_USER_BUF_0		HDMI_SPDIF_BASE(0x006C)
+/* SPDIFIN_DATA_BUF_1 [7:0] 0x00 */
+#define HDMI_SPDIFIN_DATA_BUF_1_1		HDMI_SPDIF_BASE(0x0070)
+/* SPDIFIN_DATA_BUF_1 [15:8] 0x00 */
+#define HDMI_SPDIFIN_DATA_BUF_1_2		HDMI_SPDIF_BASE(0x0074)
+/* SPDIFIN_DATA_BUF_1 [23:16] 0x00 */
+#define HDMI_SPDIFIN_DATA_BUF_1_3		HDMI_SPDIF_BASE(0x0078)
+/* SPDIFIN_DATA_BUF_1 [31:28] 0x00 */
+#define HDMI_SPDIFIN_USER_BUF_1		HDMI_SPDIF_BASE(0x007C)
+
+
+/* I2S Clock Enable Register0x00  */
+#define HDMI_I2S_CLK_CON			HDMI_I2S_BASE(0x0000)
+/* I2S Control Register 10x00  */
+#define HDMI_I2S_CON_1			HDMI_I2S_BASE(0x0004)
+/* I2S Control Register 20x00  */
+#define HDMI_I2S_CON_2			HDMI_I2S_BASE(0x0008)
+/* I2S Input Pin Selection Register 0 0x77  */
+#define HDMI_I2S_PIN_SEL_0			HDMI_I2S_BASE(0x000C)
+/* I2S Input Pin Selection Register 1 0x77  */
+#define HDMI_I2S_PIN_SEL_1			HDMI_I2S_BASE(0x0010)
+/* I2S Input Pin Selection Register 2 0x77  */
+#define HDMI_I2S_PIN_SEL_2			HDMI_I2S_BASE(0x0014)
+/* I2S Input Pin Selection Register 30x07  */
+#define HDMI_I2S_PIN_SEL_3			HDMI_I2S_BASE(0x0018)
+/* I2S DSD Control Register0x02  */
+#define HDMI_I2S_DSD_CON			HDMI_I2S_BASE(0x001C)
+/* I2S In/Mux Control Register 0x60  */
+#define HDMI_I2S_MUX_CON			HDMI_I2S_BASE(0x0020)
+/* I2S Channel Status Control Register0x00  */
+#define HDMI_I2S_CH_ST_CON			HDMI_I2S_BASE(0x0024)
+/* I2S Channel Status Block 00x00  */
+#define HDMI_I2S_CH_ST_0			HDMI_I2S_BASE(0x0028)
+/* I2S Channel Status Block 10x00  */
+#define HDMI_I2S_CH_ST_1			HDMI_I2S_BASE(0x002C)
+/* I2S Channel Status Block 20x00  */
+#define HDMI_I2S_CH_ST_2			HDMI_I2S_BASE(0x0030)
+/* I2S Channel Status Block 30x00  */
+#define HDMI_I2S_CH_ST_3			HDMI_I2S_BASE(0x0034)
+/* I2S Channel Status Block 40x00  */
+#define HDMI_I2S_CH_ST_4			HDMI_I2S_BASE(0x0038)
+/* I2S Channel Status Block Shadow Register 00x00  */
+#define HDMI_I2S_CH_ST_SH_0			HDMI_I2S_BASE(0x003C)
+/* I2S Channel Status Block Shadow Register 10x00  */
+#define HDMI_I2S_CH_ST_SH_1			HDMI_I2S_BASE(0x0040)
+/* I2S Channel Status Block Shadow Register 20x00  */
+#define HDMI_I2S_CH_ST_SH_2			HDMI_I2S_BASE(0x0044)
+/* I2S Channel Status Block Shadow Register 30x00  */
+#define HDMI_I2S_CH_ST_SH_3			HDMI_I2S_BASE(0x0048)
+/* I2S Channel Status Block Shadow Register 40x00  */
+#define HDMI_I2S_CH_ST_SH_4			HDMI_I2S_BASE(0x004C)
+/* I2S Audio Sample Validity Register0x00  */
+#define HDMI_I2S_VD_DATA			HDMI_I2S_BASE(0x0050)
+/* I2S Channel Enable Register0x03  */
+#define HDMI_I2S_MUX_CH			HDMI_I2S_BASE(0x0054)
+/* I2S CUV Enable Register0x03  */
+#define HDMI_I2S_MUX_CUV			HDMI_I2S_BASE(0x0058)
+/* I2S Interrupt Request Mask Register0x03  */
+#define HDMI_I2S_IRQ_MASK			HDMI_I2S_BASE(0x005C)
+/* I2S Interrupt Request Status Register0x00  */
+#define HDMI_I2S_IRQ_STATUS			HDMI_I2S_BASE(0x0060)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH0_L_0			HDMI_I2S_BASE(0x0064)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH0_L_1			HDMI_I2S_BASE(0x0068)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH0_L_2			HDMI_I2S_BASE(0x006C)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH0_L_3			HDMI_I2S_BASE(0x0070)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH0_R_0			HDMI_I2S_BASE(0x0074)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH0_R_1			HDMI_I2S_BASE(0x0078)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH0_R_2			HDMI_I2S_BASE(0x007C)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH0_R_3			HDMI_I2S_BASE(0x0080)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH1_L_0			HDMI_I2S_BASE(0x0084)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH1_L_1			HDMI_I2S_BASE(0x0088)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH1_L_2			HDMI_I2S_BASE(0x008C)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH1_L_3			HDMI_I2S_BASE(0x0090)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH1_R_0			HDMI_I2S_BASE(0x0094)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH1_R_1			HDMI_I2S_BASE(0x0098)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH1_R_2			HDMI_I2S_BASE(0x009C)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH1_R_3			HDMI_I2S_BASE(0x00A0)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH2_L_0			HDMI_I2S_BASE(0x00A4)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH2_L_1			HDMI_I2S_BASE(0x00A8)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH2_L_2			HDMI_I2S_BASE(0x00AC)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH2_L_3			HDMI_I2S_BASE(0x00B0)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH2_R_0			HDMI_I2S_BASE(0x00B4)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH2_R_1			HDMI_I2S_BASE(0x00B8)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH2_R_2			HDMI_I2S_BASE(0x00BC)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_Ch2_R_3			HDMI_I2S_BASE(0x00C0)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH3_L_0			HDMI_I2S_BASE(0x00C4)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH3_L_1			HDMI_I2S_BASE(0x00C8)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH3_L_2			HDMI_I2S_BASE(0x00CC)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH3_R_0			HDMI_I2S_BASE(0x00D0)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH3_R_1			HDMI_I2S_BASE(0x00D4)
+/* I2S PCM Output Data Register0x00  */
+#define HDMI_I2S_CH3_R_2			HDMI_I2S_BASE(0x00D8)
+/* I2S CUV Output Data Register0x00  */
+#define HDMI_I2S_CUV_L_R			HDMI_I2S_BASE(0x00DC)
+
+
+/* Command Register 0x00 */
+#define HDMI_TG_CMD				HDMI_TG_BASE(0x0000)
+/* Horizontal Full Size 0x72 */
+#define HDMI_TG_H_FSZ_L			HDMI_TG_BASE(0x0018)
+/* Horizontal Full Size 0x06 */
+#define HDMI_TG_H_FSZ_H			HDMI_TG_BASE(0x001C)
+/* Horizontal Active Start 0x05 */
+#define HDMI_TG_HACT_ST_L			HDMI_TG_BASE(0x0020)
+/* Horizontal Active Start 0x01 */
+#define HDMI_TG_HACT_ST_H			HDMI_TG_BASE(0x0024)
+/* Horizontal Active Size 0x00 */
+#define HDMI_TG_HACT_SZ_L			HDMI_TG_BASE(0x0028)
+/* Horizontal Active Size 0x05 */
+#define HDMI_TG_HACT_SZ_H			HDMI_TG_BASE(0x002C)
+/* Vertical Full Line Size 0xEE */
+#define HDMI_TG_V_FSZ_L			HDMI_TG_BASE(0x0030)
+/* Vertical Full Line Size 0x02 */
+#define HDMI_TG_V_FSZ_H			HDMI_TG_BASE(0x0034)
+/* Vertical Sync Position 0x01 */
+#define HDMI_TG_VSYNC_L			HDMI_TG_BASE(0x0038)
+/* Vertical Sync Position 0x00 */
+#define HDMI_TG_VSYNC_H			HDMI_TG_BASE(0x003C)
+/* Vertical Sync Position for Bottom Field 0x33 */
+#define HDMI_TG_VSYNC2_L			HDMI_TG_BASE(0x0040)
+/* Vertical Sync Position for Bottom Field 0x02 */
+#define HDMI_TG_VSYNC2_H			HDMI_TG_BASE(0x0044)
+/* Vertical Sync Active Start Position 0x1a */
+#define HDMI_TG_VACT_ST_L			HDMI_TG_BASE(0x0048)
+/* Vertical Sync Active Start Position 0x00 */
+#define HDMI_TG_VACT_ST_H			HDMI_TG_BASE(0x004C)
+/* Vertical Active Size 0xd0 */
+#define HDMI_TG_VACT_SZ_L			HDMI_TG_BASE(0x0050)
+/* Vertical Active Size 0x02 */
+#define HDMI_TG_VACT_SZ_H			HDMI_TG_BASE(0x0054)
+/* Field Change Position 0x33 */
+#define HDMI_TG_FIELD_CHG_L			HDMI_TG_BASE(0x0058)
+/* Field Change Position 0x02 */
+#define HDMI_TG_FIELD_CHG_H			HDMI_TG_BASE(0x005C)
+/* Vertical Sync Active Start Position for Bottom Field 0x48 */
+#define HDMI_TG_VACT_ST2_L			HDMI_TG_BASE(0x0060)
+/* Vertical Sync Active Start Position for Bottom Field 0x02 */
+#define HDMI_TG_VACT_ST2_H			HDMI_TG_BASE(0x0064)
+
+/* HDMI Vsync Positon for Top Field 0x01 */
+#define HDMI_TG_VSYNC_TOP_HDMI_L		HDMI_TG_BASE(0x0078)
+/* HDMI Vsync Positon for Top Field 0x00 */
+#define HDMI_TG_VSYNC_TOP_HDMI_H		HDMI_TG_BASE(0x007C)
+/* HDMI Vsync Positon for Bottom Field 0x33 */
+#define HDMI_TG_VSYNC_BOT_HDMI_L		HDMI_TG_BASE(0x0080)
+/* HDMI Vsync Positon for Bottom Field 0x02 */
+#define HDMI_TG_VSYNC_BOT_HDMI_H		HDMI_TG_BASE(0x0084)
+/* HDMI Top Field Start Position 0x01 */
+#define HDMI_TG_FIELD_TOP_HDMI_L		HDMI_TG_BASE(0x0088)
+/* HDMI Top Field Start Position 0x00 */
+#define HDMI_TG_FIELD_TOP_HDMI_H		HDMI_TG_BASE(0x008C)
+/* HDMI Bottom Field Start Position 0x33 */
+#define HDMI_TG_FIELD_BOT_HDMI_L		HDMI_TG_BASE(0x0090)
+/* HDMI Bottom Field Start Position 0x02 */
+#define HDMI_TG_FIELD_BOT_HDMI_H		HDMI_TG_BASE(0x0094)
+
+#define HDMI_EFUSE_CTRL			HDMI_EFUSE_BASE(0x0000)
+#define HDMI_EFUSE_STATUS			HDMI_EFUSE_BASE(0x0004)
+#define HDMI_EFUSE_ADDR_WIDTH		HDMI_EFUSE_BASE(0x0008)
+#define HDMI_EFUSE_SIGDEV_ASSERT		HDMI_EFUSE_BASE(0x000c)
+#define HDMI_EFUSE_SIGDEV_DEASSERT		HDMI_EFUSE_BASE(0x0010)
+#define HDMI_EFUSE_PRCHG_ASSERT		HDMI_EFUSE_BASE(0x0014)
+#define HDMI_EFUSE_PRCHG_DEASSERT		HDMI_EFUSE_BASE(0x0018)
+#define HDMI_EFUSE_FSET_ASSERT		HDMI_EFUSE_BASE(0x001c)
+#define HDMI_EFUSE_FSET_DEASSERT		HDMI_EFUSE_BASE(0x0020)
+#define HDMI_EFUSE_SENSING			HDMI_EFUSE_BASE(0x0024)
+#define HDMI_EFUSE_SCK_ASSERT		HDMI_EFUSE_BASE(0x0028)
+#define HDMI_EFUSE_SCK_DEASSERT		HDMI_EFUSE_BASE(0x002c)
+#define HDMI_EFUSE_SDOUT_OFFSET		HDMI_EFUSE_BASE(0x0030)
+#define HDMI_EFUSE_READ_OFFSET		HDMI_EFUSE_BASE(0x0034)
+
+#define HDMI_AUI_SZ				5
+#define HDMI_GCP_SZ				3
+#define HDMI_SPD_SZ				28
+#define HDMI_AVI_SZ				13
+#define HDMI_MPG_SZ				5
+#define HDMI_GMU_SX				28
+#define HDMI_ISRC_SZ			16
+#define HDMI_ACP_SZ				17
+
+/*
+ * Bit definition part
+ */
+
+/* Control Register */
+
+/* INTC_CON */
+#define HDMI_INTC_ACT_HI			(1 << 7)
+#define HDMI_INTC_ACT_LOW			(0 << 7)
+#define HDMI_INTC_EN_GLOBAL			(1 << 6)
+#define HDMI_INTC_DIS_GLOBAL		(0 << 6)
+#define HDMI_INTC_EN_I2S			(1 << 5)
+#define HDMI_INTC_DIS_I2S			(0 << 5)
+#define HDMI_INTC_EN_CEC			(1 << 4)
+#define HDMI_INTC_DIS_CEC			(0 << 4)
+#define HDMI_INTC_EN_HPD_PLUG		(1 << 3)
+#define HDMI_INTC_DIS_HPD_PLUG		(0 << 3)
+#define HDMI_INTC_EN_HPD_UNPLUG		(1 << 2)
+#define HDMI_INTC_DIS_HPD_UNPLUG		(0 << 2)
+#define HDMI_INTC_EN_SPDIF			(1 << 1)
+#define HDMI_INTC_DIS_SPDIF			(0 << 1)
+#define HDMI_INTC_EN_HDCP			(1 << 0)
+#define HDMI_INTC_DIS_HDCP			(0 << 0)
+
+/* INTC_FLAG */
+#define HDMI_INTC_FLAG_I2S			(1 << 5)
+#define HDMI_INTC_FLAG_CEC			(1 << 4)
+#define HDMI_INTC_FLAG_HPD_PLUG		(1 << 3)
+#define HDMI_INTC_FLAG_HPD_UNPLUG		(1 << 2)
+#define HDMI_INTC_FLAG_SPDIF		(1 << 1)
+#define HDMI_INTC_FLAG_HDCP			(1 << 0)
+
+/* HDCP_KEY_LOAD_DONE */
+#define HDMI_HDCP_KEY_LOAD_DONE		(1 << 0)
+
+/* HPD_STATUS */
+#define HDMI_HPD_PLUGED			(1 << 0)
+
+/* AUDIO_CLKSEL */
+#define HDMI_AUDIO_SPDIF_CLK		(1 << 0)
+#define HDMI_AUDIO_PCLK			(0 << 0)
+
+/* HDMI_PHY_RSTOUT */
+#define HDMI_PHY_SW_RSTOUT			(1 << 0)
+
+/* HDMI_PHY_VPLL */
+#define HDMI_PHY_VPLL_LOCK			(1 << 7)
+#define HDMI_PHY_VPLL_CODE_MASK		(0x7 << 0)
+
+/* HDMI_PHY_CMU */
+#define HDMI_PHY_CMU_LOCK			(1 << 7)
+#define HDMI_PHY_CMU_CODE_MASK		(0x7 << 0)
+
+/* HDMI_CORE_RSTOUT */
+#define HDMI_CORE_SW_RSTOUT			(1 << 0)
+
+
+/* Core Register */
+
+/* HDMI_CON_0 */
+#define HDMI_BLUE_SCR_EN			(1 << 5)
+#define HDMI_BLUE_SCR_DIS			(0 << 5)
+#define HDMI_ENC_OPTION			(1 << 4)
+#define HDMI_ASP_EN				(1 << 2)
+#define HDMI_ASP_DIS			(0 << 2)
+#define HDMI_PWDN_ENB_NORMAL		(1 << 1)
+#define HDMI_PWDN_ENB_PD			(0 << 1)
+#define HDMI_EN				(1 << 0)
+#define HDMI_DIS				(~(1 << 0))
+
+/* HDMI_CON_1 */
+#define HDMI_PX_LMT_CTRL_BYPASS		(0 << 5)
+#define HDMI_PX_LMT_CTRL_RGB		(1 << 5)
+#define HDMI_PX_LMT_CTRL_YPBPR		(2 << 5)
+#define HDMI_PX_LMT_CTRL_RESERVED		(3 << 5)
+/*Not support in S5PV210 */
+#define HDMI_CON_PXL_REP_RATIO_MASK		(1 << 1 | 1 << 0)
+/*Not support in S5PV210 */
+#define HDMI_DOUBLE_PIXEL_REPETITION	(0x01)
+
+/* HDMI_CON_2 */
+#define HDMI_VID_PREAMBLE_EN		(0 << 5)
+#define HDMI_VID_PREAMBLE_DIS		(1 << 5)
+#define HDMI_GUARD_BAND_EN			(0 << 1)
+#define HDMI_GUARD_BAND_DIS			(1 << 1)
+
+/* STATUS */
+#define HDMI_AUTHEN_ACK_AUTH		(1 << 7)
+#define HDMI_AUTHEN_ACK_NOT			(0 << 7)
+#define HDMI_AUD_FIFO_OVF_FULL		(1 << 6)
+#define HDMI_AUD_FIFO_OVF_NOT		(0 << 6)
+#define HDMI_UPDATE_RI_INT_OCC		(1 << 4)
+#define HDMI_UPDATE_RI_INT_NOT		(0 << 4)
+#define HDMI_UPDATE_RI_INT_CLEAR		(1 << 4)
+#define HDMI_UPDATE_PJ_INT_OCC		(1 << 3)
+#define HDMI_UPDATE_PJ_INT_NOT		(0 << 3)
+#define HDMI_UPDATE_PJ_INT_CLEAR		(1 << 3)
+#define HDMI_WRITE_INT_OCC			(1 << 2)
+#define HDMI_WRITE_INT_NOT			(0 << 2)
+#define HDMI_WRITE_INT_CLEAR		(1 << 2)
+#define HDMI_WATCHDOG_INT_OCC		(1 << 1)
+#define HDMI_WATCHDOG_INT_NOT		(0 << 1)
+#define HDMI_WATCHDOG_INT_CLEAR		(1 << 1)
+#define HDMI_WTFORACTIVERX_INT_OCC		(1)
+#define HDMI_WTFORACTIVERX_INT_NOT		(0)
+#define HDMI_WTFORACTIVERX_INT_CLEAR	(1)
+
+/* PHY_STATUS */
+#define HDMI_PHY_STATUS_READY		(1)
+
+/* STATUS_EN */
+#define HDMI_AUD_FIFO_OVF_EN		(1 << 6)
+#define HDMI_AUD_FIFO_OVF_DIS		(0 << 6)
+#define HDMI_UPDATE_RI_INT_EN		(1 << 4)
+#define HDMI_UPDATE_RI_INT_DIS		(0 << 4)
+#define HDMI_UPDATE_PJ_INT_EN		(1 << 3)
+#define HDMI_UPDATE_PJ_INT_DIS		(0 << 3)
+#define HDMI_WRITE_INT_EN			(1 << 2)
+#define HDMI_WRITE_INT_DIS			(0 << 2)
+#define HDMI_WATCHDOG_INT_EN		(1 << 1)
+#define HDMI_WATCHDOG_INT_DIS		(0 << 1)
+#define HDMI_WTFORACTIVERX_INT_EN		(1)
+#define HDMI_WTFORACTIVERX_INT_DIS		(0)
+#define HDMI_INT_EN_ALL				(HDMI_UPDATE_RI_INT_EN|\
+						HDMI_UPDATE_PJ_INT_DIS|\
+						HDMI_WRITE_INT_EN|\
+						HDMI_WATCHDOG_INT_EN|\
+						HDMI_WTFORACTIVERX_INT_EN)
+#define HDMI_INT_DIS_ALL			(~0x1F)
+
+/* HPD */
+#define HDMI_SW_HPD_PLUGGED			(1 << 1)
+#define HDMI_SW_HPD_UNPLUGGED		(0 << 1)
+#define HDMI_HPD_SEL_I_HPD			(1)
+#define HDMI_HPD_SEL_SW_HPD			(0)
+
+/* MODE_SEL */
+#define HDMI_MODE_HDMI_EN			(1 << 1)
+#define HDMI_MODE_HDMI_DIS			(0 << 1)
+#define HDMI_MODE_DVI_EN			(1)
+#define HDMI_MODE_DVI_DIS			(0)
+#define HDMI_MODE_MASK				(3)
+
+/* ENC_EN */
+#define HDMI_HDCP_ENC_ENABLE		(1)
+#define HDMI_HDCP_ENC_DISABLE		(0)
+
+
+/* Video Related Register */
+
+/* BLUESCREEN_0/1/2 */
+#define HDMI_SET_BLUESCREEN_0(x)		((x) & 0xFF)
+#define HDMI_SET_BLUESCREEN_1(x)		((x) & 0xFF)
+#define HDMI_SET_BLUESCREEN_2(x)		((x) & 0xFF)
+
+/* HDMI_YMAX/YMIN/CMAX/CMIN */
+#define HDMI_SET_YMAX(x)			((x) & 0xFF)
+#define HDMI_SET_YMIN(x)			((x) & 0xFF)
+#define HDMI_SET_CMAX(x)			((x) & 0xFF)
+#define HDMI_SET_CMIN(x)			((x) & 0xFF)
+
+/* H_BLANK_0/1 */
+#define HDMI_SET_H_BLANK_0(x)		((x) & 0xFF)
+#define HDMI_SET_H_BLANK_1(x)		(((x) >> 8) & 0x3FF)
+
+/* V_BLANK_0/1/2 */
+#define HDMI_SET_V_BLANK_0(x)		((x) & 0xFF)
+#define HDMI_SET_V_BLANK_1(x)		(((x) >> 8) & 0xFF)
+#define HDMI_SET_V_BLANK_2(x)		(((x) >> 16) & 0xFF)
+
+/* H_V_LINE_0/1/2 */
+#define HDMI_SET_H_V_LINE_0(x)		((x) & 0xFF)
+#define HDMI_SET_H_V_LINE_1(x)		(((x) >> 8) & 0xFF)
+#define HDMI_SET_H_V_LINE_2(x)		(((x) >> 16) & 0xFF)
+
+/* VSYNC_POL */
+#define HDMI_V_SYNC_POL_ACT_LOW		(1)
+#define HDMI_V_SYNC_POL_ACT_HIGH		(0)
+
+/* INT_PRO_MODE */
+#define HDMI_INTERLACE_MODE			(1)
+#define HDMI_PROGRESSIVE_MODE		(0)
+
+/* V_BLANK_F_0/1/2 */
+#define HDMI_SET_V_BLANK_F_0(x)		((x) & 0xFF)
+#define HDMI_SET_V_BLANK_F_1(x)		(((x) >> 8) & 0xFF)
+#define HDMI_SET_V_BLANK_F_2(x)		(((x) >> 16) & 0xFF)
+
+
+/* H_SYNC_GEN_0/1/2 */
+#define HDMI_SET_H_SYNC_GEN_0(x)		((x) & 0xFF)
+#define HDMI_SET_H_SYNC_GEN_1(x)		(((x) >> 8) & 0xFF)
+#define HDMI_SET_H_SYNC_GEN_2(x)		(((x) >> 16) & 0xFF)
+
+
+/* V_SYNC_GEN1_0/1/2 */
+#define HDMI_SET_V_SYNC_GEN1_0(x)		((x) & 0xFF)
+#define HDMI_SET_V_SYNC_GEN1_1(x)		(((x) >> 8) & 0xFF)
+#define HDMI_SET_V_SYNC_GEN1_2(x)		(((x) >> 16) & 0xFF)
+
+/* V_SYNC_GEN2_0/1/2 */
+#define HDMI_SET_V_SYNC_GEN2_0(x)		((x) & 0xFF)
+#define HDMI_SET_V_SYNC_GEN2_1(x)		(((x) >> 8) & 0xFF)
+#define HDMI_SET_V_SYNC_GEN2_2(x)		(((x) >> 16) & 0xFF)
+
+/* V_SYNC_GEN3_0/1/2 */
+#define HDMI_SET_V_SYNC_GEN3_0(x)		((x) & 0xFF)
+#define HDMI_SET_V_SYNC_GEN3_1(x)		(((x) >> 8) & 0xFF)
+#define HDMI_SET_V_SYNC_GEN3_2(x)		(((x) >> 16) & 0xFF)
+
+
+/* Audio Related Packet Register */
+
+/* ASP_CON */
+#define HDMI_AUD_DST_DOUBLE			(1 << 7)
+#define HDMI_AUD_NO_DST_DOUBLE		(0 << 7)
+#define HDMI_AUD_TYPE_SAMPLE		(0 << 5)
+#define HDMI_AUD_TYPE_ONE_BIT		(1 << 5)
+#define HDMI_AUD_TYPE_HBR			(2 << 5)
+#define HDMI_AUD_TYPE_DST			(3 << 5)
+#define HDMI_AUD_MODE_TWO_CH		(0 << 4)
+#define HDMI_AUD_MODE_MULTI_CH		(1 << 4)
+#define HDMI_AUD_SP_AUD3_EN			(1 << 3)
+#define HDMI_AUD_SP_AUD2_EN			(1 << 2)
+#define HDMI_AUD_SP_AUD1_EN			(1 << 1)
+#define HDMI_AUD_SP_AUD0_EN			(1 << 0)
+#define HDMI_AUD_SP_ALL_DIS			(0 << 0)
+
+#define HDMI_AUD_SET_SP_PRE(x)		((x) & 0xF)
+
+/* ASP_SP_FLAT */
+#define HDMI_ASP_SP_FLAT_AUD_SAMPLE		(0)
+
+/* ASP_CHCFG0/1/2/3 */
+#define HDMI_SPK3R_SEL_I_PCM0L		(0 << 27)
+#define HDMI_SPK3R_SEL_I_PCM0R		(1 << 27)
+#define HDMI_SPK3R_SEL_I_PCM1L		(2 << 27)
+#define HDMI_SPK3R_SEL_I_PCM1R		(3 << 27)
+#define HDMI_SPK3R_SEL_I_PCM2L		(4 << 27)
+#define HDMI_SPK3R_SEL_I_PCM2R		(5 << 27)
+#define HDMI_SPK3R_SEL_I_PCM3L		(6 << 27)
+#define HDMI_SPK3R_SEL_I_PCM3R		(7 << 27)
+#define HDMI_SPK3L_SEL_I_PCM0L		(0 << 24)
+#define HDMI_SPK3L_SEL_I_PCM0R		(1 << 24)
+#define HDMI_SPK3L_SEL_I_PCM1L		(2 << 24)
+#define HDMI_SPK3L_SEL_I_PCM1R		(3 << 24)
+#define HDMI_SPK3L_SEL_I_PCM2L		(4 << 24)
+#define HDMI_SPK3L_SEL_I_PCM2R		(5 << 24)
+#define HDMI_SPK3L_SEL_I_PCM3L		(6 << 24)
+#define HDMI_SPK3L_SEL_I_PCM3R		(7 << 24)
+#define HDMI_SPK2R_SEL_I_PCM0L		(0 << 19)
+#define HDMI_SPK2R_SEL_I_PCM0R		(1 << 19)
+#define HDMI_SPK2R_SEL_I_PCM1L		(2 << 19)
+#define HDMI_SPK2R_SEL_I_PCM1R		(3 << 19)
+#define HDMI_SPK2R_SEL_I_PCM2L		(4 << 19)
+#define HDMI_SPK2R_SEL_I_PCM2R		(5 << 19)
+#define HDMI_SPK2R_SEL_I_PCM3L		(6 << 19)
+#define HDMI_SPK2R_SEL_I_PCM3R		(7 << 19)
+#define HDMI_SPK2L_SEL_I_PCM0L		(0 << 16)
+#define HDMI_SPK2L_SEL_I_PCM0R		(1 << 16)
+#define HDMI_SPK2L_SEL_I_PCM1L		(2 << 16)
+#define HDMI_SPK2L_SEL_I_PCM1R		(3 << 16)
+#define HDMI_SPK2L_SEL_I_PCM2L		(4 << 16)
+#define HDMI_SPK2L_SEL_I_PCM2R		(5 << 16)
+#define HDMI_SPK2L_SEL_I_PCM3L		(6 << 16)
+#define HDMI_SPK2L_SEL_I_PCM3R		(7 << 16)
+#define HDMI_SPK1R_SEL_I_PCM0L		(0 << 11)
+#define HDMI_SPK1R_SEL_I_PCM0R		(1 << 11)
+#define HDMI_SPK1R_SEL_I_PCM1L		(2 << 11)
+#define HDMI_SPK1R_SEL_I_PCM1R		(3 << 11)
+#define HDMI_SPK1R_SEL_I_PCM2L		(4 << 11)
+#define HDMI_SPK1R_SEL_I_PCM2R		(5 << 11)
+#define HDMI_SPK1R_SEL_I_PCM3L		(6 << 11)
+#define HDMI_SPK1R_SEL_I_PCM3R		(7 << 11)
+#define HDMI_SPK1L_SEL_I_PCM0L		(0 << 8)
+#define HDMI_SPK1L_SEL_I_PCM0R		(1 << 8)
+#define HDMI_SPK1L_SEL_I_PCM1L		(2 << 8)
+#define HDMI_SPK1L_SEL_I_PCM1R		(3 << 8)
+#define HDMI_SPK1L_SEL_I_PCM2L		(4 << 8)
+#define HDMI_SPK1L_SEL_I_PCM2R		(5 << 8)
+#define HDMI_SPK1L_SEL_I_PCM3L		(6 << 8)
+#define HDMI_SPK1L_SEL_I_PCM3R		(7 << 8)
+#define HDMI_SPK0R_SEL_I_PCM0L		(0 << 3)
+#define HDMI_SPK0R_SEL_I_PCM0R		(1 << 3)
+#define HDMI_SPK0R_SEL_I_PCM1L		(2 << 3)
+#define HDMI_SPK0R_SEL_I_PCM1R		(3 << 3)
+#define HDMI_SPK0R_SEL_I_PCM2L		(4 << 3)
+#define HDMI_SPK0R_SEL_I_PCM2R		(5 << 3)
+#define HDMI_SPK0R_SEL_I_PCM3L		(6 << 3)
+#define HDMI_SPK0R_SEL_I_PCM3R		(7 << 3)
+#define HDMI_SPK0L_SEL_I_PCM0L		(0)
+#define HDMI_SPK0L_SEL_I_PCM0R		(1)
+#define HDMI_SPK0L_SEL_I_PCM1L		(2)
+#define HDMI_SPK0L_SEL_I_PCM1R		(3)
+#define HDMI_SPK0L_SEL_I_PCM2L		(4)
+#define HDMI_SPK0L_SEL_I_PCM2R		(5)
+#define HDMI_SPK0L_SEL_I_PCM3L		(6)
+#define HDMI_SPK0L_SEL_I_PCM3R		(7)
+
+/* ACR_CON */
+#define HDMI_ALT_CTS_RATE_CTS_1		(0 << 3)
+#define HDMI_ALT_CTS_RATE_CTS_11		(1 << 3)
+#define HDMI_ALT_CTS_RATE_CTS_21		(2 << 3)
+#define HDMI_ALT_CTS_RATE_CTS_31		(3 << 3)
+#define HDMI_ACR_TX_MODE_NO_TX		(0)
+#define HDMI_ACR_TX_MODE_TX_ONCE		(1)
+#define HDMI_ACR_TX_MODE_TXCNT_VBI		(2)
+#define HDMI_ACR_TX_MODE_TX_VPC		(3)
+#define HDMI_ACR_TX_MODE_MESURE_CTS		(4)
+
+/* ACR_MCTS0/1/2 */
+#define HDMI_SET_ACR_MCTS_0(x)		((x) & 0xFF)
+#define HDMI_SET_ACR_MCTS_1(x)		(((x) >> 8) & 0xFF)
+#define HDMI_SET_ACR_MCTS_2(x)		(((x) >> 16) & 0xFF)
+
+/* ACR_CTS0/1/2 */
+#define HDMI_SET_ACR_CTS_0(x)		((x) & 0xFF)
+#define HDMI_SET_ACR_CTS_1(x)		(((x) >> 8) & 0xFF)
+#define HDMI_SET_ACR_CTS_2(x)		(((x) >> 16) & 0xFF)
+
+/* ACR_N0/1/2 */
+#define HDMI_SET_ACR_N_0(x)			((x) & 0xFF)
+#define HDMI_SET_ACR_N_1(x)			(((x) >> 8) & 0xFF)
+#define HDMI_SET_ACR_N_2(x)			(((x) >> 16) & 0xFF)
+
+
+/* ACR_LSB2 */
+#define HDMI_ACR_LSB2_MASK			(0xFF)
+
+/* ACR_TXCNT */
+#define HDMI_ACR_TXCNT_MASK			(0x1F)
+
+/* ACR_TXINTERNAL */
+#define HDMI_ACR_TX_INTERNAL_MASK		(0xFF)
+
+/* ACR_CTS_OFFSET */
+#define HDMI_ACR_CTS_OFFSET_MASK		(0xFF)
+
+/* GCP_CON */
+#define HDMI_GCP_CON_EN_1ST_VSYNC		(1 << 3)
+#define HDMI_GCP_CON_EN_2ST_VSYNC		(1 << 2)
+#define HDMI_GCP_CON_TRANS_EVERY_VSYNC	(2)
+#define HDMI_GCP_CON_NO_TRAN		(0)
+#define HDMI_GCP_CON_TRANS_ONCE		(1)
+#define HDMI_GCP_CON_TRANS_EVERY_VSYNC	(2)
+
+/* GCP_BYTE1 */
+#define HDMI_GCP_BYTE1_MASK			(0xFF)
+
+/* GCP_BYTE2 */
+#define HDMI_GCP_BYTE2_PP_MASK		(0xF << 4)
+#define HDMI_GCP_BYTE2_CD_24BPP		(1 << 2)
+/*Not support in S5PV210 */
+#define HDMI_GCP_BYTE2_CD_30BPP		(1 << 0 | 1 << 2)
+/*Not support in S5PV210 */
+#define HDMI_GCP_BYTE2_CD_36BPP		(1 << 1 | 1 << 2)
+/*Not support in S5PV210 */
+#define HDMI_GCP_BYTE2_CD_48BPP		(1 << 0 | 1 << 1 | 1 << 2)
+
+
+/* GCP_BYTE3 */
+#define HDMI_GCP_BYTE3_MASK			(0xFF)
+
+
+/* ACP Packet Register */
+
+/* ACP_CON */
+#define HDMI_ACP_FR_RATE_MASK		(0x1F << 3)
+#define HDMI_ACP_CON_NO_TRAN		(0)
+#define HDMI_ACP_CON_TRANS_ONCE		(1)
+#define HDMI_ACP_CON_TRANS_EVERY_VSYNC	(2)
+
+/* ACP_TYPE */
+#define HDMI_ACP_TYPE_MASK			(0xFF)
+
+/* ACP_DATA00~16 */
+#define HDMI_ACP_DATA_MASK			(0xFF)
+
+
+/* ISRC1/2 Packet Register */
+
+/* ISRC_CON */
+#define HDMI_ISRC_FR_RATE_MASK		(0x1F << 3)
+#define HDMI_ISRC_EN			(1 << 2)
+#define HDMI_ISRC_DIS			(0 << 2)
+
+
+/* ISRC1_HEADER1 */
+#define HDMI_ISRC1_HEADER_MASK		(0xFF)
+
+/* ISRC1_DATA 00~15 */
+#define HDMI_ISRC1_DATA_MASK		(0xFF)
+
+/* ISRC2_DATA 00~15 */
+#define HDMI_ISRC2_DATA_MASK		(0xFF)
+
+
+/* AVI InfoFrame Register */
+
+/* AVI_CON */
+
+/* AVI_CHECK_SUM */
+#define HDMI_SET_AVI_CHECK_SUM(x)		((x) & 0xFF)
+
+/* AVI_DATA01~13 */
+#define HDMI_SET_AVI_DATA(x)		((x) & 0xFF)
+#define HDMI_AVI_PIXEL_REPETITION_DOUBLE	(1<<0)
+#define HDMI_AVI_PICTURE_ASPECT_4_3		(1<<4)
+#define HDMI_AVI_PICTURE_ASPECT_16_9	(1<<5)
+
+
+/* Audio InfoFrame Register */
+
+/* AUI_CON */
+
+/* AUI_CHECK_SUM */
+#define HDMI_SET_AUI_CHECK_SUM(x)		((x) & 0xFF)
+
+/* AUI_DATA1~5 */
+#define HDMI_SET_AUI_DATA(x)		((x) & 0xFF)
+
+
+/* MPEG Source InfoFrame registers */
+
+/* MPG_CON */
+
+/* HDMI_MPG_CHECK_SUM */
+#define HDMI_SET_MPG_CHECK_SUM(x)		((x) & 0xFF)
+
+/* MPG_DATA1~5 */
+#define HDMI_SET_MPG_DATA(x)		((x) & 0xFF)
+
+
+/* Source Product Descriptor Infoframe registers */
+
+/* SPD_CON */
+
+/* SPD_HEADER0/1/2 */
+#define HDMI_SET_SPD_HEADER(x)		((x) & 0xFF)
+
+
+/* SPD_DATA0~27 */
+#define HDMI_SET_SPD_DATA(x)		((x) & 0xFF)
+
+
+/* HDCP Register */
+
+/* HDCP_SHA1_00~19 */
+#define HDMI_SET_HDCP_SHA1(x)		((x) & 0xFF)
+
+/* HDCP_KSV_LIST_0~4 */
+
+/* HDCP_KSV_LIST_CON */
+#define HDMI_HDCP_KSV_WRITE_DONE		(0x1 << 3)
+#define HDMI_HDCP_KSV_LIST_EMPTY		(0x1 << 2)
+#define HDMI_HDCP_KSV_END			(0x1 << 1)
+#define HDMI_HDCP_KSV_READ			(0x1 << 0)
+
+/* HDCP_CTRL1 */
+#define HDMI_HDCP_EN_PJ_EN			(1 << 4)
+#define HDMI_HDCP_EN_PJ_DIS			(~(1 << 4))
+#define HDMI_HDCP_SET_REPEATER_TIMEOUT	(1 << 2)
+#define HDMI_HDCP_CLEAR_REPEATER_TIMEOUT	(~(1 << 2))
+#define HDMI_HDCP_CP_DESIRED_EN		(1 << 1)
+#define HDMI_HDCP_CP_DESIRED_DIS		(~(1 << 1))
+#define HDMI_HDCP_ENABLE_1_1_FEATURE_EN	(1)
+#define HDMI_HDCP_ENABLE_1_1_FEATURE_DIS	(~(1))
+
+/* HDCP_CHECK_RESULT */
+#define HDMI_HDCP_Pi_MATCH_RESULT_Y		((0x1 << 3) | (0x1 << 2))
+#define HDMI_HDCP_Pi_MATCH_RESULT_N		((0x1 << 3) | (0x0 << 2))
+#define HDMI_HDCP_Ri_MATCH_RESULT_Y		((0x1 << 1) | (0x1 << 0))
+#define HDMI_HDCP_Ri_MATCH_RESULT_N		((0x1 << 1) | (0x0 << 0))
+#define HDMI_HDCP_CLR_ALL_RESULTS		(0)
+
+/* HDCP_BKSV0~4 */
+/* HDCP_AKSV0~4 */
+
+/* HDCP_BCAPS */
+#define HDMI_HDCP_BCAPS_REPEATER		(1 << 6)
+#define HDMI_HDCP_BCAPS_READY		(1 << 5)
+#define HDMI_HDCP_BCAPS_FAST		(1 << 4)
+#define HDMI_HDCP_BCAPS_1_1_FEATURES	(1 << 1)
+#define HDMI_HDCP_BCAPS_FAST_REAUTH		(1)
+
+/* HDCP_BSTATUS_0/1 */
+/* HDCP_Ri_0/1 */
+/* HDCP_I2C_INT */
+/* HDCP_AN_INT */
+/* HDCP_WATCHDOG_INT */
+/* HDCP_RI_INT/1 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_1 */
+/* HDCP_Frame_Count */
+
+
+/* Gamut Metadata Packet Register */
+
+/* GAMUT_CON */
+/* GAMUT_HEADER0 */
+/* GAMUT_HEADER1 */
+/* GAMUT_HEADER2 */
+/* GAMUT_METADATA0~27 */
+
+
+/* Video Mode Register */
+
+/* VIDEO_PATTERN_GEN */
+/* HPD_GEN */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+/* HDCP_Ri_Compare_0 */
+
+
+/* SPDIF Register */
+
+/* SPDIFIN_CLK_CTRL */
+#define HDMI_SPDIFIN_READY_CLK_DOWN		(1 << 1)
+#define HDMI_SPDIFIN_CLK_ON			(1)
+
+/* SPDIFIN_OP_CTRL */
+#define HDMI_SPDIFIN_SW_RESET		(0)
+#define HDMI_SPDIFIN_STATUS_CHECK_MODE	(1)
+#define HDMI_SPDIFIN_STATUS_CHK_OP_MODE	(3)
+
+/* SPDIFIN_IRQ_MASK */
+
+/* SPDIFIN_IRQ_STATUS */
+#define HDMI_SPDIFIN_IRQ_OVERFLOW_EN			(1 << 7)
+#define HDMI_SPDIFIN_IRQ_ABNORMAL_PD_EN			(1 << 6)
+#define HDMI_SPDIFIN_IRQ_SH_NOT_DETECTED_RIGHTTIME_EN	(1 << 5)
+#define HDMI_SPDIFIN_IRQ_SH_DETECTED_EN			(1 << 4)
+#define HDMI_SPDIFIN_IRQ_SH_NOT_DETECTED_EN			(1 << 3)
+#define HDMI_SPDIFIN_IRQ_WRONG_PREAMBLE_EN			(1 << 2)
+#define HDMI_SPDIFIN_IRQ_CH_STATUS_RECOVERED_EN		(1 << 1)
+#define HDMI_SPDIFIN_IRQ_WRONG_SIG_EN			(1 << 0)
+
+/* SPDIFIN_CONFIG_1 */
+#define HDMI_SPDIFIN_CFG_FILTER_3_SAMPLE			(0 << 6)
+#define HDMI_SPDIFIN_CFG_FILTER_2_SAMPLE			(1 << 6)
+#define HDMI_SPDIFIN_CFG_LINEAR_PCM_TYPE			(0 << 5)
+#define HDMI_SPDIFIN_CFG_NO_LINEAR_PCM_TYPE			(1 << 5)
+#define HDMI_SPDIFIN_CFG_PCPD_AUTO_SET			(0 << 4)
+#define HDMI_SPDIFIN_CFG_PCPD_MANUAL_SET			(1 << 4)
+#define HDMI_SPDIFIN_CFG_WORD_LENGTH_A_SET			(0 << 3)
+#define HDMI_SPDIFIN_CFG_WORD_LENGTH_M_SET			(1 << 3)
+#define HDMI_SPDIFIN_CFG_U_V_C_P_NEGLECT			(0 << 2)
+#define HDMI_SPDIFIN_CFG_U_V_C_P_REPORT			(1 << 2)
+#define HDMI_SPDIFIN_CFG_BURST_SIZE_1			(0 << 1)
+#define HDMI_SPDIFIN_CFG_BURST_SIZE_2			(1 << 1)
+#define HDMI_SPDIFIN_CFG_DATA_ALIGN_16BIT			(0 << 0)
+#define HDMI_SPDIFIN_CFG_DATA_ALIGN_32BIT			(1 << 0)
+
+/* SPDIFIN_CONFIG_2 */
+#define HDMI_SPDIFIN_CFG2_NO_CLK_DIV			(0)
+
+/* SPDIFIN_USER_VALUE_1 */
+/* SPDIFIN_USER_VALUE_2 */
+/* SPDIFIN_USER_VALUE_3 */
+/* SPDIFIN_USER_VALUE_4 */
+/* SPDIFIN_CH_STATUS_0_1 */
+/* SPDIFIN_CH_STATUS_0_2 */
+/* SPDIFIN_CH_STATUS_0_3 */
+/* SPDIFIN_CH_STATUS_0_4 */
+/* SPDIFIN_CH_STATUS_1 */
+/* SPDIFIN_FRAME_PERIOD_1 */
+/* SPDIFIN_FRAME_PERIOD_2 */
+/* SPDIFIN_PC_INFO_1 */
+/* SPDIFIN_PC_INFO_2 */
+/* SPDIFIN_PD_INFO_1 */
+/* SPDIFIN_PD_INFO_2 */
+/* SPDIFIN_DATA_BUF_0_1 */
+/* SPDIFIN_DATA_BUF_0_2 */
+/* SPDIFIN_DATA_BUF_0_3 */
+/* SPDIFIN_USER_BUF_0 */
+/* SPDIFIN_USER_BUF_1_1 */
+/* SPDIFIN_USER_BUF_1_2 */
+/* SPDIFIN_USER_BUF_1_3 */
+/* SPDIFIN_USER_BUF_1 */
+
+
+/* I2S Register */
+
+/* I2S_CLK_CON */
+#define HDMI_I2S_CLK_DIS			(0)
+#define HDMI_I2S_CLK_EN			(1)
+
+/* I2S_CON_1 */
+#define HDMI_I2S_SCLK_FALLING_EDGE		(0 << 1)
+#define HDMI_I2S_SCLK_RISING_EDGE		(1 << 1)
+#define HDMI_I2S_L_CH_LOW_POL		(0)
+#define HDMI_I2S_L_CH_HIGH_POL		(1)
+
+/* I2S_CON_2 */
+#define HDMI_I2S_MSB_FIRST_MODE		(0 << 6)
+#define HDMI_I2S_LSB_FIRST_MODE		(1 << 6)
+#define HDMI_I2S_BIT_CH_32FS		(0 << 4)
+#define HDMI_I2S_BIT_CH_48FS		(1 << 4)
+#define HDMI_I2S_BIT_CH_RESERVED		(2 << 4)
+#define HDMI_I2S_SDATA_16BIT		(1 << 2)
+#define HDMI_I2S_SDATA_20BIT		(2 << 2)
+#define HDMI_I2S_SDATA_24BIT		(3 << 2)
+#define HDMI_I2S_BASIC_FORMAT		(0)
+#define HDMI_I2S_L_JUST_FORMAT		(2)
+#define HDMI_I2S_R_JUST_FORMAT		(3)
+#define HDMI_I2S_CON_2_CLR			(~0xFF)
+#define HDMI_I2S_SET_BIT_CH(x)		(((x) & 0x7) << 4)
+#define HDMI_I2S_SET_SDATA_BIT(x)		(((x) & 0x7) << 2)
+
+/* I2S_PIN_SEL_0 */
+#define HDMI_I2S_SEL_SCLK(x)		(((x) & 0x7) << 4)
+#define HDMI_I2S_SEL_SCLK_DEFAULT_1		(0x7 << 4)
+#define HDMI_I2S_SEL_LRCK(x)		((x) & 0x7)
+#define HDMI_I2S_SEL_LRCK_DEFAULT_0		(0x7)
+
+/* I2S_PIN_SEL_1 */
+#define HDMI_I2S_SEL_SDATA1(x)		(((x) & 0x7) << 4)
+#define HDMI_I2S_SEL_SDATA1_DEFAULT_3	(0x7 << 4)
+#define HDMI_I2S_SEL_SDATA2(x)		((x) & 0x7)
+#define HDMI_I2S_SEL_SDATA2_DEFAULT_2	(0x7)
+
+/* I2S_PIN_SEL_2 */
+#define HDMI_I2S_SEL_SDATA3(x)		(((x) & 0x7) << 4)
+#define HDMI_I2S_SEL_SDATA3_DEFAULT_5	(0x7 << 4)
+#define HDMI_I2S_SEL_SDATA2(x)		((x) & 0x7)
+#define HDMI_I2S_SEL_SDATA2_DEFAULT_4	(0x7)
+
+/* I2S_PIN_SEL_3 */
+#define HDMI_I2S_SEL_DSD(x)			((x) & 0x7)
+#define HDMI_I2S_SEL_DSD_DEFAULT_6		(0x7)
+
+/* I2S_DSD_CON */
+#define HDMI_I2S_DSD_CLK_RI_EDGE		(1 << 1)
+#define HDMI_I2S_DSD_CLK_FA_EDGE		(0 << 1)
+#define HDMI_I2S_DSD_ENABLE			(1)
+#define HDMI_I2S_DSD_DISABLE		(0)
+
+/* I2S_MUX_CON */
+#define HDMI_I2S_NOISE_FILTER_ZERO		(0 << 5)
+#define HDMI_I2S_NOISE_FILTER_2_STAGE	(1 << 5)
+#define HDMI_I2S_NOISE_FILTER_3_STAGE	(2 << 5)
+#define HDMI_I2S_NOISE_FILTER_4_STAGE	(3 << 5)
+#define HDMI_I2S_NOISE_FILTER_5_STAGE	(4 << 5)
+#define HDMI_I2S_IN_DISABLE			(1 << 4)
+#define HDMI_I2S_IN_ENABLE			(0 << 4)
+#define HDMI_I2S_AUD_SPDIF			(0 << 2)
+#define HDMI_I2S_AUD_I2S			(1 << 2)
+#define HDMI_I2S_AUD_DSD			(2 << 2)
+#define HDMI_I2S_CUV_SPDIF_ENABLE		(0 << 1)
+#define HDMI_I2S_CUV_I2S_ENABLE		(1 << 1)
+#define HDMI_I2S_MUX_DISABLE		(0)
+#define HDMI_I2S_MUX_ENABLE			(1)
+#define HDMI_I2S_MUX_CON_CLR		(~0xFF)
+
+/* I2S_CH_ST_CON */
+#define HDMI_I2S_CH_STATUS_RELOAD		(1)
+#define HDMI_I2S_CH_ST_CON_CLR		(~1)
+
+/* I2S_CH_ST_0 / I2S_CH_ST_SH_0 */
+#define HDMI_I2S_CH_STATUS_MODE_0		(0 << 6)
+#define HDMI_I2S_2AUD_CH_WITHOUT_PREEMPH	(0 << 3)
+#define HDMI_I2S_2AUD_CH_WITH_PREEMPH	(1 << 3)
+#define HDMI_I2S_DEFAULT_EMPHASIS		(0 << 3)
+#define HDMI_I2S_COPYRIGHT			(0 << 2)
+#define HDMI_I2S_NO_COPYRIGHT		(1 << 2)
+#define HDMI_I2S_LINEAR_PCM			(0 << 1)
+#define HDMI_I2S_NO_LINEAR_PCM		(1 << 1)
+#define HDMI_I2S_CONSUMER_FORMAT		(0)
+#define HDMI_I2S_PROF_FORMAT		(1)
+#define HDMI_I2S_CH_ST_0_CLR		(~0xFF)
+
+/* I2S_CH_ST_1 / I2S_CH_ST_SH_1 */
+#define HDMI_I2S_CD_PLAYER			(0x00)
+#define HDMI_I2S_DAT_PLAYER			(0x03)
+#define HDMI_I2S_DCC_PLAYER			(0x43)
+#define HDMI_I2S_MINI_DISC_PLAYER		(0x49)
+
+/* I2S_CH_ST_2 / I2S_CH_ST_SH_2 */
+#define HDMI_I2S_CHANNEL_NUM_MASK		(0xF << 4)
+#define HDMI_I2S_SOURCE_NUM_MASK		(0xF)
+#define HDMI_I2S_SET_CHANNEL_NUM(x)		((x) & (0xF) << 4)
+#define HDMI_I2S_SET_SOURCE_NUM(x)		((x) & (0xF))
+
+/* I2S_CH_ST_3 / I2S_CH_ST_SH_3 */
+#define HDMI_I2S_CLK_ACCUR_LEVEL_1		(1 << 4)
+#define HDMI_I2S_CLK_ACCUR_LEVEL_2		(0 << 4)
+#define HDMI_I2S_CLK_ACCUR_LEVEL_3		(2 << 4)
+#define HDMI_I2S_SAMPLING_FREQ_44_1		(0x0)
+#define HDMI_I2S_SAMPLING_FREQ_48		(0x2)
+#define HDMI_I2S_SAMPLING_FREQ_32		(0x3)
+#define HDMI_I2S_SAMPLING_FREQ_96		(0xA)
+#define HDMI_I2S_SET_SAMPLING_FREQ(x)	((x) & (0xF))
+
+/* I2S_CH_ST_4 / I2S_CH_ST_SH_4 */
+#define HDMI_I2S_ORG_SAMPLING_FREQ_44_1	(0xF << 4)
+#define HDMI_I2S_ORG_SAMPLING_FREQ_88_2	(0x7 << 4)
+#define HDMI_I2S_ORG_SAMPLING_FREQ_22_05	(0xB << 4)
+#define HDMI_I2S_ORG_SAMPLING_FREQ_176_4	(0x3 << 4)
+#define HDMI_I2S_WORD_LENGTH_NOT_DEFINE	(0x0 << 1)
+#define HDMI_I2S_WORD_LENGTH_MAX24_20BITS	(0x1 << 1)
+#define HDMI_I2S_WORD_LENGTH_MAX24_22BITS	(0x2 << 1)
+#define HDMI_I2S_WORD_LENGTH_MAX24_23BITS	(0x4 << 1)
+#define HDMI_I2S_WORD_LENGTH_MAX24_24BITS	(0x5 << 1)
+#define HDMI_I2S_WORD_LENGTH_MAX24_21BITS	(0x6 << 1)
+#define HDMI_I2S_WORD_LENGTH_MAX20_16BITS	(0x1 << 1)
+#define HDMI_I2S_WORD_LENGTH_MAX20_18BITS	(0x2 << 1)
+#define HDMI_I2S_WORD_LENGTH_MAX20_19BITS	(0x4 << 1)
+#define HDMI_I2S_WORD_LENGTH_MAX20_20BITS	(0x5 << 1)
+#define HDMI_I2S_WORD_LENGTH_MAX20_17BITS	(0x6 << 1)
+#define HDMI_I2S_WORD_LENGTH_MAX_24BITS	(1)
+#define HDMI_I2S_WORD_LENGTH_MAX_20BITS	(0)
+
+/* I2S_VD_DATA */
+#define HDMI_I2S_VD_AUD_SAMPLE_RELIABLE	(0)
+#define HDMI_I2S_VD_AUD_SAMPLE_UNRELIABLE	(1)
+
+/* I2S_MUX_CH */
+#define HDMI_I2S_CH3_R_EN			(1 << 7)
+#define HDMI_I2S_CH3_L_EN			(1 << 6)
+#define HDMI_I2S_CH3_EN			(3 << 6)
+#define HDMI_I2S_CH2_R_EN			(1 << 5)
+#define HDMI_I2S_CH2_L_EN			(1 << 4)
+#define HDMI_I2S_CH2_EN			(3 << 4)
+#define HDMI_I2S_CH1_R_EN			(1 << 3)
+#define HDMI_I2S_CH1_L_EN			(1 << 2)
+#define HDMI_I2S_CH1_EN			(3 << 2)
+#define HDMI_I2S_CH0_R_EN			(1 << 1)
+#define HDMI_I2S_CH0_L_EN			(1)
+#define HDMI_I2S_CH0_EN			(3)
+#define HDMI_I2S_CH_ALL_EN			(0xFF)
+#define HDMI_I2S_MUX_CH_CLR			(~HDMI_I2S_CH_ALL_EN)
+
+/* I2S_MUX_CUV */
+#define HDMI_I2S_CUV_R_EN			(1 << 1)
+#define HDMI_I2S_CUV_L_EN			(1)
+#define HDMI_I2S_CUV_RL_EN			(0x03)
+
+/* I2S_IRQ_MASK */
+#define HDMI_I2S_INT2_DIS			(0 << 1)
+#define HDMI_I2S_INT2_EN			(1 << 1)
+
+/* I2S_IRQ_STATUS */
+#define HDMI_I2S_INT2_STATUS		(1 << 1)
+
+/* I2S_CH0_L_0 */
+/* I2S_CH0_L_1 */
+/* I2S_CH0_L_2 */
+/* I2S_CH0_L_3 */
+/* I2S_CH0_R_0 */
+/* I2S_CH0_R_1 */
+/* I2S_CH0_R_2 */
+/* I2S_CH0_R_3 */
+/* I2S_CH1_L_0 */
+/* I2S_CH1_L_1 */
+/* I2S_CH1_L_2 */
+/* I2S_CH1_L_3 */
+/* I2S_CH1_R_0 */
+/* I2S_CH1_R_1 */
+/* I2S_CH1_R_2 */
+/* I2S_CH1_R_3 */
+/* I2S_CH2_L_0 */
+/* I2S_CH2_L_1 */
+/* I2S_CH2_L_2 */
+/* I2S_CH2_L_3 */
+/* I2S_CH2_R_0 */
+/* I2S_CH2_R_1 */
+/* I2S_CH2_R_2 */
+/* I2S_Ch2_R_3 */
+/* I2S_CH3_L_0 */
+/* I2S_CH3_L_1 */
+/* I2S_CH3_L_2 */
+/* I2S_CH3_R_0 */
+/* I2S_CH3_R_1 */
+/* I2S_CH3_R_2 */
+
+/* I2S_CUV_L_R */
+#define HDMI_I2S_CUV_R_DATA_MASK		(0x7 << 4)
+#define HDMI_I2S_CUV_L_DATA_MASK		(0x7)
+
+
+/* Timing Generator Register */
+/* TG_CMD */
+#define HDMI_GETSYNC_TYPE_EN		(1 << 4)
+#define HDMI_GETSYNC_TYPE_DIS		(~HDMI_GETSYNC_TYPE_EN)
+#define HDMI_GETSYNC_EN			(1 << 3)
+#define HDMI_GETSYNC_DIS			(~HDMI_GETSYNC_EN)
+#define HDMI_FIELD_EN			(1 << 1)
+#define HDMI_FIELD_DIS			(~HDMI_FIELD_EN)
+#define HDMI_TG_EN				(1)
+#define HDMI_TG_DIS				(~HDMI_TG_EN)
+
+/* TG_CFG */
+/* TG_CB_SZ */
+/* TG_INDELAY_L */
+/* TG_INDELAY_H */
+/* TG_POL_CTRL */
+
+/* TG_H_FSZ_L */
+#define HDMI_SET_TG_H_FSZ_L(x)		((x) & 0xFF)
+
+/* TG_H_FSZ_H */
+#define HDMI_SET_TG_H_FSZ_H(x)		(((x) >> 8) & 0x1F)
+
+/* TG_HACT_ST_L */
+#define HDMI_SET_TG_HACT_ST_L(x)		((x) & 0xFF)
+
+/* TG_HACT_ST_H */
+#define HDMI_SET_TG_HACT_ST_H(x)		(((x) >> 8) & 0xF)
+
+/* TG_HACT_SZ_L */
+#define HDMI_SET_TG_HACT_SZ_L(x)		((x) & 0xFF)
+
+/* TG_HACT_SZ_H */
+#define HDMI_SET_TG_HACT_SZ_H(x)		(((x) >> 8) & 0xF)
+
+/* TG_V_FSZ_L */
+#define HDMI_SET_TG_V_FSZ_L(x)		((x) & 0xFF)
+
+/* TG_V_FSZ_H */
+#define HDMI_SET_TG_V_FSZ_H(x)		(((x) >> 8) & 0x7)
+
+/* TG_VSYNC_L */
+#define HDMI_SET_TG_VSYNC_L(x)		((x) & 0xFF)
+
+/* TG_VSYNC_H */
+#define HDMI_SET_TG_VSYNC_H(x)		(((x) >> 8) & 0x7)
+
+/* TG_VSYNC2_L */
+#define HDMI_SET_TG_VSYNC2_L(x)		((x) & 0xFF)
+
+/* TG_VSYNC2_H */
+#define HDMI_SET_TG_VSYNC2_H(x)		(((x) >> 8) & 0x7)
+
+/* TG_VACT_ST_L */
+#define HDMI_SET_TG_VACT_ST_L(x)		((x) & 0xFF)
+
+/* TG_VACT_ST_H */
+#define HDMI_SET_TG_VACT_ST_H(x)		(((x) >> 8) & 0x7)
+
+/* TG_VACT_SZ_L */
+#define HDMI_SET_TG_VACT_SZ_L(x)		((x) & 0xFF)
+
+/* TG_VACT_SZ_H */
+#define HDMI_SET_TG_VACT_SZ_H(x)		(((x) >> 8) & 0x7)
+
+/* TG_FIELD_CHG_L */
+#define HDMI_SET_TG_FIELD_CHG_L(x)		((x) & 0xFF)
+
+/* TG_FIELD_CHG_H */
+#define HDMI_SET_TG_FIELD_CHG_H(x)		(((x) >> 8) & 0x7)
+
+/* TG_VACT_ST2_L */
+#define HDMI_SET_TG_VACT_ST2_L(x)		((x) & 0xFF)
+
+/* TG_VACT_ST2_H */
+#define HDMI_SET_TG_VACT_ST2_H(x)		(((x) >> 8) & 0x7)
+
+/* TG_VACT_SC_ST_L */
+/* TG_VACT_SC_ST_H */
+/* TG_VACT_SC_SZ_L */
+/* TG_VACT_SC_SZ_H */
+
+/* TG_VSYNC_TOP_HDMI_L */
+#define HDMI_SET_TG_VSYNC_TOP_HDMI_L(x)	((x) & 0xFF)
+
+/* TG_VSYNC_TOP_HDMI_H */
+#define HDMI_SET_TG_VSYNC_TOP_HDMI_H(x)	(((x) >> 8) & 0x7)
+
+/* TG_VSYNC_BOT_HDMI_L */
+#define HDMI_SET_TG_VSYNC_BOT_HDMI_L(x)	((x) & 0xFF)
+
+/* TG_VSYNC_BOT_HDMI_H */
+#define HDMI_SET_TG_VSYNC_BOT_HDMI_H(x)	(((x) >> 8) & 0x7)
+
+/* TG_FIELD_TOP_HDMI_L */
+#define HDMI_SET_TG_FIELD_TOP_HDMI_L(x)	((x) & 0xFF)
+
+/* TG_FIELD_TOP_HDMI_H */
+#define HDMI_SET_TG_FIELD_TOP_HDMI_H(x)	(((x) >> 8) & 0x7)
+
+/* TG_FIELD_BOT_HDMI_L */
+#define HDMI_SET_TG_FIELD_BOT_HDMI_L(x)	((x) & 0xFF)
+
+/* TG_FIELD_BOT_HDMI_H */
+#define HDMI_SET_TG_FIELD_BOT_HDMI_H(x)	(((x) >> 8) & 0x7)
+
+/* TG_HSYNC_HDOUT_ST_L */
+/* TG_HSYNC_HDOUT_ST_H */
+/* TG_HSYNC_HDOUT_END_L */
+/* TG_HSYNC_HDOUT_END_H */
+/* TG_VSYNC_HDOUT_ST_L */
+/* TG_VSYNC_HDOUT_ST_H */
+/* TG_VSYNC_HDOUT_END_L */
+/* TG_VSYNC_HDOUT_END_H */
+/* TG_VSYNC_HDOUT_DLY_L */
+/* TG_VSYNC_HDOUT_DLY_H */
+/* TG_BT_ERR_RANGE */
+/* TG_BT_ERR_RESULT */
+/* TG_COR_THR */
+/* TG_COR_NUM */
+/* TG_BT_CON */
+/* TG_BT_H_FSZ_L */
+/* TG_BT_H_FSZ_H */
+/* TG_BT_HSYNC_ST */
+/* TG_BT_HSYNC_SZ */
+/* TG_BT_FSZ_L */
+/* TG_BT_FSZ_H */
+/* TG_BT_VACT_T_ST_L */
+/* TG_BT_VACT_T_ST_H */
+/* TG_BT_VACT_B_ST_L */
+/* TG_BT_VACT_B_ST_H */
+/* TG_BT_VACT_SZ_L */
+/* TG_BT_VACT_SZ_H */
+/* TG_BT_VSYNC_SZ */
+
+
+/* HDCP E-FUSE Control Register */
+/* HDCP_E_FUSE_CTRL */
+#define HDMI_EFUSE_CTRL_HDCP_KEY_READ	(1)
+
+/* HDCP_E_FUSE_STATUS */
+#define HDMI_EFUSE_ECC_FAIL			(1 << 2)
+#define HDMI_EFUSE_ECC_BUSY			(1 << 1)
+#define HDMI_EFUSE_ECC_DONE			(1)
+
+/* EFUSE_ADDR_WIDTH */
+/* EFUSE_SIGDEV_ASSERT */
+/* EFUSE_SIGDEV_DE-ASSERT */
+/* EFUSE_PRCHG_ASSERT */
+/* EFUSE_PRCHG_DE-ASSERT */
+/* EFUSE_FSET_ASSERT */
+/* EFUSE_FSET_DE-ASSERT */
+/* EFUSE_SENSING */
+/* EFUSE_SCK_ASSERT */
+/* EFUSE_SCK_DEASSERT */
+/* EFUSE_SDOUT_OFFSET */
+/* EFUSE_READ_OFFSET */
+
+/* HDCP_SHA_RESULT, Not support in s5pv210 */
+/* Not support in s5pv210 */
+#define HDMI_HDCP_SHA_VALID_NO_RD		(0 << 1)
+/* Not support in s5pv210 */
+#define HDMI_HDCP_SHA_VALID_RD		(1 << 1)
+/* Not support in s5pv210 */
+#define HDMI_HDCP_SHA_VALID			(1)
+/* Not support in s5pv210 */
+#define HDMI_HDCP_SHA_NO_VALID		(0)
+
+/* DC_CONTRAL */
+/*Not support in S5PV210 */
+#define HDMI_DC_CTL_12			(1 << 1)
+/*Not support in S5PV210 */
+#define HDMI_DC_CTL_8			(0)
+/*Not support in S5PV210 */
+#define HDMI_DC_CTL_10			(1)
+#endif /* __ASM_ARCH_REGS_HDMI_H */
diff --git a/drivers/media/video/s5p-tv/regs-sdo.h b/drivers/media/video/s5p-tv/regs-sdo.h
new file mode 100644
index 0000000..6b135b5
--- /dev/null
+++ b/drivers/media/video/s5p-tv/regs-sdo.h
@@ -0,0 +1,453 @@
+/* drivers/media/video/s5p-tv/regs-sdo.h
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *		http://www.samsung.com/
+ *
+ * SDO register description file
+ *
+ * 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 __ARCH_ARM_REGS_SDO_H
+#define __ARCH_ARM_REGS_SDO_H
+
+/*
+ * Register part
+ */
+#define SDO_CLKCON			(0x0000)
+#define SDO_CONFIG			(0x0008)
+#define SDO_SCALE			(0x000C)
+#define SDO_SYNC			(0x0010)
+#define SDO_VBI				(0x0014)
+#define SDO_SCALE_CH0			(0x001C)
+#define SDO_SCALE_CH1			(0x0020)
+#define SDO_SCALE_CH2			(0x0024)
+#define SDO_YCDELAY			(0x0034)
+#define SDO_SCHLOCK			(0x0038)
+#define SDO_DAC				(0x003C)
+#define SDO_FINFO			(0x0040)
+#define SDO_Y0				(0x0044)
+#define SDO_Y1				(0x0048)
+#define SDO_Y2				(0x004C)
+#define SDO_Y3				(0x0050)
+#define SDO_Y4				(0x0054)
+#define SDO_Y5				(0x0058)
+#define SDO_Y6				(0x005C)
+#define SDO_Y7				(0x0060)
+#define SDO_Y8				(0x0064)
+#define SDO_Y9				(0x0068)
+#define SDO_Y10				(0x006C)
+#define SDO_Y11				(0x0070)
+#define SDO_CB0				(0x0080)
+#define SDO_CB1				(0x0084)
+#define SDO_CB2				(0x0088)
+#define SDO_CB3				(0x008C)
+#define SDO_CB4				(0x0090)
+#define SDO_CB5				(0x0094)
+#define SDO_CB6				(0x0098)
+#define SDO_CB7				(0x009C)
+#define SDO_CB8				(0x00A0)
+#define SDO_CB9				(0x00A4)
+#define SDO_CB10			(0x00A8)
+#define SDO_CB11			(0x00AC)
+#define SDO_CR0				(0x00C0)
+#define SDO_CR1				(0x00C4)
+#define SDO_CR2				(0x00C8)
+#define SDO_CR3				(0x00CC)
+#define SDO_CR4				(0x00D0)
+#define SDO_CR5				(0x00D4)
+#define SDO_CR6				(0x00D8)
+#define SDO_CR7				(0x00DC)
+#define SDO_CR8				(0x00E0)
+#define SDO_CR9				(0x00E4)
+#define SDO_CR10			(0x00E8)
+#define SDO_CR11			(0x00EC)
+#define SDO_MV_ON			(0x0100)
+#define SDO_MV_SLINE_FIRST_EVEN		(0x0104)
+#define SDO_MV_SLINE_FIRST_SPACE_EVEN	(0x0108)
+#define SDO_MV_SLINE_FIRST_ODD		(0x010C)
+#define SDO_MV_SLINE_FIRST_SPACE_ODD	(0x0110)
+#define SDO_MV_SLINE_SPACING		(0x0114)
+#define SDO_MV_STRIPES_NUMBER		(0x0118)
+#define SDO_MV_STRIPES_THICKNESS	(0x011C)
+#define SDO_MV_PSP_DURATION		(0x0120)
+#define SDO_MV_PSP_FIRST		(0x0124)
+#define SDO_MV_PSP_SPACING		(0x0128)
+#define SDO_MV_SEL_LINE_PSP_AGC		(0x012C)
+#define SDO_MV_SEL_FORMAT_PSP_AGC	(0x0130)
+#define SDO_MV_PSP_AGC_A_ON		(0x0134)
+#define SDO_MV_PSP_AGC_B_ON		(0x0138)
+#define SDO_MV_BACK_PORCH		(0x013C)
+#define SDO_MV_BURST_ADVANCED_ON	(0x0140)
+#define SDO_MV_BURST_DURATION_ZONE1	(0x0144)
+#define SDO_MV_BURST_DURATION_ZONE2	(0x0148)
+#define SDO_MV_BURST_DURATION_ZONE3	(0x014C)
+#define SDO_MV_BURST_PHASE_ZONE		(0x0150)
+#define SDO_MV_SLICE_PHASE_LINE		(0x0154)
+#define SDO_MV_RGB_PROTECTION_ON	(0x0158)
+#define SDO_MV_480P_PROTECTION_ON	(0x015C)
+#define SDO_CCCON			(0x0180)
+#define SDO_YSCALE			(0x0184)
+#define SDO_CBSCALE			(0x0188)
+#define SDO_CRSCALE			(0x018C)
+#define SDO_CB_CR_OFFSET		(0x0190)
+#define SDO_CVBS_CC_Y1			(0x0198)
+#define SDO_CVBS_CC_Y2			(0x019C)
+#define SDO_CVBS_CC_C			(0x01A0)
+#define SDO_CSC_525_PORCH		(0x01B0)
+#define SDO_CSC_625_PORCH		(0x01B4)
+#define SDO_OSFC00_0			(0x0200)
+#define SDO_OSFC01_0			(0x0204)
+#define SDO_OSFC02_0			(0x0208)
+#define SDO_OSFC03_0			(0x020C)
+#define SDO_OSFC04_0			(0x0210)
+#define SDO_OSFC05_0			(0x0214)
+#define SDO_OSFC06_0			(0x0218)
+#define SDO_OSFC07_0			(0x021C)
+#define SDO_OSFC08_0			(0x0220)
+#define SDO_OSFC09_0			(0x0224)
+#define SDO_OSFC10_0			(0x0228)
+#define SDO_OSFC11_0			(0x022C)
+#define SDO_OSFC12_0			(0x0230)
+#define SDO_OSFC13_0			(0x0234)
+#define SDO_OSFC14_0			(0x0238)
+#define SDO_OSFC15_0			(0x023C)
+#define SDO_OSFC16_0			(0x0240)
+#define SDO_OSFC17_0			(0x0244)
+#define SDO_OSFC18_0			(0x0248)
+#define SDO_OSFC19_0			(0x024C)
+#define SDO_OSFC20_0			(0x0250)
+#define SDO_OSFC21_0			(0x0254)
+#define SDO_OSFC22_0			(0x0258)
+#define SDO_OSFC23_0			(0x025C)
+#define SDO_XTALK0			(0x0260)
+#define SDO_XTALK1			(0x0264)
+#define SDO_XTALK2			(0x0268)
+#define SDO_BB_CTRL			(0x026C)
+#define SDO_IRQ				(0x0280)
+#define SDO_IRQMASK			(0x0284)
+#define SDO_OSFC00_1			(0x02C0)
+#define SDO_OSFC01_1			(0x02C4)
+#define SDO_OSFC02_1			(0x02C8)
+#define SDO_OSFC03_1			(0x02CC)
+#define SDO_OSFC04_1			(0x02D0)
+#define SDO_OSFC05_1			(0x02D4)
+#define SDO_OSFC06_1			(0x02D8)
+#define SDO_OSFC07_1			(0x02DC)
+#define SDO_OSFC08_1			(0x02E0)
+#define SDO_OSFC09_1			(0x02E4)
+#define SDO_OSFC10_1			(0x02E8)
+#define SDO_OSFC11_1			(0x02EC)
+#define SDO_OSFC12_1			(0x02E0)
+#define SDO_OSFC13_1			(0x02F4)
+#define SDO_OSFC14_1			(0x02F8)
+#define SDO_OSFC15_1			(0x02FC)
+#define SDO_OSFC16_1			(0x0300)
+#define SDO_OSFC17_1			(0x0304)
+#define SDO_OSFC18_1			(0x0308)
+#define SDO_OSFC19_1			(0x030C)
+#define SDO_OSFC20_1			(0x0310)
+#define SDO_OSFC21_1			(0x0314)
+#define SDO_OSFC22_1			(0x0318)
+#define SDO_OSFC23_1			(0x031C)
+#define SDO_OSFC00_2			(0x0320)
+#define SDO_OSFC01_2			(0x0324)
+#define SDO_OSFC02_2			(0x0328)
+#define SDO_OSFC03_2			(0x032C)
+#define SDO_OSFC04_2			(0x0330)
+#define SDO_OSFC05_2			(0x0334)
+#define SDO_OSFC06_2			(0x0338)
+#define SDO_OSFC07_2			(0x033C)
+#define SDO_OSFC08_2			(0x0340)
+#define SDO_OSFC09_2			(0x0344)
+#define SDO_OSFC10_2			(0x0348)
+#define SDO_OSFC11_2			(0x034C)
+#define SDO_OSFC12_2			(0x0350)
+#define SDO_OSFC13_2			(0x0354)
+#define SDO_OSFC14_2			(0x0358)
+#define SDO_OSFC15_2			(0x035C)
+#define SDO_OSFC16_2			(0x0360)
+#define SDO_OSFC17_2			(0x0364)
+#define SDO_OSFC18_2			(0x0368)
+#define SDO_OSFC19_2			(0x036C)
+#define SDO_OSFC20_2			(0x0370)
+#define SDO_OSFC21_2			(0x0374)
+#define SDO_OSFC22_2			(0x0378)
+#define SDO_OSFC23_2			(0x037C)
+#define SDO_ARMCC			(0x03C0)
+#define SDO_ARMWSS525			(0x03C4)
+#define SDO_ARMWSS625			(0x03C8)
+#define SDO_ARMCGMS525			(0x03CC)
+#define SDO_ARMCGMS625			(0x03D4)
+#define SDO_VERSION			(0x03D8)
+#define SDO_CC				(0x0380)
+#define SDO_WSS525			(0x0384)
+#define SDO_WSS625			(0x0388)
+#define SDO_CGMS525			(0x038C)
+#define SDO_CGMS625			(0x0394)
+
+
+/*
+ * Bit definition part
+*/
+/* SDO Clock Control Register (SDO_CLKCON) */
+#define SDO_TVOUT_SW_RESET		(1 << 4)
+#define SDO_TVOUT_CLOCK_READY		(1 << 1)
+#define SDO_TVOUT_CLOCK_ON		(1)
+#define SDO_TVOUT_CLOCK_OFF		(0)
+
+/* SDO Video Standard Configuration Register (SDO_CONFIG) */
+#define SDO_DAC2_Y_G			(0 << 20)
+#define SDO_DAC2_PB_B			(1 << 20)
+#define SDO_DAC2_PR_R			(2 << 20)
+#define SDO_DAC1_Y_G			(0 << 18)
+#define SDO_DAC1_PB_B			(1 << 18)
+#define SDO_DAC1_PR_R			(2 << 18)
+#define SDO_DAC0_Y_G			(0 << 16)
+#define SDO_DAC0_PB_B			(1 << 16)
+#define SDO_DAC0_PR_R			(2 << 16)
+#define SDO_DAC2_CVBS			(0 << 12)
+#define SDO_DAC2_Y			(1 << 12)
+#define SDO_DAC2_C			(2 << 12)
+#define SDO_DAC1_CVBS			(0 << 10)
+#define SDO_DAC1_Y			(1 << 10)
+#define SDO_DAC1_C			(2 << 10)
+#define SDO_DAC0_CVBS			(0 << 8)
+#define SDO_DAC0_Y			(1 << 8)
+#define SDO_DAC0_C			(2 << 8)
+#define SDO_COMPOSITE			(0 << 6)
+#define SDO_COMPONENT			(1 << 6)
+#define SDO_RGB				(0 << 5)
+#define SDO_YPBPR			(1 << 5)
+#define SDO_INTERLACED			(0 << 4)
+#define SDO_PROGRESSIVE			(1 << 4)
+#define SDO_NTSC_M			(0)
+#define SDO_PAL_M			(1)
+#define SDO_PAL_BGHID			(2)
+#define SDO_PAL_N			(3)
+#define SDO_PAL_NC			(4)
+#define SDO_NTSC_443			(8)
+#define SDO_PAL_60			(9)
+#define SDO_STANDARD_MASK		(0xf)
+
+/* SDO Video Scale Configuration Register (SDO_SCALE) */
+#define SDO_COMPONENT_LEVEL_SEL_0IRE	(0 << 3)
+#define SDO_COMPONENT_LEVEL_SEL_75IRE	(1 << 3)
+#define SDO_COMPONENT_VTOS_RATIO_10_4	(0 << 2)
+#define SDO_COMPONENT_VTOS_RATIO_7_3	(1 << 2)
+#define SDO_COMPOSITE_LEVEL_SEL_0IRE	(0 << 1)
+#define SDO_COMPOSITE_LEVEL_SEL_75IRE	(1 << 1)
+#define SDO_COMPOSITE_VTOS_RATIO_10_4	(0)
+#define SDO_COMPOSITE_VTOS_RATIO_7_3	(1)
+
+/* SDO Video sync Register  */
+#define SDO_COMPONENT_SYNC_ABSENT	(0)
+#define SDO_COMPONENT_SYNC_YG		(1)
+#define SDO_COMPONENT_SYNC_ALL		(3)
+
+/* SDO VBI Configuration Register (SDO_VBI) */
+#define SDO_CVBS_NO_WSS			(0 << 14)
+#define SDO_CVBS_WSS_INS		(1 << 14)
+#define SDO_CVBS_NO_CLOSED_CAPTION	(0 << 12)
+#define SDO_CVBS_21H_CLOSED_CAPTION	(1 << 12)
+#define SDO_CVBS_21H_284H_CLOSED_CAPTION	(2 << 12)
+#define SDO_CVBS_USE_OTHERS		(3 << 12)
+#define SDO_CVBS_CLOSED_CAPTION_MASK	(3 << 12)
+
+/* SDO Channel #0 Scale Control Register (SDO_SCALE_CH0) */
+#define SDO_SCALE_CONV_OFFSET(x)	(((x) & 0x3FF) << 16)
+#define SDO_SCALE_CONV_GAIN(x)		((x) & 0xFFF)
+
+/* SDO Video Delay Control Register (SDO_YCDELAY) */
+#define SDO_DELAY_YTOC(x)		(((x) & 0xF) << 16)
+#define SDO_ACTIVE_START_OFFSET(x)	(((x) & 0xFF) << 8)
+#define SDO_ACTIVE_END_OFFSET(x)	((x) & 0xFF)
+
+/* SDO SCH Phase Control Register (SDO_SCHLOCK) */
+#define SDO_COLOR_SC_PHASE_ADJ		(1)
+#define SDO_COLOR_SC_PHASE_NOADJ	(0)
+
+/* SDO DAC Configuration Register (SDO_DAC) */
+#define SDO_POWER_ON_DAC		(1 << 0)
+#define SDO_POWER_DOWN_DAC		(0 << 0)
+
+/* SDO Status Register (SDO_FINFO) */
+#define SDO_FIELD_MOD_1001(x)		(((x) & (0x3ff << 16)) >> 16)
+#define SDO_FIELD_ID_BOTTOM(x)		((x) & (1 << 1))
+#define SDO_FIELD_ID_BOTTOM_PI_INCATION(x)	(1)
+
+#define SDO_MV_AGC_103_ON		(1)
+
+/* SDO Color Compensation On/Off Control (SDO_CCCON) */
+#define SDO_COMPENSATION_BHS_ADJ_ON	(0 << 4)
+#define SDO_COMPENSATION_BHS_ADJ_OFF	(1 << 4)
+#define SDO_COMPENSATION_CVBS_COMP_ON	(0)
+#define SDO_COMPENSATION_CVBS_COMP_OFF	(1)
+
+/* SDO Brightness Control for Y (SDO_YSCALE) */
+#define SDO_BRIGHTNESS_GAIN(x)		(((x) & 0xFF) << 16)
+#define SDO_BRIGHTNESS_OFFSET(x)	((x) & 0xFF)
+
+/* SDO Hue/Saturation Control for CB (SDO_CBSCALE) */
+#define SDO_HS_CB_GAIN0(x)		(((x) & 0x1FF) << 16)
+#define SDO_HS_CB_GAIN1(x)		((x) & 0x1FF)
+
+/* SDO Hue/Saturation Control for CR (SDO_CRSCALE) */
+#define SDO_HS_CR_GAIN0(x)		(((x) & 0x1FF) << 16)
+#define SDO_HS_CR_GAIN1(x)		((x) & 0x1FF)
+
+/* SDO Hue/Saturation Control for CB/CR (SDO_CB_CR_OFFSET) */
+#define SDO_HS_CR_OFFSET(x)		(((x) & 0x3FF) << 16)
+#define SDO_HS_CB_OFFSET(x)		((x) & 0x3FF)
+
+#define SDO_MAX_RGB_CUBE(x)		(((x) & 0xFF) << 8)
+#define SDO_MIN_RGB_CUBE(x)		((x) & 0xFF)
+
+/* Color Compensation Control Register for CVBS Output (SDO_CVBS_CC_Y1) */
+#define SDO_Y_LOWER_MID_CVBS_CORN(x)	(((x) & 0x3FF) << 16)
+#define SDO_Y_BOTTOM_CVBS_CORN(x)		((x) & 0x3FF)
+
+/* Color Compensation Control Register for CVBS Output (SDO_CVBS_CC_Y2) */
+#define SDO_Y_TOP_CVBS_CORN(x)		(((x) & 0x3FF) << 16)
+#define SDO_Y_UPPER_MID_CVBS_CORN(x)	((x) & 0x3FF)
+
+/* Color Compensation Control Register for CVBS Output (SDO_CVBS_CC_C) */
+#define SDO_RADIUS_CVBS_CORN(x)		((x) & 0x1FF)
+
+/*
+ * SDO 525 Line Component Front/Back Porch Position
+ * Control Register (SDO_CSC_525_PORCH)
+ */
+#define SDO_COMPONENT_525_BP(x)		(((x) & 0x3FF) << 16)
+#define SDO_COMPONENT_525_FP(x)		((x) & 0x3FF)
+
+/*
+ * SDO 625 Line Component Front/Back Porch Position
+ * Control Resigter(SDO_CSC_625_PORCH
+ */
+#define SDO_COMPONENT_625_BP(x)		(((x) & 0x3FF) << 16)
+#define SDO_COMPONENT_625_FP(x)		((x) & 0x3FF)
+
+/* SDO Oversampling #0 Filter Coefficient (SDO_OSFC00_0) */
+#define SDO_OSF_COEF_ODD(x)		(((x) & 0xFFF) << 16)
+#define SDO_OSF_COEF_EVEN(x)		((x) & 0xFFF)
+
+/* SDO Channel Crosstalk Cancellation Coefficient for Ch. 0 (SDO_XTALK0) */
+#define SDO_XTALK_COEF02(x)		(((x) & 0xFF) << 16)
+#define SDO_XTALK_COEF01(x)		((x) & 0xFF)
+
+/* SDO Black Burst Control Register (SDO_BB_CTRL) */
+#define SDO_REF_BB_LEVEL_NTSC		(0x11A << 8)
+#define SDO_REF_BB_LEVEL_PAL		(0xFB << 8)
+#define SDO_SEL_BB_CJAN_CVBS0_BB1_BB2	(0 << 4)
+#define SDO_SEL_BB_CJAN_BB0_CVBS1_BB2	(1 << 4)
+#define SDO_SEL_BB_CJAN_BB0_BB1_CVBS2	(2 << 4)
+#define SDO_BB_MODE_ENABLE		(1)
+#define SDO_BB_MODE_DISABLE		(0)
+
+/* SDO Interrupt Request Register (SDO_IRQ) */
+#define SDO_VSYNC_IRQ_PEND		(1)
+#define SDO_VSYNC_NO_IRQ		(0)
+
+/* SDO Interrupt Request Masking Register (SDO_IRQMASK) */
+#define SDO_VSYNC_IRQ_ENABLE		(0)
+#define SDO_VSYNC_IRQ_DISABLE		(1)
+
+/* SDO Closed Caption Data Registers (SDO_ARMCC) */
+#define SDO_DISPLAY_CC_CAPTION(x)	(((x) & 0xFF) << 16)
+#define SDO_NON_DISPLAY_CC_CAPTION(x)	((x) & 0xFF)
+
+/* SDO WSS 525 Data Registers (SDO_ARMWSS525) */
+#define SDO_CRC_WSS525(x)			(((x) & 0x3F) << 14)
+#define SDO_WORD2_WSS525_COPY_PERMIT		(0 << 6)
+#define SDO_WORD2_WSS525_ONECOPY_PERMIT		(1 << 6)
+#define SDO_WORD2_WSS525_NOCOPY_PERMIT		(3 << 6)
+#define SDO_WORD2_WSS525_MV_PSP_OFF		(0 << 8)
+#define SDO_WORD2_WSS525_MV_PSP_ON_2LINE_BURST	(1 << 8)
+#define SDO_WORD2_WSS525_MV_PSP_ON_BURST_OFF	(2 << 8)
+#define SDO_WORD2_WSS525_MV_PSP_ON_4LINE_BURST	(3 << 8)
+#define SDO_WORD2_WSS525_ANALOG_OFF		(0 << 10)
+#define SDO_WORD2_WSS525_ANALOG_ON		(1 << 10)
+#define SDO_WORD1_WSS525_COPY_INFO		(0 << 2)
+#define SDO_WORD1_WSS525_DEFAULT		(0xF << 2)
+#define SDO_WORD0_WSS525_4_3_NORMAL		(0)
+#define SDO_WORD0_WSS525_16_9_ANAMORPIC		(1)
+#define SDO_WORD0_WSS525_4_3_LETTERBOX		(2)
+
+/* SDO WSS 625 Data Registers (SDO_ARMWSS625) */
+#define SDO_WSS625_SURROUND_SOUND_DISABLE	(0 << 11)
+#define SDO_WSS625_SURROUND_SOUND_ENABLE	(1 << 11)
+#define SDO_WSS625_NO_COPYRIGHT			(0 << 12)
+#define SDO_WSS625_COPYRIGHT			(1 << 12)
+#define SDO_WSS625_COPY_NOT_RESTRICTED		(0 << 13)
+#define SDO_WSS625_COPY_RESTRICTED		(1 << 13)
+#define SDO_WSS625_TELETEXT_NO_SUBTITLES	(0 << 8)
+#define SDO_WSS625_TELETEXT_SUBTITLES		(1 << 8)
+#define SDO_WSS625_NO_OPEN_SUBTITLES		(0 << 9)
+#define SDO_WSS625_INACT_OPEN_SUBTITLES		(1 << 9)
+#define SDO_WSS625_OUTACT_OPEN_SUBTITLES	(2 << 9)
+#define SDO_WSS625_CAMERA			(0 << 4)
+#define SDO_WSS625_FILM				(1 << 4)
+#define SDO_WSS625_NORMAL_PAL			(0 << 5)
+#define SDO_WSS625_MOTION_ADAPTIVE_COLORPLUS	(1 << 5)
+#define SDO_WSS625_HELPER_NO_SIG		(0 << 6)
+#define SDO_WSS625_HELPER_SIG			(1 << 6)
+#define SDO_WSS625_4_3_FULL_576			(0x8)
+#define SDO_WSS625_14_9_LETTERBOX_CENTER_504	(0x1)
+#define SDO_WSS625_14_9_LETTERBOX_TOP_504	(0x2)
+#define SDO_WSS625_16_9_LETTERBOX_CENTER_430	(0xb)
+#define SDO_WSS625_16_9_LETTERBOX_TOP_430	(0x4)
+#define SDO_WSS625_16_9_LETTERBOX_CENTER	(0xd)
+#define SDO_WSS625_14_9_FULL_CENTER_576		(0xe)
+#define SDO_WSS625_16_9_ANAMORPIC_576		(0x7)
+
+/* SDO CGMS-A 525 Data Registers (SDO_ARMCGMS525) */
+#define SDO_CRC_CGMS525(x)			(((x) & 0x3F) << 14)
+#define SDO_WORD2_CGMS525_COPY_PERMIT		(0 << 6)
+#define SDO_WORD2_CGMS525_ONECOPY_PERMIT	(1 << 6)
+#define SDO_WORD2_CGMS525_NOCOPY_PERMIT		(3 << 6)
+#define SDO_WORD2_CGMS525_MV_PSP_OFF		(0 << 8)
+#define SDO_WORD2_CGMS525_MV_PSP_ON_2LINE_BURST	(1 << 8)
+#define SDO_WORD2_CGMS525_MV_PSP_ON_BURST_OFF	(2 << 8)
+#define SDO_WORD2_CGMS525_MV_PSP_ON_4LINE_BURST	(3 << 8)
+#define SDO_WORD2_CGMS525_ANALOG_OFF		(0 << 10)
+#define SDO_WORD2_CGMS525_ANALOG_ON		(1 << 10)
+#define SDO_WORD1_CGMS525_COPY_INFO		(0 << 2)
+#define SDO_WORD1_CGMS525_DEFAULT		(0xF << 2)
+#define SDO_WORD0_CGMS525_4_3_NORMAL		(0)
+#define SDO_WORD0_CGMS525_16_9_ANAMORPIC	(1)
+#define SDO_WORD0_CGMS525_4_3_LETTERBOX		(2)
+
+/* SDO CGMS-A 625 Data Registers (SDO_ARMCGMS625) */
+#define SDO_CGMS625_SURROUND_SOUND_DISABLE	(0 << 11)
+#define SDO_CGMS625_SURROUND_SOUND_ENABLE	(1 << 11)
+#define SDO_CGMS625_NO_COPYRIGHT		(0 << 12)
+#define SDO_CGMS625_COPYRIGHT			(1 << 12)
+#define SDO_CGMS625_COPY_NOT_RESTRICTED		(0 << 13)
+#define SDO_CGMS625_COPY_RESTRICTED		(1 << 13)
+#define SDO_CGMS625_TELETEXT_NO_SUBTITLES	(0 << 8)
+#define SDO_CGMS625_TELETEXT_SUBTITLES		(1 << 8)
+#define SDO_CGMS625_NO_OPEN_SUBTITLES		(0 << 9)
+#define SDO_CGMS625_INACT_OPEN_SUBTITLES	(1 << 9)
+#define SDO_CGMS625_OUTACT_OPEN_SUBTITLES	(2 << 9)
+#define SDO_CGMS625_CAMERA			(0 << 4)
+#define SDO_CGMS625_FILM			(1 << 4)
+#define SDO_CGMS625_NORMAL_PAL			(0 << 5)
+#define SDO_CGMS625_MOTION_ADAPTIVE_COLORPLUS	(1 << 5)
+#define SDO_CGMS625_HELPER_NO_SIG		(0 << 6)
+#define SDO_CGMS625_HELPER_SIG			(1 << 6)
+#define SDO_CGMS625_4_3_FULL_576		(0x8)
+#define SDO_CGMS625_14_9_LETTERBOX_CENTER_504	(0x1)
+#define SDO_CGMS625_14_9_LETTERBOX_TOP_504	(0x2)
+#define SDO_CGMS625_16_9_LETTERBOX_CENTER_430	(0xb)
+#define SDO_CGMS625_16_9_LETTERBOX_TOP_430	(0x4)
+#define SDO_CGMS625_16_9_LETTERBOX_CENTER	(0xd)
+#define SDO_CGMS625_14_9_FULL_CENTER_576	(0xe)
+#define SDO_CGMS625_16_9_ANAMORPIC_576		(0x7)
+
+/* SDO Version Register (SDO_VERSION) */
+#define SDO_VERSION_NUMBER_MASK			(0xFFFFFFFF)
+
+#endif /* __ARCH_ARM_REGS_SDO_H */
diff --git a/drivers/media/video/s5p-tv/regs-vmx.h b/drivers/media/video/s5p-tv/regs-vmx.h
new file mode 100644
index 0000000..08f169a
--- /dev/null
+++ b/drivers/media/video/s5p-tv/regs-vmx.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2010 Samsung Electronics
+ * http://www.samsung.com/
+ *
+ * Mixer register header file for Samsung Mixer driver
+ *
+ * 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 __ASM_ARCH_REGS_VMX_H
+#define __ASM_ARCH_REGS_VMX_H
+
+/*
+ * Register part
+ */
+#define MXR_STATUS			(0x0000)
+#define MXR_CFG				(0x0004)
+#define MXR_INT_EN			(0x0008)
+#define MXR_INT_STATUS			(0x000C)
+#define MXR_LAYER_CFG			(0x0010)
+#define MXR_VIDEO_CFG			(0x0014)
+#define MXR_GRAPHIC0_CFG		(0x0020)
+#define MXR_GRAPHIC0_BASE		(0x0024)
+#define MXR_GRAPHIC0_SPAN		(0x0028)
+#define MXR_GRAPHIC0_SXY		(0x002C)
+#define MXR_GRAPHIC0_WH			(0x0030)
+#define MXR_GRAPHIC0_DXY		(0x0034)
+#define MXR_GRAPHIC0_BLANK		(0x0038)
+#define MXR_GRAPHIC1_CFG		(0x0040)
+#define MXR_GRAPHIC1_BASE		(0x0044)
+#define MXR_GRAPHIC1_SPAN		(0x0048)
+#define MXR_GRAPHIC1_SXY		(0x004C)
+#define MXR_GRAPHIC1_WH			(0x0050)
+#define MXR_GRAPHIC1_DXY		(0x0054)
+#define MXR_GRAPHIC1_BLANK		(0x0058)
+#define MXR_BG_CFG			(0x0060)
+#define MXR_BG_COLOR0			(0x0064)
+#define MXR_BG_COLOR1			(0x0068)
+#define MXR_BG_COLOR2			(0x006C)
+#define MXR_CM_COEFF_Y			(0x0080)
+#define MXR_CM_COEFF_CB			(0x0084)
+#define MXR_CM_COEFF_CR			(0x0088)
+#define MXR_VER				(0x0100)
+
+/* for parametrized access to registers */
+#define MXR_GRAPHIC_CFG(i)		(0x0020 + (i) * 0x20)
+#define MXR_GRAPHIC_BASE(i)		(0x0024 + (i) * 0x20)
+#define MXR_GRAPHIC_SPAN(i)		(0x0028 + (i) * 0x20)
+#define MXR_GRAPHIC_SXY(i)		(0x002C + (i) * 0x20)
+#define MXR_GRAPHIC_WH(i)		(0x0030 + (i) * 0x20)
+#define MXR_GRAPHIC_DXY(i)		(0x0034 + (i) * 0x20)
+#define MXR_GRAPHIC_BLANK(i)		(0x0038 + (i) * 0x20)
+
+/* Shadow registers */
+#define MXR_STATUS_S			(0x2000)
+#define MXR_CFG_S			(0x2004)
+#define MXR_LAYER_CFG_S			(0x2010)
+#define MXR_VIDEO_CFG_S			(0x2014)
+#define MXR_GRAPHIC0_CFG_S		(0x2020)
+#define MXR_GRAPHIC0_BASE_S		(0x2024)
+#define MXR_GRAPHIC0_SPAN_S		(0x2028)
+#define MXR_GRAPHIC0_SXY_S		(0x202C)
+#define MXR_GRAPHIC0_WH_S		(0x2030)
+#define MXR_GRAPHIC0_DXY_S		(0x2034)
+#define MXR_GRAPHIC0_BLANK_PIXEL_S	(0x2038)
+#define MXR_GRAPHIC1_CFG_S		(0x2040)
+#define MXR_GRAPHIC1_BASE_S		(0x2044)
+#define MXR_GRAPHIC1_SPAN_S		(0x2048)
+#define MXR_GRAPHIC1_SXY_S		(0x204C)
+#define MXR_GRAPHIC1_WH_S		(0x2050)
+#define MXR_GRAPHIC1_DXY_S		(0x2054)
+#define MXR_GRAPHIC1_BLANK_PIXEL_S	(0x2058)
+#define MXR_BG_COLOR0_S			(0x2064)
+#define MXR_BG_COLOR1_S			(0x2068)
+#define MXR_BG_COLOR2_S			(0x206C)
+
+/* for parametrized access to shadow registers */
+#define MXR_GRAPHIC_CFG_S(i)		(0x2020 + (i) * 0x20)
+#define MXR_GRAPHIC_BASE_S(i)		(0x2024 + (i) * 0x20)
+#define MXR_GRAPHIC_SPAN_S(i)		(0x2028 + (i) * 0x20)
+#define MXR_GRAPHIC_SXY_S(i)		(0x202C + (i) * 0x20)
+#define MXR_GRAPHIC_WH_S(i)		(0x2030 + (i) * 0x20)
+#define MXR_GRAPHIC_DXY_S(i)		(0x2034 + (i) * 0x20)
+#define MXR_GRAPHIC_BLANK_S(i)		(0x2038 + (i) * 0x20)
+
+/*
+ * Bit definition part
+ */
+
+#define MASK(high_bit, low_bit) \
+	(((2 << ((high_bit) - (low_bit))) - 1) << (low_bit))
+
+#define MASK_VAL(val, high_bit, low_bit) \
+	(((val) << (low_bit)) & MASK(high_bit, low_bit))
+
+/* MIXER_STATUS */
+#define MXR_STATUS_16_BURST		(1 << 7)
+#define MXR_STATUS_8_BURST		(0 << 7)
+#define MXR_STATUS_BURST_MASK		(1 << 7)
+#define MXR_STATUS_LITTLE_ENDIAN	(0 << 3)
+#define MXR_STATUS_BIG_ENDIAN		(1 << 3)
+#define MXR_STATUS_SYNC_ENABLE		(1 << 2)
+#define MXR_STATUS_OPERATING		(0 << 1)
+#define MXR_STATUS_IDLE_MODE		(1 << 1)
+#define MXR_STATUS_OPERATION_STATUS	(1 << 1)
+#define MXR_STATUS_REG_RUN		(1 << 0)
+
+/* MIXER_CFG */
+#define MXR_CFG_OUT_YUV444		(0 << 8)
+#define MXR_CFG_OUT_RGB888		(1 << 8)
+#define MXR_CFG_DST_TV			(0 << 7)
+#define MXR_CFG_DST_HDMI		(1 << 7)
+#define MXR_CFG_DST_MASK		(1 << 7)
+#define MXR_CFG_HD_720			(0 << 6)
+#define MXR_CFG_HD_1080			(1 << 6)
+#define MXR_CFG_GRP1_ENABLE		(1 << 5)
+#define MXR_CFG_GRP0_ENABLE		(1 << 4)
+#define MXR_CFG_VP_ENABLE		(1 << 3)
+#define MXR_CFG_SCAN_INTERLACE		(0 << 2)
+#define MXR_CFG_SCAN_PROGRASSIVE	(1 << 2)
+#define MXR_CFG_NTSC			(0 << 1)
+#define MXR_CFG_PAL			(1 << 1)
+#define MXR_CFG_SD			(0 << 0)
+#define MXR_CFG_HD			(1 << 0)
+#define MXR_CFG_SCAN_MASK		0x47
+
+/* MIXER_INT_EN */
+#define MXR_INT_EN_VSYNC		(1 << 11)
+#define MXR_INT_EN_VP			(1 << 10)
+#define MXR_INT_EN_GRP1			(1 << 9)
+#define MXR_INT_EN_GRP0			(1 << 8)
+#define MXR_INT_EN_ALL			(0x0f << 8)
+
+/* MIXER_INT_STATUS */
+#define MXR_INT_CLEAR_VSYNC		(1 << 11)
+#define MXR_INT_STATUS_VP		(1 << 10)
+#define MXR_INT_STATUS_GRP1		(1 << 9)
+#define MXR_INT_STATUS_GRP0		(1 << 8)
+#define MXR_INT_STATUS_VSYNC		(1 << 0)
+
+/* MIXER_LAYER_CFG */
+#define MXR_LAYER_CFG_GRP1_VAL(x)	MASK_VAL(x, 11, 8)
+#define MXR_LAYER_CFG_GRP1_HIDE		MASK_VAL(0, 11, 8)
+#define MXR_LAYER_CFG_GRP0_VAL(x)	MASK_VAL(x, 7, 4)
+#define MXR_LAYER_CFG_GRP0_HIDE		MASK_VAL(0, 7, 4)
+#define MXR_LAYER_CFG_VP_VAL(x)		MASK_VAL(x, 3, 0)
+#define MXR_LAYER_CFG_VP_HIDE		MASK_VAL(0, 3, 0)
+
+/* MIXER_VIDEO_CFG */
+#define MXR_VP_CFG_LIMITER_EN		(1 << 17)
+#define MXR_VP_CFG_BLEND_EN		(1 << 16)
+#define MXR_VP_CFG_ALPHA_VAL(x)		MASK_VAL(x, 7, 0)
+
+/* MIXER_GRAPHICn_CFG */
+#define MXR_GRP_CFG_COLOR_KEY_DISABLE	(1 << 21)
+#define MXR_GRP_CFG_BLEND_PRE_MUL	(1 << 20)
+#define MXR_GRP_CFG_BLEND_NORMAL	(0 << 20)
+#define MXR_GRP_CFG_WIN_BLEND		(1 << 17)
+#define MXR_GRP_CFG_PIXEL_BLEND		(1 << 16)
+#define MXR_GRP_CFG_FORMAT_VAL(x)	MASK_VAL(x, 11, 8)
+#define MXR_GRP_CFG_FORMAT_MASK		MXR_GRP_CFG_FORMAT_VAL(~0)
+#define MXR_GRP_CFG_ALPHA_VAL(x)	MASK_VAL(x, 7, 0)
+
+/* MIXER_GRAPHICn_WH */
+#define MXR_GRP_WH_H_SCALE(x)		MASK_VAL(x, 28, 28)
+#define MXR_GRP_WH_V_SCALE(x)		MASK_VAL(x, 12, 12)
+#define MXR_GRP_WH_WIDTH(x)		MASK_VAL(x, 26, 16)
+#define MXR_GRP_WH_HEIGHT(x)		MASK_VAL(x, 10, 0)
+
+/* MIXER_GRAPHICn_XY */
+#define MXR_GRP_SXY_SX(x)		MASK_VAL(x, 26, 16)
+#define MXR_GRP_SXY_SY(x)		MASK_VAL(x, 10, 0)
+
+/* MIXER_GRAPHICn_DXY */
+#define MXR_GRP_DXY_DX(x)		MASK_VAL(x, 26, 16)
+#define MXR_GRP_DXY_DY(x)		MASK_VAL(x, 10, 0)
+
+/* MIXER_BG_CFG, Not supported in S5PV210 */
+#define MXR_BG_CR_DIHER			(1 << 19)
+#define MXR_BG_CB_DIHER			(1 << 18)
+#define MXR_BG_Y_DIHER			(1 << 17)
+
+/* MIXER_BG_COLOR0/1/2 */
+#define MXR_BG_Y(x)			MASK_VAL(x, 23, 16)
+#define MXR_BG_CB(x)			MASK_VAL(x, 15, 8)
+#define MXR_BG_CR(x)			MASK_VAL(x, 7, 0)
+
+/* MIXER_CM_COEFF_{Y/CB/CR} */
+#define MXR_CM_COLOR_WIDE		(1 << 30)
+#define MXR_CM_COLOR_NARROW		(0 << 30)
+#define MXR_CM_COEF0(x)			MASK_VAL(x, 29, 20)
+#define MXR_CM_COEF1(x)			MASK_VAL(x, 19, 10)
+#define MXR_CM_COEF2(x)			MASK_VAL(x, 9, 0)
+
+#endif /* __ASM_ARCH_REGS_VMX_H */
+
diff --git a/drivers/media/video/s5p-tv/regs-vp.h b/drivers/media/video/s5p-tv/regs-vp.h
new file mode 100644
index 0000000..f06dbb6
--- /dev/null
+++ b/drivers/media/video/s5p-tv/regs-vp.h
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2010 Samsung Electronics
+ *		http://www.samsung.com/
+ *
+ * Video processor register header file for Samsung Mixer driver
+ *
+ * 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 __ARCH_ARM_REGS_VP_H
+#define __ARCH_ARM_REGS_VP_H
+
+/*
+ * Register part
+ */
+#define VP_ENABLE			(0x0000)
+#define VP_SRESET			(0x0004)
+#define VP_SHADOW_UPDATE		(0x0008)
+#define VP_FIELD_ID			(0x000C)
+#define VP_MODE				(0x0010)
+#define VP_IMG_SIZE_Y			(0x0014)
+#define VP_IMG_SIZE_C			(0x0018)
+#define VP_PER_RATE_CTRL		(0x001C)
+#define VP_TOP_Y_PTR			(0x0028)
+#define VP_BOT_Y_PTR			(0x002C)
+#define VP_TOP_C_PTR			(0x0030)
+#define VP_BOT_C_PTR			(0x0034)
+#define VP_ENDIAN_MODE			(0x03CC)
+#define VP_SRC_H_POSITION		(0x0044)
+#define VP_SRC_V_POSITION		(0x0048)
+#define VP_SRC_WIDTH			(0x004C)
+#define VP_SRC_HEIGHT			(0x0050)
+#define VP_DST_H_POSITION		(0x0054)
+#define VP_DST_V_POSITION		(0x0058)
+#define VP_DST_WIDTH			(0x005C)
+#define VP_DST_HEIGHT			(0x0060)
+#define VP_H_RATIO			(0x0064)
+#define VP_V_RATIO			(0x0068)
+#define VP_POLY8_Y0_LL			(0x006C)
+#define VP_POLY8_Y0_LH			(0x0070)
+#define VP_POLY8_Y0_HL			(0x0074)
+#define VP_POLY8_Y0_HH			(0x0078)
+#define VP_POLY8_Y1_LL			(0x007C)
+#define VP_POLY8_Y1_LH			(0x0080)
+#define VP_POLY8_Y1_HL			(0x0084)
+#define VP_POLY8_Y1_HH			(0x0088)
+#define VP_POLY8_Y2_LL			(0x008C)
+#define VP_POLY8_Y2_LH			(0x0090)
+#define VP_POLY8_Y2_HL			(0x0094)
+#define VP_POLY8_Y2_HH			(0x0098)
+#define VP_POLY8_Y3_LL			(0x009C)
+#define VP_POLY8_Y3_LH			(0x00A0)
+#define VP_POLY8_Y3_HL			(0x00A4)
+#define VP_POLY8_Y3_HH			(0x00A8)
+#define VP_POLY4_Y0_LL			(0x00EC)
+#define VP_POLY4_Y0_LH			(0x00F0)
+#define VP_POLY4_Y0_HL			(0x00F4)
+#define VP_POLY4_Y0_HH			(0x00F8)
+#define VP_POLY4_Y1_LL			(0x00FC)
+#define VP_POLY4_Y1_LH			(0x0100)
+#define VP_POLY4_Y1_HL			(0x0104)
+#define VP_POLY4_Y1_HH			(0x0108)
+#define VP_POLY4_Y2_LL			(0x010C)
+#define VP_POLY4_Y2_LH			(0x0110)
+#define VP_POLY4_Y2_HL			(0x0114)
+#define VP_POLY4_Y2_HH			(0x0118)
+#define VP_POLY4_Y3_LL			(0x011C)
+#define VP_POLY4_Y3_LH			(0x0120)
+#define VP_POLY4_Y3_HL			(0x0124)
+#define VP_POLY4_Y3_HH			(0x0128)
+#define VP_POLY4_C0_LL			(0x012C)
+#define VP_POLY4_C0_LH			(0x0130)
+#define VP_POLY4_C0_HL			(0x0134)
+#define VP_POLY4_C0_HH			(0x0138)
+#define VP_POLY4_C1_LL			(0x013C)
+#define VP_POLY4_C1_LH			(0x0140)
+#define VP_POLY4_C1_HL			(0x0144)
+#define VP_POLY4_C1_HH			(0x0148)
+#define VP_FIELD_ID_S			(0x016C)
+#define VP_MODE_S			(0x0170)
+#define VP_IMG_SIZE_Y_S			(0x0174)
+#define VP_IMG_SIZE_C_S			(0x0178)
+#define VP_TOP_Y_PTR_S			(0x0190)
+#define VP_BOT_Y_PTR_S			(0x0194)
+#define VP_TOP_C_PTR_S			(0x0198)
+#define VP_BOT_C_PTR_S			(0x019C)
+#define VP_SRC_H_POSITION_S		(0x01AC)
+#define VP_SRC_V_POSITION_S		(0x01B0)
+#define VP_SRC_WIDTH_S			(0x01B4)
+#define VP_SRC_HEIGHT_S			(0x01B8)
+#define VP_DST_H_POSITION_S		(0x01BC)
+#define VP_DST_V_POSITION_S		(0x01C0)
+#define VP_DST_WIDTH_S			(0x01C4)
+#define VP_DST_HEIGHT_S			(0x01C8)
+#define VP_H_RATIO_S			(0x01CC)
+#define VP_V_RATIO_S			(0x01D0)
+#define VP_PP_CSC_Y2Y_COEF		(0x01D4)
+#define VP_PP_CSC_CB2Y_COEF		(0x01D8)
+#define VP_PP_CSC_CR2Y_COEF		(0x01DC)
+#define VP_PP_CSC_Y2CB_COEF		(0x01E0)
+#define VP_PP_CSC_CB2CB_COEF		(0x01E4)
+#define VP_PP_CSC_CR2CB_COEF		(0x01E8)
+#define VP_PP_CSC_Y2CR_COEF		(0x01EC)
+#define VP_PP_CSC_CB2CR_COEF		(0x01F0)
+#define VP_PP_CSC_CR2CR_COEF		(0x01F4)
+#define VP_PP_BYPASS			(0x0200)
+#define VP_PP_SATURATION		(0x020C)
+#define VP_PP_SHARPNESS			(0x0210)
+#define VP_PP_LINE_EQ0			(0x0218)
+#define VP_PP_LINE_EQ1			(0x021C)
+#define VP_PP_LINE_EQ2			(0x0220)
+#define VP_PP_LINE_EQ3			(0x0224)
+#define VP_PP_LINE_EQ4			(0x0228)
+#define VP_PP_LINE_EQ5			(0x022C)
+#define VP_PP_LINE_EQ6			(0x0230)
+#define VP_PP_LINE_EQ7			(0x0234)
+#define VP_PP_BRIGHT_OFFSET		(0x0238)
+#define VP_PP_CSC_EN			(0x023C)
+#define VP_PP_BYPASS_S			(0x0258)
+#define VP_PP_SATURATION_S		(0x025C)
+#define VP_PP_SHARPNESS_S		(0x0260)
+#define VP_PP_LINE_EQ0_S		(0x0268)
+#define VP_PP_LINE_EQ1_S		(0x026C)
+#define VP_PP_LINE_EQ2_S		(0x0270)
+#define VP_PP_LINE_EQ3_S		(0x0274)
+#define VP_PP_LINE_EQ4_S		(0x0278)
+#define VP_PP_LINE_EQ5_S		(0x027C)
+#define VP_PP_LINE_EQ6_S		(0x0280)
+#define VP_PP_LINE_EQ7_S		(0x0284)
+#define VP_PP_BRIGHT_OFFSET_S		(0x0288)
+#define VP_PP_CSC_EN_S			(0x028C)
+#define VP_PP_CSC_Y2Y_COEF_S		(0x0290)
+#define VP_PP_CSC_CB2Y_COEF_S		(0x0294)
+#define VP_PP_CSC_CR2Y_COEF_S		(0x0298)
+#define VP_PP_CSC_Y2CB_COEF_S		(0x029C)
+#define VP_PP_CSC_CB2CB_COEF_S		(0x02A0)
+#define VP_PP_CSC_CR2CB_COEF_S		(0x02A4)
+#define VP_PP_CSC_Y2CR_COEF_S		(0x02A8)
+#define VP_PP_CSC_CB2CR_COEF_S		(0x02AC)
+#define VP_PP_CSC_CR2CR_COEF_S		(0x02B0)
+#define VP_ENDIAN_MODE_S		(0x03EC)
+#define VP_VERSION_INFO			(0x03FC)
+
+#define MASK(high_bit, low_bit) \
+	(((2 << ((high_bit) - (low_bit))) - 1) << (low_bit))
+
+#define MASK_VAL(val, high_bit, low_bit) \
+	(((val) << (low_bit)) & MASK(high_bit, low_bit))
+/*
+ * Bit definition part
+ */
+
+ /* VP_ENABLE */
+#define VP_ENABLE_ON_S			(1 << 2)
+#define VP_ENABLE_OPERATION_STATUS	(1 << 1)
+#define VP_ENABLE_ON			(1 << 0)
+
+/* VP_SRESET */
+#define VP_SRESET_PROCESSING		(1 << 0)
+
+/* VP_SHADOW_UPDATE */
+#define VP_SHADOW_UPDATE_ENABLE		(1 << 0)
+
+/* VP_FIELD_ID */
+#define VP_FIELD_ID_TOP			(0 << 0)
+#define VP_FIELD_ID_BOTTOM		(1 << 0)
+
+/* VP_MODE */
+#define VP_MODE_NV12			(0 << 6)
+#define VP_MODE_NV21			(1 << 6)
+#define VP_MODE_LINE_SKIP		(1 << 5)
+#define VP_MODE_MEM_LINEAR		(0 << 4)
+#define VP_MODE_MEM_TILED		(1 << 4)
+#define VP_MODE_FMT_MASK		(VP_MODE_NV21 | VP_MODE_MEM_TILED)
+#define VP_MODE_CROMA_EXP_TOP		(0 << 3)
+#define VP_MODE_CROMA_EXP_TOPBOT	(1 << 3)
+#define VP_MODE_FIELD_ID_AUTO_TOGGLING	(1 << 2)
+#define VP_MODE_2D_IPC			(1 << 1)
+
+/* VP_IMG_SIZE_Y */
+/* VP_IMG_SIZE_C */
+#define VP_IMG_HSIZE(x)			MASK_VAL(x, 29, 16)
+#define VP_IMG_VSIZE(x)			MASK_VAL(x, 13, 0)
+
+/* VP_ENDIAN_MODE */
+#define VP_ENDIAN_MODE_BIG		(0 << 0)
+#define VP_ENDIAN_MODE_LITTLE		(1 << 0)
+
+/* VP_SRC_H_POSITION */
+#define VP_SRC_H_POSITION_VAL(x)	MASK_VAL(x, 14, 4)
+
+/* VP_SRC_V_POSITION */
+#define VP_SRC_V_POSITION_VAL(x)	MASK_VAL(x, 10, 0)
+
+/* VP_SRC_WIDTH */
+/* VP_SRC_HEIGHT */
+#define VP_SRC_WIDTH_VAL(x)		MASK_VAL(x, 10, 0)
+#define VP_SRC_HEIGHT_VAL(x)		MASK_VAL(x, 10, 0)
+
+/* VP_DST_H_POSITION */
+/* VP_DST_V_POSITION */
+#define VP_DST_H_POSITION_VAL(x)	MASK_VAL(x, 10, 0)
+#define VP_DST_V_POSITION_VAL(x)	MASK_VAL(x, 10, 0)
+
+/* VP_DST_WIDTH */
+/* VP_DST_HEIGHT */
+#define VP_DST_WIDTH_VAL(x)		MASK_VAL(x, 10, 0)
+#define VP_DST_HEIGHT_VAL(x)		MASK_VAL(x, 10, 0)
+
+/* VP_H_RATIO */
+/* VP_V_RATIO */
+#define VP_H_RATIO_VAL(x)		MASK_VAL(x, 18, 0)
+#define VP_V_RATIO_VAL(x)		MASK_VAL(x, 18, 0)
+
+/* PP_CSC_Y2Y_COEF */
+#define PP_Y2Y_COEF_601_TO_709		(0x400)
+#define PP_Y2Y_COEF_709_TO_601		(0x400)
+
+/* PP_CSC_CB2Y_COEF */
+#define PP_CB2Y_COEF_601_TO_709		(0x879)
+#define PP_CB2Y_COEF_709_TO_601		(0x068)
+
+/* PP_CSC_CR2Y_COEF */
+#define PP_CR2Y_COEF_601_TO_709		(0x8D9)
+#define PP_CR2Y_COEF_709_TO_601		(0x0C9)
+
+/* PP_CSC_Y2CB_COEF */
+#define PP_Y2CB_COEF_601_TO_709		(0x0)
+#define PP_Y2CB_COEF_709_TO_601		(0x0)
+
+/* PP_CSC_CB2CB_COEF */
+#define PP_CB2CB_COEF_601_TO_709	(0x413)
+#define PP_CB2CB_COEF_709_TO_601	(0x3F6)
+
+/* PP_CSC_CR2CB_COEF */
+#define PP_CR2CB_COEF_601_TO_709	(0x875)
+#define PP_CR2CB_COEF_709_TO_601	(0x871)
+
+/* PP_CSC_Y2CR_COEF */
+#define PP_Y2CR_COEF_601_TO_709		(0x0)
+#define PP_Y2CR_COEF_709_TO_601		(0x0)
+
+/* PP_CSC_CB2CR_COEF */
+#define PP_CB2CR_COEF_601_TO_709	(0x04D)
+#define PP_CB2CR_COEF_709_TO_601	(0x84A)
+
+/* PP_CSC_CR2CR_COEF */
+#define PP_CR2CR_COEF_601_TO_709	(0x41A)
+#define PP_CR2CR_COEF_709_TO_601	(0xBEF)
+
+#define PP_CSC_COEF(x)			MASK_VAL(x, 11, 0)
+
+/* PP_BYPASS */
+#define VP_BY_PASS_ENABLE		(0)
+#define VP_BY_PASS_DISABLE		(1)
+
+/* PP_SATURATION */
+#define VP_SATURATION(x)		MASK_VAL(x, 7, 0)
+
+/* PP_SHARPNESS */
+#define VP_TH_HNOISE(x)			MASK_VAL(x, 15, 8)
+#define VP_SHARPNESS(x)			MASK_VAL(x, 1, 0)
+
+/* PP_LINE_EQ0 ~ 7 */
+#define VP_LINE_INTC(x)			MASK_VAL(x, 23, 8)
+#define VP_LINE_SLOPE(x)		MASK_VAL(x, 7, 0)
+
+/* PP_BRIGHT_OFFSET */
+#define VP_BRIGHT_OFFSET(x)		MASK_VAL(x, 8, 0)
+
+/* PP_CSC_EN */
+#define VP_SUB_Y_OFFSET_ENABLE		(1 << 1)
+#define VP_CSC_ENABLE			(1)
+
+#endif /* __ARCH_ARM_REGS_VP_H */
diff --git a/drivers/media/video/s5p-tv/sdo_drv.c b/drivers/media/video/s5p-tv/sdo_drv.c
new file mode 100644
index 0000000..b2ebe75
--- /dev/null
+++ b/drivers/media/video/s5p-tv/sdo_drv.c
@@ -0,0 +1,530 @@
+/*
+ * Samsung Standard Definition Output (SDO) driver
+ *
+ * Copyright (c) 2011 Samsung Electronics
+ *
+ * Tomasz Stanislawski, t.stanislaws@samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundiation. either version 2 of the License,
+ * or (at your option) any later version
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+#include <media/v4l2-subdev.h>
+
+#include "regs-sdo.h"
+
+MODULE_AUTHOR("Tomasz Stanislawski, t.stanislaws@samsung.com");
+MODULE_DESCRIPTION("Samsung Standard Definition Output (SDO)");
+MODULE_LICENSE("GPL");
+
+#define SDO_DEFAULT_STD	V4L2_STD_PAL_B
+
+static struct platform_driver sdo_driver;
+
+struct sdo_format {
+	v4l2_std_id id;
+	/* all modes are 720 pixels wide */
+	unsigned int height;
+	unsigned int cookie;
+};
+
+struct sdo_device {
+	/** pointer to device parent */
+	struct device *dev;
+	/** base address of SDO registers */
+	void __iomem *regs;
+	/** SDO interrupt */
+	unsigned int irq;
+	/** DAC source clock */
+	struct clk *sclk_dac;
+	/** DAC clock */
+	struct clk *dac;
+	/** DAC physical interface */
+	struct clk *dacphy;
+	/** clock for control of VPLL */
+	struct clk *fout_vpll;
+	/** regulator for SDO IP power */
+	struct regulator *vdac;
+	/** regulator for SDO plug detection */
+	struct regulator *vdet;
+	/** subdev used as device interface */
+	struct v4l2_subdev sd;
+	/** current format */
+	const struct sdo_format *fmt;
+};
+
+static inline struct sdo_device *sd_to_sdev(struct v4l2_subdev *sd)
+{
+	return container_of(sd, struct sdo_device, sd);
+}
+
+static inline
+void sdo_write_mask(struct sdo_device *sdev, u32 reg_id, u32 value, u32 mask)
+{
+	u32 old = readl(sdev->regs + reg_id);
+	value = (value & mask) | (old & ~mask);
+	writel(value, sdev->regs + reg_id);
+}
+
+static inline
+void sdo_write(struct sdo_device *sdev, u32 reg_id, u32 value)
+{
+	writel(value, sdev->regs + reg_id);
+}
+
+static inline
+u32 sdo_read(struct sdo_device *sdev, u32 reg_id)
+{
+	return readl(sdev->regs + reg_id);
+}
+
+static void sdo_reg_debug(struct sdo_device *sdev);
+
+static int __init sdo_init(void)
+{
+	int ret;
+	static const char banner[] __initdata = KERN_INFO \
+		"Samsung Standard Definition Output (SDO) driver, "
+		"(c) 2011 Samsung Electronics\n";
+	printk(banner);
+
+	ret = platform_driver_register(&sdo_driver);
+	if (ret)
+		printk(KERN_ERR "SDO platform driver register failed\n");
+
+	return ret;
+}
+module_init(sdo_init);
+
+static void __exit sdo_exit(void)
+{
+	platform_driver_unregister(&sdo_driver);
+}
+module_exit(sdo_exit);
+
+static int __devinit sdo_probe(struct platform_device *pdev);
+static int __devexit sdo_remove(struct platform_device *pdev);
+static const struct dev_pm_ops sdo_pm_ops;
+
+static struct platform_driver sdo_driver __refdata = {
+	.probe = sdo_probe,
+	.remove = __devexit_p(sdo_remove),
+	.driver = {
+		.name = "s5p-sdo",
+		.owner = THIS_MODULE,
+		.pm = &sdo_pm_ops,
+	}
+};
+
+static irqreturn_t sdo_irq_handler(int irq, void *dev_data);
+static const struct sdo_format *sdo_find_format(v4l2_std_id id);
+static const struct v4l2_subdev_ops sdo_sd_ops;
+
+static int __devinit sdo_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct sdo_device *sdev;
+	struct resource *res;
+	int ret = 0;
+	struct clk *sclk_vpll;
+
+	dev_info(dev, "probe start\n");
+	sdev = kzalloc(sizeof *sdev, GFP_KERNEL);
+	if (!sdev) {
+		dev_err(dev, "not enough memory.\n");
+		ret = -ENOMEM;
+		goto fail;
+	}
+	sdev->dev = dev;
+
+	/* mapping registers */
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(dev, "get memory resource failed.\n");
+		ret = -ENXIO;
+		goto fail_sdev;
+	}
+
+	sdev->regs = ioremap(res->start, resource_size(res));
+	if (sdev->regs == NULL) {
+		dev_err(dev, "register mapping failed.\n");
+		ret = -ENXIO;
+		goto fail_sdev;
+	}
+
+	/* acquiring interrupt */
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	if (res == NULL) {
+		dev_err(dev, "get interrupt resource failed.\n");
+		ret = -ENXIO;
+		goto fail_regs;
+	}
+	ret = request_irq(res->start, sdo_irq_handler, 0, "s5p-sdo", sdev);
+	if (ret) {
+		dev_err(dev, "request interrupt failed.\n");
+		goto fail_regs;
+	}
+	sdev->irq = res->start;
+
+	/* acquire clocks */
+	sdev->sclk_dac = clk_get(dev, "sclk_dac");
+	if (IS_ERR_OR_NULL(sdev->sclk_dac)) {
+		dev_err(dev, "failed to get clock 'sclk_dac'\n");
+		ret = -ENXIO;
+		goto fail_irq;
+	}
+	sdev->dac = clk_get(dev, "dac");
+	if (IS_ERR_OR_NULL(sdev->dac)) {
+		dev_err(dev, "failed to get clock 'dac'\n");
+		ret = -ENXIO;
+		goto fail_sclk_dac;
+	}
+	sdev->dacphy = clk_get(dev, "dacphy");
+	if (IS_ERR_OR_NULL(sdev->dacphy)) {
+		dev_err(dev, "failed to get clock 'dacphy'\n");
+		ret = -ENXIO;
+		goto fail_dac;
+	}
+	sclk_vpll = clk_get(dev, "sclk_vpll");
+	if (IS_ERR_OR_NULL(sclk_vpll)) {
+		dev_err(dev, "failed to get clock 'sclk_vpll'\n");
+		ret = -ENXIO;
+		goto fail_dacphy;
+	}
+	clk_set_parent(sdev->sclk_dac, sclk_vpll);
+	clk_put(sclk_vpll);
+	sdev->fout_vpll = clk_get(dev, "fout_vpll");
+	if (IS_ERR_OR_NULL(sdev->fout_vpll)) {
+		dev_err(dev, "failed to get clock 'fout_vpll'\n");
+		goto fail_dacphy;
+	}
+	dev_info(dev, "fout_vpll.rate = %lu\n", clk_get_rate(sclk_vpll));
+
+	/* acquire regulator */
+	sdev->vdac = regulator_get(dev, "vdd33a_dac");
+	if (IS_ERR_OR_NULL(sdev->vdac)) {
+		dev_err(dev, "failed to get regulator 'vdac'\n");
+		goto fail_fout_vpll;
+	}
+	sdev->vdet = regulator_get(dev, "vdet");
+	if (IS_ERR_OR_NULL(sdev->vdet)) {
+		dev_err(dev, "failed to get regulator 'vdet'\n");
+		goto fail_vdac;
+	}
+
+	/* configure power management */
+	pm_runtime_enable(dev);
+
+	/* configuration of interface subdevice */
+	v4l2_subdev_init(&sdev->sd, &sdo_sd_ops);
+	sdev->sd.owner = THIS_MODULE;
+	strlcpy(sdev->sd.name, sdo_driver.driver.name, sizeof sdev->sd.name);
+
+	/* set default format */
+	sdev->fmt = sdo_find_format(SDO_DEFAULT_STD);
+	BUG_ON(sdev->fmt == NULL);
+
+	/* keeping subdev in device's private for use by other drivers */
+	dev_set_drvdata(dev, &sdev->sd);
+
+	dev_info(dev, "probe succeeded\n");
+	return 0;
+
+fail_vdac:
+	regulator_put(sdev->vdac);
+fail_fout_vpll:
+	clk_put(sdev->fout_vpll);
+fail_dacphy:
+	clk_put(sdev->dacphy);
+fail_dac:
+	clk_put(sdev->dac);
+fail_sclk_dac:
+	clk_put(sdev->sclk_dac);
+fail_irq:
+	free_irq(sdev->irq, sdev);
+fail_regs:
+	iounmap(sdev->regs);
+fail_sdev:
+	kfree(sdev);
+fail:
+	dev_info(dev, "probe failed\n");
+	return ret;
+}
+
+static int __devexit sdo_remove(struct platform_device *pdev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(&pdev->dev);
+	struct sdo_device *sdev = sd_to_sdev(sd);
+
+	pm_runtime_disable(&pdev->dev);
+	regulator_put(sdev->vdet);
+	regulator_put(sdev->vdac);
+	clk_put(sdev->fout_vpll);
+	clk_put(sdev->dacphy);
+	clk_put(sdev->dac);
+	clk_put(sdev->sclk_dac);
+	free_irq(sdev->irq, sdev);
+	iounmap(sdev->regs);
+	kfree(sdev);
+
+	dev_info(&pdev->dev, "remove successful\n");
+	return 0;
+}
+
+static int sdo_runtime_suspend(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct sdo_device *sdev = sd_to_sdev(sd);
+
+	dev_info(dev, "suspend\n");
+	regulator_disable(sdev->vdet);
+	regulator_disable(sdev->vdac);
+	clk_disable(sdev->dac);
+	clk_disable(sdev->sclk_dac);
+	return 0;
+}
+
+static int sdo_runtime_resume(struct device *dev)
+{
+	struct v4l2_subdev *sd = dev_get_drvdata(dev);
+	struct sdo_device *sdev = sd_to_sdev(sd);
+
+	dev_info(dev, "resume\n");
+	clk_enable(sdev->sclk_dac);
+	clk_enable(sdev->dac);
+	regulator_enable(sdev->vdac);
+	regulator_enable(sdev->vdet);
+
+	/* software reset */
+	sdo_write_mask(sdev, SDO_CLKCON, ~0, SDO_TVOUT_SW_RESET);
+	mdelay(10);
+	sdo_write_mask(sdev, SDO_CLKCON, 0, SDO_TVOUT_SW_RESET);
+
+	/* setting TV mode */
+	sdo_write_mask(sdev, SDO_CONFIG, sdev->fmt->cookie, SDO_STANDARD_MASK);
+	/* XXX: forcing interlaced mode using undocumented bit */
+	sdo_write_mask(sdev, SDO_CONFIG, 0, SDO_PROGRESSIVE);
+	/* turn all VBI off */
+	sdo_write_mask(sdev, SDO_VBI, 0, SDO_CVBS_WSS_INS |
+		SDO_CVBS_CLOSED_CAPTION_MASK);
+	/* turn all post processing off */
+	sdo_write_mask(sdev, SDO_CCCON, ~0, SDO_COMPENSATION_BHS_ADJ_OFF |
+		SDO_COMPENSATION_CVBS_COMP_OFF);
+	sdo_reg_debug(sdev);
+	return 0;
+}
+
+static const struct dev_pm_ops sdo_pm_ops = {
+	.runtime_suspend = sdo_runtime_suspend,
+	.runtime_resume	 = sdo_runtime_resume,
+};
+
+static irqreturn_t sdo_irq_handler(int irq, void *dev_data)
+{
+	struct sdo_device *sdev = dev_data;
+
+	/* clear interrupt */
+	sdo_write_mask(sdev, SDO_IRQ, ~0, SDO_VSYNC_IRQ_PEND);
+	return IRQ_HANDLED;
+}
+
+static int sdo_s_power(struct v4l2_subdev *sd, int on);
+static int sdo_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std);
+static int sdo_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *std);
+static int sdo_g_mbus_fmt(struct v4l2_subdev *sd,
+	struct v4l2_mbus_framefmt *fmt);
+static int sdo_s_stream(struct v4l2_subdev *sd, int on);
+
+static const struct v4l2_subdev_core_ops sdo_sd_core_ops = {
+	.s_power = sdo_s_power,
+};
+
+static const struct v4l2_subdev_video_ops sdo_sd_video_ops = {
+	.s_std_output = sdo_s_std_output,
+	.querystd = NULL,
+	.g_tvnorms = sdo_g_tvnorms,
+	.g_mbus_fmt = sdo_g_mbus_fmt,
+	.s_stream = sdo_s_stream,
+};
+
+static const struct v4l2_subdev_ops sdo_sd_ops = {
+	.core = &sdo_sd_core_ops,
+	.video = &sdo_sd_video_ops,
+};
+
+static const struct sdo_format sdo_format[] = {
+	{ V4L2_STD_NTSC_M,	.height = 480, .cookie = SDO_NTSC_M },
+	{ V4L2_STD_PAL_M,	.height = 480, .cookie = SDO_PAL_M },
+	{ V4L2_STD_PAL_B,	.height = 576, .cookie = SDO_PAL_BGHID },
+	{ V4L2_STD_PAL_D,	.height = 576, .cookie = SDO_PAL_BGHID },
+	{ V4L2_STD_PAL_G,	.height = 576, .cookie = SDO_PAL_BGHID },
+	{ V4L2_STD_PAL_H,	.height = 576, .cookie = SDO_PAL_BGHID },
+	{ V4L2_STD_PAL_I,	.height = 576, .cookie = SDO_PAL_BGHID },
+	{ V4L2_STD_PAL_N,	.height = 576, .cookie = SDO_PAL_N },
+	{ V4L2_STD_PAL_Nc,	.height = 576, .cookie = SDO_PAL_NC },
+	{ V4L2_STD_NTSC_443,	.height = 480, .cookie = SDO_NTSC_443 },
+	{ V4L2_STD_PAL_60,	.height = 480, .cookie = SDO_PAL_60 },
+};
+
+static int sdo_g_tvnorms(struct v4l2_subdev *sd, v4l2_std_id *std)
+{
+	*std = V4L2_STD_NTSC_M | V4L2_STD_PAL_M | V4L2_STD_PAL_B |
+		V4L2_STD_PAL_D | V4L2_STD_PAL_G | V4L2_STD_PAL_H |
+		V4L2_STD_PAL_I | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc |
+		V4L2_STD_NTSC_443 | V4L2_STD_PAL_60;
+	return 0;
+}
+
+static int sdo_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+	struct sdo_device *sdev = sd_to_sdev(sd);
+	const struct sdo_format *fmt;
+	fmt = sdo_find_format(std);
+	if (fmt == NULL)
+		return -EINVAL;
+	sdev->fmt = fmt;
+	return 0;
+}
+
+static int sdo_g_mbus_fmt(struct v4l2_subdev *sd,
+	struct v4l2_mbus_framefmt *fmt)
+{
+	struct sdo_device *sdev = sd_to_sdev(sd);
+
+	if (!sdev->fmt)
+		return -ENXIO;
+	/* all modes are 720 pixels wide */
+	fmt->width = 720;
+	fmt->height = sdev->fmt->height;
+	fmt->code = V4L2_MBUS_FMT_FIXED;
+	fmt->field = V4L2_FIELD_INTERLACED;
+	return 0;
+}
+
+static int sdo_s_power(struct v4l2_subdev *sd, int on)
+{
+	struct sdo_device *sdev = sd_to_sdev(sd);
+	struct device *dev = sdev->dev;
+	int ret;
+
+	dev_info(dev, "sdo_s_power(%d)\n", on);
+
+	if (on)
+		ret = pm_runtime_get_sync(dev);
+	else
+		ret = pm_runtime_put_sync(dev);
+
+	/* only values < 0 indicate errors */
+	return IS_ERR_VALUE(ret) ? ret : 0;
+}
+
+static int sdo_streamon(struct sdo_device *sdev)
+{
+	/* set proper clock for Timing Generator */
+	clk_set_rate(sdev->fout_vpll, 54000000);
+	dev_info(sdev->dev, "fout_vpll.rate = %lu\n",
+		clk_get_rate(sdev->fout_vpll));
+	/* enable clock in SDO */
+	sdo_write_mask(sdev, SDO_CLKCON, ~0, SDO_TVOUT_CLOCK_ON);
+	clk_enable(sdev->dacphy);
+	/* enable DAC */
+	sdo_write_mask(sdev, SDO_DAC, ~0, SDO_POWER_ON_DAC);
+	sdo_reg_debug(sdev);
+	return 0;
+}
+
+static int sdo_streamoff(struct sdo_device *sdev)
+{
+	int tries;
+
+	sdo_write_mask(sdev, SDO_DAC, 0, SDO_POWER_ON_DAC);
+	clk_disable(sdev->dacphy);
+	sdo_write_mask(sdev, SDO_CLKCON, 0, SDO_TVOUT_CLOCK_ON);
+	for (tries = 100; tries; --tries) {
+		if (sdo_read(sdev, SDO_CLKCON) & SDO_TVOUT_CLOCK_READY)
+			break;
+		mdelay(1);
+	}
+	if (tries == 0)
+		dev_err(sdev->dev, "failed to stop streaming\n");
+	return tries ? 0 : -EIO;
+}
+
+static int sdo_s_stream(struct v4l2_subdev *sd, int on)
+{
+	struct sdo_device *sdev = sd_to_sdev(sd);
+	if (on)
+		return sdo_streamon(sdev);
+	else
+		return sdo_streamoff(sdev);
+}
+
+static const struct sdo_format *sdo_find_format(v4l2_std_id id)
+{
+	int i;
+	for (i = 0; i < ARRAY_SIZE(sdo_format); ++i)
+		if (sdo_format[i].id & id)
+			return &sdo_format[i];
+	return NULL;
+}
+
+static void sdo_reg_debug(struct sdo_device *sdev)
+{
+#define DBGREG(reg_id) \
+	dev_info(sdev->dev, #reg_id " = %08x\n", \
+		sdo_read(sdev, reg_id))
+
+	DBGREG(SDO_CLKCON);
+	DBGREG(SDO_CONFIG);
+	DBGREG(SDO_SCALE);
+	DBGREG(SDO_SYNC);
+	DBGREG(SDO_VBI);
+	DBGREG(SDO_SCALE_CH0);
+	DBGREG(SDO_SCALE_CH1);
+	DBGREG(SDO_SCALE_CH2);
+	DBGREG(SDO_YCDELAY);
+	DBGREG(SDO_SCHLOCK);
+	DBGREG(SDO_DAC);
+	DBGREG(SDO_FINFO);
+	DBGREG(SDO_CCCON);
+	DBGREG(SDO_YSCALE);
+	DBGREG(SDO_CBSCALE);
+	DBGREG(SDO_CRSCALE);
+	DBGREG(SDO_CB_CR_OFFSET);
+	DBGREG(SDO_CVBS_CC_Y1);
+	DBGREG(SDO_CVBS_CC_Y2);
+	DBGREG(SDO_CVBS_CC_C);
+	DBGREG(SDO_CSC_525_PORCH);
+	DBGREG(SDO_CSC_625_PORCH);
+	DBGREG(SDO_XTALK0);
+	DBGREG(SDO_XTALK1);
+	DBGREG(SDO_XTALK2);
+	DBGREG(SDO_BB_CTRL);
+	DBGREG(SDO_IRQ);
+	DBGREG(SDO_IRQMASK);
+	DBGREG(SDO_ARMCC);
+	DBGREG(SDO_ARMWSS525);
+	DBGREG(SDO_ARMWSS625);
+	DBGREG(SDO_ARMCGMS525);
+	DBGREG(SDO_ARMCGMS625);
+	DBGREG(SDO_VERSION);
+	DBGREG(SDO_CC);
+	DBGREG(SDO_WSS525);
+	DBGREG(SDO_WSS625);
+	DBGREG(SDO_CGMS525);
+	DBGREG(SDO_CGMS625);
+}
-- 
1.7.5.1


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v4 0/3] TV driver for Samsung S5P platform (media part)
  2011-05-31 10:20 ` Tomasz Stanislawski
@ 2011-06-02  0:57   ` Kyungmin Park
  0 siblings, 0 replies; 7+ messages in thread
From: Kyungmin Park @ 2011-06-02  0:57 UTC (permalink / raw)
  To: Tomasz Stanislawski
  Cc: jiun.yu, linux-media, Marek Szyprowski, hverkuil,
	선경일, 김영락,
	이일호, 김경환

Hi,

It's good to know the future chip design changes. but as it doesn't be
known to others except the internal chip design team.
So with restricted information. there's no way to implement it with
current known chip.
If you want to change the design. open and show the changed IPs.

another thing is that current codes are pending for long time. so in
our case, merge it first and expand it for next chips.

Thank you,
Kyungmin Park

On Tue, May 31, 2011 at 7:20 PM, Tomasz Stanislawski
<t.stanislaws@samsung.com> wrote:
> JiUn Yu wrote:
>>
>>
>>>
>>> 5. Mixer & Video Processor driver. It is called 's5p-mixer' because of
>>> historical reasons. It was decided combine VP and MXR drivers into one
>>> because
>>> of shared interrupt and very similar interface via V4L2 nodes. The driver
>>> is a
>>> realization of many-to-many relation between multiple input layers and
>>> multiple
>>> outputs. All shared resources are kept in struct mxr_device. It provides
>>> utilities for management and synchronization of access to resources and
>>> reference counting. The outputs are obtained from HDMI/SDO private data.
>>>  One
>>> layer is a single video node. Simple inheritance is applied because there
>>> only
>>> little difference between layer's types. Every layer type implements set
>>> of
>>> ops.  There are different ops for Mixer layers and other for VP layer.
>>>
>>
>> I agreed with subdev of hdmi, hdmiphy, sdo and videoDAC. It is very
>> flexible in case of adding new interface or removing current interface.
>> But 's5p-mixer' driver is not flexible. So, If new scaler is added instead
>> of VP or mixer is someting changed,
>> I think current architecture of tvout driver can't support.
>> How about separating vp and mixer driver?
>>
>
> Hi Yu,
> The designed architecture TV driver was not prepared for removal of VP, or
> MIxer input nodes.
> I decided only to allow flexible outputs because I knew 2 boards with
> different output configuration (Goni - only SDO, Universal - HDMI and SDO).
> I need more information about VP substitute before changing design of the
> whole driver. Some of extensions could be applied by adding extra layer type
> to existing layer_vp and layer_grp ones.
>
> Best regards
> Tomasz Stanislawski
>>
>> N떑꿩�r툤y鉉싕b쾊Ф푤v�^�)頻{.n�+돴쪐{콡�bj)�鍊w* jgП� 텎쉸듶줷/곴�z받뻿�2듷솳鈺�&�)傘첺뛴�� 췍쳺�h�
>> �j:+v돣둾�明
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-media" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v4 0/3] TV driver for Samsung S5P platform (media part)
  2011-05-29 11:33 [PATCH v4 0/3] TV driver for Samsung S5P platform (media part) JiUn Yu
@ 2011-05-31 10:20 ` Tomasz Stanislawski
  2011-06-02  0:57   ` Kyungmin Park
  0 siblings, 1 reply; 7+ messages in thread
From: Tomasz Stanislawski @ 2011-05-31 10:20 UTC (permalink / raw)
  To: jiun.yu
  Cc: linux-media, Marek Szyprowski, Kyungmin Park, hverkuil,
	선경일, 김영락,
	이일호, 김경환

JiUn Yu wrote:
>   
>> 5. Mixer & Video Processor driver. It is called 's5p-mixer' because of
>> historical reasons. It was decided combine VP and MXR drivers into one because
>> of shared interrupt and very similar interface via V4L2 nodes. The driver is a
>> realization of many-to-many relation between multiple input layers and multiple
>> outputs. All shared resources are kept in struct mxr_device. It provides
>> utilities for management and synchronization of access to resources and
>> reference counting. The outputs are obtained from HDMI/SDO private data.  One
>> layer is a single video node. Simple inheritance is applied because there only
>> little difference between layer's types. Every layer type implements set of
>> ops.  There are different ops for Mixer layers and other for VP layer.
>>     
>
> I agreed with subdev of hdmi, hdmiphy, sdo and videoDAC. It is very flexible in case of adding new interface or removing current interface.
> But 's5p-mixer' driver is not flexible. So, If new scaler is added instead of VP or mixer is someting changed,
> I think current architecture of tvout driver can't support.
> How about separating vp and mixer driver?
>   
Hi Yu,
The designed architecture TV driver was not prepared for removal of VP, 
or MIxer input nodes.
I decided only to allow flexible outputs because I knew 2 boards with 
different output configuration (Goni - only SDO, Universal - HDMI and SDO).
I need more information about VP substitute before changing design of 
the whole driver. Some of extensions could be applied by adding extra 
layer type to existing layer_vp and layer_grp ones.

Best regards
Tomasz Stanislawski
> N떑꿩�r툤y鉉싕b쾊Ф푤v�^�)頻{.n�+돴쪐{콡�bj)�鍊w*\x1fjgП�\x1e텎쉸듶줷/곴�z받뻿�2듷솳鈺�&�)傘첺뛴��\x1e췍쳺�h�\x0f�j:+v돣둾�明


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v4 0/3] TV driver for Samsung S5P platform (media part)
@ 2011-05-29 11:33 JiUn Yu
  2011-05-31 10:20 ` Tomasz Stanislawski
  0 siblings, 1 reply; 7+ messages in thread
From: JiUn Yu @ 2011-05-29 11:33 UTC (permalink / raw)
  To: Tomasz Stanislawski, linux-media
  Cc: Marek Szyprowski, Kyungmin Park, hverkuil,
	선경일, 김영락,
	이일호, 김경환



> 5. Mixer & Video Processor driver. It is called 's5p-mixer' because of
> historical reasons. It was decided combine VP and MXR drivers into one because
> of shared interrupt and very similar interface via V4L2 nodes. The driver is a
> realization of many-to-many relation between multiple input layers and multiple
> outputs. All shared resources are kept in struct mxr_device. It provides
> utilities for management and synchronization of access to resources and
> reference counting. The outputs are obtained from HDMI/SDO private data.  One
> layer is a single video node. Simple inheritance is applied because there only
> little difference between layer's types. Every layer type implements set of
> ops.  There are different ops for Mixer layers and other for VP layer.

I agreed with subdev of hdmi, hdmiphy, sdo and videoDAC. It is very flexible in case of adding new interface or removing current interface.
But 's5p-mixer' driver is not flexible. So, If new scaler is added instead of VP or mixer is someting changed,
I think current architecture of tvout driver can't support.
How about separating vp and mixer driver?


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2011-06-02  0:57 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-24 13:09 [PATCH v4 0/3] TV driver for Samsung S5P platform (media part) Tomasz Stanislawski
2011-05-24 13:09 ` [PATCH 1/3] v4l: add macro for 1080p59_54 preset Tomasz Stanislawski
2011-05-24 13:09 ` [PATCH 2/3] v4l: add g_tvnorms callback to V4L2 subdev Tomasz Stanislawski
2011-05-24 13:09 ` [PATCH 3/3] s5p-tv: add drivers for TV on Samsung S5P platform Tomasz Stanislawski
2011-05-29 11:33 [PATCH v4 0/3] TV driver for Samsung S5P platform (media part) JiUn Yu
2011-05-31 10:20 ` Tomasz Stanislawski
2011-06-02  0:57   ` Kyungmin Park

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.