Merge tag 'u-boot-atmel-fixes-2021.01-b' of https://gitlab.denx.de/u-boot/custodians...
[platform/kernel/u-boot.git] / drivers / phy / phy-stm32-usbphyc.c
index 8e98b4b..ab4a913 100644 (file)
@@ -9,11 +9,14 @@
 #include <dm.h>
 #include <fdtdec.h>
 #include <generic-phy.h>
+#include <log.h>
 #include <reset.h>
 #include <syscon.h>
 #include <usb.h>
 #include <asm/io.h>
+#include <dm/device_compat.h>
 #include <linux/bitops.h>
+#include <linux/delay.h>
 #include <power/regulator.h>
 
 /* USBPHYC registers */
@@ -37,7 +40,8 @@
 
 #define MAX_PHYS               2
 
-#define PLL_LOCK_TIME_US       100
+/* max 100 us for PLL lock and 100 us for PHY init */
+#define PLL_INIT_TIME_US       200
 #define PLL_PWR_DOWN_TIME_US   5
 #define PLL_FVCO               2880     /* in MHz */
 #define PLL_INFF_MIN_RATE      19200000 /* in Hz */
@@ -51,17 +55,18 @@ struct pll_params {
 struct stm32_usbphyc {
        fdt_addr_t base;
        struct clk clk;
+       struct udevice *vdda1v1;
+       struct udevice *vdda1v8;
        struct stm32_usbphyc_phy {
                struct udevice *vdd;
-               struct udevice *vdda1v1;
-               struct udevice *vdda1v8;
-               int index;
+               struct udevice *vbus;
                bool init;
                bool powered;
        } phys[MAX_PHYS];
 };
 
-void stm32_usbphyc_get_pll_params(u32 clk_rate, struct pll_params *pll_params)
+static void stm32_usbphyc_get_pll_params(u32 clk_rate,
+                                        struct pll_params *pll_params)
 {
        unsigned long long fvco, ndiv, frac;
 
@@ -154,6 +159,18 @@ static int stm32_usbphyc_phy_init(struct phy *phy)
        if (pllen && stm32_usbphyc_is_init(usbphyc))
                goto initialized;
 
+       if (usbphyc->vdda1v1) {
+               ret = regulator_set_enable(usbphyc->vdda1v1, true);
+               if (ret)
+                       return ret;
+       }
+
+       if (usbphyc->vdda1v8) {
+               ret = regulator_set_enable(usbphyc->vdda1v8, true);
+               if (ret)
+                       return ret;
+       }
+
        if (pllen) {
                clrbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
                udelay(PLL_PWR_DOWN_TIME_US);
@@ -165,11 +182,8 @@ static int stm32_usbphyc_phy_init(struct phy *phy)
 
        setbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
 
-       /*
-        * We must wait PLL_LOCK_TIME_US before checking that PLLEN
-        * bit is still set
-        */
-       udelay(PLL_LOCK_TIME_US);
+       /* We must wait PLL_INIT_TIME_US before using PHY */
+       udelay(PLL_INIT_TIME_US);
 
        if (!(readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN))
                return -EIO;
@@ -184,6 +198,7 @@ static int stm32_usbphyc_phy_exit(struct phy *phy)
 {
        struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
        struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
+       int ret;
 
        pr_debug("%s phy ID = %lu\n", __func__, phy->id);
        usbphyc_phy->init = false;
@@ -203,6 +218,18 @@ static int stm32_usbphyc_phy_exit(struct phy *phy)
        if (readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN)
                return -EIO;
 
+       if (usbphyc->vdda1v1) {
+               ret = regulator_set_enable(usbphyc->vdda1v1, false);
+               if (ret)
+                       return ret;
+       }
+
+       if (usbphyc->vdda1v8) {
+               ret = regulator_set_enable(usbphyc->vdda1v8, false);
+               if (ret)
+                       return ret;
+       }
+
        return 0;
 }
 
@@ -213,19 +240,13 @@ static int stm32_usbphyc_phy_power_on(struct phy *phy)
        int ret;
 
        pr_debug("%s phy ID = %lu\n", __func__, phy->id);
-       if (usbphyc_phy->vdda1v1) {
-               ret = regulator_set_enable(usbphyc_phy->vdda1v1, true);
-               if (ret)
-                       return ret;
-       }
-
-       if (usbphyc_phy->vdda1v8) {
-               ret = regulator_set_enable(usbphyc_phy->vdda1v8, true);
+       if (usbphyc_phy->vdd) {
+               ret = regulator_set_enable(usbphyc_phy->vdd, true);
                if (ret)
                        return ret;
        }
-       if (usbphyc_phy->vdd) {
-               ret = regulator_set_enable(usbphyc_phy->vdd, true);
+       if (usbphyc_phy->vbus) {
+               ret = regulator_set_enable(usbphyc_phy->vbus, true);
                if (ret)
                        return ret;
        }
@@ -247,20 +268,13 @@ static int stm32_usbphyc_phy_power_off(struct phy *phy)
        if (stm32_usbphyc_is_powered(usbphyc))
                return 0;
 
-       if (usbphyc_phy->vdda1v1) {
-               ret = regulator_set_enable(usbphyc_phy->vdda1v1, false);
-               if (ret)
-                       return ret;
-       }
-
-       if (usbphyc_phy->vdda1v8) {
-               ret = regulator_set_enable(usbphyc_phy->vdda1v8, false);
+       if (usbphyc_phy->vbus) {
+               ret = regulator_set_enable(usbphyc_phy->vbus, false);
                if (ret)
                        return ret;
        }
-
        if (usbphyc_phy->vdd) {
-               ret = regulator_set_enable(usbphyc_phy->vdd, false);
+               ret = regulator_set_enable_if_allowed(usbphyc_phy->vdd, false);
                if (ret)
                        return ret;
        }
@@ -268,7 +282,7 @@ static int stm32_usbphyc_phy_power_off(struct phy *phy)
        return 0;
 }
 
-static int stm32_usbphyc_get_regulator(struct udevice *dev, ofnode node,
+static int stm32_usbphyc_get_regulator(ofnode node,
                                       char *supply_name,
                                       struct udevice **regulator)
 {
@@ -278,19 +292,14 @@ static int stm32_usbphyc_get_regulator(struct udevice *dev, ofnode node,
        ret = ofnode_parse_phandle_with_args(node, supply_name,
                                             NULL, 0, 0,
                                             &regulator_phandle);
-       if (ret) {
-               dev_err(dev, "Can't find %s property (%d)\n", supply_name, ret);
+       if (ret)
                return ret;
-       }
 
        ret = uclass_get_device_by_ofnode(UCLASS_REGULATOR,
                                          regulator_phandle.node,
                                          regulator);
-
-       if (ret) {
-               dev_err(dev, "Can't get %s regulator (%d)\n", supply_name, ret);
+       if (ret)
                return ret;
-       }
 
        return 0;
 }
@@ -298,19 +307,20 @@ static int stm32_usbphyc_get_regulator(struct udevice *dev, ofnode node,
 static int stm32_usbphyc_of_xlate(struct phy *phy,
                                  struct ofnode_phandle_args *args)
 {
-       if (args->args_count > 1) {
-               pr_debug("%s: invalid args_count: %d\n", __func__,
-                        args->args_count);
-               return -EINVAL;
-       }
+       if (args->args_count < 1)
+               return -ENODEV;
 
        if (args->args[0] >= MAX_PHYS)
                return -ENODEV;
 
-       if (args->args_count)
-               phy->id = args->args[0];
-       else
-               phy->id = 0;
+       phy->id = args->args[0];
+
+       if ((phy->id == 0 && args->args_count != 1) ||
+           (phy->id == 1 && args->args_count != 2)) {
+               dev_err(phy->dev, "invalid number of cells for phy port%ld\n",
+                       phy->id);
+               return -EINVAL;
+       }
 
        return 0;
 }
@@ -351,6 +361,21 @@ static int stm32_usbphyc_probe(struct udevice *dev)
                reset_deassert(&reset);
        }
 
+       /* get usbphyc regulator */
+       ret = device_get_supply_regulator(dev, "vdda1v1-supply",
+                                         &usbphyc->vdda1v1);
+       if (ret) {
+               dev_err(dev, "Can't get vdda1v1-supply regulator\n");
+               return ret;
+       }
+
+       ret = device_get_supply_regulator(dev, "vdda1v8-supply",
+                                         &usbphyc->vdda1v8);
+       if (ret) {
+               dev_err(dev, "Can't get vdda1v8-supply regulator\n");
+               return ret;
+       }
+
        /*
         * parse all PHY subnodes in order to populate regulator associated
         * to each PHY port
@@ -359,23 +384,19 @@ static int stm32_usbphyc_probe(struct udevice *dev)
        for (i = 0; i < MAX_PHYS; i++) {
                struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + i;
 
-               usbphyc_phy->index = i;
                usbphyc_phy->init = false;
                usbphyc_phy->powered = false;
-               ret = stm32_usbphyc_get_regulator(dev, node, "phy-supply",
+               ret = stm32_usbphyc_get_regulator(node, "phy-supply",
                                                  &usbphyc_phy->vdd);
-               if (ret)
+               if (ret) {
+                       dev_err(dev, "Can't get phy-supply regulator\n");
                        return ret;
+               }
 
-               ret = stm32_usbphyc_get_regulator(dev, node, "vdda1v1-supply",
-                                                 &usbphyc_phy->vdda1v1);
+               ret = stm32_usbphyc_get_regulator(node, "vbus-supply",
+                                                 &usbphyc_phy->vbus);
                if (ret)
-                       return ret;
-
-               ret = stm32_usbphyc_get_regulator(dev, node, "vdda1v8-supply",
-                                                 &usbphyc_phy->vdda1v8);
-               if (ret)
-                       return ret;
+                       usbphyc_phy->vbus = NULL;
 
                node = dev_read_next_subnode(node);
        }