summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorYe.Li <B37916@freescale.com>2014-06-10 13:42:48 +0800
committerYe.Li <B37916@freescale.com>2014-06-17 11:13:48 +0800
commita07cc4604e692d8149fe4c74071839558e19c757 (patch)
treeec950e74e7419db6d773b1a9bc743e917bb94ff8 /board
parent5bf3ee7227a9d1685c3234af91cd9dd2569fcd6f (diff)
downloadu-boot-imx-a07cc4604e692d8149fe4c74071839558e19c757.zip
u-boot-imx-a07cc4604e692d8149fe4c74071839558e19c757.tar.gz
u-boot-imx-a07cc4604e692d8149fe4c74071839558e19c757.tar.bz2
ENGR00315894-38 MX6 Sabreauto:Add IPUv3 splash screen support
This patch adds IPUv3 splash screen support for the MX6Q/SDL Sabreauto platforms. The default display is the Hannstar-XGA LVDS panel. Users may set the uboot variable 'panel' to be 'HDMI' to switch to use HDMI splash screen. To avoid duplicate configures on different sabre platforms, this patch moves the IPUv3 splash screen relevant configures to the head file 'mx6qsabre_common.h'. Also, this patch modifies the condition to build in EPDC splash screen feature in order to avoid the build break due to the migration of the IPUv3 splash screen relevant configures. Signed-off-by: Liu Ying <Ying.Liu@freescale.com> Signed-off-by: Ye.Li <B37916@freescale.com>
Diffstat (limited to 'board')
-rw-r--r--board/freescale/mx6qsabreauto/mx6qsabreauto.c201
1 files changed, 201 insertions, 0 deletions
diff --git a/board/freescale/mx6qsabreauto/mx6qsabreauto.c b/board/freescale/mx6qsabreauto/mx6qsabreauto.c
index 0c592fe..0fd9e77 100644
--- a/board/freescale/mx6qsabreauto/mx6qsabreauto.c
+++ b/board/freescale/mx6qsabreauto/mx6qsabreauto.c
@@ -23,6 +23,10 @@
#include <miiphy.h>
#include <netdev.h>
#include <asm/arch/sys_proto.h>
+#include <asm/arch/mxc_hdmi.h>
+#include <linux/fb.h>
+#include <ipu_pixfmt.h>
+
#include <i2c.h>
#ifdef CONFIG_CMD_SATA
@@ -553,6 +557,199 @@ int board_phy_config(struct phy_device *phydev)
return 0;
}
+#if defined(CONFIG_VIDEO_IPUV3)
+struct display_info_t {
+ int bus;
+ int addr;
+ int pixfmt;
+ int (*detect)(struct display_info_t const *dev);
+ void (*enable)(struct display_info_t const *dev);
+ struct fb_videomode mode;
+};
+
+static void disable_lvds(struct display_info_t const *dev)
+{
+ struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
+
+ int reg = readl(&iomux->gpr[2]);
+
+ reg &= ~(IOMUXC_GPR2_LVDS_CH0_MODE_MASK |
+ IOMUXC_GPR2_LVDS_CH1_MODE_MASK);
+
+ writel(reg, &iomux->gpr[2]);
+}
+
+static void do_enable_hdmi(struct display_info_t const *dev)
+{
+ disable_lvds(dev);
+ imx_enable_hdmi_phy();
+}
+
+static struct display_info_t const displays[] = {{
+ .bus = -1,
+ .addr = 0,
+ .pixfmt = IPU_PIX_FMT_RGB666,
+ .detect = NULL,
+ .enable = NULL,
+ .mode = {
+ .name = "Hannstar-XGA",
+ .refresh = 60,
+ .xres = 1024,
+ .yres = 768,
+ .pixclock = 15385,
+ .left_margin = 220,
+ .right_margin = 40,
+ .upper_margin = 21,
+ .lower_margin = 7,
+ .hsync_len = 60,
+ .vsync_len = 10,
+ .sync = FB_SYNC_EXT,
+ .vmode = FB_VMODE_NONINTERLACED
+} }, {
+ .bus = -1,
+ .addr = 0,
+ .pixfmt = IPU_PIX_FMT_RGB24,
+ .detect = NULL,
+ .enable = do_enable_hdmi,
+ .mode = {
+ .name = "HDMI",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = 39721,
+ .left_margin = 48,
+ .right_margin = 16,
+ .upper_margin = 33,
+ .lower_margin = 10,
+ .hsync_len = 96,
+ .vsync_len = 2,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED
+} } };
+
+int board_video_skip(void)
+{
+ int i;
+ int ret;
+ char const *panel = getenv("panel");
+
+ if (!panel) {
+ for (i = 0; i < ARRAY_SIZE(displays); i++) {
+ struct display_info_t const *dev = displays+i;
+ if (dev->detect && dev->detect(dev)) {
+ panel = dev->mode.name;
+ printf("auto-detected panel %s\n", panel);
+ break;
+ }
+ }
+ if (!panel) {
+ panel = displays[0].mode.name;
+ printf("No panel detected: default to %s\n", panel);
+ i = 0;
+ }
+ } else {
+ for (i = 0; i < ARRAY_SIZE(displays); i++) {
+ if (!strcmp(panel, displays[i].mode.name))
+ break;
+ }
+ }
+
+ if (i < ARRAY_SIZE(displays)) {
+ ret = ipuv3_fb_init(&displays[i].mode, 0,
+ displays[i].pixfmt);
+ if (!ret) {
+ if (displays[i].enable)
+ displays[i].enable(displays+i);
+ printf("Display: %s (%ux%u)\n",
+ displays[i].mode.name,
+ displays[i].mode.xres,
+ displays[i].mode.yres);
+ } else
+ printf("LCD %s cannot be configured: %d\n",
+ displays[i].mode.name, ret);
+ } else {
+ printf("unsupported panel %s\n", panel);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+iomux_v3_cfg_t const backlight_pads[] = {
+ MX6_PAD_SD4_DAT1__GPIO2_IO09 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+};
+
+static void setup_iomux_backlight(void)
+{
+ gpio_direction_output(IMX_GPIO_NR(2, 9), 1);
+ imx_iomux_v3_setup_multiple_pads(backlight_pads,
+ ARRAY_SIZE(backlight_pads));
+}
+
+static void setup_display(void)
+{
+ struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+ struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
+ int reg;
+
+ setup_iomux_backlight();
+ enable_ipu_clock();
+ imx_setup_hdmi();
+
+ /* Turn on LDB_DI0 and LDB_DI1 clocks */
+ reg = readl(&mxc_ccm->CCGR3);
+ reg |= MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
+ writel(reg, &mxc_ccm->CCGR3);
+
+ /* Set LDB_DI0 and LDB_DI1 clk select to 3b'011 */
+ reg = readl(&mxc_ccm->cs2cdr);
+ reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK |
+ MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK);
+ reg |= (3 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET) |
+ (3 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET);
+ writel(reg, &mxc_ccm->cs2cdr);
+
+ reg = readl(&mxc_ccm->cscmr2);
+ reg |= MXC_CCM_CSCMR2_LDB_DI0_IPU_DIV | MXC_CCM_CSCMR2_LDB_DI1_IPU_DIV;
+ writel(reg, &mxc_ccm->cscmr2);
+
+ reg = readl(&mxc_ccm->chsccdr);
+ reg |= (CHSCCDR_CLK_SEL_LDB_DI0 <<
+ MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
+ reg |= (CHSCCDR_CLK_SEL_LDB_DI0 <<
+ MXC_CCM_CHSCCDR_IPU1_DI1_CLK_SEL_OFFSET);
+ writel(reg, &mxc_ccm->chsccdr);
+
+ reg = IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW |
+ IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW |
+ IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG |
+ IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT |
+ IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG |
+ IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT |
+ IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0 |
+ IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED;
+ writel(reg, &iomux->gpr[2]);
+
+ reg = readl(&iomux->gpr[3]);
+ reg &= ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK |
+ IOMUXC_GPR3_HDMI_MUX_CTL_MASK);
+ reg |= (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
+ IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET) |
+ (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
+ IOMUXC_GPR3_HDMI_MUX_CTL_OFFSET);
+ writel(reg, &iomux->gpr[3]);
+}
+#endif /* CONFIG_VIDEO_IPUV3 */
+
+/*
+ * Do not overwrite the console
+ * Use always serial for U-Boot console
+ */
+int overwrite_console(void)
+{
+ return 1;
+}
+
int board_eth_init(bd_t *bis)
{
setup_iomux_enet();
@@ -601,6 +798,10 @@ int board_early_init_f(void)
{
setup_iomux_uart();
+#if defined(CONFIG_VIDEO_IPUV3)
+ setup_display();
+#endif
+
#ifdef CONFIG_SYS_USE_SPINOR
setup_spinor();
#endif