mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-27 17:41:34 +00:00
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
1 changed files with 65 additions and 42 deletions
|
@ -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;
|
||||
priv->info = (struct stm32_clk_info *)dev_get_driver_data(dev);
|
||||
|
||||
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;
|
||||
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},
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue