Platforms that have configured DWC_USB3_HSPHY_INTERFACE with
value 3, i.e. UTMI+ and ULPI, need to inform the driver of
the actual HSPHY interface type with the property. "utmi" if
the interface is UTMI+ or "ulpi" if the interface is ULPI.

Signed-off-by: Heikki Krogerus <heikki.kroge...@linux.intel.com>
---
 Documentation/devicetree/bindings/usb/dwc3.txt |  2 ++
 drivers/usb/dwc3/core.c                        | 29 ++++++++++++++++++++++++--
 drivers/usb/dwc3/core.h                        |  3 +++
 drivers/usb/dwc3/platform_data.h               |  2 ++
 4 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/Documentation/devicetree/bindings/usb/dwc3.txt 
b/Documentation/devicetree/bindings/usb/dwc3.txt
index 5cc3643..0815eac 100644
--- a/Documentation/devicetree/bindings/usb/dwc3.txt
+++ b/Documentation/devicetree/bindings/usb/dwc3.txt
@@ -38,6 +38,8 @@ Optional properties:
  - snps,is-utmi-l1-suspend: true when DWC3 asserts output signal
                        utmi_l1_suspend_n, false when asserts utmi_sleep_n
  - snps,hird-threshold: HIRD threshold
+ - snps,hsphy_interface: High-Speed PHY interface selection between "utmi" for
+   UTMI+ and "ulpi" for ULPI when the DWC_USB3_HSPHY_INTERFACE has value 3.
 
 This is usually a subnode to DWC3 glue to which it is connected.
 
diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
index 6b02e12..b229ba1 100644
--- a/drivers/usb/dwc3/core.c
+++ b/drivers/usb/dwc3/core.c
@@ -395,9 +395,10 @@ static void dwc3_cache_hwparams(struct dwc3 *dwc)
  * dwc3_phy_setup - Configure USB PHY Interface of DWC3 Core
  * @dwc: Pointer to our controller context structure
  */
-static void dwc3_phy_setup(struct dwc3 *dwc)
+static int dwc3_phy_setup(struct dwc3 *dwc)
 {
        u32 reg;
+       int ret;
 
        reg = dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0));
 
@@ -438,6 +439,22 @@ static void dwc3_phy_setup(struct dwc3 *dwc)
 
        reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0));
 
+       /* Select the HS PHY interface */
+       switch (DWC3_GHWPARAMS3_HSPHY_IFC(dwc->hwparams.hwparams3)) {
+       case DWC3_GHWPARAMS3_HSPHY_IFC_UTMI_ULPI:
+               if (!strncmp(dwc->hsphy_interface, "utmi", 4)) {
+                       reg &= ~DWC3_GUSB2PHYCFG_ULPI_UTMI;
+               } else if (!strncmp(dwc->hsphy_interface, "ulpi", 4)) {
+                       reg |= DWC3_GUSB2PHYCFG_ULPI_UTMI;
+               } else {
+                       dev_err(dwc->dev, "HSPHY Interface not defined\n");
+                       return -EINVAL;
+               }
+               /* FALLTHROUGH */
+       default:
+               break;
+       }
+
        /*
         * Above 1.94a, it is recommended to set DWC3_GUSB2PHYCFG_SUSPHY to
         * '0' during coreConsultant configuration. So default value will
@@ -451,6 +468,8 @@ static void dwc3_phy_setup(struct dwc3 *dwc)
                reg &= ~DWC3_GUSB2PHYCFG_SUSPHY;
 
        dwc3_writel(dwc->regs, DWC3_GUSB2PHYCFG(0), reg);
+
+       return 0;
 }
 
 /**
@@ -844,6 +863,8 @@ static int dwc3_probe(struct platform_device *pdev)
                                "snps,tx_de_emphasis_quirk");
                of_property_read_u8(node, "snps,tx_de_emphasis",
                                &tx_de_emphasis);
+               of_property_read_string(node, "snps,hsphy_interface",
+                                       &dwc->hsphy_interface);
        } else if (pdata) {
                dwc->maximum_speed = pdata->maximum_speed;
                dwc->has_lpm_erratum = pdata->has_lpm_erratum;
@@ -871,6 +892,8 @@ static int dwc3_probe(struct platform_device *pdev)
                dwc->tx_de_emphasis_quirk = pdata->tx_de_emphasis_quirk;
                if (pdata->tx_de_emphasis)
                        tx_de_emphasis = pdata->tx_de_emphasis;
+
+               dwc->hsphy_interface = pdata->hsphy_interface;
        }
 
        /* default to superspeed if no maximum_speed passed */
@@ -886,7 +909,9 @@ static int dwc3_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, dwc);
        dwc3_cache_hwparams(dwc);
 
-       dwc3_phy_setup(dwc);
+       ret = dwc3_phy_setup(dwc);
+       if (ret)
+               goto err0;
 
        ret = dwc3_core_get_phy(dwc);
        if (ret)
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index c6eafaa..7b3ab64 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -682,6 +682,7 @@ struct dwc3_scratchpad_array {
  * @test_mode_nr: test feature selector
  * @lpm_nyet_threshold: LPM NYET response threshold
  * @hird_threshold: HIRD threshold
+ * @hsphy_interface: "utmi" or "ulpi"
  * @delayed_status: true when gadget driver asks for delayed status
  * @ep0_bounced: true when we used bounce buffer
  * @ep0_expect_in: true when we expect a DATA IN transfer
@@ -809,6 +810,8 @@ struct dwc3 {
        u8                      lpm_nyet_threshold;
        u8                      hird_threshold;
 
+       const char              *hsphy_interface;
+
        unsigned                delayed_status:1;
        unsigned                ep0_bounced:1;
        unsigned                ep0_expect_in:1;
diff --git a/drivers/usb/dwc3/platform_data.h b/drivers/usb/dwc3/platform_data.h
index a2bd464..d3614ec 100644
--- a/drivers/usb/dwc3/platform_data.h
+++ b/drivers/usb/dwc3/platform_data.h
@@ -45,4 +45,6 @@ struct dwc3_platform_data {
 
        unsigned tx_de_emphasis_quirk:1;
        unsigned tx_de_emphasis:2;
+
+       const char *hsphy_interface;
 };
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to