linux/drivers/clk/clk-stm32f4.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Author: Daniel Thompson <daniel.thompson@linaro.org>
   4 *
   5 * Inspired by clk-asm9260.c .
   6 */
   7
   8#include <linux/clk-provider.h>
   9#include <linux/err.h>
  10#include <linux/io.h>
  11#include <linux/iopoll.h>
  12#include <linux/ioport.h>
  13#include <linux/slab.h>
  14#include <linux/spinlock.h>
  15#include <linux/of.h>
  16#include <linux/of_address.h>
  17#include <linux/regmap.h>
  18#include <linux/mfd/syscon.h>
  19
  20/*
  21 * Include list of clocks wich are not derived from system clock (SYSCLOCK)
  22 * The index of these clocks is the secondary index of DT bindings
  23 *
  24 */
  25#include <dt-bindings/clock/stm32fx-clock.h>
  26
  27#define STM32F4_RCC_CR                  0x00
  28#define STM32F4_RCC_PLLCFGR             0x04
  29#define STM32F4_RCC_CFGR                0x08
  30#define STM32F4_RCC_AHB1ENR             0x30
  31#define STM32F4_RCC_AHB2ENR             0x34
  32#define STM32F4_RCC_AHB3ENR             0x38
  33#define STM32F4_RCC_APB1ENR             0x40
  34#define STM32F4_RCC_APB2ENR             0x44
  35#define STM32F4_RCC_BDCR                0x70
  36#define STM32F4_RCC_CSR                 0x74
  37#define STM32F4_RCC_PLLI2SCFGR          0x84
  38#define STM32F4_RCC_PLLSAICFGR          0x88
  39#define STM32F4_RCC_DCKCFGR             0x8c
  40#define STM32F7_RCC_DCKCFGR2            0x90
  41
  42#define NONE -1
  43#define NO_IDX  NONE
  44#define NO_MUX  NONE
  45#define NO_GATE NONE
  46
  47struct stm32f4_gate_data {
  48        u8      offset;
  49        u8      bit_idx;
  50        const char *name;
  51        const char *parent_name;
  52        unsigned long flags;
  53};
  54
  55static const struct stm32f4_gate_data stm32f429_gates[] __initconst = {
  56        { STM32F4_RCC_AHB1ENR,  0,      "gpioa",        "ahb_div" },
  57        { STM32F4_RCC_AHB1ENR,  1,      "gpiob",        "ahb_div" },
  58        { STM32F4_RCC_AHB1ENR,  2,      "gpioc",        "ahb_div" },
  59        { STM32F4_RCC_AHB1ENR,  3,      "gpiod",        "ahb_div" },
  60        { STM32F4_RCC_AHB1ENR,  4,      "gpioe",        "ahb_div" },
  61        { STM32F4_RCC_AHB1ENR,  5,      "gpiof",        "ahb_div" },
  62        { STM32F4_RCC_AHB1ENR,  6,      "gpiog",        "ahb_div" },
  63        { STM32F4_RCC_AHB1ENR,  7,      "gpioh",        "ahb_div" },
  64        { STM32F4_RCC_AHB1ENR,  8,      "gpioi",        "ahb_div" },
  65        { STM32F4_RCC_AHB1ENR,  9,      "gpioj",        "ahb_div" },
  66        { STM32F4_RCC_AHB1ENR, 10,      "gpiok",        "ahb_div" },
  67        { STM32F4_RCC_AHB1ENR, 12,      "crc",          "ahb_div" },
  68        { STM32F4_RCC_AHB1ENR, 18,      "bkpsra",       "ahb_div" },
  69        { STM32F4_RCC_AHB1ENR, 20,      "ccmdatam",     "ahb_div" },
  70        { STM32F4_RCC_AHB1ENR, 21,      "dma1",         "ahb_div" },
  71        { STM32F4_RCC_AHB1ENR, 22,      "dma2",         "ahb_div" },
  72        { STM32F4_RCC_AHB1ENR, 23,      "dma2d",        "ahb_div" },
  73        { STM32F4_RCC_AHB1ENR, 25,      "ethmac",       "ahb_div" },
  74        { STM32F4_RCC_AHB1ENR, 26,      "ethmactx",     "ahb_div" },
  75        { STM32F4_RCC_AHB1ENR, 27,      "ethmacrx",     "ahb_div" },
  76        { STM32F4_RCC_AHB1ENR, 28,      "ethmacptp",    "ahb_div" },
  77        { STM32F4_RCC_AHB1ENR, 29,      "otghs",        "ahb_div" },
  78        { STM32F4_RCC_AHB1ENR, 30,      "otghsulpi",    "ahb_div" },
  79
  80        { STM32F4_RCC_AHB2ENR,  0,      "dcmi",         "ahb_div" },
  81        { STM32F4_RCC_AHB2ENR,  4,      "cryp",         "ahb_div" },
  82        { STM32F4_RCC_AHB2ENR,  5,      "hash",         "ahb_div" },
  83        { STM32F4_RCC_AHB2ENR,  6,      "rng",          "pll48" },
  84        { STM32F4_RCC_AHB2ENR,  7,      "otgfs",        "pll48" },
  85
  86        { STM32F4_RCC_AHB3ENR,  0,      "fmc",          "ahb_div",
  87                CLK_IGNORE_UNUSED },
  88
  89        { STM32F4_RCC_APB1ENR,  0,      "tim2",         "apb1_mul" },
  90        { STM32F4_RCC_APB1ENR,  1,      "tim3",         "apb1_mul" },
  91        { STM32F4_RCC_APB1ENR,  2,      "tim4",         "apb1_mul" },
  92        { STM32F4_RCC_APB1ENR,  3,      "tim5",         "apb1_mul" },
  93        { STM32F4_RCC_APB1ENR,  4,      "tim6",         "apb1_mul" },
  94        { STM32F4_RCC_APB1ENR,  5,      "tim7",         "apb1_mul" },
  95        { STM32F4_RCC_APB1ENR,  6,      "tim12",        "apb1_mul" },
  96        { STM32F4_RCC_APB1ENR,  7,      "tim13",        "apb1_mul" },
  97        { STM32F4_RCC_APB1ENR,  8,      "tim14",        "apb1_mul" },
  98        { STM32F4_RCC_APB1ENR, 11,      "wwdg",         "apb1_div" },
  99        { STM32F4_RCC_APB1ENR, 14,      "spi2",         "apb1_div" },
 100        { STM32F4_RCC_APB1ENR, 15,      "spi3",         "apb1_div" },
 101        { STM32F4_RCC_APB1ENR, 17,      "uart2",        "apb1_div" },
 102        { STM32F4_RCC_APB1ENR, 18,      "uart3",        "apb1_div" },
 103        { STM32F4_RCC_APB1ENR, 19,      "uart4",        "apb1_div" },
 104        { STM32F4_RCC_APB1ENR, 20,      "uart5",        "apb1_div" },
 105        { STM32F4_RCC_APB1ENR, 21,      "i2c1",         "apb1_div" },
 106        { STM32F4_RCC_APB1ENR, 22,      "i2c2",         "apb1_div" },
 107        { STM32F4_RCC_APB1ENR, 23,      "i2c3",         "apb1_div" },
 108        { STM32F4_RCC_APB1ENR, 25,      "can1",         "apb1_div" },
 109        { STM32F4_RCC_APB1ENR, 26,      "can2",         "apb1_div" },
 110        { STM32F4_RCC_APB1ENR, 28,      "pwr",          "apb1_div" },
 111        { STM32F4_RCC_APB1ENR, 29,      "dac",          "apb1_div" },
 112        { STM32F4_RCC_APB1ENR, 30,      "uart7",        "apb1_div" },
 113        { STM32F4_RCC_APB1ENR, 31,      "uart8",        "apb1_div" },
 114
 115        { STM32F4_RCC_APB2ENR,  0,      "tim1",         "apb2_mul" },
 116        { STM32F4_RCC_APB2ENR,  1,      "tim8",         "apb2_mul" },
 117        { STM32F4_RCC_APB2ENR,  4,      "usart1",       "apb2_div" },
 118        { STM32F4_RCC_APB2ENR,  5,      "usart6",       "apb2_div" },
 119        { STM32F4_RCC_APB2ENR,  8,      "adc1",         "apb2_div" },
 120        { STM32F4_RCC_APB2ENR,  9,      "adc2",         "apb2_div" },
 121        { STM32F4_RCC_APB2ENR, 10,      "adc3",         "apb2_div" },
 122        { STM32F4_RCC_APB2ENR, 11,      "sdio",         "pll48" },
 123        { STM32F4_RCC_APB2ENR, 12,      "spi1",         "apb2_div" },
 124        { STM32F4_RCC_APB2ENR, 13,      "spi4",         "apb2_div" },
 125        { STM32F4_RCC_APB2ENR, 14,      "syscfg",       "apb2_div" },
 126        { STM32F4_RCC_APB2ENR, 16,      "tim9",         "apb2_mul" },
 127        { STM32F4_RCC_APB2ENR, 17,      "tim10",        "apb2_mul" },
 128        { STM32F4_RCC_APB2ENR, 18,      "tim11",        "apb2_mul" },
 129        { STM32F4_RCC_APB2ENR, 20,      "spi5",         "apb2_div" },
 130        { STM32F4_RCC_APB2ENR, 21,      "spi6",         "apb2_div" },
 131        { STM32F4_RCC_APB2ENR, 22,      "sai1",         "apb2_div" },
 132        { STM32F4_RCC_APB2ENR, 26,      "ltdc",         "apb2_div" },
 133};
 134
 135static const struct stm32f4_gate_data stm32f469_gates[] __initconst = {
 136        { STM32F4_RCC_AHB1ENR,  0,      "gpioa",        "ahb_div" },
 137        { STM32F4_RCC_AHB1ENR,  1,      "gpiob",        "ahb_div" },
 138        { STM32F4_RCC_AHB1ENR,  2,      "gpioc",        "ahb_div" },
 139        { STM32F4_RCC_AHB1ENR,  3,      "gpiod",        "ahb_div" },
 140        { STM32F4_RCC_AHB1ENR,  4,      "gpioe",        "ahb_div" },
 141        { STM32F4_RCC_AHB1ENR,  5,      "gpiof",        "ahb_div" },
 142        { STM32F4_RCC_AHB1ENR,  6,      "gpiog",        "ahb_div" },
 143        { STM32F4_RCC_AHB1ENR,  7,      "gpioh",        "ahb_div" },
 144        { STM32F4_RCC_AHB1ENR,  8,      "gpioi",        "ahb_div" },
 145        { STM32F4_RCC_AHB1ENR,  9,      "gpioj",        "ahb_div" },
 146        { STM32F4_RCC_AHB1ENR, 10,      "gpiok",        "ahb_div" },
 147        { STM32F4_RCC_AHB1ENR, 12,      "crc",          "ahb_div" },
 148        { STM32F4_RCC_AHB1ENR, 18,      "bkpsra",       "ahb_div" },
 149        { STM32F4_RCC_AHB1ENR, 20,      "ccmdatam",     "ahb_div" },
 150        { STM32F4_RCC_AHB1ENR, 21,      "dma1",         "ahb_div" },
 151        { STM32F4_RCC_AHB1ENR, 22,      "dma2",         "ahb_div" },
 152        { STM32F4_RCC_AHB1ENR, 23,      "dma2d",        "ahb_div" },
 153        { STM32F4_RCC_AHB1ENR, 25,      "ethmac",       "ahb_div" },
 154        { STM32F4_RCC_AHB1ENR, 26,      "ethmactx",     "ahb_div" },
 155        { STM32F4_RCC_AHB1ENR, 27,      "ethmacrx",     "ahb_div" },
 156        { STM32F4_RCC_AHB1ENR, 28,      "ethmacptp",    "ahb_div" },
 157        { STM32F4_RCC_AHB1ENR, 29,      "otghs",        "ahb_div" },
 158        { STM32F4_RCC_AHB1ENR, 30,      "otghsulpi",    "ahb_div" },
 159
 160        { STM32F4_RCC_AHB2ENR,  0,      "dcmi",         "ahb_div" },
 161        { STM32F4_RCC_AHB2ENR,  4,      "cryp",         "ahb_div" },
 162        { STM32F4_RCC_AHB2ENR,  5,      "hash",         "ahb_div" },
 163        { STM32F4_RCC_AHB2ENR,  6,      "rng",          "pll48" },
 164        { STM32F4_RCC_AHB2ENR,  7,      "otgfs",        "pll48" },
 165
 166        { STM32F4_RCC_AHB3ENR,  0,      "fmc",          "ahb_div",
 167                CLK_IGNORE_UNUSED },
 168        { STM32F4_RCC_AHB3ENR,  1,      "qspi",         "ahb_div",
 169                CLK_IGNORE_UNUSED },
 170
 171        { STM32F4_RCC_APB1ENR,  0,      "tim2",         "apb1_mul" },
 172        { STM32F4_RCC_APB1ENR,  1,      "tim3",         "apb1_mul" },
 173        { STM32F4_RCC_APB1ENR,  2,      "tim4",         "apb1_mul" },
 174        { STM32F4_RCC_APB1ENR,  3,      "tim5",         "apb1_mul" },
 175        { STM32F4_RCC_APB1ENR,  4,      "tim6",         "apb1_mul" },
 176        { STM32F4_RCC_APB1ENR,  5,      "tim7",         "apb1_mul" },
 177        { STM32F4_RCC_APB1ENR,  6,      "tim12",        "apb1_mul" },
 178        { STM32F4_RCC_APB1ENR,  7,      "tim13",        "apb1_mul" },
 179        { STM32F4_RCC_APB1ENR,  8,      "tim14",        "apb1_mul" },
 180        { STM32F4_RCC_APB1ENR, 11,      "wwdg",         "apb1_div" },
 181        { STM32F4_RCC_APB1ENR, 14,      "spi2",         "apb1_div" },
 182        { STM32F4_RCC_APB1ENR, 15,      "spi3",         "apb1_div" },
 183        { STM32F4_RCC_APB1ENR, 17,      "uart2",        "apb1_div" },
 184        { STM32F4_RCC_APB1ENR, 18,      "uart3",        "apb1_div" },
 185        { STM32F4_RCC_APB1ENR, 19,      "uart4",        "apb1_div" },
 186        { STM32F4_RCC_APB1ENR, 20,      "uart5",        "apb1_div" },
 187        { STM32F4_RCC_APB1ENR, 21,      "i2c1",         "apb1_div" },
 188        { STM32F4_RCC_APB1ENR, 22,      "i2c2",         "apb1_div" },
 189        { STM32F4_RCC_APB1ENR, 23,      "i2c3",         "apb1_div" },
 190        { STM32F4_RCC_APB1ENR, 25,      "can1",         "apb1_div" },
 191        { STM32F4_RCC_APB1ENR, 26,      "can2",         "apb1_div" },
 192        { STM32F4_RCC_APB1ENR, 28,      "pwr",          "apb1_div" },
 193        { STM32F4_RCC_APB1ENR, 29,      "dac",          "apb1_div" },
 194        { STM32F4_RCC_APB1ENR, 30,      "uart7",        "apb1_div" },
 195        { STM32F4_RCC_APB1ENR, 31,      "uart8",        "apb1_div" },
 196
 197        { STM32F4_RCC_APB2ENR,  0,      "tim1",         "apb2_mul" },
 198        { STM32F4_RCC_APB2ENR,  1,      "tim8",         "apb2_mul" },
 199        { STM32F4_RCC_APB2ENR,  4,      "usart1",       "apb2_div" },
 200        { STM32F4_RCC_APB2ENR,  5,      "usart6",       "apb2_div" },
 201        { STM32F4_RCC_APB2ENR,  8,      "adc1",         "apb2_div" },
 202        { STM32F4_RCC_APB2ENR,  9,      "adc2",         "apb2_div" },
 203        { STM32F4_RCC_APB2ENR, 10,      "adc3",         "apb2_div" },
 204        { STM32F4_RCC_APB2ENR, 11,      "sdio",         "sdmux" },
 205        { STM32F4_RCC_APB2ENR, 12,      "spi1",         "apb2_div" },
 206        { STM32F4_RCC_APB2ENR, 13,      "spi4",         "apb2_div" },
 207        { STM32F4_RCC_APB2ENR, 14,      "syscfg",       "apb2_div" },
 208        { STM32F4_RCC_APB2ENR, 16,      "tim9",         "apb2_mul" },
 209        { STM32F4_RCC_APB2ENR, 17,      "tim10",        "apb2_mul" },
 210        { STM32F4_RCC_APB2ENR, 18,      "tim11",        "apb2_mul" },
 211        { STM32F4_RCC_APB2ENR, 20,      "spi5",         "apb2_div" },
 212        { STM32F4_RCC_APB2ENR, 21,      "spi6",         "apb2_div" },
 213        { STM32F4_RCC_APB2ENR, 22,      "sai1",         "apb2_div" },
 214        { STM32F4_RCC_APB2ENR, 26,      "ltdc",         "apb2_div" },
 215};
 216
 217static const struct stm32f4_gate_data stm32f746_gates[] __initconst = {
 218        { STM32F4_RCC_AHB1ENR,  0,      "gpioa",        "ahb_div" },
 219        { STM32F4_RCC_AHB1ENR,  1,      "gpiob",        "ahb_div" },
 220        { STM32F4_RCC_AHB1ENR,  2,      "gpioc",        "ahb_div" },
 221        { STM32F4_RCC_AHB1ENR,  3,      "gpiod",        "ahb_div" },
 222        { STM32F4_RCC_AHB1ENR,  4,      "gpioe",        "ahb_div" },
 223        { STM32F4_RCC_AHB1ENR,  5,      "gpiof",        "ahb_div" },
 224        { STM32F4_RCC_AHB1ENR,  6,      "gpiog",        "ahb_div" },
 225        { STM32F4_RCC_AHB1ENR,  7,      "gpioh",        "ahb_div" },
 226        { STM32F4_RCC_AHB1ENR,  8,      "gpioi",        "ahb_div" },
 227        { STM32F4_RCC_AHB1ENR,  9,      "gpioj",        "ahb_div" },
 228        { STM32F4_RCC_AHB1ENR, 10,      "gpiok",        "ahb_div" },
 229        { STM32F4_RCC_AHB1ENR, 12,      "crc",          "ahb_div" },
 230        { STM32F4_RCC_AHB1ENR, 18,      "bkpsra",       "ahb_div" },
 231        { STM32F4_RCC_AHB1ENR, 20,      "dtcmram",      "ahb_div" },
 232        { STM32F4_RCC_AHB1ENR, 21,      "dma1",         "ahb_div" },
 233        { STM32F4_RCC_AHB1ENR, 22,      "dma2",         "ahb_div" },
 234        { STM32F4_RCC_AHB1ENR, 23,      "dma2d",        "ahb_div" },
 235        { STM32F4_RCC_AHB1ENR, 25,      "ethmac",       "ahb_div" },
 236        { STM32F4_RCC_AHB1ENR, 26,      "ethmactx",     "ahb_div" },
 237        { STM32F4_RCC_AHB1ENR, 27,      "ethmacrx",     "ahb_div" },
 238        { STM32F4_RCC_AHB1ENR, 28,      "ethmacptp",    "ahb_div" },
 239        { STM32F4_RCC_AHB1ENR, 29,      "otghs",        "ahb_div" },
 240        { STM32F4_RCC_AHB1ENR, 30,      "otghsulpi",    "ahb_div" },
 241
 242        { STM32F4_RCC_AHB2ENR,  0,      "dcmi",         "ahb_div" },
 243        { STM32F4_RCC_AHB2ENR,  4,      "cryp",         "ahb_div" },
 244        { STM32F4_RCC_AHB2ENR,  5,      "hash",         "ahb_div" },
 245        { STM32F4_RCC_AHB2ENR,  6,      "rng",          "pll48"   },
 246        { STM32F4_RCC_AHB2ENR,  7,      "otgfs",        "pll48"   },
 247
 248        { STM32F4_RCC_AHB3ENR,  0,      "fmc",          "ahb_div",
 249                CLK_IGNORE_UNUSED },
 250        { STM32F4_RCC_AHB3ENR,  1,      "qspi",         "ahb_div",
 251                CLK_IGNORE_UNUSED },
 252
 253        { STM32F4_RCC_APB1ENR,  0,      "tim2",         "apb1_mul" },
 254        { STM32F4_RCC_APB1ENR,  1,      "tim3",         "apb1_mul" },
 255        { STM32F4_RCC_APB1ENR,  2,      "tim4",         "apb1_mul" },
 256        { STM32F4_RCC_APB1ENR,  3,      "tim5",         "apb1_mul" },
 257        { STM32F4_RCC_APB1ENR,  4,      "tim6",         "apb1_mul" },
 258        { STM32F4_RCC_APB1ENR,  5,      "tim7",         "apb1_mul" },
 259        { STM32F4_RCC_APB1ENR,  6,      "tim12",        "apb1_mul" },
 260        { STM32F4_RCC_APB1ENR,  7,      "tim13",        "apb1_mul" },
 261        { STM32F4_RCC_APB1ENR,  8,      "tim14",        "apb1_mul" },
 262        { STM32F4_RCC_APB1ENR, 11,      "wwdg",         "apb1_div" },
 263        { STM32F4_RCC_APB1ENR, 14,      "spi2",         "apb1_div" },
 264        { STM32F4_RCC_APB1ENR, 15,      "spi3",         "apb1_div" },
 265        { STM32F4_RCC_APB1ENR, 16,      "spdifrx",      "apb1_div" },
 266        { STM32F4_RCC_APB1ENR, 25,      "can1",         "apb1_div" },
 267        { STM32F4_RCC_APB1ENR, 26,      "can2",         "apb1_div" },
 268        { STM32F4_RCC_APB1ENR, 27,      "cec",          "apb1_div" },
 269        { STM32F4_RCC_APB1ENR, 28,      "pwr",          "apb1_div" },
 270        { STM32F4_RCC_APB1ENR, 29,      "dac",          "apb1_div" },
 271
 272        { STM32F4_RCC_APB2ENR,  0,      "tim1",         "apb2_mul" },
 273        { STM32F4_RCC_APB2ENR,  1,      "tim8",         "apb2_mul" },
 274        { STM32F4_RCC_APB2ENR,  7,      "sdmmc2",       "sdmux"    },
 275        { STM32F4_RCC_APB2ENR,  8,      "adc1",         "apb2_div" },
 276        { STM32F4_RCC_APB2ENR,  9,      "adc2",         "apb2_div" },
 277        { STM32F4_RCC_APB2ENR, 10,      "adc3",         "apb2_div" },
 278        { STM32F4_RCC_APB2ENR, 11,      "sdmmc",        "sdmux"    },
 279        { STM32F4_RCC_APB2ENR, 12,      "spi1",         "apb2_div" },
 280        { STM32F4_RCC_APB2ENR, 13,      "spi4",         "apb2_div" },
 281        { STM32F4_RCC_APB2ENR, 14,      "syscfg",       "apb2_div" },
 282        { STM32F4_RCC_APB2ENR, 16,      "tim9",         "apb2_mul" },
 283        { STM32F4_RCC_APB2ENR, 17,      "tim10",        "apb2_mul" },
 284        { STM32F4_RCC_APB2ENR, 18,      "tim11",        "apb2_mul" },
 285        { STM32F4_RCC_APB2ENR, 20,      "spi5",         "apb2_div" },
 286        { STM32F4_RCC_APB2ENR, 21,      "spi6",         "apb2_div" },
 287        { STM32F4_RCC_APB2ENR, 22,      "sai1",         "apb2_div" },
 288        { STM32F4_RCC_APB2ENR, 23,      "sai2",         "apb2_div" },
 289        { STM32F4_RCC_APB2ENR, 26,      "ltdc",         "apb2_div" },
 290};
 291
 292static const struct stm32f4_gate_data stm32f769_gates[] __initconst = {
 293        { STM32F4_RCC_AHB1ENR,  0,      "gpioa",        "ahb_div" },
 294        { STM32F4_RCC_AHB1ENR,  1,      "gpiob",        "ahb_div" },
 295        { STM32F4_RCC_AHB1ENR,  2,      "gpioc",        "ahb_div" },
 296        { STM32F4_RCC_AHB1ENR,  3,      "gpiod",        "ahb_div" },
 297        { STM32F4_RCC_AHB1ENR,  4,      "gpioe",        "ahb_div" },
 298        { STM32F4_RCC_AHB1ENR,  5,      "gpiof",        "ahb_div" },
 299        { STM32F4_RCC_AHB1ENR,  6,      "gpiog",        "ahb_div" },
 300        { STM32F4_RCC_AHB1ENR,  7,      "gpioh",        "ahb_div" },
 301        { STM32F4_RCC_AHB1ENR,  8,      "gpioi",        "ahb_div" },
 302        { STM32F4_RCC_AHB1ENR,  9,      "gpioj",        "ahb_div" },
 303        { STM32F4_RCC_AHB1ENR, 10,      "gpiok",        "ahb_div" },
 304        { STM32F4_RCC_AHB1ENR, 12,      "crc",          "ahb_div" },
 305        { STM32F4_RCC_AHB1ENR, 18,      "bkpsra",       "ahb_div" },
 306        { STM32F4_RCC_AHB1ENR, 20,      "dtcmram",      "ahb_div" },
 307        { STM32F4_RCC_AHB1ENR, 21,      "dma1",         "ahb_div" },
 308        { STM32F4_RCC_AHB1ENR, 22,      "dma2",         "ahb_div" },
 309        { STM32F4_RCC_AHB1ENR, 23,      "dma2d",        "ahb_div" },
 310        { STM32F4_RCC_AHB1ENR, 25,      "ethmac",       "ahb_div" },
 311        { STM32F4_RCC_AHB1ENR, 26,      "ethmactx",     "ahb_div" },
 312        { STM32F4_RCC_AHB1ENR, 27,      "ethmacrx",     "ahb_div" },
 313        { STM32F4_RCC_AHB1ENR, 28,      "ethmacptp",    "ahb_div" },
 314        { STM32F4_RCC_AHB1ENR, 29,      "otghs",        "ahb_div" },
 315        { STM32F4_RCC_AHB1ENR, 30,      "otghsulpi",    "ahb_div" },
 316
 317        { STM32F4_RCC_AHB2ENR,  0,      "dcmi",         "ahb_div" },
 318        { STM32F4_RCC_AHB2ENR,  1,      "jpeg",         "ahb_div" },
 319        { STM32F4_RCC_AHB2ENR,  4,      "cryp",         "ahb_div" },
 320        { STM32F4_RCC_AHB2ENR,  5,      "hash",         "ahb_div" },
 321        { STM32F4_RCC_AHB2ENR,  6,      "rng",          "pll48"   },
 322        { STM32F4_RCC_AHB2ENR,  7,      "otgfs",        "pll48"   },
 323
 324        { STM32F4_RCC_AHB3ENR,  0,      "fmc",          "ahb_div",
 325                CLK_IGNORE_UNUSED },
 326        { STM32F4_RCC_AHB3ENR,  1,      "qspi",         "ahb_div",
 327                CLK_IGNORE_UNUSED },
 328
 329        { STM32F4_RCC_APB1ENR,  0,      "tim2",         "apb1_mul" },
 330        { STM32F4_RCC_APB1ENR,  1,      "tim3",         "apb1_mul" },
 331        { STM32F4_RCC_APB1ENR,  2,      "tim4",         "apb1_mul" },
 332        { STM32F4_RCC_APB1ENR,  3,      "tim5",         "apb1_mul" },
 333        { STM32F4_RCC_APB1ENR,  4,      "tim6",         "apb1_mul" },
 334        { STM32F4_RCC_APB1ENR,  5,      "tim7",         "apb1_mul" },
 335        { STM32F4_RCC_APB1ENR,  6,      "tim12",        "apb1_mul" },
 336        { STM32F4_RCC_APB1ENR,  7,      "tim13",        "apb1_mul" },
 337        { STM32F4_RCC_APB1ENR,  8,      "tim14",        "apb1_mul" },
 338        { STM32F4_RCC_APB1ENR, 10,      "rtcapb",       "apb1_mul" },
 339        { STM32F4_RCC_APB1ENR, 11,      "wwdg",         "apb1_div" },
 340        { STM32F4_RCC_APB1ENR, 13,      "can3",         "apb1_div" },
 341        { STM32F4_RCC_APB1ENR, 14,      "spi2",         "apb1_div" },
 342        { STM32F4_RCC_APB1ENR, 15,      "spi3",         "apb1_div" },
 343        { STM32F4_RCC_APB1ENR, 16,      "spdifrx",      "apb1_div" },
 344        { STM32F4_RCC_APB1ENR, 25,      "can1",         "apb1_div" },
 345        { STM32F4_RCC_APB1ENR, 26,      "can2",         "apb1_div" },
 346        { STM32F4_RCC_APB1ENR, 27,      "cec",          "apb1_div" },
 347        { STM32F4_RCC_APB1ENR, 28,      "pwr",          "apb1_div" },
 348        { STM32F4_RCC_APB1ENR, 29,      "dac",          "apb1_div" },
 349
 350        { STM32F4_RCC_APB2ENR,  0,      "tim1",         "apb2_mul" },
 351        { STM32F4_RCC_APB2ENR,  1,      "tim8",         "apb2_mul" },
 352        { STM32F4_RCC_APB2ENR,  7,      "sdmmc2",       "sdmux2" },
 353        { STM32F4_RCC_APB2ENR,  8,      "adc1",         "apb2_div" },
 354        { STM32F4_RCC_APB2ENR,  9,      "adc2",         "apb2_div" },
 355        { STM32F4_RCC_APB2ENR, 10,      "adc3",         "apb2_div" },
 356        { STM32F4_RCC_APB2ENR, 11,      "sdmmc1",       "sdmux1" },
 357        { STM32F4_RCC_APB2ENR, 12,      "spi1",         "apb2_div" },
 358        { STM32F4_RCC_APB2ENR, 13,      "spi4",         "apb2_div" },
 359        { STM32F4_RCC_APB2ENR, 14,      "syscfg",       "apb2_div" },
 360        { STM32F4_RCC_APB2ENR, 16,      "tim9",         "apb2_mul" },
 361        { STM32F4_RCC_APB2ENR, 17,      "tim10",        "apb2_mul" },
 362        { STM32F4_RCC_APB2ENR, 18,      "tim11",        "apb2_mul" },
 363        { STM32F4_RCC_APB2ENR, 20,      "spi5",         "apb2_div" },
 364        { STM32F4_RCC_APB2ENR, 21,      "spi6",         "apb2_div" },
 365        { STM32F4_RCC_APB2ENR, 22,      "sai1",         "apb2_div" },
 366        { STM32F4_RCC_APB2ENR, 23,      "sai2",         "apb2_div" },
 367        { STM32F4_RCC_APB2ENR, 26,      "ltdc",         "apb2_div" },
 368        { STM32F4_RCC_APB2ENR, 30,      "mdio",         "apb2_div" },
 369};
 370
 371/*
 372 * This bitmask tells us which bit offsets (0..192) on STM32F4[23]xxx
 373 * have gate bits associated with them. Its combined hweight is 71.
 374 */
 375#define MAX_GATE_MAP 3
 376
 377static const u64 stm32f42xx_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull,
 378                                                       0x0000000000000001ull,
 379                                                       0x04777f33f6fec9ffull };
 380
 381static const u64 stm32f46xx_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull,
 382                                                       0x0000000000000003ull,
 383                                                       0x0c777f33f6fec9ffull };
 384
 385static const u64 stm32f746_gate_map[MAX_GATE_MAP] = { 0x000000f17ef417ffull,
 386                                                      0x0000000000000003ull,
 387                                                      0x04f77f833e01c9ffull };
 388
 389static const u64 stm32f769_gate_map[MAX_GATE_MAP] = { 0x000000f37ef417ffull,
 390                                                      0x0000000000000003ull,
 391                                                      0x44F77F833E01EDFFull };
 392
 393static const u64 *stm32f4_gate_map;
 394
 395static struct clk_hw **clks;
 396
 397static DEFINE_SPINLOCK(stm32f4_clk_lock);
 398static void __iomem *base;
 399
 400static struct regmap *pdrm;
 401
 402static int stm32fx_end_primary_clk;
 403
 404/*
 405 * "Multiplier" device for APBx clocks.
 406 *
 407 * The APBx dividers are power-of-two dividers and, if *not* running in 1:1
 408 * mode, they also tap out the one of the low order state bits to run the
 409 * timers. ST datasheets represent this feature as a (conditional) clock
 410 * multiplier.
 411 */
 412struct clk_apb_mul {
 413        struct clk_hw hw;
 414        u8 bit_idx;
 415};
 416
 417#define to_clk_apb_mul(_hw) container_of(_hw, struct clk_apb_mul, hw)
 418
 419static unsigned long clk_apb_mul_recalc_rate(struct clk_hw *hw,
 420                                             unsigned long parent_rate)
 421{
 422        struct clk_apb_mul *am = to_clk_apb_mul(hw);
 423
 424        if (readl(base + STM32F4_RCC_CFGR) & BIT(am->bit_idx))
 425                return parent_rate * 2;
 426
 427        return parent_rate;
 428}
 429
 430static long clk_apb_mul_round_rate(struct clk_hw *hw, unsigned long rate,
 431                                   unsigned long *prate)
 432{
 433        struct clk_apb_mul *am = to_clk_apb_mul(hw);
 434        unsigned long mult = 1;
 435
 436        if (readl(base + STM32F4_RCC_CFGR) & BIT(am->bit_idx))
 437                mult = 2;
 438
 439        if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
 440                unsigned long best_parent = rate / mult;
 441
 442                *prate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent);
 443        }
 444
 445        return *prate * mult;
 446}
 447
 448static int clk_apb_mul_set_rate(struct clk_hw *hw, unsigned long rate,
 449                                unsigned long parent_rate)
 450{
 451        /*
 452         * We must report success but we can do so unconditionally because
 453         * clk_apb_mul_round_rate returns values that ensure this call is a
 454         * nop.
 455         */
 456
 457        return 0;
 458}
 459
 460static const struct clk_ops clk_apb_mul_factor_ops = {
 461        .round_rate = clk_apb_mul_round_rate,
 462        .set_rate = clk_apb_mul_set_rate,
 463        .recalc_rate = clk_apb_mul_recalc_rate,
 464};
 465
 466static struct clk *clk_register_apb_mul(struct device *dev, const char *name,
 467                                        const char *parent_name,
 468                                        unsigned long flags, u8 bit_idx)
 469{
 470        struct clk_apb_mul *am;
 471        struct clk_init_data init;
 472        struct clk *clk;
 473
 474        am = kzalloc(sizeof(*am), GFP_KERNEL);
 475        if (!am)
 476                return ERR_PTR(-ENOMEM);
 477
 478        am->bit_idx = bit_idx;
 479        am->hw.init = &init;
 480
 481        init.name = name;
 482        init.ops = &clk_apb_mul_factor_ops;
 483        init.flags = flags;
 484        init.parent_names = &parent_name;
 485        init.num_parents = 1;
 486
 487        clk = clk_register(dev, &am->hw);
 488
 489        if (IS_ERR(clk))
 490                kfree(am);
 491
 492        return clk;
 493}
 494
 495enum {
 496        PLL,
 497        PLL_I2S,
 498        PLL_SAI,
 499};
 500
 501static const struct clk_div_table pll_divp_table[] = {
 502        { 0, 2 }, { 1, 4 }, { 2, 6 }, { 3, 8 }, { 0 }
 503};
 504
 505static const struct clk_div_table pll_divq_table[] = {
 506        { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 6 }, { 7, 7 },
 507        { 8, 8 }, { 9, 9 }, { 10, 10 }, { 11, 11 }, { 12, 12 }, { 13, 13 },
 508        { 14, 14 }, { 15, 15 },
 509        { 0 }
 510};
 511
 512static const struct clk_div_table pll_divr_table[] = {
 513        { 2, 2 }, { 3, 3 }, { 4, 4 }, { 5, 5 }, { 6, 6 }, { 7, 7 }, { 0 }
 514};
 515
 516struct stm32f4_pll {
 517        spinlock_t *lock;
 518        struct  clk_gate gate;
 519        u8 offset;
 520        u8 bit_rdy_idx;
 521        u8 status;
 522        u8 n_start;
 523};
 524
 525#define to_stm32f4_pll(_gate) container_of(_gate, struct stm32f4_pll, gate)
 526
 527struct stm32f4_pll_post_div_data {
 528        int idx;
 529        int pll_idx;
 530        const char *name;
 531        const char *parent;
 532        u8 flag;
 533        u8 offset;
 534        u8 shift;
 535        u8 width;
 536        u8 flag_div;
 537        const struct clk_div_table *div_table;
 538};
 539
 540struct stm32f4_vco_data {
 541        const char *vco_name;
 542        u8 offset;
 543        u8 bit_idx;
 544        u8 bit_rdy_idx;
 545};
 546
 547static const struct stm32f4_vco_data  vco_data[] = {
 548        { "vco",     STM32F4_RCC_PLLCFGR,    24, 25 },
 549        { "vco-i2s", STM32F4_RCC_PLLI2SCFGR, 26, 27 },
 550        { "vco-sai", STM32F4_RCC_PLLSAICFGR, 28, 29 },
 551};
 552
 553
 554static const struct clk_div_table post_divr_table[] = {
 555        { 0, 2 }, { 1, 4 }, { 2, 8 }, { 3, 16 }, { 0 }
 556};
 557
 558#define MAX_POST_DIV 3
 559static const struct stm32f4_pll_post_div_data  post_div_data[MAX_POST_DIV] = {
 560        { CLK_I2SQ_PDIV, PLL_VCO_I2S, "plli2s-q-div", "plli2s-q",
 561                CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 0, 5, 0, NULL},
 562
 563        { CLK_SAIQ_PDIV, PLL_VCO_SAI, "pllsai-q-div", "pllsai-q",
 564                CLK_SET_RATE_PARENT, STM32F4_RCC_DCKCFGR, 8, 5, 0, NULL },
 565
 566        { NO_IDX, PLL_VCO_SAI, "pllsai-r-div", "pllsai-r", CLK_SET_RATE_PARENT,
 567                STM32F4_RCC_DCKCFGR, 16, 2, 0, post_divr_table },
 568};
 569
 570struct stm32f4_div_data {
 571        u8 shift;
 572        u8 width;
 573        u8 flag_div;
 574        const struct clk_div_table *div_table;
 575};
 576
 577#define MAX_PLL_DIV 3
 578static const struct stm32f4_div_data  div_data[MAX_PLL_DIV] = {
 579        { 16, 2, 0, pll_divp_table },
 580        { 24, 4, 0, pll_divq_table },
 581        { 28, 3, 0, pll_divr_table },
 582};
 583
 584struct stm32f4_pll_data {
 585        u8 pll_num;
 586        u8 n_start;
 587        const char *div_name[MAX_PLL_DIV];
 588};
 589
 590static const struct stm32f4_pll_data stm32f429_pll[MAX_PLL_DIV] = {
 591        { PLL,     192, { "pll", "pll48",    NULL       } },
 592        { PLL_I2S, 192, { NULL,  "plli2s-q", "plli2s-r" } },
 593        { PLL_SAI,  49, { NULL,  "pllsai-q", "pllsai-r" } },
 594};
 595
 596static const struct stm32f4_pll_data stm32f469_pll[MAX_PLL_DIV] = {
 597        { PLL,     50, { "pll",      "pll-q",    "pll-r"    } },
 598        { PLL_I2S, 50, { "plli2s-p", "plli2s-q", "plli2s-r" } },
 599        { PLL_SAI, 50, { "pllsai-p", "pllsai-q", "pllsai-r" } },
 600};
 601
 602static int stm32f4_pll_is_enabled(struct clk_hw *hw)
 603{
 604        return clk_gate_ops.is_enabled(hw);
 605}
 606
 607#define PLL_TIMEOUT 10000
 608
 609static int stm32f4_pll_enable(struct clk_hw *hw)
 610{
 611        struct clk_gate *gate = to_clk_gate(hw);
 612        struct stm32f4_pll *pll = to_stm32f4_pll(gate);
 613        int bit_status;
 614        unsigned int timeout = PLL_TIMEOUT;
 615
 616        if (clk_gate_ops.is_enabled(hw))
 617                return 0;
 618
 619        clk_gate_ops.enable(hw);
 620
 621        do {
 622                bit_status = !(readl(gate->reg) & BIT(pll->bit_rdy_idx));
 623
 624        } while (bit_status && --timeout);
 625
 626        return bit_status;
 627}
 628
 629static void stm32f4_pll_disable(struct clk_hw *hw)
 630{
 631        clk_gate_ops.disable(hw);
 632}
 633
 634static unsigned long stm32f4_pll_recalc(struct clk_hw *hw,
 635                unsigned long parent_rate)
 636{
 637        struct clk_gate *gate = to_clk_gate(hw);
 638        struct stm32f4_pll *pll = to_stm32f4_pll(gate);
 639        unsigned long n;
 640
 641        n = (readl(base + pll->offset) >> 6) & 0x1ff;
 642
 643        return parent_rate * n;
 644}
 645
 646static long stm32f4_pll_round_rate(struct clk_hw *hw, unsigned long rate,
 647                unsigned long *prate)
 648{
 649        struct clk_gate *gate = to_clk_gate(hw);
 650        struct stm32f4_pll *pll = to_stm32f4_pll(gate);
 651        unsigned long n;
 652
 653        n = rate / *prate;
 654
 655        if (n < pll->n_start)
 656                n = pll->n_start;
 657        else if (n > 432)
 658                n = 432;
 659
 660        return *prate * n;
 661}
 662
 663static int stm32f4_pll_set_rate(struct clk_hw *hw, unsigned long rate,
 664                                unsigned long parent_rate)
 665{
 666        struct clk_gate *gate = to_clk_gate(hw);
 667        struct stm32f4_pll *pll = to_stm32f4_pll(gate);
 668
 669        unsigned long n;
 670        unsigned long val;
 671        int pll_state;
 672
 673        pll_state = stm32f4_pll_is_enabled(hw);
 674
 675        if (pll_state)
 676                stm32f4_pll_disable(hw);
 677
 678        n = rate  / parent_rate;
 679
 680        val = readl(base + pll->offset) & ~(0x1ff << 6);
 681
 682        writel(val | ((n & 0x1ff) <<  6), base + pll->offset);
 683
 684        if (pll_state)
 685                stm32f4_pll_enable(hw);
 686
 687        return 0;
 688}
 689
 690static const struct clk_ops stm32f4_pll_gate_ops = {
 691        .enable         = stm32f4_pll_enable,
 692        .disable        = stm32f4_pll_disable,
 693        .is_enabled     = stm32f4_pll_is_enabled,
 694        .recalc_rate    = stm32f4_pll_recalc,
 695        .round_rate     = stm32f4_pll_round_rate,
 696        .set_rate       = stm32f4_pll_set_rate,
 697};
 698
 699struct stm32f4_pll_div {
 700        struct clk_divider div;
 701        struct clk_hw *hw_pll;
 702};
 703
 704#define to_pll_div_clk(_div) container_of(_div, struct stm32f4_pll_div, div)
 705
 706static unsigned long stm32f4_pll_div_recalc_rate(struct clk_hw *hw,
 707                unsigned long parent_rate)
 708{
 709        return clk_divider_ops.recalc_rate(hw, parent_rate);
 710}
 711
 712static long stm32f4_pll_div_round_rate(struct clk_hw *hw, unsigned long rate,
 713                                unsigned long *prate)
 714{
 715        return clk_divider_ops.round_rate(hw, rate, prate);
 716}
 717
 718static int stm32f4_pll_div_set_rate(struct clk_hw *hw, unsigned long rate,
 719                                unsigned long parent_rate)
 720{
 721        int pll_state, ret;
 722
 723        struct clk_divider *div = to_clk_divider(hw);
 724        struct stm32f4_pll_div *pll_div = to_pll_div_clk(div);
 725
 726        pll_state = stm32f4_pll_is_enabled(pll_div->hw_pll);
 727
 728        if (pll_state)
 729                stm32f4_pll_disable(pll_div->hw_pll);
 730
 731        ret = clk_divider_ops.set_rate(hw, rate, parent_rate);
 732
 733        if (pll_state)
 734                stm32f4_pll_enable(pll_div->hw_pll);
 735
 736        return ret;
 737}
 738
 739static const struct clk_ops stm32f4_pll_div_ops = {
 740        .recalc_rate = stm32f4_pll_div_recalc_rate,
 741        .round_rate = stm32f4_pll_div_round_rate,
 742        .set_rate = stm32f4_pll_div_set_rate,
 743};
 744
 745static struct clk_hw *clk_register_pll_div(const char *name,
 746                const char *parent_name, unsigned long flags,
 747                void __iomem *reg, u8 shift, u8 width,
 748                u8 clk_divider_flags, const struct clk_div_table *table,
 749                struct clk_hw *pll_hw, spinlock_t *lock)
 750{
 751        struct stm32f4_pll_div *pll_div;
 752        struct clk_hw *hw;
 753        struct clk_init_data init;
 754        int ret;
 755
 756        /* allocate the divider */
 757        pll_div = kzalloc(sizeof(*pll_div), GFP_KERNEL);
 758        if (!pll_div)
 759                return ERR_PTR(-ENOMEM);
 760
 761        init.name = name;
 762        init.ops = &stm32f4_pll_div_ops;
 763        init.flags = flags;
 764        init.parent_names = (parent_name ? &parent_name : NULL);
 765        init.num_parents = (parent_name ? 1 : 0);
 766
 767        /* struct clk_divider assignments */
 768        pll_div->div.reg = reg;
 769        pll_div->div.shift = shift;
 770        pll_div->div.width = width;
 771        pll_div->div.flags = clk_divider_flags;
 772        pll_div->div.lock = lock;
 773        pll_div->div.table = table;
 774        pll_div->div.hw.init = &init;
 775
 776        pll_div->hw_pll = pll_hw;
 777
 778        /* register the clock */
 779        hw = &pll_div->div.hw;
 780        ret = clk_hw_register(NULL, hw);
 781        if (ret) {
 782                kfree(pll_div);
 783                hw = ERR_PTR(ret);
 784        }
 785
 786        return hw;
 787}
 788
 789static struct clk_hw *stm32f4_rcc_register_pll(const char *pllsrc,
 790                const struct stm32f4_pll_data *data,  spinlock_t *lock)
 791{
 792        struct stm32f4_pll *pll;
 793        struct clk_init_data init = { NULL };
 794        void __iomem *reg;
 795        struct clk_hw *pll_hw;
 796        int ret;
 797        int i;
 798        const struct stm32f4_vco_data *vco;
 799
 800
 801        pll = kzalloc(sizeof(*pll), GFP_KERNEL);
 802        if (!pll)
 803                return ERR_PTR(-ENOMEM);
 804
 805        vco = &vco_data[data->pll_num];
 806
 807        init.name = vco->vco_name;
 808        init.ops = &stm32f4_pll_gate_ops;
 809        init.flags = CLK_SET_RATE_GATE;
 810        init.parent_names = &pllsrc;
 811        init.num_parents = 1;
 812
 813        pll->gate.lock = lock;
 814        pll->gate.reg = base + STM32F4_RCC_CR;
 815        pll->gate.bit_idx = vco->bit_idx;
 816        pll->gate.hw.init = &init;
 817
 818        pll->offset = vco->offset;
 819        pll->n_start = data->n_start;
 820        pll->bit_rdy_idx = vco->bit_rdy_idx;
 821        pll->status = (readl(base + STM32F4_RCC_CR) >> vco->bit_idx) & 0x1;
 822
 823        reg = base + pll->offset;
 824
 825        pll_hw = &pll->gate.hw;
 826        ret = clk_hw_register(NULL, pll_hw);
 827        if (ret) {
 828                kfree(pll);
 829                return ERR_PTR(ret);
 830        }
 831
 832        for (i = 0; i < MAX_PLL_DIV; i++)
 833                if (data->div_name[i])
 834                        clk_register_pll_div(data->div_name[i],
 835                                        vco->vco_name,
 836                                        0,
 837                                        reg,
 838                                        div_data[i].shift,
 839                                        div_data[i].width,
 840                                        div_data[i].flag_div,
 841                                        div_data[i].div_table,
 842                                        pll_hw,
 843                                        lock);
 844        return pll_hw;
 845}
 846
 847/*
 848 * Converts the primary and secondary indices (as they appear in DT) to an
 849 * offset into our struct clock array.
 850 */
 851static int stm32f4_rcc_lookup_clk_idx(u8 primary, u8 secondary)
 852{
 853        u64 table[MAX_GATE_MAP];
 854
 855        if (primary == 1) {
 856                if (WARN_ON(secondary >= stm32fx_end_primary_clk))
 857                        return -EINVAL;
 858                return secondary;
 859        }
 860
 861        memcpy(table, stm32f4_gate_map, sizeof(table));
 862
 863        /* only bits set in table can be used as indices */
 864        if (WARN_ON(secondary >= BITS_PER_BYTE * sizeof(table) ||
 865                    0 == (table[BIT_ULL_WORD(secondary)] &
 866                          BIT_ULL_MASK(secondary))))
 867                return -EINVAL;
 868
 869        /* mask out bits above our current index */
 870        table[BIT_ULL_WORD(secondary)] &=
 871            GENMASK_ULL(secondary % BITS_PER_LONG_LONG, 0);
 872
 873        return stm32fx_end_primary_clk - 1 + hweight64(table[0]) +
 874               (BIT_ULL_WORD(secondary) >= 1 ? hweight64(table[1]) : 0) +
 875               (BIT_ULL_WORD(secondary) >= 2 ? hweight64(table[2]) : 0);
 876}
 877
 878static struct clk_hw *
 879stm32f4_rcc_lookup_clk(struct of_phandle_args *clkspec, void *data)
 880{
 881        int i = stm32f4_rcc_lookup_clk_idx(clkspec->args[0], clkspec->args[1]);
 882
 883        if (i < 0)
 884                return ERR_PTR(-EINVAL);
 885
 886        return clks[i];
 887}
 888
 889#define to_rgclk(_rgate) container_of(_rgate, struct stm32_rgate, gate)
 890
 891static inline void disable_power_domain_write_protection(void)
 892{
 893        if (pdrm)
 894                regmap_update_bits(pdrm, 0x00, (1 << 8), (1 << 8));
 895}
 896
 897static inline void enable_power_domain_write_protection(void)
 898{
 899        if (pdrm)
 900                regmap_update_bits(pdrm, 0x00, (1 << 8), (0 << 8));
 901}
 902
 903static inline void sofware_reset_backup_domain(void)
 904{
 905        unsigned long val;
 906
 907        val = readl(base + STM32F4_RCC_BDCR);
 908        writel(val | BIT(16), base + STM32F4_RCC_BDCR);
 909        writel(val & ~BIT(16), base + STM32F4_RCC_BDCR);
 910}
 911
 912struct stm32_rgate {
 913        struct  clk_gate gate;
 914        u8      bit_rdy_idx;
 915};
 916
 917#define RGATE_TIMEOUT 50000
 918
 919static int rgclk_enable(struct clk_hw *hw)
 920{
 921        struct clk_gate *gate = to_clk_gate(hw);
 922        struct stm32_rgate *rgate = to_rgclk(gate);
 923        int bit_status;
 924        unsigned int timeout = RGATE_TIMEOUT;
 925
 926        if (clk_gate_ops.is_enabled(hw))
 927                return 0;
 928
 929        disable_power_domain_write_protection();
 930
 931        clk_gate_ops.enable(hw);
 932
 933        do {
 934                bit_status = !(readl(gate->reg) & BIT(rgate->bit_rdy_idx));
 935                if (bit_status)
 936                        udelay(100);
 937
 938        } while (bit_status && --timeout);
 939
 940        enable_power_domain_write_protection();
 941
 942        return bit_status;
 943}
 944
 945static void rgclk_disable(struct clk_hw *hw)
 946{
 947        clk_gate_ops.disable(hw);
 948}
 949
 950static int rgclk_is_enabled(struct clk_hw *hw)
 951{
 952        return clk_gate_ops.is_enabled(hw);
 953}
 954
 955static const struct clk_ops rgclk_ops = {
 956        .enable = rgclk_enable,
 957        .disable = rgclk_disable,
 958        .is_enabled = rgclk_is_enabled,
 959};
 960
 961static struct clk_hw *clk_register_rgate(struct device *dev, const char *name,
 962                const char *parent_name, unsigned long flags,
 963                void __iomem *reg, u8 bit_idx, u8 bit_rdy_idx,
 964                u8 clk_gate_flags, spinlock_t *lock)
 965{
 966        struct stm32_rgate *rgate;
 967        struct clk_init_data init = { NULL };
 968        struct clk_hw *hw;
 969        int ret;
 970
 971        rgate = kzalloc(sizeof(*rgate), GFP_KERNEL);
 972        if (!rgate)
 973                return ERR_PTR(-ENOMEM);
 974
 975        init.name = name;
 976        init.ops = &rgclk_ops;
 977        init.flags = flags;
 978        init.parent_names = &parent_name;
 979        init.num_parents = 1;
 980
 981        rgate->bit_rdy_idx = bit_rdy_idx;
 982
 983        rgate->gate.lock = lock;
 984        rgate->gate.reg = reg;
 985        rgate->gate.bit_idx = bit_idx;
 986        rgate->gate.hw.init = &init;
 987
 988        hw = &rgate->gate.hw;
 989        ret = clk_hw_register(dev, hw);
 990        if (ret) {
 991                kfree(rgate);
 992                hw = ERR_PTR(ret);
 993        }
 994
 995        return hw;
 996}
 997
 998static int cclk_gate_enable(struct clk_hw *hw)
 999{
1000        int ret;
1001
1002        disable_power_domain_write_protection();
1003
1004        ret = clk_gate_ops.enable(hw);
1005
1006        enable_power_domain_write_protection();
1007
1008        return ret;
1009}
1010
1011static void cclk_gate_disable(struct clk_hw *hw)
1012{
1013        disable_power_domain_write_protection();
1014
1015        clk_gate_ops.disable(hw);
1016
1017        enable_power_domain_write_protection();
1018}
1019
1020static int cclk_gate_is_enabled(struct clk_hw *hw)
1021{
1022        return clk_gate_ops.is_enabled(hw);
1023}
1024
1025static const struct clk_ops cclk_gate_ops = {
1026        .enable         = cclk_gate_enable,
1027        .disable        = cclk_gate_disable,
1028        .is_enabled     = cclk_gate_is_enabled,
1029};
1030
1031static u8 cclk_mux_get_parent(struct clk_hw *hw)
1032{
1033        return clk_mux_ops.get_parent(hw);
1034}
1035
1036static int cclk_mux_set_parent(struct clk_hw *hw, u8 index)
1037{
1038        int ret;
1039
1040        disable_power_domain_write_protection();
1041
1042        sofware_reset_backup_domain();
1043
1044        ret = clk_mux_ops.set_parent(hw, index);
1045
1046        enable_power_domain_write_protection();
1047
1048        return ret;
1049}
1050
1051static const struct clk_ops cclk_mux_ops = {
1052        .get_parent = cclk_mux_get_parent,
1053        .set_parent = cclk_mux_set_parent,
1054};
1055
1056static struct clk_hw *stm32_register_cclk(struct device *dev, const char *name,
1057                const char * const *parent_names, int num_parents,
1058                void __iomem *reg, u8 bit_idx, u8 shift, unsigned long flags,
1059                spinlock_t *lock)
1060{
1061        struct clk_hw *hw;
1062        struct clk_gate *gate;
1063        struct clk_mux *mux;
1064
1065        gate = kzalloc(sizeof(*gate), GFP_KERNEL);
1066        if (!gate) {
1067                hw = ERR_PTR(-EINVAL);
1068                goto fail;
1069        }
1070
1071        mux = kzalloc(sizeof(*mux), GFP_KERNEL);
1072        if (!mux) {
1073                kfree(gate);
1074                hw = ERR_PTR(-EINVAL);
1075                goto fail;
1076        }
1077
1078        gate->reg = reg;
1079        gate->bit_idx = bit_idx;
1080        gate->flags = 0;
1081        gate->lock = lock;
1082
1083        mux->reg = reg;
1084        mux->shift = shift;
1085        mux->mask = 3;
1086        mux->flags = 0;
1087
1088        hw = clk_hw_register_composite(dev, name, parent_names, num_parents,
1089                        &mux->hw, &cclk_mux_ops,
1090                        NULL, NULL,
1091                        &gate->hw, &cclk_gate_ops,
1092                        flags);
1093
1094        if (IS_ERR(hw)) {
1095                kfree(gate);
1096                kfree(mux);
1097        }
1098
1099fail:
1100        return hw;
1101}
1102
1103static const char *sys_parents[] __initdata =   { "hsi", NULL, "pll" };
1104
1105static const struct clk_div_table ahb_div_table[] = {
1106        { 0x0,   1 }, { 0x1,   1 }, { 0x2,   1 }, { 0x3,   1 },
1107        { 0x4,   1 }, { 0x5,   1 }, { 0x6,   1 }, { 0x7,   1 },
1108        { 0x8,   2 }, { 0x9,   4 }, { 0xa,   8 }, { 0xb,  16 },
1109        { 0xc,  64 }, { 0xd, 128 }, { 0xe, 256 }, { 0xf, 512 },
1110        { 0 },
1111};
1112
1113static const struct clk_div_table apb_div_table[] = {
1114        { 0,  1 }, { 0,  1 }, { 0,  1 }, { 0,  1 },
1115        { 4,  2 }, { 5,  4 }, { 6,  8 }, { 7, 16 },
1116        { 0 },
1117};
1118
1119static const char *rtc_parents[4] = {
1120        "no-clock", "lse", "lsi", "hse-rtc"
1121};
1122
1123static const char *pll_src = "pll-src";
1124
1125static const char *pllsrc_parent[2] = { "hsi", NULL };
1126
1127static const char *dsi_parent[2] = { NULL, "pll-r" };
1128
1129static const char *lcd_parent[1] = { "pllsai-r-div" };
1130
1131static const char *i2s_parents[2] = { "plli2s-r", NULL };
1132
1133static const char *sai_parents[4] = { "pllsai-q-div", "plli2s-q-div", NULL,
1134        "no-clock" };
1135
1136static const char *pll48_parents[2] = { "pll-q", "pllsai-p" };
1137
1138static const char *sdmux_parents[2] = { "pll48", "sys" };
1139
1140static const char *hdmi_parents[2] = { "lse", "hsi_div488" };
1141
1142static const char *spdif_parent[1] = { "plli2s-p" };
1143
1144static const char *lptim_parent[4] = { "apb1_mul", "lsi", "hsi", "lse" };
1145
1146static const char *uart_parents1[4] = { "apb2_div", "sys", "hsi", "lse" };
1147static const char *uart_parents2[4] = { "apb1_div", "sys", "hsi", "lse" };
1148
1149static const char *i2c_parents[4] = { "apb1_div", "sys", "hsi", "no-clock" };
1150
1151static const char * const dfsdm1_src[] = { "apb2_div", "sys" };
1152static const char * const adsfdm1_parent[] = { "sai1_clk", "sai2_clk" };
1153
1154struct stm32_aux_clk {
1155        int idx;
1156        const char *name;
1157        const char * const *parent_names;
1158        int num_parents;
1159        int offset_mux;
1160        u8 shift;
1161        u8 mask;
1162        int offset_gate;
1163        u8 bit_idx;
1164        unsigned long flags;
1165};
1166
1167struct stm32f4_clk_data {
1168        const struct stm32f4_gate_data *gates_data;
1169        const u64 *gates_map;
1170        int gates_num;
1171        const struct stm32f4_pll_data *pll_data;
1172        const struct stm32_aux_clk *aux_clk;
1173        int aux_clk_num;
1174        int end_primary;
1175};
1176
1177static const struct stm32_aux_clk stm32f429_aux_clk[] = {
1178        {
1179                CLK_LCD, "lcd-tft", lcd_parent, ARRAY_SIZE(lcd_parent),
1180                NO_MUX, 0, 0,
1181                STM32F4_RCC_APB2ENR, 26,
1182                CLK_SET_RATE_PARENT
1183        },
1184        {
1185                CLK_I2S, "i2s", i2s_parents, ARRAY_SIZE(i2s_parents),
1186                STM32F4_RCC_CFGR, 23, 1,
1187                NO_GATE, 0,
1188                CLK_SET_RATE_PARENT
1189        },
1190        {
1191                CLK_SAI1, "sai1-a", sai_parents, ARRAY_SIZE(sai_parents),
1192                STM32F4_RCC_DCKCFGR, 20, 3,
1193                STM32F4_RCC_APB2ENR, 22,
1194                CLK_SET_RATE_PARENT
1195        },
1196        {
1197                CLK_SAI2, "sai1-b", sai_parents, ARRAY_SIZE(sai_parents),
1198                STM32F4_RCC_DCKCFGR, 22, 3,
1199                STM32F4_RCC_APB2ENR, 22,
1200                CLK_SET_RATE_PARENT
1201        },
1202};
1203
1204static const struct stm32_aux_clk stm32f469_aux_clk[] = {
1205        {
1206                CLK_LCD, "lcd-tft", lcd_parent, ARRAY_SIZE(lcd_parent),
1207                NO_MUX, 0, 0,
1208                STM32F4_RCC_APB2ENR, 26,
1209                CLK_SET_RATE_PARENT
1210        },
1211        {
1212                CLK_I2S, "i2s", i2s_parents, ARRAY_SIZE(i2s_parents),
1213                STM32F4_RCC_CFGR, 23, 1,
1214                NO_GATE, 0,
1215                CLK_SET_RATE_PARENT
1216        },
1217        {
1218                CLK_SAI1, "sai1-a", sai_parents, ARRAY_SIZE(sai_parents),
1219                STM32F4_RCC_DCKCFGR, 20, 3,
1220                STM32F4_RCC_APB2ENR, 22,
1221                CLK_SET_RATE_PARENT
1222        },
1223        {
1224                CLK_SAI2, "sai1-b", sai_parents, ARRAY_SIZE(sai_parents),
1225                STM32F4_RCC_DCKCFGR, 22, 3,
1226                STM32F4_RCC_APB2ENR, 22,
1227                CLK_SET_RATE_PARENT
1228        },
1229        {
1230                NO_IDX, "pll48", pll48_parents, ARRAY_SIZE(pll48_parents),
1231                STM32F4_RCC_DCKCFGR, 27, 1,
1232                NO_GATE, 0,
1233                0
1234        },
1235        {
1236                NO_IDX, "sdmux", sdmux_parents, ARRAY_SIZE(sdmux_parents),
1237                STM32F4_RCC_DCKCFGR, 28, 1,
1238                NO_GATE, 0,
1239                0
1240        },
1241        {
1242                CLK_F469_DSI, "dsi", dsi_parent, ARRAY_SIZE(dsi_parent),
1243                STM32F4_RCC_DCKCFGR, 29, 1,
1244                STM32F4_RCC_APB2ENR, 27,
1245                CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT
1246        },
1247};
1248
1249static const struct stm32_aux_clk stm32f746_aux_clk[] = {
1250        {
1251                CLK_LCD, "lcd-tft", lcd_parent, ARRAY_SIZE(lcd_parent),
1252                NO_MUX, 0, 0,
1253                STM32F4_RCC_APB2ENR, 26,
1254                CLK_SET_RATE_PARENT
1255        },
1256        {
1257                CLK_I2S, "i2s", i2s_parents, ARRAY_SIZE(i2s_parents),
1258                STM32F4_RCC_CFGR, 23, 1,
1259                NO_GATE, 0,
1260                CLK_SET_RATE_PARENT
1261        },
1262        {
1263                CLK_SAI1, "sai1_clk", sai_parents, ARRAY_SIZE(sai_parents),
1264                STM32F4_RCC_DCKCFGR, 20, 3,
1265                STM32F4_RCC_APB2ENR, 22,
1266                CLK_SET_RATE_PARENT
1267        },
1268        {
1269                CLK_SAI2, "sai2_clk", sai_parents, ARRAY_SIZE(sai_parents),
1270                STM32F4_RCC_DCKCFGR, 22, 3,
1271                STM32F4_RCC_APB2ENR, 23,
1272                CLK_SET_RATE_PARENT
1273        },
1274        {
1275                NO_IDX, "pll48", pll48_parents, ARRAY_SIZE(pll48_parents),
1276                STM32F7_RCC_DCKCFGR2, 27, 1,
1277                NO_GATE, 0,
1278                0
1279        },
1280        {
1281                NO_IDX, "sdmux", sdmux_parents, ARRAY_SIZE(sdmux_parents),
1282                STM32F7_RCC_DCKCFGR2, 28, 1,
1283                NO_GATE, 0,
1284                0
1285        },
1286        {
1287                CLK_HDMI_CEC, "hdmi-cec",
1288                hdmi_parents, ARRAY_SIZE(hdmi_parents),
1289                STM32F7_RCC_DCKCFGR2, 26, 1,
1290                NO_GATE, 0,
1291                0
1292        },
1293        {
1294                CLK_SPDIF, "spdif-rx",
1295                spdif_parent, ARRAY_SIZE(spdif_parent),
1296                STM32F7_RCC_DCKCFGR2, 22, 3,
1297                STM32F4_RCC_APB2ENR, 23,
1298                CLK_SET_RATE_PARENT
1299        },
1300        {
1301                CLK_USART1, "usart1",
1302                uart_parents1, ARRAY_SIZE(uart_parents1),
1303                STM32F7_RCC_DCKCFGR2, 0, 3,
1304                STM32F4_RCC_APB2ENR, 4,
1305                CLK_SET_RATE_PARENT,
1306        },
1307        {
1308                CLK_USART2, "usart2",
1309                uart_parents2, ARRAY_SIZE(uart_parents1),
1310                STM32F7_RCC_DCKCFGR2, 2, 3,
1311                STM32F4_RCC_APB1ENR, 17,
1312                CLK_SET_RATE_PARENT,
1313        },
1314        {
1315                CLK_USART3, "usart3",
1316                uart_parents2, ARRAY_SIZE(uart_parents1),
1317                STM32F7_RCC_DCKCFGR2, 4, 3,
1318                STM32F4_RCC_APB1ENR, 18,
1319                CLK_SET_RATE_PARENT,
1320        },
1321        {
1322                CLK_UART4, "uart4",
1323                uart_parents2, ARRAY_SIZE(uart_parents1),
1324                STM32F7_RCC_DCKCFGR2, 6, 3,
1325                STM32F4_RCC_APB1ENR, 19,
1326                CLK_SET_RATE_PARENT,
1327        },
1328        {
1329                CLK_UART5, "uart5",
1330                uart_parents2, ARRAY_SIZE(uart_parents1),
1331                STM32F7_RCC_DCKCFGR2, 8, 3,
1332                STM32F4_RCC_APB1ENR, 20,
1333                CLK_SET_RATE_PARENT,
1334        },
1335        {
1336                CLK_USART6, "usart6",
1337                uart_parents1, ARRAY_SIZE(uart_parents1),
1338                STM32F7_RCC_DCKCFGR2, 10, 3,
1339                STM32F4_RCC_APB2ENR, 5,
1340                CLK_SET_RATE_PARENT,
1341        },
1342
1343        {
1344                CLK_UART7, "uart7",
1345                uart_parents2, ARRAY_SIZE(uart_parents1),
1346                STM32F7_RCC_DCKCFGR2, 12, 3,
1347                STM32F4_RCC_APB1ENR, 30,
1348                CLK_SET_RATE_PARENT,
1349        },
1350        {
1351                CLK_UART8, "uart8",
1352                uart_parents2, ARRAY_SIZE(uart_parents1),
1353                STM32F7_RCC_DCKCFGR2, 14, 3,
1354                STM32F4_RCC_APB1ENR, 31,
1355                CLK_SET_RATE_PARENT,
1356        },
1357        {
1358                CLK_I2C1, "i2c1",
1359                i2c_parents, ARRAY_SIZE(i2c_parents),
1360                STM32F7_RCC_DCKCFGR2, 16, 3,
1361                STM32F4_RCC_APB1ENR, 21,
1362                CLK_SET_RATE_PARENT,
1363        },
1364        {
1365                CLK_I2C2, "i2c2",
1366                i2c_parents, ARRAY_SIZE(i2c_parents),
1367                STM32F7_RCC_DCKCFGR2, 18, 3,
1368                STM32F4_RCC_APB1ENR, 22,
1369                CLK_SET_RATE_PARENT,
1370        },
1371        {
1372                CLK_I2C3, "i2c3",
1373                i2c_parents, ARRAY_SIZE(i2c_parents),
1374                STM32F7_RCC_DCKCFGR2, 20, 3,
1375                STM32F4_RCC_APB1ENR, 23,
1376                CLK_SET_RATE_PARENT,
1377        },
1378        {
1379                CLK_I2C4, "i2c4",
1380                i2c_parents, ARRAY_SIZE(i2c_parents),
1381                STM32F7_RCC_DCKCFGR2, 22, 3,
1382                STM32F4_RCC_APB1ENR, 24,
1383                CLK_SET_RATE_PARENT,
1384        },
1385
1386        {
1387                CLK_LPTIMER, "lptim1",
1388                lptim_parent, ARRAY_SIZE(lptim_parent),
1389                STM32F7_RCC_DCKCFGR2, 24, 3,
1390                STM32F4_RCC_APB1ENR, 9,
1391                CLK_SET_RATE_PARENT
1392        },
1393};
1394
1395static const struct stm32_aux_clk stm32f769_aux_clk[] = {
1396        {
1397                CLK_LCD, "lcd-tft", lcd_parent, ARRAY_SIZE(lcd_parent),
1398                NO_MUX, 0, 0,
1399                STM32F4_RCC_APB2ENR, 26,
1400                CLK_SET_RATE_PARENT
1401        },
1402        {
1403                CLK_I2S, "i2s", i2s_parents, ARRAY_SIZE(i2s_parents),
1404                STM32F4_RCC_CFGR, 23, 1,
1405                NO_GATE, 0,
1406                CLK_SET_RATE_PARENT
1407        },
1408        {
1409                CLK_SAI1, "sai1_clk", sai_parents, ARRAY_SIZE(sai_parents),
1410                STM32F4_RCC_DCKCFGR, 20, 3,
1411                STM32F4_RCC_APB2ENR, 22,
1412                CLK_SET_RATE_PARENT
1413        },
1414        {
1415                CLK_SAI2, "sai2_clk", sai_parents, ARRAY_SIZE(sai_parents),
1416                STM32F4_RCC_DCKCFGR, 22, 3,
1417                STM32F4_RCC_APB2ENR, 23,
1418                CLK_SET_RATE_PARENT
1419        },
1420        {
1421                NO_IDX, "pll48", pll48_parents, ARRAY_SIZE(pll48_parents),
1422                STM32F7_RCC_DCKCFGR2, 27, 1,
1423                NO_GATE, 0,
1424                0
1425        },
1426        {
1427                NO_IDX, "sdmux1", sdmux_parents, ARRAY_SIZE(sdmux_parents),
1428                STM32F7_RCC_DCKCFGR2, 28, 1,
1429                NO_GATE, 0,
1430                0
1431        },
1432        {
1433                NO_IDX, "sdmux2", sdmux_parents, ARRAY_SIZE(sdmux_parents),
1434                STM32F7_RCC_DCKCFGR2, 29, 1,
1435                NO_GATE, 0,
1436                0
1437        },
1438        {
1439                CLK_HDMI_CEC, "hdmi-cec",
1440                hdmi_parents, ARRAY_SIZE(hdmi_parents),
1441                STM32F7_RCC_DCKCFGR2, 26, 1,
1442                NO_GATE, 0,
1443                0
1444        },
1445        {
1446                CLK_SPDIF, "spdif-rx",
1447                spdif_parent, ARRAY_SIZE(spdif_parent),
1448                STM32F7_RCC_DCKCFGR2, 22, 3,
1449                STM32F4_RCC_APB2ENR, 23,
1450                CLK_SET_RATE_PARENT
1451        },
1452        {
1453                CLK_USART1, "usart1",
1454                uart_parents1, ARRAY_SIZE(uart_parents1),
1455                STM32F7_RCC_DCKCFGR2, 0, 3,
1456                STM32F4_RCC_APB2ENR, 4,
1457                CLK_SET_RATE_PARENT,
1458        },
1459        {
1460                CLK_USART2, "usart2",
1461                uart_parents2, ARRAY_SIZE(uart_parents1),
1462                STM32F7_RCC_DCKCFGR2, 2, 3,
1463                STM32F4_RCC_APB1ENR, 17,
1464                CLK_SET_RATE_PARENT,
1465        },
1466        {
1467                CLK_USART3, "usart3",
1468                uart_parents2, ARRAY_SIZE(uart_parents1),
1469                STM32F7_RCC_DCKCFGR2, 4, 3,
1470                STM32F4_RCC_APB1ENR, 18,
1471                CLK_SET_RATE_PARENT,
1472        },
1473        {
1474                CLK_UART4, "uart4",
1475                uart_parents2, ARRAY_SIZE(uart_parents1),
1476                STM32F7_RCC_DCKCFGR2, 6, 3,
1477                STM32F4_RCC_APB1ENR, 19,
1478                CLK_SET_RATE_PARENT,
1479        },
1480        {
1481                CLK_UART5, "uart5",
1482                uart_parents2, ARRAY_SIZE(uart_parents1),
1483                STM32F7_RCC_DCKCFGR2, 8, 3,
1484                STM32F4_RCC_APB1ENR, 20,
1485                CLK_SET_RATE_PARENT,
1486        },
1487        {
1488                CLK_USART6, "usart6",
1489                uart_parents1, ARRAY_SIZE(uart_parents1),
1490                STM32F7_RCC_DCKCFGR2, 10, 3,
1491                STM32F4_RCC_APB2ENR, 5,
1492                CLK_SET_RATE_PARENT,
1493        },
1494        {
1495                CLK_UART7, "uart7",
1496                uart_parents2, ARRAY_SIZE(uart_parents1),
1497                STM32F7_RCC_DCKCFGR2, 12, 3,
1498                STM32F4_RCC_APB1ENR, 30,
1499                CLK_SET_RATE_PARENT,
1500        },
1501        {
1502                CLK_UART8, "uart8",
1503                uart_parents2, ARRAY_SIZE(uart_parents1),
1504                STM32F7_RCC_DCKCFGR2, 14, 3,
1505                STM32F4_RCC_APB1ENR, 31,
1506                CLK_SET_RATE_PARENT,
1507        },
1508        {
1509                CLK_I2C1, "i2c1",
1510                i2c_parents, ARRAY_SIZE(i2c_parents),
1511                STM32F7_RCC_DCKCFGR2, 16, 3,
1512                STM32F4_RCC_APB1ENR, 21,
1513                CLK_SET_RATE_PARENT,
1514        },
1515        {
1516                CLK_I2C2, "i2c2",
1517                i2c_parents, ARRAY_SIZE(i2c_parents),
1518                STM32F7_RCC_DCKCFGR2, 18, 3,
1519                STM32F4_RCC_APB1ENR, 22,
1520                CLK_SET_RATE_PARENT,
1521        },
1522        {
1523                CLK_I2C3, "i2c3",
1524                i2c_parents, ARRAY_SIZE(i2c_parents),
1525                STM32F7_RCC_DCKCFGR2, 20, 3,
1526                STM32F4_RCC_APB1ENR, 23,
1527                CLK_SET_RATE_PARENT,
1528        },
1529        {
1530                CLK_I2C4, "i2c4",
1531                i2c_parents, ARRAY_SIZE(i2c_parents),
1532                STM32F7_RCC_DCKCFGR2, 22, 3,
1533                STM32F4_RCC_APB1ENR, 24,
1534                CLK_SET_RATE_PARENT,
1535        },
1536        {
1537                CLK_LPTIMER, "lptim1",
1538                lptim_parent, ARRAY_SIZE(lptim_parent),
1539                STM32F7_RCC_DCKCFGR2, 24, 3,
1540                STM32F4_RCC_APB1ENR, 9,
1541                CLK_SET_RATE_PARENT
1542        },
1543        {
1544                CLK_F769_DSI, "dsi",
1545                dsi_parent, ARRAY_SIZE(dsi_parent),
1546                STM32F7_RCC_DCKCFGR2, 0, 1,
1547                STM32F4_RCC_APB2ENR, 27,
1548                CLK_SET_RATE_PARENT
1549        },
1550        {
1551                CLK_DFSDM1, "dfsdm1",
1552                dfsdm1_src, ARRAY_SIZE(dfsdm1_src),
1553                STM32F4_RCC_DCKCFGR, 25, 1,
1554                STM32F4_RCC_APB2ENR, 29,
1555                CLK_SET_RATE_PARENT
1556        },
1557        {
1558                CLK_ADFSDM1, "adfsdm1",
1559                adsfdm1_parent, ARRAY_SIZE(adsfdm1_parent),
1560                STM32F4_RCC_DCKCFGR, 26, 1,
1561                STM32F4_RCC_APB2ENR, 29,
1562                CLK_SET_RATE_PARENT
1563        },
1564};
1565
1566static const struct stm32f4_clk_data stm32f429_clk_data = {
1567        .end_primary    = END_PRIMARY_CLK,
1568        .gates_data     = stm32f429_gates,
1569        .gates_map      = stm32f42xx_gate_map,
1570        .gates_num      = ARRAY_SIZE(stm32f429_gates),
1571        .pll_data       = stm32f429_pll,
1572        .aux_clk        = stm32f429_aux_clk,
1573        .aux_clk_num    = ARRAY_SIZE(stm32f429_aux_clk),
1574};
1575
1576static const struct stm32f4_clk_data stm32f469_clk_data = {
1577        .end_primary    = END_PRIMARY_CLK,
1578        .gates_data     = stm32f469_gates,
1579        .gates_map      = stm32f46xx_gate_map,
1580        .gates_num      = ARRAY_SIZE(stm32f469_gates),
1581        .pll_data       = stm32f469_pll,
1582        .aux_clk        = stm32f469_aux_clk,
1583        .aux_clk_num    = ARRAY_SIZE(stm32f469_aux_clk),
1584};
1585
1586static const struct stm32f4_clk_data stm32f746_clk_data = {
1587        .end_primary    = END_PRIMARY_CLK_F7,
1588        .gates_data     = stm32f746_gates,
1589        .gates_map      = stm32f746_gate_map,
1590        .gates_num      = ARRAY_SIZE(stm32f746_gates),
1591        .pll_data       = stm32f469_pll,
1592        .aux_clk        = stm32f746_aux_clk,
1593        .aux_clk_num    = ARRAY_SIZE(stm32f746_aux_clk),
1594};
1595
1596static const struct stm32f4_clk_data stm32f769_clk_data = {
1597        .end_primary    = END_PRIMARY_CLK_F7,
1598        .gates_data     = stm32f769_gates,
1599        .gates_map      = stm32f769_gate_map,
1600        .gates_num      = ARRAY_SIZE(stm32f769_gates),
1601        .pll_data       = stm32f469_pll,
1602        .aux_clk        = stm32f769_aux_clk,
1603        .aux_clk_num    = ARRAY_SIZE(stm32f769_aux_clk),
1604};
1605
1606static const struct of_device_id stm32f4_of_match[] = {
1607        {
1608                .compatible = "st,stm32f42xx-rcc",
1609                .data = &stm32f429_clk_data
1610        },
1611        {
1612                .compatible = "st,stm32f469-rcc",
1613                .data = &stm32f469_clk_data
1614        },
1615        {
1616                .compatible = "st,stm32f746-rcc",
1617                .data = &stm32f746_clk_data
1618        },
1619        {
1620                .compatible = "st,stm32f769-rcc",
1621                .data = &stm32f769_clk_data
1622        },
1623        {}
1624};
1625
1626static struct clk_hw *stm32_register_aux_clk(const char *name,
1627                const char * const *parent_names, int num_parents,
1628                int offset_mux, u8 shift, u8 mask,
1629                int offset_gate, u8 bit_idx,
1630                unsigned long flags, spinlock_t *lock)
1631{
1632        struct clk_hw *hw;
1633        struct clk_gate *gate = NULL;
1634        struct clk_mux *mux = NULL;
1635        struct clk_hw *mux_hw = NULL, *gate_hw = NULL;
1636        const struct clk_ops *mux_ops = NULL, *gate_ops = NULL;
1637
1638        if (offset_gate != NO_GATE) {
1639                gate = kzalloc(sizeof(*gate), GFP_KERNEL);
1640                if (!gate) {
1641                        hw = ERR_PTR(-EINVAL);
1642                        goto fail;
1643                }
1644
1645                gate->reg = base + offset_gate;
1646                gate->bit_idx = bit_idx;
1647                gate->flags = 0;
1648                gate->lock = lock;
1649                gate_hw = &gate->hw;
1650                gate_ops = &clk_gate_ops;
1651        }
1652
1653        if (offset_mux != NO_MUX) {
1654                mux = kzalloc(sizeof(*mux), GFP_KERNEL);
1655                if (!mux) {
1656                        hw = ERR_PTR(-EINVAL);
1657                        goto fail;
1658                }
1659
1660                mux->reg = base + offset_mux;
1661                mux->shift = shift;
1662                mux->mask = mask;
1663                mux->flags = 0;
1664                mux_hw = &mux->hw;
1665                mux_ops = &clk_mux_ops;
1666        }
1667
1668        if (mux_hw == NULL && gate_hw == NULL) {
1669                hw = ERR_PTR(-EINVAL);
1670                goto fail;
1671        }
1672
1673        hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
1674                        mux_hw, mux_ops,
1675                        NULL, NULL,
1676                        gate_hw, gate_ops,
1677                        flags);
1678
1679fail:
1680        if (IS_ERR(hw)) {
1681                kfree(gate);
1682                kfree(mux);
1683        }
1684
1685        return hw;
1686}
1687
1688static void __init stm32f4_rcc_init(struct device_node *np)
1689{
1690        const char *hse_clk, *i2s_in_clk;
1691        int n;
1692        const struct of_device_id *match;
1693        const struct stm32f4_clk_data *data;
1694        unsigned long pllm;
1695        struct clk_hw *pll_src_hw;
1696
1697        base = of_iomap(np, 0);
1698        if (!base) {
1699                pr_err("%pOFn: unable to map resource\n", np);
1700                return;
1701        }
1702
1703        pdrm = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
1704        if (IS_ERR(pdrm)) {
1705                pdrm = NULL;
1706                pr_warn("%s: Unable to get syscfg\n", __func__);
1707        }
1708
1709        match = of_match_node(stm32f4_of_match, np);
1710        if (WARN_ON(!match))
1711                return;
1712
1713        data = match->data;
1714
1715        stm32fx_end_primary_clk = data->end_primary;
1716
1717        clks = kmalloc_array(data->gates_num + stm32fx_end_primary_clk,
1718                        sizeof(*clks), GFP_KERNEL);
1719        if (!clks)
1720                goto fail;
1721
1722        stm32f4_gate_map = data->gates_map;
1723
1724        hse_clk = of_clk_get_parent_name(np, 0);
1725        dsi_parent[0] = hse_clk;
1726        pllsrc_parent[1] = hse_clk;
1727
1728        i2s_in_clk = of_clk_get_parent_name(np, 1);
1729
1730        i2s_parents[1] = i2s_in_clk;
1731        sai_parents[2] = i2s_in_clk;
1732
1733        if (of_device_is_compatible(np, "st,stm32f769-rcc")) {
1734                clk_hw_register_gate(NULL, "dfsdm1_apb", "apb2_div", 0,
1735                                     base + STM32F4_RCC_APB2ENR, 29,
1736                                     CLK_IGNORE_UNUSED, &stm32f4_clk_lock);
1737                dsi_parent[0] = pll_src;
1738                sai_parents[3] = pll_src;
1739        }
1740
1741        clks[CLK_HSI] = clk_hw_register_fixed_rate_with_accuracy(NULL, "hsi",
1742                        NULL, 0, 16000000, 160000);
1743
1744        pll_src_hw = clk_hw_register_mux(NULL, pll_src, pllsrc_parent,
1745                                         ARRAY_SIZE(pllsrc_parent), 0,
1746                                         base + STM32F4_RCC_PLLCFGR, 22, 1, 0,
1747                                         &stm32f4_clk_lock);
1748
1749        pllm = readl(base + STM32F4_RCC_PLLCFGR) & 0x3f;
1750
1751        clk_hw_register_fixed_factor(NULL, "vco_in", pll_src,
1752                                     0, 1, pllm);
1753
1754        stm32f4_rcc_register_pll("vco_in", &data->pll_data[0],
1755                        &stm32f4_clk_lock);
1756
1757        clks[PLL_VCO_I2S] = stm32f4_rcc_register_pll("vco_in",
1758                        &data->pll_data[1], &stm32f4_clk_lock);
1759
1760        clks[PLL_VCO_SAI] = stm32f4_rcc_register_pll("vco_in",
1761                        &data->pll_data[2], &stm32f4_clk_lock);
1762
1763        for (n = 0; n < MAX_POST_DIV; n++) {
1764                const struct stm32f4_pll_post_div_data *post_div;
1765                struct clk_hw *hw;
1766
1767                post_div = &post_div_data[n];
1768
1769                hw = clk_register_pll_div(post_div->name,
1770                                post_div->parent,
1771                                post_div->flag,
1772                                base + post_div->offset,
1773                                post_div->shift,
1774                                post_div->width,
1775                                post_div->flag_div,
1776                                post_div->div_table,
1777                                clks[post_div->pll_idx],
1778                                &stm32f4_clk_lock);
1779
1780                if (post_div->idx != NO_IDX)
1781                        clks[post_div->idx] = hw;
1782        }
1783
1784        sys_parents[1] = hse_clk;
1785
1786        clks[CLK_SYSCLK] = clk_hw_register_mux_table(
1787            NULL, "sys", sys_parents, ARRAY_SIZE(sys_parents), 0,
1788            base + STM32F4_RCC_CFGR, 0, 3, 0, NULL, &stm32f4_clk_lock);
1789
1790        clk_register_divider_table(NULL, "ahb_div", "sys",
1791                                   CLK_SET_RATE_PARENT, base + STM32F4_RCC_CFGR,
1792                                   4, 4, 0, ahb_div_table, &stm32f4_clk_lock);
1793
1794        clk_register_divider_table(NULL, "apb1_div", "ahb_div",
1795                                   CLK_SET_RATE_PARENT, base + STM32F4_RCC_CFGR,
1796                                   10, 3, 0, apb_div_table, &stm32f4_clk_lock);
1797        clk_register_apb_mul(NULL, "apb1_mul", "apb1_div",
1798                             CLK_SET_RATE_PARENT, 12);
1799
1800        clk_register_divider_table(NULL, "apb2_div", "ahb_div",
1801                                   CLK_SET_RATE_PARENT, base + STM32F4_RCC_CFGR,
1802                                   13, 3, 0, apb_div_table, &stm32f4_clk_lock);
1803        clk_register_apb_mul(NULL, "apb2_mul", "apb2_div",
1804                             CLK_SET_RATE_PARENT, 15);
1805
1806        clks[SYSTICK] = clk_hw_register_fixed_factor(NULL, "systick", "ahb_div",
1807                                                  0, 1, 8);
1808        clks[FCLK] = clk_hw_register_fixed_factor(NULL, "fclk", "ahb_div",
1809                                               0, 1, 1);
1810
1811        for (n = 0; n < data->gates_num; n++) {
1812                const struct stm32f4_gate_data *gd;
1813                unsigned int secondary;
1814                int idx;
1815
1816                gd = &data->gates_data[n];
1817                secondary = 8 * (gd->offset - STM32F4_RCC_AHB1ENR) +
1818                        gd->bit_idx;
1819                idx = stm32f4_rcc_lookup_clk_idx(0, secondary);
1820
1821                if (idx < 0)
1822                        goto fail;
1823
1824                clks[idx] = clk_hw_register_gate(
1825                    NULL, gd->name, gd->parent_name, gd->flags,
1826                    base + gd->offset, gd->bit_idx, 0, &stm32f4_clk_lock);
1827
1828                if (IS_ERR(clks[idx])) {
1829                        pr_err("%pOF: Unable to register leaf clock %s\n",
1830                               np, gd->name);
1831                        goto fail;
1832                }
1833        }
1834
1835        clks[CLK_LSI] = clk_register_rgate(NULL, "lsi", "clk-lsi", 0,
1836                        base + STM32F4_RCC_CSR, 0, 1, 0, &stm32f4_clk_lock);
1837
1838        if (IS_ERR(clks[CLK_LSI])) {
1839                pr_err("Unable to register lsi clock\n");
1840                goto fail;
1841        }
1842
1843        clks[CLK_LSE] = clk_register_rgate(NULL, "lse", "clk-lse", 0,
1844                        base + STM32F4_RCC_BDCR, 0, 1, 0, &stm32f4_clk_lock);
1845
1846        if (IS_ERR(clks[CLK_LSE])) {
1847                pr_err("Unable to register lse clock\n");
1848                goto fail;
1849        }
1850
1851        clks[CLK_HSE_RTC] = clk_hw_register_divider(NULL, "hse-rtc", "clk-hse",
1852                        0, base + STM32F4_RCC_CFGR, 16, 5, 0,
1853                        &stm32f4_clk_lock);
1854
1855        if (IS_ERR(clks[CLK_HSE_RTC])) {
1856                pr_err("Unable to register hse-rtc clock\n");
1857                goto fail;
1858        }
1859
1860        clks[CLK_RTC] = stm32_register_cclk(NULL, "rtc", rtc_parents, 4,
1861                        base + STM32F4_RCC_BDCR, 15, 8, 0, &stm32f4_clk_lock);
1862
1863        if (IS_ERR(clks[CLK_RTC])) {
1864                pr_err("Unable to register rtc clock\n");
1865                goto fail;
1866        }
1867
1868        for (n = 0; n < data->aux_clk_num; n++) {
1869                const struct stm32_aux_clk *aux_clk;
1870                struct clk_hw *hw;
1871
1872                aux_clk = &data->aux_clk[n];
1873
1874                hw = stm32_register_aux_clk(aux_clk->name,
1875                                aux_clk->parent_names, aux_clk->num_parents,
1876                                aux_clk->offset_mux, aux_clk->shift,
1877                                aux_clk->mask, aux_clk->offset_gate,
1878                                aux_clk->bit_idx, aux_clk->flags,
1879                                &stm32f4_clk_lock);
1880
1881                if (IS_ERR(hw)) {
1882                        pr_warn("Unable to register %s clk\n", aux_clk->name);
1883                        continue;
1884                }
1885
1886                if (aux_clk->idx != NO_IDX)
1887                        clks[aux_clk->idx] = hw;
1888        }
1889
1890        if (of_device_is_compatible(np, "st,stm32f746-rcc")) {
1891
1892                clk_hw_register_fixed_factor(NULL, "hsi_div488", "hsi", 0,
1893                                1, 488);
1894
1895                clks[CLK_PLL_SRC] = pll_src_hw;
1896        }
1897
1898        of_clk_add_hw_provider(np, stm32f4_rcc_lookup_clk, NULL);
1899
1900        return;
1901fail:
1902        kfree(clks);
1903        iounmap(base);
1904}
1905CLK_OF_DECLARE_DRIVER(stm32f42xx_rcc, "st,stm32f42xx-rcc", stm32f4_rcc_init);
1906CLK_OF_DECLARE_DRIVER(stm32f46xx_rcc, "st,stm32f469-rcc", stm32f4_rcc_init);
1907CLK_OF_DECLARE_DRIVER(stm32f746_rcc, "st,stm32f746-rcc", stm32f4_rcc_init);
1908CLK_OF_DECLARE_DRIVER(stm32f769_rcc, "st,stm32f769-rcc", stm32f4_rcc_init);
1909
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.