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