sifive: fu540: add ddr driver
[oweals/u-boot.git] / drivers / phy / meson-gxl-usb3.c
index a385fbdf126cae20fabe8471a711ff112df278d2..9de55bb5df0cbd0c0eff88b55e665f2813813f4b 100644 (file)
@@ -1,14 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Meson GXL USB3 PHY driver
  *
  * Copyright (C) 2018 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 <generic-phy.h>
 #include <regmap.h>
 #include <clk.h>
+#include <linux/usb/otg.h>
+
+#include <asm/arch/usb-gx.h>
 
 #include <linux/bitops.h>
 #include <linux/compat.h>
 #include <linux/bitfield.h>
 
-DECLARE_GLOBAL_DATA_PTR;
-
 #define USB_R0                                                 0x00
        #define USB_R0_P30_FSEL_MASK                            GENMASK(5, 0)
        #define USB_R0_P30_PHY_RESET                            BIT(6)
@@ -95,20 +96,35 @@ struct phy_meson_gxl_usb3_priv {
 #endif
 };
 
-static int
-phy_meson_gxl_usb3_set_host_mode(struct phy_meson_gxl_usb3_priv *priv)
+void phy_meson_gxl_usb3_set_mode(struct phy *phy, enum usb_dr_mode mode)
 {
+       struct udevice *dev = phy->dev;
+       struct phy_meson_gxl_usb3_priv *priv = dev_get_priv(dev);
        uint val;
 
-       regmap_read(priv->regmap, USB_R0, &val);
-       val &= ~USB_R0_U2D_ACT;
-       regmap_write(priv->regmap, USB_R0, val);
-
-       regmap_read(priv->regmap, USB_R4, &val);
-       val &= ~USB_R4_P21_SLEEP_M0;
-       regmap_write(priv->regmap, USB_R4, val);
-
-       return 0;
+       switch (mode) {
+       case USB_DR_MODE_UNKNOWN:
+       case USB_DR_MODE_HOST:
+       case USB_DR_MODE_OTG:
+               regmap_read(priv->regmap, USB_R0, &val);
+               val &= ~USB_R0_U2D_ACT;
+               regmap_write(priv->regmap, USB_R0, val);
+
+               regmap_read(priv->regmap, USB_R4, &val);
+               val &= ~USB_R4_P21_SLEEP_M0;
+               regmap_write(priv->regmap, USB_R4, val);
+               break;
+
+       case USB_DR_MODE_PERIPHERAL:
+               regmap_read(priv->regmap, USB_R0, &val);
+               val |= USB_R0_U2D_ACT;
+               regmap_write(priv->regmap, USB_R0, val);
+
+               regmap_read(priv->regmap, USB_R4, &val);
+               val |= USB_R4_P21_SLEEP_M0;
+               regmap_write(priv->regmap, USB_R4, val);
+               break;
+       }
 }
 
 static int phy_meson_gxl_usb3_power_on(struct phy *phy)
@@ -124,7 +140,9 @@ static int phy_meson_gxl_usb3_power_on(struct phy *phy)
        val |= FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff);
        regmap_write(priv->regmap, USB_R5, val);
 
-       return phy_meson_gxl_usb3_set_host_mode(priv);
+       phy_meson_gxl_usb3_set_mode(phy, USB_DR_MODE_HOST);
+
+       return 0;
 }
 
 static int phy_meson_gxl_usb3_power_off(struct phy *phy)
@@ -166,7 +184,7 @@ int meson_gxl_usb3_phy_probe(struct udevice *dev)
        struct phy_meson_gxl_usb3_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;