X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=drivers%2Fphy%2Fphy-stm32-usbphyc.c;h=ab4a913c934420fff9a450ff1de1204d7219bd0a;hb=5a1a8a63be8f7262a300eddafb18020926b12fb6;hp=ec5b47c8a4e07f191fd40aef056de29469f95610;hpb=1655f2da8449db915fe414e3f88e64ad64f6a77a;p=platform%2Fkernel%2Fu-boot.git diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c index ec5b47c..ab4a913 100644 --- a/drivers/phy/phy-stm32-usbphyc.c +++ b/drivers/phy/phy-stm32-usbphyc.c @@ -9,11 +9,14 @@ #include #include #include +#include #include #include #include #include +#include #include +#include #include /* 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,16 +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; + 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; @@ -153,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); @@ -164,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; @@ -183,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; @@ -202,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; } @@ -212,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; } @@ -246,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 (usbphyc_phy->vbus) { + ret = regulator_set_enable(usbphyc_phy->vbus, false); if (ret) return ret; } - - if (usbphyc_phy->vdda1v8) { - ret = regulator_set_enable(usbphyc_phy->vdda1v8, 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; } @@ -267,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) { @@ -277,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, ®ulator_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; } @@ -307,7 +317,7 @@ static int stm32_usbphyc_of_xlate(struct phy *phy, if ((phy->id == 0 && args->args_count != 1) || (phy->id == 1 && args->args_count != 2)) { - dev_err(dev, "invalid number of cells for phy port%ld\n", + dev_err(phy->dev, "invalid number of cells for phy port%ld\n", phy->id); return -EINVAL; } @@ -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 @@ -361,20 +386,17 @@ static int stm32_usbphyc_probe(struct udevice *dev) 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) - return ret; - - ret = stm32_usbphyc_get_regulator(dev, node, "vdda1v1-supply", - &usbphyc_phy->vdda1v1); - if (ret) + if (ret) { + dev_err(dev, "Can't get phy-supply regulator\n"); return ret; + } - ret = stm32_usbphyc_get_regulator(dev, node, "vdda1v8-supply", - &usbphyc_phy->vdda1v8); + ret = stm32_usbphyc_get_regulator(node, "vbus-supply", + &usbphyc_phy->vbus); if (ret) - return ret; + usbphyc_phy->vbus = NULL; node = dev_read_next_subnode(node); }