diff mbox

[3/4] S5PC110: add MIPI-DSI support for platform and machine.

Message ID 1290496593-4927-1-git-send-email-inki.dae@samsung.com (mailing list archive)
State Superseded
Delegated to: Paul Mundt
Headers show

Commit Message

Inki Dae Nov. 23, 2010, 7:16 a.m. UTC
None
diff mbox

Patch

diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig
index 862f239..447701f 100644
--- a/arch/arm/mach-s5pv210/Kconfig
+++ b/arch/arm/mach-s5pv210/Kconfig
@@ -53,6 +53,12 @@  config S5PV210_SETUP_SDHCI_GPIO
 	help
 	  Common setup code for SDHCI gpio.
 
+config S5PV210_SETUP_DSIM
+	bool
+	depends on REGULATOR
+	help
+	  Common setup code for MIPI-DSIM.
+
 menu "S5PC110 Machines"
 
 config MACH_AQUILA
@@ -68,6 +74,7 @@  config MACH_AQUILA
 	select S5P_DEV_ONENAND
 	select S5PV210_SETUP_FB_24BPP
 	select S5PV210_SETUP_SDHCI
+	select S5PV210_SETUP_DSIM
 	help
 	  Machine support for the Samsung Aquila target based on S5PC110 SoC
 
@@ -86,12 +93,14 @@  config MACH_GONI
 	select S3C_DEV_I2C2
 	select S3C_DEV_USB_HSOTG
 	select S5P_DEV_ONENAND
+	select S5P_DEV_DSIM
 	select SAMSUNG_DEV_KEYPAD
 	select S5PV210_SETUP_FB_24BPP
 	select S5PV210_SETUP_I2C1
 	select S5PV210_SETUP_I2C2
 	select S5PV210_SETUP_KEYPAD
 	select S5PV210_SETUP_SDHCI
+	select S5PV210_SETUP_DSIM
 	help
 	  Machine support for Samsung GONI board
 	  S5PC110(MCP) is one of package option of S5PV210
@@ -107,6 +116,7 @@  config MACH_SMDKC110
 	select S5PV210_SETUP_I2C1
 	select S5PV210_SETUP_I2C2
 	select S5PV210_SETUP_IDE
+	select S5PV210_SETUP_DSIM
 	help
 	  Machine support for Samsung SMDKC110
 	  S5PC110(MCP) is one of package option of S5PV210
@@ -135,6 +145,7 @@  config MACH_SMDKV210
 	select S5PV210_SETUP_IDE
 	select S5PV210_SETUP_KEYPAD
 	select S5PV210_SETUP_SDHCI
+	select S5PV210_SETUP_DSIM
 	help
 	  Machine support for Samsung SMDKV210
 
diff --git a/arch/arm/mach-s5pv210/Makefile b/arch/arm/mach-s5pv210/Makefile
index ff1a0db..f6a6443 100644
--- a/arch/arm/mach-s5pv210/Makefile
+++ b/arch/arm/mach-s5pv210/Makefile
@@ -29,6 +29,7 @@  obj-$(CONFIG_MACH_TORBRECK)	+= mach-torbreck.o
 
 obj-y				+= dev-audio.o
 obj-$(CONFIG_S3C64XX_DEV_SPI)	+= dev-spi.o
+obj-$(CONFIG_S5P_DEV_DSIM)	+= dev-dsim.o
 
 obj-$(CONFIG_S5PV210_SETUP_FB_24BPP)	+= setup-fb-24bpp.o
 obj-$(CONFIG_S5PV210_SETUP_I2C1) 	+= setup-i2c1.o
@@ -37,3 +38,4 @@  obj-$(CONFIG_S5PV210_SETUP_IDE)		+= setup-ide.o
 obj-$(CONFIG_S5PV210_SETUP_KEYPAD)	+= setup-keypad.o
 obj-$(CONFIG_S5PV210_SETUP_SDHCI)       += setup-sdhci.o
 obj-$(CONFIG_S5PV210_SETUP_SDHCI_GPIO)	+= setup-sdhci-gpio.o
+obj-$(CONFIG_S5PV210_SETUP_DSIM)	+= setup-dsim.o
diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c
index 019c3a6..9cbf244 100644
--- a/arch/arm/mach-s5pv210/clock.c
+++ b/arch/arm/mach-s5pv210/clock.c
@@ -347,6 +347,12 @@  static struct clk init_clocks_disable[] = {
 		.enable		= s5pv210_clk_ip0_ctrl,
 		.ctrlbit	= (1 << 26),
 	}, {
+		.name		= "dsim",
+		.id		= -1,
+		.parent		= &clk_hclk_dsys.clk,
+		.enable		= s5pv210_clk_ip1_ctrl,
+		.ctrlbit	= (1<<2),
+	}, {
 		.name		= "otg",
 		.id		= -1,
 		.parent		= &clk_hclk_psys.clk,
diff --git a/arch/arm/mach-s5pv210/dev-dsim.c b/arch/arm/mach-s5pv210/dev-dsim.c
new file mode 100644
index 0000000..3f43d72
--- /dev/null
+++ b/arch/arm/mach-s5pv210/dev-dsim.c
@@ -0,0 +1,149 @@ 
+/* linux/arch/arm/plat-s5pc11x/dev-dsim.c
+ *
+ * Copyright 2009 Samsung Electronics
+ *	InKi Dae <inki.dae@samsung.com>
+ *
+ * S5PC1XX series device definition for MIPI-DSIM
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/fb.h>
+
+#include <mach/map.h>
+#include <mach/irqs.h>
+
+#include <plat/devs.h>
+#include <plat/cpu.h>
+#include <plat/fb.h>
+
+#include <plat/dsim.h>
+#include <plat/mipi_ddi.h>
+
+static struct dsim_config dsim_info = {
+	/* main frame fifo auto flush at VSYNC pulse */
+	.auto_flush = false,
+	.eot_disable = false,
+
+	.auto_vertical_cnt = false,
+	.hse = false,
+	.hfp = false,
+	.hbp = false,
+	.hsa = false,
+
+	.e_no_data_lane = DSIM_DATA_LANE_2,
+	.e_byte_clk = DSIM_PLL_OUT_DIV8,
+
+	/*
+	 * ===========================================
+	 * |    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    |
+	 * |    3    |   118   |    1    |    472    |
+	 * |   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    |
+	 * -------------------------------------------
+	 */
+
+	/* 472MHz: LSI Recommended */
+	.p = 3,
+	.m = 118,
+	.s = 1,
+
+	/* D-PHY PLL stable time spec :min = 200usec ~ max 400usec */
+	.pll_stable_time = 400,
+
+	.esc_clk = 10 * 1000000,	/* escape clk : 10MHz */
+
+	/* stop state holding counter after bta change count 0 ~ 0xfff */
+	.stop_holding_cnt = 0x0f,
+	.bta_timeout = 0xff,		/* bta timeout 0 ~ 0xff */
+	.rx_timeout = 0xffff,		/* lp rx timeout 0 ~ 0xffff */
+
+	.e_lane_swap = DSIM_NO_CHANGE,
+};
+
+/* define ddi platform data based on MIPI-DSI. */
+static struct mipi_ddi_platform_data mipi_ddi_pd = {
+	.cmd_write			= s5p_dsim_wr_data,
+	.cmd_read			= NULL,
+	.get_dsim_frame_done		= s5p_dsim_get_frame_done_status,
+	.clear_dsim_frame_done		= s5p_dsim_clear_frame_done,
+	.change_dsim_transfer_mode	= s5p_dsim_change_transfer_mode,
+	.get_fb_frame_done		= NULL,
+	.trigger			= NULL,
+};
+
+static struct dsim_lcd_config dsim_lcd_info = {
+	.e_interface			= DSIM_COMMAND,
+	.parameter[DSI_VIRTUAL_CH_ID]	= (unsigned int)DSIM_VIRTUAL_CH_0,
+	.parameter[DSI_FORMAT]		= (unsigned int)DSIM_24BPP_888,
+	.parameter[DSI_VIDEO_MODE_SEL]	= (unsigned int)DSIM_BURST,
+	.mipi_ddi_pd			= (void *)&mipi_ddi_pd,
+};
+
+static struct resource s5p_dsim_resource[] = {
+	[0] = {
+		.start = S5PV210_PA_DSI,
+		.end   = S5PV210_PA_DSI + S5PV210_SZ_DSI - 1,
+		.flags = IORESOURCE_MEM,
+	},
+	[1] = {
+		.start = IRQ_MIPIDSI,
+		.end   = IRQ_MIPIDSI,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct s5p_platform_dsim dsim_platform_data = {
+	.clk_name		= "dsim",
+	.mipi_1_1v_name		= "vmipi_1.1v",
+	.mipi_1_8v_name		= "vmipi_1.8v",
+	.dsim_info		= &dsim_info,
+	.dsim_lcd_info		= &dsim_lcd_info,
+
+	.mipi_power		= s5p_dsim_mipi_power,
+	.part_reset		= s5p_dsim_part_reset,
+	.init_d_phy		= s5p_dsim_init_d_phy,
+	.get_fb_frame_done	= NULL,
+	.trigger		= NULL,
+
+	.platform_rev		= 1,
+
+	/*
+	 * the stable time of needing to write data on SFR
+	 * when the mipi mode becomes LP mode.
+	 */
+	.delay_for_stabilization = 600,
+};
+
+struct platform_device s5p_device_dsim = {
+	.name			= "s5p-dsim",
+	.id			= 0,
+	.num_resources		= ARRAY_SIZE(s5p_dsim_resource),
+	.resource		= s5p_dsim_resource,
+	.dev			= {
+		.platform_data = (void *)&dsim_platform_data,
+	},
+};
diff --git a/arch/arm/mach-s5pv210/include/mach/map.h b/arch/arm/mach-s5pv210/include/mach/map.h
index 861d7fe..1ad2dad 100644
--- a/arch/arm/mach-s5pv210/include/mach/map.h
+++ b/arch/arm/mach-s5pv210/include/mach/map.h
@@ -69,6 +69,10 @@ 
 
 #define S5PV210_PA_FB		(0xF8000000)
 
+/* MIPI-DSI */
+#define S5PV210_PA_DSI		(0xFA500000)
+#define S5PV210_SZ_DSI		SZ_1M
+
 #define S5PV210_PA_FIMC0	(0xFB200000)
 #define S5PV210_PA_FIMC1	(0xFB300000)
 #define S5PV210_PA_FIMC2	(0xFB400000)
diff --git a/arch/arm/mach-s5pv210/include/mach/regs-clock.h b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
index ebaabe0..c8b9366 100644
--- a/arch/arm/mach-s5pv210/include/mach/regs-clock.h
+++ b/arch/arm/mach-s5pv210/include/mach/regs-clock.h
@@ -196,7 +196,8 @@ 
 #define S5P_OTHERS_USB_SIG_MASK		(1 << 16)
 
 /* MIPI */
-#define S5P_MIPI_DPHY_EN		(3)
+#define S5P_MIPI_DPHY_EN		(3 << 0)
+#define S5P_MIPI_M_RESETN		(1 << 1)
 
 /* S5P_DAC_CONTROL */
 #define S5P_DAC_ENABLE			(1)
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c
index b1dcf96..500cc1b 100644
--- a/arch/arm/mach-s5pv210/mach-goni.c
+++ b/arch/arm/mach-s5pv210/mach-goni.c
@@ -269,10 +269,18 @@  static void __init goni_tsp_init(void)
 /* MAX8998 regulators */
 #if defined(CONFIG_REGULATOR_MAX8998) || defined(CONFIG_REGULATOR_MAX8998_MODULE)
 
+static struct regulator_consumer_supply goni_ldo3_consumers[] = {
+	REGULATOR_SUPPLY("vmipi_1.1v", ""),
+};
+
 static struct regulator_consumer_supply goni_ldo5_consumers[] = {
 	REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"),
 };
 
+static struct regulator_consumer_supply goni_ldo7_consumers[] = {
+	REGULATOR_SUPPLY("vmipi_1.8v", ""),
+};
+
 static struct regulator_init_data goni_ldo2_data = {
 	.constraints	= {
 		.name		= "VALIVE_1.1V",
@@ -294,6 +302,8 @@  static struct regulator_init_data goni_ldo3_data = {
 		.apply_uV	= 1,
 		.always_on	= 1,
 	},
+	.num_consumer_supplies = ARRAY_SIZE(goni_ldo3_consumers),
+	.consumer_supplies = goni_ldo3_consumers,
 };
 
 static struct regulator_init_data goni_ldo4_data = {
@@ -333,6 +343,8 @@  static struct regulator_init_data goni_ldo7_data = {
 		.apply_uV	= 1,
 		.always_on	= 1,
 	},
+	.num_consumer_supplies = ARRAY_SIZE(goni_ldo7_consumers),
+	.consumer_supplies = goni_ldo7_consumers,
 };
 
 static struct regulator_init_data goni_ldo8_data = {
diff --git a/arch/arm/mach-s5pv210/setup-dsim.c b/arch/arm/mach-s5pv210/setup-dsim.c
new file mode 100644
index 0000000..874efa0
--- /dev/null
+++ b/arch/arm/mach-s5pv210/setup-dsim.c
@@ -0,0 +1,144 @@ 
+/*
+ * S5PC110 MIPI-DSIM driver.
+ *
+ * Author: InKi Dae <inki.dae@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/kernel.h>
+#include <linux/string.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+
+#include <mach/map.h>
+#include <mach/regs-clock.h>
+
+#include <plat/dsim.h>
+#include <plat/clock.h>
+#include <plat/regs-dsim.h>
+
+static int s5p_dsim_enable_d_phy(struct dsim_global *dsim, unsigned int enable)
+{
+	unsigned int reg;
+
+	WARN_ON(dsim == NULL);
+
+	reg = readl(S5P_MIPI_CONTROL) & ~(1 << 0);
+	reg |= (enable << 0);
+	writel(reg, S5P_MIPI_CONTROL);
+
+	dev_dbg(dsim->dev, "%s : %x\n", __func__, reg);
+
+	return 0;
+}
+
+static int s5p_dsim_enable_dsi_master(struct dsim_global *dsim,
+	unsigned int enable)
+{
+	unsigned int reg;
+
+	WARN_ON(dsim == NULL);
+
+	reg = readl(S5P_MIPI_CONTROL) & ~(1 << 2);
+	reg |= (enable << 2);
+	writel(reg, S5P_MIPI_CONTROL);
+
+	dev_dbg(dsim->dev, "%s : %x\n", __func__, reg);
+
+	return 0;
+}
+
+int s5p_dsim_part_reset(struct dsim_global *dsim)
+{
+	WARN_ON(dsim == NULL);
+
+	writel(S5P_MIPI_M_RESETN, S5P_MIPI_PHY_CON0);
+
+	dev_dbg(dsim->dev, "%s\n", __func__);
+
+	return 0;
+}
+
+int s5p_dsim_init_d_phy(struct dsim_global *dsim)
+{
+	WARN_ON(dsim == NULL);
+
+	/**
+	 * DPHY and Master block must be enabled at the system initialization
+	 * step before data access from/to DPHY begins.
+	 */
+	s5p_dsim_enable_d_phy(dsim, 1);
+
+	s5p_dsim_enable_dsi_master(dsim, 1);
+
+	dev_dbg(dsim->dev, "%s\n", __func__);
+
+	return 0;
+}
+
+int s5p_dsim_mipi_power(struct dsim_global *dsim, struct regulator *p_mipi_1_1v,
+	struct regulator *p_mipi_1_8v, unsigned int enable)
+{
+	int ret = -1;
+
+	WARN_ON(dsim == NULL);
+
+	if (IS_ERR(p_mipi_1_1v) || IS_ERR(p_mipi_1_8v)) {
+		dev_err(dsim->dev, "p_mipi_1_1v or p_mipi_1_8v is NULL.\n");
+		return -EINVAL;
+	}
+
+	if (enable) {
+		if (p_mipi_1_1v)
+			ret = regulator_enable(p_mipi_1_1v);
+
+		if (ret < 0) {
+			dev_err(dsim->dev,
+				"failed to enable regulator mipi_1_1v.\n");
+			return ret;
+		}
+
+		if (p_mipi_1_8v)
+			ret = regulator_enable(p_mipi_1_8v);
+
+		if (ret < 0) {
+			dev_err(dsim->dev,
+				"failed to enable regulator mipi_1_8v.\n");
+			return ret;
+		}
+	} else {
+		if (p_mipi_1_1v)
+			ret = regulator_force_disable(p_mipi_1_1v);
+		if (ret < 0) {
+			dev_err(dsim->dev,
+				"failed to disable regulator mipi_1_1v.\n");
+			return ret;
+		}
+
+		if (p_mipi_1_8v)
+			ret = regulator_force_disable(p_mipi_1_8v);
+		if (ret < 0) {
+			dev_err(dsim->dev,
+				"failed to disable regulator mipi_1_8v.\n");
+			return ret;
+		}
+	}
+
+	return ret;
+}
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index 65dbfa8..73a34e0 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -56,3 +56,8 @@  config S5P_DEV_ONENAND
 	bool
 	help
 	  Compile in platform device definition for OneNAND controller
+
+config S5P_DEV_DSIM
+	bool
+	help
+	  Compile in platform device definitions for MIPI-DSI