[U-Boot] [PATCH 05/11] clk: stm32f7: add STM32F4 support
patrice.chotard at st.com
patrice.chotard at st.com
Wed Nov 15 12:14:47 UTC 2017
From: Patrice Chotard <patrice.chotard at st.com>
STM32F4 and STM32F7 RCC clock IP are very similar.
Same driver can be used to managed RCC clock for
these 2 SoCs.
Differences between STM32F4 and F7 will be managed using
different compatible string :
_ overdrive clock is only supported by STM32F7
_ different sys_pll_psc parameters can be used between STM32F4
and STM32F7.
Signed-off-by: Patrice Chotard <patrice.chotard at st.com>
Reviewed-by: Vikas Manocha <vikas.manocha at st.com>
---
drivers/clk/clk_stm32f7.c | 109 ++++++++++++++++++++++++++++------------------
1 file changed, 66 insertions(+), 43 deletions(-)
diff --git a/drivers/clk/clk_stm32f7.c b/drivers/clk/clk_stm32f7.c
index eb8a5bf..4c69740 100644
--- a/drivers/clk/clk_stm32f7.c
+++ b/drivers/clk/clk_stm32f7.c
@@ -81,37 +81,51 @@ struct pll_psc {
#define APB_PSC_8 0x6
#define APB_PSC_16 0x7
+struct stm32_clk_info {
+ struct pll_psc sys_pll_psc;
+ bool has_overdrive;
+};
+
+struct stm32_clk_info stm32f4_clk_info = {
+ /* 180 MHz */
+ .sys_pll_psc = {
+ .pll_m = 8,
+ .pll_n = 360,
+ .pll_p = 2,
+ .pll_q = 8,
+ .ahb_psc = AHB_PSC_1,
+ .apb1_psc = APB_PSC_4,
+ .apb2_psc = APB_PSC_2,
+ },
+ .has_overdrive = false,
+};
+
+struct stm32_clk_info stm32f7_clk_info = {
+ /* 200 MHz */
+ .sys_pll_psc = {
+ .pll_m = 25,
+ .pll_n = 400,
+ .pll_p = 2,
+ .pll_q = 8,
+ .ahb_psc = AHB_PSC_1,
+ .apb1_psc = APB_PSC_4,
+ .apb2_psc = APB_PSC_2,
+ },
+ .has_overdrive = true,
+};
+
struct stm32_clk {
struct stm32_rcc_regs *base;
struct stm32_pwr_regs *pwr_regs;
+ struct stm32_clk_info *info;
};
-#if !defined(CONFIG_STM32_HSE_HZ)
-#error "CONFIG_STM32_HSE_HZ not defined!"
-#else
-#if (CONFIG_STM32_HSE_HZ == 25000000)
-#if (CONFIG_SYS_CLK_FREQ == 200000000)
-/* 200 MHz */
-struct pll_psc sys_pll_psc = {
- .pll_m = 25,
- .pll_n = 400,
- .pll_p = 2,
- .pll_q = 8,
- .ahb_psc = AHB_PSC_1,
- .apb1_psc = APB_PSC_4,
- .apb2_psc = APB_PSC_2
-};
-#endif
-#else
-#error "No PLL/Prescaler configuration for given CONFIG_STM32_HSE_HZ exists"
-#endif
-#endif
-
static int configure_clocks(struct udevice *dev)
{
struct stm32_clk *priv = dev_get_priv(dev);
struct stm32_rcc_regs *regs = priv->base;
struct stm32_pwr_regs *pwr = priv->pwr_regs;
+ struct pll_psc sys_pll_psc = priv->info->sys_pll_psc;
/* Reset RCC configuration */
setbits_le32(®s->cr, RCC_CR_HSION);
@@ -148,17 +162,23 @@ static int configure_clocks(struct udevice *dev)
while (!(readl(®s->cr) & RCC_CR_PLLRDY))
;
- /* Enable high performance mode, System frequency up to 200 MHz */
setbits_le32(®s->apb1enr, RCC_APB1ENR_PWREN);
- setbits_le32(&pwr->cr1, PWR_CR1_ODEN);
- /* Infinite wait! */
- while (!(readl(&pwr->csr1) & PWR_CSR1_ODRDY))
- ;
- /* Enable the Over-drive switch */
- setbits_le32(&pwr->cr1, PWR_CR1_ODSWEN);
- /* Infinite wait! */
- while (!(readl(&pwr->csr1) & PWR_CSR1_ODSWRDY))
- ;
+
+ if (priv->info->has_overdrive) {
+ /*
+ * Enable high performance mode
+ * System frequency up to 200 MHz
+ */
+ setbits_le32(&pwr->cr1, PWR_CR1_ODEN);
+ /* Infinite wait! */
+ while (!(readl(&pwr->csr1) & PWR_CSR1_ODRDY))
+ ;
+ /* Enable the Over-drive switch */
+ setbits_le32(&pwr->cr1, PWR_CR1_ODSWEN);
+ /* Infinite wait! */
+ while (!(readl(&pwr->csr1) & PWR_CSR1_ODSWRDY))
+ ;
+ }
stm32_flash_latency_cfg(5);
clrbits_le32(®s->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1));
@@ -273,22 +293,25 @@ static int stm32_clk_probe(struct udevice *dev)
struct stm32_clk *priv = dev_get_priv(dev);
fdt_addr_t addr;
- addr = devfdt_get_addr(dev);
+ addr = dev_read_addr(dev);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
priv->base = (struct stm32_rcc_regs *)addr;
-
- err = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0,
- &args);
- if (err) {
- debug("%s: can't find syscon device (%d)\n", __func__,
- err);
- return err;
+ priv->info = (struct stm32_clk_info *)dev_get_driver_data(dev);
+
+ if (priv->info->has_overdrive) {
+ err = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0,
+ &args);
+ if (err) {
+ debug("%s: can't find syscon device (%d)\n", __func__,
+ err);
+ return err;
+ }
+
+ priv->pwr_regs = (struct stm32_pwr_regs *)ofnode_get_addr(args.node);
}
- priv->pwr_regs = (struct stm32_pwr_regs *)ofnode_get_addr(args.node);
-
configure_clocks(dev);
return 0;
@@ -318,8 +341,8 @@ static struct clk_ops stm32_clk_ops = {
};
static const struct udevice_id stm32_clk_ids[] = {
- { .compatible = "st,stm32f42xx-rcc"},
- { .compatible = "st,stm32f746-rcc"},
+ { .compatible = "st,stm32f42xx-rcc", .data = (ulong)&stm32f4_clk_info},
+ { .compatible = "st,stm32f746-rcc", .data = (ulong)&stm32f7_clk_info},
{}
};
--
1.9.1
More information about the U-Boot
mailing list