Hi Patrick On 4/26/22 14:37, Patrick Delaunay wrote: > ck_usbo_48m is generated by usbphyc PLL and used by OTG controller > for Full-Speed use cases with dedicated Full-Speed transceiver. > > ck_usbo_48m is available as soon as the PLL is enabled. > > Signed-off-by: Patrick Delaunay <patrick.delau...@foss.st.com> > --- > > drivers/phy/phy-stm32-usbphyc.c | 79 +++++++++++++++++++++++++++++++++ > 1 file changed, 79 insertions(+) > > diff --git a/drivers/phy/phy-stm32-usbphyc.c b/drivers/phy/phy-stm32-usbphyc.c > index 16c8799eca..e0b8fcb8f2 100644 > --- a/drivers/phy/phy-stm32-usbphyc.c > +++ b/drivers/phy/phy-stm32-usbphyc.c > @@ -7,6 +7,7 @@ > > #include <common.h> > #include <clk.h> > +#include <clk-uclass.h> > #include <div64.h> > #include <dm.h> > #include <fdtdec.h> > @@ -17,6 +18,7 @@ > #include <usb.h> > #include <asm/io.h> > #include <dm/device_compat.h> > +#include <dm/lists.h> > #include <linux/bitops.h> > #include <linux/delay.h> > #include <power/regulator.h> > @@ -49,6 +51,9 @@ > #define PLL_INFF_MIN_RATE 19200000 /* in Hz */ > #define PLL_INFF_MAX_RATE 38400000 /* in Hz */ > > +/* USBPHYC_CLK48 */ > +#define USBPHYC_CLK48_FREQ 48000000 /* in Hz */ > + > struct pll_params { > u8 ndiv; > u16 frac; > @@ -355,6 +360,16 @@ static const struct phy_ops stm32_usbphyc_phy_ops = { > .of_xlate = stm32_usbphyc_of_xlate, > }; > > +static int stm32_usbphyc_bind(struct udevice *dev) > +{ > + int ret; > + > + ret = device_bind_driver_to_node(dev, "stm32-usbphyc-clk", > "ck_usbo_48m", > + dev_ofnode(dev), NULL); > + > + return log_ret(ret); > +} > + > static int stm32_usbphyc_probe(struct udevice *dev) > { > struct stm32_usbphyc *usbphyc = dev_get_priv(dev); > @@ -444,6 +459,70 @@ U_BOOT_DRIVER(stm32_usb_phyc) = { > .id = UCLASS_PHY, > .of_match = stm32_usbphyc_of_match, > .ops = &stm32_usbphyc_phy_ops, > + .bind = stm32_usbphyc_bind, > .probe = stm32_usbphyc_probe, > .priv_auto = sizeof(struct stm32_usbphyc), > }; > + > +struct stm32_usbphyc_clk { > + bool enable; > +}; > + > +static ulong stm32_usbphyc_clk48_get_rate(struct clk *clk) > +{ > + return USBPHYC_CLK48_FREQ; > +} > + > +static int stm32_usbphyc_clk48_enable(struct clk *clk) > +{ > + struct stm32_usbphyc_clk *usbphyc_clk = dev_get_priv(clk->dev); > + struct stm32_usbphyc *usbphyc; > + int ret; > + > + if (usbphyc_clk->enable) > + return 0; > + > + usbphyc = dev_get_priv(clk->dev->parent); > + > + /* ck_usbo_48m is generated by usbphyc PLL */ > + ret = stm32_usbphyc_pll_enable(usbphyc); > + if (ret) > + return ret; > + > + usbphyc_clk->enable = true; > + > + return 0; > +} > + > +static int stm32_usbphyc_clk48_disable(struct clk *clk) > +{ > + struct stm32_usbphyc_clk *usbphyc_clk = dev_get_priv(clk->dev); > + struct stm32_usbphyc *usbphyc; > + int ret; > + > + if (!usbphyc_clk->enable) > + return 0; > + > + usbphyc = dev_get_priv(clk->dev->parent); > + > + ret = stm32_usbphyc_pll_disable(usbphyc); > + if (ret) > + return ret; > + > + usbphyc_clk->enable = false; > + > + return 0; > +} > + > +const struct clk_ops usbphyc_clk48_ops = { > + .get_rate = stm32_usbphyc_clk48_get_rate, > + .enable = stm32_usbphyc_clk48_enable, > + .disable = stm32_usbphyc_clk48_disable, > +}; > + > +U_BOOT_DRIVER(stm32_usb_phyc_clk) = { > + .name = "stm32-usbphyc-clk", > + .id = UCLASS_CLK, > + .ops = &usbphyc_clk48_ops, > + .priv_auto = sizeof(struct stm32_usbphyc_clk), > +};
Reviewed-by: Patrice Chotard <patrice.chot...@foss.st.com> Thanks PAtrice