Allow using different PHY interfaces for multiple USB controllers. When no
value is set in DT, we fall back to CONFIG_MXC_USB_PORTSC for now to stay
compatible with current board configurations.

This also adds support for the HSIC mode of the i.MX7.

Signed-off-by: Markus Niebel <markus.nie...@ew.tq-group.com>
Signed-off-by: Matthias Schiffer <matthias.schif...@ew.tq-group.com>
---
 drivers/usb/host/ehci-mx6.c | 25 +++++++++++++++++++++++--
 include/usb/ehci-ci.h       |  1 +
 2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/drivers/usb/host/ehci-mx6.c b/drivers/usb/host/ehci-mx6.c
index c3e4170513e..1bd6147c76a 100644
--- a/drivers/usb/host/ehci-mx6.c
+++ b/drivers/usb/host/ehci-mx6.c
@@ -23,6 +23,7 @@
 #include <asm/mach-types.h>
 #include <power/regulator.h>
 #include <linux/usb/otg.h>
+#include <linux/usb/phy.h>
 
 #include "ehci.h"
 
@@ -435,6 +436,7 @@ struct ehci_mx6_priv_data {
        struct clk clk;
        struct phy phy;
        enum usb_init_type init_type;
+       enum usb_phy_interface phy_type;
 #if !defined(CONFIG_PHY)
        int portnr;
        void __iomem *phy_addr;
@@ -443,6 +445,24 @@ struct ehci_mx6_priv_data {
 #endif
 };
 
+static u32 mx6_portsc(enum usb_phy_interface phy_type)
+{
+       switch (phy_type) {
+       case USBPHY_INTERFACE_MODE_UTMI:
+               return PORT_PTS_UTMI;
+       case USBPHY_INTERFACE_MODE_UTMIW:
+               return PORT_PTS_UTMI | PORT_PTS_PTW;
+       case USBPHY_INTERFACE_MODE_ULPI:
+               return PORT_PTS_ULPI;
+       case USBPHY_INTERFACE_MODE_SERIAL:
+               return PORT_PTS_SERIAL;
+       case USBPHY_INTERFACE_MODE_HSIC:
+               return PORT_PTS_HSIC;
+       default:
+               return CONFIG_MXC_USB_PORTSC;
+       }
+}
+
 static int mx6_init_after_reset(struct ehci_ctrl *dev)
 {
        struct ehci_mx6_priv_data *priv = dev->priv;
@@ -479,7 +499,7 @@ static int mx6_init_after_reset(struct ehci_ctrl *dev)
                return 0;
 
        setbits_le32(&ehci->usbmode, CM_HOST);
-       writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
+       writel(mx6_portsc(priv->phy_type), &ehci->portsc);
        setbits_le32(&ehci->portsc, USB_EN);
 
        mdelay(10);
@@ -641,6 +661,7 @@ static int ehci_usb_probe(struct udevice *dev)
 
        priv->ehci = ehci;
        priv->init_type = type;
+       priv->phy_type = usb_get_phy_mode(dev_ofnode(dev));
 
 #if CONFIG_IS_ENABLED(CLK)
        ret = clk_get_by_index(dev, 0, &priv->clk);
@@ -690,7 +711,7 @@ static int ehci_usb_probe(struct udevice *dev)
 
        if (priv->init_type == USB_INIT_HOST) {
                setbits_le32(&ehci->usbmode, CM_HOST);
-               writel(CONFIG_MXC_USB_PORTSC, &ehci->portsc);
+               writel(mx6_portsc(priv->phy_type), &ehci->portsc);
                setbits_le32(&ehci->portsc, USB_EN);
        }
 
diff --git a/include/usb/ehci-ci.h b/include/usb/ehci-ci.h
index bf5d26faa53..2cdb3146e86 100644
--- a/include/usb/ehci-ci.h
+++ b/include/usb/ehci-ci.h
@@ -23,6 +23,7 @@
 #define PORT_PTS_ULPI          (2 << 30)
 #define PORT_PTS_SERIAL                (3 << 30)
 #define PORT_PTS_PTW           (1 << 28)
+#define PORT_PTS_HSIC          (1 << 25)
 #define PORT_PFSC              (1 << 24) /* Defined on Page 39-44 of the 
mpc5151 ERM */
 #define PORT_PTS_PHCD          (1 << 23)
 #define PORT_PP                        (1 << 12)
-- 
2.17.1

Reply via email to