Hi Marek On 04/26/2018 05:13 PM, Marek Vasut wrote: > On 04/26/2018 04:23 PM, Patrice Chotard wrote: >> From: Christophe Kerello <[email protected]> >> >> This patch adds phy tranceiver driver for STM32 USB PHY >> Controller (usbphyc) that provides dual port High-Speed >> phy for OTG (single port) and EHCI/OHCI host controller >> (two ports). >> One port of the phy is shared between the two USB controllers >> through a UTMI+ switch. >> >> Signed-off-by: Christophe Kerello <[email protected]> >> Signed-off-by: Patrice Chotard <[email protected]> > > [...] > >> +struct pll_params { >> + u8 ndiv; >> + u16 frac; >> +}; >> + >> +struct stm32_usbphyc { >> + fdt_addr_t base; >> + struct clk clk; >> + struct stm32_usbphyc_phy { >> + struct udevice *vdd; >> + struct udevice *vdda1v1; >> + struct udevice *vdda1v8; >> + int index; >> + bool init; >> + bool powered; >> + } phys[MAX_PHYS]; > > Shouldn't there be one driver instance per PHY ?
This driver manages a PHY provider + PHY child sub nodes as requested by Kernel maintainer. more details here : https://lkml.org/lkml/2018/3/2/670 If you want i can add more details in v2 by including the DT bindings documentation ? > >> +}; >> + >> +void stm32_usbphyc_get_pll_params(u32 clk_rate, struct pll_params >> *pll_params) >> +{ >> + unsigned long long fvco, ndiv, frac; >> + >> + /* >> + * | FVCO = INFF*2*(NDIV + FRACT/2^16 ) when DITHER_DISABLE[1] = 1 >> + * | FVCO = 2880MHz >> + * | NDIV = integer part of input bits to set the LDF >> + * | FRACT = fractional part of input bits to set the LDF >> + * => PLLNDIV = integer part of (FVCO / (INFF*2)) >> + * => PLLFRACIN = fractional part of(FVCO / INFF*2) * 2^16 >> + * <=> PLLFRACIN = ((FVCO / (INFF*2)) - PLLNDIV) * 2^16 >> + */ >> + fvco = (unsigned long long)PLL_FVCO * 1000000; /* In Hz */ >> + >> + ndiv = fvco; >> + do_div(ndiv, (clk_rate * 2)); >> + pll_params->ndiv = (u8)ndiv; >> + >> + frac = fvco * (1 << 16); >> + do_div(frac, (clk_rate * 2)); >> + frac = frac - (ndiv * (1 << 16)); >> + pll_params->frac = (u16)frac; >> +} >> + >> +static int stm32_usbphyc_pll_init(struct stm32_usbphyc *usbphyc) >> +{ >> + struct pll_params pll_params; >> + u32 clk_rate = clk_get_rate(&usbphyc->clk); >> + u32 usbphyc_pll; >> + >> + if ((clk_rate < PLL_INFF_MIN_RATE) || (clk_rate > PLL_INFF_MAX_RATE)) { >> + pr_debug("%s: input clk freq (%dHz) out of range\n", >> + __func__, clk_rate); >> + return -EINVAL; >> + } >> + >> + stm32_usbphyc_get_pll_params(clk_rate, &pll_params); >> + >> + usbphyc_pll = PLLDITHEN1 | PLLDITHEN0 | PLLSTRBYP; >> + usbphyc_pll |= ((pll_params.ndiv << PLLNDIV_SHIFT) & PLLNDIV); >> + >> + if (pll_params.frac) { >> + usbphyc_pll |= PLLFRACCTL; >> + usbphyc_pll |= ((pll_params.frac << PLLFRACIN_SHIFT) >> + & PLLFRACIN); >> + } >> + >> + writel(usbphyc_pll, usbphyc->base + STM32_USBPHYC_PLL); >> + >> + pr_debug("%s: input clk freq=%dHz, ndiv=%d, frac=%d\n", __func__, > > dev_dbg There's no access to udevice struct here that's why pr_debug() is used. Thanks > >> + clk_rate, pll_params.ndiv, pll_params.frac); >> + >> + return 0; >> +} > [...] > _______________________________________________ U-Boot mailing list [email protected] https://lists.denx.de/listinfo/u-boot

