]> git.sur5r.net Git - u-boot/commitdiff
clk: stm32f7: add STM32F4 support
authorPatrice Chotard <patrice.chotard@st.com>
Wed, 15 Nov 2017 12:14:47 +0000 (13:14 +0100)
committerTom Rini <trini@konsulko.com>
Thu, 30 Nov 2017 03:30:50 +0000 (22:30 -0500)
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@st.com>
Reviewed-by: Vikas Manocha <vikas.manocha@st.com>
drivers/clk/clk_stm32f7.c

index eb8a5bf10d2a2452ba98e5e0ce17b91550bfdc5e..4c69740f73e4e80026ad91abd6f069113c3e1174 100644 (file)
@@ -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(&regs->cr, RCC_CR_HSION);
@@ -148,17 +162,23 @@ static int configure_clocks(struct udevice *dev)
        while (!(readl(&regs->cr) & RCC_CR_PLLRDY))
                ;
 
-       /* Enable high performance mode, System frequency up to 200 MHz */
        setbits_le32(&regs->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(&regs->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},
        {}
 };