Set the usb otg port on the cubox to host mode and attach ehci to it.
authorjsg <jsg@openbsd.org>
Sat, 30 May 2015 08:09:19 +0000 (08:09 +0000)
committerjsg <jsg@openbsd.org>
Sat, 30 May 2015 08:09:19 +0000 (08:09 +0000)
While ehci attaches, devices don't seem to be recognised in the otg port.
From Patrick Wildt in bitrig.

sys/arch/armv7/imx/imx6.c
sys/arch/armv7/imx/imxccm.c
sys/arch/armv7/imx/imxccmvar.h
sys/arch/armv7/imx/imxehci.c

index 5fa3ca0..2f3a0fa 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: imx6.c,v 1.2 2013/11/06 19:03:07 syl Exp $ */
+/* $OpenBSD: imx6.c,v 1.3 2015/05/30 08:09:19 jsg Exp $ */
 /*
  * Copyright (c) 2011 Uwe Stuehler <uwe@openbsd.org>
  * Copyright (c) 2012 Patrick Wildt <patrick@blueri.se>
@@ -319,6 +319,17 @@ struct armv7_dev imx6_devs[] = {
          .irq = { USBH1_IRQ }
        },
 
+       { .name = "ehci",
+         .unit = 1,
+         .mem = {
+                 { USBOTG_EHCI_ADDR, USBx_SIZE },
+                 { USBOTG_ADDR, USBx_SIZE },
+                 { USBPHY1_ADDR, USBPHYx_SIZE },
+                 { USBNC_ADDR, USBx_SIZE },
+         },
+         .irq = { USBOTG_IRQ }
+       },
+
        /*
         * Ethernet
         */
index 6d9d518..2035457 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: imxccm.c,v 1.4 2014/09/19 16:43:19 jsg Exp $ */
+/* $OpenBSD: imxccm.c,v 1.5 2015/05/30 08:09:19 jsg Exp $ */
 /*
  * Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se>
  *
@@ -75,6 +75,9 @@
 #define CCM_ANALOG_PLL_USB2_SET                        0x4024
 #define CCM_ANALOG_PLL_USB2_CLR                        0x4028
 #define CCM_ANALOG_PLL_SYS                     0x4030
+#define CCM_ANALOG_USB1_CHRG_DETECT            0x41b0
+#define CCM_ANALOG_USB1_CHRG_DETECT_SET                0x41b4
+#define CCM_ANALOG_USB1_CHRG_DETECT_CLR                0x41b8
 #define CCM_ANALOG_USB2_CHRG_DETECT            0x4210
 #define CCM_ANALOG_USB2_CHRG_DETECT_SET                0x4214
 #define CCM_ANALOG_USB2_CHRG_DETECT_CLR                0x4218
 #define CCM_CSCMR1_PERCLK_CLK_SEL_MASK         0x1f
 #define CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK     0x7f
 #define CCM_ANALOG_PLL_ARM_BYPASS              (1 << 16)
+#define CCM_ANALOG_PLL_USB1_DIV_SELECT_MASK    0x1
+#define CCM_ANALOG_PLL_USB1_EN_USB_CLKS                (1 << 6)
+#define CCM_ANALOG_PLL_USB1_POWER              (1 << 12)
+#define CCM_ANALOG_PLL_USB1_ENABLE             (1 << 13)
+#define CCM_ANALOG_PLL_USB1_BYPASS             (1 << 16)
+#define CCM_ANALOG_PLL_USB1_LOCK               (1 << 31)
 #define CCM_ANALOG_PLL_USB2_DIV_SELECT_MASK    0x1
 #define CCM_ANALOG_PLL_USB2_EN_USB_CLKS                (1 << 6)
 #define CCM_ANALOG_PLL_USB2_POWER              (1 << 12)
 #define CCM_ANALOG_PLL_USB2_BYPASS             (1 << 16)
 #define CCM_ANALOG_PLL_USB2_LOCK               (1U << 31)
 #define CCM_ANALOG_PLL_SYS_DIV_SELECT_MASK     0x1
+#define CCM_ANALOG_USB1_CHRG_DETECT_CHK_CHRG_B (1 << 19)
+#define CCM_ANALOG_USB1_CHRG_DETECT_EN_B       (1 << 20)
 #define CCM_ANALOG_USB2_CHRG_DETECT_CHK_CHRG_B (1 << 19)
 #define CCM_ANALOG_USB2_CHRG_DETECT_EN_B       (1 << 20)
 #define CCM_ANALOG_DIGPROG_MINOR_MASK          0xff
@@ -204,7 +215,9 @@ unsigned int imxccm_get_ipg_perclk(void);
 unsigned int imxccm_get_uartclk(void);
 void imxccm_enable_i2c(int x);
 void imxccm_enable_usboh3(void);
+void imxccm_disable_usb1_chrg_detect(void);
 void imxccm_disable_usb2_chrg_detect(void);
+void imxccm_enable_pll_usb1(void);
 void imxccm_enable_pll_usb2(void);
 void imxccm_enable_pll_enet(void);
 void imxccm_enable_enet(void);
@@ -543,6 +556,16 @@ imxccm_enable_pcie(void)
        HSET4(sc, CCM_CCGR4, CCM_CCGR4_125M_PCIE);
 }
 
+void 
+imxccm_disable_usb1_chrg_detect(void)
+{
+       struct imxccm_softc *sc = imxccm_sc;
+
+       HWRITE4(sc, CCM_ANALOG_USB1_CHRG_DETECT_SET,
+             CCM_ANALOG_USB1_CHRG_DETECT_CHK_CHRG_B
+           | CCM_ANALOG_USB1_CHRG_DETECT_EN_B);
+}
+
 void
 imxccm_disable_usb2_chrg_detect(void)
 {
@@ -553,6 +576,19 @@ imxccm_disable_usb2_chrg_detect(void)
            | CCM_ANALOG_USB2_CHRG_DETECT_EN_B);
 }
 
+void
+imxccm_enable_pll_usb1(void)
+{
+       struct imxccm_softc *sc = imxccm_sc;
+
+       HWRITE4(sc, CCM_ANALOG_PLL_USB1_CLR, CCM_ANALOG_PLL_USB1_BYPASS);
+
+       HWRITE4(sc, CCM_ANALOG_PLL_USB1_SET,
+             CCM_ANALOG_PLL_USB1_ENABLE
+           | CCM_ANALOG_PLL_USB1_POWER
+           | CCM_ANALOG_PLL_USB1_EN_USB_CLKS);
+}
+
 void
 imxccm_enable_pll_usb2(void)
 {
index decfc2a..86ebdaa 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: imxccmvar.h,v 1.1 2013/09/06 20:45:53 patrick Exp $ */
+/* $OpenBSD: imxccmvar.h,v 1.2 2015/05/30 08:09:19 jsg Exp $ */
 /*
  * Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se>
  *
@@ -25,7 +25,9 @@ unsigned int imxccm_get_ipg_perclk(void);
 unsigned int imxccm_get_ahbclk(void);
 void imxccm_enable_i2c(int x);
 void imxccm_enable_usboh3(void);
+void imxccm_disable_usb1_chrg_detect(void);
 void imxccm_disable_usb2_chrg_detect(void);
+void imxccm_enable_pll_usb1(void);
 void imxccm_enable_pll_usb2(void);
 void imxccm_enable_enet(void);
 void imxccm_enable_sata(void);
index 0de9785..b876f1e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: imxehci.c,v 1.7 2015/03/29 03:24:17 jsg Exp $ */
+/*     $OpenBSD: imxehci.c,v 1.8 2015/05/30 08:09:19 jsg Exp $ */
 /*
  * Copyright (c) 2012-2013 Patrick Wildt <patrick@blueri.se>
  *
 #define USBPHY_CTRL_SFTRST             (1U << 31)
 
 /* ehci */
-#define EHCI_USBMODE                   0x68
+#define EHCI_USBMODE                   0xa8
 
 #define EHCI_USBMODE_HOST              (3 << 0)
 #define EHCI_PS_PTS_UTMI_MASK  ((1 << 25) | (3 << 30))
 
 /* usb non-core */
+#define USBNC_USB_OTG_CTRL             0x00
 #define USBNC_USB_UH1_CTRL             0x04
 
+#define USBNC_USB_OTG_CTRL_OVER_CUR_POL        (1 << 8)
+#define USBNC_USB_OTG_CTRL_OVER_CUR_DIS        (1 << 7)
 #define USBNC_USB_UH1_CTRL_OVER_CUR_POL        (1 << 8)
 #define USBNC_USB_UH1_CTRL_OVER_CUR_DIS        (1 << 7)
 
+/* port specific addresses */
+#define USBOTG_EHCI_ADDR       0x02184100
+#define USBUH1_EHCI_ADDR       0x02184300
+#define USBUH2_EHCI_ADDR       0x02184500
+#define USBUH3_EHCI_ADDR       0x02184700
+
 /* board specific */
 #define EHCI_HUMMINGBOARD_USB_H1_PWR   0
 #define EHCI_HUMMINGBOARD_USB_OTG_PWR  (2*32+22)
@@ -125,53 +134,77 @@ imxehci_attach(struct device *parent, struct device *self, void *aux)
 
        printf("\n");
 
-       /* enable usb port power */
-       switch (board_id)
-       {
-       case BOARD_ID_IMX6_PHYFLEX:
-               imxgpio_set_dir(EHCI_PHYFLEX_USB_H1_PWR, IMXGPIO_DIR_OUT);
-               delay(10);
-               imxgpio_set_bit(EHCI_PHYFLEX_USB_H1_PWR);
-               delay(10);
-               break;
-       case BOARD_ID_IMX6_CUBOXI:
-       case BOARD_ID_IMX6_HUMMINGBOARD:
-               imxgpio_set_bit(EHCI_HUMMINGBOARD_USB_H1_PWR);
-               imxgpio_set_dir(EHCI_HUMMINGBOARD_USB_H1_PWR, IMXGPIO_DIR_OUT);
-               delay(10);
-               break;
-       case BOARD_ID_IMX6_SABRELITE:
-               imxgpio_clear_bit(EHCI_NITROGEN6X_USB_HUB_RST);
-               imxgpio_set_dir(EHCI_NITROGEN6X_USB_HUB_RST, IMXGPIO_DIR_OUT);
-               delay(1000 * 2);
-               imxgpio_set_bit(EHCI_NITROGEN6X_USB_HUB_RST);
-               delay(10);
-               break;
-       case BOARD_ID_IMX6_SABRESD:
-               imxgpio_set_bit(EHCI_SABRESD_USB_PWR);
-               imxgpio_set_dir(EHCI_SABRESD_USB_PWR, IMXGPIO_DIR_OUT);
-               delay(10);
-               break;
-       case BOARD_ID_IMX6_UTILITE:
-               imxgpio_clear_bit(EHCI_UTILITE_USB_HUB_RST);
-               imxgpio_set_dir(EHCI_UTILITE_USB_HUB_RST, IMXGPIO_DIR_OUT);
-               delay(10);
-               imxgpio_set_bit(EHCI_UTILITE_USB_HUB_RST);
-               delay(1000);
-               break;
-       }
-
        imxccm_enable_usboh3();
        delay(1000);
-       /* disable the carger detection, else signal on DP will be poor */
-       imxccm_disable_usb2_chrg_detect();
-       /* power host 1 */
-       imxccm_enable_pll_usb2();
-
-       /* over current and polarity setting */
-       bus_space_write_4(sc->sc.iot, sc->nc_ioh, USBNC_USB_UH1_CTRL,
-           bus_space_read_4(sc->sc.iot, sc->nc_ioh, USBNC_USB_UH1_CTRL) |
-           (USBNC_USB_UH1_CTRL_OVER_CUR_POL | USBNC_USB_UH1_CTRL_OVER_CUR_DIS));
+
+       if (aa->aa_dev->mem[0].addr == USBUH1_EHCI_ADDR) {
+               /* enable usb port power */
+               switch (board_id)
+               {
+               case BOARD_ID_IMX6_PHYFLEX:
+                       imxgpio_set_dir(EHCI_PHYFLEX_USB_H1_PWR, IMXGPIO_DIR_OUT);
+                       delay(10);
+                       imxgpio_set_bit(EHCI_PHYFLEX_USB_H1_PWR);
+                       delay(10);
+                       break;
+               case BOARD_ID_IMX6_CUBOXI:
+               case BOARD_ID_IMX6_HUMMINGBOARD:
+                       imxgpio_set_bit(EHCI_HUMMINGBOARD_USB_H1_PWR);
+                       imxgpio_set_dir(EHCI_HUMMINGBOARD_USB_H1_PWR, IMXGPIO_DIR_OUT);
+                       delay(10);
+                       break;
+               case BOARD_ID_IMX6_SABRELITE:
+                       imxgpio_clear_bit(EHCI_NITROGEN6X_USB_HUB_RST);
+                       imxgpio_set_dir(EHCI_NITROGEN6X_USB_HUB_RST, IMXGPIO_DIR_OUT);
+                       delay(1000 * 2);
+                       imxgpio_set_bit(EHCI_NITROGEN6X_USB_HUB_RST);
+                       delay(10);
+                       break;
+               case BOARD_ID_IMX6_SABRESD:
+                       imxgpio_set_bit(EHCI_SABRESD_USB_PWR);
+                       imxgpio_set_dir(EHCI_SABRESD_USB_PWR, IMXGPIO_DIR_OUT);
+                       delay(10);
+                       break;
+               case BOARD_ID_IMX6_UTILITE:
+                       imxgpio_clear_bit(EHCI_UTILITE_USB_HUB_RST);
+                       imxgpio_set_dir(EHCI_UTILITE_USB_HUB_RST, IMXGPIO_DIR_OUT);
+                       delay(10);
+                       imxgpio_set_bit(EHCI_UTILITE_USB_HUB_RST);
+                       delay(1000);
+                       break;
+               }
+
+               /* disable the carger detection, else signal on DP will be poor */
+               imxccm_disable_usb2_chrg_detect();
+               /* power host 1 */
+               imxccm_enable_pll_usb2();
+
+               /* over current and polarity setting */
+               bus_space_write_4(sc->sc.iot, sc->nc_ioh, USBNC_USB_UH1_CTRL,
+                   bus_space_read_4(sc->sc.iot, sc->nc_ioh, USBNC_USB_UH1_CTRL) |
+                   (USBNC_USB_UH1_CTRL_OVER_CUR_POL | USBNC_USB_UH1_CTRL_OVER_CUR_DIS));
+       } else if (aa->aa_dev->mem[0].addr == USBOTG_EHCI_ADDR) {
+               /* enable usb port power */
+               switch (board_id)
+               {
+               case BOARD_ID_IMX6_CUBOXI:
+               case BOARD_ID_IMX6_HUMMINGBOARD:
+                       imxgpio_set_dir(EHCI_HUMMINGBOARD_USB_OTG_PWR, IMXGPIO_DIR_OUT);
+                       imxgpio_set_bit(EHCI_HUMMINGBOARD_USB_OTG_PWR);
+                       delay(10);
+                       break;
+               }
+
+               /* disable the carger detection, else signal on DP will be poor */
+               imxccm_disable_usb1_chrg_detect();
+               /* power host 0 */
+               imxccm_enable_pll_usb1();
+
+               /* over current and polarity setting */
+               bus_space_write_4(sc->sc.iot, sc->nc_ioh, USBNC_USB_OTG_CTRL,
+                   bus_space_read_4(sc->sc.iot, sc->nc_ioh, USBNC_USB_OTG_CTRL) |
+                   (USBNC_USB_OTG_CTRL_OVER_CUR_POL | USBNC_USB_OTG_CTRL_OVER_CUR_DIS));
+       }
 
        bus_space_write_4(sc->sc.iot, sc->ph_ioh, USBPHY_CTRL_CLR,
            USBPHY_CTRL_CLKGATE);