]> git.sur5r.net Git - u-boot/blobdiff - board/boundary/nitrogen6x/nitrogen6x.c
nitrogen6x: add otg usb host/device mode support
[u-boot] / board / boundary / nitrogen6x / nitrogen6x.c
index 1a29b6f4bd0639ff06aef6056b70b1ca83b421db..53cb8dffd0d534629a4de5c7b9798733015adb6e 100644 (file)
@@ -2,7 +2,7 @@
  * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
  * Copyright (C) 2013, Boundary Devices <info@boundarydevices.com>
  *
- * SPDX-License-Identifier:    GPL-2.0+ 
+ * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
@@ -30,6 +30,7 @@
 #include <i2c.h>
 
 DECLARE_GLOBAL_DATA_PTR;
+#define GP_USB_OTG_PWR IMX_GPIO_NR(3, 22)
 
 #define UART_PAD_CTRL  (PAD_CTL_PUS_100K_UP |                  \
        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm |                 \
@@ -179,6 +180,14 @@ iomux_v3_cfg_t const enet_pads2[] = {
        MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL      | MUX_PAD_CTRL(ENET_PAD_CTRL),
 };
 
+static iomux_v3_cfg_t const misc_pads[] = {
+       MX6_PAD_GPIO_1__USB_OTG_ID              | MUX_PAD_CTRL(WEAK_PULLUP),
+       MX6_PAD_KEY_COL4__USBOH3_USBOTG_OC      | MUX_PAD_CTRL(WEAK_PULLUP),
+       MX6_PAD_EIM_D30__USBOH3_USBH1_OC        | MUX_PAD_CTRL(WEAK_PULLUP),
+       /* OTG Power enable */
+       MX6_PAD_EIM_D22__GPIO_3_22              | MUX_PAD_CTRL(OUTPUT_40OHM),
+};
+
 /* wl1271 pads on nitrogen6x */
 iomux_v3_cfg_t const wl12xx_pads[] = {
        (MX6_PAD_NANDF_CS1__GPIO_6_14 & ~MUX_PAD_CTRL_MASK)
@@ -250,6 +259,15 @@ int board_ehci_hcd_init(int port)
 
        return 0;
 }
+
+int board_ehci_power(int port, int on)
+{
+       if (port)
+               return 0;
+       gpio_set_value(GP_USB_OTG_PWR, on);
+       return 0;
+}
+
 #endif
 
 #ifdef CONFIG_FSL_ESDHC
@@ -369,6 +387,11 @@ int board_eth_init(bd_t *bis)
                free(bus);
        }
 #endif
+
+#ifdef CONFIG_MV_UDC
+       /* For otg ethernet*/
+       usb_eth_initialize(bis);
+#endif
        return 0;
 }
 
@@ -461,25 +484,12 @@ struct display_info_t {
 static int detect_hdmi(struct display_info_t const *dev)
 {
        struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
-       return readb(&hdmi->phy_stat0) & HDMI_PHY_HPD;
+       return readb(&hdmi->phy_stat0) & HDMI_DVI_STAT;
 }
 
-static void enable_hdmi(struct display_info_t const *dev)
+static void do_enable_hdmi(struct display_info_t const *dev)
 {
-       struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
-       u8 reg;
-       printf("%s: setup HDMI monitor\n", __func__);
-       reg = readb(&hdmi->phy_conf0);
-       reg |= HDMI_PHY_CONF0_PDZ_MASK;
-       writeb(reg, &hdmi->phy_conf0);
-
-       udelay(3000);
-       reg |= HDMI_PHY_CONF0_ENTMDS_MASK;
-       writeb(reg, &hdmi->phy_conf0);
-       udelay(3000);
-       reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK;
-       writeb(reg, &hdmi->phy_conf0);
-       writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz);
+       imx_enable_hdmi_phy();
 }
 
 static int detect_i2c(struct display_info_t const *dev)
@@ -512,7 +522,7 @@ static struct display_info_t const displays[] = {{
        .addr   = 0,
        .pixfmt = IPU_PIX_FMT_RGB24,
        .detect = detect_hdmi,
-       .enable = enable_hdmi,
+       .enable = do_enable_hdmi,
        .mode   = {
                .name           = "HDMI",
                .refresh        = 60,
@@ -606,6 +616,7 @@ int board_video_skip(void)
                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++) {
@@ -622,9 +633,10 @@ int board_video_skip(void)
                               displays[i].mode.name,
                               displays[i].mode.xres,
                               displays[i].mode.yres);
-               } else
+               } else {
                        printf("LCD %s cannot be configured: %d\n",
                               displays[i].mode.name, ret);
+               }
        } else {
                printf("unsupported panel %s\n", panel);
                ret = -EINVAL;
@@ -635,31 +647,16 @@ int board_video_skip(void)
 static void setup_display(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;
-       struct hdmi_regs *hdmi  = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
-
        int reg;
 
+       enable_ipu_clock();
+       imx_setup_hdmi();
        /* 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;
+       reg |=  MXC_CCM_CCGR3_LDB_DI0_MASK;
        writel(reg, &mxc_ccm->CCGR3);
 
-       /* Turn on HDMI PHY clock */
-       reg = __raw_readl(&mxc_ccm->CCGR2);
-       reg |=  MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK
-              |MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK;
-       writel(reg, &mxc_ccm->CCGR2);
-
-       /* clear HDMI PHY reset */
-       writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz);
-
-       /* 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
@@ -673,15 +670,8 @@ static void setup_display(void)
        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);
+               <<MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_OFFSET);
        writel(reg, &mxc_ccm->chsccdr);
 
        reg = IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES
@@ -696,7 +686,8 @@ static void setup_display(void)
        writel(reg, &iomux->gpr[2]);
 
        reg = readl(&iomux->gpr[3]);
-       reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
+       reg = (reg & ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK
+                       |IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
            | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
               <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
        writel(reg, &iomux->gpr[3]);
@@ -717,6 +708,7 @@ int board_early_init_f(void)
        gpio_direction_input(WL12XX_WL_IRQ_GP);
        gpio_direction_output(WL12XX_WL_ENABLE_GP, 0);
        gpio_direction_output(WL12XX_BT_ENABLE_GP, 0);
+       gpio_direction_output(GP_USB_OTG_PWR, 0); /* OTG power off */
 
        imx_iomux_v3_setup_multiple_pads(wl12xx_pads, ARRAY_SIZE(wl12xx_pads));
        setup_buttons();
@@ -738,6 +730,15 @@ int overwrite_console(void)
 
 int board_init(void)
 {
+       struct iomuxc_base_regs *const iomuxc_regs
+               = (struct iomuxc_base_regs *)IOMUXC_BASE_ADDR;
+
+       clrsetbits_le32(&iomuxc_regs->gpr[1],
+                       IOMUXC_GPR1_OTG_ID_MASK,
+                       IOMUXC_GPR1_OTG_ID_GPIO1);
+
+       imx_iomux_v3_setup_multiple_pads(misc_pads, ARRAY_SIZE(misc_pads));
+
        /* address of boot parameters */
        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;