[U-Boot] [PATCH V4] i.MX6: mx6qsabrelite: Add splash screen support
Eric Nelson
eric.nelson at boundarydevices.com
Sat Sep 22 00:53:50 CEST 2012
Adds support for two LVDS panels and one RGB panel to the SABRE-Lite
board:
Hannstar-XGA - 1024 x 768 LVDS (Freescale part number MCIMX-LVDS1)
wsvga-lvds - 1024 x 600 LVDS (Boundary p/n Nit6X_1024x600)
wvga-rgb - 800 x 480 RGB (Boundary p/n Nit6X_800x480)
Auto-detects panel by probing the I2C touch controller of each.
Setting 'panel' environment variable to one of the names above will override
auto-detection.
Signed-off-by: Eric Nelson <eric.nelson at boundarydevices.com>
---
board/freescale/mx6qsabrelite/mx6qsabrelite.c | 245 ++++++++++++++++++++++++-
drivers/video/ipu_common.c | 2 +-
include/configs/mx6qsabrelite.h | 15 ++-
3 files changed, 259 insertions(+), 3 deletions(-)
diff --git a/board/freescale/mx6qsabrelite/mx6qsabrelite.c b/board/freescale/mx6qsabrelite/mx6qsabrelite.c
index 4b4e89b..d274d8c 100644
--- a/board/freescale/mx6qsabrelite/mx6qsabrelite.c
+++ b/board/freescale/mx6qsabrelite/mx6qsabrelite.c
@@ -36,6 +36,11 @@
#include <micrel.h>
#include <miiphy.h>
#include <netdev.h>
+#include <linux/fb.h>
+#include <ipu_pixfmt.h>
+#include <asm/arch/crm_regs.h>
+#include <i2c.h>
+
DECLARE_GLOBAL_DATA_PTR;
#define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
@@ -372,14 +377,252 @@ int setup_sata(void)
}
#endif
+#if defined(CONFIG_VIDEO_IPUV3)
+static struct fb_videomode videomodes[] = {{
+ .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, /* a.k.a. LVDS */
+ .vmode = FB_VMODE_NONINTERLACED
+ }, {
+ .name = "wsvga-lvds",
+ .refresh = 60,
+ .xres = 1024,
+ .yres = 600,
+ .pixclock = 15385,
+ .left_margin = 220,
+ .right_margin = 40,
+ .upper_margin = 21,
+ .lower_margin = 7,
+ .hsync_len = 60,
+ .vsync_len = 10,
+ .sync = FB_SYNC_EXT, /* a.k.a. LVDS */
+ .vmode = FB_VMODE_NONINTERLACED
+ }, {
+ .name = "wvga-rgb",
+ .refresh = 57,
+ .xres = 800,
+ .yres = 480,
+ .pixclock = 37037,
+ .left_margin = 40,
+ .right_margin = 60,
+ .upper_margin = 10,
+ .lower_margin = 10,
+ .hsync_len = 20,
+ .vsync_len = 10,
+ .sync = 0,
+ .vmode = FB_VMODE_NONINTERLACED
+} };
+
+#define IS_LVDS(m) (FB_SYNC_EXT & (m).sync)
+
+struct i2c_display {
+ int bus;
+ int addr;
+ char const *name;
+};
+
+static struct i2c_display const i2c_displays[] = {
+{
+ .bus = 2,
+ .addr = 0x4,
+ .name = "Hannstar-XGA",
+}, {
+ .bus = 2,
+ .addr = 0x38,
+ .name = "wsvga-lvds",
+}, {
+ .bus = 2,
+ .addr = 0x48,
+ .name = "wvga-rgb",
+} };
+
+static iomux_v3_cfg_t rgb_pads[] = {
+ MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+ MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15,
+ MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2,
+ MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3,
+ MX6Q_PAD_DI0_PIN4__GPIO_4_20,
+ MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
+ MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
+ MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
+ MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
+ MX6Q_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
+ MX6Q_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
+ MX6Q_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
+ MX6Q_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
+ MX6Q_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
+ MX6Q_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
+ MX6Q_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
+ MX6Q_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
+ MX6Q_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
+ MX6Q_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
+ MX6Q_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
+ MX6Q_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
+ MX6Q_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
+ MX6Q_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
+ MX6Q_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
+ MX6Q_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
+ MX6Q_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20,
+ MX6Q_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
+ MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
+ MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
+};
+
+static iomux_v3_cfg_t backlight_pads[] = {
+ /* Backlight on RGB connector: J15 */
+ MX6Q_PAD_SD1_DAT3__GPIO_1_21 | MUX_PAD_CTRL(NO_PAD_CTRL),
+#define RGB_BACKLIGHT_GP IMX_GPIO_NR(1, 21)
+
+ /* Backlight on LVDS connector: J6 */
+ MX6Q_PAD_SD1_CMD__GPIO_1_18 | MUX_PAD_CTRL(NO_PAD_CTRL),
+#define LVDS_BACKLIGHT_GP IMX_GPIO_NR(1, 18)
+};
+
+int board_video_skip(void)
+{
+ int i;
+ int ret;
+ char const *panel = getenv("panel");
+ if (!panel) {
+ for (i = 0; i < ARRAY_SIZE(i2c_displays); i++) {
+ struct i2c_display const *dev = i2c_displays+i;
+ if ((0 == i2c_set_bus_num(dev->bus))
+ &&
+ (0 == i2c_probe(dev->addr))) {
+ panel = dev->name;
+ printf("auto-detected panel %s\n", panel);
+ break;
+ }
+ }
+ if (!panel) {
+ panel = videomodes[0].name;
+ printf("No panel detected: default to %s\n", panel);
+ }
+ }
+ for (i = 0; i < ARRAY_SIZE(videomodes); i++) {
+ if (!strcmp(panel, videomodes[i].name))
+ break;
+ }
+ if (i < ARRAY_SIZE(videomodes)) {
+ ret = ipuv3_fb_init(videomodes+i, 0, IPU_PIX_FMT_RGB666);
+ if (!ret) {
+ if (IS_LVDS(videomodes[i]))
+ gpio_direction_output(LVDS_BACKLIGHT_GP, 1);
+ else {
+ imx_iomux_v3_setup_multiple_pads(
+ rgb_pads,
+ ARRAY_SIZE(rgb_pads));
+ gpio_direction_output(RGB_BACKLIGHT_GP, 1);
+ }
+ printf("Display: %s (%ux%u)\n",
+ videomodes[i].name,
+ videomodes[i].xres,
+ videomodes[i].yres);
+ } else
+ printf("LCD %s cannot be configured: %d\n",
+ videomodes[i].name, ret);
+ } else {
+ printf("unsupported panel %s\n", panel);
+ ret = -EINVAL;
+ }
+ return (0 != ret);
+}
+
+void lcd_iomux(void)
+{
+ struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+ struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
+ struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
+
+ int reg;
+
+ /* Turn on LDB0,IPU,IPU DI0 clocks */
+ reg = __raw_readl(&mxc_ccm->CCGR3);
+ reg |= MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET
+ |MXC_CCM_CCGR3_LDB_DI0_MASK;
+ writel(reg, &mxc_ccm->CCGR3);
+
+ /* set PFD1_FRAC to 0x13 == 455 MHz (480*18)/0x13 */
+ writel(ANATOP_PFD_480_PFD1_FRAC_MASK, &anatop->pfd_480_clr);
+ writel(0x13<<ANATOP_PFD_480_PFD1_FRAC_SHIFT, &anatop->pfd_480_set);
+
+ /* set LDB0, LDB1 clk select to 011/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;
+ writel(reg, &mxc_ccm->cscmr2);
+
+ reg = readl(&mxc_ccm->chsccdr);
+ reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK
+ |MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK
+ |MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK);
+ reg |= (CHSCCDR_CLK_SEL_LDB_DI0
+ <<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET)
+ |(CHSCCDR_PODF_DIVIDE_BY_3
+ <<MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET)
+ |(CHSCCDR_IPU_PRE_CLK_540M_PFD
+ <<MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET);
+ writel(reg, &mxc_ccm->chsccdr);
+
+ reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
+ |IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH
+ |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_CH1_MODE_DISABLED
+ |IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0;
+ writel(reg, &iomux->gpr[2]);
+
+ reg = readl(&iomux->gpr[3]);
+ reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
+ | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
+ <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
+ writel(reg, &iomux->gpr[3]);
+
+ /* backlights off until needed */
+ imx_iomux_v3_setup_multiple_pads(backlight_pads,
+ ARRAY_SIZE(backlight_pads));
+ gpio_direction_input(LVDS_BACKLIGHT_GP);
+ gpio_direction_input(RGB_BACKLIGHT_GP);
+}
+#endif
+
int board_early_init_f(void)
{
setup_iomux_uart();
setup_buttons();
-
+#if defined(CONFIG_VIDEO_IPUV3)
+ lcd_iomux();
+#endif
return 0;
}
+/*
+ * Do not overwrite the console
+ * Use always serial for U-Boot console
+ */
+int overwrite_console(void)
+{
+ return 1;
+}
+
int board_init(void)
{
/* address of boot parameters */
diff --git a/drivers/video/ipu_common.c b/drivers/video/ipu_common.c
index cc8f881..5f0a1a8 100644
--- a/drivers/video/ipu_common.c
+++ b/drivers/video/ipu_common.c
@@ -218,7 +218,7 @@ static struct clk ipu_clk = {
#else
.enable_reg = (u32 *)(CCM_BASE_ADDR +
offsetof(struct mxc_ccm_reg, CCGR3)),
- .enable_shift = MXC_CCM_CCGR3_IPU1_IPU_DI0_OFFSET,
+ .enable_shift = MXC_CCM_CCGR3_IPU1_IPU_MASK,
#endif
.enable = clk_ipu_enable,
.disable = clk_ipu_disable,
diff --git a/include/configs/mx6qsabrelite.h b/include/configs/mx6qsabrelite.h
index 72d0154..d0c3e0a 100644
--- a/include/configs/mx6qsabrelite.h
+++ b/include/configs/mx6qsabrelite.h
@@ -39,7 +39,7 @@
#define CONFIG_REVISION_TAG
/* Size of malloc() pool */
-#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024)
+#define CONFIG_SYS_MALLOC_LEN (10 * 1024 * 1024)
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_MISC_INIT_R
@@ -121,6 +121,19 @@
/* Miscellaneous commands */
#define CONFIG_CMD_BMODE
+/* Framebuffer and LCD */
+#define CONFIG_VIDEO
+#define CONFIG_VIDEO_IPUV3
+#define CONFIG_CFB_CONSOLE
+#define CONFIG_VGA_AS_SINGLE_DEVICE
+#define CONFIG_SYS_CONSOLE_IS_IN_ENV
+#define CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE
+#define CONFIG_VIDEO_BMP_RLE8
+#define CONFIG_SPLASH_SCREEN
+#define CONFIG_BMP_16BPP
+#define CONFIG_VIDEO_LOGO
+#define CONFIG_IPUV3_CLK 260000000
+
/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
#define CONFIG_CONS_INDEX 1
--
1.7.9
More information about the U-Boot
mailing list