[U-Boot] [PATCH] 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
---
drivers/clk/clk_stm32f.c | 36 +++++++++++++++++++++++++----------- drivers/misc/stm32_rcc.c | 12 +++++++++--- include/stm32_rcc.h | 3 ++- 3 files changed, 36 insertions(+), 15 deletions(-)
diff --git a/drivers/clk/clk_stm32f.c b/drivers/clk/clk_stm32f.c index d8eab1a88d7c..b5773181e8fb 100644 --- a/drivers/clk/clk_stm32f.c +++ b/drivers/clk/clk_stm32f.c @@ -134,6 +134,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 @@ -180,8 +181,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); @@ -189,17 +194,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, @@ -207,18 +218,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) { @@ -618,12 +627,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)); diff --git a/drivers/misc/stm32_rcc.c b/drivers/misc/stm32_rcc.c index 87d9928362be..454a9cccfcc2 100644 --- a/drivers/misc/stm32_rcc.c +++ b/drivers/misc/stm32_rcc.c @@ -12,9 +12,14 @@ #include <dm/device-internal.h> #include <dm/lists.h>
-struct stm32_rcc_clk stm32_rcc_clk_f4 = { +struct stm32_rcc_clk stm32_rcc_clk_f42x = { .drv_name = "stm32fx_rcc_clock", - .soc = STM32F4, + .soc = STM32F42X, +}; + +struct stm32_rcc_clk stm32_rcc_clk_f469 = { + .drv_name = "stm32fx_rcc_clock", + .soc = STM32F469, };
struct stm32_rcc_clk stm32_rcc_clk_f7 = { @@ -62,7 +67,8 @@ static const struct misc_ops stm32_rcc_ops = { };
static const struct udevice_id stm32_rcc_ids[] = { - {.compatible = "st,stm32f42xx-rcc", .data = (ulong)&stm32_rcc_clk_f4 }, + {.compatible = "st,stm32f42xx-rcc", .data = (ulong)&stm32_rcc_clk_f42x }, + {.compatible = "st,stm32f469-rcc", .data = (ulong)&stm32_rcc_clk_f469 }, {.compatible = "st,stm32f746-rcc", .data = (ulong)&stm32_rcc_clk_f7 }, {.compatible = "st,stm32h743-rcc", .data = (ulong)&stm32_rcc_clk_h7 }, { } diff --git a/include/stm32_rcc.h b/include/stm32_rcc.h index 484bc305f9c0..5cfbec0f15a1 100644 --- a/include/stm32_rcc.h +++ b/include/stm32_rcc.h @@ -41,7 +41,8 @@ struct stm32_clk_info { };
enum soc_family { - STM32F4, + STM32F42X, + STM32F469, STM32F7, };

On Wed, Apr 11, 2018 at 05:07:45PM +0200, Patrice Chotard wrote:
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
Applied to u-boot/master, thanks!
participants (2)
-
Patrice Chotard
-
Tom Rini