b251942bb41bef2ae7945a78dd07e90bfcf10c64
[openwrt/staging/linusw.git] /
1 From d731b472cf1c4cace108edacee64eac7f93aea5b Mon Sep 17 00:00:00 2001
2 From: Jonathan Bell <jonathan@raspberrypi.com>
3 Date: Tue, 5 Mar 2024 10:07:17 +0000
4 Subject: [PATCH 0927/1085] drivers: clk: rp1: add GPCLK source muxes and
5 additional PLL dividers
6
7 General-purpose clocks are routed (via a pad) to a large variety of
8 peripheral aux muxes, and themselves gather a large variety of source
9 clocks. Entries without a corresponding name string should not be
10 selected - they bring out internal test/debug clocks which may be
11 intermittent or very high frequency.
12
13 As the GPCLK inputs to peripheral muxes come from a pad, differentiate
14 the source name from the divider output name. This allows the
15 possibility of specifying an off-chip clock source to drive the internal
16 peripheral clock.
17
18 Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
19 ---
20 drivers/clk/clk-rp1.c | 294 ++++++++++++++++++++++++++++++++++--------
21 1 file changed, 242 insertions(+), 52 deletions(-)
22
23 --- a/drivers/clk/clk-rp1.c
24 +++ b/drivers/clk/clk-rp1.c
25 @@ -35,6 +35,7 @@
26 #define PLL_AUDIO_FBDIV_FRAC 0x0c00c
27 #define PLL_AUDIO_PRIM 0x0c010
28 #define PLL_AUDIO_SEC 0x0c014
29 +#define PLL_AUDIO_TERN 0x0c018
30
31 #define PLL_VIDEO_CS 0x10000
32 #define PLL_VIDEO_PWR 0x10004
33 @@ -43,6 +44,8 @@
34 #define PLL_VIDEO_PRIM 0x10010
35 #define PLL_VIDEO_SEC 0x10014
36
37 +#define GPCLK_OE_CTRL 0x00000
38 +
39 #define CLK_SYS_CTRL 0x00014
40 #define CLK_SYS_DIV_INT 0x00018
41 #define CLK_SYS_SEL 0x00020
42 @@ -245,7 +248,7 @@
43 #define LOCK_TIMEOUT_NS 100000000
44 #define FC_TIMEOUT_NS 100000000
45
46 -#define MAX_CLK_PARENTS 8
47 +#define MAX_CLK_PARENTS 16
48
49 #define MEASURE_CLOCK_RATE
50 const char * const fc0_ref_clk_name = "clk_slow_sys";
51 @@ -351,6 +354,7 @@ struct rp1_clock_data {
52 int num_std_parents;
53 int num_aux_parents;
54 unsigned long flags;
55 + u32 oe_mask;
56 u32 clk_src_mask;
57 u32 ctrl_reg;
58 u32 div_int_reg;
59 @@ -1011,6 +1015,10 @@ static int rp1_clock_on(struct clk_hw *h
60 spin_lock(&clockman->regs_lock);
61 clockman_write(clockman, data->ctrl_reg,
62 clockman_read(clockman, data->ctrl_reg) | CLK_CTRL_ENABLE);
63 + /* If this is a GPCLK, turn on the output-enable */
64 + if (data->oe_mask)
65 + clockman_write(clockman, GPCLK_OE_CTRL,
66 + clockman_read(clockman, GPCLK_OE_CTRL) | data->oe_mask);
67 spin_unlock(&clockman->regs_lock);
68
69 #ifdef MEASURE_CLOCK_RATE
70 @@ -1028,6 +1036,10 @@ static void rp1_clock_off(struct clk_hw
71 spin_lock(&clockman->regs_lock);
72 clockman_write(clockman, data->ctrl_reg,
73 clockman_read(clockman, data->ctrl_reg) & ~CLK_CTRL_ENABLE);
74 + /* If this is a GPCLK, turn off the output-enable */
75 + if (data->oe_mask)
76 + clockman_write(clockman, GPCLK_OE_CTRL,
77 + clockman_read(clockman, GPCLK_OE_CTRL) & ~data->oe_mask);
78 spin_unlock(&clockman->regs_lock);
79 }
80
81 @@ -1614,6 +1626,15 @@ static const struct rp1_clk_desc clk_des
82 .fc0_src = FC_NUM(5, 1),
83 ),
84
85 + [RP1_PLL_VIDEO_PRI_PH] = REGISTER_PLL_PH(
86 + .name = "pll_video_pri_ph",
87 + .source_pll = "pll_video",
88 + .ph_reg = PLL_VIDEO_PRIM,
89 + .fixed_divider = 2,
90 + .phase = RP1_PLL_PHASE_0,
91 + .fc0_src = FC_NUM(4, 3),
92 + ),
93 +
94 [RP1_PLL_SYS_SEC] = REGISTER_PLL_DIV(
95 .name = "pll_sys_sec",
96 .source_pll = "pll_sys_core",
97 @@ -1635,6 +1656,13 @@ static const struct rp1_clk_desc clk_des
98 .fc0_src = FC_NUM(5, 3),
99 ),
100
101 + [RP1_PLL_AUDIO_TERN] = REGISTER_PLL_DIV(
102 + .name = "pll_audio_tern",
103 + .source_pll = "pll_audio_core",
104 + .ctrl_reg = PLL_AUDIO_TERN,
105 + .fc0_src = FC_NUM(6, 2),
106 + ),
107 +
108 [RP1_CLK_SYS] = REGISTER_CLK(
109 .name = "clk_sys",
110 .parents = {"xosc", "-", "pll_sys"},
111 @@ -1665,9 +1693,15 @@ static const struct rp1_clk_desc clk_des
112 .name = "clk_uart",
113 .parents = {"pll_sys_pri_ph",
114 "pll_video",
115 - "xosc"},
116 + "xosc",
117 + "clksrc_gp0",
118 + "clksrc_gp1",
119 + "clksrc_gp2",
120 + "clksrc_gp3",
121 + "clksrc_gp4",
122 + "clksrc_gp5"},
123 .num_std_parents = 0,
124 - .num_aux_parents = 3,
125 + .num_aux_parents = 9,
126 .ctrl_reg = CLK_UART_CTRL,
127 .div_int_reg = CLK_UART_DIV_INT,
128 .sel_reg = CLK_UART_SEL,
129 @@ -1677,9 +1711,17 @@ static const struct rp1_clk_desc clk_des
130
131 [RP1_CLK_ETH] = REGISTER_CLK(
132 .name = "clk_eth",
133 - .parents = {"-"},
134 - .num_std_parents = 1,
135 - .num_aux_parents = 0,
136 + .parents = {"pll_sys_sec",
137 + "pll_sys",
138 + "pll_video_sec",
139 + "clksrc_gp0",
140 + "clksrc_gp1",
141 + "clksrc_gp2",
142 + "clksrc_gp3",
143 + "clksrc_gp4",
144 + "clksrc_gp5"},
145 + .num_std_parents = 0,
146 + .num_aux_parents = 9,
147 .ctrl_reg = CLK_ETH_CTRL,
148 .div_int_reg = CLK_ETH_DIV_INT,
149 .sel_reg = CLK_ETH_SEL,
150 @@ -1691,9 +1733,15 @@ static const struct rp1_clk_desc clk_des
151 .name = "clk_pwm0",
152 .parents = {"pll_audio_pri_ph",
153 "pll_video_sec",
154 - "xosc"},
155 + "xosc",
156 + "clksrc_gp0",
157 + "clksrc_gp1",
158 + "clksrc_gp2",
159 + "clksrc_gp3",
160 + "clksrc_gp4",
161 + "clksrc_gp5"},
162 .num_std_parents = 0,
163 - .num_aux_parents = 3,
164 + .num_aux_parents = 9,
165 .ctrl_reg = CLK_PWM0_CTRL,
166 .div_int_reg = CLK_PWM0_DIV_INT,
167 .div_frac_reg = CLK_PWM0_DIV_FRAC,
168 @@ -1706,9 +1754,15 @@ static const struct rp1_clk_desc clk_des
169 .name = "clk_pwm1",
170 .parents = {"pll_audio_pri_ph",
171 "pll_video_sec",
172 - "xosc"},
173 + "xosc",
174 + "clksrc_gp0",
175 + "clksrc_gp1",
176 + "clksrc_gp2",
177 + "clksrc_gp3",
178 + "clksrc_gp4",
179 + "clksrc_gp5"},
180 .num_std_parents = 0,
181 - .num_aux_parents = 3,
182 + .num_aux_parents = 9,
183 .ctrl_reg = CLK_PWM1_CTRL,
184 .div_int_reg = CLK_PWM1_DIV_INT,
185 .div_frac_reg = CLK_PWM1_DIV_FRAC,
186 @@ -1719,9 +1773,19 @@ static const struct rp1_clk_desc clk_des
187
188 [RP1_CLK_AUDIO_IN] = REGISTER_CLK(
189 .name = "clk_audio_in",
190 - .parents = {"-"},
191 - .num_std_parents = 1,
192 - .num_aux_parents = 0,
193 + .parents = {"pll_audio",
194 + "pll_audio_pri_ph",
195 + "pll_audio_sec",
196 + "pll_video_sec",
197 + "xosc",
198 + "clksrc_gp0",
199 + "clksrc_gp1",
200 + "clksrc_gp2",
201 + "clksrc_gp3",
202 + "clksrc_gp4",
203 + "clksrc_gp5"},
204 + .num_std_parents = 0,
205 + .num_aux_parents = 11,
206 .ctrl_reg = CLK_AUDIO_IN_CTRL,
207 .div_int_reg = CLK_AUDIO_IN_DIV_INT,
208 .sel_reg = CLK_AUDIO_IN_SEL,
209 @@ -1731,9 +1795,18 @@ static const struct rp1_clk_desc clk_des
210
211 [RP1_CLK_AUDIO_OUT] = REGISTER_CLK(
212 .name = "clk_audio_out",
213 - .parents = {"-"},
214 - .num_std_parents = 1,
215 - .num_aux_parents = 0,
216 + .parents = {"pll_audio",
217 + "pll_audio_sec",
218 + "pll_video_sec",
219 + "xosc",
220 + "clksrc_gp0",
221 + "clksrc_gp1",
222 + "clksrc_gp2",
223 + "clksrc_gp3",
224 + "clksrc_gp4",
225 + "clksrc_gp5"},
226 + .num_std_parents = 0,
227 + .num_aux_parents = 10,
228 .ctrl_reg = CLK_AUDIO_OUT_CTRL,
229 .div_int_reg = CLK_AUDIO_OUT_DIV_INT,
230 .sel_reg = CLK_AUDIO_OUT_SEL,
231 @@ -1745,9 +1818,15 @@ static const struct rp1_clk_desc clk_des
232 .name = "clk_i2s",
233 .parents = {"xosc",
234 "pll_audio",
235 - "pll_audio_sec"},
236 + "pll_audio_sec",
237 + "clksrc_gp0",
238 + "clksrc_gp1",
239 + "clksrc_gp2",
240 + "clksrc_gp3",
241 + "clksrc_gp4",
242 + "clksrc_gp5"},
243 .num_std_parents = 0,
244 - .num_aux_parents = 3,
245 + .num_aux_parents = 9,
246 .ctrl_reg = CLK_I2S_CTRL,
247 .div_int_reg = CLK_I2S_DIV_INT,
248 .sel_reg = CLK_I2S_SEL,
249 @@ -1782,9 +1861,16 @@ static const struct rp1_clk_desc clk_des
250
251 [RP1_CLK_ETH_TSU] = REGISTER_CLK(
252 .name = "clk_eth_tsu",
253 - .parents = {"xosc"},
254 + .parents = {"xosc",
255 + "pll_video_sec",
256 + "clksrc_gp0",
257 + "clksrc_gp1",
258 + "clksrc_gp2",
259 + "clksrc_gp3",
260 + "clksrc_gp4",
261 + "clksrc_gp5"},
262 .num_std_parents = 0,
263 - .num_aux_parents = 1,
264 + .num_aux_parents = 8,
265 .ctrl_reg = CLK_ETH_TSU_CTRL,
266 .div_int_reg = CLK_ETH_TSU_DIV_INT,
267 .sel_reg = CLK_ETH_TSU_SEL,
268 @@ -1794,9 +1880,16 @@ static const struct rp1_clk_desc clk_des
269
270 [RP1_CLK_ADC] = REGISTER_CLK(
271 .name = "clk_adc",
272 - .parents = {"xosc"},
273 + .parents = {"xosc",
274 + "pll_audio_tern",
275 + "clksrc_gp0",
276 + "clksrc_gp1",
277 + "clksrc_gp2",
278 + "clksrc_gp3",
279 + "clksrc_gp4",
280 + "clksrc_gp5"},
281 .num_std_parents = 0,
282 - .num_aux_parents = 1,
283 + .num_aux_parents = 8,
284 .ctrl_reg = CLK_ADC_CTRL,
285 .div_int_reg = CLK_ADC_DIV_INT,
286 .sel_reg = CLK_ADC_SEL,
287 @@ -1830,9 +1923,25 @@ static const struct rp1_clk_desc clk_des
288
289 [RP1_CLK_GP0] = REGISTER_CLK(
290 .name = "clk_gp0",
291 - .parents = {"xosc"},
292 + .parents = {"xosc",
293 + "clksrc_gp1",
294 + "clksrc_gp2",
295 + "clksrc_gp3",
296 + "clksrc_gp4",
297 + "clksrc_gp5",
298 + "pll_sys",
299 + "pll_audio",
300 + "",
301 + "",
302 + "clk_i2s",
303 + "clk_adc",
304 + "",
305 + "",
306 + "",
307 + "clk_sys"},
308 .num_std_parents = 0,
309 - .num_aux_parents = 1,
310 + .num_aux_parents = 16,
311 + .oe_mask = BIT(0),
312 .ctrl_reg = CLK_GP0_CTRL,
313 .div_int_reg = CLK_GP0_DIV_INT,
314 .div_frac_reg = CLK_GP0_DIV_FRAC,
315 @@ -1843,9 +1952,25 @@ static const struct rp1_clk_desc clk_des
316
317 [RP1_CLK_GP1] = REGISTER_CLK(
318 .name = "clk_gp1",
319 - .parents = {"xosc"},
320 + .parents = {"clk_sdio_timer",
321 + "clksrc_gp0",
322 + "clksrc_gp2",
323 + "clksrc_gp3",
324 + "clksrc_gp4",
325 + "clksrc_gp5",
326 + "pll_sys_pri_ph",
327 + "pll_audio_pri_ph",
328 + "",
329 + "",
330 + "clk_adc",
331 + "clk_dpi",
332 + "clk_pwm0",
333 + "",
334 + "",
335 + ""},
336 .num_std_parents = 0,
337 - .num_aux_parents = 1,
338 + .num_aux_parents = 16,
339 + .oe_mask = BIT(1),
340 .ctrl_reg = CLK_GP1_CTRL,
341 .div_int_reg = CLK_GP1_DIV_INT,
342 .div_frac_reg = CLK_GP1_DIV_FRAC,
343 @@ -1856,9 +1981,25 @@ static const struct rp1_clk_desc clk_des
344
345 [RP1_CLK_GP2] = REGISTER_CLK(
346 .name = "clk_gp2",
347 - .parents = {"xosc"},
348 + .parents = {"clk_sdio_alt_src",
349 + "clksrc_gp0",
350 + "clksrc_gp1",
351 + "clksrc_gp3",
352 + "clksrc_gp4",
353 + "clksrc_gp5",
354 + "pll_sys_sec",
355 + "pll_audio_sec",
356 + "pll_video",
357 + "clk_audio_in",
358 + "clk_dpi",
359 + "clk_pwm0",
360 + "clk_pwm1",
361 + "clk_mipi0_dpi",
362 + "clk_mipi1_cfg",
363 + "clk_sys"},
364 .num_std_parents = 0,
365 - .num_aux_parents = 1,
366 + .num_aux_parents = 16,
367 + .oe_mask = BIT(2),
368 .ctrl_reg = CLK_GP2_CTRL,
369 .div_int_reg = CLK_GP2_DIV_INT,
370 .div_frac_reg = CLK_GP2_DIV_FRAC,
371 @@ -1869,9 +2010,25 @@ static const struct rp1_clk_desc clk_des
372
373 [RP1_CLK_GP3] = REGISTER_CLK(
374 .name = "clk_gp3",
375 - .parents = {"xosc"},
376 + .parents = {"xosc",
377 + "clksrc_gp0",
378 + "clksrc_gp1",
379 + "clksrc_gp2",
380 + "clksrc_gp4",
381 + "clksrc_gp5",
382 + "",
383 + "",
384 + "pll_video_pri_ph",
385 + "clk_audio_out",
386 + "",
387 + "",
388 + "clk_mipi1_dpi",
389 + "",
390 + "",
391 + ""},
392 .num_std_parents = 0,
393 - .num_aux_parents = 1,
394 + .num_aux_parents = 16,
395 + .oe_mask = BIT(3),
396 .ctrl_reg = CLK_GP3_CTRL,
397 .div_int_reg = CLK_GP3_DIV_INT,
398 .div_frac_reg = CLK_GP3_DIV_FRAC,
399 @@ -1882,9 +2039,26 @@ static const struct rp1_clk_desc clk_des
400
401 [RP1_CLK_GP4] = REGISTER_CLK(
402 .name = "clk_gp4",
403 - .parents = {"xosc"},
404 + .parents = {"xosc",
405 + "clksrc_gp0",
406 + "clksrc_gp1",
407 + "clksrc_gp2",
408 + "clksrc_gp3",
409 + "clksrc_gp5",
410 + "pll_audio_tern",
411 + "pll_video_sec",
412 + "",
413 + "",
414 + "",
415 + "clk_mipi0_cfg",
416 + "clk_uart",
417 + "",
418 + "",
419 + "clk_sys",
420 + },
421 .num_std_parents = 0,
422 - .num_aux_parents = 1,
423 + .num_aux_parents = 16,
424 + .oe_mask = BIT(4),
425 .ctrl_reg = CLK_GP4_CTRL,
426 .div_int_reg = CLK_GP4_DIV_INT,
427 .div_frac_reg = CLK_GP4_DIV_FRAC,
428 @@ -1895,9 +2069,25 @@ static const struct rp1_clk_desc clk_des
429
430 [RP1_CLK_GP5] = REGISTER_CLK(
431 .name = "clk_gp5",
432 - .parents = {"xosc"},
433 + .parents = {"xosc",
434 + "clksrc_gp0",
435 + "clksrc_gp1",
436 + "clksrc_gp2",
437 + "clksrc_gp3",
438 + "clksrc_gp4",
439 + "pll_audio_tern",
440 + "pll_video_sec",
441 + "clk_eth_tsu",
442 + "",
443 + "clk_vec",
444 + "",
445 + "",
446 + "",
447 + "",
448 + ""},
449 .num_std_parents = 0,
450 - .num_aux_parents = 1,
451 + .num_aux_parents = 16,
452 + .oe_mask = BIT(5),
453 .ctrl_reg = CLK_GP5_CTRL,
454 .div_int_reg = CLK_GP5_DIV_INT,
455 .div_frac_reg = CLK_GP5_DIV_FRAC,
456 @@ -1911,11 +2101,11 @@ static const struct rp1_clk_desc clk_des
457 .parents = {"pll_sys_pri_ph",
458 "pll_video_sec",
459 "pll_video",
460 - "clk_gp0",
461 - "clk_gp1",
462 - "clk_gp2",
463 - "clk_gp3",
464 - "clk_gp4"},
465 + "clksrc_gp0",
466 + "clksrc_gp1",
467 + "clksrc_gp2",
468 + "clksrc_gp3",
469 + "clksrc_gp4"},
470 .num_std_parents = 0,
471 .num_aux_parents = 8, /* XXX in fact there are more than 8 */
472 .ctrl_reg = VIDEO_CLK_VEC_CTRL,
473 @@ -1931,11 +2121,11 @@ static const struct rp1_clk_desc clk_des
474 .parents = {"pll_sys",
475 "pll_video_sec",
476 "pll_video",
477 - "clk_gp0",
478 - "clk_gp1",
479 - "clk_gp2",
480 - "clk_gp3",
481 - "clk_gp4"},
482 + "clksrc_gp0",
483 + "clksrc_gp1",
484 + "clksrc_gp2",
485 + "clksrc_gp3",
486 + "clksrc_gp4"},
487 .num_std_parents = 0,
488 .num_aux_parents = 8, /* XXX in fact there are more than 8 */
489 .ctrl_reg = VIDEO_CLK_DPI_CTRL,
490 @@ -1952,10 +2142,10 @@ static const struct rp1_clk_desc clk_des
491 "pll_video_sec",
492 "pll_video",
493 "clksrc_mipi0_dsi_byteclk",
494 - "clk_gp0",
495 - "clk_gp1",
496 - "clk_gp2",
497 - "clk_gp3"},
498 + "clksrc_gp0",
499 + "clksrc_gp1",
500 + "clksrc_gp2",
501 + "clksrc_gp3"},
502 .num_std_parents = 0,
503 .num_aux_parents = 8, /* XXX in fact there are more than 8 */
504 .ctrl_reg = VIDEO_CLK_MIPI0_DPI_CTRL,
505 @@ -1973,10 +2163,10 @@ static const struct rp1_clk_desc clk_des
506 "pll_video_sec",
507 "pll_video",
508 "clksrc_mipi1_dsi_byteclk",
509 - "clk_gp0",
510 - "clk_gp1",
511 - "clk_gp2",
512 - "clk_gp3"},
513 + "clksrc_gp0",
514 + "clksrc_gp1",
515 + "clksrc_gp2",
516 + "clksrc_gp3"},
517 .num_std_parents = 0,
518 .num_aux_parents = 8, /* XXX in fact there are more than 8 */
519 .ctrl_reg = VIDEO_CLK_MIPI1_DPI_CTRL,