[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(&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},
 	{}
 };
 
-- 
1.9.1



More information about the U-Boot mailing list