usb: ehci-mx6: Make regulator DM_REGULATOR dependent
[oweals/u-boot.git] / drivers / usb / host / ehci-msm.c
index 17bfa7c02f58364893576749acda0b5bc47cea44..5c257ccf4d226b04772f34601b65e673f2810cd5 100644 (file)
 #include <linux/compat.h>
 #include "ehci.h"
 
-/* PHY viewport regs */
-#define ULPI_MISC_A_READ         0x96
-#define ULPI_MISC_A_SET          0x97
-#define ULPI_MISC_A_CLEAR        0x98
-#define ULPI_MISC_A_VBUSVLDEXTSEL    (1 << 1)
-#define ULPI_MISC_A_VBUSVLDEXT       (1 << 0)
-
-#define GEN2_SESS_VLD_CTRL_EN (1 << 7)
-
-#define SESS_VLD_CTRL         (1 << 25)
-
 struct msm_ehci_priv {
        struct ehci_ctrl ctrl; /* Needed by EHCI */
        struct usb_ehci *ehci; /* Start of IP core*/
        struct ulpi_viewport ulpi_vp; /* ULPI Viewport */
+       struct phy phy;
 };
 
-int __weak board_prepare_usb(enum usb_init_type type)
-{
-       return 0;
-}
-
-static void setup_usb_phy(struct msm_ehci_priv *priv)
-{
-       /* Select and enable external configuration with USB PHY */
-       ulpi_write(&priv->ulpi_vp, (u8 *)ULPI_MISC_A_SET,
-                  ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT);
-}
-
-static void reset_usb_phy(struct msm_ehci_priv *priv)
-{
-       /* Disable VBUS mimicing in the controller. */
-       ulpi_write(&priv->ulpi_vp, (u8 *)ULPI_MISC_A_CLEAR,
-                  ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT);
-}
-
-
 static int msm_init_after_reset(struct ehci_ctrl *dev)
 {
        struct msm_ehci_priv *p = container_of(dev, struct msm_ehci_priv, ctrl);
        struct usb_ehci *ehci = p->ehci;
 
-       /* select ULPI phy */
-       writel(PORT_PTS_ULPI, &ehci->portsc);
-       setup_usb_phy(p);
-
-       /* Enable sess_vld */
-       setbits_le32(&ehci->genconfig2, GEN2_SESS_VLD_CTRL_EN);
-
-       /* Enable external vbus configuration in the LINK */
-       setbits_le32(&ehci->usbcmd, SESS_VLD_CTRL);
-
-       /* USB_OTG_HS_AHB_BURST */
-       writel(0x0, &ehci->sbuscfg);
-
-       /* USB_OTG_HS_AHB_MODE: HPROT_MODE */
-       /* Bus access related config. */
-       writel(0x08, &ehci->sbusmode);
+       generic_phy_reset(&p->phy);
 
        /* set mode to host controller */
        writel(CM_HOST, &ehci->usbmode);
@@ -94,6 +49,7 @@ static int ehci_usb_probe(struct udevice *dev)
 {
        struct msm_ehci_priv *p = dev_get_priv(dev);
        struct usb_ehci *ehci = p->ehci;
+       struct usb_platdata *plat = dev_get_platdata(dev);
        struct ehci_hccr *hccr;
        struct ehci_hcor *hcor;
        int ret;
@@ -102,11 +58,16 @@ static int ehci_usb_probe(struct udevice *dev)
        hcor = (struct ehci_hcor *)((phys_addr_t)hccr +
                        HC_LENGTH(ehci_readl(&(hccr)->cr_capbase)));
 
-       ret = board_prepare_usb(USB_INIT_HOST);
+       ret = ehci_setup_phy(dev, &p->phy, 0);
+       if (ret)
+               return ret;
+
+       ret = board_usb_init(0, plat->init_type);
        if (ret < 0)
                return ret;
 
-       return ehci_register(dev, hccr, hcor, &msm_ehci_ops, 0, USB_INIT_HOST);
+       return ehci_register(dev, hccr, hcor, &msm_ehci_ops, 0,
+                            plat->init_type);
 }
 
 static int ehci_usb_remove(struct udevice *dev)
@@ -122,9 +83,11 @@ static int ehci_usb_remove(struct udevice *dev)
        /* Stop controller. */
        clrbits_le32(&ehci->usbcmd, CMD_RUN);
 
-       reset_usb_phy(p);
+       ret = ehci_shutdown_phy(dev, &p->phy);
+       if (ret)
+               return ret;
 
-       ret = board_prepare_usb(USB_INIT_DEVICE); /* Board specific hook */
+       ret = board_usb_init(0, USB_INIT_DEVICE); /* Board specific hook */
        if (ret < 0)
                return ret;
 
@@ -158,6 +121,18 @@ static int ehci_usb_ofdata_to_platdata(struct udevice *dev)
        return 0;
 }
 
+#if defined(CONFIG_CI_UDC)
+/* Little quirk that MSM needs with Chipidea controller
+ * Must reinit phy after reset
+ */
+void ci_init_after_reset(struct ehci_ctrl *ctrl)
+{
+       struct msm_ehci_priv *p = ctrl->priv;
+
+       generic_phy_reset(&p->phy);
+}
+#endif
+
 static const struct udevice_id ehci_usb_ids[] = {
        { .compatible = "qcom,ehci-host", },
        { }
@@ -172,5 +147,6 @@ U_BOOT_DRIVER(usb_ehci) = {
        .remove = ehci_usb_remove,
        .ops    = &ehci_usb_ops,
        .priv_auto_alloc_size = sizeof(struct msm_ehci_priv),
+       .platdata_auto_alloc_size = sizeof(struct usb_platdata),
        .flags  = DM_FLAG_ALLOC_PRIV_DMA,
 };