blob: 45300336d52a0e3aedf1f88783acb15b438ea17b [file] [log] [blame]
Ley Foon Tan6751e7d2018-05-18 22:05:22 +08001// SPDX-License-Identifier: GPL-2.0
2/*
Dinesh Maniyamc851f2f2023-12-07 15:46:02 +08003 * Copyright (C) 2016-2023 Intel Corporation <www.intel.com>
Ley Foon Tan6751e7d2018-05-18 22:05:22 +08004 *
5 */
6
7#include <common.h>
Simon Glass3ba929a2020-10-30 21:38:53 -06008#include <asm/global_data.h>
Ley Foon Tan6751e7d2018-05-18 22:05:22 +08009#include <asm/io.h>
10#include <asm/arch/clock_manager.h>
Siew Chin Lim954d5992021-03-24 13:11:34 +080011#include <asm/arch/handoff_soc64.h>
Ley Foon Tan6751e7d2018-05-18 22:05:22 +080012#include <asm/arch/system_manager.h>
13
14DECLARE_GLOBAL_DATA_PTR;
15
Ley Foon Tan6751e7d2018-05-18 22:05:22 +080016/*
17 * function to write the bypass register which requires a poll of the
18 * busy bit
19 */
20static void cm_write_bypass_mainpll(u32 val)
21{
Ley Foon Tan26695912019-11-08 10:38:21 +080022 writel(val, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_BYPASS);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +080023 cm_wait_for_fsm();
24}
25
26static void cm_write_bypass_perpll(u32 val)
27{
Ley Foon Tan26695912019-11-08 10:38:21 +080028 writel(val, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_BYPASS);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +080029 cm_wait_for_fsm();
30}
31
32/* function to write the ctrl register which requires a poll of the busy bit */
33static void cm_write_ctrl(u32 val)
34{
Ley Foon Tan26695912019-11-08 10:38:21 +080035 writel(val, socfpga_get_clkmgr_addr() + CLKMGR_S10_CTRL);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +080036 cm_wait_for_fsm();
37}
38
39/*
40 * Setup clocks while making no assumptions about previous state of the clocks.
41 */
42void cm_basic_init(const struct cm_config * const cfg)
43{
44 u32 mdiv, refclkdiv, mscnt, hscnt, vcocalib;
45
46 if (cfg == 0)
47 return;
48
49 /* Put all plls in bypass */
50 cm_write_bypass_mainpll(CLKMGR_BYPASS_MAINPLL_ALL);
51 cm_write_bypass_perpll(CLKMGR_BYPASS_PERPLL_ALL);
52
53 /* setup main PLL dividers where calculate the vcocalib value */
54 mdiv = (cfg->main_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) &
55 CLKMGR_FDBCK_MDIV_MASK;
56 refclkdiv = (cfg->main_pll_pllglob >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
57 CLKMGR_PLLGLOB_REFCLKDIV_MASK;
58 mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv;
59 hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv -
60 CLKMGR_HSCNT_CONST;
61 vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
62 ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) <<
63 CLKMGR_VCOCALIB_MSCNT_OFFSET);
64
65 writel((cfg->main_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK &
66 ~CLKMGR_PLLGLOB_RST_MASK),
Ley Foon Tan26695912019-11-08 10:38:21 +080067 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLGLOB);
68 writel(cfg->main_pll_fdbck,
69 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_FDBCK);
70 writel(vcocalib,
71 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_VCOCALIB);
72 writel(cfg->main_pll_pllc0,
73 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLC0);
74 writel(cfg->main_pll_pllc1,
75 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLC1);
76 writel(cfg->main_pll_nocdiv,
77 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_NOCDIV);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +080078
79 /* setup peripheral PLL dividers */
80 /* calculate the vcocalib value */
81 mdiv = (cfg->per_pll_fdbck >> CLKMGR_FDBCK_MDIV_OFFSET) &
82 CLKMGR_FDBCK_MDIV_MASK;
83 refclkdiv = (cfg->per_pll_pllglob >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
84 CLKMGR_PLLGLOB_REFCLKDIV_MASK;
85 mscnt = CLKMGR_MSCNT_CONST / (CLKMGR_MDIV_CONST + mdiv) / refclkdiv;
86 hscnt = (mdiv + CLKMGR_MDIV_CONST) * mscnt / refclkdiv -
87 CLKMGR_HSCNT_CONST;
88 vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
89 ((mscnt & CLKMGR_VCOCALIB_MSCNT_MASK) <<
90 CLKMGR_VCOCALIB_MSCNT_OFFSET);
91
92 writel((cfg->per_pll_pllglob & ~CLKMGR_PLLGLOB_PD_MASK &
93 ~CLKMGR_PLLGLOB_RST_MASK),
Ley Foon Tan26695912019-11-08 10:38:21 +080094 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLGLOB);
95 writel(cfg->per_pll_fdbck,
96 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_FDBCK);
97 writel(vcocalib,
98 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_VCOCALIB);
99 writel(cfg->per_pll_pllc0,
100 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLC0);
101 writel(cfg->per_pll_pllc1,
102 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLC1);
103 writel(cfg->per_pll_emacctl,
104 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_EMACCTL);
105 writel(cfg->per_pll_gpiodiv,
106 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_GPIODIV);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800107
108 /* Take both PLL out of reset and power up */
Ley Foon Tan26695912019-11-08 10:38:21 +0800109 setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLGLOB,
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800110 CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
Ley Foon Tan26695912019-11-08 10:38:21 +0800111 setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLGLOB,
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800112 CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
113
114#define LOCKED_MASK \
115 (CLKMGR_STAT_MAINPLL_LOCKED | \
116 CLKMGR_STAT_PERPLL_LOCKED)
117
118 cm_wait_for_lock(LOCKED_MASK);
119
120 /*
121 * Dividers for C2 to C9 only init after PLLs are lock. As dividers
122 * only take effect upon value change, we shall set a maximum value as
123 * default value.
124 */
Ley Foon Tan26695912019-11-08 10:38:21 +0800125 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_MPUCLK);
126 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_NOCCLK);
127 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR2CLK);
128 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR3CLK);
129 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR4CLK);
130 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR5CLK);
131 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR6CLK);
132 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR7CLK);
133 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR8CLK);
134 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR9CLK);
135 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR2CLK);
136 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR3CLK);
137 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR4CLK);
138 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR5CLK);
139 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR6CLK);
140 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR7CLK);
141 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR8CLK);
142 writel(0xff, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR9CLK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800143
Ley Foon Tan26695912019-11-08 10:38:21 +0800144 writel(cfg->main_pll_mpuclk,
145 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_MPUCLK);
146 writel(cfg->main_pll_nocclk,
147 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_NOCCLK);
148 writel(cfg->main_pll_cntr2clk,
149 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR2CLK);
150 writel(cfg->main_pll_cntr3clk,
151 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR3CLK);
152 writel(cfg->main_pll_cntr4clk,
153 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR4CLK);
154 writel(cfg->main_pll_cntr5clk,
155 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR5CLK);
156 writel(cfg->main_pll_cntr6clk,
157 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR6CLK);
158 writel(cfg->main_pll_cntr7clk,
159 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR7CLK);
160 writel(cfg->main_pll_cntr8clk,
161 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR8CLK);
162 writel(cfg->main_pll_cntr9clk,
163 socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_CNTR9CLK);
164 writel(cfg->per_pll_cntr2clk,
165 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR2CLK);
166 writel(cfg->per_pll_cntr3clk,
167 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR3CLK);
168 writel(cfg->per_pll_cntr4clk,
169 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR4CLK);
170 writel(cfg->per_pll_cntr5clk,
171 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR5CLK);
172 writel(cfg->per_pll_cntr6clk,
173 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR6CLK);
174 writel(cfg->per_pll_cntr7clk,
175 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR7CLK);
176 writel(cfg->per_pll_cntr8clk,
177 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR8CLK);
178 writel(cfg->per_pll_cntr9clk,
179 socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_CNTR9CLK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800180
181 /* Take all PLLs out of bypass */
182 cm_write_bypass_mainpll(0);
183 cm_write_bypass_perpll(0);
184
185 /* clear safe mode / out of boot mode */
Ley Foon Tan26695912019-11-08 10:38:21 +0800186 cm_write_ctrl(readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_CTRL) &
187 ~(CLKMGR_CTRL_SAFEMODE));
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800188
189 /* Now ungate non-hw-managed clocks */
Ley Foon Tan26695912019-11-08 10:38:21 +0800190 writel(~0, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_EN);
191 writel(~0, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_EN);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800192
193 /* Clear the loss of lock bits (write 1 to clear) */
Ley Foon Tan26695912019-11-08 10:38:21 +0800194 writel(CLKMGR_INTER_PERPLLLOST_MASK |
195 CLKMGR_INTER_MAINPLLLOST_MASK,
196 socfpga_get_clkmgr_addr() + CLKMGR_S10_INTRCLR);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800197}
198
199static unsigned long cm_get_main_vco_clk_hz(void)
200{
201 unsigned long fref, refdiv, mdiv, reg, vco;
202
Ley Foon Tan26695912019-11-08 10:38:21 +0800203 reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLGLOB);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800204
205 fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) &
206 CLKMGR_PLLGLOB_VCO_PSRC_MASK;
207 switch (fref) {
208 case CLKMGR_VCO_PSRC_EOSC1:
209 fref = cm_get_osc_clk_hz();
210 break;
211 case CLKMGR_VCO_PSRC_INTOSC:
212 fref = cm_get_intosc_clk_hz();
213 break;
214 case CLKMGR_VCO_PSRC_F2S:
215 fref = cm_get_fpga_clk_hz();
216 break;
217 }
218
219 refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
220 CLKMGR_PLLGLOB_REFCLKDIV_MASK;
221
Ley Foon Tan26695912019-11-08 10:38:21 +0800222 reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_FDBCK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800223 mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK;
224
225 vco = fref / refdiv;
226 vco = vco * (CLKMGR_MDIV_CONST + mdiv);
227 return vco;
228}
229
230static unsigned long cm_get_per_vco_clk_hz(void)
231{
232 unsigned long fref, refdiv, mdiv, reg, vco;
233
Ley Foon Tan26695912019-11-08 10:38:21 +0800234 reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLGLOB);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800235
236 fref = (reg >> CLKMGR_PLLGLOB_VCO_PSRC_OFFSET) &
237 CLKMGR_PLLGLOB_VCO_PSRC_MASK;
238 switch (fref) {
239 case CLKMGR_VCO_PSRC_EOSC1:
240 fref = cm_get_osc_clk_hz();
241 break;
242 case CLKMGR_VCO_PSRC_INTOSC:
243 fref = cm_get_intosc_clk_hz();
244 break;
245 case CLKMGR_VCO_PSRC_F2S:
246 fref = cm_get_fpga_clk_hz();
247 break;
248 }
249
250 refdiv = (reg >> CLKMGR_PLLGLOB_REFCLKDIV_OFFSET) &
251 CLKMGR_PLLGLOB_REFCLKDIV_MASK;
252
Ley Foon Tan26695912019-11-08 10:38:21 +0800253 reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_FDBCK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800254 mdiv = (reg >> CLKMGR_FDBCK_MDIV_OFFSET) & CLKMGR_FDBCK_MDIV_MASK;
255
256 vco = fref / refdiv;
257 vco = vco * (CLKMGR_MDIV_CONST + mdiv);
258 return vco;
259}
260
261unsigned long cm_get_mpu_clk_hz(void)
262{
Ley Foon Tan26695912019-11-08 10:38:21 +0800263 unsigned long clock = readl(socfpga_get_clkmgr_addr() +
264 CLKMGR_S10_MAINPLL_MPUCLK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800265
266 clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
267
268 switch (clock) {
269 case CLKMGR_CLKSRC_MAIN:
270 clock = cm_get_main_vco_clk_hz();
Ley Foon Tan26695912019-11-08 10:38:21 +0800271 clock /= (readl(socfpga_get_clkmgr_addr() +
272 CLKMGR_S10_MAINPLL_PLLC0) &
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800273 CLKMGR_PLLC0_DIV_MASK);
274 break;
275
276 case CLKMGR_CLKSRC_PER:
277 clock = cm_get_per_vco_clk_hz();
Ley Foon Tan26695912019-11-08 10:38:21 +0800278 clock /= (readl(socfpga_get_clkmgr_addr() +
279 CLKMGR_S10_PERPLL_PLLC0) &
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800280 CLKMGR_CLKCNT_MSK);
281 break;
282
283 case CLKMGR_CLKSRC_OSC1:
284 clock = cm_get_osc_clk_hz();
285 break;
286
287 case CLKMGR_CLKSRC_INTOSC:
288 clock = cm_get_intosc_clk_hz();
289 break;
290
291 case CLKMGR_CLKSRC_FPGA:
292 clock = cm_get_fpga_clk_hz();
293 break;
294 }
295
Ley Foon Tan26695912019-11-08 10:38:21 +0800296 clock /= 1 + (readl(socfpga_get_clkmgr_addr() +
297 CLKMGR_S10_MAINPLL_MPUCLK) & CLKMGR_CLKCNT_MSK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800298 return clock;
299}
300
301unsigned int cm_get_l3_main_clk_hz(void)
302{
Ley Foon Tan26695912019-11-08 10:38:21 +0800303 u32 clock = readl(socfpga_get_clkmgr_addr() +
304 CLKMGR_S10_MAINPLL_NOCCLK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800305
306 clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
307
308 switch (clock) {
309 case CLKMGR_CLKSRC_MAIN:
310 clock = cm_get_main_vco_clk_hz();
Ley Foon Tan26695912019-11-08 10:38:21 +0800311 clock /= (readl(socfpga_get_clkmgr_addr() +
312 CLKMGR_S10_MAINPLL_PLLC1) &
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800313 CLKMGR_PLLC0_DIV_MASK);
314 break;
315
316 case CLKMGR_CLKSRC_PER:
317 clock = cm_get_per_vco_clk_hz();
Ley Foon Tan26695912019-11-08 10:38:21 +0800318 clock /= (readl(socfpga_get_clkmgr_addr() +
319 CLKMGR_S10_PERPLL_PLLC1) & CLKMGR_CLKCNT_MSK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800320 break;
321
322 case CLKMGR_CLKSRC_OSC1:
323 clock = cm_get_osc_clk_hz();
324 break;
325
326 case CLKMGR_CLKSRC_INTOSC:
327 clock = cm_get_intosc_clk_hz();
328 break;
329
330 case CLKMGR_CLKSRC_FPGA:
331 clock = cm_get_fpga_clk_hz();
332 break;
333 }
334
Ley Foon Tan26695912019-11-08 10:38:21 +0800335 clock /= 1 + (readl(socfpga_get_clkmgr_addr() +
336 CLKMGR_S10_MAINPLL_NOCCLK) & CLKMGR_CLKCNT_MSK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800337 return clock;
338}
339
340unsigned int cm_get_mmc_controller_clk_hz(void)
341{
Ley Foon Tan26695912019-11-08 10:38:21 +0800342 u32 clock = readl(socfpga_get_clkmgr_addr() +
343 CLKMGR_S10_PERPLL_CNTR6CLK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800344
345 clock = (clock >> CLKMGR_CLKSRC_OFFSET) & CLKMGR_CLKSRC_MASK;
346
347 switch (clock) {
348 case CLKMGR_CLKSRC_MAIN:
349 clock = cm_get_l3_main_clk_hz();
Ley Foon Tan26695912019-11-08 10:38:21 +0800350 clock /= 1 + (readl(socfpga_get_clkmgr_addr() +
351 CLKMGR_S10_MAINPLL_CNTR6CLK) &
352 CLKMGR_CLKCNT_MSK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800353 break;
354
355 case CLKMGR_CLKSRC_PER:
356 clock = cm_get_l3_main_clk_hz();
Ley Foon Tan26695912019-11-08 10:38:21 +0800357 clock /= 1 + (readl(socfpga_get_clkmgr_addr() +
358 CLKMGR_S10_PERPLL_CNTR6CLK) &
359 CLKMGR_CLKCNT_MSK);
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800360 break;
361
362 case CLKMGR_CLKSRC_OSC1:
363 clock = cm_get_osc_clk_hz();
364 break;
365
366 case CLKMGR_CLKSRC_INTOSC:
367 clock = cm_get_intosc_clk_hz();
368 break;
369
370 case CLKMGR_CLKSRC_FPGA:
371 clock = cm_get_fpga_clk_hz();
372 break;
373 }
374 return clock / 4;
375}
376
377unsigned int cm_get_l4_sp_clk_hz(void)
378{
379 u32 clock = cm_get_l3_main_clk_hz();
380
Ley Foon Tan26695912019-11-08 10:38:21 +0800381 clock /= (1 << ((readl(socfpga_get_clkmgr_addr() +
382 CLKMGR_S10_MAINPLL_NOCDIV) >>
383 CLKMGR_NOCDIV_L4SPCLK_OFFSET) & CLKMGR_CLKCNT_MSK));
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800384 return clock;
385}
386
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800387unsigned int cm_get_spi_controller_clk_hz(void)
388{
389 u32 clock = cm_get_l3_main_clk_hz();
390
Ley Foon Tan26695912019-11-08 10:38:21 +0800391 clock /= (1 << ((readl(socfpga_get_clkmgr_addr() +
392 CLKMGR_S10_MAINPLL_NOCDIV) >>
393 CLKMGR_NOCDIV_L4MAIN_OFFSET) & CLKMGR_CLKCNT_MSK));
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800394 return clock;
395}
396
397unsigned int cm_get_l4_sys_free_clk_hz(void)
398{
399 return cm_get_l3_main_clk_hz() / 4;
400}
401
Dinesh Maniyamc851f2f2023-12-07 15:46:02 +0800402/*
403 * Override weak dw_spi_get_clk implementation in designware_spi.c driver
404 */
405
406int dw_spi_get_clk(struct udevice *bus, ulong *rate)
407{
408 *rate = cm_get_spi_controller_clk_hz();
409 if (!*rate) {
410 printf("SPI: clock rate is zero");
411 return -EINVAL;
412 }
413
414 return 0;
415}
416
Ley Foon Tan6751e7d2018-05-18 22:05:22 +0800417void cm_print_clock_quick_summary(void)
418{
419 printf("MPU %d kHz\n", (u32)(cm_get_mpu_clk_hz() / 1000));
420 printf("L3 main %d kHz\n", cm_get_l3_main_clk_hz() / 1000);
421 printf("Main VCO %d kHz\n", (u32)(cm_get_main_vco_clk_hz() / 1000));
422 printf("Per VCO %d kHz\n", (u32)(cm_get_per_vco_clk_hz() / 1000));
423 printf("EOSC1 %d kHz\n", cm_get_osc_clk_hz() / 1000);
424 printf("HPS MMC %d kHz\n", cm_get_mmc_controller_clk_hz() / 1000);
425 printf("UART %d kHz\n", cm_get_l4_sp_clk_hz() / 1000);
426}