From 288f17e6481d556cd9eff62ca64b4d4c5863fd9e Mon Sep 17 00:00:00 2001 From: Patrice Chotard Date: Tue, 18 Jul 2017 09:29:05 +0200 Subject: [PATCH] clk: stm32f7: add clock .get_rate() callback Add clock framework .get_rate callback. This step will allow to convert all drivers which was using proprietary clock_get() to use clock framework .get_rate(). Signed-off-by: Patrice Chotard Acked-by: Vikas MANOCHA --- arch/arm/include/asm/arch-stm32f7/rcc.h | 2 + drivers/clk/clk_stm32f7.c | 62 +++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/arch/arm/include/asm/arch-stm32f7/rcc.h b/arch/arm/include/asm/arch-stm32f7/rcc.h index 0f8d50b4c6..cc9b57f803 100644 --- a/arch/arm/include/asm/arch-stm32f7/rcc.h +++ b/arch/arm/include/asm/arch-stm32f7/rcc.h @@ -8,6 +8,8 @@ #ifndef _STM32_RCC_H #define _STM32_RCC_H +#include + /* * RCC AHB1ENR specific definitions */ diff --git a/drivers/clk/clk_stm32f7.c b/drivers/clk/clk_stm32f7.c index 7dd91b6a58..5e20b0cbb7 100644 --- a/drivers/clk/clk_stm32f7.c +++ b/drivers/clk/clk_stm32f7.c @@ -12,6 +12,8 @@ #include #include +#include + #define RCC_CR_HSION BIT(0) #define RCC_CR_HSEON BIT(16) #define RCC_CR_HSERDY BIT(17) @@ -220,6 +222,65 @@ unsigned long clock_get(enum clock clck) } } +static unsigned long stm32_clk_get_rate(struct clk *clk) +{ + struct stm32_clk *priv = dev_get_priv(clk->dev); + struct stm32_rcc_regs *regs = priv->base; + u32 sysclk = 0; + u32 shift = 0; + /* Prescaler table lookups for clock computation */ + u8 ahb_psc_table[16] = { + 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9 + }; + u8 apb_psc_table[8] = { + 0, 0, 0, 0, 1, 2, 3, 4 + }; + + if ((readl(®s->cfgr) & RCC_CFGR_SWS_MASK) == + RCC_CFGR_SWS_PLL) { + u16 pllm, plln, pllp; + pllm = (readl(®s->pllcfgr) & RCC_PLLCFGR_PLLM_MASK); + plln = ((readl(®s->pllcfgr) & RCC_PLLCFGR_PLLN_MASK) + >> RCC_PLLCFGR_PLLN_SHIFT); + pllp = ((((readl(®s->pllcfgr) & RCC_PLLCFGR_PLLP_MASK) + >> RCC_PLLCFGR_PLLP_SHIFT) + 1) << 1); + sysclk = ((CONFIG_STM32_HSE_HZ / pllm) * plln) / pllp; + } else { + return -EINVAL; + } + + switch (clk->id) { + /* + * AHB CLOCK: 3 x 32 bits consecutive registers are used : + * AHB1, AHB2 and AHB3 + */ + case STM32F7_AHB1_CLOCK(GPIOA) ... STM32F7_AHB3_CLOCK(QSPI): + shift = ahb_psc_table[( + (readl(®s->cfgr) & RCC_CFGR_AHB_PSC_MASK) + >> RCC_CFGR_HPRE_SHIFT)]; + return sysclk >>= shift; + break; + /* APB1 CLOCK */ + case STM32F7_APB1_CLOCK(TIM2) ... STM32F7_APB1_CLOCK(UART8): + shift = apb_psc_table[( + (readl(®s->cfgr) & RCC_CFGR_APB1_PSC_MASK) + >> RCC_CFGR_PPRE1_SHIFT)]; + return sysclk >>= shift; + break; + /* APB2 CLOCK */ + case STM32F7_APB2_CLOCK(TIM1) ... STM32F7_APB2_CLOCK(LTDC): + shift = apb_psc_table[( + (readl(®s->cfgr) & RCC_CFGR_APB2_PSC_MASK) + >> RCC_CFGR_PPRE2_SHIFT)]; + return sysclk >>= shift; + break; + default: + error("clock index %ld out of range\n", clk->id); + return -EINVAL; + break; + } +} + static int stm32_clk_enable(struct clk *clk) { struct stm32_clk *priv = dev_get_priv(clk->dev); @@ -291,6 +352,7 @@ static int stm32_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args) static struct clk_ops stm32_clk_ops = { .of_xlate = stm32_clk_of_xlate, .enable = stm32_clk_enable, + .get_rate = stm32_clk_get_rate, }; static const struct udevice_id stm32_clk_ids[] = { -- 2.39.2