Commit | Line | Data |
---|---|---|
637cee5f GF |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | |
3 | * Copyright (C) STMicroelectronics 2022 - All Rights Reserved | |
4 | * Author: Gabriel Fernandez <gabriel.fernandez@foss.st.com> for STMicroelectronics. | |
5 | */ | |
6 | ||
7 | #include <linux/clk.h> | |
8 | #include <linux/module.h> | |
9 | #include <linux/of_address.h> | |
10 | #include <linux/platform_device.h> | |
11 | #include <dt-bindings/clock/stm32mp13-clks.h> | |
12 | #include "clk-stm32-core.h" | |
13 | #include "stm32mp13_rcc.h" | |
14 | ||
15 | #define RCC_CLR_OFFSET 0x4 | |
16 | ||
17 | /* STM32 Gates definition */ | |
18 | enum enum_gate_cfg { | |
19 | GATE_MCO1, | |
20 | GATE_MCO2, | |
21 | GATE_DBGCK, | |
22 | GATE_TRACECK, | |
23 | GATE_DDRC1, | |
24 | GATE_DDRC1LP, | |
25 | GATE_DDRPHYC, | |
26 | GATE_DDRPHYCLP, | |
27 | GATE_DDRCAPB, | |
28 | GATE_DDRCAPBLP, | |
29 | GATE_AXIDCG, | |
30 | GATE_DDRPHYCAPB, | |
31 | GATE_DDRPHYCAPBLP, | |
32 | GATE_TIM2, | |
33 | GATE_TIM3, | |
34 | GATE_TIM4, | |
35 | GATE_TIM5, | |
36 | GATE_TIM6, | |
37 | GATE_TIM7, | |
38 | GATE_LPTIM1, | |
39 | GATE_SPI2, | |
40 | GATE_SPI3, | |
41 | GATE_USART3, | |
42 | GATE_UART4, | |
43 | GATE_UART5, | |
44 | GATE_UART7, | |
45 | GATE_UART8, | |
46 | GATE_I2C1, | |
47 | GATE_I2C2, | |
48 | GATE_SPDIF, | |
49 | GATE_TIM1, | |
50 | GATE_TIM8, | |
51 | GATE_SPI1, | |
52 | GATE_USART6, | |
53 | GATE_SAI1, | |
54 | GATE_SAI2, | |
55 | GATE_DFSDM, | |
56 | GATE_ADFSDM, | |
57 | GATE_FDCAN, | |
58 | GATE_LPTIM2, | |
59 | GATE_LPTIM3, | |
60 | GATE_LPTIM4, | |
61 | GATE_LPTIM5, | |
62 | GATE_VREF, | |
63 | GATE_DTS, | |
64 | GATE_PMBCTRL, | |
65 | GATE_HDP, | |
66 | GATE_SYSCFG, | |
67 | GATE_DCMIPP, | |
68 | GATE_DDRPERFM, | |
69 | GATE_IWDG2APB, | |
70 | GATE_USBPHY, | |
71 | GATE_STGENRO, | |
72 | GATE_LTDC, | |
73 | GATE_RTCAPB, | |
74 | GATE_TZC, | |
75 | GATE_ETZPC, | |
76 | GATE_IWDG1APB, | |
77 | GATE_BSEC, | |
78 | GATE_STGENC, | |
79 | GATE_USART1, | |
80 | GATE_USART2, | |
81 | GATE_SPI4, | |
82 | GATE_SPI5, | |
83 | GATE_I2C3, | |
84 | GATE_I2C4, | |
85 | GATE_I2C5, | |
86 | GATE_TIM12, | |
87 | GATE_TIM13, | |
88 | GATE_TIM14, | |
89 | GATE_TIM15, | |
90 | GATE_TIM16, | |
91 | GATE_TIM17, | |
92 | GATE_DMA1, | |
93 | GATE_DMA2, | |
94 | GATE_DMAMUX1, | |
95 | GATE_DMA3, | |
96 | GATE_DMAMUX2, | |
97 | GATE_ADC1, | |
98 | GATE_ADC2, | |
99 | GATE_USBO, | |
100 | GATE_TSC, | |
101 | GATE_GPIOA, | |
102 | GATE_GPIOB, | |
103 | GATE_GPIOC, | |
104 | GATE_GPIOD, | |
105 | GATE_GPIOE, | |
106 | GATE_GPIOF, | |
107 | GATE_GPIOG, | |
108 | GATE_GPIOH, | |
109 | GATE_GPIOI, | |
110 | GATE_PKA, | |
111 | GATE_SAES, | |
112 | GATE_CRYP1, | |
113 | GATE_HASH1, | |
114 | GATE_RNG1, | |
115 | GATE_BKPSRAM, | |
116 | GATE_AXIMC, | |
117 | GATE_MCE, | |
118 | GATE_ETH1CK, | |
119 | GATE_ETH1TX, | |
120 | GATE_ETH1RX, | |
121 | GATE_ETH1MAC, | |
122 | GATE_FMC, | |
123 | GATE_QSPI, | |
124 | GATE_SDMMC1, | |
125 | GATE_SDMMC2, | |
126 | GATE_CRC1, | |
127 | GATE_USBH, | |
128 | GATE_ETH2CK, | |
129 | GATE_ETH2TX, | |
130 | GATE_ETH2RX, | |
131 | GATE_ETH2MAC, | |
132 | GATE_ETH1STP, | |
133 | GATE_ETH2STP, | |
134 | GATE_MDMA, | |
135 | GATE_NB | |
136 | }; | |
137 | ||
138 | #define _CFG_GATE(_id, _offset, _bit_idx, _offset_clr)\ | |
139 | [(_id)] = {\ | |
140 | .offset = (_offset),\ | |
141 | .bit_idx = (_bit_idx),\ | |
142 | .set_clr = (_offset_clr),\ | |
143 | } | |
144 | ||
145 | #define CFG_GATE(_id, _offset, _bit_idx)\ | |
146 | _CFG_GATE(_id, _offset, _bit_idx, 0) | |
147 | ||
148 | #define CFG_GATE_SETCLR(_id, _offset, _bit_idx)\ | |
149 | _CFG_GATE(_id, _offset, _bit_idx, RCC_CLR_OFFSET) | |
150 | ||
151 | static struct stm32_gate_cfg stm32mp13_gates[] = { | |
152 | CFG_GATE(GATE_MCO1, RCC_MCO1CFGR, 12), | |
153 | CFG_GATE(GATE_MCO2, RCC_MCO2CFGR, 12), | |
154 | CFG_GATE(GATE_DBGCK, RCC_DBGCFGR, 8), | |
155 | CFG_GATE(GATE_TRACECK, RCC_DBGCFGR, 9), | |
156 | CFG_GATE(GATE_DDRC1, RCC_DDRITFCR, 0), | |
157 | CFG_GATE(GATE_DDRC1LP, RCC_DDRITFCR, 1), | |
158 | CFG_GATE(GATE_DDRPHYC, RCC_DDRITFCR, 4), | |
159 | CFG_GATE(GATE_DDRPHYCLP, RCC_DDRITFCR, 5), | |
160 | CFG_GATE(GATE_DDRCAPB, RCC_DDRITFCR, 6), | |
161 | CFG_GATE(GATE_DDRCAPBLP, RCC_DDRITFCR, 7), | |
162 | CFG_GATE(GATE_AXIDCG, RCC_DDRITFCR, 8), | |
163 | CFG_GATE(GATE_DDRPHYCAPB, RCC_DDRITFCR, 9), | |
164 | CFG_GATE(GATE_DDRPHYCAPBLP, RCC_DDRITFCR, 10), | |
165 | CFG_GATE_SETCLR(GATE_TIM2, RCC_MP_APB1ENSETR, 0), | |
166 | CFG_GATE_SETCLR(GATE_TIM3, RCC_MP_APB1ENSETR, 1), | |
167 | CFG_GATE_SETCLR(GATE_TIM4, RCC_MP_APB1ENSETR, 2), | |
168 | CFG_GATE_SETCLR(GATE_TIM5, RCC_MP_APB1ENSETR, 3), | |
169 | CFG_GATE_SETCLR(GATE_TIM6, RCC_MP_APB1ENSETR, 4), | |
170 | CFG_GATE_SETCLR(GATE_TIM7, RCC_MP_APB1ENSETR, 5), | |
171 | CFG_GATE_SETCLR(GATE_LPTIM1, RCC_MP_APB1ENSETR, 9), | |
172 | CFG_GATE_SETCLR(GATE_SPI2, RCC_MP_APB1ENSETR, 11), | |
173 | CFG_GATE_SETCLR(GATE_SPI3, RCC_MP_APB1ENSETR, 12), | |
174 | CFG_GATE_SETCLR(GATE_USART3, RCC_MP_APB1ENSETR, 15), | |
175 | CFG_GATE_SETCLR(GATE_UART4, RCC_MP_APB1ENSETR, 16), | |
176 | CFG_GATE_SETCLR(GATE_UART5, RCC_MP_APB1ENSETR, 17), | |
177 | CFG_GATE_SETCLR(GATE_UART7, RCC_MP_APB1ENSETR, 18), | |
178 | CFG_GATE_SETCLR(GATE_UART8, RCC_MP_APB1ENSETR, 19), | |
179 | CFG_GATE_SETCLR(GATE_I2C1, RCC_MP_APB1ENSETR, 21), | |
180 | CFG_GATE_SETCLR(GATE_I2C2, RCC_MP_APB1ENSETR, 22), | |
181 | CFG_GATE_SETCLR(GATE_SPDIF, RCC_MP_APB1ENSETR, 26), | |
182 | CFG_GATE_SETCLR(GATE_TIM1, RCC_MP_APB2ENSETR, 0), | |
183 | CFG_GATE_SETCLR(GATE_TIM8, RCC_MP_APB2ENSETR, 1), | |
184 | CFG_GATE_SETCLR(GATE_SPI1, RCC_MP_APB2ENSETR, 8), | |
185 | CFG_GATE_SETCLR(GATE_USART6, RCC_MP_APB2ENSETR, 13), | |
186 | CFG_GATE_SETCLR(GATE_SAI1, RCC_MP_APB2ENSETR, 16), | |
187 | CFG_GATE_SETCLR(GATE_SAI2, RCC_MP_APB2ENSETR, 17), | |
188 | CFG_GATE_SETCLR(GATE_DFSDM, RCC_MP_APB2ENSETR, 20), | |
189 | CFG_GATE_SETCLR(GATE_ADFSDM, RCC_MP_APB2ENSETR, 21), | |
190 | CFG_GATE_SETCLR(GATE_FDCAN, RCC_MP_APB2ENSETR, 24), | |
191 | CFG_GATE_SETCLR(GATE_LPTIM2, RCC_MP_APB3ENSETR, 0), | |
192 | CFG_GATE_SETCLR(GATE_LPTIM3, RCC_MP_APB3ENSETR, 1), | |
193 | CFG_GATE_SETCLR(GATE_LPTIM4, RCC_MP_APB3ENSETR, 2), | |
194 | CFG_GATE_SETCLR(GATE_LPTIM5, RCC_MP_APB3ENSETR, 3), | |
195 | CFG_GATE_SETCLR(GATE_VREF, RCC_MP_APB3ENSETR, 13), | |
196 | CFG_GATE_SETCLR(GATE_DTS, RCC_MP_APB3ENSETR, 16), | |
197 | CFG_GATE_SETCLR(GATE_PMBCTRL, RCC_MP_APB3ENSETR, 17), | |
198 | CFG_GATE_SETCLR(GATE_HDP, RCC_MP_APB3ENSETR, 20), | |
199 | CFG_GATE_SETCLR(GATE_SYSCFG, RCC_MP_NS_APB3ENSETR, 0), | |
200 | CFG_GATE_SETCLR(GATE_DCMIPP, RCC_MP_APB4ENSETR, 1), | |
201 | CFG_GATE_SETCLR(GATE_DDRPERFM, RCC_MP_APB4ENSETR, 8), | |
202 | CFG_GATE_SETCLR(GATE_IWDG2APB, RCC_MP_APB4ENSETR, 15), | |
203 | CFG_GATE_SETCLR(GATE_USBPHY, RCC_MP_APB4ENSETR, 16), | |
204 | CFG_GATE_SETCLR(GATE_STGENRO, RCC_MP_APB4ENSETR, 20), | |
205 | CFG_GATE_SETCLR(GATE_LTDC, RCC_MP_NS_APB4ENSETR, 0), | |
206 | CFG_GATE_SETCLR(GATE_RTCAPB, RCC_MP_APB5ENSETR, 8), | |
207 | CFG_GATE_SETCLR(GATE_TZC, RCC_MP_APB5ENSETR, 11), | |
208 | CFG_GATE_SETCLR(GATE_ETZPC, RCC_MP_APB5ENSETR, 13), | |
209 | CFG_GATE_SETCLR(GATE_IWDG1APB, RCC_MP_APB5ENSETR, 15), | |
210 | CFG_GATE_SETCLR(GATE_BSEC, RCC_MP_APB5ENSETR, 16), | |
211 | CFG_GATE_SETCLR(GATE_STGENC, RCC_MP_APB5ENSETR, 20), | |
212 | CFG_GATE_SETCLR(GATE_USART1, RCC_MP_APB6ENSETR, 0), | |
213 | CFG_GATE_SETCLR(GATE_USART2, RCC_MP_APB6ENSETR, 1), | |
214 | CFG_GATE_SETCLR(GATE_SPI4, RCC_MP_APB6ENSETR, 2), | |
215 | CFG_GATE_SETCLR(GATE_SPI5, RCC_MP_APB6ENSETR, 3), | |
216 | CFG_GATE_SETCLR(GATE_I2C3, RCC_MP_APB6ENSETR, 4), | |
217 | CFG_GATE_SETCLR(GATE_I2C4, RCC_MP_APB6ENSETR, 5), | |
218 | CFG_GATE_SETCLR(GATE_I2C5, RCC_MP_APB6ENSETR, 6), | |
219 | CFG_GATE_SETCLR(GATE_TIM12, RCC_MP_APB6ENSETR, 7), | |
220 | CFG_GATE_SETCLR(GATE_TIM13, RCC_MP_APB6ENSETR, 8), | |
221 | CFG_GATE_SETCLR(GATE_TIM14, RCC_MP_APB6ENSETR, 9), | |
222 | CFG_GATE_SETCLR(GATE_TIM15, RCC_MP_APB6ENSETR, 10), | |
223 | CFG_GATE_SETCLR(GATE_TIM16, RCC_MP_APB6ENSETR, 11), | |
224 | CFG_GATE_SETCLR(GATE_TIM17, RCC_MP_APB6ENSETR, 12), | |
225 | CFG_GATE_SETCLR(GATE_DMA1, RCC_MP_AHB2ENSETR, 0), | |
226 | CFG_GATE_SETCLR(GATE_DMA2, RCC_MP_AHB2ENSETR, 1), | |
227 | CFG_GATE_SETCLR(GATE_DMAMUX1, RCC_MP_AHB2ENSETR, 2), | |
228 | CFG_GATE_SETCLR(GATE_DMA3, RCC_MP_AHB2ENSETR, 3), | |
229 | CFG_GATE_SETCLR(GATE_DMAMUX2, RCC_MP_AHB2ENSETR, 4), | |
230 | CFG_GATE_SETCLR(GATE_ADC1, RCC_MP_AHB2ENSETR, 5), | |
231 | CFG_GATE_SETCLR(GATE_ADC2, RCC_MP_AHB2ENSETR, 6), | |
232 | CFG_GATE_SETCLR(GATE_USBO, RCC_MP_AHB2ENSETR, 8), | |
233 | CFG_GATE_SETCLR(GATE_TSC, RCC_MP_AHB4ENSETR, 15), | |
234 | CFG_GATE_SETCLR(GATE_GPIOA, RCC_MP_NS_AHB4ENSETR, 0), | |
235 | CFG_GATE_SETCLR(GATE_GPIOB, RCC_MP_NS_AHB4ENSETR, 1), | |
236 | CFG_GATE_SETCLR(GATE_GPIOC, RCC_MP_NS_AHB4ENSETR, 2), | |
237 | CFG_GATE_SETCLR(GATE_GPIOD, RCC_MP_NS_AHB4ENSETR, 3), | |
238 | CFG_GATE_SETCLR(GATE_GPIOE, RCC_MP_NS_AHB4ENSETR, 4), | |
239 | CFG_GATE_SETCLR(GATE_GPIOF, RCC_MP_NS_AHB4ENSETR, 5), | |
240 | CFG_GATE_SETCLR(GATE_GPIOG, RCC_MP_NS_AHB4ENSETR, 6), | |
241 | CFG_GATE_SETCLR(GATE_GPIOH, RCC_MP_NS_AHB4ENSETR, 7), | |
242 | CFG_GATE_SETCLR(GATE_GPIOI, RCC_MP_NS_AHB4ENSETR, 8), | |
243 | CFG_GATE_SETCLR(GATE_PKA, RCC_MP_AHB5ENSETR, 2), | |
244 | CFG_GATE_SETCLR(GATE_SAES, RCC_MP_AHB5ENSETR, 3), | |
245 | CFG_GATE_SETCLR(GATE_CRYP1, RCC_MP_AHB5ENSETR, 4), | |
246 | CFG_GATE_SETCLR(GATE_HASH1, RCC_MP_AHB5ENSETR, 5), | |
247 | CFG_GATE_SETCLR(GATE_RNG1, RCC_MP_AHB5ENSETR, 6), | |
248 | CFG_GATE_SETCLR(GATE_BKPSRAM, RCC_MP_AHB5ENSETR, 8), | |
249 | CFG_GATE_SETCLR(GATE_AXIMC, RCC_MP_AHB5ENSETR, 16), | |
250 | CFG_GATE_SETCLR(GATE_MCE, RCC_MP_AHB6ENSETR, 1), | |
251 | CFG_GATE_SETCLR(GATE_ETH1CK, RCC_MP_AHB6ENSETR, 7), | |
252 | CFG_GATE_SETCLR(GATE_ETH1TX, RCC_MP_AHB6ENSETR, 8), | |
253 | CFG_GATE_SETCLR(GATE_ETH1RX, RCC_MP_AHB6ENSETR, 9), | |
254 | CFG_GATE_SETCLR(GATE_ETH1MAC, RCC_MP_AHB6ENSETR, 10), | |
255 | CFG_GATE_SETCLR(GATE_FMC, RCC_MP_AHB6ENSETR, 12), | |
256 | CFG_GATE_SETCLR(GATE_QSPI, RCC_MP_AHB6ENSETR, 14), | |
257 | CFG_GATE_SETCLR(GATE_SDMMC1, RCC_MP_AHB6ENSETR, 16), | |
258 | CFG_GATE_SETCLR(GATE_SDMMC2, RCC_MP_AHB6ENSETR, 17), | |
259 | CFG_GATE_SETCLR(GATE_CRC1, RCC_MP_AHB6ENSETR, 20), | |
260 | CFG_GATE_SETCLR(GATE_USBH, RCC_MP_AHB6ENSETR, 24), | |
261 | CFG_GATE_SETCLR(GATE_ETH2CK, RCC_MP_AHB6ENSETR, 27), | |
262 | CFG_GATE_SETCLR(GATE_ETH2TX, RCC_MP_AHB6ENSETR, 28), | |
263 | CFG_GATE_SETCLR(GATE_ETH2RX, RCC_MP_AHB6ENSETR, 29), | |
264 | CFG_GATE_SETCLR(GATE_ETH2MAC, RCC_MP_AHB6ENSETR, 30), | |
265 | CFG_GATE_SETCLR(GATE_ETH1STP, RCC_MP_AHB6LPENSETR, 11), | |
266 | CFG_GATE_SETCLR(GATE_ETH2STP, RCC_MP_AHB6LPENSETR, 31), | |
267 | CFG_GATE_SETCLR(GATE_MDMA, RCC_MP_NS_AHB6ENSETR, 0), | |
268 | }; | |
269 | ||
270 | /* STM32 Divivers definition */ | |
271 | enum enum_div_cfg { | |
272 | DIV_RTC, | |
273 | DIV_HSI, | |
274 | DIV_MCO1, | |
275 | DIV_MCO2, | |
276 | DIV_TRACE, | |
277 | DIV_ETH1PTP, | |
278 | DIV_ETH2PTP, | |
279 | DIV_NB | |
280 | }; | |
281 | ||
282 | static const struct clk_div_table ck_trace_div_table[] = { | |
283 | { 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 }, | |
284 | { 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 }, | |
285 | { 0 }, | |
286 | }; | |
287 | ||
288 | #define CFG_DIV(_id, _offset, _shift, _width, _flags, _table, _ready)\ | |
289 | [(_id)] = {\ | |
290 | .offset = (_offset),\ | |
291 | .shift = (_shift),\ | |
292 | .width = (_width),\ | |
293 | .flags = (_flags),\ | |
294 | .table = (_table),\ | |
295 | .ready = (_ready),\ | |
296 | } | |
297 | ||
298 | static const struct stm32_div_cfg stm32mp13_dividers[DIV_NB] = { | |
299 | CFG_DIV(DIV_RTC, RCC_RTCDIVR, 0, 6, 0, NULL, DIV_NO_RDY), | |
300 | CFG_DIV(DIV_MCO1, RCC_MCO1CFGR, 4, 4, 0, NULL, DIV_NO_RDY), | |
301 | CFG_DIV(DIV_MCO2, RCC_MCO2CFGR, 4, 4, 0, NULL, DIV_NO_RDY), | |
302 | CFG_DIV(DIV_TRACE, RCC_DBGCFGR, 0, 3, 0, ck_trace_div_table, DIV_NO_RDY), | |
303 | CFG_DIV(DIV_ETH1PTP, RCC_ETH12CKSELR, 4, 4, 0, NULL, DIV_NO_RDY), | |
304 | CFG_DIV(DIV_ETH2PTP, RCC_ETH12CKSELR, 12, 4, 0, NULL, DIV_NO_RDY), | |
305 | }; | |
306 | ||
307 | /* STM32 Muxes definition */ | |
308 | enum enum_mux_cfg { | |
309 | MUX_ADC1, | |
310 | MUX_ADC2, | |
311 | MUX_DCMIPP, | |
312 | MUX_ETH1, | |
313 | MUX_ETH2, | |
314 | MUX_FDCAN, | |
315 | MUX_FMC, | |
316 | MUX_I2C12, | |
317 | MUX_I2C3, | |
318 | MUX_I2C4, | |
319 | MUX_I2C5, | |
320 | MUX_LPTIM1, | |
321 | MUX_LPTIM2, | |
322 | MUX_LPTIM3, | |
323 | MUX_LPTIM45, | |
324 | MUX_MCO1, | |
325 | MUX_MCO2, | |
326 | MUX_QSPI, | |
327 | MUX_RNG1, | |
328 | MUX_SAES, | |
329 | MUX_SAI1, | |
330 | MUX_SAI2, | |
331 | MUX_SDMMC1, | |
332 | MUX_SDMMC2, | |
333 | MUX_SPDIF, | |
334 | MUX_SPI1, | |
335 | MUX_SPI23, | |
336 | MUX_SPI4, | |
337 | MUX_SPI5, | |
338 | MUX_STGEN, | |
339 | MUX_UART1, | |
340 | MUX_UART2, | |
341 | MUX_UART4, | |
342 | MUX_UART6, | |
343 | MUX_UART35, | |
344 | MUX_UART78, | |
345 | MUX_USBO, | |
346 | MUX_USBPHY, | |
347 | MUX_NB | |
348 | }; | |
349 | ||
350 | #define _CFG_MUX(_id, _offset, _shift, _witdh, _ready, _flags)\ | |
351 | [_id] = {\ | |
352 | .offset = (_offset),\ | |
353 | .shift = (_shift),\ | |
354 | .width = (_witdh),\ | |
355 | .ready = (_ready),\ | |
356 | .flags = (_flags),\ | |
357 | } | |
358 | ||
359 | #define CFG_MUX(_id, _offset, _shift, _witdh)\ | |
360 | _CFG_MUX(_id, _offset, _shift, _witdh, MUX_NO_RDY, 0) | |
361 | ||
362 | static const struct stm32_mux_cfg stm32mp13_muxes[] = { | |
363 | CFG_MUX(MUX_I2C12, RCC_I2C12CKSELR, 0, 3), | |
364 | CFG_MUX(MUX_LPTIM45, RCC_LPTIM45CKSELR, 0, 3), | |
365 | CFG_MUX(MUX_SPI23, RCC_SPI2S23CKSELR, 0, 3), | |
366 | CFG_MUX(MUX_UART35, RCC_UART35CKSELR, 0, 3), | |
367 | CFG_MUX(MUX_UART78, RCC_UART78CKSELR, 0, 3), | |
368 | CFG_MUX(MUX_ADC1, RCC_ADC12CKSELR, 0, 2), | |
369 | CFG_MUX(MUX_ADC2, RCC_ADC12CKSELR, 2, 2), | |
370 | CFG_MUX(MUX_DCMIPP, RCC_DCMIPPCKSELR, 0, 2), | |
371 | CFG_MUX(MUX_ETH1, RCC_ETH12CKSELR, 0, 2), | |
372 | CFG_MUX(MUX_ETH2, RCC_ETH12CKSELR, 8, 2), | |
373 | CFG_MUX(MUX_FDCAN, RCC_FDCANCKSELR, 0, 2), | |
374 | CFG_MUX(MUX_I2C3, RCC_I2C345CKSELR, 0, 3), | |
375 | CFG_MUX(MUX_I2C4, RCC_I2C345CKSELR, 3, 3), | |
376 | CFG_MUX(MUX_I2C5, RCC_I2C345CKSELR, 6, 3), | |
377 | CFG_MUX(MUX_LPTIM1, RCC_LPTIM1CKSELR, 0, 3), | |
378 | CFG_MUX(MUX_LPTIM2, RCC_LPTIM23CKSELR, 0, 3), | |
379 | CFG_MUX(MUX_LPTIM3, RCC_LPTIM23CKSELR, 3, 3), | |
380 | CFG_MUX(MUX_MCO1, RCC_MCO1CFGR, 0, 3), | |
381 | CFG_MUX(MUX_MCO2, RCC_MCO2CFGR, 0, 3), | |
382 | CFG_MUX(MUX_RNG1, RCC_RNG1CKSELR, 0, 2), | |
383 | CFG_MUX(MUX_SAES, RCC_SAESCKSELR, 0, 2), | |
384 | CFG_MUX(MUX_SAI1, RCC_SAI1CKSELR, 0, 3), | |
385 | CFG_MUX(MUX_SAI2, RCC_SAI2CKSELR, 0, 3), | |
386 | CFG_MUX(MUX_SPDIF, RCC_SPDIFCKSELR, 0, 2), | |
387 | CFG_MUX(MUX_SPI1, RCC_SPI2S1CKSELR, 0, 3), | |
388 | CFG_MUX(MUX_SPI4, RCC_SPI45CKSELR, 0, 3), | |
389 | CFG_MUX(MUX_SPI5, RCC_SPI45CKSELR, 3, 3), | |
390 | CFG_MUX(MUX_STGEN, RCC_STGENCKSELR, 0, 2), | |
391 | CFG_MUX(MUX_UART1, RCC_UART12CKSELR, 0, 3), | |
392 | CFG_MUX(MUX_UART2, RCC_UART12CKSELR, 3, 3), | |
393 | CFG_MUX(MUX_UART4, RCC_UART4CKSELR, 0, 3), | |
394 | CFG_MUX(MUX_UART6, RCC_UART6CKSELR, 0, 3), | |
395 | CFG_MUX(MUX_USBO, RCC_USBCKSELR, 4, 1), | |
396 | CFG_MUX(MUX_USBPHY, RCC_USBCKSELR, 0, 2), | |
397 | CFG_MUX(MUX_FMC, RCC_FMCCKSELR, 0, 2), | |
398 | CFG_MUX(MUX_QSPI, RCC_QSPICKSELR, 0, 2), | |
399 | CFG_MUX(MUX_SDMMC1, RCC_SDMMC12CKSELR, 0, 3), | |
400 | CFG_MUX(MUX_SDMMC2, RCC_SDMMC12CKSELR, 3, 3), | |
401 | }; | |
402 | ||
93e336c2 GF |
403 | struct clk_stm32_securiy { |
404 | u32 offset; | |
405 | u8 bit_idx; | |
406 | unsigned long scmi_id; | |
407 | }; | |
408 | ||
409 | enum security_clk { | |
410 | SECF_NONE, | |
411 | SECF_LPTIM2, | |
412 | SECF_LPTIM3, | |
413 | SECF_VREF, | |
414 | SECF_DCMIPP, | |
415 | SECF_USBPHY, | |
416 | SECF_TZC, | |
417 | SECF_ETZPC, | |
418 | SECF_IWDG1, | |
419 | SECF_BSEC, | |
420 | SECF_STGENC, | |
421 | SECF_STGENRO, | |
422 | SECF_USART1, | |
423 | SECF_USART2, | |
424 | SECF_SPI4, | |
425 | SECF_SPI5, | |
426 | SECF_I2C3, | |
427 | SECF_I2C4, | |
428 | SECF_I2C5, | |
429 | SECF_TIM12, | |
430 | SECF_TIM13, | |
431 | SECF_TIM14, | |
432 | SECF_TIM15, | |
433 | SECF_TIM16, | |
434 | SECF_TIM17, | |
435 | SECF_DMA3, | |
436 | SECF_DMAMUX2, | |
437 | SECF_ADC1, | |
438 | SECF_ADC2, | |
439 | SECF_USBO, | |
440 | SECF_TSC, | |
441 | SECF_PKA, | |
442 | SECF_SAES, | |
443 | SECF_CRYP1, | |
444 | SECF_HASH1, | |
445 | SECF_RNG1, | |
446 | SECF_BKPSRAM, | |
447 | SECF_MCE, | |
448 | SECF_FMC, | |
449 | SECF_QSPI, | |
450 | SECF_SDMMC1, | |
451 | SECF_SDMMC2, | |
452 | SECF_ETH1CK, | |
453 | SECF_ETH1TX, | |
454 | SECF_ETH1RX, | |
455 | SECF_ETH1MAC, | |
456 | SECF_ETH1STP, | |
457 | SECF_ETH2CK, | |
458 | SECF_ETH2TX, | |
459 | SECF_ETH2RX, | |
460 | SECF_ETH2MAC, | |
461 | SECF_ETH2STP, | |
462 | SECF_MCO1, | |
463 | SECF_MCO2 | |
464 | }; | |
465 | ||
466 | #define SECF(_sec_id, _offset, _bit_idx)[_sec_id] = {\ | |
467 | .offset = _offset,\ | |
468 | .bit_idx = _bit_idx,\ | |
469 | .scmi_id = -1,\ | |
470 | } | |
471 | ||
472 | static const struct clk_stm32_securiy stm32mp13_security[] = { | |
473 | SECF(SECF_LPTIM2, RCC_APB3SECSR, RCC_APB3SECSR_LPTIM2SECF), | |
474 | SECF(SECF_LPTIM3, RCC_APB3SECSR, RCC_APB3SECSR_LPTIM3SECF), | |
475 | SECF(SECF_VREF, RCC_APB3SECSR, RCC_APB3SECSR_VREFSECF), | |
476 | SECF(SECF_DCMIPP, RCC_APB4SECSR, RCC_APB4SECSR_DCMIPPSECF), | |
477 | SECF(SECF_USBPHY, RCC_APB4SECSR, RCC_APB4SECSR_USBPHYSECF), | |
478 | SECF(SECF_TZC, RCC_APB5SECSR, RCC_APB5SECSR_TZCSECF), | |
479 | SECF(SECF_ETZPC, RCC_APB5SECSR, RCC_APB5SECSR_ETZPCSECF), | |
480 | SECF(SECF_IWDG1, RCC_APB5SECSR, RCC_APB5SECSR_IWDG1SECF), | |
481 | SECF(SECF_BSEC, RCC_APB5SECSR, RCC_APB5SECSR_BSECSECF), | |
482 | SECF(SECF_STGENC, RCC_APB5SECSR, RCC_APB5SECSR_STGENCSECF), | |
483 | SECF(SECF_STGENRO, RCC_APB5SECSR, RCC_APB5SECSR_STGENROSECF), | |
484 | SECF(SECF_USART1, RCC_APB6SECSR, RCC_APB6SECSR_USART1SECF), | |
485 | SECF(SECF_USART2, RCC_APB6SECSR, RCC_APB6SECSR_USART2SECF), | |
486 | SECF(SECF_SPI4, RCC_APB6SECSR, RCC_APB6SECSR_SPI4SECF), | |
487 | SECF(SECF_SPI5, RCC_APB6SECSR, RCC_APB6SECSR_SPI5SECF), | |
488 | SECF(SECF_I2C3, RCC_APB6SECSR, RCC_APB6SECSR_I2C3SECF), | |
489 | SECF(SECF_I2C4, RCC_APB6SECSR, RCC_APB6SECSR_I2C4SECF), | |
490 | SECF(SECF_I2C5, RCC_APB6SECSR, RCC_APB6SECSR_I2C5SECF), | |
491 | SECF(SECF_TIM12, RCC_APB6SECSR, RCC_APB6SECSR_TIM12SECF), | |
492 | SECF(SECF_TIM13, RCC_APB6SECSR, RCC_APB6SECSR_TIM13SECF), | |
493 | SECF(SECF_TIM14, RCC_APB6SECSR, RCC_APB6SECSR_TIM14SECF), | |
494 | SECF(SECF_TIM15, RCC_APB6SECSR, RCC_APB6SECSR_TIM15SECF), | |
495 | SECF(SECF_TIM16, RCC_APB6SECSR, RCC_APB6SECSR_TIM16SECF), | |
496 | SECF(SECF_TIM17, RCC_APB6SECSR, RCC_APB6SECSR_TIM17SECF), | |
497 | SECF(SECF_DMA3, RCC_AHB2SECSR, RCC_AHB2SECSR_DMA3SECF), | |
498 | SECF(SECF_DMAMUX2, RCC_AHB2SECSR, RCC_AHB2SECSR_DMAMUX2SECF), | |
499 | SECF(SECF_ADC1, RCC_AHB2SECSR, RCC_AHB2SECSR_ADC1SECF), | |
500 | SECF(SECF_ADC2, RCC_AHB2SECSR, RCC_AHB2SECSR_ADC2SECF), | |
501 | SECF(SECF_USBO, RCC_AHB2SECSR, RCC_AHB2SECSR_USBOSECF), | |
502 | SECF(SECF_TSC, RCC_AHB4SECSR, RCC_AHB4SECSR_TSCSECF), | |
503 | SECF(SECF_PKA, RCC_AHB5SECSR, RCC_AHB5SECSR_PKASECF), | |
504 | SECF(SECF_SAES, RCC_AHB5SECSR, RCC_AHB5SECSR_SAESSECF), | |
505 | SECF(SECF_CRYP1, RCC_AHB5SECSR, RCC_AHB5SECSR_CRYP1SECF), | |
506 | SECF(SECF_HASH1, RCC_AHB5SECSR, RCC_AHB5SECSR_HASH1SECF), | |
507 | SECF(SECF_RNG1, RCC_AHB5SECSR, RCC_AHB5SECSR_RNG1SECF), | |
508 | SECF(SECF_BKPSRAM, RCC_AHB5SECSR, RCC_AHB5SECSR_BKPSRAMSECF), | |
509 | SECF(SECF_MCE, RCC_AHB6SECSR, RCC_AHB6SECSR_MCESECF), | |
510 | SECF(SECF_FMC, RCC_AHB6SECSR, RCC_AHB6SECSR_FMCSECF), | |
511 | SECF(SECF_QSPI, RCC_AHB6SECSR, RCC_AHB6SECSR_QSPISECF), | |
512 | SECF(SECF_SDMMC1, RCC_AHB6SECSR, RCC_AHB6SECSR_SDMMC1SECF), | |
513 | SECF(SECF_SDMMC2, RCC_AHB6SECSR, RCC_AHB6SECSR_SDMMC2SECF), | |
514 | SECF(SECF_ETH1CK, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH1CKSECF), | |
515 | SECF(SECF_ETH1TX, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH1TXSECF), | |
516 | SECF(SECF_ETH1RX, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH1RXSECF), | |
517 | SECF(SECF_ETH1MAC, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH1MACSECF), | |
518 | SECF(SECF_ETH1STP, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH1STPSECF), | |
519 | SECF(SECF_ETH2CK, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH2CKSECF), | |
520 | SECF(SECF_ETH2TX, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH2TXSECF), | |
521 | SECF(SECF_ETH2RX, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH2RXSECF), | |
522 | SECF(SECF_ETH2MAC, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH2MACSECF), | |
523 | SECF(SECF_ETH2STP, RCC_AHB6SECSR, RCC_AHB6SECSR_ETH2STPSECF), | |
524 | SECF(SECF_MCO1, RCC_SECCFGR, RCC_SECCFGR_MCO1SEC), | |
525 | SECF(SECF_MCO2, RCC_SECCFGR, RCC_SECCFGR_MCO2SEC), | |
526 | }; | |
527 | ||
f95cea83 GF |
528 | static const char * const eth12_src[] = { |
529 | "pll4_p", "pll3_q" | |
530 | }; | |
531 | ||
5f0d4721 GF |
532 | static const char * const mco1_src[] = { |
533 | "ck_hsi", "ck_hse", "ck_csi", "ck_lsi", "ck_lse" | |
534 | }; | |
535 | ||
536 | static const char * const mco2_src[] = { | |
537 | "ck_mpu", "ck_axi", "ck_mlahb", "pll4_p", "ck_hse", "ck_hsi" | |
538 | }; | |
539 | ||
f95cea83 GF |
540 | static struct clk_stm32_mux ck_ker_eth1 = { |
541 | .mux_id = MUX_ETH1, | |
542 | .hw.init = CLK_HW_INIT_PARENTS("ck_ker_eth1", eth12_src, &clk_stm32_mux_ops, | |
543 | CLK_OPS_PARENT_ENABLE | CLK_SET_RATE_NO_REPARENT), | |
544 | }; | |
545 | ||
95f5e0a4 GF |
546 | static struct clk_stm32_gate eth1ck_k = { |
547 | .gate_id = GATE_ETH1CK, | |
548 | .hw.init = CLK_HW_INIT_HW("eth1ck_k", &ck_ker_eth1.hw, &clk_stm32_gate_ops, 0), | |
549 | }; | |
550 | ||
720e34ab GF |
551 | static struct clk_stm32_div eth1ptp_k = { |
552 | .div_id = DIV_ETH1PTP, | |
553 | .hw.init = CLK_HW_INIT_HW("eth1ptp_k", &ck_ker_eth1.hw, &clk_stm32_divider_ops, | |
554 | CLK_SET_RATE_NO_REPARENT), | |
555 | }; | |
556 | ||
5f0d4721 GF |
557 | static struct clk_stm32_composite ck_mco1 = { |
558 | .gate_id = GATE_MCO1, | |
559 | .mux_id = MUX_MCO1, | |
560 | .div_id = DIV_MCO1, | |
561 | .hw.init = CLK_HW_INIT_PARENTS("ck_mco1", mco1_src, &clk_stm32_composite_ops, | |
562 | CLK_OPS_PARENT_ENABLE | CLK_SET_RATE_NO_REPARENT | | |
563 | CLK_IGNORE_UNUSED), | |
564 | }; | |
565 | ||
566 | static struct clk_stm32_composite ck_mco2 = { | |
567 | .gate_id = GATE_MCO2, | |
568 | .mux_id = MUX_MCO2, | |
569 | .div_id = DIV_MCO2, | |
570 | .hw.init = CLK_HW_INIT_PARENTS("ck_mco2", mco2_src, &clk_stm32_composite_ops, | |
571 | CLK_OPS_PARENT_ENABLE | CLK_SET_RATE_NO_REPARENT | | |
572 | CLK_IGNORE_UNUSED), | |
573 | }; | |
574 | ||
637cee5f | 575 | static const struct clock_config stm32mp13_clock_cfg[] = { |
93e336c2 GF |
576 | STM32_MUX_CFG(NO_ID, ck_ker_eth1, SECF_ETH1CK), |
577 | STM32_GATE_CFG(ETH1CK_K, eth1ck_k, SECF_ETH1CK), | |
578 | STM32_DIV_CFG(ETH1PTP_K, eth1ptp_k, SECF_ETH1CK), | |
579 | STM32_COMPOSITE_CFG(CK_MCO1, ck_mco1, SECF_MCO1), | |
580 | STM32_COMPOSITE_CFG(CK_MCO2, ck_mco2, SECF_MCO2), | |
637cee5f GF |
581 | }; |
582 | ||
93e336c2 GF |
583 | static int stm32mp13_clock_is_provided_by_secure(void __iomem *base, |
584 | const struct clock_config *cfg) | |
585 | { | |
586 | int sec_id = cfg->sec_id; | |
587 | ||
588 | if (sec_id != SECF_NONE) { | |
589 | const struct clk_stm32_securiy *secf; | |
590 | ||
591 | secf = &stm32mp13_security[sec_id]; | |
592 | ||
593 | return !!(readl(base + secf->offset) & BIT(secf->bit_idx)); | |
594 | } | |
595 | ||
596 | return 0; | |
597 | } | |
598 | ||
637cee5f GF |
599 | static u16 stm32mp13_cpt_gate[GATE_NB]; |
600 | ||
601 | static struct clk_stm32_clock_data stm32mp13_clock_data = { | |
602 | .gate_cpt = stm32mp13_cpt_gate, | |
603 | .gates = stm32mp13_gates, | |
604 | .muxes = stm32mp13_muxes, | |
605 | .dividers = stm32mp13_dividers, | |
606 | }; | |
607 | ||
608 | static const struct stm32_rcc_match_data stm32mp13_data = { | |
609 | .tab_clocks = stm32mp13_clock_cfg, | |
610 | .num_clocks = ARRAY_SIZE(stm32mp13_clock_cfg), | |
611 | .clock_data = &stm32mp13_clock_data, | |
93e336c2 | 612 | .check_security = &stm32mp13_clock_is_provided_by_secure, |
637cee5f GF |
613 | .maxbinding = STM32MP1_LAST_CLK, |
614 | .clear_offset = RCC_CLR_OFFSET, | |
615 | }; | |
616 | ||
617 | static const struct of_device_id stm32mp13_match_data[] = { | |
618 | { | |
619 | .compatible = "st,stm32mp13-rcc", | |
620 | .data = &stm32mp13_data, | |
621 | }, | |
622 | { } | |
623 | }; | |
624 | MODULE_DEVICE_TABLE(of, stm32mp13_match_data); | |
625 | ||
626 | static int stm32mp1_rcc_init(struct device *dev) | |
627 | { | |
628 | void __iomem *rcc_base; | |
629 | int ret = -ENOMEM; | |
630 | ||
631 | rcc_base = of_iomap(dev_of_node(dev), 0); | |
632 | if (!rcc_base) { | |
633 | dev_err(dev, "%pOFn: unable to map resource", dev_of_node(dev)); | |
634 | goto out; | |
635 | } | |
636 | ||
637 | ret = stm32_rcc_init(dev, stm32mp13_match_data, rcc_base); | |
638 | out: | |
639 | if (ret) { | |
640 | if (rcc_base) | |
641 | iounmap(rcc_base); | |
642 | ||
643 | of_node_put(dev_of_node(dev)); | |
644 | } | |
645 | ||
646 | return ret; | |
647 | } | |
648 | ||
649 | static int get_clock_deps(struct device *dev) | |
650 | { | |
651 | static const char * const clock_deps_name[] = { | |
652 | "hsi", "hse", "csi", "lsi", "lse", | |
653 | }; | |
654 | size_t deps_size = sizeof(struct clk *) * ARRAY_SIZE(clock_deps_name); | |
655 | struct clk **clk_deps; | |
656 | int i; | |
657 | ||
658 | clk_deps = devm_kzalloc(dev, deps_size, GFP_KERNEL); | |
659 | if (!clk_deps) | |
660 | return -ENOMEM; | |
661 | ||
662 | for (i = 0; i < ARRAY_SIZE(clock_deps_name); i++) { | |
663 | struct clk *clk = of_clk_get_by_name(dev_of_node(dev), | |
664 | clock_deps_name[i]); | |
665 | ||
666 | if (IS_ERR(clk)) { | |
667 | if (PTR_ERR(clk) != -EINVAL && PTR_ERR(clk) != -ENOENT) | |
668 | return PTR_ERR(clk); | |
669 | } else { | |
670 | /* Device gets a reference count on the clock */ | |
671 | clk_deps[i] = devm_clk_get(dev, __clk_get_name(clk)); | |
672 | clk_put(clk); | |
673 | } | |
674 | } | |
675 | ||
676 | return 0; | |
677 | } | |
678 | ||
679 | static int stm32mp1_rcc_clocks_probe(struct platform_device *pdev) | |
680 | { | |
681 | struct device *dev = &pdev->dev; | |
682 | int ret = get_clock_deps(dev); | |
683 | ||
684 | if (!ret) | |
685 | ret = stm32mp1_rcc_init(dev); | |
686 | ||
687 | return ret; | |
688 | } | |
689 | ||
690 | static int stm32mp1_rcc_clocks_remove(struct platform_device *pdev) | |
691 | { | |
692 | struct device *dev = &pdev->dev; | |
693 | struct device_node *child, *np = dev_of_node(dev); | |
694 | ||
695 | for_each_available_child_of_node(np, child) | |
696 | of_clk_del_provider(child); | |
697 | ||
698 | return 0; | |
699 | } | |
700 | ||
701 | static struct platform_driver stm32mp13_rcc_clocks_driver = { | |
702 | .driver = { | |
703 | .name = "stm32mp13_rcc", | |
704 | .of_match_table = stm32mp13_match_data, | |
705 | }, | |
706 | .probe = stm32mp1_rcc_clocks_probe, | |
707 | .remove = stm32mp1_rcc_clocks_remove, | |
708 | }; | |
709 | ||
710 | static int __init stm32mp13_clocks_init(void) | |
711 | { | |
712 | return platform_driver_register(&stm32mp13_rcc_clocks_driver); | |
713 | } | |
714 | core_initcall(stm32mp13_clocks_init); |