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
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.
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
18 Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
20 drivers/clk/clk-rp1.c | 294 ++++++++++++++++++++++++++++++++++--------
21 1 file changed, 242 insertions(+), 52 deletions(-)
23 --- a/drivers/clk/clk-rp1.c
24 +++ b/drivers/clk/clk-rp1.c
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
31 #define PLL_VIDEO_CS 0x10000
32 #define PLL_VIDEO_PWR 0x10004
34 #define PLL_VIDEO_PRIM 0x10010
35 #define PLL_VIDEO_SEC 0x10014
37 +#define GPCLK_OE_CTRL 0x00000
39 #define CLK_SYS_CTRL 0x00014
40 #define CLK_SYS_DIV_INT 0x00018
41 #define CLK_SYS_SEL 0x00020
43 #define LOCK_TIMEOUT_NS 100000000
44 #define FC_TIMEOUT_NS 100000000
46 -#define MAX_CLK_PARENTS 8
47 +#define MAX_CLK_PARENTS 16
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 {
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 */
65 + clockman_write(clockman, GPCLK_OE_CTRL,
66 + clockman_read(clockman, GPCLK_OE_CTRL) | data->oe_mask);
67 spin_unlock(&clockman->regs_lock);
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 */
76 + clockman_write(clockman, GPCLK_OE_CTRL,
77 + clockman_read(clockman, GPCLK_OE_CTRL) & ~data->oe_mask);
78 spin_unlock(&clockman->regs_lock);
81 @@ -1614,6 +1626,15 @@ static const struct rp1_clk_desc clk_des
82 .fc0_src = FC_NUM(5, 1),
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,
90 + .phase = RP1_PLL_PHASE_0,
91 + .fc0_src = FC_NUM(4, 3),
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),
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),
108 [RP1_CLK_SYS] = REGISTER_CLK(
110 .parents = {"xosc", "-", "pll_sys"},
111 @@ -1665,9 +1693,15 @@ static const struct rp1_clk_desc clk_des
113 .parents = {"pll_sys_pri_ph",
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
131 [RP1_CLK_ETH] = REGISTER_CLK(
134 - .num_std_parents = 1,
135 - .num_aux_parents = 0,
136 + .parents = {"pll_sys_sec",
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
152 .parents = {"pll_audio_pri_ph",
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
170 .parents = {"pll_audio_pri_ph",
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
188 [RP1_CLK_AUDIO_IN] = REGISTER_CLK(
189 .name = "clk_audio_in",
191 - .num_std_parents = 1,
192 - .num_aux_parents = 0,
193 + .parents = {"pll_audio",
194 + "pll_audio_pri_ph",
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
211 [RP1_CLK_AUDIO_OUT] = REGISTER_CLK(
212 .name = "clk_audio_out",
214 - .num_std_parents = 1,
215 - .num_aux_parents = 0,
216 + .parents = {"pll_audio",
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
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
251 [RP1_CLK_ETH_TSU] = REGISTER_CLK(
252 .name = "clk_eth_tsu",
253 - .parents = {"xosc"},
254 + .parents = {"xosc",
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
270 [RP1_CLK_ADC] = REGISTER_CLK(
272 - .parents = {"xosc"},
273 + .parents = {"xosc",
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
289 [RP1_CLK_GP0] = REGISTER_CLK(
291 - .parents = {"xosc"},
292 + .parents = {"xosc",
308 .num_std_parents = 0,
309 - .num_aux_parents = 1,
310 + .num_aux_parents = 16,
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
317 [RP1_CLK_GP1] = REGISTER_CLK(
319 - .parents = {"xosc"},
320 + .parents = {"clk_sdio_timer",
327 + "pll_audio_pri_ph",
336 .num_std_parents = 0,
337 - .num_aux_parents = 1,
338 + .num_aux_parents = 16,
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
345 [RP1_CLK_GP2] = REGISTER_CLK(
347 - .parents = {"xosc"},
348 + .parents = {"clk_sdio_alt_src",
364 .num_std_parents = 0,
365 - .num_aux_parents = 1,
366 + .num_aux_parents = 16,
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
373 [RP1_CLK_GP3] = REGISTER_CLK(
375 - .parents = {"xosc"},
376 + .parents = {"xosc",
384 + "pll_video_pri_ph",
392 .num_std_parents = 0,
393 - .num_aux_parents = 1,
394 + .num_aux_parents = 16,
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
401 [RP1_CLK_GP4] = REGISTER_CLK(
403 - .parents = {"xosc"},
404 + .parents = {"xosc",
421 .num_std_parents = 0,
422 - .num_aux_parents = 1,
423 + .num_aux_parents = 16,
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
430 [RP1_CLK_GP5] = REGISTER_CLK(
432 - .parents = {"xosc"},
433 + .parents = {"xosc",
449 .num_std_parents = 0,
450 - .num_aux_parents = 1,
451 + .num_aux_parents = 16,
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",
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",
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
493 "clksrc_mipi0_dsi_byteclk",
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
508 "clksrc_mipi1_dsi_byteclk",
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,