File Index
Files and directories
Sign in
FILE

clk-stm32f4.c

File preview with syntax highlighting.

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