diff options
author | Patrice Chotard <patrice.chotard@st.com> | 2018-04-11 17:07:45 +0200 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2018-05-08 09:07:34 -0400 |
commit | 8b41464547330a39cc7e0ef87a5dd8f34db324e1 (patch) | |
tree | ea0eb1eb7e28a3dba811bed5f1532a3acc2e296a /drivers/clk | |
parent | 274fb461f4792431b3777874472c8bd6149e6168 (diff) | |
download | u-boot-8b41464547330a39cc7e0ef87a5dd8f34db324e1.tar.gz |
clk: clk_stm32f: Use PLLSAIP as USB 48MHz clock
On all STM32F4 and F7 SoCs family (except STM32F429), PLLSAI
output P can be used as 48MHz clock source for USB and SDMMC.
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Tested By: Bruno Herrera <bruherrera@gmail.com>
Diffstat (limited to 'drivers/clk')
-rw-r--r-- | drivers/clk/clk_stm32f.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/drivers/clk/clk_stm32f.c b/drivers/clk/clk_stm32f.c index 6c1e2575ff..cbcfe3a89d 100644 --- a/drivers/clk/clk_stm32f.c +++ b/drivers/clk/clk_stm32f.c @@ -133,6 +133,7 @@ struct stm32_clk { struct stm32_pwr_regs *pwr_regs; struct stm32_clk_info info; unsigned long hse_rate; + bool pllsaip; }; #ifdef CONFIG_VIDEO_STM32 @@ -179,8 +180,12 @@ static int configure_clocks(struct udevice *dev) /* configure SDMMC clock */ if (priv->info.v2) { /*stm32f7 case */ - /* select PLLQ as 48MHz clock source */ - clrbits_le32(®s->dckcfgr2, RCC_DCKCFGRX_CK48MSEL); + if (priv->pllsaip) + /* select PLLSAIP as 48MHz clock source */ + setbits_le32(®s->dckcfgr2, RCC_DCKCFGRX_CK48MSEL); + else + /* select PLLQ as 48MHz clock source */ + clrbits_le32(®s->dckcfgr2, RCC_DCKCFGRX_CK48MSEL); /* select 48MHz as SDMMC1 clock source */ clrbits_le32(®s->dckcfgr2, RCC_DCKCFGRX_SDMMC1SEL); @@ -188,17 +193,23 @@ static int configure_clocks(struct udevice *dev) /* select 48MHz as SDMMC2 clock source */ clrbits_le32(®s->dckcfgr2, RCC_DCKCFGR2_SDMMC2SEL); } else { /* stm32f4 case */ - /* select PLLQ as 48MHz clock source */ - clrbits_le32(®s->dckcfgr, RCC_DCKCFGRX_CK48MSEL); + if (priv->pllsaip) + /* select PLLSAIP as 48MHz clock source */ + setbits_le32(®s->dckcfgr, RCC_DCKCFGRX_CK48MSEL); + else + /* select PLLQ as 48MHz clock source */ + clrbits_le32(®s->dckcfgr, RCC_DCKCFGRX_CK48MSEL); /* select 48MHz as SDMMC1 clock source */ clrbits_le32(®s->dckcfgr, RCC_DCKCFGRX_SDMMC1SEL); } -#ifdef CONFIG_VIDEO_STM32 /* - * Configure the SAI PLL to generate LTDC pixel clock + * Configure the SAI PLL to generate LTDC pixel clock and + * 48 Mhz for SDMMC and USB */ + clrsetbits_le32(®s->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIP_MASK, + RCC_PLLSAICFGR_PLLSAIP_4); clrsetbits_le32(®s->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIR_MASK, RCC_PLLSAICFGR_PLLSAIR_3); clrsetbits_le32(®s->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIN_MASK, @@ -206,18 +217,16 @@ static int configure_clocks(struct udevice *dev) clrsetbits_le32(®s->dckcfgr, RCC_DCKCFGR_PLLSAIDIVR_MASK, RCC_DCKCFGR_PLLSAIDIVR_2 << RCC_DCKCFGR_PLLSAIDIVR_SHIFT); -#endif + /* Enable the main PLL */ setbits_le32(®s->cr, RCC_CR_PLLON); while (!(readl(®s->cr) & RCC_CR_PLLRDY)) ; -#ifdef CONFIG_VIDEO_STM32 -/* Enable the SAI PLL */ + /* Enable the SAI PLL */ setbits_le32(®s->cr, RCC_CR_PLLSAION); while (!(readl(®s->cr) & RCC_CR_PLLSAIRDY)) ; -#endif setbits_le32(®s->apb1enr, RCC_APB1ENR_PWREN); if (priv->info.has_overdrive) { @@ -617,12 +626,17 @@ static int stm32_clk_probe(struct udevice *dev) return -EINVAL; priv->base = (struct stm32_rcc_regs *)addr; + priv->pllsaip = true; switch (dev_get_driver_data(dev)) { - case STM32F4: + case STM32F42X: + priv->pllsaip = false; + /* fallback into STM32F469 case */ + case STM32F469: memcpy(&priv->info, &stm32f4_clk_info, sizeof(struct stm32_clk_info)); break; + case STM32F7: memcpy(&priv->info, &stm32f7_clk_info, sizeof(struct stm32_clk_info)); |