Merge https://gitlab.denx.de/u-boot/custodians/u-boot-mpc85xx
[oweals/u-boot.git] / drivers / phy / meson-gxl-usb2.c
index 15c9c89fd9e099ae77c8abb1b22351ab9ccd8841..2267bd08c2c719e1c7eb165ce54e3614f584cf2c 100644 (file)
@@ -1,28 +1,30 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Meson GXL and GXM USB2 PHY driver
  *
  * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
  * Copyright (C) 2018 BayLibre, SAS
  * Author: Neil Armstrong <narmstron@baylibre.com>
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
+#include <malloc.h>
 #include <asm/io.h>
 #include <bitfield.h>
 #include <dm.h>
 #include <errno.h>
 #include <generic-phy.h>
 #include <regmap.h>
+#include <linux/delay.h>
 #include <power/regulator.h>
 #include <clk.h>
+#include <linux/usb/otg.h>
+
+#include <asm/arch/usb-gx.h>
 
 #include <linux/bitops.h>
 #include <linux/compat.h>
 
-DECLARE_GLOBAL_DATA_PTR;
-
 /* bits [31:27] are read-only */
 #define U2P_R0                                                 0x0
        #define U2P_R0_BYPASS_SEL                               BIT(0)
@@ -123,15 +125,30 @@ static void phy_meson_gxl_usb2_reset(struct phy_meson_gxl_usb2_priv *priv)
        udelay(RESET_COMPLETE_TIME);
 }
 
-static void
-phy_meson_gxl_usb2_set_host_mode(struct phy_meson_gxl_usb2_priv *priv)
+void phy_meson_gxl_usb2_set_mode(struct phy *phy, enum usb_dr_mode mode)
 {
+       struct udevice *dev = phy->dev;
+       struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
        uint val;
 
        regmap_read(priv->regmap, U2P_R0, &val);
-       val |= U2P_R0_DM_PULLDOWN;
-       val |= U2P_R0_DP_PULLDOWN;
-       val &= ~U2P_R0_ID_PULLUP;
+
+       switch (mode) {
+       case USB_DR_MODE_UNKNOWN:
+       case USB_DR_MODE_HOST:
+       case USB_DR_MODE_OTG:
+               val |= U2P_R0_DM_PULLDOWN;
+               val |= U2P_R0_DP_PULLDOWN;
+               val &= ~U2P_R0_ID_PULLUP;
+               break;
+
+       case USB_DR_MODE_PERIPHERAL:
+               val &= ~U2P_R0_DM_PULLDOWN;
+               val &= ~U2P_R0_DP_PULLDOWN;
+               val |= U2P_R0_ID_PULLUP;
+               break;
+       }
+
        regmap_write(priv->regmap, U2P_R0, val);
 
        phy_meson_gxl_usb2_reset(priv);
@@ -148,7 +165,7 @@ static int phy_meson_gxl_usb2_power_on(struct phy *phy)
        val &= ~U2P_R0_POWER_ON_RESET;
        regmap_write(priv->regmap, U2P_R0, val);
 
-       phy_meson_gxl_usb2_set_host_mode(priv);
+       phy_meson_gxl_usb2_set_mode(phy, USB_DR_MODE_HOST);
 
 #if CONFIG_IS_ENABLED(DM_REGULATOR)
        if (priv->phy_supply) {
@@ -195,7 +212,7 @@ int meson_gxl_usb2_phy_probe(struct udevice *dev)
        struct phy_meson_gxl_usb2_priv *priv = dev_get_priv(dev);
        int ret;
 
-       ret = regmap_init_mem(dev, &priv->regmap);
+       ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap);
        if (ret)
                return ret;