Linux Audio

Check our new training course

Yocto / OpenEmbedded training

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