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