[U-Boot] [RESEND][PATCH v1] phy: add support for STM32 usb phy controller
Marek Vasut
marek.vasut at gmail.com
Thu Apr 26 15:13:02 UTC 2018
On 04/26/2018 04:23 PM, Patrice Chotard wrote:
> From: Christophe Kerello <christophe.kerello at st.com>
>
> 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 <christophe.kerello at st.com>
> Signed-off-by: Patrice Chotard <patrice.chotard at st.com>
[...]
> +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 ?
> +};
> +
> +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
> + clk_rate, pll_params.ndiv, pll_params.frac);
> +
> + return 0;
> +}
[...]
--
Best regards,
Marek Vasut
More information about the U-Boot
mailing list