blob: 05e42127b57b8e17cc6f5b3a3e8c50cebd054e19 [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
Ley Foon Tan6751e7d2018-05-18 22:05:22 +080015/*
16 * function to write the bypass register which requires a poll of the
17 * busy bit
18 */
19static void cm_write_bypass_mainpll(u32 val)
20{
Ley Foon Tan26695912019-11-08 10:38:21 +080021 writel(val, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_BYPASS);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +080022 cm_wait_for_fsm();
23}
24
25static void cm_write_bypass_perpll(u32 val)
26{
Ley Foon Tan26695912019-11-08 10:38:21 +080027 writel(val, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_BYPASS);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +080028 cm_wait_for_fsm();
29}
30
31/* function to write the ctrl register which requires a poll of the busy bit */
32static void cm_write_ctrl(u32 val)
33{
Ley Foon Tan26695912019-11-08 10:38:21 +080034 writel(val, socfpga_get_clkmgr_addr() + CLKMGR_S10_CTRL);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +080035 cm_wait_for_fsm();
36}
37
38/*
39 * Setup clocks while making no assumptions about previous state of the clocks.
40 */
41void cm_basic_init(const struct cm_config * const cfg)
42{
43 u32 mdiv, refclkdiv, mscnt, hscnt, vcocalib;
44
45 if (cfg == 0)
46 return;
47
48 /* Put all plls in bypass */
49 cm_write_bypass_mainpll(CLKMGR_BYPASS_MAINPLL_ALL);
50 cm_write_bypass_perpll(CLKMGR_BYPASS_PERPLL_ALL);
51
52 /* setup main PLL dividers where calculate the vcocalib value */
53 mdiv = (cfg->main_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) &
54 CLKMGR_FDBCK_MDIV_MASK;
55 refclkdiv = (cfg->main_pll_pllglob >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
56 CLKMGR_PLLGLOB_REFCLKDIV_MASK;
57 mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv;
58 hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv -
59 CLKMGR_HSCNT_CONST;
60 vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
61 ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) <<
62 CLKMGR_VCOCALIB_MSCNT_OFFSET);
63
64 writel((cfg->main_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK &
65 ~CLKMGR_PLLGLOB_RST_MASK),
Ley Foon Tan26695912019-11-08 10:38:21 +080066 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLGLOB);
67 writel(cfg->main_pll_fdbck,
68 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_FDBCK);
69 writel(vcocalib,
70 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_VCOCALIB);
71 writel(cfg->main_pll_pllc0,
72 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLC0);
73 writel(cfg->main_pll_pllc1,
74 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLC1);
75 writel(cfg->main_pll_nocdiv,
76 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_NOCDIV);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +080077
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),
Ley Foon Tan26695912019-11-08 10:38:21 +080093 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLGLOB);
94 writel(cfg->per_pll_fdbck,
95 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_FDBCK);
96 writel(vcocalib,
97 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_VCOCALIB);
98 writel(cfg->per_pll_pllc0,
99 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLC0);
100 writel(cfg->per_pll_pllc1,
101 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLC1);
102 writel(cfg->per_pll_emacctl,
103 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_EMACCTL);
104 writel(cfg->per_pll_gpiodiv,
105 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_GPIODIV);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800106
107 /* Take both PLL out of reset and power up */
Ley Foon Tan26695912019-11-08 10:38:21 +0800108 setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLGLOB,
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800109 CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
Ley Foon Tan26695912019-11-08 10:38:21 +0800110 setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLGLOB,
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800111 CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
112
113#define LOCKED_MASK \
114 (CLKMGR_STAT_MAINPLL_LOCKED | \
115 CLKMGR_STAT_PERPLL_LOCKED)
116
117 cm_wait_for_lock(LOCKED_MASK);
118
119 /*
120 * Dividers for C2 to C9 only init after PLLs are lock. As dividers
121 * only take effect upon value change, we shall set a maximum value as
122 * default value.
123 */
Ley Foon Tan26695912019-11-08 10:38:21 +0800124 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_MPUCLK);
125 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_NOCCLK);
126 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR2CLK);
127 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR3CLK);
128 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR4CLK);
129 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR5CLK);
130 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR6CLK);
131 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR7CLK);
132 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR8CLK);
133 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR9CLK);
134 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR2CLK);
135 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR3CLK);
136 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR4CLK);
137 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR5CLK);
138 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR6CLK);
139 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR7CLK);
140 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR8CLK);
141 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR9CLK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800142
Ley Foon Tan26695912019-11-08 10:38:21 +0800143 writel(cfg->main_pll_mpuclk,
144 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_MPUCLK);
145 writel(cfg->main_pll_nocclk,
146 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_NOCCLK);
147 writel(cfg->main_pll_cntr2clk,
148 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR2CLK);
149 writel(cfg->main_pll_cntr3clk,
150 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR3CLK);
151 writel(cfg->main_pll_cntr4clk,
152 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR4CLK);
153 writel(cfg->main_pll_cntr5clk,
154 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR5CLK);
155 writel(cfg->main_pll_cntr6clk,
156 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR6CLK);
157 writel(cfg->main_pll_cntr7clk,
158 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR7CLK);
159 writel(cfg->main_pll_cntr8clk,
160 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR8CLK);
161 writel(cfg->main_pll_cntr9clk,
162 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR9CLK);
163 writel(cfg->per_pll_cntr2clk,
164 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR2CLK);
165 writel(cfg->per_pll_cntr3clk,
166 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR3CLK);
167 writel(cfg->per_pll_cntr4clk,
168 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR4CLK);
169 writel(cfg->per_pll_cntr5clk,
170 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR5CLK);
171 writel(cfg->per_pll_cntr6clk,
172 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR6CLK);
173 writel(cfg->per_pll_cntr7clk,
174 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR7CLK);
175 writel(cfg->per_pll_cntr8clk,
176 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR8CLK);
177 writel(cfg->per_pll_cntr9clk,
178 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR9CLK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800179
180 /* Take all PLLs out of bypass */
181 cm_write_bypass_mainpll(0);
182 cm_write_bypass_perpll(0);
183
184 /* clear safe mode / out of boot mode */
Ley Foon Tan26695912019-11-08 10:38:21 +0800185 cm_write_ctrl(readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_CTRL) &
186 ~(CLKMGR_CTRL_SAFEMODE));
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800187
188 /* Now ungate non-hw-managed clocks */
Ley Foon Tan26695912019-11-08 10:38:21 +0800189 writel(~0, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_EN);
190 writel(~0, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_EN);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800191
192 /* Clear the loss of lock bits (write 1 to clear) */
Ley Foon Tan26695912019-11-08 10:38:21 +0800193 writel(CLKMGR_INTER_PERPLLLOST_MASK |
194 CLKMGR_INTER_MAINPLLLOST_MASK,
195 socfpga_get_clkmgr_addr() + CLKMGR_S10_INTRCLR);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800196}
197
198static unsigned long cm_get_main_vco_clk_hz(void)
199{
200 unsigned long fref, refdiv, mdiv, reg, vco;
201
Ley Foon Tan26695912019-11-08 10:38:21 +0800202 reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLGLOB);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800203
204 fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) &
205 CLKMGR_PLLGLOB_VCO_PSRC_MASK;
206 switch (fref) {
207 case CLKMGR_VCO_PSRC_EOSC1:
208 fref = cm_get_osc_clk_hz();
209 break;
210 case CLKMGR_VCO_PSRC_INTOSC:
211 fref = cm_get_intosc_clk_hz();
212 break;
213 case CLKMGR_VCO_PSRC_F2S:
214 fref = cm_get_fpga_clk_hz();
215 break;
216 }
217
218 refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
219 CLKMGR_PLLGLOB_REFCLKDIV_MASK;
220
Ley Foon Tan26695912019-11-08 10:38:21 +0800221 reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_FDBCK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800222 mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK;
223
224 vco = fref / refdiv;
225 vco = vco * (CLKMGR_MDIV_CONST + mdiv);
226 return vco;
227}
228
229static unsigned long cm_get_per_vco_clk_hz(void)
230{
231 unsigned long fref, refdiv, mdiv, reg, vco;
232
Ley Foon Tan26695912019-11-08 10:38:21 +0800233 reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLGLOB);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800234
235 fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) &
236 CLKMGR_PLLGLOB_VCO_PSRC_MASK;
237 switch (fref) {
238 case CLKMGR_VCO_PSRC_EOSC1:
239 fref = cm_get_osc_clk_hz();
240 break;
241 case CLKMGR_VCO_PSRC_INTOSC:
242 fref = cm_get_intosc_clk_hz();
243 break;
244 case CLKMGR_VCO_PSRC_F2S:
245 fref = cm_get_fpga_clk_hz();
246 break;
247 }
248
249 refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
250 CLKMGR_PLLGLOB_REFCLKDIV_MASK;
251
Ley Foon Tan26695912019-11-08 10:38:21 +0800252 reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_FDBCK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800253 mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK;
254
255 vco = fref / refdiv;
256 vco = vco * (CLKMGR_MDIV_CONST + mdiv);
257 return vco;
258}
259
260unsigned long cm_get_mpu_clk_hz(void)
261{
Ley Foon Tan26695912019-11-08 10:38:21 +0800262 unsigned long clock = readl(socfpga_get_clkmgr_addr() +
263 CLKMGR_S10_MAINPLL_MPUCLK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800264
265 clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
266
267 switch (clock) {
268 case CLKMGR_CLKSRC_MAIN:
269 clock = cm_get_main_vco_clk_hz();
Ley Foon Tan26695912019-11-08 10:38:21 +0800270 clock /= (readl(socfpga_get_clkmgr_addr() +
271 CLKMGR_S10_MAINPLL_PLLC0) &
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800272 CLKMGR_PLLC0_DIV_MASK);
273 break;
274
275 case CLKMGR_CLKSRC_PER:
276 clock = cm_get_per_vco_clk_hz();
Ley Foon Tan26695912019-11-08 10:38:21 +0800277 clock /= (readl(socfpga_get_clkmgr_addr() +
278 CLKMGR_S10_PERPLL_PLLC0) &
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800279 CLKMGR_CLKCNT_MSK);
280 break;
281
282 case CLKMGR_CLKSRC_OSC1:
283 clock = cm_get_osc_clk_hz();
284 break;
285
286 case CLKMGR_CLKSRC_INTOSC:
287 clock = cm_get_intosc_clk_hz();
288 break;
289
290 case CLKMGR_CLKSRC_FPGA:
291 clock = cm_get_fpga_clk_hz();
292 break;
293 }
294
Ley Foon Tan26695912019-11-08 10:38:21 +0800295 clock /= 1 + (readl(socfpga_get_clkmgr_addr() +
296 CLKMGR_S10_MAINPLL_MPUCLK) & CLKMGR_CLKCNT_MSK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800297 return clock;
298}
299
300unsigned int cm_get_l3_main_clk_hz(void)
301{
Ley Foon Tan26695912019-11-08 10:38:21 +0800302 u32 clock = readl(socfpga_get_clkmgr_addr() +
303 CLKMGR_S10_MAINPLL_NOCCLK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800304
305 clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
306
307 switch (clock) {
308 case CLKMGR_CLKSRC_MAIN:
309 clock = cm_get_main_vco_clk_hz();
Ley Foon Tan26695912019-11-08 10:38:21 +0800310 clock /= (readl(socfpga_get_clkmgr_addr() +
311 CLKMGR_S10_MAINPLL_PLLC1) &
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800312 CLKMGR_PLLC0_DIV_MASK);
313 break;
314
315 case CLKMGR_CLKSRC_PER:
316 clock = cm_get_per_vco_clk_hz();
Ley Foon Tan26695912019-11-08 10:38:21 +0800317 clock /= (readl(socfpga_get_clkmgr_addr() +
318 CLKMGR_S10_PERPLL_PLLC1) & CLKMGR_CLKCNT_MSK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800319 break;
320
321 case CLKMGR_CLKSRC_OSC1:
322 clock = cm_get_osc_clk_hz();
323 break;
324
325 case CLKMGR_CLKSRC_INTOSC:
326 clock = cm_get_intosc_clk_hz();
327 break;
328
329 case CLKMGR_CLKSRC_FPGA:
330 clock = cm_get_fpga_clk_hz();
331 break;
332 }
333
Ley Foon Tan26695912019-11-08 10:38:21 +0800334 clock /= 1 + (readl(socfpga_get_clkmgr_addr() +
335 CLKMGR_S10_MAINPLL_NOCCLK) & CLKMGR_CLKCNT_MSK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800336 return clock;
337}
338
339unsigned int cm_get_mmc_controller_clk_hz(void)
340{
Ley Foon Tan26695912019-11-08 10:38:21 +0800341 u32 clock = readl(socfpga_get_clkmgr_addr() +
342 CLKMGR_S10_PERPLL_CNTR6CLK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800343
344 clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
345
346 switch (clock) {
347 case CLKMGR_CLKSRC_MAIN:
348 clock = cm_get_l3_main_clk_hz();
Ley Foon Tan26695912019-11-08 10:38:21 +0800349 clock /= 1 + (readl(socfpga_get_clkmgr_addr() +
350 CLKMGR_S10_MAINPLL_CNTR6CLK) &
351 CLKMGR_CLKCNT_MSK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800352 break;
353
354 case CLKMGR_CLKSRC_PER:
355 clock = cm_get_l3_main_clk_hz();
Ley Foon Tan26695912019-11-08 10:38:21 +0800356 clock /= 1 + (readl(socfpga_get_clkmgr_addr() +
357 CLKMGR_S10_PERPLL_CNTR6CLK) &
358 CLKMGR_CLKCNT_MSK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800359 break;
360
361 case CLKMGR_CLKSRC_OSC1:
362 clock = cm_get_osc_clk_hz();
363 break;
364
365 case CLKMGR_CLKSRC_INTOSC:
366 clock = cm_get_intosc_clk_hz();
367 break;
368
369 case CLKMGR_CLKSRC_FPGA:
370 clock = cm_get_fpga_clk_hz();
371 break;
372 }
373 return clock / 4;
374}
375
376unsigned int cm_get_l4_sp_clk_hz(void)
377{
378 u32 clock = cm_get_l3_main_clk_hz();
379
Ley Foon Tan26695912019-11-08 10:38:21 +0800380 clock /= (1 << ((readl(socfpga_get_clkmgr_addr() +
381 CLKMGR_S10_MAINPLL_NOCDIV) >>
382 CLKMGR_NOCDIV_L4SPCLK_OFFSET) & CLKMGR_CLKCNT_MSK));
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800383 return clock;
384}
385
386unsigned int cm_get_qspi_controller_clk_hz(void)
387{
Ley Foon Tan0b1680e2019-11-27 15:55:18 +0800388 return readl(socfpga_get_sysmgr_addr() +
389 SYSMGR_SOC64_BOOT_SCRATCH_COLD0);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800390}
391
392unsigned int cm_get_spi_controller_clk_hz(void)
393{
394 u32 clock = cm_get_l3_main_clk_hz();
395
Ley Foon Tan26695912019-11-08 10:38:21 +0800396 clock /= (1 << ((readl(socfpga_get_clkmgr_addr() +
397 CLKMGR_S10_MAINPLL_NOCDIV) >>
398 CLKMGR_NOCDIV_L4MAIN_OFFSET) & CLKMGR_CLKCNT_MSK));
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800399 return clock;
400}
401
402unsigned int cm_get_l4_sys_free_clk_hz(void)
403{
404 return cm_get_l3_main_clk_hz() / 4;
405}
406
407void cm_print_clock_quick_summary(void)
408{
409 printf("MPU %d kHz\n", (u32)(cm_get_mpu_clk_hz() / 1000));
410 printf("L3 main %d kHz\n", cm_get_l3_main_clk_hz() / 1000);
411 printf("Main VCO %d kHz\n", (u32)(cm_get_main_vco_clk_hz() / 1000));
412 printf("Per VCO %d kHz\n", (u32)(cm_get_per_vco_clk_hz() / 1000));
413 printf("EOSC1 %d kHz\n", cm_get_osc_clk_hz() / 1000);
414 printf("HPS MMC %d kHz\n", cm_get_mmc_controller_clk_hz() / 1000);
415 printf("UART %d kHz\n", cm_get_l4_sp_clk_hz() / 1000);
416}