aboutsummaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorJimmy Rubin <ejimrub@steludxu031.lud.stericsson.com>2010-06-11 13:38:15 +0200
committerJohn Rigby <john.rigby@linaro.org>2010-09-02 22:45:43 -0600
commit8c47209c5bf71bfcb79544171a2ac744b93eb081 (patch)
treeb711a6a61c3f182a0dd4e6d0d95f68e9305fe720 /arch/arm
parent8eba235f737a41b41f0cd5e5cf60c3aef1261eff (diff)
downloadlinux-2.6.34-ux500-8c47209c5bf71bfcb79544171a2ac744b93eb081.tar.gz
MCDE: Supports new HDMI features
This patch does the following: * Dynamic resolution change (HDMI and TV-out) * Dynamic change of rotation (Main display) * Dynamic change to 24 and 32 bpp (RGB888, RGBA8888, RGBX8888) * HDMI stability improvements * Removes Framebuffer_console for V.20 and HREF+. * Support for disabling display initialization if u-boot supports startup graphics * Adds prcmu handling from the mcde driver ST Ericsson Change-Id: WP259361 Signed-off-by: Mian Yousaf Kaukab <mian.yousaf.kaukab@stericsson.com> Change-Id: I37e91d49f1550a3ecd041d4ddf67ce57e086772c Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/2536 Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
Diffstat (limited to 'arch/arm')
-rwxr-xr-xarch/arm/configs/mop500_power_defconfig4
-rwxr-xr-xarch/arm/mach-ux500/Makefile1
-rw-r--r--arch/arm/mach-ux500/board-mop500-mcde.c449
-rwxr-xr-xarch/arm/mach-ux500/board-mop500.c491
-rwxr-xr-xarch/arm/mach-ux500/include/mach/prcmu-fw-api.h1
-rwxr-xr-xarch/arm/mach-ux500/include/mach/prcmu-regs.h26
-rwxr-xr-xarch/arm/mach-ux500/prcmu-fw.c85
7 files changed, 595 insertions, 462 deletions
diff --git a/arch/arm/configs/mop500_power_defconfig b/arch/arm/configs/mop500_power_defconfig
index f98e650934f..a427cb63fc0 100755
--- a/arch/arm/configs/mop500_power_defconfig
+++ b/arch/arm/configs/mop500_power_defconfig
@@ -1309,8 +1309,8 @@ CONFIG_FB_B2R2=y
# Console display driver support
#
# CONFIG_VGA_CONSOLE is not set
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_DUMMY_CONSOLE is not set
+# CONFIG_FRAMEBUFFER_CONSOLE is not set
# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
# CONFIG_FONTS is not set
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile
index e7bbb54e48c..3e3d7ad581c 100755
--- a/arch/arm/mach-ux500/Makefile
+++ b/arch/arm/mach-ux500/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o mop500-sdi.o
obj-$(CONFIG_UX500_SOC_DB5500) += db5500-devices.o cpu-db5500.o
obj-$(CONFIG_UX500_SOC_DB8500) += db8500-devices.o hsi.o mcde.o \
cpu-db8500.o prcmu-fw.o
+obj-$(CONFIG_FB_MCDE) += board-mop500-mcde.o
obj-$(CONFIG_MACH_U8500_SIMULATOR) += board-mop500.o mop500-sdi.o
obj-$(CONFIG_MACH_U5500_SIMULATOR) += board-u5500.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o localtimer.o
diff --git a/arch/arm/mach-ux500/board-mop500-mcde.c b/arch/arm/mach-ux500/board-mop500-mcde.c
new file mode 100644
index 00000000000..7fbb35caf22
--- /dev/null
+++ b/arch/arm/mach-ux500/board-mop500-mcde.c
@@ -0,0 +1,449 @@
+/*
+ * Copyright (C) ST-Ericsson AB 2010
+ *
+ * Author: Marcus Lorentzon <marcus.xm.lorentzon@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+#include <linux/platform_device.h>
+#include <mach/tc35892.h>
+#include <mach/ab8500_denc.h>
+#include <video/av8100.h>
+#include <video/mcde_display.h>
+#include <video/mcde_display-generic_dsi.h>
+#include <video/mcde_display-av8100.h>
+#include <video/mcde_display-ab8500.h>
+#include <video/mcde_fb.h>
+#include <video/mcde_dss.h>
+
+#define DSI_UNIT_INTERVAL_0 0xA
+#define DSI_UNIT_INTERVAL_1 0xA
+#define DSI_UNIT_INTERVAL_2 0x6
+
+static bool rotate_main = true;
+static bool display_initialize_during_boot;
+
+static int __init startup_graphics_setup(char *str)
+{
+ if (!str)
+ return 1;
+
+ switch (*str) {
+ case '0':
+ pr_info("No Startup graphics support\n");
+ display_initialize_during_boot = false;
+ break;
+ case '1':
+ pr_info("Startup graphics supported\n");
+ display_initialize_during_boot = true;
+ break;
+ default:
+ display_initialize_during_boot = false;
+ break;
+ };
+
+ return 1;
+}
+__setup("startup_graphics=", startup_graphics_setup);
+
+#ifdef CONFIG_DISPLAY_GENERIC_DSI_PRIMARY
+static struct mcde_port port0 = {
+ .type = MCDE_PORTTYPE_DSI,
+ .mode = MCDE_PORTMODE_CMD,
+ .pixel_format = MCDE_PORTPIXFMT_DSI_24BPP,
+ .ifc = 1,
+ .link = 0,
+ .sync_src = MCDE_SYNCSRC_BTA,
+ .update_auto_trig = false,
+ .phy = {
+ .dsi = {
+ .virt_id = 0,
+ .num_data_lanes = 2,
+ .ui = DSI_UNIT_INTERVAL_0,
+ },
+ },
+};
+
+struct mcde_display_generic_platform_data generic_display0_pdata = {
+ .reset_gpio = EGPIO_PIN_15,
+ .reset_delay = 1,
+#ifdef CONFIG_REGULATOR
+ .regulator_id = "v-display",
+ .min_supply_voltage = 2500000, /* 2.5V */
+ .max_supply_voltage = 2700000 /* 2.7V */
+#endif
+};
+
+struct mcde_display_device generic_display0 = {
+ .name = "mcde_disp_generic",
+ .id = 0,
+ .port = &port0,
+ .chnl_id = MCDE_CHNL_A,
+ .fifo = MCDE_FIFO_C0,
+ .default_pixel_format = MCDE_OVLYPIXFMT_RGB565,
+ .native_x_res = 864,
+ .native_y_res = 480,
+ .synchronized_update = false,
+ /* TODO: Remove rotation buffers once ESRAM driver is completed */
+ .rotbuf1 = U8500_ESRAM_BASE + 0x20000 * 4,
+ .rotbuf2 = U8500_ESRAM_BASE + 0x20000 * 4 + 0x10000,
+ .dev = {
+ .platform_data = &generic_display0_pdata,
+ },
+};
+#endif /* CONFIG_DISPLAY_GENERIC_DSI_PRIMARY */
+
+#ifdef CONFIG_DISPLAY_GENERIC_DSI_SECONDARY
+static struct mcde_port subdisplay_port = {
+ .type = MCDE_PORTTYPE_DSI,
+ .mode = MCDE_PORTMODE_CMD,
+ .pixel_format = MCDE_PORTPIXFMT_DSI_24BPP,
+ .ifc = 1,
+ .link = 1,
+ .sync_src = MCDE_SYNCSRC_BTA,
+ .update_auto_trig = false,
+ .phy = {
+ .dsi = {
+ .virt_id = 0,
+ .num_data_lanes = 2,
+ .ui = DSI_UNIT_INTERVAL_1,
+ },
+ },
+
+};
+
+static struct mcde_display_generic_platform_data generic_subdisplay_pdata = {
+ .reset_gpio = EGPIO_PIN_14,
+ .reset_delay = 1,
+#ifdef CONFIG_REGULATOR
+ .regulator_id = "v-display",
+ .min_supply_voltage = 2500000, /* 2.5V */
+ .max_supply_voltage = 2700000 /* 2.7V */
+#endif
+};
+
+static struct mcde_display_device generic_subdisplay = {
+ .name = "mcde_disp_generic_subdisplay",
+ .id = 1,
+ .port = &subdisplay_port,
+ .chnl_id = MCDE_CHNL_C1,
+ .fifo = MCDE_FIFO_C1,
+ .default_pixel_format = MCDE_OVLYPIXFMT_RGB565,
+ .native_x_res = 864,
+ .native_y_res = 480,
+ .synchronized_update = false,
+ .dev = {
+ .platform_data = &generic_subdisplay_pdata,
+ },
+};
+#endif /* CONFIG_DISPLAY_GENERIC_DSI_SECONDARY */
+
+
+#ifdef CONFIG_DISPLAY_AB8500_TERTIARY
+static struct mcde_port port_tvout1 = {
+ .type = MCDE_PORTTYPE_DPI,
+ .pixel_format = MCDE_PORTPIXFMT_DPI_24BPP,
+ .ifc = 0,
+ .link = 1,
+ .sync_src = MCDE_SYNCSRC_OFF,
+ .update_auto_trig = true,
+ .phy = {
+ .dpi = {
+ .num_data_lanes = 4, /* DDR mode */
+ },
+ },
+};
+
+static struct ab8500_display_platform_data ab8500_display_pdata = {
+ /* REVIEW use "#ifdef CONFIG_REGULATOR" as with other displays */
+ /* TODO use this ID as soon as we switch to newer kernel with support or
+ * ab8500 TVout regulator
+ .regulator_id = "v-tvout",
+ */
+ /* REVIEW change name: use transform instead of convert? */
+ .rgb_2_yCbCr_convert = {
+ .matrix = {
+ {0x42, 0x81, 0x19},
+ {0xffda, 0xffb6, 0x70},
+ {0x70, 0xffa2, 0xffee},
+ },
+ .offset = {0x80, 0x10, 0x80},
+ }
+};
+
+static int ab8500_platform_enable(struct mcde_display_device *ddev)
+{
+ int res = 0;
+ /* probe checks for pdata */
+ struct ab8500_display_platform_data *pdata = ddev->dev.platform_data;
+
+ dev_info(&ddev->dev, "%s\n", __func__);
+ res = stm_gpio_altfuncenable(GPIO_ALT_LCD_PANELB);
+ if (res != 0)
+ goto alt_func_failed;
+
+ if (pdata->regulator) {
+ res = regulator_enable(pdata->regulator);
+ if (res != 0)
+ goto regu_failed;
+ }
+
+ return res;
+
+regu_failed:
+ (void) stm_gpio_altfuncdisable(GPIO_ALT_LCD_PANELB);
+alt_func_failed:
+ dev_warn(&ddev->dev, "Failure during %s\n", __func__);
+ return res;
+}
+
+static int ab8500_platform_disable(struct mcde_display_device *ddev)
+{
+ int res;
+ /* probe checks for pdata */
+ struct ab8500_display_platform_data *pdata = ddev->dev.platform_data;
+
+ dev_info(&ddev->dev, "%s\n", __func__);
+
+ res = stm_gpio_altfuncdisable(GPIO_ALT_LCD_PANELB);
+ if (res != 0)
+ goto alt_func_failed;
+
+ if (pdata->regulator) {
+ res = regulator_disable(pdata->regulator);
+ if (res != 0)
+ goto regu_failed;
+ }
+
+ return res;
+regu_failed:
+ (void) stm_gpio_altfuncenable(GPIO_ALT_LCD_PANELB);
+alt_func_failed:
+ dev_warn(&ddev->dev, "Failure during %s\n", __func__);
+ return res;
+
+}
+
+static struct mcde_display_device tvout_ab8500_display = {
+ .name = "mcde_tv_ab8500",
+ .id = 2,
+ .port = &port_tvout1,
+ .chnl_id = MCDE_CHNL_B,
+ .fifo = MCDE_FIFO_B,
+ .default_pixel_format = MCDE_OVLYPIXFMT_RGB565,
+ .native_x_res = 720,
+ .native_y_res = 576,
+ .synchronized_update = true,
+ .dev = {
+ .platform_data = &ab8500_display_pdata,
+ },
+
+ /*
+ * We might need to describe the std here:
+ * - there are different PAL / NTSC formats (do they require MCDE
+ * settings?)
+ */
+ .platform_enable = ab8500_platform_enable,
+ .platform_disable = ab8500_platform_disable,
+};
+
+static struct ab8500_denc_platform_data ab8500_denc_pdata = {
+ .ddr_enable = true,
+ .ddr_little_endian = false,
+};
+
+static struct platform_device ab8500_denc = {
+ .name = "ab8500_denc",
+ .id = -1,
+ .dev = {
+ .platform_data = &ab8500_denc_pdata,
+ },
+};
+#endif /* CONFIG_DISPLAY_AB8500_TERTIARY */
+
+#ifdef CONFIG_DISPLAY_AV8100_TERTIARY
+static struct mcde_port port2 = {
+ .type = MCDE_PORTTYPE_DSI,
+ .mode = MCDE_PORTMODE_CMD,
+ .pixel_format = MCDE_PORTPIXFMT_DSI_24BPP,
+ .ifc = 1,
+ .link = 2,
+#ifdef AV8100_HW_TE_I2SDAT3
+ .sync_src = MCDE_SYNCSRC_TE1,
+#else
+ .sync_src = MCDE_SYNCSRC_TE0,
+#endif /* AV8100_HW_TE_I2SDAT3 */
+ .update_auto_trig = true,
+ .phy = {
+ .dsi = {
+ .virt_id = 0,
+ .num_data_lanes = 2,
+ .ui = DSI_UNIT_INTERVAL_2,
+ },
+ },
+};
+
+struct mcde_display_hdmi_platform_data av8100_hdmi_pdata = {
+ .reset_gpio = 0,
+ .reset_delay = 1,
+ .regulator_id = NULL, /* TODO: "display_main" */
+ .ddb_id = 1,
+ .rgb_2_yCbCr_convert = {
+ .matrix = {
+ {0x42, 0x81, 0x19},
+ {0xffda, 0xffb6, 0x70},
+ {0x70, 0xffa2, 0xffee},
+ },
+ .offset = {0x80, 0x10, 0x80},
+ }
+};
+
+static int av8100_platform_enable(struct mcde_display_device *dev)
+{
+ int ret = 0;
+ struct mcde_display_hdmi_platform_data *pdata =
+ dev->dev.platform_data;
+
+ ret = stm_gpio_altfuncenable(GPIO_ALT_LCD_PANELA);
+ if (ret != 0)
+ goto alt_func_failed;
+
+ if (pdata->reset_gpio)
+ gpio_set_value(pdata->reset_gpio, pdata->reset_high);
+ if (pdata->regulator)
+ ret = regulator_enable(pdata->regulator);
+alt_func_failed:
+ return ret;
+}
+
+static int av8100_platform_disable(struct mcde_display_device *dev)
+{
+ int ret = 0;
+ struct mcde_display_hdmi_platform_data *pdata =
+ dev->dev.platform_data;
+
+ ret = stm_gpio_altfuncdisable(GPIO_ALT_LCD_PANELA);
+ if (ret != 0)
+ goto alt_func_failed;
+ if (pdata->reset_gpio)
+ gpio_set_value(pdata->reset_gpio, !pdata->reset_high);
+ if (pdata->regulator)
+ ret = regulator_disable(pdata->regulator);
+alt_func_failed:
+ return ret;
+}
+
+static struct mcde_display_device av8100_hdmi = {
+ .name = "av8100_hdmi",
+ .id = 2,
+ .port = &port2,
+ .chnl_id = MCDE_CHNL_B,
+ .fifo = MCDE_FIFO_B,
+ .default_pixel_format = MCDE_OVLYPIXFMT_RGB565,
+#ifdef CONFIG_AV8100_SDTV
+ .native_x_res = 720,
+ .native_y_res = 576,
+#else
+ .native_x_res = 1280,
+ .native_y_res = 720,
+#endif
+ .synchronized_update = true,
+ .dev = {
+ .platform_data = &av8100_hdmi_pdata,
+ },
+ .platform_enable = av8100_platform_enable,
+ .platform_disable = av8100_platform_disable,
+};
+#endif /* CONFIG_DISPLAY_AV8100_TERTIARY */
+
+static struct fb_info *fbs[3] = { NULL, NULL, NULL };
+static struct mcde_display_device *displays[3] = { NULL, NULL, NULL };
+
+static int display_registered_callback(struct notifier_block *nb,
+ unsigned long event, void *dev)
+{
+ struct mcde_display_device *ddev = dev;
+ u16 width, height;
+ bool rotate;
+ bool display_initialized;
+
+ if (event != MCDE_DSS_EVENT_DISPLAY_REGISTERED)
+ return 0;
+
+ if (ddev->id < 0 || ddev->id >= ARRAY_SIZE(fbs))
+ return 0;
+
+ mcde_dss_get_native_resolution(ddev, &width, &height);
+
+ display_initialized = (ddev->id == 0 && display_initialize_during_boot);
+ rotate = (ddev->id == 0 && rotate_main);
+ if (rotate) {
+ u16 tmp = height;
+ height = width;
+ width = tmp;
+ }
+
+ /* Create frame buffer */
+ fbs[ddev->id] = mcde_fb_create(ddev,
+ width, height,
+ width, height * 2,
+ ddev->default_pixel_format,
+ rotate ? FB_ROTATE_CW : FB_ROTATE_UR,
+ display_initialized);
+ if (IS_ERR(fbs[ddev->id]))
+ pr_warning("Failed to create fb for display %s\n", ddev->name);
+ else
+ pr_info("Framebuffer created (%s)\n", ddev->name);
+
+ return 0;
+}
+
+static struct notifier_block display_nb = {
+ .notifier_call = display_registered_callback,
+};
+
+int __init init_display_devices(void)
+{
+ int ret;
+
+ ret = mcde_dss_register_notifier(&display_nb);
+ if (ret)
+ pr_warning("Failed to register dss notifier\n");
+
+#ifdef CONFIG_DISPLAY_GENERIC_DSI_PRIMARY
+ ret = mcde_display_device_register(&generic_display0);
+ if (ret)
+ pr_warning("Failed to register generic display device 0\n");
+ displays[0] = &generic_display0;
+#endif
+
+#ifdef CONFIG_DISPLAY_GENERIC_DSI_SECONDARY
+ ret = mcde_display_device_register(&generic_subdisplay);
+ if (ret)
+ pr_warning("Failed to register generic sub display device\n");
+ displays[1] = &generic_subdisplay;
+#endif
+
+#ifdef CONFIG_DISPLAY_AV8100_TERTIARY
+ ret = mcde_display_device_register(&av8100_hdmi);
+ if (ret)
+ pr_warning("Failed to register av8100_hdmi\n");
+ displays[2] = &av8100_hdmi;
+#endif
+#ifdef CONFIG_DISPLAY_AB8500_TERTIARY
+ ret = platform_device_register(&ab8500_denc);
+ if (ret)
+ pr_warning("Failed to register ab8500_denc device\n");
+ else {
+ ret = mcde_display_device_register(&tvout_ab8500_display);
+ if (ret)
+ pr_warning("Failed to register ab8500 tvout device\n");
+ displays[2] = &tvout_ab8500_display;
+ }
+#endif
+
+ return ret;
+}
+
+module_init(init_display_devices);
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index b4dace33e87..782a9801aa2 100755
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -40,30 +40,16 @@
#include <mach/setup.h>
#include <mach/i2c.h>
#include <mach/tc35893-keypad.h>
-
-#include <video/mcde_display.h>
-#include <video/mcde_display-generic_dsi.h>
-#include <video/mcde_display-av8100.h>
-#include <video/mcde_display-ab8500.h>
-#include <video/mcde_fb.h>
-#include <video/mcde_dss.h>
#include <video/av8100.h>
-#include <mach/ab8500_denc.h>
#define IRQ_KP 1 /*To DO*/
int href_v1_board;
-extern int platform_id;
#define MOP500_PLATFORM_ID 0
#define HREF_PLATFORM_ID 1
-#define AV8100_CUT_1_0
-
-/*
- * This is only non-static because MCDE accesses it directly. Make this static
- * once MCDE is fixed to not depend on these variables.
- */
+/*#define AV8100_HW_TE_I2SDAT3*/ /* REVIEW/TODO: remove? */
int platform_id = MOP500_PLATFORM_ID;
/* we have equally similar boards with very minimal
@@ -123,14 +109,20 @@ static struct gpio_altfun_data gpio_altfun_table[] = {
__GPIO_ALT(GPIO_ALT_SDIO, 208, 214, 0, NMK_GPIO_ALT_A, "sdio"),
__GPIO_ALT(GPIO_ALT_TRACE, 70, 74, 0, NMK_GPIO_ALT_C, "stm"),
__GPIO_ALT(GPIO_ALT_SDMMC2, 128, 138, 0, NMK_GPIO_ALT_A, "mmc2"),
- __GPIO_ALT(GPIO_ALT_LCD_PANELB, 78, 81, 1, NMK_GPIO_ALT_A, "mcde tvout"),
- __GPIO_ALT(GPIO_ALT_LCD_PANELB, 150, 150, 0, NMK_GPIO_ALT_B, "mcde tvout"),
- __GPIO_ALT(GPIO_ALT_LCD_PANELA, 68, 68, 0, NMK_GPIO_ALT_A, "mcde tvout"),
- __GPIO_ALT(GPIO_ALT_MMIO_INIT_BOARD, 141, 142, 0, NMK_GPIO_ALT_B, "mmio"),
+ __GPIO_ALT(GPIO_ALT_LCD_PANELB, 78, 81, 1, NMK_GPIO_ALT_A,
+ "mcde tvout"),
+ __GPIO_ALT(GPIO_ALT_LCD_PANELB, 150, 150, 0, NMK_GPIO_ALT_B,
+ "mcde tvout"),
+ __GPIO_ALT(GPIO_ALT_LCD_PANELA, 68, 68, 0, NMK_GPIO_ALT_A,
+ "mcde tvout"),
+ __GPIO_ALT(GPIO_ALT_MMIO_INIT_BOARD, 141, 142, 0, NMK_GPIO_ALT_B,
+ "mmio"),
__GPIO_ALT(GPIO_ALT_MMIO_CAM_SET_I2C, 8, 9, 0, NMK_GPIO_ALT_A, "mmio"),
- __GPIO_ALT(GPIO_ALT_MMIO_CAM_SET_EXT_CLK, 227, 228, 0, NMK_GPIO_ALT_A, "mmio"),
+ __GPIO_ALT(GPIO_ALT_MMIO_CAM_SET_EXT_CLK, 227, 228, 0, NMK_GPIO_ALT_A,
+ "mmio"),
#ifndef CONFIG_U8500_TSC_EXT_CLK_SHARE
- __GPIO_ALT(GPIO_ALT_TP_SET_EXT_CLK, 228, 228, 0, NMK_GPIO_ALT_A, "u8500_tp"),
+ __GPIO_ALT(GPIO_ALT_TP_SET_EXT_CLK, 228, 228, 0, NMK_GPIO_ALT_A,
+ "u8500_tp"),
#endif
};
@@ -497,10 +489,12 @@ static int bu21013_gpio_board_init(int reset_pin)
if (!config_set) {
retval = stm_gpio_altfuncenable(GPIO_ALT_TP_SET_EXT_CLK);
if (retval < 0) {
- printk(KERN_ERR "%s: gpio alternate failed\n", __func__);
+ printk(KERN_ERR "%s: gpio alternate failed\n",
+ __func__);
return retval;
}
- clk_base = (void __iomem *)IO_ADDRESS(U8500_PRCMU_BASE + PRCMU_CLOCK_OCR);
+ clk_base = (void __iomem *)IO_ADDRESS(U8500_PRCMU_BASE +
+ PRCMU_CLOCK_OCR);
clk_value = readl(clk_base);
writel(TSC_EXT_CLOCK_9_6MHZ, clk_base);
}
@@ -520,7 +514,8 @@ static int bu21013_gpio_board_init(int reset_pin)
}
retval = gpio_direction_output(reset_pin, 1);
if (retval < 0) {
- printk(KERN_ERR "%s: gpio direction failed\n", __func__);
+ printk(KERN_ERR "%s: gpio direction failed\n",
+ __func__);
return retval;
}
gpio_set_value(reset_pin, 1);
@@ -546,7 +541,8 @@ static int bu21013_gpio_board_exit(int reset_pin)
if (!config_disable_set) {
retval = gpio_direction_output(reset_pin, 0);
if (retval < 0) {
- printk(KERN_ERR "%s: gpio direction failed\n", __func__);
+ printk(KERN_ERR "%s: gpio direction failed\n",
+ __func__);
return retval;
}
gpio_set_value(reset_pin, 0);
@@ -576,11 +572,14 @@ static int bu21013_init_irq(void (*callback)(void *parameter), void *data)
retval = tc35892_set_callback(EGPIO_PIN_12, callback,
(void *)data);
if (retval < 0)
- printk(KERN_ERR "%s: set callback failed\n", __func__);
+ printk(KERN_ERR "%s: set callback failed\n",
+ __func__);
retval = tc35892_set_gpio_intr_conf(EGPIO_PIN_12,
- EDGE_SENSITIVE, TC35892_FALLING_EDGE_OR_LOWLEVEL);
+ EDGE_SENSITIVE,
+ TC35892_FALLING_EDGE_OR_LOWLEVEL);
if (retval < 0)
- printk(KERN_ERR "%s: config failed\n", __func__);
+ printk(KERN_ERR "%s: config failed\n",
+ __func__);
}
}
return retval;
@@ -597,12 +596,14 @@ static int bu21013_exit_irq(void)
if (platform_id == MOP500_PLATFORM_ID) {
retval = stmpe2401_remove_callback(EGPIO_PIN_3);
if (retval < 0)
- printk(KERN_ERR "%s: remove callback failed\n", __func__);
+ pr_err("%s: remove callback failed\n",
+ __func__);
} else if (platform_id == HREF_PLATFORM_ID) {
if (!href_v1_board) {
retval = tc35892_remove_callback(EGPIO_PIN_12);
if (retval < 0)
- printk(KERN_ERR "%s: remove calllback failed\n", __func__);
+ pr_err("%s: remove calllback failed\n",
+ __func__);
}
}
return retval;
@@ -1163,436 +1164,6 @@ struct platform_device sensors1p_device = {
};
#endif
-#ifdef CONFIG_FB_MCDE
-#define DSI_UNIT_INTERVAL_0 0xA
-#define DSI_UNIT_INTERVAL_1 0xA
-#define DSI_UNIT_INTERVAL_2 0x6
-
-static bool rotate_main = true;
-static bool display_initialize_during_boot;
-
-#ifdef CONFIG_DISPLAY_GENERIC_DSI_PRIMARY
-static struct mcde_port port0 = {
- .type = MCDE_PORTTYPE_DSI,
- .mode = MCDE_PORTMODE_CMD,
- .ifc = 1,
- .link = 0,
- .sync_src = MCDE_SYNCSRC_BTA,
- .update_auto_trig = false,
- .phy = {
- .dsi = {
- .virt_id = 0,
- .num_data_lanes = 2,
- .ui = DSI_UNIT_INTERVAL_0,
- },
- },
-};
-
-struct mcde_display_generic_platform_data generic_display0_pdata = {
- .reset_gpio = EGPIO_PIN_15,
- .reset_delay = 1,
-#ifdef CONFIG_REGULATOR
- .regulator_id = "v-display",
- .min_supply_voltage = 2500000, /* 2.5V */
- .max_supply_voltage = 2700000 /* 2.7V */
-#endif
-};
-
-struct mcde_display_device generic_display0 = {
- .name = "mcde_disp_generic",
- .id = 0,
- .port = &port0,
- .chnl_id = MCDE_CHNL_A,
- .fifo = MCDE_FIFO_C0,
- .default_pixel_format = MCDE_OVLYPIXFMT_RGB565,
- .port_pixel_format = MCDE_PORTPIXFMT_DSI_24BPP,
- .native_x_res = 864,
- .native_y_res = 480,
- .synchronized_update = false,
- /* TODO: Remove rotation buffers once ESRAM driver is completed */
- .rotbuf1 = U8500_ESRAM_BASE + 0x20000 * 4,
- .rotbuf2 = U8500_ESRAM_BASE + 0x20000 * 4 + 0x10000,
- .dev = {
- .platform_data = &generic_display0_pdata,
- },
-};
-#endif /* CONFIG_DISPLAY_GENERIC_DSI_PRIMARY */
-
-#ifdef CONFIG_DISPLAY_GENERIC_DSI_SECONDARY
-static struct mcde_port subdisplay_port = {
- .type = MCDE_PORTTYPE_DSI,
- .mode = MCDE_PORTMODE_CMD,
- .ifc = 1,
- .link = 1,
- .sync_src = MCDE_SYNCSRC_BTA,
- .update_auto_trig = false,
- .phy = {
- .dsi = {
- .virt_id = 0,
- .num_data_lanes = 2,
- .ui = DSI_UNIT_INTERVAL_1,
- },
- },
-};
-
-static struct mcde_display_generic_platform_data generic_subdisplay_pdata = {
- .reset_gpio = EGPIO_PIN_14,
- .reset_delay = 1,
-#ifdef CONFIG_REGULATOR
- .regulator_id = "v-display",
- .min_supply_voltage = 2500000, /* 2.5V */
- .max_supply_voltage = 2700000 /* 2.7V */
-#endif
-};
-
-static struct mcde_display_device generic_subdisplay = {
- .name = "mcde_disp_generic_subdisplay",
- .id = 1,
- .port = &subdisplay_port,
- .chnl_id = MCDE_CHNL_C1,
- .fifo = MCDE_FIFO_C1,
- .default_pixel_format = MCDE_OVLYPIXFMT_RGB565,
- .port_pixel_format = MCDE_PORTPIXFMT_DSI_24BPP,
- .native_x_res = 864,
- .native_y_res = 480,
- .synchronized_update = false,
- .dev = {
- .platform_data = &generic_subdisplay_pdata,
- },
-};
-#endif /* CONFIG_DISPLAY_GENERIC_DSI_SECONDARY */
-
-
-#ifdef CONFIG_DISPLAY_AB8500_TERTIARY
-static struct mcde_port port_tvout1 = {
- .type = MCDE_PORTTYPE_DPI,
- .ifc = 0,
- .link = 1,
- .sync_src = MCDE_SYNCSRC_OFF,
- .update_auto_trig = true,
- .phy = {
- .dpi = {
- .num_data_lanes = 4, /* DDR mode */
- },
- },
-};
-
-static struct ab8500_display_platform_data ab8500_display_pdata = {
- /* TODO use this ID as soon as we switch to newer kernel with support or
- * ab8500 TVout regulator
- .regulator_id = "v-tvout",
- */
-};
-
-static int ab8500_platform_enable(struct mcde_display_device *ddev)
-{
- int res = 0;
- /* probe checks for pdata */
- struct ab8500_display_platform_data *pdata = ddev->dev.platform_data;
-
- pr_info("%s\n", __func__);
- res = stm_gpio_altfuncenable(GPIO_ALT_LCD_PANELB);
- if (res != 0)
- goto alt_func_failed;
-
- if (pdata->regulator) {
- res = regulator_enable(pdata->regulator);
- if (res != 0)
- goto regu_failed;
- }
-
-out:
- return res;
-
-regu_failed:
- (void) stm_gpio_altfuncdisable(GPIO_ALT_LCD_PANELB);
-alt_func_failed:
- dev_warn(&ddev->dev, "Failure during %s\n", __func__);
- goto out;
-}
-
-static int ab8500_platform_disable(struct mcde_display_device *ddev)
-{
- int res;
- /* probe checks for pdata */
- struct ab8500_display_platform_data *pdata = ddev->dev.platform_data;
-
- dev_info(&ddev->dev, "%s\n", __func__);
-
- res = stm_gpio_altfuncdisable(GPIO_ALT_LCD_PANELB);
- if (res != 0)
- goto alt_func_failed;
-
- if (pdata->regulator) {
- res = regulator_disable(pdata->regulator);
- if (res != 0)
- goto regu_failed;
- }
-
-out:
- return res;
-regu_failed:
- (void) stm_gpio_altfuncenable(GPIO_ALT_LCD_PANELB);
-alt_func_failed:
- dev_warn(&ddev->dev, "Failure during %s\n", __func__);
- goto out;
-
-}
-
-static struct mcde_display_device tvout_ab8500_display = {
- .name = "mcde_tv_ab8500",
- .id = 2,
- .port = &port_tvout1,
- .chnl_id = MCDE_CHNL_B,
- .fifo = MCDE_FIFO_B,
- .default_pixel_format = MCDE_OVLYPIXFMT_RGB565,
- .port_pixel_format = MCDE_PORTPIXFMT_DPI_24BPP,
- .native_x_res = 720,
- .native_y_res = 576,
- .synchronized_update = true,
- .video_mode = {
- .xres = 720,
- .yres = 576,
- },
- .dev = {
- .platform_data = &ab8500_display_pdata,
- },
-
- /* We might need to describe the std here:
- * - there are different PAL / NTSC formats (do they require MCDE
- * settings?)
- */
- .platform_enable = ab8500_platform_enable,
- .platform_disable = ab8500_platform_disable,
-};
-
-static struct ab8500_denc_platform_data ab8500_denc_pdata = {
- .ddr_enable = true,
- .ddr_little_endian = false,
-};
-
-static struct platform_device ab8500_denc = {
- .name = "ab8500_denc",
- .id = -1,
- .dev = {
- .platform_data = &ab8500_denc_pdata,
- },
-};
-#endif /* CONFIG_DISPLAY_AB8500_TERTIARY */
-
-#ifdef CONFIG_DISPLAY_AV8100_TERTIARY
-static struct mcde_port port2 = {
- .type = MCDE_PORTTYPE_DSI,
- .mode = MCDE_PORTMODE_CMD,
- .ifc = 1,
- .link = 2,
- .sync_src = MCDE_SYNCSRC_TE0,
- .update_auto_trig = true,
- .phy = {
- .dsi = {
- .virt_id = 0,
- .num_data_lanes = 2,
- .ui = DSI_UNIT_INTERVAL_2,
- },
- },
-};
-
-struct mcde_display_generic_platform_data av8100_hdmi_pdata = {
- .reset_gpio = 0,
- .reset_delay = 1,
- .regulator_id = NULL, /* TODO: "display_main" */
- .ddb_id = 1,
-};
-
-static int av8100_platform_enable(struct mcde_display_device *dev)
-{
-#define GPIO1B_AFSLA_REG_OFFSET 0x20
-#define GPIO1B_AFSLB_REG_OFFSET 0x24
-
- int ret = 0;
- struct mcde_display_hdmi_platform_data *pdata =
- dev->dev.platform_data;
-
-#ifdef AV8100_CUT_1_0
- volatile u32 __iomem *gpio_68_remap;
-#endif
-#ifdef AV8100_CUT_2_1
- volatile u32 __iomem *gpio_69_remap;
-#endif
-
- /* HW trig begin */
-#ifdef AV8100_CUT_1_0
- gpio_68_remap = (u32 *) ioremap(
- U8500_GPIO1_BASE + GPIO1B_AFSLB_REG_OFFSET,
- (U8500_GPIO1_BASE + GPIO1B_AFSLB_REG_OFFSET + 3) -
- (U8500_GPIO1_BASE + GPIO1B_AFSLB_REG_OFFSET) + 1);
-
- *gpio_68_remap &= 0xffffffef;
- iounmap(gpio_68_remap);
-
- gpio_68_remap = (u32 *) ioremap(
- U8500_GPIO1_BASE + GPIO1B_AFSLA_REG_OFFSET,
- (U8500_GPIO1_BASE + GPIO1B_AFSLA_REG_OFFSET + 3) -
- (U8500_GPIO1_BASE + GPIO1B_AFSLA_REG_OFFSET) + 1);
- *gpio_68_remap |= 0x10;
- iounmap(gpio_68_remap);
-#endif
-
-#ifdef AV8100_CUT_2_1
- gpio_69_remap = (u32 *) ioremap(
- U8500_GPIO1_BASE + GPIO1B_AFSLB_REG_OFFSET,
- (U8500_GPIO1_BASE + GPIO1B_AFSLB_REG_OFFSET + 3) -
- (U8500_GPIO1_BASE + GPIO1B_AFSLB_REG_OFFSET) + 1);
-
- *gpio_69_remap &= 0xffffffdf;
- iounmap(gpio_69_remap);
-
- gpio_69_remap = (u32 *) ioremap(
- U8500_GPIO1_BASE + GPIO1B_AFSLA_REG_OFFSET,
- (U8500_GPIO1_BASE + GPIO1B_AFSLA_REG_OFFSET + 3) -
- (U8500_GPIO1_BASE + GPIO1B_AFSLA_REG_OFFSET) + 1);
- *gpio_69_remap |= 0x20;
- iounmap(gpio_69_remap);
-#endif
- /* HW trig end */
-
- if (pdata->reset_gpio)
- gpio_set_value(pdata->reset_gpio, pdata->reset_high);
- if (pdata->regulator)
- ret = regulator_enable(pdata->regulator);
- return ret;
-}
-
-static int av8100_platform_disable(struct mcde_display_device *dev)
-{
- int ret = 0;
- struct mcde_display_hdmi_platform_data *pdata =
- dev->dev.platform_data;
-
- if (pdata->reset_gpio)
- gpio_set_value(pdata->reset_gpio, !pdata->reset_high);
- if (pdata->regulator)
- ret = regulator_disable(pdata->regulator);
-
- return ret;
-}
-
-static struct mcde_display_device av8100_hdmi = {
- .name = "av8100_hdmi",
- .id = 2,
- .port = &port2,
- .chnl_id = MCDE_CHNL_B,
- .fifo = MCDE_FIFO_B,
- .default_pixel_format = MCDE_OVLYPIXFMT_RGB565,
- .port_pixel_format = MCDE_PORTPIXFMT_DSI_24BPP,
-#ifdef CONFIG_AV8100_SDTV
- .native_x_res = 720,
- .native_y_res = 576,
-#else
- .native_x_res = 1280,
- .native_y_res = 720,
-#endif
- .synchronized_update = true,
- .dev = {
- .platform_data = &av8100_hdmi_pdata,
- },
- .platform_enable = av8100_platform_enable,
- .platform_disable = av8100_platform_disable,
-};
-#endif /* CONFIG_DISPLAY_AV8100_TERTIARY */
-
-static struct fb_info *fbs[3] = { NULL, NULL, NULL };
-static struct mcde_display_device *displays[3] = { NULL, NULL, NULL };
-
-static int display_registered_callback(struct notifier_block *nb,
- unsigned long event, void *dev)
-{
- struct mcde_display_device *ddev = dev;
- u16 width, height;
- bool rotate;
- bool display_initialized;
-
- if (event != MCDE_DSS_EVENT_DISPLAY_REGISTERED)
- return 0;
-
- if (ddev->id < 0 || ddev->id >= ARRAY_SIZE(fbs))
- return 0;
-
- mcde_dss_get_native_resolution(ddev, &width, &height);
-
- display_initialized = (ddev->id == 0 && display_initialize_during_boot);
- rotate = (ddev->id == 0 && rotate_main);
- if (rotate) {
- u16 tmp = height;
- height = width;
- width = tmp;
- }
-
- /* Create frame buffer */
- fbs[ddev->id] = mcde_fb_create(ddev,
- width, height,
- width, height * 2,
- ddev->default_pixel_format,
- rotate ? FB_ROTATE_CW : FB_ROTATE_UR,
- display_initialized);
- if (IS_ERR(fbs[ddev->id]))
- pr_warning("Failed to create fb for display %s\n", ddev->name);
- else
- pr_info("Framebuffer created (%s)\n", ddev->name);
-
- return 0;
-}
-
-static struct notifier_block display_nb = {
- .notifier_call = display_registered_callback,
-};
-
-int __init init_display_devices(void)
-{
- int ret;
-
- ret = mcde_dss_register_notifier(&display_nb);
- if (ret)
- pr_warning("Failed to register dss notifier\n");
-
-#ifdef CONFIG_DISPLAY_GENERIC_DSI_PRIMARY
- ret = mcde_display_device_register(&generic_display0);
- if (ret)
- pr_warning("Failed to register generic display device 0\n");
- displays[0] = &generic_display0;
-#endif
-
-#ifdef CONFIG_DISPLAY_GENERIC_DSI_SECONDARY
- ret = mcde_display_device_register(&generic_subdisplay);
- if (ret)
- pr_warning("Failed to register generic sub display device\n");
- displays[1] = &generic_subdisplay;
-#endif
-
-#ifdef CONFIG_DISPLAY_AV8100_TERTIARY
- ret = mcde_display_device_register(&av8100_hdmi);
- if (ret)
- pr_warning("Failed to register av8100_hdmi\n");
- displays[2] = &av8100_hdmi;
-#endif
-#ifdef CONFIG_DISPLAY_AB8500_TERTIARY
- ret = platform_device_register(&ab8500_denc);
- if (ret)
- pr_warning("Failed to register ab8500_denc device\n");
- else {
- ret = mcde_display_device_register(&tvout_ab8500_display);
- if (ret)
- pr_warning("Failed to register ab8500 tvout device\n");
- displays[2] = &tvout_ab8500_display;
- }
-#endif
-
- return ret;
-}
-
-module_init(init_display_devices);
-#endif /* CONFIG_FB_MCDE */
-
static struct i2s_board_info stm_i2s_board_info[] __initdata = {
{
.modalias = "i2s_device.0",
diff --git a/arch/arm/mach-ux500/include/mach/prcmu-fw-api.h b/arch/arm/mach-ux500/include/mach/prcmu-fw-api.h
index 3be7c5cfa33..e9491d1378c 100755
--- a/arch/arm/mach-ux500/include/mach/prcmu-fw-api.h
+++ b/arch/arm/mach-ux500/include/mach/prcmu-fw-api.h
@@ -118,5 +118,6 @@ void prcmu_set_callback_modem_reset_request(void (*func)(void));
void prcmu_system_reset(void);
int prcmu_is_ca_wake_req_pending(void);
int prcmu_read_ack_mb7(void);
+int prcmu_enable_mcde(void);
#endif /* __MACH_PRCMU_FW_API_V1_H */
diff --git a/arch/arm/mach-ux500/include/mach/prcmu-regs.h b/arch/arm/mach-ux500/include/mach/prcmu-regs.h
index b852663a270..0972342dfb5 100755
--- a/arch/arm/mach-ux500/include/mach/prcmu-regs.h
+++ b/arch/arm/mach-ux500/include/mach/prcmu-regs.h
@@ -67,4 +67,30 @@
/* System reset register */
#define PRCM_APE_SOFTRST (_PRCMU_BASE + 0x228)
+/* Level shifter and clamp control registers */
+#define PRCM_MMIP_LS_CLAMP_SET (_PRCMU_BASE + 0x420)
+#define PRCM_MMIP_LS_CLAMP_CLR (_PRCMU_BASE + 0x424)
+
+/* PRCMU clock/PLL/reset registers */
+#define PRCM_PLLDSI_FREQ (_PRCMU_BASE + 0x500)
+#define PRCM_PLLDSI_ENABLE (_PRCMU_BASE + 0x504)
+#define PRCM_LCDCLK_MGT (_PRCMU_BASE + 0x044)
+#define PRCM_MCDECLK_MGT (_PRCMU_BASE + 0x064)
+#define PRCM_HDMICLK_MGT (_PRCMU_BASE + 0x058)
+#define PRCM_TVCLK_MGT (_PRCMU_BASE + 0x07c)
+#define PRCM_DSI_PLLOUT_SEL (_PRCMU_BASE + 0x530)
+#define PRCM_DSITVCLK_DIV (_PRCMU_BASE + 0x52C)
+#define PRCM_APE_RESETN_SET (_PRCMU_BASE + 0x1E4)
+#define PRCM_APE_RESETN_CLR (_PRCMU_BASE + 0x1E8)
+
+/* ePOD and memory power signal control registers */
+#define PRCM_EPOD_C_SET (_PRCMU_BASE + 0x410)
+#define PRCM_SRAM_LS_SLEEP (_PRCMU_BASE + 0x304)
+
+/* Debug power control unit registers */
+#define PRCM_POWER_STATE_SET (_PRCMU_BASE + 0x254)
+
+/* Miscellaneous unit registers */
+#define PRCM_DSI_SW_RESET (_PRCMU_BASE + 0x324)
+
#endif /* __MACH_PRCMU__REGS_H */
diff --git a/arch/arm/mach-ux500/prcmu-fw.c b/arch/arm/mach-ux500/prcmu-fw.c
index 8772a145406..8c98f2fa587 100755
--- a/arch/arm/mach-ux500/prcmu-fw.c
+++ b/arch/arm/mach-ux500/prcmu-fw.c
@@ -80,6 +80,91 @@ static void (*prcmu_modem_reset_shrm)(void);
static int prcmu_set_hwacc_st(enum hw_acc_t hw_acc, enum hw_accst_t hw_accst);
+
+/*
+* Used by MCDE to setup all necessary PRCMU registers
+*/
+#define PRCMU_CLAMP_DSS_DSIPLL 0x00600C00
+#define PRCMU_RESET_DSS 0x0000000C
+#define PRCMU_ENABLE_DSS_MEM 0x00200000
+#define PRCMU_ENABLE_DSS_LOGIC 0x00100000
+#define PRCMU_DSS_SLEEP_OUTPUT_MASK 0x400
+#define PRCMU_UNCLAMP_DSS_DSIPLL 0x00600C00
+#define PRCMU_POWER_ON_DSI 0x00008000
+
+#define PRCMU_DSI_CLOCK_SETTING 0x00000145
+#define PRCMU_DSI_LP_CLOCK_SETTING 0x00000141
+#define PRCMU_PLLDSI_FREQ_SETTING 0x0004012B
+
+#define PRCMU_ENABLE_PLLDSI 0x00000001
+#define PRCMU_RELEASE_RESET_DSS 0x0000400C
+#define PRCMU_DSI_PLLOUT_SEL_SETTING 0x00000202
+#define PRCMU_ENABLE_ESCAPE_CLOCK 0x07031717
+#define PRCMU_DSI_RESET_SW 0x00000007
+
+#define PRCMU_MCDE_DELAY 10
+
+int prcmu_enable_mcde(void)
+{
+#ifndef CONFIG_REGULATOR /* Only for V10 */
+ u32 temp;
+#endif
+ /* Clamp DSS out, DSIPLL in/out, (why not DSS input?) */
+ writel(PRCMU_CLAMP_DSS_DSIPLL, PRCM_MMIP_LS_CLAMP_SET);
+ mdelay(PRCMU_MCDE_DELAY);
+ /* Enable DSS_M_INITN, DSS_L_RESETN, DSIPLL_RESETN resets */
+ writel(PRCMU_RESET_DSS, PRCM_APE_RESETN_CLR);
+ mdelay(PRCMU_MCDE_DELAY);
+#ifndef CONFIG_REGULATOR /* Only for V10 */
+ /* Power on DSS mem */
+ writel(PRCMU_ENABLE_DSS_MEM, PRCM_EPOD_C_SET);
+ mdelay(PRCMU_MCDE_DELAY);
+ /* Power on DSS logic */
+ writel(PRCMU_ENABLE_DSS_LOGIC, PRCM_EPOD_C_SET);
+ mdelay(PRCMU_MCDE_DELAY);
+ /* Release DSS_SLEEP */
+ temp = readl(PRCM_SRAM_LS_SLEEP);
+ writel(temp & ~PRCMU_DSS_SLEEP_OUTPUT_MASK, PRCM_SRAM_LS_SLEEP);
+ mdelay(PRCMU_MCDE_DELAY);
+#endif
+ /* Unclamp DSS out, DSIPLL in/out, (why not DSS input?) */
+ writel(PRCMU_UNCLAMP_DSS_DSIPLL, PRCM_MMIP_LS_CLAMP_CLR);
+ mdelay(PRCMU_MCDE_DELAY);
+#ifndef CONFIG_REGULATOR /* Only for V10 */
+ /* Power on CSI_DSI */
+ writel(PRCMU_POWER_ON_DSI, PRCM_POWER_STATE_SET);
+ mdelay(PRCMU_MCDE_DELAY);
+#endif
+ /* HDMI and TVCLK Should be handled somewhere else */
+ /* PLLDIV=5, PLLSW=2, CLKEN=1 */
+ writel(PRCMU_DSI_CLOCK_SETTING, PRCM_HDMICLK_MGT);
+ mdelay(PRCMU_MCDE_DELAY);
+ /* PLLDIV=14, PLLSW=2, CLKEN=1 */
+ writel(PRCMU_DSI_LP_CLOCK_SETTING, PRCM_TVCLK_MGT);
+ mdelay(PRCMU_MCDE_DELAY);
+
+ /* D=43, N=1, R=4, SELDIV2=0 */
+ writel(PRCMU_PLLDSI_FREQ_SETTING, PRCM_PLLDSI_FREQ);
+ mdelay(PRCMU_MCDE_DELAY);
+ /* Start DSI PLL */
+ writel(PRCMU_ENABLE_PLLDSI, PRCM_PLLDSI_ENABLE);
+ mdelay(PRCMU_MCDE_DELAY);
+ /* Release DSS_M_INITN, DSS_L_RESETN, DSIPLL_RESETN */
+ writel(PRCMU_RELEASE_RESET_DSS, PRCM_APE_RESETN_SET);
+ mdelay(PRCMU_MCDE_DELAY);
+ /* DSI0=phi/2, DSI1=phi/2 */
+ writel(PRCMU_DSI_PLLOUT_SEL_SETTING, PRCM_DSI_PLLOUT_SEL);
+ mdelay(PRCMU_MCDE_DELAY);
+ /* Enable ESC clk 0/1/2, div2=3, div1=0x17, div0=0x17 */
+ writel(PRCMU_ENABLE_ESCAPE_CLOCK, PRCM_DSITVCLK_DIV);
+ mdelay(PRCMU_MCDE_DELAY);
+ /* Release DSI reset 0/1/2 */
+ writel(PRCMU_DSI_RESET_SW, PRCM_DSI_SW_RESET);
+ mdelay(PRCMU_MCDE_DELAY);
+ return 0;
+}
+
+
/* Internal functions */
/**