clk: stm32f7: add STM32F4 support
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>
This commit is contained in:
parent
1555903c8d
commit
f9333c93c8
@ -81,37 +81,51 @@ struct pll_psc {
|
|||||||
#define APB_PSC_8 0x6
|
#define APB_PSC_8 0x6
|
||||||
#define APB_PSC_16 0x7
|
#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_clk {
|
||||||
struct stm32_rcc_regs *base;
|
struct stm32_rcc_regs *base;
|
||||||
struct stm32_pwr_regs *pwr_regs;
|
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)
|
static int configure_clocks(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct stm32_clk *priv = dev_get_priv(dev);
|
struct stm32_clk *priv = dev_get_priv(dev);
|
||||||
struct stm32_rcc_regs *regs = priv->base;
|
struct stm32_rcc_regs *regs = priv->base;
|
||||||
struct stm32_pwr_regs *pwr = priv->pwr_regs;
|
struct stm32_pwr_regs *pwr = priv->pwr_regs;
|
||||||
|
struct pll_psc sys_pll_psc = priv->info->sys_pll_psc;
|
||||||
|
|
||||||
/* Reset RCC configuration */
|
/* Reset RCC configuration */
|
||||||
setbits_le32(®s->cr, RCC_CR_HSION);
|
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))
|
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(®s->apb1enr, RCC_APB1ENR_PWREN);
|
||||||
setbits_le32(&pwr->cr1, PWR_CR1_ODEN);
|
|
||||||
/* Infinite wait! */
|
if (priv->info->has_overdrive) {
|
||||||
while (!(readl(&pwr->csr1) & PWR_CSR1_ODRDY))
|
/*
|
||||||
;
|
* Enable high performance mode
|
||||||
/* Enable the Over-drive switch */
|
* System frequency up to 200 MHz
|
||||||
setbits_le32(&pwr->cr1, PWR_CR1_ODSWEN);
|
*/
|
||||||
/* Infinite wait! */
|
setbits_le32(&pwr->cr1, PWR_CR1_ODEN);
|
||||||
while (!(readl(&pwr->csr1) & PWR_CSR1_ODSWRDY))
|
/* 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);
|
stm32_flash_latency_cfg(5);
|
||||||
clrbits_le32(®s->cfgr, (RCC_CFGR_SW0 | RCC_CFGR_SW1));
|
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);
|
struct stm32_clk *priv = dev_get_priv(dev);
|
||||||
fdt_addr_t addr;
|
fdt_addr_t addr;
|
||||||
|
|
||||||
addr = devfdt_get_addr(dev);
|
addr = dev_read_addr(dev);
|
||||||
if (addr == FDT_ADDR_T_NONE)
|
if (addr == FDT_ADDR_T_NONE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
priv->base = (struct stm32_rcc_regs *)addr;
|
priv->base = (struct stm32_rcc_regs *)addr;
|
||||||
|
priv->info = (struct stm32_clk_info *)dev_get_driver_data(dev);
|
||||||
|
|
||||||
err = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0,
|
if (priv->info->has_overdrive) {
|
||||||
&args);
|
err = dev_read_phandle_with_args(dev, "st,syscfg", NULL, 0, 0,
|
||||||
if (err) {
|
&args);
|
||||||
debug("%s: can't find syscon device (%d)\n", __func__,
|
if (err) {
|
||||||
err);
|
debug("%s: can't find syscon device (%d)\n", __func__,
|
||||||
return err;
|
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);
|
configure_clocks(dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -318,8 +341,8 @@ static struct clk_ops stm32_clk_ops = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct udevice_id stm32_clk_ids[] = {
|
static const struct udevice_id stm32_clk_ids[] = {
|
||||||
{ .compatible = "st,stm32f42xx-rcc"},
|
{ .compatible = "st,stm32f42xx-rcc", .data = (ulong)&stm32f4_clk_info},
|
||||||
{ .compatible = "st,stm32f746-rcc"},
|
{ .compatible = "st,stm32f746-rcc", .data = (ulong)&stm32f7_clk_info},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user