blob: 3ba2a00c02a39f9d94bd64e5f2a21234736e89f9 [file] [log] [blame]
Ley Foon Tan6751e7d2018-05-18 22:05:22 +08001// SPDX-License-Identifier: GPL-2.0
2/*
3 * Copyright (C) 2016-2018 Intel Corporation <www.intel.com>
4 *
5 */
6
7#include <common.h>
8#include <asm/io.h>
9#include <asm/arch/clock_manager.h>
10#include <asm/arch/handoff_s10.h>
11#include <asm/arch/system_manager.h>
12
13DECLARE_GLOBAL_DATA_PTR;
14
15static const struct socfpga_clock_manager *clock_manager_base =
16 (struct socfpga_clock_manager *)SOCFPGA_CLKMGR_ADDRESS;
17static const struct socfpga_system_manager *sysmgr_regs =
18 (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS;
19
20/*
21 * function to write the bypass register which requires a poll of the
22 * busy bit
23 */
24static void cm_write_bypass_mainpll(u32 val)
25{
26 writel(val, &clock_manager_base->main_pll.bypass);
27 cm_wait_for_fsm();
28}
29
30static void cm_write_bypass_perpll(u32 val)
31{
32 writel(val, &clock_manager_base->per_pll.bypass);
33 cm_wait_for_fsm();
34}
35
36/* function to write the ctrl register which requires a poll of the busy bit */
37static void cm_write_ctrl(u32 val)
38{
39 writel(val, &clock_manager_base->ctrl);
40 cm_wait_for_fsm();
41}
42
43/*
44 * Setup clocks while making no assumptions about previous state of the clocks.
45 */
46void cm_basic_init(const struct cm_config * const cfg)
47{
48 u32 mdiv, refclkdiv, mscnt, hscnt, vcocalib;
49
50 if (cfg == 0)
51 return;
52
53 /* Put all plls in bypass */
54 cm_write_bypass_mainpll(CLKMGR_BYPASS_MAINPLL_ALL);
55 cm_write_bypass_perpll(CLKMGR_BYPASS_PERPLL_ALL);
56
57 /* setup main PLL dividers where calculate the vcocalib value */
58 mdiv = (cfg->main_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) &
59 CLKMGR_FDBCK_MDIV_MASK;
60 refclkdiv = (cfg->main_pll_pllglob >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
61 CLKMGR_PLLGLOB_REFCLKDIV_MASK;
62 mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv;
63 hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv -
64 CLKMGR_HSCNT_CONST;
65 vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
66 ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) <<
67 CLKMGR_VCOCALIB_MSCNT_OFFSET);
68
69 writel((cfg->main_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK &
70 ~CLKMGR_PLLGLOB_RST_MASK),
71 &clock_manager_base->main_pll.pllglob);
72 writel(cfg->main_pll_fdbck, &clock_manager_base->main_pll.fdbck);
73 writel(vcocalib, &clock_manager_base->main_pll.vcocalib);
74 writel(cfg->main_pll_pllc0, &clock_manager_base->main_pll.pllc0);
75 writel(cfg->main_pll_pllc1, &clock_manager_base->main_pll.pllc1);
76 writel(cfg->main_pll_nocdiv, &clock_manager_base->main_pll.nocdiv);
77
78 /* setup peripheral PLL dividers */
79 /* calculate the vcocalib value */
80 mdiv = (cfg->per_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) &
81 CLKMGR_FDBCK_MDIV_MASK;
82 refclkdiv = (cfg->per_pll_pllglob >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
83 CLKMGR_PLLGLOB_REFCLKDIV_MASK;
84 mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv;
85 hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv -
86 CLKMGR_HSCNT_CONST;
87 vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
88 ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) <<
89 CLKMGR_VCOCALIB_MSCNT_OFFSET);
90
91 writel((cfg->per_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK &
92 ~CLKMGR_PLLGLOB_RST_MASK),
93 &clock_manager_base->per_pll.pllglob);
94 writel(cfg->per_pll_fdbck, &clock_manager_base->per_pll.fdbck);
95 writel(vcocalib, &clock_manager_base->per_pll.vcocalib);
96 writel(cfg->per_pll_pllc0, &clock_manager_base->per_pll.pllc0);
97 writel(cfg->per_pll_pllc1, &clock_manager_base->per_pll.pllc1);
98 writel(cfg->per_pll_emacctl, &clock_manager_base->per_pll.emacctl);
99 writel(cfg->per_pll_gpiodiv, &clock_manager_base->per_pll.gpiodiv);
100
101 /* Take both PLL out of reset and power up */
102 setbits_le32(&clock_manager_base->main_pll.pllglob,
103 CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
104 setbits_le32(&clock_manager_base->per_pll.pllglob,
105 CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
106
107#define LOCKED_MASK \
108 (CLKMGR_STAT_MAINPLL_LOCKED | \
109 CLKMGR_STAT_PERPLL_LOCKED)
110
111 cm_wait_for_lock(LOCKED_MASK);
112
113 /*
114 * Dividers for C2 to C9 only init after PLLs are lock. As dividers
115 * only take effect upon value change, we shall set a maximum value as
116 * default value.
117 */
118 writel(0xff, &clock_manager_base->main_pll.mpuclk);
119 writel(0xff, &clock_manager_base->main_pll.nocclk);
120 writel(0xff, &clock_manager_base->main_pll.cntr2clk);
121 writel(0xff, &clock_manager_base->main_pll.cntr3clk);
122 writel(0xff, &clock_manager_base->main_pll.cntr4clk);
123 writel(0xff, &clock_manager_base->main_pll.cntr5clk);
124 writel(0xff, &clock_manager_base->main_pll.cntr6clk);
125 writel(0xff, &clock_manager_base->main_pll.cntr7clk);
126 writel(0xff, &clock_manager_base->main_pll.cntr8clk);
127 writel(0xff, &clock_manager_base->main_pll.cntr9clk);
128 writel(0xff, &clock_manager_base->per_pll.cntr2clk);
129 writel(0xff, &clock_manager_base->per_pll.cntr3clk);
130 writel(0xff, &clock_manager_base->per_pll.cntr4clk);
131 writel(0xff, &clock_manager_base->per_pll.cntr5clk);
132 writel(0xff, &clock_manager_base->per_pll.cntr6clk);
133 writel(0xff, &clock_manager_base->per_pll.cntr7clk);
134 writel(0xff, &clock_manager_base->per_pll.cntr8clk);
135 writel(0xff, &clock_manager_base->per_pll.cntr9clk);
136
137 writel(cfg->main_pll_mpuclk, &clock_manager_base->main_pll.mpuclk);
138 writel(cfg->main_pll_nocclk, &clock_manager_base->main_pll.nocclk);
139 writel(cfg->main_pll_cntr2clk, &clock_manager_base->main_pll.cntr2clk);
140 writel(cfg->main_pll_cntr3clk, &clock_manager_base->main_pll.cntr3clk);
141 writel(cfg->main_pll_cntr4clk, &clock_manager_base->main_pll.cntr4clk);
142 writel(cfg->main_pll_cntr5clk, &clock_manager_base->main_pll.cntr5clk);
143 writel(cfg->main_pll_cntr6clk, &clock_manager_base->main_pll.cntr6clk);
144 writel(cfg->main_pll_cntr7clk, &clock_manager_base->main_pll.cntr7clk);
145 writel(cfg->main_pll_cntr8clk, &clock_manager_base->main_pll.cntr8clk);
146 writel(cfg->main_pll_cntr9clk, &clock_manager_base->main_pll.cntr9clk);
147 writel(cfg->per_pll_cntr2clk, &clock_manager_base->per_pll.cntr2clk);
148 writel(cfg->per_pll_cntr3clk, &clock_manager_base->per_pll.cntr3clk);
149 writel(cfg->per_pll_cntr4clk, &clock_manager_base->per_pll.cntr4clk);
150 writel(cfg->per_pll_cntr5clk, &clock_manager_base->per_pll.cntr5clk);
151 writel(cfg->per_pll_cntr6clk, &clock_manager_base->per_pll.cntr6clk);
152 writel(cfg->per_pll_cntr7clk, &clock_manager_base->per_pll.cntr7clk);
153 writel(cfg->per_pll_cntr8clk, &clock_manager_base->per_pll.cntr8clk);
154 writel(cfg->per_pll_cntr9clk, &clock_manager_base->per_pll.cntr9clk);
155
156 /* Take all PLLs out of bypass */
157 cm_write_bypass_mainpll(0);
158 cm_write_bypass_perpll(0);
159
160 /* clear safe mode / out of boot mode */
161 cm_write_ctrl(readl(&clock_manager_base->ctrl)
162 & ~(CLKMGR_CTRL_SAFEMODE));
163
164 /* Now ungate non-hw-managed clocks */
165 writel(~0, &clock_manager_base->main_pll.en);
166 writel(~0, &clock_manager_base->per_pll.en);
167
168 /* Clear the loss of lock bits (write 1 to clear) */
169 writel(CLKMGR_INTER_PERPLLLOST_MASK | CLKMGR_INTER_MAINPLLLOST_MASK,
170 &clock_manager_base->intrclr);
171}
172
173static unsigned long cm_get_main_vco_clk_hz(void)
174{
175 unsigned long fref, refdiv, mdiv, reg, vco;
176
177 reg = readl(&clock_manager_base->main_pll.pllglob);
178
179 fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) &
180 CLKMGR_PLLGLOB_VCO_PSRC_MASK;
181 switch (fref) {
182 case CLKMGR_VCO_PSRC_EOSC1:
183 fref = cm_get_osc_clk_hz();
184 break;
185 case CLKMGR_VCO_PSRC_INTOSC:
186 fref = cm_get_intosc_clk_hz();
187 break;
188 case CLKMGR_VCO_PSRC_F2S:
189 fref = cm_get_fpga_clk_hz();
190 break;
191 }
192
193 refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
194 CLKMGR_PLLGLOB_REFCLKDIV_MASK;
195
196 reg = readl(&clock_manager_base->main_pll.fdbck);
197 mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK;
198
199 vco = fref / refdiv;
200 vco = vco * (CLKMGR_MDIV_CONST + mdiv);
201 return vco;
202}
203
204static unsigned long cm_get_per_vco_clk_hz(void)
205{
206 unsigned long fref, refdiv, mdiv, reg, vco;
207
208 reg = readl(&clock_manager_base->per_pll.pllglob);
209
210 fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) &
211 CLKMGR_PLLGLOB_VCO_PSRC_MASK;
212 switch (fref) {
213 case CLKMGR_VCO_PSRC_EOSC1:
214 fref = cm_get_osc_clk_hz();
215 break;
216 case CLKMGR_VCO_PSRC_INTOSC:
217 fref = cm_get_intosc_clk_hz();
218 break;
219 case CLKMGR_VCO_PSRC_F2S:
220 fref = cm_get_fpga_clk_hz();
221 break;
222 }
223
224 refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
225 CLKMGR_PLLGLOB_REFCLKDIV_MASK;
226
227 reg = readl(&clock_manager_base->per_pll.fdbck);
228 mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK;
229
230 vco = fref / refdiv;
231 vco = vco * (CLKMGR_MDIV_CONST + mdiv);
232 return vco;
233}
234
235unsigned long cm_get_mpu_clk_hz(void)
236{
237 unsigned long clock = readl(&clock_manager_base->main_pll.mpuclk);
238
239 clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
240
241 switch (clock) {
242 case CLKMGR_CLKSRC_MAIN:
243 clock = cm_get_main_vco_clk_hz();
244 clock /= (readl(&clock_manager_base->main_pll.pllc0) &
245 CLKMGR_PLLC0_DIV_MASK);
246 break;
247
248 case CLKMGR_CLKSRC_PER:
249 clock = cm_get_per_vco_clk_hz();
250 clock /= (readl(&clock_manager_base->per_pll.pllc0) &
251 CLKMGR_CLKCNT_MSK);
252 break;
253
254 case CLKMGR_CLKSRC_OSC1:
255 clock = cm_get_osc_clk_hz();
256 break;
257
258 case CLKMGR_CLKSRC_INTOSC:
259 clock = cm_get_intosc_clk_hz();
260 break;
261
262 case CLKMGR_CLKSRC_FPGA:
263 clock = cm_get_fpga_clk_hz();
264 break;
265 }
266
267 clock /= 1 + (readl(&clock_manager_base->main_pll.mpuclk) &
268 CLKMGR_CLKCNT_MSK);
269 return clock;
270}
271
272unsigned int cm_get_l3_main_clk_hz(void)
273{
274 u32 clock = readl(&clock_manager_base->main_pll.nocclk);
275
276 clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
277
278 switch (clock) {
279 case CLKMGR_CLKSRC_MAIN:
280 clock = cm_get_main_vco_clk_hz();
281 clock /= (readl(&clock_manager_base->main_pll.pllc1) &
282 CLKMGR_PLLC0_DIV_MASK);
283 break;
284
285 case CLKMGR_CLKSRC_PER:
286 clock = cm_get_per_vco_clk_hz();
287 clock /= (readl(&clock_manager_base->per_pll.pllc1) &
288 CLKMGR_CLKCNT_MSK);
289 break;
290
291 case CLKMGR_CLKSRC_OSC1:
292 clock = cm_get_osc_clk_hz();
293 break;
294
295 case CLKMGR_CLKSRC_INTOSC:
296 clock = cm_get_intosc_clk_hz();
297 break;
298
299 case CLKMGR_CLKSRC_FPGA:
300 clock = cm_get_fpga_clk_hz();
301 break;
302 }
303
304 clock /= 1 + (readl(&clock_manager_base->main_pll.nocclk) &
305 CLKMGR_CLKCNT_MSK);
306 return clock;
307}
308
309unsigned int cm_get_mmc_controller_clk_hz(void)
310{
311 u32 clock = readl(&clock_manager_base->per_pll.cntr6clk);
312
313 clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
314
315 switch (clock) {
316 case CLKMGR_CLKSRC_MAIN:
317 clock = cm_get_l3_main_clk_hz();
318 clock /= 1 + (readl(&clock_manager_base->main_pll.cntr6clk) &
319 CLKMGR_CLKCNT_MSK);
320 break;
321
322 case CLKMGR_CLKSRC_PER:
323 clock = cm_get_l3_main_clk_hz();
324 clock /= 1 + (readl(&clock_manager_base->per_pll.cntr6clk) &
325 CLKMGR_CLKCNT_MSK);
326 break;
327
328 case CLKMGR_CLKSRC_OSC1:
329 clock = cm_get_osc_clk_hz();
330 break;
331
332 case CLKMGR_CLKSRC_INTOSC:
333 clock = cm_get_intosc_clk_hz();
334 break;
335
336 case CLKMGR_CLKSRC_FPGA:
337 clock = cm_get_fpga_clk_hz();
338 break;
339 }
340 return clock / 4;
341}
342
343unsigned int cm_get_l4_sp_clk_hz(void)
344{
345 u32 clock = cm_get_l3_main_clk_hz();
346
347 clock /= (1 << ((readl(&clock_manager_base->main_pll.nocdiv) >>
348 CLKMGR_NOCDIV_L4SPCLK_OFFSET) & CLKMGR_CLKCNT_MSK));
349 return clock;
350}
351
352unsigned int cm_get_qspi_controller_clk_hz(void)
353{
354 return readl(&sysmgr_regs->boot_scratch_cold0);
355}
356
357unsigned int cm_get_spi_controller_clk_hz(void)
358{
359 u32 clock = cm_get_l3_main_clk_hz();
360
361 clock /= (1 << ((readl(&clock_manager_base->main_pll.nocdiv) >>
362 CLKMGR_NOCDIV_L4MAIN_OFFSET) & CLKMGR_CLKCNT_MSK));
363 return clock;
364}
365
366unsigned int cm_get_l4_sys_free_clk_hz(void)
367{
368 return cm_get_l3_main_clk_hz() / 4;
369}
370
371void cm_print_clock_quick_summary(void)
372{
373 printf("MPU %d kHz\n", (u32)(cm_get_mpu_clk_hz() / 1000));
374 printf("L3 main %d kHz\n", cm_get_l3_main_clk_hz() / 1000);
375 printf("Main VCO %d kHz\n", (u32)(cm_get_main_vco_clk_hz() / 1000));
376 printf("Per VCO %d kHz\n", (u32)(cm_get_per_vco_clk_hz() / 1000));
377 printf("EOSC1 %d kHz\n", cm_get_osc_clk_hz() / 1000);
378 printf("HPS MMC %d kHz\n", cm_get_mmc_controller_clk_hz() / 1000);
379 printf("UART %d kHz\n", cm_get_l4_sp_clk_hz() / 1000);
380}