Add LVDS and HDMI support.

Signed-off-by: Otavio Salvador <ota...@ossystems.com.br>
---

 board/congatec/cgtqmx6eval/cgtqmx6eval.c | 181 +++++++++++++++++++++++++++++++
 include/configs/cgtqmx6eval.h            |  20 ++++
 2 files changed, 201 insertions(+)

diff --git a/board/congatec/cgtqmx6eval/cgtqmx6eval.c 
b/board/congatec/cgtqmx6eval/cgtqmx6eval.c
index a3d01bf..e9461df 100644
--- a/board/congatec/cgtqmx6eval/cgtqmx6eval.c
+++ b/board/congatec/cgtqmx6eval/cgtqmx6eval.c
@@ -17,6 +17,8 @@
 #include <asm/imx-common/iomux-v3.h>
 #include <asm/imx-common/boot_mode.h>
 #include <asm/imx-common/mxc_i2c.h>
+#include <asm/arch/mxc_hdmi.h>
+#include <asm/arch/crm_regs.h>
 #include <malloc.h>
 #include <mmc.h>
 #include <fsl_esdhc.h>
@@ -25,6 +27,8 @@
 #include <i2c.h>
 #include <power/pmic.h>
 #include <power/pfuze100_pmic.h>
+#include <linux/fb.h>
+#include <ipu_pixfmt.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -505,10 +509,187 @@ int board_ehci_power(int port, int on)
        return 0;
 }
 
+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 = 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 } }
+};
+
+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;
+}
+
+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;
+
+       enable_ipu_clock();
+       imx_setup_hdmi();
+
+       /* Turn on LDB0, LDB1, IPU,IPU DI0 clocks */
+       reg = __raw_readl(&mxc_ccm->CCGR3);
+       reg |= MXC_CCM_CCGR3_LDB_DI0_MASK | MXC_CCM_CCGR3_LDB_DI1_MASK;
+       writel(reg, &mxc_ccm->CCGR3);
+
+       /* 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 | 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_BGREF_RRMODE_EXTERNAL_RES
+           | 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_DISABLED
+           | IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0;
+       writel(reg, &iomux->gpr[2]);
+
+       reg = readl(&iomux->gpr[3]);
+       reg = (reg & ~(IOMUXC_GPR3_LVDS1_MUX_CTL_MASK |
+              IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
+           | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0 <<
+              IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET);
+       writel(reg, &iomux->gpr[3]);
+}
+
+/*
+ * Do not overwrite the console
+ * Use always serial for U-Boot console
+ */
+int overwrite_console(void)
+{
+       return 1;
+}
+
 int board_early_init_f(void)
 {
        setup_iomux_uart();
        setup_spinor();
+       setup_display();
 
        return 0;
 }
diff --git a/include/configs/cgtqmx6eval.h b/include/configs/cgtqmx6eval.h
index a88c4db..0a778a7 100644
--- a/include/configs/cgtqmx6eval.h
+++ b/include/configs/cgtqmx6eval.h
@@ -93,6 +93,26 @@
 #define CONFIG_USB_KEYBOARD
 #define CONFIG_SYS_USB_EVENT_POLL_VIA_CONTROL_EP
 
+/* Framebuffer */
+#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_SPLASH_SCREEN_ALIGN
+#define CONFIG_BMP_16BPP
+#define CONFIG_VIDEO_LOGO
+#define CONFIG_VIDEO_BMP_LOGO
+#ifdef CONFIG_MX6DL
+#define CONFIG_IPUV3_CLK 198000000
+#else
+#define CONFIG_IPUV3_CLK 264000000
+#endif
+#define CONFIG_IMX_HDMI
+
 #define CONFIG_DEFAULT_FDT_FILE "imx6q-congatec.dtb"
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
-- 
2.4.5

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to