summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorPatrice Chotard <patrice.chotard@st.com>2018-04-11 17:07:45 +0200
committerTom Rini <trini@konsulko.com>2018-05-08 09:07:34 -0400
commit8b41464547330a39cc7e0ef87a5dd8f34db324e1 (patch)
treeea0eb1eb7e28a3dba811bed5f1532a3acc2e296a /drivers
parent274fb461f4792431b3777874472c8bd6149e6168 (diff)
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')
-rw-r--r--drivers/clk/clk_stm32f.c36
-rw-r--r--drivers/misc/stm32_rcc.c12
2 files changed, 34 insertions, 14 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(&regs->dckcfgr2, RCC_DCKCFGRX_CK48MSEL);
+ if (priv->pllsaip)
+ /* select PLLSAIP as 48MHz clock source */
+ setbits_le32(&regs->dckcfgr2, RCC_DCKCFGRX_CK48MSEL);
+ else
+ /* select PLLQ as 48MHz clock source */
+ clrbits_le32(&regs->dckcfgr2, RCC_DCKCFGRX_CK48MSEL);
/* select 48MHz as SDMMC1 clock source */
clrbits_le32(&regs->dckcfgr2, RCC_DCKCFGRX_SDMMC1SEL);
@@ -188,17 +193,23 @@ static int configure_clocks(struct udevice *dev)
/* select 48MHz as SDMMC2 clock source */
clrbits_le32(&regs->dckcfgr2, RCC_DCKCFGR2_SDMMC2SEL);
} else { /* stm32f4 case */
- /* select PLLQ as 48MHz clock source */
- clrbits_le32(&regs->dckcfgr, RCC_DCKCFGRX_CK48MSEL);
+ if (priv->pllsaip)
+ /* select PLLSAIP as 48MHz clock source */
+ setbits_le32(&regs->dckcfgr, RCC_DCKCFGRX_CK48MSEL);
+ else
+ /* select PLLQ as 48MHz clock source */
+ clrbits_le32(&regs->dckcfgr, RCC_DCKCFGRX_CK48MSEL);
/* select 48MHz as SDMMC1 clock source */
clrbits_le32(&regs->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(&regs->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIP_MASK,
+ RCC_PLLSAICFGR_PLLSAIP_4);
clrsetbits_le32(&regs->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIR_MASK,
RCC_PLLSAICFGR_PLLSAIR_3);
clrsetbits_le32(&regs->pllsaicfgr, RCC_PLLSAICFGR_PLLSAIN_MASK,
@@ -206,18 +217,16 @@ static int configure_clocks(struct udevice *dev)
clrsetbits_le32(&regs->dckcfgr, RCC_DCKCFGR_PLLSAIDIVR_MASK,
RCC_DCKCFGR_PLLSAIDIVR_2 << RCC_DCKCFGR_PLLSAIDIVR_SHIFT);
-#endif
+
/* Enable the main PLL */
setbits_le32(&regs->cr, RCC_CR_PLLON);
while (!(readl(&regs->cr) & RCC_CR_PLLRDY))
;
-#ifdef CONFIG_VIDEO_STM32
-/* Enable the SAI PLL */
+ /* Enable the SAI PLL */
setbits_le32(&regs->cr, RCC_CR_PLLSAION);
while (!(readl(&regs->cr) & RCC_CR_PLLSAIRDY))
;
-#endif
setbits_le32(&regs->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));
diff --git a/drivers/misc/stm32_rcc.c b/drivers/misc/stm32_rcc.c
index b436900d7c..dee82c0b7b 100644
--- a/drivers/misc/stm32_rcc.c
+++ b/drivers/misc/stm32_rcc.c
@@ -11,9 +11,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 = {
@@ -61,7 +66,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 },
{ }