All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 2/2]ARM: EXYNOS: support mipi dsi driver
@ 2012-04-04  6:29 Donghwa Lee
  0 siblings, 0 replies; only message in thread
From: Donghwa Lee @ 2012-04-04  6:29 UTC (permalink / raw)
  To: u-boot

This patch is MIPI DSI interface driver for EXYNOS SoC

Signed-off-by: Donghwa Lee <dh09.lee@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 arch/arm/include/asm/arch-exynos/dsim.h      |  181 +++++++
 arch/arm/include/asm/arch-exynos/mipi_dsim.h |  392 +++++++++++++++
 drivers/video/Makefile                       |    3 +
 drivers/video/exynos_fb.c                    |    4 +
 drivers/video/exynos_mipi_dsi.c              |  256 ++++++++++
 drivers/video/exynos_mipi_dsi_common.c       |  645 +++++++++++++++++++++++++
 drivers/video/exynos_mipi_dsi_common.h       |   48 ++
 drivers/video/exynos_mipi_dsi_lowlevel.c     |  669 ++++++++++++++++++++++++++
 drivers/video/exynos_mipi_dsi_lowlevel.h     |  111 +++++
 drivers/video/s6e8ax0.c                      |  289 +++++++++++
 include/lcd.h                                |    1 +
 11 files changed, 2599 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-exynos/dsim.h
 create mode 100644 arch/arm/include/asm/arch-exynos/mipi_dsim.h
 create mode 100644 drivers/video/exynos_mipi_dsi.c
 create mode 100644 drivers/video/exynos_mipi_dsi_common.c
 create mode 100644 drivers/video/exynos_mipi_dsi_common.h
 create mode 100644 drivers/video/exynos_mipi_dsi_lowlevel.c
 create mode 100644 drivers/video/exynos_mipi_dsi_lowlevel.h
 create mode 100644 drivers/video/s6e8ax0.c

diff --git a/arch/arm/include/asm/arch-exynos/dsim.h b/arch/arm/include/asm/arch-exynos/dsim.h
new file mode 100644
index 0000000..e148aca
--- /dev/null
+++ b/arch/arm/include/asm/arch-exynos/dsim.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * Author: InKi Dae <inki.dae@samsung.com>
+ * Author: Donghwa Lee <dh09.lee@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __ASM_ARM_ARCH_DSIM_H_
+#define __ASM_ARM_ARCH_DSIM_H_
+
+#ifndef __ASSEMBLY__
+
+struct exynos_mipi_dsim {
+	unsigned int	status;
+	unsigned int	swrst;
+	unsigned int	clkctrl;
+	unsigned int	timeout;
+	unsigned int	config;
+	unsigned int	escmode;
+	unsigned int	mdresol;
+	unsigned int	mvporch;
+	unsigned int	mhporch;
+	unsigned int	msync;
+	unsigned int	sdresol;
+	unsigned int	intsrc;
+	unsigned int	intmsk;
+	unsigned int	pkthdr;
+	unsigned int	payload;
+	unsigned int	rxfifo;
+	unsigned int	fifothld;
+	unsigned int	fifoctrl;
+	unsigned int	memacchr;
+	unsigned int	pllctrl;
+	unsigned int	plltmr;
+	unsigned int	phyacchr;
+	unsigned int	phyacchr1;
+};
+
+#endif	/* __ASSEMBLY__ */
+
+/*
+ * Bit Definitions
+ */
+/* DSIM_STATUS */
+#define DSIM_STOP_STATE_DAT(x)	(((x) & 0xf) << 0)
+#define DSIM_STOP_STATE_CLK	(1 << 8)
+#define DSIM_TX_READY_HS_CLK	(1 << 10)
+#define DSIM_PLL_STABLE		(1 << 31)
+
+/* DSIM_SWRST */
+#define DSIM_FUNCRST		(1 << 16)
+#define DSIM_SWRST		(1 << 0)
+
+/* EXYNOS_DSIM_TIMEOUT */
+#define DSIM_LPDR_TOUT_SHIFT	(0)
+#define DSIM_BTA_TOUT_SHIFT	(16)
+
+/* EXYNOS_DSIM_CLKCTRL */
+#define DSIM_LANE_ESC_CLKEN_SHIFT	(19)
+#define DSIM_BYTE_CLKEN_SHIFT		(24)
+#define DSIM_BYTE_CLK_SRC_SHIFT		(25)
+#define DSIM_PLL_BYPASS_SHIFT		(27)
+#define DSIM_ESC_CLKEN_SHIFT		(28)
+#define DSIM_TX_REQUEST_HSCLK_SHIFT	(31)
+#define DSIM_LANE_ESC_CLKEN(x)		(((x) & 0x1f) << \
+						DSIM_LANE_ESC_CLKEN_SHIFT)
+#define DSIM_BYTE_CLK_ENABLE		(1 << DSIM_BYTE_CLKEN_SHIFT)
+#define DSIM_BYTE_CLK_DISABLE		(0 << DSIM_BYTE_CLKEN_SHIFT)
+#define DSIM_PLL_BYPASS_EXTERNAL	(1 << DSIM_PLL_BYPASS_SHIFT)
+#define DSIM_ESC_CLKEN_ENABLE		(1 << DSIM_ESC_CLKEN_SHIFT)
+#define DSIM_ESC_CLKEN_DISABLE		(0 << DSIM_ESC_CLKEN_SHIFT)
+
+/* EXYNOS_DSIM_CONFIG */
+#define DSIM_NUM_OF_DATALANE_SHIFT	(5)
+#define DSIM_SUBPIX_SHIFT		(8)
+#define DSIM_MAINPIX_SHIFT		(12)
+#define DSIM_SUBVC_SHIFT		(16)
+#define DSIM_MAINVC_SHIFT		(18)
+#define DSIM_HSA_MODE_SHIFT		(20)
+#define DSIM_HBP_MODE_SHIFT		(21)
+#define DSIM_HFP_MODE_SHIFT		(22)
+#define DSIM_HSE_MODE_SHIFT		(23)
+#define DSIM_AUTO_MODE_SHIFT		(24)
+#define DSIM_VIDEO_MODE_SHIFT		(25)
+#define DSIM_BURST_MODE_SHIFT		(26)
+#define DSIM_EOT_PACKET_SHIFT		(28)
+#define DSIM_AUTO_FLUSH_SHIFT		(29)
+#define DSIM_LANE_ENx(x)		(((x) & 0x1f) << 0)
+
+#define DSIM_NUM_OF_DATA_LANE(x)	((x) << DSIM_NUM_OF_DATALANE_SHIFT)
+
+/* EXYNOS_DSIM_ESCMODE */
+#define DSIM_TX_LPDT_SHIFT		(6)
+#define DSIM_CMD_LPDT_SHIFT		(7)
+#define DSIM_TX_LPDT_LP			(1 << DSIM_TX_LPDT_SHIFT)
+#define DSIM_CMD_LPDT_LP		(1 << DSIM_CMD_LPDT_SHIFT)
+#define DSIM_STOP_STATE_CNT_SHIFT	(21)
+#define DSIM_FORCE_STOP_STATE_SHIFT	(20)
+
+/* EXYNOS_DSIM_MDRESOL */
+#define DSIM_MAIN_STAND_BY		(1 << 31)
+#define DSIM_MAIN_VRESOL(x)		(((x) & 0x7ff) << 16)
+#define DSIM_MAIN_HRESOL(x)		(((x) & 0X7ff) << 0)
+
+/* EXYNOS_DSIM_MVPORCH */
+#define DSIM_CMD_ALLOW_SHIFT		(28)
+#define DSIM_STABLE_VFP_SHIFT		(16)
+#define DSIM_MAIN_VBP_SHIFT		(0)
+#define DSIM_CMD_ALLOW_MASK		(0xf << DSIM_CMD_ALLOW_SHIFT)
+#define DSIM_STABLE_VFP_MASK		(0x7ff << DSIM_STABLE_VFP_SHIFT)
+#define DSIM_MAIN_VBP_MASK		(0x7ff << DSIM_MAIN_VBP_SHIFT)
+
+/* EXYNOS_DSIM_MHPORCH */
+#define DSIM_MAIN_HFP_SHIFT		(16)
+#define DSIM_MAIN_HBP_SHIFT		(0)
+#define DSIM_MAIN_HFP_MASK		((0xffff) << DSIM_MAIN_HFP_SHIFT)
+#define DSIM_MAIN_HBP_MASK		((0xffff) << DSIM_MAIN_HBP_SHIFT)
+
+/* EXYNOS_DSIM_MSYNC */
+#define DSIM_MAIN_VSA_SHIFT		(22)
+#define DSIM_MAIN_HSA_SHIFT		(0)
+#define DSIM_MAIN_VSA_MASK		((0x3ff) << DSIM_MAIN_VSA_SHIFT)
+#define DSIM_MAIN_HSA_MASK		((0xffff) << DSIM_MAIN_HSA_SHIFT)
+
+/* EXYNOS_DSIM_SDRESOL */
+#define DSIM_SUB_STANDY_SHIFT		(31)
+#define DSIM_SUB_VRESOL_SHIFT		(16)
+#define DSIM_SUB_HRESOL_SHIFT		(0)
+#define DSIM_SUB_STANDY_MASK		((0x1) << DSIM_SUB_STANDY_SHIFT)
+#define DSIM_SUB_VRESOL_MASK		((0x7ff) << DSIM_SUB_VRESOL_SHIFT)
+#define DSIM_SUB_HRESOL_MASK		((0x7ff) << DSIM_SUB_HRESOL_SHIFT)
+
+/* EXYNOS_DSIM_INTSRC */
+#define INTSRC_FRAME_DONE		(1 << 24)
+#define INTSRC_PLL_STABLE		(1 << 31)
+#define INTSRC_SWRST_RELEASE		(1 << 30)
+
+/* EXYNOS_DSIM_INTMSK */
+#define INTMSK_FRAME_DONE		(1 << 24)
+
+/* EXYNOS_DSIM_FIFOCTRL */
+#define SFR_HEADER_EMPTY		(1 << 22)
+
+/* EXYNOS_DSIM_PKTHDR */
+#define DSIM_PKTHDR_DI(x)		(((x) & 0x3f) << 0)
+#define DSIM_PKTHDR_DAT0(x)		((x) << 8)
+#define DSIM_PKTHDR_DAT1(x)		((x) << 16)
+
+/* EXYNOS_DSIM_PHYACCHR */
+#define DSIM_AFC_CTL(x)			(((x) & 0x7) << 5)
+#define DSIM_AFC_CTL_SHIFT		(5)
+#define DSIM_AFC_EN			(1 << 14)
+
+/* EXYNOS_DSIM_PHYACCHR1 */
+#define DSIM_DPDN_SWAP_DATA_SHIFT	(0)
+
+/* EXYNOS_DSIM_PLLCTRL */
+#define DSIM_SCALER_SHIFT		(1)
+#define DSIM_MAIN_SHIFT			(4)
+#define DSIM_PREDIV_SHIFT		(13)
+#define DSIM_PRECTRL_SHIFT		(20)
+#define DSIM_PLL_EN_SHIFT		(23)
+#define DSIM_FREQ_BAND_SHIFT		(24)
+#define DSIM_ZEROCTRL_SHIFT		(28)
+
+#endif
diff --git a/arch/arm/include/asm/arch-exynos/mipi_dsim.h b/arch/arm/include/asm/arch-exynos/mipi_dsim.h
new file mode 100644
index 0000000..d94ae5a
--- /dev/null
+++ b/arch/arm/include/asm/arch-exynos/mipi_dsim.h
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * Author: InKi Dae <inki.dae@samsung.com>
+ * Author: Donghwa Lee <dh09.lee@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _DSIM_H
+#define _DSIM_H
+
+#include <linux/fb.h>
+
+#define PANEL_NAME_SIZE		(32)
+
+enum mipi_dsim_interface_type {
+	DSIM_COMMAND,
+	DSIM_VIDEO
+};
+
+enum mipi_dsim_virtual_ch_no {
+	DSIM_VIRTUAL_CH_0,
+	DSIM_VIRTUAL_CH_1,
+	DSIM_VIRTUAL_CH_2,
+	DSIM_VIRTUAL_CH_3
+};
+
+enum mipi_dsim_burst_mode_type {
+	DSIM_NON_BURST_SYNC_EVENT,
+	DSIM_BURST_SYNC_EVENT,
+	DSIM_NON_BURST_SYNC_PULSE,
+	DSIM_BURST,
+	DSIM_NON_VIDEO_MODE
+};
+
+enum mipi_dsim_no_of_data_lane {
+	DSIM_DATA_LANE_1,
+	DSIM_DATA_LANE_2,
+	DSIM_DATA_LANE_3,
+	DSIM_DATA_LANE_4
+};
+
+enum mipi_dsim_byte_clk_src {
+	DSIM_PLL_OUT_DIV8,
+	DSIM_EXT_CLK_DIV8,
+	DSIM_EXT_CLK_BYPASS
+};
+
+enum mipi_dsim_pixel_format {
+	DSIM_CMD_3BPP,
+	DSIM_CMD_8BPP,
+	DSIM_CMD_12BPP,
+	DSIM_CMD_16BPP,
+	DSIM_VID_16BPP_565,
+	DSIM_VID_18BPP_666PACKED,
+	DSIM_18BPP_666LOOSELYPACKED,
+	DSIM_24BPP_888
+};
+
+/* MIPI DSI Processor-to-Peripheral transaction types */
+enum {
+	MIPI_DSI_V_SYNC_START				= 0x01,
+	MIPI_DSI_V_SYNC_END				= 0x11,
+	MIPI_DSI_H_SYNC_START				= 0x21,
+	MIPI_DSI_H_SYNC_END				= 0x31,
+
+	MIPI_DSI_COLOR_MODE_OFF				= 0x02,
+	MIPI_DSI_COLOR_MODE_ON				= 0x12,
+	MIPI_DSI_SHUTDOWN_PERIPHERAL			= 0x22,
+	MIPI_DSI_TURN_ON_PERIPHERAL			= 0x32,
+
+	MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM		= 0x03,
+	MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM		= 0x13,
+	MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM		= 0x23,
+
+	MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM		= 0x04,
+	MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM		= 0x14,
+	MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM		= 0x24,
+
+	MIPI_DSI_DCS_SHORT_WRITE			= 0x05,
+	MIPI_DSI_DCS_SHORT_WRITE_PARAM			= 0x15,
+
+	MIPI_DSI_DCS_READ				= 0x06,
+
+	MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE		= 0x37,
+
+	MIPI_DSI_END_OF_TRANSMISSION			= 0x08,
+
+	MIPI_DSI_NULL_PACKET				= 0x09,
+	MIPI_DSI_BLANKING_PACKET			= 0x19,
+	MIPI_DSI_GENERIC_LONG_WRITE			= 0x29,
+	MIPI_DSI_DCS_LONG_WRITE				= 0x39,
+
+	MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20	= 0x0c,
+	MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24		= 0x1c,
+	MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16		= 0x2c,
+
+	MIPI_DSI_PACKED_PIXEL_STREAM_30			= 0x0d,
+	MIPI_DSI_PACKED_PIXEL_STREAM_36			= 0x1d,
+	MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12		= 0x3d,
+
+	MIPI_DSI_PACKED_PIXEL_STREAM_16			= 0x0e,
+	MIPI_DSI_PACKED_PIXEL_STREAM_18			= 0x1e,
+	MIPI_DSI_PIXEL_STREAM_3BYTE_18			= 0x2e,
+	MIPI_DSI_PACKED_PIXEL_STREAM_24			= 0x3e,
+};
+
+/*
+ * struct mipi_dsim_config - interface for configuring mipi-dsi controller.
+ *
+ * @auto_flush: enable or disable Auto flush of MD FIFO using VSYNC pulse.
+ * @eot_disable: enable or disable EoT packet in HS mode.
+ * @auto_vertical_cnt: specifies auto vertical count mode.
+ *	in Video mode, the vertical line transition uses line counter
+ *	configured by VSA, VBP, and Vertical resolution.
+ *	If this bit is set to '1', the line counter does not use VSA and VBP
+ *	registers.(in command mode, this variable is ignored)
+ * @hse: set horizontal sync event mode.
+ *	In VSYNC pulse and Vporch area, MIPI DSI master transfers only HSYNC
+ *	start packet to MIPI DSI slave at MIPI DSI spec1.1r02.
+ *	this bit transfers HSYNC end packet in VSYNC pulse and Vporch area
+ *	(in mommand mode, this variable is ignored)
+ * @hfp: specifies HFP disable mode.
+ *	if this variable is set, DSI master ignores HFP area in VIDEO mode.
+ *	(in command mode, this variable is ignored)
+ * @hbp: specifies HBP disable mode.
+ *	if this variable is set, DSI master ignores HBP area in VIDEO mode.
+ *	(in command mode, this variable is ignored)
+ * @hsa: specifies HSA disable mode.
+ *	if this variable is set, DSI master ignores HSA area in VIDEO mode.
+ *	(in command mode, this variable is ignored)
+ * @e_interface: specifies interface to be used.(CPU or RGB interface)
+ * @e_virtual_ch: specifies virtual channel number that main or
+ *	sub diaplsy uses.
+ * @e_pixel_format: specifies pixel stream format for main or sub display.
+ * @e_burst_mode: selects Burst mode in Video mode.
+ *	in Non-burst mode, RGB data area is filled with RGB data and NULL
+ *	packets, according to input bandwidth of RGB interface.
+ *	In Burst mode, RGB data area is filled with RGB data only.
+ * @e_no_data_lane: specifies data lane count to be used by Master.
+ * @e_byte_clk: select byte clock source. (it must be DSIM_PLL_OUT_DIV8)
+ *	DSIM_EXT_CLK_DIV8 and DSIM_EXT_CLK_BYPASSS are not supported.
+ * @pll_stable_time: specifies the PLL Timer for stability of the ganerated
+ *	clock(System clock cycle base)
+ *	if the timer value goes to 0x00000000, the clock stable bit of status
+ *	and interrupt register is set.
+ * @esc_clk: specifies escape clock frequency for getting the escape clock
+ *	prescaler value.
+ * @stop_holding_cnt: specifies the interval value between transmitting
+ *	read packet(or write "set_tear_on" command) and BTA request.
+ *	after transmitting read packet or write "set_tear_on" command,
+ *	BTA requests to D-PHY automatically. this counter value specifies
+ *	the interval between them.
+ * @bta_timeout: specifies the timer for BTA.
+ *	this register specifies time out from BTA request to change
+ *	the direction with respect to Tx escape clock.
+ * @rx_timeout: specifies the timer for LP Rx mode timeout.
+ *	this register specifies time out on how long RxValid deasserts,
+ *	after RxLpdt asserts with respect to Tx escape clock.
+ *	- RxValid specifies Rx data valid indicator.
+ *	- RxLpdt specifies an indicator that D-PHY is under RxLpdt mode.
+ *	- RxValid and RxLpdt specifies signal from D-PHY.
+ */
+struct mipi_dsim_config {
+	unsigned char			auto_flush;
+	unsigned char			eot_disable;
+
+	unsigned char			auto_vertical_cnt;
+	unsigned char			hse;
+	unsigned char			hfp;
+	unsigned char			hbp;
+	unsigned char			hsa;
+
+	enum mipi_dsim_interface_type	e_interface;
+	enum mipi_dsim_virtual_ch_no	e_virtual_ch;
+	enum mipi_dsim_pixel_format	e_pixel_format;
+	enum mipi_dsim_burst_mode_type	e_burst_mode;
+	enum mipi_dsim_no_of_data_lane	e_no_data_lane;
+	enum mipi_dsim_byte_clk_src	e_byte_clk;
+
+	/*
+	 * ===========================================
+	 * |    P    |    M    |    S    |    MHz    |
+	 * -------------------------------------------
+	 * |    3    |   100   |    3    |    100    |
+	 * |    3    |   100   |    2    |    200    |
+	 * |    3    |    63   |    1    |    252    |
+	 * |    4    |   100   |    1    |    300    |
+	 * |    4    |   110   |    1    |    330    |
+	 * |   12    |   350   |    1    |    350    |
+	 * |    3    |   100   |    1    |    400    |
+	 * |    4    |   150   |    1    |    450    |
+	 * |    6    |   118   |    1    |    472    |
+	 * |	3    |   120   |    1    |    480    |
+	 * |   12    |   250   |    0    |    500    |
+	 * |    4    |   100   |    0    |    600    |
+	 * |    3    |    81   |    0    |    648    |
+	 * |    3    |    88   |    0    |    704    |
+	 * |    3    |    90   |    0    |    720    |
+	 * |    3    |   100   |    0    |    800    |
+	 * |   12    |   425   |    0    |    850    |
+	 * |    4    |   150   |    0    |    900    |
+	 * |   12    |   475   |    0    |    950    |
+	 * |    6    |   250   |    0    |   1000    |
+	 * -------------------------------------------
+	 */
+
+	/*
+	 * pms could be calculated as the following.
+	 * M * 24 / P * 2 ^ S = MHz
+	 */
+	unsigned char			p;
+	unsigned short			m;
+	unsigned char			s;
+
+	unsigned int			pll_stable_time;
+	unsigned long			esc_clk;
+
+	unsigned short			stop_holding_cnt;
+	unsigned char			bta_timeout;
+	unsigned short			rx_timeout;
+};
+
+/*
+ * struct mipi_dsim_device - global interface for mipi-dsi driver.
+ *
+ * @dev: driver model representation of the device.
+ * @id: unique device id.
+ * @clock: pointer to MIPI-DSI clock of clock framework.
+ * @irq: interrupt number to MIPI-DSI controller.
+ * @reg_base: base address to memory mapped SRF of MIPI-DSI controller.
+ *	(virtual address)
+ * @lock: the mutex protecting this data structure.
+ * @dsim_info: infomation for configuring mipi-dsi controller.
+ * @master_ops: callbacks to mipi-dsi operations.
+ * @dsim_lcd_dev: pointer to activated ddi device.
+ *	(it would be registered by mipi-dsi driver.)
+ * @dsim_lcd_drv: pointer to activated_ddi driver.
+ *	(it would be registered by mipi-dsi driver.)
+ * @lcd_info: pointer to mipi_lcd_info structure.
+ * @state: specifies status of MIPI-DSI controller.
+ *	the status could be RESET, INIT, STOP, HSCLKEN and ULPS.
+ * @resume_complete: indicates whether resume operation is completed or not.
+ * @data_lane: specifiec enabled data lane number.
+ *	this variable would be set by driver according to e_no_data_lane
+ *	automatically.
+ * @e_clk_src: select byte clock source.
+ * @pd: pointer to MIPI-DSI driver platform data.
+ */
+struct mipi_dsim_device {
+	struct mipi_dsim_config		*dsim_config;
+	struct mipi_dsim_master_ops	*master_ops;
+	struct mipi_dsim_lcd_device	*dsim_lcd_dev;
+	struct mipi_dsim_lcd_driver	*dsim_lcd_drv;
+
+	unsigned int			state;
+	unsigned int			data_lane;
+	enum mipi_dsim_byte_clk_src	e_clk_src;
+
+	struct exynos_platform_mipi_dsim	*pd;
+};
+
+/*
+ * struct exynos_platform_mipi_dsim - interface to platform data
+ *	for mipi-dsi driver.
+ *
+ * @lcd_panel_name: specifies lcd panel name registered to mipi-dsi driver.
+ *	lcd panel driver searched would be actived.
+ * @dsim_config: pointer of structure for configuring mipi-dsi controller.
+ * @lcd_panel_info: pointer for lcd panel specific structure.
+ *	this structure specifies width, height, timing and polarity and so on.
+ * @mipi_power: callback pointer for enabling or disabling mipi power.
+ * @phy_enable: pointer to a callback controlling D-PHY enable/reset
+ */
+struct exynos_platform_mipi_dsim {
+	char				lcd_panel_name[PANEL_NAME_SIZE];
+
+	struct mipi_dsim_config		*dsim_config;
+	void				*lcd_panel_info;
+
+	int (*lcd_power)(void);
+	int (*mipi_power)(void);
+	int (*phy_enable)(int on, u32 reset);
+};
+/*
+ * struct mipi_dsim_master_ops - callbacks to mipi-dsi operations.
+ *
+ * @cmd_write: transfer command to lcd panel at LP mode.
+ * @cmd_read: read command from rx register.
+ * @get_dsim_frame_done: get the status that all screen data have been
+ *	transferred to mipi-dsi.
+ * @clear_dsim_frame_done: clear frame done status.
+ * @get_fb_frame_done: get frame done status of display controller.
+ * @trigger: trigger display controller.
+ *	- this one would be used only in case of CPU mode.
+ */
+
+struct mipi_dsim_master_ops {
+	int (*cmd_write)(struct mipi_dsim_device *dsim, unsigned int data_id,
+		unsigned int data0, unsigned int data1);
+	int (*cmd_read)(struct mipi_dsim_device *dsim, unsigned int data_id,
+		unsigned int data0, unsigned int data1);
+	int (*get_dsim_frame_done)(struct mipi_dsim_device *dsim);
+	int (*clear_dsim_frame_done)(struct mipi_dsim_device *dsim);
+
+	int (*get_fb_frame_done)(void);
+	void (*trigger)(struct fb_info *info);
+};
+
+/*
+ * device structure for mipi-dsi based lcd panel.
+ *
+ * @name: name of the device to use with this device, or an
+ *	alias for that name.
+ * @dev: driver model representation of the device.
+ * @id: id of device to be registered.
+ * @bus_id: bus id for identifing connected bus
+ *	and this bus id should be same as id of mipi_dsim_device.
+ * @irq: irq number for signaling when framebuffer transfer of
+ *	lcd panel module is completed.
+ *	this irq would be used only for MIPI-DSI based CPU mode lcd panel.
+ * @master: pointer to mipi-dsi master device object.
+ * @platform_data: lcd panel specific platform data.
+ */
+struct mipi_dsim_lcd_device {
+	char			*name;
+	char			*panel_id;
+	int			id;
+	int			bus_id;
+
+	struct mipi_dsim_device *master;
+	void			*platform_data;
+};
+
+/*
+ * driver structure for mipi-dsi based lcd panel.
+ *
+ * this structure should be registered by lcd panel driver.
+ * mipi-dsi driver seeks lcd panel registered through name field
+ * and calls these callback functions in appropriate time.
+ *
+ * @name: name of the driver to use with this device, or an
+ *	alias for that name.
+ * @id: id of driver to be registered.
+ *	this id would be used for finding device object registered.
+ */
+struct mipi_dsim_lcd_driver {
+	char			*name;
+	int			id;
+
+	int	(*mipi_panel_init)(struct mipi_dsim_device *dsim_dev);
+	void	(*mipi_display_on)(struct mipi_dsim_device *dsim_dev);
+};
+
+int exynos_mipi_dsi_init(void);
+
+/*
+ * register mipi_dsim_lcd_driver object defined by lcd panel driver
+ * to mipi-dsi driver.
+ */
+int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver
+						*lcd_drv);
+
+/*
+ * register mipi_dsim_lcd_device to mipi-dsi master.
+ */
+int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device
+						*lcd_dev);
+
+/*
+ * exynos_dsim_phy_enable - global MIPI-DSI receiver D-PHY control
+ * @pdev: MIPI-DSIM platform device
+ * @on: true to enable D-PHY and deassert its reset
+ *	false to disable D-PHY
+ */
+int exynos_dsim_phy_enable(int on);
+
+#endif /* _DSIM_H */
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 8896abe..4fad20d 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -29,7 +29,10 @@ COBJS-$(CONFIG_ATI_RADEON_FB) += ati_radeon_fb.o videomodes.o
 COBJS-$(CONFIG_ATMEL_LCD) += atmel_lcdfb.o
 COBJS-$(CONFIG_CFB_CONSOLE) += cfb_console.o
 COBJS-$(CONFIG_EXYNOS_FB) += exynos_fb.o exynos_fimd.o
+COBJS-$(CONFIG_EXYNOS_MIPI_DSIM) += exynos_mipi_dsi.o exynos_mipi_dsi_common.o \
+				exynos_mipi_dsi_lowlevel.o
 COBJS-$(CONFIG_FSL_DIU_FB) += fsl_diu_fb.o videomodes.o
+COBJS-$(CONFIG_S6E8AX0) += s6e8ax0.o
 COBJS-$(CONFIG_S6E63D6) += s6e63d6.o
 COBJS-$(CONFIG_SED156X) += sed156x.o
 COBJS-$(CONFIG_VIDEO_AMBA) += amba.o
diff --git a/drivers/video/exynos_fb.c b/drivers/video/exynos_fb.c
index 2c11cb2..a658b8c 100644
--- a/drivers/video/exynos_fb.c
+++ b/drivers/video/exynos_fb.c
@@ -30,6 +30,7 @@
 #include <asm/arch/cpu.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/clk.h>
+#include <asm/arch/mipi_dsim.h>
 #include <asm/arch/system.h>
 #include <malloc.h>
 #include "exynos_fb.h"
@@ -98,6 +99,9 @@ static void lcd_panel_on(vidinfo_t *vid)
 
 	if (vid->enable_ldo)
 		vid->enable_ldo(1);
+
+	if (vid->mipi_enabled)
+		exynos_mipi_dsi_init();
 }
 
 void lcd_ctrl_init(void *lcdbase)
diff --git a/drivers/video/exynos_mipi_dsi.c b/drivers/video/exynos_mipi_dsi.c
new file mode 100644
index 0000000..112cb6b
--- /dev/null
+++ b/drivers/video/exynos_mipi_dsi.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * Author: InKi Dae <inki.dae@samsung.com>
+ * Author: Donghwa Lee <dh09.lee@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <ubi_uboot.h>
+#include <common.h>
+#include <lcd.h>
+#include <asm/errno.h>
+#include <asm/arch/dsim.h>
+#include <asm/arch/mipi_dsim.h>
+#include <asm/arch/power.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clk.h>
+#include <linux/types.h>
+#include <linux/list.h>
+
+#include "exynos_mipi_dsi_lowlevel.h"
+#include "exynos_mipi_dsi_common.h"
+
+#define master_to_driver(a)	(a->dsim_lcd_drv)
+#define master_to_device(a)	(a->dsim_lcd_dev)
+
+static struct exynos_platform_mipi_dsim *dsim_pd;
+
+struct mipi_dsim_ddi {
+	int				bus_id;
+	struct list_head		list;
+	struct mipi_dsim_lcd_device	*dsim_lcd_dev;
+	struct mipi_dsim_lcd_driver	*dsim_lcd_drv;
+};
+
+static LIST_HEAD(dsim_ddi_list);
+static LIST_HEAD(dsim_lcd_dev_list);
+
+int exynos_mipi_dsi_register_lcd_device(struct mipi_dsim_lcd_device *lcd_dev)
+{
+	struct mipi_dsim_ddi *dsim_ddi;
+
+	if (!lcd_dev) {
+		debug("mipi_dsim_lcd_device is NULL.\n");
+		return -EFAULT;
+	}
+
+	if (!lcd_dev->name) {
+		debug("dsim_lcd_device name is NULL.\n");
+		return -EFAULT;
+	}
+
+	dsim_ddi = kzalloc(sizeof(struct mipi_dsim_ddi), GFP_KERNEL);
+	if (!dsim_ddi) {
+		debug("failed to allocate dsim_ddi object.\n");
+		return -EFAULT;
+	}
+
+	dsim_ddi->dsim_lcd_dev = lcd_dev;
+
+	list_add_tail(&dsim_ddi->list, &dsim_ddi_list);
+
+	return 0;
+}
+
+struct mipi_dsim_ddi
+	*exynos_mipi_dsi_find_lcd_device(struct mipi_dsim_lcd_driver *lcd_drv)
+{
+	struct mipi_dsim_ddi *dsim_ddi;
+	struct mipi_dsim_lcd_device *lcd_dev;
+
+	list_for_each_entry(dsim_ddi, &dsim_ddi_list, list) {
+		lcd_dev = dsim_ddi->dsim_lcd_dev;
+		if (!lcd_dev)
+			continue;
+
+		if (lcd_drv->id >= 0) {
+			if ((strcmp(lcd_drv->name, lcd_dev->name)) == 0 &&
+					lcd_drv->id == lcd_dev->id) {
+				/**
+				 * bus_id would be used to identify
+				 * connected bus.
+				 */
+				dsim_ddi->bus_id = lcd_dev->bus_id;
+
+				return dsim_ddi;
+			}
+		} else {
+			if ((strcmp(lcd_drv->name, lcd_dev->name)) == 0) {
+				/**
+				 * bus_id would be used to identify
+				 * connected bus.
+				 */
+				dsim_ddi->bus_id = lcd_dev->bus_id;
+
+				return dsim_ddi;
+			}
+		}
+
+		kfree(dsim_ddi);
+		list_del(&dsim_ddi_list);
+	}
+
+	return NULL;
+}
+
+int exynos_mipi_dsi_register_lcd_driver(struct mipi_dsim_lcd_driver *lcd_drv)
+{
+	struct mipi_dsim_ddi *dsim_ddi;
+
+	if (!lcd_drv) {
+		debug("mipi_dsim_lcd_driver is NULL.\n");
+		return -EFAULT;
+	}
+
+	if (!lcd_drv->name) {
+		debug("dsim_lcd_driver name is NULL.\n");
+		return -EFAULT;
+	}
+
+	dsim_ddi = exynos_mipi_dsi_find_lcd_device(lcd_drv);
+	if (!dsim_ddi) {
+		debug("mipi_dsim_ddi object not found.\n");
+		return -EFAULT;
+	}
+
+	dsim_ddi->dsim_lcd_drv = lcd_drv;
+
+	debug("registered panel driver(%s) to mipi-dsi driver.\n",
+		lcd_drv->name);
+
+	return 0;
+
+}
+
+struct mipi_dsim_ddi
+	*exynos_mipi_dsi_bind_lcd_ddi(struct mipi_dsim_device *dsim,
+			const char *name)
+{
+	struct mipi_dsim_ddi *dsim_ddi;
+	struct mipi_dsim_lcd_driver *lcd_drv;
+	struct mipi_dsim_lcd_device *lcd_dev;
+
+	list_for_each_entry(dsim_ddi, &dsim_ddi_list, list) {
+		lcd_drv = dsim_ddi->dsim_lcd_drv;
+		lcd_dev = dsim_ddi->dsim_lcd_dev;
+		if (!lcd_drv || !lcd_dev)
+				continue;
+
+		debug("lcd_drv->id = %d, lcd_dev->id = %d\n",
+					lcd_drv->id, lcd_dev->id);
+
+		if ((strcmp(lcd_drv->name, name) == 0)) {
+			lcd_dev->master = dsim;
+
+			dsim->dsim_lcd_dev = lcd_dev;
+			dsim->dsim_lcd_drv = lcd_drv;
+
+			return dsim_ddi;
+		}
+	}
+
+	return NULL;
+}
+
+/* define MIPI-DSI Master operations. */
+static struct mipi_dsim_master_ops master_ops = {
+	.cmd_write			= exynos_mipi_dsi_wr_data,
+	.get_dsim_frame_done		= exynos_mipi_dsi_get_frame_done_status,
+	.clear_dsim_frame_done		= exynos_mipi_dsi_clear_frame_done,
+};
+
+int exynos_mipi_dsi_init(void)
+{
+	struct mipi_dsim_device *dsim;
+	struct mipi_dsim_config *dsim_config;
+	struct mipi_dsim_ddi *dsim_ddi;
+
+	dsim = kzalloc(sizeof(struct mipi_dsim_device), GFP_KERNEL);
+	if (!dsim) {
+		debug("failed to allocate dsim object.\n");
+		return -EFAULT;
+	}
+
+	/* get mipi_dsim_config. */
+	dsim_config = dsim_pd->dsim_config;
+	if (dsim_config == NULL) {
+		debug("failed to get dsim config data.\n");
+		return -EFAULT;
+	}
+
+	dsim->pd = dsim_pd;
+	dsim->dsim_config = dsim_config;
+	dsim->master_ops = &master_ops;
+
+
+	/* bind lcd ddi matched with panel name. */
+	dsim_ddi = exynos_mipi_dsi_bind_lcd_ddi(dsim, dsim_pd->lcd_panel_name);
+	if (!dsim_ddi) {
+		debug("mipi_dsim_ddi object not found.\n");
+		return -ENOSYS;
+	}
+	if (dsim_pd->lcd_power)
+		dsim_pd->lcd_power();
+
+	if (dsim_pd->mipi_power)
+		dsim_pd->mipi_power();
+
+	if (dsim_pd->phy_enable)
+		dsim_pd->phy_enable(1, EXYNOS_MIPI_PHY_MRESETN);
+
+	set_mipi_clk();
+
+	exynos_mipi_dsi_init_dsim(dsim);
+	exynos_mipi_dsi_init_link(dsim);
+	exynos_mipi_dsi_set_hs_enable(dsim);
+
+	/* set display timing. */
+	exynos_mipi_dsi_set_display_mode(dsim, dsim->dsim_config);
+
+	/* initialize mipi-dsi client(lcd panel). */
+	if (dsim_ddi->dsim_lcd_drv && dsim_ddi->dsim_lcd_drv->mipi_panel_init) {
+		dsim_ddi->dsim_lcd_drv->mipi_panel_init(dsim);
+		dsim_ddi->dsim_lcd_drv->mipi_display_on(dsim);
+	}
+
+	debug("mipi-dsi driver(%s mode) has been probed.\n",
+		(dsim_config->e_interface == DSIM_COMMAND) ?
+			"CPU" : "RGB");
+
+	return 0;
+}
+
+void exynos_set_dsim_platform_data(struct exynos_platform_mipi_dsim *pd)
+{
+	if (pd == NULL) {
+		debug("pd is NULL\n");
+		return;
+	}
+
+	dsim_pd = pd;
+}
diff --git a/drivers/video/exynos_mipi_dsi_common.c b/drivers/video/exynos_mipi_dsi_common.c
new file mode 100644
index 0000000..08611b6
--- /dev/null
+++ b/drivers/video/exynos_mipi_dsi_common.c
@@ -0,0 +1,645 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * Author: InKi Dae <inki.dae@samsung.com>
+ * Author: Donghwa Lee <dh09.lee@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <lcd.h>
+#include <asm/errno.h>
+#include <asm/arch/dsim.h>
+#include <asm/arch/mipi_dsim.h>
+#include <linux/types.h>
+#include <linux/fb.h>
+
+#include "exynos_mipi_dsi_lowlevel.h"
+
+#define MHZ			(1000 * 1000)
+#define FIN_HZ			(24 * MHZ)
+
+#define DFIN_PLL_MIN_HZ		(6 * MHZ)
+#define DFIN_PLL_MAX_HZ		(12 * MHZ)
+
+#define DFVCO_MIN_HZ		(500 * MHZ)
+#define DFVCO_MAX_HZ		(1000 * MHZ)
+
+#define TRY_GET_FIFO_TIMEOUT	(5000 * 2)
+
+/* MIPI-DSIM status types. */
+enum {
+	DSIM_STATE_INIT,	/* should be initialized. */
+	DSIM_STATE_STOP,	/* CPU and LCDC are LP mode. */
+	DSIM_STATE_HSCLKEN,	/* HS clock was enabled. */
+	DSIM_STATE_ULPS
+};
+
+/* define DSI lane types. */
+enum {
+	DSIM_LANE_CLOCK = (1 << 0),
+	DSIM_LANE_DATA0 = (1 << 1),
+	DSIM_LANE_DATA1 = (1 << 2),
+	DSIM_LANE_DATA2 = (1 << 3),
+	DSIM_LANE_DATA3 = (1 << 4)
+};
+
+static unsigned int dpll_table[15] = {
+	100, 120, 170, 220, 270,
+	320, 390, 450, 510, 560,
+	640, 690, 770, 870, 950 };
+
+static void exynos_mipi_dsi_long_data_wr(struct mipi_dsim_device *dsim,
+		unsigned int data0, unsigned int data1)
+{
+	unsigned int data_cnt = 0, payload = 0;
+
+	/* in case that data count is more then 4 */
+	for (data_cnt = 0; data_cnt < data1; data_cnt += 4) {
+		/*
+		 * after sending 4bytes per one time,
+		 * send remainder data less then 4.
+		 */
+		if ((data1 - data_cnt) < 4) {
+			if ((data1 - data_cnt) == 3) {
+				payload = *(u8 *)(data0 + data_cnt) |
+				    (*(u8 *)(data0 + (data_cnt + 1))) << 8 |
+					(*(u8 *)(data0 + (data_cnt + 2))) << 16;
+			debug("count = 3 payload = %x, %x %x %x\n",
+				payload, *(u8 *)(data0 + data_cnt),
+				*(u8 *)(data0 + (data_cnt + 1)),
+				*(u8 *)(data0 + (data_cnt + 2)));
+			} else if ((data1 - data_cnt) == 2) {
+				payload = *(u8 *)(data0 + data_cnt) |
+					(*(u8 *)(data0 + (data_cnt + 1))) << 8;
+			debug("count = 2 payload = %x, %x %x\n", payload,
+				*(u8 *)(data0 + data_cnt),
+				*(u8 *)(data0 + (data_cnt + 1)));
+			} else if ((data1 - data_cnt) == 1) {
+				payload = *(u8 *)(data0 + data_cnt);
+			}
+
+			exynos_mipi_dsi_wr_tx_data(dsim, payload);
+		/* send 4bytes per one time. */
+		} else {
+			payload = *(u8 *)(data0 + data_cnt) |
+				(*(u8 *)(data0 + (data_cnt + 1))) << 8 |
+				(*(u8 *)(data0 + (data_cnt + 2))) << 16 |
+				(*(u8 *)(data0 + (data_cnt + 3))) << 24;
+
+			debug("count = 4 payload = %x, %x %x %x %x\n",
+				payload, *(u8 *)(data0 + data_cnt),
+				*(u8 *)(data0 + (data_cnt + 1)),
+				*(u8 *)(data0 + (data_cnt + 2)),
+				*(u8 *)(data0 + (data_cnt + 3)));
+
+			exynos_mipi_dsi_wr_tx_data(dsim, payload);
+		}
+	}
+}
+
+int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id,
+	unsigned int data0, unsigned int data1)
+{
+	unsigned int timeout = TRY_GET_FIFO_TIMEOUT;
+	unsigned long delay_val, delay;
+	unsigned int check_rx_ack = 0;
+
+	if (dsim->state == DSIM_STATE_ULPS) {
+		debug("state is ULPS.\n");
+
+		return -EINVAL;
+	}
+
+	delay_val = MHZ / dsim->dsim_config->esc_clk;
+	delay = 10 * delay_val;
+
+	udelay(delay * 1000);
+
+	/* only if transfer mode is LPDT, wait SFR becomes empty. */
+	if (dsim->state == DSIM_STATE_STOP) {
+		while (!(exynos_mipi_dsi_get_fifo_state(dsim) &
+				SFR_HEADER_EMPTY)) {
+			if ((timeout--) > 0)
+				udelay(1000);
+			else {
+				debug("SRF header fifo is not empty.\n");
+				return -EINVAL;
+			}
+		}
+	}
+
+	switch (data_id) {
+	/* short packet types of packet types for command. */
+	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
+	case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
+	case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
+	case MIPI_DSI_DCS_SHORT_WRITE:
+	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
+	case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
+		debug("data0 = %x data1 = %x\n",
+				data0, data1);
+		exynos_mipi_dsi_wr_tx_header(dsim, data_id, data0, data1);
+		if (check_rx_ack)
+			/* process response func should be implemented */
+			return 0;
+		else
+			return -EINVAL;
+
+	/* general command */
+	case MIPI_DSI_COLOR_MODE_OFF:
+	case MIPI_DSI_COLOR_MODE_ON:
+	case MIPI_DSI_SHUTDOWN_PERIPHERAL:
+	case MIPI_DSI_TURN_ON_PERIPHERAL:
+		exynos_mipi_dsi_wr_tx_header(dsim, data_id, data0, data1);
+		if (check_rx_ack)
+			/* process response func should be implemented. */
+			return 0;
+		else
+			return -EINVAL;
+
+	/* packet types for video data */
+	case MIPI_DSI_V_SYNC_START:
+	case MIPI_DSI_V_SYNC_END:
+	case MIPI_DSI_H_SYNC_START:
+	case MIPI_DSI_H_SYNC_END:
+	case MIPI_DSI_END_OF_TRANSMISSION:
+		return 0;
+
+	/* short and response packet types for command */
+	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
+	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
+	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
+	case MIPI_DSI_DCS_READ:
+		exynos_mipi_dsi_clear_all_interrupt(dsim);
+		exynos_mipi_dsi_wr_tx_header(dsim, data_id, data0, data1);
+		/* process response func should be implemented. */
+		return 0;
+
+	/* long packet type and null packet */
+	case MIPI_DSI_NULL_PACKET:
+	case MIPI_DSI_BLANKING_PACKET:
+		return 0;
+	case MIPI_DSI_GENERIC_LONG_WRITE:
+	case MIPI_DSI_DCS_LONG_WRITE:
+	{
+		unsigned int size, data_cnt = 0, payload = 0;
+
+		size = data1 * 4;
+
+		/* if data count is less then 4, then send 3bytes data.  */
+		if (data1 < 4) {
+			payload = *(u8 *)(data0) |
+				*(u8 *)(data0 + 1) << 8 |
+				*(u8 *)(data0 + 2) << 16;
+
+			exynos_mipi_dsi_wr_tx_data(dsim, payload);
+
+			debug("count = %d payload = %x,%x %x %x\n",
+				data1, payload,
+				*(u8 *)(data0 + data_cnt),
+				*(u8 *)(data0 + (data_cnt + 1)),
+				*(u8 *)(data0 + (data_cnt + 2)));
+		/* in case that data count is more then 4 */
+		} else
+			exynos_mipi_dsi_long_data_wr(dsim, data0, data1);
+
+		/* put data into header fifo */
+		exynos_mipi_dsi_wr_tx_header(dsim, data_id, data1 & 0xff,
+			(data1 & 0xff00) >> 8);
+
+	}
+	if (check_rx_ack)
+		/* process response func should be implemented. */
+		return 0;
+	else
+		return -EINVAL;
+
+	/* packet typo for video data */
+	case MIPI_DSI_PACKED_PIXEL_STREAM_16:
+	case MIPI_DSI_PACKED_PIXEL_STREAM_18:
+	case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
+	case MIPI_DSI_PACKED_PIXEL_STREAM_24:
+		if (check_rx_ack)
+			/* process response func should be implemented. */
+			return 0;
+		else
+			return -EINVAL;
+	default:
+		debug("data id %x is not supported current DSI spec.\n",
+			data_id);
+
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+int exynos_mipi_dsi_pll_on(struct mipi_dsim_device *dsim, unsigned int enable)
+{
+	int sw_timeout;
+
+	if (enable) {
+		sw_timeout = 1000;
+
+		exynos_mipi_dsi_clear_interrupt(dsim);
+		exynos_mipi_dsi_enable_pll(dsim, 1);
+		while (1) {
+			sw_timeout--;
+			if (exynos_mipi_dsi_is_pll_stable(dsim))
+				return 0;
+			if (sw_timeout == 0)
+				return -EINVAL;
+		}
+	} else
+		exynos_mipi_dsi_enable_pll(dsim, 0);
+
+	return 0;
+}
+
+unsigned long exynos_mipi_dsi_change_pll(struct mipi_dsim_device *dsim,
+	unsigned int pre_divider, unsigned int main_divider,
+	unsigned int scaler)
+{
+	unsigned long dfin_pll, dfvco, dpll_out;
+	unsigned int i, freq_band = 0xf;
+
+	dfin_pll = (FIN_HZ / pre_divider);
+
+	/******************************************************
+	 *	Serial Clock(=ByteClk X 8)	FreqBand[3:0] *
+	 ******************************************************
+	 *	~ 99.99 MHz			0000
+	 *	100 ~ 119.99 MHz		0001
+	 *	120 ~ 159.99 MHz		0010
+	 *	160 ~ 199.99 MHz		0011
+	 *	200 ~ 239.99 MHz		0100
+	 *	140 ~ 319.99 MHz		0101
+	 *	320 ~ 389.99 MHz		0110
+	 *	390 ~ 449.99 MHz		0111
+	 *	450 ~ 509.99 MHz		1000
+	 *	510 ~ 559.99 MHz		1001
+	 *	560 ~ 639.99 MHz		1010
+	 *	640 ~ 689.99 MHz		1011
+	 *	690 ~ 769.99 MHz		1100
+	 *	770 ~ 869.99 MHz		1101
+	 *	870 ~ 949.99 MHz		1110
+	 *	950 ~ 1000 MHz			1111
+	 ******************************************************/
+	if (dfin_pll < DFIN_PLL_MIN_HZ || dfin_pll > DFIN_PLL_MAX_HZ) {
+		debug("fin_pll range should be 6MHz ~ 12MHz\n");
+		exynos_mipi_dsi_enable_afc(dsim, 0, 0);
+	} else {
+		if (dfin_pll < 7 * MHZ)
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x1);
+		else if (dfin_pll < 8 * MHZ)
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x0);
+		else if (dfin_pll < 9 * MHZ)
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x3);
+		else if (dfin_pll < 10 * MHZ)
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x2);
+		else if (dfin_pll < 11 * MHZ)
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x5);
+		else
+			exynos_mipi_dsi_enable_afc(dsim, 1, 0x4);
+	}
+
+	dfvco = dfin_pll * main_divider;
+	debug("dfvco = %lu, dfin_pll = %lu, main_divider = %d\n",
+				dfvco, dfin_pll, main_divider);
+	if (dfvco < DFVCO_MIN_HZ || dfvco > DFVCO_MAX_HZ)
+		debug("fvco range should be 500MHz ~ 1000MHz\n");
+
+	dpll_out = dfvco / (1 << scaler);
+	debug("dpll_out = %lu, dfvco = %lu, scaler = %d\n",
+		dpll_out, dfvco, scaler);
+
+	for (i = 0; i < ARRAY_SIZE(dpll_table); i++) {
+		if (dpll_out < dpll_table[i] * MHZ) {
+			freq_band = i;
+			break;
+		}
+	}
+
+	debug("freq_band = %d\n", freq_band);
+
+	exynos_mipi_dsi_pll_freq(dsim, pre_divider, main_divider, scaler);
+
+	exynos_mipi_dsi_hs_zero_ctrl(dsim, 0);
+	exynos_mipi_dsi_prep_ctrl(dsim, 0);
+
+	/* Freq Band */
+	exynos_mipi_dsi_pll_freq_band(dsim, freq_band);
+
+	/* Stable time */
+	exynos_mipi_dsi_pll_stable_time(dsim,
+				dsim->dsim_config->pll_stable_time);
+
+	/* Enable PLL */
+	debug("FOUT of mipi dphy pll is %luMHz\n",
+		(dpll_out / MHZ));
+
+	return dpll_out;
+}
+
+int exynos_mipi_dsi_set_clock(struct mipi_dsim_device *dsim,
+	unsigned int byte_clk_sel, unsigned int enable)
+{
+	unsigned int esc_div;
+	unsigned long esc_clk_error_rate;
+	unsigned long hs_clk = 0, byte_clk = 0, escape_clk = 0;
+
+	if (enable) {
+		dsim->e_clk_src = byte_clk_sel;
+
+		/* Escape mode clock and byte clock source */
+		exynos_mipi_dsi_set_byte_clock_src(dsim, byte_clk_sel);
+
+		/* DPHY, DSIM Link : D-PHY clock out */
+		if (byte_clk_sel == DSIM_PLL_OUT_DIV8) {
+			hs_clk = exynos_mipi_dsi_change_pll(dsim,
+				dsim->dsim_config->p, dsim->dsim_config->m,
+				dsim->dsim_config->s);
+			if (hs_clk == 0) {
+				debug("failed to get hs clock.\n");
+				return -EINVAL;
+			}
+
+			byte_clk = hs_clk / 8;
+			exynos_mipi_dsi_enable_pll_bypass(dsim, 0);
+			exynos_mipi_dsi_pll_on(dsim, 1);
+		/* DPHY : D-PHY clock out, DSIM link : external clock out */
+		} else if (byte_clk_sel == DSIM_EXT_CLK_DIV8)
+			debug("not support EXT CLK source for MIPI DSIM\n");
+		else if (byte_clk_sel == DSIM_EXT_CLK_BYPASS)
+			debug("not support EXT CLK source for MIPI DSIM\n");
+
+		/* escape clock divider */
+		esc_div = byte_clk / (dsim->dsim_config->esc_clk);
+		debug("esc_div = %d, byte_clk = %lu, esc_clk = %lu\n",
+			esc_div, byte_clk, dsim->dsim_config->esc_clk);
+		if ((byte_clk / esc_div) >= (20 * MHZ) ||
+				(byte_clk / esc_div) >
+					dsim->dsim_config->esc_clk)
+			esc_div += 1;
+
+		escape_clk = byte_clk / esc_div;
+		debug("escape_clk = %lu, byte_clk = %lu, esc_div = %d\n",
+			escape_clk, byte_clk, esc_div);
+
+		/* enable escape clock. */
+		exynos_mipi_dsi_enable_byte_clock(dsim, 1);
+
+		/* enable byte clk and escape clock */
+		exynos_mipi_dsi_set_esc_clk_prs(dsim, 1, esc_div);
+		/* escape clock on lane */
+		exynos_mipi_dsi_enable_esc_clk_on_lane(dsim,
+			(DSIM_LANE_CLOCK | dsim->data_lane), 1);
+
+		debug("byte clock is %luMHz\n",
+			(byte_clk / MHZ));
+		debug("escape clock that user's need is %lu\n",
+			(dsim->dsim_config->esc_clk / MHZ));
+		debug("escape clock divider is %x\n", esc_div);
+		debug("escape clock is %luMHz\n",
+			((byte_clk / esc_div) / MHZ));
+
+		if ((byte_clk / esc_div) > escape_clk) {
+			esc_clk_error_rate = escape_clk /
+				(byte_clk / esc_div);
+			debug("error rate is %lu over.\n",
+				(esc_clk_error_rate / 100));
+		} else if ((byte_clk / esc_div) < (escape_clk)) {
+			esc_clk_error_rate = (byte_clk / esc_div) /
+				escape_clk;
+			debug("error rate is %lu under.\n",
+				(esc_clk_error_rate / 100));
+		}
+	} else {
+		exynos_mipi_dsi_enable_esc_clk_on_lane(dsim,
+			(DSIM_LANE_CLOCK | dsim->data_lane), 0);
+		exynos_mipi_dsi_set_esc_clk_prs(dsim, 0, 0);
+
+		/* disable escape clock. */
+		exynos_mipi_dsi_enable_byte_clock(dsim, 0);
+
+		if (byte_clk_sel == DSIM_PLL_OUT_DIV8)
+			exynos_mipi_dsi_pll_on(dsim, 0);
+	}
+
+	return 0;
+}
+
+int exynos_mipi_dsi_init_dsim(struct mipi_dsim_device *dsim)
+{
+	dsim->state = DSIM_STATE_INIT;
+
+	switch (dsim->dsim_config->e_no_data_lane) {
+	case DSIM_DATA_LANE_1:
+		dsim->data_lane = DSIM_LANE_DATA0;
+		break;
+	case DSIM_DATA_LANE_2:
+		dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1;
+		break;
+	case DSIM_DATA_LANE_3:
+		dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
+			DSIM_LANE_DATA2;
+		break;
+	case DSIM_DATA_LANE_4:
+		dsim->data_lane = DSIM_LANE_DATA0 | DSIM_LANE_DATA1 |
+			DSIM_LANE_DATA2 | DSIM_LANE_DATA3;
+		break;
+	default:
+		debug("data lane is invalid.\n");
+		return -EINVAL;
+	};
+
+	exynos_mipi_dsi_sw_reset(dsim);
+	exynos_mipi_dsi_dp_dn_swap(dsim, 0);
+
+	return 0;
+}
+
+int exynos_mipi_dsi_enable_frame_done_int(struct mipi_dsim_device *dsim,
+	unsigned int enable)
+{
+	/* enable only frame done interrupt */
+	exynos_mipi_dsi_set_interrupt_mask(dsim, INTMSK_FRAME_DONE, enable);
+
+	return 0;
+}
+
+static void convert_to_fb_videomode(struct fb_videomode *mode1,
+				vidinfo_t *mode2)
+{
+	mode1->xres = mode2->vl_width;
+	mode1->yres = mode2->vl_height;
+	mode1->upper_margin = mode2->vl_vfpd;
+	mode1->lower_margin = mode2->vl_vbpd;
+	mode1->left_margin = mode2->vl_hfpd;
+	mode1->right_margin = mode2->vl_hbpd;
+	mode1->vsync_len = mode2->vl_vspw;
+	mode1->hsync_len = mode2->vl_hspw;
+}
+
+int exynos_mipi_dsi_set_display_mode(struct mipi_dsim_device *dsim,
+	struct mipi_dsim_config *dsim_config)
+{
+	struct exynos_platform_mipi_dsim *dsim_pd;
+	struct fb_videomode lcd_video;
+	vidinfo_t *vid;
+
+	dsim_pd = (struct exynos_platform_mipi_dsim *)dsim->pd;
+	vid = (vidinfo_t *)dsim_pd->lcd_panel_info;
+
+	convert_to_fb_videomode(&lcd_video, vid);
+
+	/* in case of VIDEO MODE (RGB INTERFACE), it sets polarities. */
+	if (dsim->dsim_config->e_interface == (u32) DSIM_VIDEO) {
+		if (dsim->dsim_config->auto_vertical_cnt == 0) {
+			exynos_mipi_dsi_set_main_disp_vporch(dsim,
+				vid->vl_cmd_allow_len,
+				lcd_video.upper_margin,
+				lcd_video.lower_margin);
+			exynos_mipi_dsi_set_main_disp_hporch(dsim,
+				lcd_video.left_margin,
+				lcd_video.right_margin);
+			exynos_mipi_dsi_set_main_disp_sync_area(dsim,
+				lcd_video.vsync_len,
+				lcd_video.hsync_len);
+		}
+	}
+
+	exynos_mipi_dsi_set_main_disp_resol(dsim, lcd_video.xres,
+			lcd_video.yres);
+
+	exynos_mipi_dsi_display_config(dsim, dsim->dsim_config);
+
+	debug("lcd panel ==> width = %d, height = %d\n",
+			lcd_video.xres, lcd_video.yres);
+
+	return 0;
+}
+
+int exynos_mipi_dsi_init_link(struct mipi_dsim_device *dsim)
+{
+	unsigned int time_out = 100;
+
+	switch (dsim->state) {
+	case DSIM_STATE_INIT:
+		exynos_mipi_dsi_init_fifo_pointer(dsim, 0x1f);
+
+		/* dsi configuration */
+		exynos_mipi_dsi_init_config(dsim);
+		exynos_mipi_dsi_enable_lane(dsim, DSIM_LANE_CLOCK, 1);
+		exynos_mipi_dsi_enable_lane(dsim, dsim->data_lane, 1);
+
+		/* set clock configuration */
+		exynos_mipi_dsi_set_clock(dsim,
+					dsim->dsim_config->e_byte_clk, 1);
+
+		/* check clock and data lane state are stop state */
+		while (!(exynos_mipi_dsi_is_lane_state(dsim))) {
+			time_out--;
+			if (time_out == 0) {
+				debug("DSI Master is not stop state.\n");
+				debug("Check initialization process\n");
+
+				return -EINVAL;
+			}
+		}
+
+		if (time_out != 0) {
+			debug("DSI Master driver has been completed.\n");
+			debug("DSI Master state is stop state\n");
+		}
+
+		dsim->state = DSIM_STATE_STOP;
+
+		/* BTA sequence counters */
+		exynos_mipi_dsi_set_stop_state_counter(dsim,
+			dsim->dsim_config->stop_holding_cnt);
+		exynos_mipi_dsi_set_bta_timeout(dsim,
+			dsim->dsim_config->bta_timeout);
+		exynos_mipi_dsi_set_lpdr_timeout(dsim,
+			dsim->dsim_config->rx_timeout);
+
+
+		return 0;
+	default:
+		debug("DSI Master is already init.\n");
+		return 0;
+	}
+
+	return 0;
+}
+
+int exynos_mipi_dsi_set_hs_enable(struct mipi_dsim_device *dsim)
+{
+	if (dsim->state == DSIM_STATE_STOP) {
+		if (dsim->e_clk_src != DSIM_EXT_CLK_BYPASS) {
+			dsim->state = DSIM_STATE_HSCLKEN;
+
+			 /* set LCDC and CPU transfer mode to HS. */
+			exynos_mipi_dsi_set_lcdc_transfer_mode(dsim, 0);
+			exynos_mipi_dsi_set_cpu_transfer_mode(dsim, 0);
+
+			exynos_mipi_dsi_enable_hs_clock(dsim, 1);
+
+			return 0;
+		} else
+			debug("clock source is external bypass.\n");
+	} else
+		debug("DSIM is not stop state.\n");
+
+	return 0;
+}
+
+int exynos_mipi_dsi_set_data_transfer_mode(struct mipi_dsim_device *dsim,
+		unsigned int mode)
+{
+	if (mode) {
+		if (dsim->state != DSIM_STATE_HSCLKEN) {
+			debug("HS Clock lane is not enabled.\n");
+			return -EINVAL;
+		}
+
+		exynos_mipi_dsi_set_lcdc_transfer_mode(dsim, 0);
+	} else {
+		if (dsim->state == DSIM_STATE_INIT || dsim->state ==
+			DSIM_STATE_ULPS) {
+			debug("DSI Master is not STOP or HSDT state.\n");
+			return -EINVAL;
+		}
+
+		exynos_mipi_dsi_set_cpu_transfer_mode(dsim, 0);
+	}
+
+	return 0;
+}
+
+int exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim)
+{
+	return _exynos_mipi_dsi_get_frame_done_status(dsim);
+}
+
+int exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim)
+{
+	_exynos_mipi_dsi_clear_frame_done(dsim);
+
+	return 0;
+}
diff --git a/drivers/video/exynos_mipi_dsi_common.h b/drivers/video/exynos_mipi_dsi_common.h
new file mode 100644
index 0000000..4d80679
--- /dev/null
+++ b/drivers/video/exynos_mipi_dsi_common.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * Author: InKi Dae <inki.dae@samsung.com>
+ * Author: Donghwa Lee <dh09.lee@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <linux/fb.h>
+
+#ifndef _EXYNOS_MIPI_DSI_COMMON_H
+#define _EXYNOS_MIPI_DSI_COMMON_H
+
+int exynos_mipi_dsi_wr_data(struct mipi_dsim_device *dsim, unsigned int data_id,
+	unsigned int data0, unsigned int data1);
+int exynos_mipi_dsi_pll_on(struct mipi_dsim_device *dsim, unsigned int enable);
+unsigned long exynos_mipi_dsi_change_pll(struct mipi_dsim_device *dsim,
+	unsigned int pre_divider, unsigned int main_divider,
+	unsigned int scaler);
+int exynos_mipi_dsi_set_clock(struct mipi_dsim_device *dsim,
+	unsigned int byte_clk_sel, unsigned int enable);
+int exynos_mipi_dsi_init_dsim(struct mipi_dsim_device *dsim);
+int exynos_mipi_dsi_set_display_mode(struct mipi_dsim_device *dsim,
+			struct mipi_dsim_config *dsim_info);
+int exynos_mipi_dsi_init_link(struct mipi_dsim_device *dsim);
+int exynos_mipi_dsi_set_hs_enable(struct mipi_dsim_device *dsim);
+int exynos_mipi_dsi_set_data_transfer_mode(struct mipi_dsim_device *dsim,
+		unsigned int mode);
+int exynos_mipi_dsi_enable_frame_done_int(struct mipi_dsim_device *dsim,
+	unsigned int enable);
+int exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device *dsim);
+int exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim);
+
+#endif /* _EXYNOS_MIPI_DSI_COMMON_H */
diff --git a/drivers/video/exynos_mipi_dsi_lowlevel.c b/drivers/video/exynos_mipi_dsi_lowlevel.c
new file mode 100644
index 0000000..b4e1cad
--- /dev/null
+++ b/drivers/video/exynos_mipi_dsi_lowlevel.c
@@ -0,0 +1,669 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * Author: InKi Dae <inki.dae@samsung.com>
+ * Author: Donghwa Lee <dh09.lee@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <lcd.h>
+#include <asm/errno.h>
+#include <asm/arch/dsim.h>
+#include <asm/arch/mipi_dsim.h>
+#include <asm/arch/power.h>
+#include <asm/arch/cpu.h>
+#include <linux/types.h>
+#include <linux/list.h>
+
+#include <asm/arch/mipi_dsim.h>
+
+#include "exynos_mipi_dsi_lowlevel.h"
+#include "exynos_mipi_dsi_common.h"
+
+void exynos_mipi_dsi_func_reset(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg;
+
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+
+	reg = readl(&mipi_dsim->swrst);
+
+	reg |= DSIM_FUNCRST;
+
+	writel(reg, &mipi_dsim->swrst);
+}
+
+void exynos_mipi_dsi_sw_reset(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg = 0;
+
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+
+	reg = readl(&mipi_dsim->swrst);
+
+	reg |= DSIM_SWRST;
+	reg |= DSIM_FUNCRST;
+
+	writel(reg, &mipi_dsim->swrst);
+}
+
+void exynos_mipi_dsi_sw_release(struct mipi_dsim_device *dsim)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = readl(&mipi_dsim->intsrc);
+
+	reg |= INTSRC_SWRST_RELEASE;
+
+	writel(reg, &mipi_dsim->intsrc);
+
+	reg = 0;
+	reg = readl(&mipi_dsim->intsrc);
+}
+
+void exynos_mipi_dsi_set_interrupt_mask(struct mipi_dsim_device *dsim,
+		unsigned int mode, unsigned int mask)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = readl(&mipi_dsim->intmsk);
+
+	if (mask)
+		reg |= mode;
+	else
+		reg &= ~mode;
+
+	writel(reg, &mipi_dsim->intmsk);
+}
+
+void exynos_mipi_dsi_init_fifo_pointer(struct mipi_dsim_device *dsim,
+		unsigned int cfg)
+{
+	unsigned int reg;
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+
+	reg = readl(&mipi_dsim->fifoctrl);
+
+	writel(reg & ~(cfg), &mipi_dsim->fifoctrl);
+	udelay(10* 1000);
+	reg |= cfg;
+
+	writel(reg, &mipi_dsim->fifoctrl);
+}
+
+/*
+ * this function set PLL P, M and S value in D-PHY
+ */
+void exynos_mipi_dsi_set_phy_tunning(struct mipi_dsim_device *dsim,
+		unsigned int value)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+
+	writel(DSIM_AFC_CTL(value), &mipi_dsim->phyacchr);
+}
+
+void exynos_mipi_dsi_set_main_disp_resol(struct mipi_dsim_device *dsim,
+	unsigned int width_resol, unsigned int height_resol)
+{
+	unsigned int reg;
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+
+	/* standby should be set after configuration so set to not ready*/
+	reg = (readl(&mipi_dsim->mdresol)) & ~(DSIM_MAIN_STAND_BY);
+	writel(reg, &mipi_dsim->mdresol);
+
+	/* reset resolution */
+	reg &= ~(DSIM_MAIN_VRESOL(0x7ff) | DSIM_MAIN_HRESOL(0x7ff));
+	reg |= DSIM_MAIN_VRESOL(height_resol) | DSIM_MAIN_HRESOL(width_resol);
+
+	reg |= DSIM_MAIN_STAND_BY;
+	writel(reg, &mipi_dsim->mdresol);
+}
+
+void exynos_mipi_dsi_set_main_disp_vporch(struct mipi_dsim_device *dsim,
+	unsigned int cmd_allow, unsigned int vfront, unsigned int vback)
+{
+	unsigned int reg;
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+
+	reg = (readl(&mipi_dsim->mvporch)) &
+		~((DSIM_CMD_ALLOW_MASK) | (DSIM_STABLE_VFP_MASK) |
+		(DSIM_MAIN_VBP_MASK));
+
+	reg |= ((cmd_allow & 0xf) << DSIM_CMD_ALLOW_SHIFT) |
+		((vfront & 0x7ff) << DSIM_STABLE_VFP_SHIFT) |
+		((vback & 0x7ff) << DSIM_MAIN_VBP_SHIFT);
+
+	writel(reg, &mipi_dsim->mvporch);
+}
+
+void exynos_mipi_dsi_set_main_disp_hporch(struct mipi_dsim_device *dsim,
+	unsigned int front, unsigned int back)
+{
+	unsigned int reg;
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+
+	reg = (readl(&mipi_dsim->mhporch)) &
+		~((DSIM_MAIN_HFP_MASK) | (DSIM_MAIN_HBP_MASK));
+
+	reg |= (front << DSIM_MAIN_HFP_SHIFT) | (back << DSIM_MAIN_HBP_SHIFT);
+
+	writel(reg, &mipi_dsim->mhporch);
+}
+
+void exynos_mipi_dsi_set_main_disp_sync_area(struct mipi_dsim_device *dsim,
+	unsigned int vert, unsigned int hori)
+{
+	unsigned int reg;
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+
+	reg = (readl(&mipi_dsim->msync)) &
+		~((DSIM_MAIN_VSA_MASK) | (DSIM_MAIN_HSA_MASK));
+
+	reg |= ((vert & 0x3ff) << DSIM_MAIN_VSA_SHIFT) |
+		(hori << DSIM_MAIN_HSA_SHIFT);
+
+	writel(reg, &mipi_dsim->msync);
+}
+
+void exynos_mipi_dsi_set_sub_disp_resol(struct mipi_dsim_device *dsim,
+	unsigned int vert, unsigned int hori)
+{
+	unsigned int reg;
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+
+	reg = (readl(&mipi_dsim->sdresol)) &
+		~(DSIM_SUB_STANDY_MASK);
+
+	writel(reg, &mipi_dsim->sdresol);
+
+	reg &= ~(DSIM_SUB_VRESOL_MASK) | ~(DSIM_SUB_HRESOL_MASK);
+	reg |= ((vert & 0x7ff) << DSIM_SUB_VRESOL_SHIFT) |
+		((hori & 0x7ff) << DSIM_SUB_HRESOL_SHIFT);
+	writel(reg, &mipi_dsim->sdresol);
+
+	/* DSIM STANDBY */
+	reg |= (1 << DSIM_SUB_STANDY_SHIFT);
+	writel(reg, &mipi_dsim->sdresol);
+}
+
+void exynos_mipi_dsi_init_config(struct mipi_dsim_device *dsim)
+{
+	struct mipi_dsim_config *dsim_config = dsim->dsim_config;
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int cfg = (readl(&mipi_dsim->config)) &
+		~((1 << DSIM_EOT_PACKET_SHIFT) |
+		(0x1f << DSIM_HSA_MODE_SHIFT) |
+		(0x3 << DSIM_NUM_OF_DATALANE_SHIFT));
+
+	cfg =	(dsim_config->auto_flush << DSIM_AUTO_FLUSH_SHIFT) |
+		(dsim_config->eot_disable << DSIM_EOT_PACKET_SHIFT) |
+		(dsim_config->auto_vertical_cnt << DSIM_AUTO_MODE_SHIFT) |
+		(dsim_config->hse << DSIM_HSE_MODE_SHIFT) |
+		(dsim_config->hfp << DSIM_HFP_MODE_SHIFT) |
+		(dsim_config->hbp << DSIM_HBP_MODE_SHIFT) |
+		(dsim_config->hsa << DSIM_HSA_MODE_SHIFT) |
+		(dsim_config->e_no_data_lane << DSIM_NUM_OF_DATALANE_SHIFT);
+
+	writel(cfg, &mipi_dsim->config);
+}
+
+void exynos_mipi_dsi_display_config(struct mipi_dsim_device *dsim,
+				struct mipi_dsim_config *dsim_config)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+
+	u32 reg = (readl(&mipi_dsim->config)) &
+		~((0x3 << DSIM_BURST_MODE_SHIFT) | (1 << DSIM_VIDEO_MODE_SHIFT)
+		| (0x3 << DSIM_MAINVC_SHIFT) | (0x7 << DSIM_MAINPIX_SHIFT)
+		| (0x3 << DSIM_SUBVC_SHIFT) | (0x7 << DSIM_SUBPIX_SHIFT));
+
+	if (dsim_config->e_interface == DSIM_VIDEO)
+		reg |= (1 << DSIM_VIDEO_MODE_SHIFT);
+	else if (dsim_config->e_interface == DSIM_COMMAND)
+		reg &= ~(1 << DSIM_VIDEO_MODE_SHIFT);
+	else {
+		printf("unknown lcd type.\n");
+		return;
+	}
+
+	/* main lcd */
+	reg |= ((u8) (dsim_config->e_burst_mode) & 0x3) << DSIM_BURST_MODE_SHIFT
+	| ((u8) (dsim_config->e_virtual_ch) & 0x3) << DSIM_MAINVC_SHIFT
+	| ((u8) (dsim_config->e_pixel_format) & 0x7) << DSIM_MAINPIX_SHIFT;
+
+	writel(reg, &mipi_dsim->config);
+}
+
+void exynos_mipi_dsi_enable_lane(struct mipi_dsim_device *dsim,
+			unsigned int lane, unsigned int enable)
+{
+	unsigned int reg;
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+
+	reg = readl(&mipi_dsim->config);
+
+	if (enable)
+		reg |= DSIM_LANE_ENx(lane);
+	else
+		reg &= ~DSIM_LANE_ENx(lane);
+
+	writel(reg, &mipi_dsim->config);
+}
+
+
+void exynos_mipi_dsi_set_data_lane_number(struct mipi_dsim_device *dsim,
+	unsigned int count)
+{
+	unsigned int cfg;
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+
+	/* get the data lane number. */
+	cfg = DSIM_NUM_OF_DATA_LANE(count);
+
+	writel(cfg, &mipi_dsim->config);
+}
+
+void exynos_mipi_dsi_enable_afc(struct mipi_dsim_device *dsim,
+			unsigned int enable, unsigned int afc_code)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = readl(&mipi_dsim->phyacchr);
+
+	reg = 0;
+
+	if (enable) {
+		reg |= DSIM_AFC_EN;
+		reg &= ~(0x7 << DSIM_AFC_CTL_SHIFT);
+		reg |= DSIM_AFC_CTL(afc_code);
+	} else
+		reg &= ~DSIM_AFC_EN;
+
+	writel(reg, &mipi_dsim->phyacchr);
+}
+
+void exynos_mipi_dsi_enable_pll_bypass(struct mipi_dsim_device *dsim,
+	unsigned int enable)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = (readl(&mipi_dsim->clkctrl)) &
+		~(DSIM_PLL_BYPASS_EXTERNAL);
+
+	reg |= enable << DSIM_PLL_BYPASS_SHIFT;
+
+	writel(reg, &mipi_dsim->clkctrl);
+}
+
+void exynos_mipi_dsi_pll_freq_band(struct mipi_dsim_device *dsim,
+		unsigned int freq_band)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = (readl(&mipi_dsim->pllctrl)) &
+		~(0x1f << DSIM_FREQ_BAND_SHIFT);
+
+	reg |= ((freq_band & 0x1f) << DSIM_FREQ_BAND_SHIFT);
+
+	writel(reg, &mipi_dsim->pllctrl);
+}
+
+void exynos_mipi_dsi_pll_freq(struct mipi_dsim_device *dsim,
+		unsigned int pre_divider, unsigned int main_divider,
+		unsigned int scaler)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = (readl(&mipi_dsim->pllctrl)) &
+		~(0x7ffff << 1);
+
+	reg |= ((pre_divider & 0x3f) << DSIM_PREDIV_SHIFT) |
+		((main_divider & 0x1ff) << DSIM_MAIN_SHIFT) |
+		((scaler & 0x7) << DSIM_SCALER_SHIFT);
+
+	writel(reg, &mipi_dsim->pllctrl);
+}
+
+void exynos_mipi_dsi_pll_stable_time(struct mipi_dsim_device *dsim,
+	unsigned int lock_time)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+
+	writel(lock_time, &mipi_dsim->plltmr);
+}
+
+void exynos_mipi_dsi_enable_pll(struct mipi_dsim_device *dsim,
+				unsigned int enable)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = (readl(&mipi_dsim->pllctrl)) &
+		~(0x1 << DSIM_PLL_EN_SHIFT);
+
+	reg |= ((enable & 0x1) << DSIM_PLL_EN_SHIFT);
+
+	writel(reg, &mipi_dsim->pllctrl);
+}
+
+void exynos_mipi_dsi_set_byte_clock_src(struct mipi_dsim_device *dsim,
+		unsigned int src)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = (readl(&mipi_dsim->clkctrl)) &
+		~(0x3 << DSIM_BYTE_CLK_SRC_SHIFT);
+
+	reg |= ((unsigned int) src) << DSIM_BYTE_CLK_SRC_SHIFT;
+
+	writel(reg, &mipi_dsim->clkctrl);
+}
+
+void exynos_mipi_dsi_enable_byte_clock(struct mipi_dsim_device *dsim,
+		unsigned int enable)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = (readl(&mipi_dsim->clkctrl)) &
+		~(1 << DSIM_BYTE_CLKEN_SHIFT);
+
+	reg |= enable << DSIM_BYTE_CLKEN_SHIFT;
+
+	writel(reg, &mipi_dsim->clkctrl);
+}
+
+void exynos_mipi_dsi_set_esc_clk_prs(struct mipi_dsim_device *dsim,
+		unsigned int enable, unsigned int prs_val)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = (readl(&mipi_dsim->clkctrl)) &
+		~((1 << DSIM_ESC_CLKEN_SHIFT) | (0xffff));
+
+	reg |= enable << DSIM_ESC_CLKEN_SHIFT;
+	if (enable)
+		reg |= prs_val;
+
+	writel(reg, &mipi_dsim->clkctrl);
+}
+
+void exynos_mipi_dsi_enable_esc_clk_on_lane(struct mipi_dsim_device *dsim,
+		unsigned int lane_sel, unsigned int enable)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = readl(&mipi_dsim->clkctrl);
+
+	if (enable)
+		reg |= DSIM_LANE_ESC_CLKEN(lane_sel);
+	else
+
+		reg &= ~DSIM_LANE_ESC_CLKEN(lane_sel);
+
+	writel(reg, &mipi_dsim->clkctrl);
+}
+
+void exynos_mipi_dsi_force_dphy_stop_state(struct mipi_dsim_device *dsim,
+	unsigned int enable)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = (readl(&mipi_dsim->escmode)) &
+		~(0x1 << DSIM_FORCE_STOP_STATE_SHIFT);
+
+	reg |= ((enable & 0x1) << DSIM_FORCE_STOP_STATE_SHIFT);
+
+	writel(reg, &mipi_dsim->escmode);
+}
+
+unsigned int exynos_mipi_dsi_is_lane_state(struct mipi_dsim_device *dsim)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = readl(&mipi_dsim->status);
+
+	/**
+	 * check clock and data lane states.
+	 * if MIPI-DSI controller was enabled at bootloader then
+	 * TX_READY_HS_CLK is enabled otherwise STOP_STATE_CLK.
+	 * so it should be checked for two case.
+	 */
+	if ((reg & DSIM_STOP_STATE_DAT(0xf)) &&
+			((reg & DSIM_STOP_STATE_CLK) ||
+			 (reg & DSIM_TX_READY_HS_CLK)))
+		return 1;
+	else
+		return 0;
+}
+
+void exynos_mipi_dsi_set_stop_state_counter(struct mipi_dsim_device *dsim,
+		unsigned int cnt_val)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = (readl(&mipi_dsim->escmode)) &
+		~(0x7ff << DSIM_STOP_STATE_CNT_SHIFT);
+
+	reg |= ((cnt_val & 0x7ff) << DSIM_STOP_STATE_CNT_SHIFT);
+
+	writel(reg, &mipi_dsim->escmode);
+}
+
+void exynos_mipi_dsi_set_bta_timeout(struct mipi_dsim_device *dsim,
+		unsigned int timeout)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = (readl(&mipi_dsim->timeout)) &
+		~(0xff << DSIM_BTA_TOUT_SHIFT);
+
+	reg |= (timeout << DSIM_BTA_TOUT_SHIFT);
+
+	writel(reg, &mipi_dsim->timeout);
+}
+
+void exynos_mipi_dsi_set_lpdr_timeout(struct mipi_dsim_device *dsim,
+		unsigned int timeout)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = (readl(&mipi_dsim->timeout)) &
+		~(0xffff << DSIM_LPDR_TOUT_SHIFT);
+
+	reg |= (timeout << DSIM_LPDR_TOUT_SHIFT);
+
+	writel(reg, &mipi_dsim->timeout);
+}
+
+void exynos_mipi_dsi_set_cpu_transfer_mode(struct mipi_dsim_device *dsim,
+		unsigned int lp)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = readl(&mipi_dsim->escmode);
+
+	reg &= ~DSIM_CMD_LPDT_LP;
+
+	if (lp)
+		reg |= DSIM_CMD_LPDT_LP;
+
+	writel(reg, &mipi_dsim->escmode);
+}
+
+void exynos_mipi_dsi_set_lcdc_transfer_mode(struct mipi_dsim_device *dsim,
+		unsigned int lp)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = readl(&mipi_dsim->escmode);
+
+	reg &= ~DSIM_TX_LPDT_LP;
+
+	if (lp)
+		reg |= DSIM_TX_LPDT_LP;
+
+	writel(reg, &mipi_dsim->escmode);
+}
+
+void exynos_mipi_dsi_enable_hs_clock(struct mipi_dsim_device *dsim,
+		unsigned int enable)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = (readl(&mipi_dsim->clkctrl)) &
+		~(1 << DSIM_TX_REQUEST_HSCLK_SHIFT);
+
+	reg |= enable << DSIM_TX_REQUEST_HSCLK_SHIFT;
+
+	writel(reg, &mipi_dsim->clkctrl);
+}
+
+void exynos_mipi_dsi_dp_dn_swap(struct mipi_dsim_device *dsim,
+		unsigned int swap_en)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = readl(&mipi_dsim->phyacchr1);
+
+	reg &= ~(0x3 << DSIM_DPDN_SWAP_DATA_SHIFT);
+	reg |= (swap_en & 0x3) << DSIM_DPDN_SWAP_DATA_SHIFT;
+
+	writel(reg, &mipi_dsim->phyacchr1);
+}
+
+void exynos_mipi_dsi_hs_zero_ctrl(struct mipi_dsim_device *dsim,
+		unsigned int hs_zero)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = (readl(&mipi_dsim->pllctrl)) &
+		~(0xf << DSIM_ZEROCTRL_SHIFT);
+
+	reg |= ((hs_zero & 0xf) << DSIM_ZEROCTRL_SHIFT);
+
+	writel(reg, &mipi_dsim->pllctrl);
+}
+
+void exynos_mipi_dsi_prep_ctrl(struct mipi_dsim_device *dsim, unsigned int prep)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = (readl(&mipi_dsim->pllctrl)) &
+		~(0x7 << DSIM_PRECTRL_SHIFT);
+
+	reg |= ((prep & 0x7) << DSIM_PRECTRL_SHIFT);
+
+	writel(reg, &mipi_dsim->pllctrl);
+}
+
+void exynos_mipi_dsi_clear_interrupt(struct mipi_dsim_device *dsim)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = readl(&mipi_dsim->intsrc);
+
+	reg |= INTSRC_PLL_STABLE;
+
+	writel(reg, &mipi_dsim->intsrc);
+}
+
+void exynos_mipi_dsi_clear_all_interrupt(struct mipi_dsim_device *dsim)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = readl(&mipi_dsim->intsrc);
+
+	reg |= 0xffffffff;
+
+	writel(reg, &mipi_dsim->intsrc);
+}
+
+unsigned int exynos_mipi_dsi_is_pll_stable(struct mipi_dsim_device *dsim)
+{
+	unsigned int reg;
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+
+	reg = readl(&mipi_dsim->status);
+
+	return reg & DSIM_PLL_STABLE ? 1 : 0;
+}
+
+unsigned int exynos_mipi_dsi_get_fifo_state(struct mipi_dsim_device *dsim)
+{
+	unsigned int ret;
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+
+	ret = readl(&mipi_dsim->fifoctrl) & ~(0x1f);
+
+	return ret;
+}
+
+void exynos_mipi_dsi_wr_tx_header(struct mipi_dsim_device *dsim,
+	unsigned int di, unsigned int data0, unsigned int data1)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = (DSIM_PKTHDR_DAT1(data1) | DSIM_PKTHDR_DAT0(data0) |
+			DSIM_PKTHDR_DI(di));
+
+	writel(reg, &mipi_dsim->pkthdr);
+}
+
+unsigned int _exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device
+						*dsim)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = readl(&mipi_dsim->intsrc);
+
+	return (reg & INTSRC_FRAME_DONE) ? 1 : 0;
+}
+
+void _exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+	unsigned int reg = readl(&mipi_dsim->intsrc);
+
+	writel(reg | INTSRC_FRAME_DONE, &mipi_dsim->intsrc);
+}
+
+void exynos_mipi_dsi_wr_tx_data(struct mipi_dsim_device *dsim,
+		unsigned int tx_data)
+{
+	struct exynos_mipi_dsim *mipi_dsim =
+		(struct exynos_mipi_dsim *)samsung_get_base_mipi_dsim();
+
+	writel(tx_data, &mipi_dsim->payload);
+}
diff --git a/drivers/video/exynos_mipi_dsi_lowlevel.h b/drivers/video/exynos_mipi_dsi_lowlevel.h
new file mode 100644
index 0000000..4b8c441
--- /dev/null
+++ b/drivers/video/exynos_mipi_dsi_lowlevel.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * Author: InKi Dae <inki.dae@samsung.com>
+ * Author: Donghwa Lee <dh09.lee@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _EXYNOS_MIPI_DSI_LOWLEVEL_H
+#define _EXYNOS_MIPI_DSI_LOWLEVEL_H
+
+void exynos_mipi_dsi_register(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_func_reset(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_sw_reset(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_sw_release(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_set_interrupt_mask(struct mipi_dsim_device *dsim,
+	unsigned int mode, unsigned int mask);
+void exynos_mipi_dsi_set_data_lane_number(struct mipi_dsim_device *dsim,
+					unsigned int count);
+void exynos_mipi_dsi_init_fifo_pointer(struct mipi_dsim_device *dsim,
+					unsigned int cfg);
+void exynos_mipi_dsi_set_phy_tunning(struct mipi_dsim_device *dsim,
+				unsigned int value);
+void exynos_mipi_dsi_set_phy_tunning(struct mipi_dsim_device *dsim,
+				unsigned int value);
+void exynos_mipi_dsi_set_main_disp_resol(struct mipi_dsim_device *dsim,
+		unsigned int width_resol, unsigned int height_resol);
+void exynos_mipi_dsi_set_main_disp_vporch(struct mipi_dsim_device *dsim,
+	unsigned int cmd_allow, unsigned int vfront, unsigned int vback);
+void exynos_mipi_dsi_set_main_disp_hporch(struct mipi_dsim_device *dsim,
+			unsigned int front, unsigned int back);
+void exynos_mipi_dsi_set_main_disp_sync_area(struct mipi_dsim_device *dsim,
+				unsigned int vert, unsigned int hori);
+void exynos_mipi_dsi_set_sub_disp_resol(struct mipi_dsim_device *dsim,
+				unsigned int vert, unsigned int hori);
+void exynos_mipi_dsi_init_config(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_display_config(struct mipi_dsim_device *dsim,
+				struct mipi_dsim_config *dsim_config);
+void exynos_mipi_dsi_set_data_lane_number(struct mipi_dsim_device *dsim,
+				unsigned int count);
+void exynos_mipi_dsi_enable_lane(struct mipi_dsim_device *dsim,
+			unsigned int lane, unsigned int enable);
+void exynos_mipi_dsi_enable_afc(struct mipi_dsim_device *dsim,
+			unsigned int enable, unsigned int afc_code);
+void exynos_mipi_dsi_enable_pll_bypass(struct mipi_dsim_device *dsim,
+				unsigned int enable);
+void exynos_mipi_dsi_pll_freq_band(struct mipi_dsim_device *dsim,
+				unsigned int freq_band);
+void exynos_mipi_dsi_pll_freq(struct mipi_dsim_device *dsim,
+			unsigned int pre_divider, unsigned int main_divider,
+			unsigned int scaler);
+void exynos_mipi_dsi_pll_stable_time(struct mipi_dsim_device *dsim,
+			unsigned int lock_time);
+void exynos_mipi_dsi_enable_pll(struct mipi_dsim_device *dsim,
+					unsigned int enable);
+void exynos_mipi_dsi_set_byte_clock_src(struct mipi_dsim_device *dsim,
+					unsigned int src);
+void exynos_mipi_dsi_enable_byte_clock(struct mipi_dsim_device *dsim,
+					unsigned int enable);
+void exynos_mipi_dsi_set_esc_clk_prs(struct mipi_dsim_device *dsim,
+				unsigned int enable, unsigned int prs_val);
+void exynos_mipi_dsi_enable_esc_clk_on_lane(struct mipi_dsim_device *dsim,
+				unsigned int lane_sel, unsigned int enable);
+void exynos_mipi_dsi_force_dphy_stop_state(struct mipi_dsim_device *dsim,
+				unsigned int enable);
+unsigned int exynos_mipi_dsi_is_lane_state(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_set_stop_state_counter(struct mipi_dsim_device *dsim,
+				unsigned int cnt_val);
+void exynos_mipi_dsi_set_bta_timeout(struct mipi_dsim_device *dsim,
+				unsigned int timeout);
+void exynos_mipi_dsi_set_lpdr_timeout(struct mipi_dsim_device *dsim,
+				unsigned int timeout);
+void exynos_mipi_dsi_set_lcdc_transfer_mode(struct mipi_dsim_device *dsim,
+					unsigned int lp);
+void exynos_mipi_dsi_set_cpu_transfer_mode(struct mipi_dsim_device *dsim,
+					unsigned int lp);
+void exynos_mipi_dsi_enable_hs_clock(struct mipi_dsim_device *dsim,
+				unsigned int enable);
+void exynos_mipi_dsi_dp_dn_swap(struct mipi_dsim_device *dsim,
+				unsigned int swap_en);
+void exynos_mipi_dsi_hs_zero_ctrl(struct mipi_dsim_device *dsim,
+				unsigned int hs_zero);
+void exynos_mipi_dsi_prep_ctrl(struct mipi_dsim_device *dsim,
+				unsigned int prep);
+void exynos_mipi_dsi_clear_interrupt(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_clear_all_interrupt(struct mipi_dsim_device *dsim);
+unsigned int exynos_mipi_dsi_is_pll_stable(struct mipi_dsim_device *dsim);
+unsigned int exynos_mipi_dsi_get_fifo_state(struct mipi_dsim_device *dsim);
+unsigned int _exynos_mipi_dsi_get_frame_done_status(struct mipi_dsim_device
+						*dsim);
+void _exynos_mipi_dsi_clear_frame_done(struct mipi_dsim_device *dsim);
+void exynos_mipi_dsi_wr_tx_header(struct mipi_dsim_device *dsim,
+		unsigned int di, unsigned int data0, unsigned int data1);
+void exynos_mipi_dsi_wr_tx_data(struct mipi_dsim_device *dsim,
+		unsigned int tx_data);
+
+#endif /* _EXYNOS_MIPI_DSI_LOWLEVEL_H */
diff --git a/drivers/video/s6e8ax0.c b/drivers/video/s6e8ax0.c
new file mode 100644
index 0000000..364e137
--- /dev/null
+++ b/drivers/video/s6e8ax0.c
@@ -0,0 +1,289 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ *
+ * Author: Donghwa Lee <dh09.lee@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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <lcd.h>
+#include <asm/errno.h>
+#include <asm/arch/dsim.h>
+#include <asm/arch/mipi_dsim.h>
+#include <asm/arch/power.h>
+#include <asm/arch/cpu.h>
+#include <linux/types.h>
+#include <linux/list.h>
+
+#include "exynos_mipi_dsi_lowlevel.h"
+#include "exynos_mipi_dsi_common.h"
+
+#define DSIM_PM_STABLE_TIME	(10)
+#define MIN_BRIGHTNESS		(0)
+#define MAX_BRIGHTNESS		(10)
+
+#define lcd_to_master(a)	(a->dsim_dev->master)
+#define lcd_to_master_ops(a)	((lcd_to_master(a))->master_ops)
+
+enum {
+	DSIM_NONE_STATE = 0,
+	DSIM_RESUME_COMPLETE = 1,
+	DSIM_FRAME_DONE = 2,
+};
+
+struct s6e8ax0 {
+	unsigned int			power;
+	unsigned int			updated;
+	unsigned int			gamma;
+	unsigned int			resume_complete;
+
+	struct mipi_dsim_lcd_device	*lcd_dev;
+	struct lcd_platform_data	*ddi_pd;
+};
+
+static void s6e8ax0_panel_cond(struct mipi_dsim_device *dsim_dev)
+{
+	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
+
+	const unsigned char data_to_send[] = {
+		0xf8, 0x3d, 0x35, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x4c,
+		0x6e, 0x10, 0x27, 0x7d, 0x3f, 0x10, 0x00, 0x00, 0x20,
+		0x04, 0x08, 0x6e, 0x00, 0x00, 0x00, 0x02, 0x08, 0x08,
+		0x23, 0x23, 0xc0, 0xc8, 0x08, 0x48, 0xc1, 0x00, 0xc3,
+		0xff, 0xff, 0xc8
+	};
+
+	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
+			(unsigned int)data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_display_cond(struct mipi_dsim_device *dsim_dev)
+{
+	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
+
+	const unsigned char data_to_send[] = {
+		0xf2, 0x80, 0x03, 0x0d
+	};
+
+	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
+			(unsigned int)data_to_send,
+			ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_gamma_cond(struct mipi_dsim_device *dsim_dev)
+{
+	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
+
+	/* 7500K 2.2 Set (M3, 300cd) */
+	const unsigned char data_to_send[] = {
+		0xfa, 0x01, 0x0f, 0x00, 0x0f, 0xda, 0xc0, 0xe4, 0xc8,
+		0xc8, 0xc6, 0xd3, 0xd6, 0xd0, 0xab, 0xb2, 0xa6, 0xbf,
+		0xc2, 0xb9, 0x00, 0x93, 0x00, 0x86, 0x00, 0xd1
+	};
+
+	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
+			(unsigned int)data_to_send,
+			ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_gamma_update(struct mipi_dsim_device *dsim_dev)
+{
+	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
+
+	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_SHORT_WRITE_PARAM, 0xf7, 0x3);
+}
+
+static void s6e8ax0_etc_source_control(struct mipi_dsim_device *dsim_dev)
+{
+	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
+
+	const unsigned char data_to_send[] = {
+		0xf6, 0x00, 0x02, 0x00
+	};
+
+	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
+			(unsigned int)data_to_send,
+			ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_etc_pentile_control(struct mipi_dsim_device *dsim_dev)
+{
+	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
+
+	const unsigned char data_to_send[] = {
+		0xb6, 0x0c, 0x02, 0x03, 0x32, 0xff, 0x44, 0x44, 0xc0,
+		0x00
+	};
+
+	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
+			(unsigned int)data_to_send,
+			ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_etc_mipi_control1(struct mipi_dsim_device *dsim_dev)
+{
+	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
+
+	const unsigned char data_to_send[] = {
+		0xe1, 0x10, 0x1c, 0x17, 0x08, 0x1d
+	};
+
+	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
+			(unsigned int)data_to_send,
+			ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_etc_mipi_control2(struct mipi_dsim_device *dsim_dev)
+{
+	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
+	const unsigned char data_to_send[] = {
+		0xe2, 0xed, 0x07, 0xc3, 0x13, 0x0d, 0x03
+	};
+
+	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
+			(unsigned int)data_to_send,
+			ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_etc_power_control(struct mipi_dsim_device *dsim_dev)
+{
+	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
+	const unsigned char data_to_send[] = {
+		0xf4, 0xcf, 0x0a, 0x12, 0x10, 0x19, 0x33, 0x02
+	};
+
+	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
+		(unsigned int)data_to_send, ARRAY_SIZE(data_to_send));
+}
+static void s6e8ax0_etc_mipi_control3(struct mipi_dsim_device *dsim_dev)
+{
+	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
+	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_SHORT_WRITE_PARAM, 0xe3, 0x40);
+}
+
+static void s6e8ax0_etc_mipi_control4(struct mipi_dsim_device *dsim_dev)
+{
+	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
+	const unsigned char data_to_send[] = {
+		0xe4, 0x00, 0x00, 0x14, 0x80, 0x00, 0x00, 0x00
+	};
+
+	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
+		(unsigned int)data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_elvss_set(struct mipi_dsim_device *dsim_dev)
+{
+	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
+
+	const unsigned char data_to_send[] = {
+		0xb1, 0x04, 0x00
+	};
+
+	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
+			(unsigned int)data_to_send,
+			ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_display_on(struct mipi_dsim_device *dsim_dev)
+{
+	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
+	ops->cmd_write(dsim_dev,
+		MIPI_DSI_DCS_SHORT_WRITE, 0x29, 0x00);
+}
+
+static void s6e8ax0_sleep_out(struct mipi_dsim_device *dsim_dev)
+{
+	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
+	ops->cmd_write(dsim_dev,
+		MIPI_DSI_DCS_SHORT_WRITE, 0x11, 0x00);
+}
+
+static void s6e8ax0_apply_level1_key(struct mipi_dsim_device *dsim_dev)
+{
+	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
+	const unsigned char data_to_send[] = {
+		0xf0, 0x5a, 0x5a
+	};
+
+	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
+		(unsigned int)data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_apply_mtp_key(struct mipi_dsim_device *dsim_dev)
+{
+	struct mipi_dsim_master_ops *ops = dsim_dev->master_ops;
+	const unsigned char data_to_send[] = {
+		0xf1, 0x5a, 0x5a
+	};
+
+	ops->cmd_write(dsim_dev, MIPI_DSI_DCS_LONG_WRITE,
+		(unsigned int)data_to_send, ARRAY_SIZE(data_to_send));
+}
+
+static void s6e8ax0_panel_init(struct mipi_dsim_device *dsim_dev)
+{
+	/*
+	 * in case of setting gamma and panel condition at first,
+	 * it shuold be setting like below.
+	 * set_gamma() -> set_panel_condition()
+	 */
+
+	s6e8ax0_apply_level1_key(dsim_dev);
+	s6e8ax0_apply_mtp_key(dsim_dev);
+
+	s6e8ax0_sleep_out(dsim_dev);
+	udelay(5 * 1000);
+	s6e8ax0_panel_cond(dsim_dev);
+	s6e8ax0_display_cond(dsim_dev);
+	s6e8ax0_gamma_cond(dsim_dev);
+	s6e8ax0_gamma_update(dsim_dev);
+
+	s6e8ax0_etc_source_control(dsim_dev);
+	s6e8ax0_elvss_set(dsim_dev);
+	s6e8ax0_etc_pentile_control(dsim_dev);
+	s6e8ax0_etc_mipi_control1(dsim_dev);
+	s6e8ax0_etc_mipi_control2(dsim_dev);
+	s6e8ax0_etc_power_control(dsim_dev);
+	s6e8ax0_etc_mipi_control3(dsim_dev);
+	s6e8ax0_etc_mipi_control4(dsim_dev);
+}
+
+static int s6e8ax0_panel_set(struct mipi_dsim_device *dsim_dev)
+{
+	s6e8ax0_panel_init(dsim_dev);
+
+	return 0;
+}
+
+static void s6e8ax0_display_enable(struct mipi_dsim_device *dsim_dev)
+{
+	s6e8ax0_display_on(dsim_dev);
+}
+
+static struct mipi_dsim_lcd_driver s6e8ax0_dsim_ddi_driver = {
+	.name = "s6e8ax0",
+	.id = -1,
+
+	.mipi_panel_init = s6e8ax0_panel_set,
+	.mipi_display_on = s6e8ax0_display_enable,
+};
+
+void s6e8ax0_init(void)
+{
+	exynos_mipi_dsi_register_lcd_driver(&s6e8ax0_dsim_ddi_driver);
+}
diff --git a/include/lcd.h b/include/lcd.h
index 651ff42..bd21333 100644
--- a/include/lcd.h
+++ b/include/lcd.h
@@ -230,6 +230,7 @@ typedef struct vidinfo {
 	unsigned int power_on_delay;
 	unsigned int reset_delay;
 	unsigned int interface_mode;
+	unsigned int mipi_enabled;
 	unsigned int cs_setup;
 	unsigned int wr_setup;
 	unsigned int wr_act;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2012-04-04  6:29 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-04-04  6:29 [U-Boot] [PATCH 2/2]ARM: EXYNOS: support mipi dsi driver Donghwa Lee

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.