[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