1*624d2caeSTom Rini // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
23b291216SPatrice Chotard /*
33b291216SPatrice Chotard  * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
43b291216SPatrice Chotard  */
53b291216SPatrice Chotard 
63b291216SPatrice Chotard #include <common.h>
73b291216SPatrice Chotard #include <clk.h>
83b291216SPatrice Chotard #include <div64.h>
93b291216SPatrice Chotard #include <dm.h>
103b291216SPatrice Chotard #include <fdtdec.h>
113b291216SPatrice Chotard #include <generic-phy.h>
123b291216SPatrice Chotard #include <reset.h>
133b291216SPatrice Chotard #include <syscon.h>
143b291216SPatrice Chotard #include <usb.h>
153b291216SPatrice Chotard #include <asm/io.h>
163b291216SPatrice Chotard #include <linux/bitops.h>
173b291216SPatrice Chotard #include <power/regulator.h>
183b291216SPatrice Chotard 
193b291216SPatrice Chotard /* USBPHYC registers */
203b291216SPatrice Chotard #define STM32_USBPHYC_PLL	0x0
213b291216SPatrice Chotard #define STM32_USBPHYC_MISC	0x8
223b291216SPatrice Chotard 
233b291216SPatrice Chotard /* STM32_USBPHYC_PLL bit fields */
243b291216SPatrice Chotard #define PLLNDIV			GENMASK(6, 0)
253b291216SPatrice Chotard #define PLLNDIV_SHIFT		0
263b291216SPatrice Chotard #define PLLFRACIN		GENMASK(25, 10)
273b291216SPatrice Chotard #define PLLFRACIN_SHIFT		10
283b291216SPatrice Chotard #define PLLEN			BIT(26)
293b291216SPatrice Chotard #define PLLSTRB			BIT(27)
303b291216SPatrice Chotard #define PLLSTRBYP		BIT(28)
313b291216SPatrice Chotard #define PLLFRACCTL		BIT(29)
323b291216SPatrice Chotard #define PLLDITHEN0		BIT(30)
333b291216SPatrice Chotard #define PLLDITHEN1		BIT(31)
343b291216SPatrice Chotard 
353b291216SPatrice Chotard /* STM32_USBPHYC_MISC bit fields */
363b291216SPatrice Chotard #define SWITHOST		BIT(0)
373b291216SPatrice Chotard 
383b291216SPatrice Chotard #define MAX_PHYS		2
393b291216SPatrice Chotard 
403b291216SPatrice Chotard #define PLL_LOCK_TIME_US	100
413b291216SPatrice Chotard #define PLL_PWR_DOWN_TIME_US	5
423b291216SPatrice Chotard #define PLL_FVCO		2880	 /* in MHz */
433b291216SPatrice Chotard #define PLL_INFF_MIN_RATE	19200000 /* in Hz */
443b291216SPatrice Chotard #define PLL_INFF_MAX_RATE	38400000 /* in Hz */
453b291216SPatrice Chotard 
463b291216SPatrice Chotard struct pll_params {
473b291216SPatrice Chotard 	u8 ndiv;
483b291216SPatrice Chotard 	u16 frac;
493b291216SPatrice Chotard };
503b291216SPatrice Chotard 
513b291216SPatrice Chotard struct stm32_usbphyc {
523b291216SPatrice Chotard 	fdt_addr_t base;
533b291216SPatrice Chotard 	struct clk clk;
543b291216SPatrice Chotard 	struct stm32_usbphyc_phy {
553b291216SPatrice Chotard 		struct udevice *vdd;
563b291216SPatrice Chotard 		struct udevice *vdda1v1;
573b291216SPatrice Chotard 		struct udevice *vdda1v8;
583b291216SPatrice Chotard 		int index;
593b291216SPatrice Chotard 		bool init;
603b291216SPatrice Chotard 		bool powered;
613b291216SPatrice Chotard 	} phys[MAX_PHYS];
623b291216SPatrice Chotard };
633b291216SPatrice Chotard 
stm32_usbphyc_get_pll_params(u32 clk_rate,struct pll_params * pll_params)643b291216SPatrice Chotard void stm32_usbphyc_get_pll_params(u32 clk_rate, struct pll_params *pll_params)
653b291216SPatrice Chotard {
663b291216SPatrice Chotard 	unsigned long long fvco, ndiv, frac;
673b291216SPatrice Chotard 
683b291216SPatrice Chotard 	/*
693b291216SPatrice Chotard 	 *    | FVCO = INFF*2*(NDIV + FRACT/2^16 ) when DITHER_DISABLE[1] = 1
703b291216SPatrice Chotard 	 *    | FVCO = 2880MHz
713b291216SPatrice Chotard 	 *    | NDIV = integer part of input bits to set the LDF
723b291216SPatrice Chotard 	 *    | FRACT = fractional part of input bits to set the LDF
733b291216SPatrice Chotard 	 *  =>	PLLNDIV = integer part of (FVCO / (INFF*2))
743b291216SPatrice Chotard 	 *  =>	PLLFRACIN = fractional part of(FVCO / INFF*2) * 2^16
753b291216SPatrice Chotard 	 * <=>  PLLFRACIN = ((FVCO / (INFF*2)) - PLLNDIV) * 2^16
763b291216SPatrice Chotard 	 */
773b291216SPatrice Chotard 	fvco = (unsigned long long)PLL_FVCO * 1000000; /* In Hz */
783b291216SPatrice Chotard 
793b291216SPatrice Chotard 	ndiv = fvco;
803b291216SPatrice Chotard 	do_div(ndiv, (clk_rate * 2));
813b291216SPatrice Chotard 	pll_params->ndiv = (u8)ndiv;
823b291216SPatrice Chotard 
833b291216SPatrice Chotard 	frac = fvco * (1 << 16);
843b291216SPatrice Chotard 	do_div(frac, (clk_rate * 2));
853b291216SPatrice Chotard 	frac = frac - (ndiv * (1 << 16));
863b291216SPatrice Chotard 	pll_params->frac = (u16)frac;
873b291216SPatrice Chotard }
883b291216SPatrice Chotard 
stm32_usbphyc_pll_init(struct stm32_usbphyc * usbphyc)893b291216SPatrice Chotard static int stm32_usbphyc_pll_init(struct stm32_usbphyc *usbphyc)
903b291216SPatrice Chotard {
913b291216SPatrice Chotard 	struct pll_params pll_params;
923b291216SPatrice Chotard 	u32 clk_rate = clk_get_rate(&usbphyc->clk);
933b291216SPatrice Chotard 	u32 usbphyc_pll;
943b291216SPatrice Chotard 
953b291216SPatrice Chotard 	if ((clk_rate < PLL_INFF_MIN_RATE) || (clk_rate > PLL_INFF_MAX_RATE)) {
963b291216SPatrice Chotard 		pr_debug("%s: input clk freq (%dHz) out of range\n",
973b291216SPatrice Chotard 			 __func__, clk_rate);
983b291216SPatrice Chotard 		return -EINVAL;
993b291216SPatrice Chotard 	}
1003b291216SPatrice Chotard 
1013b291216SPatrice Chotard 	stm32_usbphyc_get_pll_params(clk_rate, &pll_params);
1023b291216SPatrice Chotard 
1033b291216SPatrice Chotard 	usbphyc_pll = PLLDITHEN1 | PLLDITHEN0 | PLLSTRBYP;
1043b291216SPatrice Chotard 	usbphyc_pll |= ((pll_params.ndiv << PLLNDIV_SHIFT) & PLLNDIV);
1053b291216SPatrice Chotard 
1063b291216SPatrice Chotard 	if (pll_params.frac) {
1073b291216SPatrice Chotard 		usbphyc_pll |= PLLFRACCTL;
1083b291216SPatrice Chotard 		usbphyc_pll |= ((pll_params.frac << PLLFRACIN_SHIFT)
1093b291216SPatrice Chotard 				 & PLLFRACIN);
1103b291216SPatrice Chotard 	}
1113b291216SPatrice Chotard 
1123b291216SPatrice Chotard 	writel(usbphyc_pll, usbphyc->base + STM32_USBPHYC_PLL);
1133b291216SPatrice Chotard 
1143b291216SPatrice Chotard 	pr_debug("%s: input clk freq=%dHz, ndiv=%d, frac=%d\n", __func__,
1153b291216SPatrice Chotard 		 clk_rate, pll_params.ndiv, pll_params.frac);
1163b291216SPatrice Chotard 
1173b291216SPatrice Chotard 	return 0;
1183b291216SPatrice Chotard }
1193b291216SPatrice Chotard 
stm32_usbphyc_is_init(struct stm32_usbphyc * usbphyc)1203b291216SPatrice Chotard static bool stm32_usbphyc_is_init(struct stm32_usbphyc *usbphyc)
1213b291216SPatrice Chotard {
1223b291216SPatrice Chotard 	int i;
1233b291216SPatrice Chotard 
1243b291216SPatrice Chotard 	for (i = 0; i < MAX_PHYS; i++) {
1253b291216SPatrice Chotard 		if (usbphyc->phys[i].init)
1263b291216SPatrice Chotard 			return true;
1273b291216SPatrice Chotard 	}
1283b291216SPatrice Chotard 
1293b291216SPatrice Chotard 	return false;
1303b291216SPatrice Chotard }
1313b291216SPatrice Chotard 
stm32_usbphyc_is_powered(struct stm32_usbphyc * usbphyc)1323b291216SPatrice Chotard static bool stm32_usbphyc_is_powered(struct stm32_usbphyc *usbphyc)
1333b291216SPatrice Chotard {
1343b291216SPatrice Chotard 	int i;
1353b291216SPatrice Chotard 
1363b291216SPatrice Chotard 	for (i = 0; i < MAX_PHYS; i++) {
1373b291216SPatrice Chotard 		if (usbphyc->phys[i].powered)
1383b291216SPatrice Chotard 			return true;
1393b291216SPatrice Chotard 	}
1403b291216SPatrice Chotard 
1413b291216SPatrice Chotard 	return false;
1423b291216SPatrice Chotard }
1433b291216SPatrice Chotard 
stm32_usbphyc_phy_init(struct phy * phy)1443b291216SPatrice Chotard static int stm32_usbphyc_phy_init(struct phy *phy)
1453b291216SPatrice Chotard {
1463b291216SPatrice Chotard 	struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
1473b291216SPatrice Chotard 	struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
1483b291216SPatrice Chotard 	bool pllen = readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN ?
1493b291216SPatrice Chotard 		     true : false;
1503b291216SPatrice Chotard 	int ret;
1513b291216SPatrice Chotard 
1523b291216SPatrice Chotard 	pr_debug("%s phy ID = %lu\n", __func__, phy->id);
1533b291216SPatrice Chotard 	/* Check if one phy port has already configured the pll */
1543b291216SPatrice Chotard 	if (pllen && stm32_usbphyc_is_init(usbphyc))
1553b291216SPatrice Chotard 		goto initialized;
1563b291216SPatrice Chotard 
1573b291216SPatrice Chotard 	if (pllen) {
1583b291216SPatrice Chotard 		clrbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
1593b291216SPatrice Chotard 		udelay(PLL_PWR_DOWN_TIME_US);
1603b291216SPatrice Chotard 	}
1613b291216SPatrice Chotard 
1623b291216SPatrice Chotard 	ret = stm32_usbphyc_pll_init(usbphyc);
1633b291216SPatrice Chotard 	if (ret)
1643b291216SPatrice Chotard 		return ret;
1653b291216SPatrice Chotard 
1663b291216SPatrice Chotard 	setbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
1673b291216SPatrice Chotard 
1683b291216SPatrice Chotard 	/*
1693b291216SPatrice Chotard 	 * We must wait PLL_LOCK_TIME_US before checking that PLLEN
1703b291216SPatrice Chotard 	 * bit is still set
1713b291216SPatrice Chotard 	 */
1723b291216SPatrice Chotard 	udelay(PLL_LOCK_TIME_US);
1733b291216SPatrice Chotard 
1743b291216SPatrice Chotard 	if (!(readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN))
1753b291216SPatrice Chotard 		return -EIO;
1763b291216SPatrice Chotard 
1773b291216SPatrice Chotard initialized:
1783b291216SPatrice Chotard 	usbphyc_phy->init = true;
1793b291216SPatrice Chotard 
1803b291216SPatrice Chotard 	return 0;
1813b291216SPatrice Chotard }
1823b291216SPatrice Chotard 
stm32_usbphyc_phy_exit(struct phy * phy)1833b291216SPatrice Chotard static int stm32_usbphyc_phy_exit(struct phy *phy)
1843b291216SPatrice Chotard {
1853b291216SPatrice Chotard 	struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
1863b291216SPatrice Chotard 	struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
1873b291216SPatrice Chotard 
1883b291216SPatrice Chotard 	pr_debug("%s phy ID = %lu\n", __func__, phy->id);
1893b291216SPatrice Chotard 	usbphyc_phy->init = false;
1903b291216SPatrice Chotard 
1913b291216SPatrice Chotard 	/* Check if other phy port requires pllen */
1923b291216SPatrice Chotard 	if (stm32_usbphyc_is_init(usbphyc))
1933b291216SPatrice Chotard 		return 0;
1943b291216SPatrice Chotard 
1953b291216SPatrice Chotard 	clrbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
1963b291216SPatrice Chotard 
1973b291216SPatrice Chotard 	/*
1983b291216SPatrice Chotard 	 * We must wait PLL_PWR_DOWN_TIME_US before checking that PLLEN
1993b291216SPatrice Chotard 	 * bit is still clear
2003b291216SPatrice Chotard 	 */
2013b291216SPatrice Chotard 	udelay(PLL_PWR_DOWN_TIME_US);
2023b291216SPatrice Chotard 
2033b291216SPatrice Chotard 	if (readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN)
2043b291216SPatrice Chotard 		return -EIO;
2053b291216SPatrice Chotard 
2063b291216SPatrice Chotard 	return 0;
2073b291216SPatrice Chotard }
2083b291216SPatrice Chotard 
stm32_usbphyc_phy_power_on(struct phy * phy)2093b291216SPatrice Chotard static int stm32_usbphyc_phy_power_on(struct phy *phy)
2103b291216SPatrice Chotard {
2113b291216SPatrice Chotard 	struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
2123b291216SPatrice Chotard 	struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
2133b291216SPatrice Chotard 	int ret;
2143b291216SPatrice Chotard 
2153b291216SPatrice Chotard 	pr_debug("%s phy ID = %lu\n", __func__, phy->id);
2163b291216SPatrice Chotard 	if (usbphyc_phy->vdda1v1) {
2173b291216SPatrice Chotard 		ret = regulator_set_enable(usbphyc_phy->vdda1v1, true);
2183b291216SPatrice Chotard 		if (ret)
2193b291216SPatrice Chotard 			return ret;
2203b291216SPatrice Chotard 	}
2213b291216SPatrice Chotard 
2223b291216SPatrice Chotard 	if (usbphyc_phy->vdda1v8) {
2233b291216SPatrice Chotard 		ret = regulator_set_enable(usbphyc_phy->vdda1v8, true);
2243b291216SPatrice Chotard 		if (ret)
2253b291216SPatrice Chotard 			return ret;
2263b291216SPatrice Chotard 	}
2273b291216SPatrice Chotard 	if (usbphyc_phy->vdd) {
2283b291216SPatrice Chotard 		ret = regulator_set_enable(usbphyc_phy->vdd, true);
2293b291216SPatrice Chotard 		if (ret)
2303b291216SPatrice Chotard 			return ret;
2313b291216SPatrice Chotard 	}
2323b291216SPatrice Chotard 
2333b291216SPatrice Chotard 	usbphyc_phy->powered = true;
2343b291216SPatrice Chotard 
2353b291216SPatrice Chotard 	return 0;
2363b291216SPatrice Chotard }
2373b291216SPatrice Chotard 
stm32_usbphyc_phy_power_off(struct phy * phy)2383b291216SPatrice Chotard static int stm32_usbphyc_phy_power_off(struct phy *phy)
2393b291216SPatrice Chotard {
2403b291216SPatrice Chotard 	struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
2413b291216SPatrice Chotard 	struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
2423b291216SPatrice Chotard 	int ret;
2433b291216SPatrice Chotard 
2443b291216SPatrice Chotard 	pr_debug("%s phy ID = %lu\n", __func__, phy->id);
2453b291216SPatrice Chotard 	usbphyc_phy->powered = false;
2463b291216SPatrice Chotard 
2473b291216SPatrice Chotard 	if (stm32_usbphyc_is_powered(usbphyc))
2483b291216SPatrice Chotard 		return 0;
2493b291216SPatrice Chotard 
2503b291216SPatrice Chotard 	if (usbphyc_phy->vdda1v1) {
2513b291216SPatrice Chotard 		ret = regulator_set_enable(usbphyc_phy->vdda1v1, false);
2523b291216SPatrice Chotard 		if (ret)
2533b291216SPatrice Chotard 			return ret;
2543b291216SPatrice Chotard 	}
2553b291216SPatrice Chotard 
2563b291216SPatrice Chotard 	if (usbphyc_phy->vdda1v8) {
2573b291216SPatrice Chotard 		ret = regulator_set_enable(usbphyc_phy->vdda1v8, false);
2583b291216SPatrice Chotard 		if (ret)
2593b291216SPatrice Chotard 			return ret;
2603b291216SPatrice Chotard 	}
2613b291216SPatrice Chotard 
2623b291216SPatrice Chotard 	if (usbphyc_phy->vdd) {
2633b291216SPatrice Chotard 		ret = regulator_set_enable(usbphyc_phy->vdd, false);
2643b291216SPatrice Chotard 		if (ret)
2653b291216SPatrice Chotard 			return ret;
2663b291216SPatrice Chotard 	}
2673b291216SPatrice Chotard 
2683b291216SPatrice Chotard 	return 0;
2693b291216SPatrice Chotard }
2703b291216SPatrice Chotard 
stm32_usbphyc_get_regulator(struct udevice * dev,ofnode node,char * supply_name,struct udevice ** regulator)2713b291216SPatrice Chotard static int stm32_usbphyc_get_regulator(struct udevice *dev, ofnode node,
2723b291216SPatrice Chotard 				       char *supply_name,
2733b291216SPatrice Chotard 				       struct udevice **regulator)
2743b291216SPatrice Chotard {
2753b291216SPatrice Chotard 	struct ofnode_phandle_args regulator_phandle;
2763b291216SPatrice Chotard 	int ret;
2773b291216SPatrice Chotard 
2783b291216SPatrice Chotard 	ret = ofnode_parse_phandle_with_args(node, supply_name,
2793b291216SPatrice Chotard 					     NULL, 0, 0,
2803b291216SPatrice Chotard 					     &regulator_phandle);
2813b291216SPatrice Chotard 	if (ret) {
2823b291216SPatrice Chotard 		dev_err(dev, "Can't find %s property (%d)\n", supply_name, ret);
2833b291216SPatrice Chotard 		return ret;
2843b291216SPatrice Chotard 	}
2853b291216SPatrice Chotard 
2863b291216SPatrice Chotard 	ret = uclass_get_device_by_ofnode(UCLASS_REGULATOR,
2873b291216SPatrice Chotard 					  regulator_phandle.node,
2883b291216SPatrice Chotard 					  regulator);
2893b291216SPatrice Chotard 
2903b291216SPatrice Chotard 	if (ret) {
2913b291216SPatrice Chotard 		dev_err(dev, "Can't get %s regulator (%d)\n", supply_name, ret);
2923b291216SPatrice Chotard 		return ret;
2933b291216SPatrice Chotard 	}
2943b291216SPatrice Chotard 
2953b291216SPatrice Chotard 	return 0;
2963b291216SPatrice Chotard }
2973b291216SPatrice Chotard 
stm32_usbphyc_of_xlate(struct phy * phy,struct ofnode_phandle_args * args)2983b291216SPatrice Chotard static int stm32_usbphyc_of_xlate(struct phy *phy,
2993b291216SPatrice Chotard 				  struct ofnode_phandle_args *args)
3003b291216SPatrice Chotard {
3013b291216SPatrice Chotard 	if (args->args_count > 1) {
3023b291216SPatrice Chotard 		pr_debug("%s: invalid args_count: %d\n", __func__,
3033b291216SPatrice Chotard 			 args->args_count);
3043b291216SPatrice Chotard 		return -EINVAL;
3053b291216SPatrice Chotard 	}
3063b291216SPatrice Chotard 
3073b291216SPatrice Chotard 	if (args->args[0] >= MAX_PHYS)
3083b291216SPatrice Chotard 		return -ENODEV;
3093b291216SPatrice Chotard 
3103b291216SPatrice Chotard 	if (args->args_count)
3113b291216SPatrice Chotard 		phy->id = args->args[0];
3123b291216SPatrice Chotard 	else
3133b291216SPatrice Chotard 		phy->id = 0;
3143b291216SPatrice Chotard 
3153b291216SPatrice Chotard 	return 0;
3163b291216SPatrice Chotard }
3173b291216SPatrice Chotard 
3183b291216SPatrice Chotard static const struct phy_ops stm32_usbphyc_phy_ops = {
3193b291216SPatrice Chotard 	.init = stm32_usbphyc_phy_init,
3203b291216SPatrice Chotard 	.exit = stm32_usbphyc_phy_exit,
3213b291216SPatrice Chotard 	.power_on = stm32_usbphyc_phy_power_on,
3223b291216SPatrice Chotard 	.power_off = stm32_usbphyc_phy_power_off,
3233b291216SPatrice Chotard 	.of_xlate = stm32_usbphyc_of_xlate,
3243b291216SPatrice Chotard };
3253b291216SPatrice Chotard 
stm32_usbphyc_probe(struct udevice * dev)3263b291216SPatrice Chotard static int stm32_usbphyc_probe(struct udevice *dev)
3273b291216SPatrice Chotard {
3283b291216SPatrice Chotard 	struct stm32_usbphyc *usbphyc = dev_get_priv(dev);
3293b291216SPatrice Chotard 	struct reset_ctl reset;
3303b291216SPatrice Chotard 	ofnode node;
3313b291216SPatrice Chotard 	int i, ret;
3323b291216SPatrice Chotard 
3333b291216SPatrice Chotard 	usbphyc->base = dev_read_addr(dev);
3343b291216SPatrice Chotard 	if (usbphyc->base == FDT_ADDR_T_NONE)
3353b291216SPatrice Chotard 		return -EINVAL;
3363b291216SPatrice Chotard 
3373b291216SPatrice Chotard 	/* Enable clock */
3383b291216SPatrice Chotard 	ret = clk_get_by_index(dev, 0, &usbphyc->clk);
3393b291216SPatrice Chotard 	if (ret)
3403b291216SPatrice Chotard 		return ret;
3413b291216SPatrice Chotard 
3423b291216SPatrice Chotard 	ret = clk_enable(&usbphyc->clk);
3433b291216SPatrice Chotard 	if (ret)
3443b291216SPatrice Chotard 		return ret;
3453b291216SPatrice Chotard 
3463b291216SPatrice Chotard 	/* Reset */
3473b291216SPatrice Chotard 	ret = reset_get_by_index(dev, 0, &reset);
3483b291216SPatrice Chotard 	if (!ret) {
3493b291216SPatrice Chotard 		reset_assert(&reset);
3503b291216SPatrice Chotard 		udelay(2);
3513b291216SPatrice Chotard 		reset_deassert(&reset);
3523b291216SPatrice Chotard 	}
3533b291216SPatrice Chotard 
3543b291216SPatrice Chotard 	/*
3553b291216SPatrice Chotard 	 * parse all PHY subnodes in order to populate regulator associated
3563b291216SPatrice Chotard 	 * to each PHY port
3573b291216SPatrice Chotard 	 */
3583b291216SPatrice Chotard 	node = dev_read_first_subnode(dev);
3593b291216SPatrice Chotard 	for (i = 0; i < MAX_PHYS; i++) {
3603b291216SPatrice Chotard 		struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + i;
3613b291216SPatrice Chotard 
3623b291216SPatrice Chotard 		usbphyc_phy->index = i;
3633b291216SPatrice Chotard 		usbphyc_phy->init = false;
3643b291216SPatrice Chotard 		usbphyc_phy->powered = false;
3653b291216SPatrice Chotard 		ret = stm32_usbphyc_get_regulator(dev, node, "phy-supply",
3663b291216SPatrice Chotard 						  &usbphyc_phy->vdd);
3673b291216SPatrice Chotard 		if (ret)
3683b291216SPatrice Chotard 			return ret;
3693b291216SPatrice Chotard 
3703b291216SPatrice Chotard 		ret = stm32_usbphyc_get_regulator(dev, node, "vdda1v1-supply",
3713b291216SPatrice Chotard 						  &usbphyc_phy->vdda1v1);
3723b291216SPatrice Chotard 		if (ret)
3733b291216SPatrice Chotard 			return ret;
3743b291216SPatrice Chotard 
3753b291216SPatrice Chotard 		ret = stm32_usbphyc_get_regulator(dev, node, "vdda1v8-supply",
3763b291216SPatrice Chotard 						  &usbphyc_phy->vdda1v8);
3773b291216SPatrice Chotard 		if (ret)
3783b291216SPatrice Chotard 			return ret;
3793b291216SPatrice Chotard 
3803b291216SPatrice Chotard 		node = dev_read_next_subnode(node);
3813b291216SPatrice Chotard 	}
3823b291216SPatrice Chotard 
3833b291216SPatrice Chotard 	/* Check if second port has to be used for host controller */
3843b291216SPatrice Chotard 	if (dev_read_bool(dev, "st,port2-switch-to-host"))
3853b291216SPatrice Chotard 		setbits_le32(usbphyc->base + STM32_USBPHYC_MISC, SWITHOST);
3863b291216SPatrice Chotard 
3873b291216SPatrice Chotard 	return 0;
3883b291216SPatrice Chotard }
3893b291216SPatrice Chotard 
3903b291216SPatrice Chotard static const struct udevice_id stm32_usbphyc_of_match[] = {
3913b291216SPatrice Chotard 	{ .compatible = "st,stm32mp1-usbphyc", },
3923b291216SPatrice Chotard 	{ },
3933b291216SPatrice Chotard };
3943b291216SPatrice Chotard 
3953b291216SPatrice Chotard U_BOOT_DRIVER(stm32_usb_phyc) = {
3963b291216SPatrice Chotard 	.name = "stm32-usbphyc",
3973b291216SPatrice Chotard 	.id = UCLASS_PHY,
3983b291216SPatrice Chotard 	.of_match = stm32_usbphyc_of_match,
3993b291216SPatrice Chotard 	.ops = &stm32_usbphyc_phy_ops,
4003b291216SPatrice Chotard 	.probe = stm32_usbphyc_probe,
4013b291216SPatrice Chotard 	.priv_auto_alloc_size = sizeof(struct stm32_usbphyc),
4023b291216SPatrice Chotard };
403