Merge git://git.denx.de/u-boot-fsl-qoriq
[oweals/u-boot.git] / drivers / clk / clk_stm32f7.c
index 7dd91b6a58572eff712d25fe55f66f500c6b58ec..96a06b8f8cb11525a18cde1ba218c08cddc54e71 100644 (file)
@@ -12,6 +12,8 @@
 #include <asm/arch/stm32.h>
 #include <asm/arch/stm32_periph.h>
 
+#include <dt-bindings/mfd/stm32f7-rcc.h>
+
 #define RCC_CR_HSION                   BIT(0)
 #define RCC_CR_HSEON                   BIT(16)
 #define RCC_CR_HSERDY                  BIT(17)
@@ -169,8 +171,10 @@ static int configure_clocks(struct udevice *dev)
        return 0;
 }
 
-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 */
@@ -181,41 +185,47 @@ unsigned long clock_get(enum clock clck)
                0, 0, 0, 0, 1, 2, 3, 4
        };
 
-       if ((readl(&STM32_RCC->cfgr) & RCC_CFGR_SWS_MASK) ==
+       if ((readl(&regs->cfgr) & RCC_CFGR_SWS_MASK) ==
                        RCC_CFGR_SWS_PLL) {
                u16 pllm, plln, pllp;
-               pllm = (readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLM_MASK);
-               plln = ((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLN_MASK)
+               pllm = (readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLM_MASK);
+               plln = ((readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLN_MASK)
                        >> RCC_PLLCFGR_PLLN_SHIFT);
-               pllp = ((((readl(&STM32_RCC->pllcfgr) & RCC_PLLCFGR_PLLP_MASK)
+               pllp = ((((readl(&regs->pllcfgr) & RCC_PLLCFGR_PLLP_MASK)
                        >> RCC_PLLCFGR_PLLP_SHIFT) + 1) << 1);
                sysclk = ((CONFIG_STM32_HSE_HZ / pllm) * plln) / pllp;
+       } else {
+               return -EINVAL;
        }
 
-       switch (clck) {
-       case CLOCK_CORE:
-               return sysclk;
-               break;
-       case CLOCK_AHB:
+       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(&STM32_RCC->cfgr) & RCC_CFGR_AHB_PSC_MASK)
+                       (readl(&regs->cfgr) & RCC_CFGR_AHB_PSC_MASK)
                        >> RCC_CFGR_HPRE_SHIFT)];
                return sysclk >>= shift;
                break;
-       case CLOCK_APB1:
+       /* APB1 CLOCK */
+       case STM32F7_APB1_CLOCK(TIM2) ... STM32F7_APB1_CLOCK(UART8):
                shift = apb_psc_table[(
-                       (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB1_PSC_MASK)
+                       (readl(&regs->cfgr) & RCC_CFGR_APB1_PSC_MASK)
                        >> RCC_CFGR_PPRE1_SHIFT)];
                return sysclk >>= shift;
                break;
-       case CLOCK_APB2:
+       /* APB2 CLOCK */
+       case STM32F7_APB2_CLOCK(TIM1) ... STM32F7_APB2_CLOCK(LTDC):
                shift = apb_psc_table[(
-                       (readl(&STM32_RCC->cfgr) & RCC_CFGR_APB2_PSC_MASK)
+                       (readl(&regs->cfgr) & RCC_CFGR_APB2_PSC_MASK)
                        >> RCC_CFGR_PPRE2_SHIFT)];
                return sysclk >>= shift;
                break;
        default:
-               return 0;
+               pr_err("clock index %ld out of range\n", clk->id);
+               return -EINVAL;
                break;
        }
 }
@@ -291,6 +301,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[] = {
@@ -299,10 +310,11 @@ static const struct udevice_id stm32_clk_ids[] = {
 };
 
 U_BOOT_DRIVER(stm32f7_clk) = {
-       .name           = "stm32f7_clk",
-       .id             = UCLASS_CLK,
-       .of_match       = stm32_clk_ids,
-       .ops            = &stm32_clk_ops,
-       .probe          = stm32_clk_probe,
-       .flags          = DM_FLAG_PRE_RELOC,
+       .name                   = "stm32f7_clk",
+       .id                     = UCLASS_CLK,
+       .of_match               = stm32_clk_ids,
+       .ops                    = &stm32_clk_ops,
+       .probe                  = stm32_clk_probe,
+       .priv_auto_alloc_size   = sizeof(struct stm32_clk),
+       .flags                  = DM_FLAG_PRE_RELOC,
 };