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