1 // 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/global_data.h>
9 #include <asm/io.h>
10 #include <asm/arch/clock_manager.h>
11 #include <asm/arch/handoff_soc64.h>
12 #include <asm/arch/system_manager.h>
13 
14 DECLARE_GLOBAL_DATA_PTR;
15 
16 /*
17  * function to write the bypass register which requires a poll of the
18  * busy bit
19  */
cm_write_bypass_mainpll(u32 val)20 static void cm_write_bypass_mainpll(u32 val)
21 {
22 	writel(val, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_BYPASS);
23 	cm_wait_for_fsm();
24 }
25 
cm_write_bypass_perpll(u32 val)26 static void cm_write_bypass_perpll(u32 val)
27 {
28 	writel(val, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_BYPASS);
29 	cm_wait_for_fsm();
30 }
31 
32 /* function to write the ctrl register which requires a poll of the busy bit */
cm_write_ctrl(u32 val)33 static void cm_write_ctrl(u32 val)
34 {
35 	writel(val, socfpga_get_clkmgr_addr() + CLKMGR_S10_CTRL);
36 	cm_wait_for_fsm();
37 }
38 
39 /*
40  * Setup clocks while making no assumptions about previous state of the clocks.
41  */
cm_basic_init(const struct cm_config * const cfg)42 void 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),
67 		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);
78 
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),
94 		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);
107 
108 	/* Take both PLL out of reset and power up */
109 	setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLGLOB,
110 		     CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
111 	setbits_le32(socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLGLOB,
112 		     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 	 */
125 	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);
143 
144 	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);
180 
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 */
186 	cm_write_ctrl(readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_CTRL) &
187 		      ~(CLKMGR_CTRL_SAFEMODE));
188 
189 	/* Now ungate non-hw-managed clocks */
190 	writel(~0, socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_EN);
191 	writel(~0, socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_EN);
192 
193 	/* Clear the loss of lock bits (write 1 to clear) */
194 	writel(CLKMGR_INTER_PERPLLLOST_MASK |
195 		      CLKMGR_INTER_MAINPLLLOST_MASK,
196 		      socfpga_get_clkmgr_addr() + CLKMGR_S10_INTRCLR);
197 }
198 
cm_get_main_vco_clk_hz(void)199 static unsigned long cm_get_main_vco_clk_hz(void)
200 {
201 	 unsigned long fref, refdiv, mdiv, reg, vco;
202 
203 	reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_PLLGLOB);
204 
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 
222 	reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_MAINPLL_FDBCK);
223 	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 
cm_get_per_vco_clk_hz(void)230 static unsigned long cm_get_per_vco_clk_hz(void)
231 {
232 	unsigned long fref, refdiv, mdiv, reg, vco;
233 
234 	reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_PLLGLOB);
235 
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 
253 	reg = readl(socfpga_get_clkmgr_addr() + CLKMGR_S10_PERPLL_FDBCK);
254 	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 
cm_get_mpu_clk_hz(void)261 unsigned long cm_get_mpu_clk_hz(void)
262 {
263 	unsigned long clock = readl(socfpga_get_clkmgr_addr() +
264 				    CLKMGR_S10_MAINPLL_MPUCLK);
265 
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();
271 		clock /= (readl(socfpga_get_clkmgr_addr() +
272 				CLKMGR_S10_MAINPLL_PLLC0) &
273 			  CLKMGR_PLLC0_DIV_MASK);
274 		break;
275 
276 	case CLKMGR_CLKSRC_PER:
277 		clock = cm_get_per_vco_clk_hz();
278 		clock /= (readl(socfpga_get_clkmgr_addr() +
279 				CLKMGR_S10_PERPLL_PLLC0) &
280 			  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 
296 	clock /= 1 + (readl(socfpga_get_clkmgr_addr() +
297 			    CLKMGR_S10_MAINPLL_MPUCLK) & CLKMGR_CLKCNT_MSK);
298 	return clock;
299 }
300 
cm_get_l3_main_clk_hz(void)301 unsigned int cm_get_l3_main_clk_hz(void)
302 {
303 	u32 clock = readl(socfpga_get_clkmgr_addr() +
304 			  CLKMGR_S10_MAINPLL_NOCCLK);
305 
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();
311 		clock /= (readl(socfpga_get_clkmgr_addr() +
312 				CLKMGR_S10_MAINPLL_PLLC1) &
313 			  CLKMGR_PLLC0_DIV_MASK);
314 		break;
315 
316 	case CLKMGR_CLKSRC_PER:
317 		clock = cm_get_per_vco_clk_hz();
318 		clock /= (readl(socfpga_get_clkmgr_addr() +
319 			  CLKMGR_S10_PERPLL_PLLC1) & CLKMGR_CLKCNT_MSK);
320 		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 
335 	clock /= 1 + (readl(socfpga_get_clkmgr_addr() +
336 		      CLKMGR_S10_MAINPLL_NOCCLK) & CLKMGR_CLKCNT_MSK);
337 	return clock;
338 }
339 
cm_get_mmc_controller_clk_hz(void)340 unsigned int cm_get_mmc_controller_clk_hz(void)
341 {
342 	u32 clock = readl(socfpga_get_clkmgr_addr() +
343 			  CLKMGR_S10_PERPLL_CNTR6CLK);
344 
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();
350 		clock /= 1 + (readl(socfpga_get_clkmgr_addr() +
351 				    CLKMGR_S10_MAINPLL_CNTR6CLK) &
352 			      CLKMGR_CLKCNT_MSK);
353 		break;
354 
355 	case CLKMGR_CLKSRC_PER:
356 		clock = cm_get_l3_main_clk_hz();
357 		clock /= 1 + (readl(socfpga_get_clkmgr_addr() +
358 				    CLKMGR_S10_PERPLL_CNTR6CLK) &
359 			      CLKMGR_CLKCNT_MSK);
360 		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 
cm_get_l4_sp_clk_hz(void)377 unsigned int cm_get_l4_sp_clk_hz(void)
378 {
379 	u32 clock = cm_get_l3_main_clk_hz();
380 
381 	clock /= (1 << ((readl(socfpga_get_clkmgr_addr() +
382 			       CLKMGR_S10_MAINPLL_NOCDIV) >>
383 			 CLKMGR_NOCDIV_L4SPCLK_OFFSET) & CLKMGR_CLKCNT_MSK));
384 	return clock;
385 }
386 
cm_get_spi_controller_clk_hz(void)387 unsigned int cm_get_spi_controller_clk_hz(void)
388 {
389 	u32 clock = cm_get_l3_main_clk_hz();
390 
391 	clock /= (1 << ((readl(socfpga_get_clkmgr_addr() +
392 			       CLKMGR_S10_MAINPLL_NOCDIV) >>
393 			 CLKMGR_NOCDIV_L4MAIN_OFFSET) & CLKMGR_CLKCNT_MSK));
394 	return clock;
395 }
396 
cm_get_l4_sys_free_clk_hz(void)397 unsigned int cm_get_l4_sys_free_clk_hz(void)
398 {
399 	return cm_get_l3_main_clk_hz() / 4;
400 }
401 
cm_print_clock_quick_summary(void)402 void cm_print_clock_quick_summary(void)
403 {
404 	printf("MPU         %d kHz\n", (u32)(cm_get_mpu_clk_hz() / 1000));
405 	printf("L3 main     %d kHz\n", cm_get_l3_main_clk_hz() / 1000);
406 	printf("Main VCO    %d kHz\n", (u32)(cm_get_main_vco_clk_hz() / 1000));
407 	printf("Per VCO     %d kHz\n", (u32)(cm_get_per_vco_clk_hz() / 1000));
408 	printf("EOSC1       %d kHz\n", cm_get_osc_clk_hz() / 1000);
409 	printf("HPS MMC     %d kHz\n", cm_get_mmc_controller_clk_hz() / 1000);
410 	printf("UART        %d kHz\n", cm_get_l4_sp_clk_hz() / 1000);
411 }
412