xref: /openbmc/u-boot/arch/arm/mach-imx/mx7ulp/scg.c (revision 3ebd892f)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2016 Freescale Semiconductor, Inc.
4  */
5 
6 #include <common.h>
7 #include <div64.h>
8 #include <asm/io.h>
9 #include <errno.h>
10 #include <asm/arch/imx-regs.h>
11 #include <asm/arch/pcc.h>
12 #include <asm/arch/sys_proto.h>
13 
14 scg_p scg1_regs = (scg_p)SCG1_RBASE;
15 
16 static u32 scg_src_get_rate(enum scg_clk clksrc)
17 {
18 	u32 reg;
19 
20 	switch (clksrc) {
21 	case SCG_SOSC_CLK:
22 		reg = readl(&scg1_regs->sosccsr);
23 		if (!(reg & SCG_SOSC_CSR_SOSCVLD_MASK))
24 			return 0;
25 
26 		return 24000000;
27 	case SCG_FIRC_CLK:
28 		reg = readl(&scg1_regs->firccsr);
29 		if (!(reg & SCG_FIRC_CSR_FIRCVLD_MASK))
30 			return 0;
31 
32 		return 48000000;
33 	case SCG_SIRC_CLK:
34 		reg = readl(&scg1_regs->sirccsr);
35 		if (!(reg & SCG_SIRC_CSR_SIRCVLD_MASK))
36 			return 0;
37 
38 		return 16000000;
39 	case SCG_ROSC_CLK:
40 		reg = readl(&scg1_regs->rtccsr);
41 		if (!(reg & SCG_ROSC_CSR_ROSCVLD_MASK))
42 			return 0;
43 
44 		return 32768;
45 	default:
46 		break;
47 	}
48 
49 	return 0;
50 }
51 
52 static u32 scg_sircdiv_get_rate(enum scg_clk clk)
53 {
54 	u32 reg, val, rate;
55 	u32 shift, mask;
56 
57 	switch (clk) {
58 	case SCG_SIRC_DIV1_CLK:
59 		mask = SCG_SIRCDIV_DIV1_MASK;
60 		shift = SCG_SIRCDIV_DIV1_SHIFT;
61 		break;
62 	case SCG_SIRC_DIV2_CLK:
63 		mask = SCG_SIRCDIV_DIV2_MASK;
64 		shift = SCG_SIRCDIV_DIV2_SHIFT;
65 		break;
66 	case SCG_SIRC_DIV3_CLK:
67 		mask = SCG_SIRCDIV_DIV3_MASK;
68 		shift = SCG_SIRCDIV_DIV3_SHIFT;
69 		break;
70 	default:
71 		return 0;
72 	}
73 
74 	reg = readl(&scg1_regs->sirccsr);
75 	if (!(reg & SCG_SIRC_CSR_SIRCVLD_MASK))
76 		return 0;
77 
78 	reg = readl(&scg1_regs->sircdiv);
79 	val = (reg & mask) >> shift;
80 
81 	if (!val) /*clock disabled*/
82 		return 0;
83 
84 	rate = scg_src_get_rate(SCG_SIRC_CLK);
85 	rate = rate / (1 << (val - 1));
86 
87 	return rate;
88 }
89 
90 static u32 scg_fircdiv_get_rate(enum scg_clk clk)
91 {
92 	u32 reg, val, rate;
93 	u32 shift, mask;
94 
95 	switch (clk) {
96 	case SCG_FIRC_DIV1_CLK:
97 		mask = SCG_FIRCDIV_DIV1_MASK;
98 		shift = SCG_FIRCDIV_DIV1_SHIFT;
99 		break;
100 	case SCG_FIRC_DIV2_CLK:
101 		mask = SCG_FIRCDIV_DIV2_MASK;
102 		shift = SCG_FIRCDIV_DIV2_SHIFT;
103 		break;
104 	case SCG_FIRC_DIV3_CLK:
105 		mask = SCG_FIRCDIV_DIV3_MASK;
106 		shift = SCG_FIRCDIV_DIV3_SHIFT;
107 		break;
108 	default:
109 		return 0;
110 	}
111 
112 	reg = readl(&scg1_regs->firccsr);
113 	if (!(reg & SCG_FIRC_CSR_FIRCVLD_MASK))
114 		return 0;
115 
116 	reg = readl(&scg1_regs->fircdiv);
117 	val = (reg & mask) >> shift;
118 
119 	if (!val) /*clock disabled*/
120 		return 0;
121 
122 	rate = scg_src_get_rate(SCG_FIRC_CLK);
123 	rate = rate / (1 << (val - 1));
124 
125 	return rate;
126 }
127 
128 static u32 scg_soscdiv_get_rate(enum scg_clk clk)
129 {
130 	u32 reg, val, rate;
131 	u32 shift, mask;
132 
133 	switch (clk) {
134 	case SCG_SOSC_DIV1_CLK:
135 		mask = SCG_SOSCDIV_DIV1_MASK;
136 		shift = SCG_SOSCDIV_DIV1_SHIFT;
137 		break;
138 	case SCG_SOSC_DIV2_CLK:
139 		mask = SCG_SOSCDIV_DIV2_MASK;
140 		shift = SCG_SOSCDIV_DIV2_SHIFT;
141 		break;
142 	case SCG_SOSC_DIV3_CLK:
143 		mask = SCG_SOSCDIV_DIV3_MASK;
144 		shift = SCG_SOSCDIV_DIV3_SHIFT;
145 		break;
146 	default:
147 		return 0;
148 	}
149 
150 	reg = readl(&scg1_regs->sosccsr);
151 	if (!(reg & SCG_SOSC_CSR_SOSCVLD_MASK))
152 		return 0;
153 
154 	reg = readl(&scg1_regs->soscdiv);
155 	val = (reg & mask) >> shift;
156 
157 	if (!val) /*clock disabled*/
158 		return 0;
159 
160 	rate = scg_src_get_rate(SCG_SOSC_CLK);
161 	rate = rate / (1 << (val - 1));
162 
163 	return rate;
164 }
165 
166 static u32 scg_apll_pfd_get_rate(enum scg_clk clk)
167 {
168 	u32 reg, val, rate;
169 	u32 shift, mask, gate, valid;
170 
171 	switch (clk) {
172 	case SCG_APLL_PFD0_CLK:
173 		gate = SCG_PLL_PFD0_GATE_MASK;
174 		valid = SCG_PLL_PFD0_VALID_MASK;
175 		mask = SCG_PLL_PFD0_FRAC_MASK;
176 		shift = SCG_PLL_PFD0_FRAC_SHIFT;
177 		break;
178 	case SCG_APLL_PFD1_CLK:
179 		gate = SCG_PLL_PFD1_GATE_MASK;
180 		valid = SCG_PLL_PFD1_VALID_MASK;
181 		mask = SCG_PLL_PFD1_FRAC_MASK;
182 		shift = SCG_PLL_PFD1_FRAC_SHIFT;
183 		break;
184 	case SCG_APLL_PFD2_CLK:
185 		gate = SCG_PLL_PFD2_GATE_MASK;
186 		valid = SCG_PLL_PFD2_VALID_MASK;
187 		mask = SCG_PLL_PFD2_FRAC_MASK;
188 		shift = SCG_PLL_PFD2_FRAC_SHIFT;
189 		break;
190 	case SCG_APLL_PFD3_CLK:
191 		gate = SCG_PLL_PFD3_GATE_MASK;
192 		valid = SCG_PLL_PFD3_VALID_MASK;
193 		mask = SCG_PLL_PFD3_FRAC_MASK;
194 		shift = SCG_PLL_PFD3_FRAC_SHIFT;
195 		break;
196 	default:
197 		return 0;
198 	}
199 
200 	reg = readl(&scg1_regs->apllpfd);
201 	if (reg & gate || !(reg & valid))
202 		return 0;
203 
204 	clk_debug("scg_apll_pfd_get_rate reg 0x%x\n", reg);
205 
206 	val = (reg & mask) >> shift;
207 	rate = decode_pll(PLL_A7_APLL);
208 
209 	rate = rate / val * 18;
210 
211 	clk_debug("scg_apll_pfd_get_rate rate %u\n", rate);
212 
213 	return rate;
214 }
215 
216 static u32 scg_spll_pfd_get_rate(enum scg_clk clk)
217 {
218 	u32 reg, val, rate;
219 	u32 shift, mask, gate, valid;
220 
221 	switch (clk) {
222 	case SCG_SPLL_PFD0_CLK:
223 		gate = SCG_PLL_PFD0_GATE_MASK;
224 		valid = SCG_PLL_PFD0_VALID_MASK;
225 		mask = SCG_PLL_PFD0_FRAC_MASK;
226 		shift = SCG_PLL_PFD0_FRAC_SHIFT;
227 		break;
228 	case SCG_SPLL_PFD1_CLK:
229 		gate = SCG_PLL_PFD1_GATE_MASK;
230 		valid = SCG_PLL_PFD1_VALID_MASK;
231 		mask = SCG_PLL_PFD1_FRAC_MASK;
232 		shift = SCG_PLL_PFD1_FRAC_SHIFT;
233 		break;
234 	case SCG_SPLL_PFD2_CLK:
235 		gate = SCG_PLL_PFD2_GATE_MASK;
236 		valid = SCG_PLL_PFD2_VALID_MASK;
237 		mask = SCG_PLL_PFD2_FRAC_MASK;
238 		shift = SCG_PLL_PFD2_FRAC_SHIFT;
239 		break;
240 	case SCG_SPLL_PFD3_CLK:
241 		gate = SCG_PLL_PFD3_GATE_MASK;
242 		valid = SCG_PLL_PFD3_VALID_MASK;
243 		mask = SCG_PLL_PFD3_FRAC_MASK;
244 		shift = SCG_PLL_PFD3_FRAC_SHIFT;
245 		break;
246 	default:
247 		return 0;
248 	}
249 
250 	reg = readl(&scg1_regs->spllpfd);
251 	if (reg & gate || !(reg & valid))
252 		return 0;
253 
254 	clk_debug("scg_spll_pfd_get_rate reg 0x%x\n", reg);
255 
256 	val = (reg & mask) >> shift;
257 	rate = decode_pll(PLL_A7_SPLL);
258 
259 	rate = rate / val * 18;
260 
261 	clk_debug("scg_spll_pfd_get_rate rate %u\n", rate);
262 
263 	return rate;
264 }
265 
266 static u32 scg_apll_get_rate(void)
267 {
268 	u32 reg, val, rate;
269 
270 	reg = readl(&scg1_regs->apllcfg);
271 	val = (reg & SCG_PLL_CFG_PLLSEL_MASK) >> SCG_PLL_CFG_PLLSEL_SHIFT;
272 
273 	if (!val) {
274 		/* APLL clock after two dividers */
275 		rate = decode_pll(PLL_A7_APLL);
276 
277 		val = (reg & SCG_PLL_CFG_POSTDIV1_MASK) >>
278 			SCG_PLL_CFG_POSTDIV1_SHIFT;
279 		rate = rate / (val + 1);
280 
281 		val = (reg & SCG_PLL_CFG_POSTDIV2_MASK) >>
282 			SCG_PLL_CFG_POSTDIV2_SHIFT;
283 		rate = rate / (val + 1);
284 	} else {
285 		/* APLL PFD clock */
286 		val = (reg & SCG_PLL_CFG_PFDSEL_MASK) >>
287 			SCG_PLL_CFG_PFDSEL_SHIFT;
288 		rate = scg_apll_pfd_get_rate(SCG_APLL_PFD0_CLK + val);
289 	}
290 
291 	return rate;
292 }
293 
294 static u32 scg_spll_get_rate(void)
295 {
296 	u32 reg, val, rate;
297 
298 	reg = readl(&scg1_regs->spllcfg);
299 	val = (reg & SCG_PLL_CFG_PLLSEL_MASK) >> SCG_PLL_CFG_PLLSEL_SHIFT;
300 
301 	clk_debug("scg_spll_get_rate reg 0x%x\n", reg);
302 
303 	if (!val) {
304 		/* APLL clock after two dividers */
305 		rate = decode_pll(PLL_A7_SPLL);
306 
307 		val = (reg & SCG_PLL_CFG_POSTDIV1_MASK) >>
308 			SCG_PLL_CFG_POSTDIV1_SHIFT;
309 		rate = rate / (val + 1);
310 
311 		val = (reg & SCG_PLL_CFG_POSTDIV2_MASK) >>
312 			SCG_PLL_CFG_POSTDIV2_SHIFT;
313 		rate = rate / (val + 1);
314 
315 		clk_debug("scg_spll_get_rate SPLL %u\n", rate);
316 
317 	} else {
318 		/* APLL PFD clock */
319 		val = (reg & SCG_PLL_CFG_PFDSEL_MASK) >>
320 			SCG_PLL_CFG_PFDSEL_SHIFT;
321 		rate = scg_spll_pfd_get_rate(SCG_SPLL_PFD0_CLK + val);
322 
323 		clk_debug("scg_spll_get_rate PFD %u\n", rate);
324 	}
325 
326 	return rate;
327 }
328 
329 static u32 scg_ddr_get_rate(void)
330 {
331 	u32 reg, val, rate, div;
332 
333 	reg = readl(&scg1_regs->ddrccr);
334 	val = (reg & SCG_DDRCCR_DDRCS_MASK) >> SCG_DDRCCR_DDRCS_SHIFT;
335 	div = (reg & SCG_DDRCCR_DDRDIV_MASK) >> SCG_DDRCCR_DDRDIV_SHIFT;
336 
337 	if (!div)
338 		return 0;
339 
340 	if (!val) {
341 		reg = readl(&scg1_regs->apllcfg);
342 		val = (reg & SCG_PLL_CFG_PFDSEL_MASK) >>
343 			SCG_PLL_CFG_PFDSEL_SHIFT;
344 		rate = scg_apll_pfd_get_rate(SCG_APLL_PFD0_CLK + val);
345 	} else {
346 		rate = decode_pll(PLL_USB);
347 	}
348 
349 	rate = rate / (1 << (div - 1));
350 	return rate;
351 }
352 
353 static u32 scg_nic_get_rate(enum scg_clk clk)
354 {
355 	u32 reg, val, rate;
356 	u32 shift, mask;
357 
358 	reg = readl(&scg1_regs->niccsr);
359 	val = (reg & SCG_NICCSR_NICCS_MASK) >> SCG_NICCSR_NICCS_SHIFT;
360 
361 	clk_debug("scg_nic_get_rate niccsr 0x%x\n", reg);
362 
363 	if (!val)
364 		rate = scg_src_get_rate(SCG_FIRC_CLK);
365 	else
366 		rate = scg_ddr_get_rate();
367 
368 	clk_debug("scg_nic_get_rate parent rate %u\n", rate);
369 
370 	val = (reg & SCG_NICCSR_NIC0DIV_MASK) >> SCG_NICCSR_NIC0DIV_SHIFT;
371 
372 	rate = rate / (val + 1);
373 
374 	clk_debug("scg_nic_get_rate NIC0 rate %u\n", rate);
375 
376 	switch (clk) {
377 	case SCG_NIC0_CLK:
378 		return rate;
379 	case SCG_GPU_CLK:
380 		mask = SCG_NICCSR_GPUDIV_MASK;
381 		shift = SCG_NICCSR_GPUDIV_SHIFT;
382 		break;
383 	case SCG_NIC1_EXT_CLK:
384 	case SCG_NIC1_BUS_CLK:
385 	case SCG_NIC1_CLK:
386 		mask = SCG_NICCSR_NIC1DIV_MASK;
387 		shift = SCG_NICCSR_NIC1DIV_SHIFT;
388 		break;
389 	default:
390 		return 0;
391 	}
392 
393 	val = (reg & mask) >> shift;
394 	rate = rate / (val + 1);
395 
396 	clk_debug("scg_nic_get_rate NIC1 rate %u\n", rate);
397 
398 	switch (clk) {
399 	case SCG_GPU_CLK:
400 	case SCG_NIC1_CLK:
401 		return rate;
402 	case SCG_NIC1_EXT_CLK:
403 		mask = SCG_NICCSR_NIC1EXTDIV_MASK;
404 		shift = SCG_NICCSR_NIC1EXTDIV_SHIFT;
405 		break;
406 	case SCG_NIC1_BUS_CLK:
407 		mask = SCG_NICCSR_NIC1BUSDIV_MASK;
408 		shift = SCG_NICCSR_NIC1BUSDIV_SHIFT;
409 		break;
410 	default:
411 		return 0;
412 	}
413 
414 	val = (reg & mask) >> shift;
415 	rate = rate / (val + 1);
416 
417 	clk_debug("scg_nic_get_rate NIC1 bus rate %u\n", rate);
418 	return rate;
419 }
420 
421 
422 static enum scg_clk scg_scs_array[4] = {
423 	SCG_SOSC_CLK, SCG_SIRC_CLK, SCG_FIRC_CLK, SCG_ROSC_CLK,
424 };
425 
426 static u32 scg_sys_get_rate(enum scg_clk clk)
427 {
428 	u32 reg, val, rate;
429 
430 	if (clk != SCG_CORE_CLK && clk != SCG_BUS_CLK)
431 		return 0;
432 
433 	reg = readl(&scg1_regs->csr);
434 	val = (reg & SCG_CCR_SCS_MASK) >> SCG_CCR_SCS_SHIFT;
435 
436 	clk_debug("scg_sys_get_rate reg 0x%x\n", reg);
437 
438 	switch (val) {
439 	case SCG_SCS_SYS_OSC:
440 	case SCG_SCS_SLOW_IRC:
441 	case SCG_SCS_FAST_IRC:
442 	case SCG_SCS_RTC_OSC:
443 		rate = scg_src_get_rate(scg_scs_array[val]);
444 		break;
445 	case 5:
446 		rate = scg_apll_get_rate();
447 		break;
448 	case 6:
449 		rate = scg_spll_get_rate();
450 		break;
451 	default:
452 		return 0;
453 	}
454 
455 	clk_debug("scg_sys_get_rate parent rate %u\n", rate);
456 
457 	val = (reg & SCG_CCR_DIVCORE_MASK) >> SCG_CCR_DIVCORE_SHIFT;
458 
459 	rate = rate / (val + 1);
460 
461 	if (clk == SCG_BUS_CLK) {
462 		val = (reg & SCG_CCR_DIVBUS_MASK) >> SCG_CCR_DIVBUS_SHIFT;
463 		rate = rate / (val + 1);
464 	}
465 
466 	return rate;
467 }
468 
469 u32 decode_pll(enum pll_clocks pll)
470 {
471 	u32 reg,  pre_div, infreq, mult;
472 	u32 num, denom;
473 
474 	/*
475 	 * Alought there are four choices for the bypass src,
476 	 * we choose OSC_24M which is the default set in ROM.
477 	 */
478 	switch (pll) {
479 	case PLL_A7_SPLL:
480 		reg = readl(&scg1_regs->spllcsr);
481 
482 		if (!(reg & SCG_SPLL_CSR_SPLLVLD_MASK))
483 			return 0;
484 
485 		reg = readl(&scg1_regs->spllcfg);
486 
487 		pre_div = (reg & SCG_PLL_CFG_PREDIV_MASK) >>
488 			   SCG_PLL_CFG_PREDIV_SHIFT;
489 		pre_div += 1;
490 
491 		mult = (reg & SCG1_SPLL_CFG_MULT_MASK) >>
492 			   SCG_PLL_CFG_MULT_SHIFT;
493 
494 		infreq = (reg & SCG_PLL_CFG_CLKSRC_MASK) >>
495 			   SCG_PLL_CFG_CLKSRC_SHIFT;
496 		if (!infreq)
497 			infreq = scg_src_get_rate(SCG_SOSC_CLK);
498 		else
499 			infreq = scg_src_get_rate(SCG_FIRC_CLK);
500 
501 		num = readl(&scg1_regs->spllnum);
502 		denom = readl(&scg1_regs->splldenom);
503 
504 		infreq = infreq / pre_div;
505 
506 		return infreq * mult + infreq * num / denom;
507 
508 	case PLL_A7_APLL:
509 		reg = readl(&scg1_regs->apllcsr);
510 
511 		if (!(reg & SCG_APLL_CSR_APLLVLD_MASK))
512 			return 0;
513 
514 		reg = readl(&scg1_regs->apllcfg);
515 
516 		pre_div = (reg & SCG_PLL_CFG_PREDIV_MASK) >>
517 			   SCG_PLL_CFG_PREDIV_SHIFT;
518 		pre_div += 1;
519 
520 		mult = (reg & SCG_APLL_CFG_MULT_MASK) >>
521 			   SCG_PLL_CFG_MULT_SHIFT;
522 
523 		infreq = (reg & SCG_PLL_CFG_CLKSRC_MASK) >>
524 			   SCG_PLL_CFG_CLKSRC_SHIFT;
525 		if (!infreq)
526 			infreq = scg_src_get_rate(SCG_SOSC_CLK);
527 		else
528 			infreq = scg_src_get_rate(SCG_FIRC_CLK);
529 
530 		num = readl(&scg1_regs->apllnum);
531 		denom = readl(&scg1_regs->aplldenom);
532 
533 		infreq = infreq / pre_div;
534 
535 		return infreq * mult + infreq * num / denom;
536 
537 	case PLL_USB:
538 		reg = readl(&scg1_regs->upllcsr);
539 
540 		if (!(reg & SCG_UPLL_CSR_UPLLVLD_MASK))
541 			return 0;
542 
543 		return 480000000u;
544 
545 	case PLL_MIPI:
546 		return 480000000u;
547 	default:
548 		printf("Unsupported pll clocks %d\n", pll);
549 		break;
550 	}
551 
552 	return 0;
553 }
554 
555 u32 scg_clk_get_rate(enum scg_clk clk)
556 {
557 	switch (clk) {
558 	case SCG_SIRC_DIV1_CLK:
559 	case SCG_SIRC_DIV2_CLK:
560 	case SCG_SIRC_DIV3_CLK:
561 		return scg_sircdiv_get_rate(clk);
562 
563 	case SCG_FIRC_DIV1_CLK:
564 	case SCG_FIRC_DIV2_CLK:
565 	case SCG_FIRC_DIV3_CLK:
566 		return scg_fircdiv_get_rate(clk);
567 
568 	case SCG_SOSC_DIV1_CLK:
569 	case SCG_SOSC_DIV2_CLK:
570 	case SCG_SOSC_DIV3_CLK:
571 		return scg_soscdiv_get_rate(clk);
572 
573 	case SCG_CORE_CLK:
574 	case SCG_BUS_CLK:
575 		return scg_sys_get_rate(clk);
576 
577 	case SCG_SPLL_PFD0_CLK:
578 	case SCG_SPLL_PFD1_CLK:
579 	case SCG_SPLL_PFD2_CLK:
580 	case SCG_SPLL_PFD3_CLK:
581 		return scg_spll_pfd_get_rate(clk);
582 
583 	case SCG_APLL_PFD0_CLK:
584 	case SCG_APLL_PFD1_CLK:
585 	case SCG_APLL_PFD2_CLK:
586 	case SCG_APLL_PFD3_CLK:
587 		return scg_apll_pfd_get_rate(clk);
588 
589 	case SCG_DDR_CLK:
590 		return scg_ddr_get_rate();
591 
592 	case SCG_NIC0_CLK:
593 	case SCG_GPU_CLK:
594 	case SCG_NIC1_CLK:
595 	case SCG_NIC1_BUS_CLK:
596 	case SCG_NIC1_EXT_CLK:
597 		return scg_nic_get_rate(clk);
598 
599 	case USB_PLL_OUT:
600 		return decode_pll(PLL_USB);
601 
602 	case MIPI_PLL_OUT:
603 		return decode_pll(PLL_MIPI);
604 
605 	case SCG_SOSC_CLK:
606 	case SCG_FIRC_CLK:
607 	case SCG_SIRC_CLK:
608 	case SCG_ROSC_CLK:
609 		return scg_src_get_rate(clk);
610 	default:
611 		return 0;
612 	}
613 }
614 
615 int scg_enable_pll_pfd(enum scg_clk clk, u32 frac)
616 {
617 	u32 reg;
618 	u32 shift, mask, gate, valid;
619 	u32 addr;
620 
621 	if (frac < 12 || frac > 35)
622 		return -EINVAL;
623 
624 	switch (clk) {
625 	case SCG_SPLL_PFD0_CLK:
626 	case SCG_APLL_PFD0_CLK:
627 		gate = SCG_PLL_PFD0_GATE_MASK;
628 		valid = SCG_PLL_PFD0_VALID_MASK;
629 		mask = SCG_PLL_PFD0_FRAC_MASK;
630 		shift = SCG_PLL_PFD0_FRAC_SHIFT;
631 
632 		if (clk == SCG_SPLL_PFD0_CLK)
633 			addr = (u32)(&scg1_regs->spllpfd);
634 		else
635 			addr = (u32)(&scg1_regs->apllpfd);
636 		break;
637 	case SCG_SPLL_PFD1_CLK:
638 	case SCG_APLL_PFD1_CLK:
639 		gate = SCG_PLL_PFD1_GATE_MASK;
640 		valid = SCG_PLL_PFD1_VALID_MASK;
641 		mask = SCG_PLL_PFD1_FRAC_MASK;
642 		shift = SCG_PLL_PFD1_FRAC_SHIFT;
643 
644 		if (clk == SCG_SPLL_PFD1_CLK)
645 			addr = (u32)(&scg1_regs->spllpfd);
646 		else
647 			addr = (u32)(&scg1_regs->apllpfd);
648 		break;
649 	case SCG_SPLL_PFD2_CLK:
650 	case SCG_APLL_PFD2_CLK:
651 		gate = SCG_PLL_PFD2_GATE_MASK;
652 		valid = SCG_PLL_PFD2_VALID_MASK;
653 		mask = SCG_PLL_PFD2_FRAC_MASK;
654 		shift = SCG_PLL_PFD2_FRAC_SHIFT;
655 
656 		if (clk == SCG_SPLL_PFD2_CLK)
657 			addr = (u32)(&scg1_regs->spllpfd);
658 		else
659 			addr = (u32)(&scg1_regs->apllpfd);
660 		break;
661 	case SCG_SPLL_PFD3_CLK:
662 	case SCG_APLL_PFD3_CLK:
663 		gate = SCG_PLL_PFD3_GATE_MASK;
664 		valid = SCG_PLL_PFD3_VALID_MASK;
665 		mask = SCG_PLL_PFD3_FRAC_MASK;
666 		shift = SCG_PLL_PFD3_FRAC_SHIFT;
667 
668 		if (clk == SCG_SPLL_PFD3_CLK)
669 			addr = (u32)(&scg1_regs->spllpfd);
670 		else
671 			addr = (u32)(&scg1_regs->apllpfd);
672 		break;
673 	default:
674 		return -EINVAL;
675 	}
676 
677 	/* Gate the PFD */
678 	reg = readl(addr);
679 	reg |= gate;
680 	writel(reg, addr);
681 
682 	/* Write Frac divider */
683 	reg &= ~mask;
684 	reg |= (frac << shift) & mask;
685 	writel(reg, addr);
686 
687 	/*
688 	 * Un-gate the PFD
689 	 * (Need un-gate before checking valid, not align with RM)
690 	 */
691 	reg &= ~gate;
692 	writel(reg, addr);
693 
694 	/* Wait for PFD clock being valid */
695 	do {
696 		reg = readl(addr);
697 	} while (!(reg & valid));
698 
699 	return 0;
700 }
701 
702 #define SIM_MISC_CTRL0_USB_PLL_EN_MASK (0x1 << 2)
703 int scg_enable_usb_pll(bool usb_control)
704 {
705 	u32 sosc_rate;
706 	s32 timeout = 1000000;
707 	u32 reg;
708 
709 	struct usbphy_regs *usbphy =
710 		(struct usbphy_regs *)USBPHY_RBASE;
711 
712 	sosc_rate = scg_src_get_rate(SCG_SOSC_CLK);
713 	if (!sosc_rate)
714 		return -EPERM;
715 
716 	reg = readl(SIM0_RBASE + 0x3C);
717 	if (usb_control)
718 		reg &= ~SIM_MISC_CTRL0_USB_PLL_EN_MASK;
719 	else
720 		reg |= SIM_MISC_CTRL0_USB_PLL_EN_MASK;
721 	writel(reg, SIM0_RBASE + 0x3C);
722 
723 	if (!(readl(&usbphy->usb1_pll_480_ctrl) & PLL_USB_LOCK_MASK)) {
724 		writel(0x1c00000, &usbphy->usb1_pll_480_ctrl_clr);
725 
726 		switch (sosc_rate) {
727 		case 24000000:
728 			writel(0xc00000, &usbphy->usb1_pll_480_ctrl_set);
729 			break;
730 
731 		case 30000000:
732 			writel(0x800000, &usbphy->usb1_pll_480_ctrl_set);
733 			break;
734 
735 		case 19200000:
736 			writel(0x1400000, &usbphy->usb1_pll_480_ctrl_set);
737 			break;
738 
739 		default:
740 			writel(0xc00000, &usbphy->usb1_pll_480_ctrl_set);
741 			break;
742 		}
743 
744 		/* Enable the regulator first */
745 		writel(PLL_USB_REG_ENABLE_MASK,
746 		       &usbphy->usb1_pll_480_ctrl_set);
747 
748 		/* Wait at least 15us */
749 		udelay(15);
750 
751 		/* Enable the power */
752 		writel(PLL_USB_PWR_MASK, &usbphy->usb1_pll_480_ctrl_set);
753 
754 		/* Wait lock */
755 		while (timeout--) {
756 			if (readl(&usbphy->usb1_pll_480_ctrl) &
757 			    PLL_USB_LOCK_MASK)
758 				break;
759 		}
760 
761 		if (timeout <= 0) {
762 			/* If timeout, we power down the pll */
763 			writel(PLL_USB_PWR_MASK,
764 			       &usbphy->usb1_pll_480_ctrl_clr);
765 			return -ETIME;
766 		}
767 	}
768 
769 	/* Clear the bypass */
770 	writel(PLL_USB_BYPASS_MASK, &usbphy->usb1_pll_480_ctrl_clr);
771 
772 	/* Enable the PLL clock out to USB */
773 	writel((PLL_USB_EN_USB_CLKS_MASK | PLL_USB_ENABLE_MASK),
774 	       &usbphy->usb1_pll_480_ctrl_set);
775 
776 	if (!usb_control) {
777 		while (timeout--) {
778 			if (readl(&scg1_regs->upllcsr) &
779 			    SCG_UPLL_CSR_UPLLVLD_MASK)
780 				break;
781 		}
782 
783 		if (timeout <= 0) {
784 			reg = readl(SIM0_RBASE + 0x3C);
785 			reg &= ~SIM_MISC_CTRL0_USB_PLL_EN_MASK;
786 			writel(reg, SIM0_RBASE + 0x3C);
787 			return -ETIME;
788 		}
789 	}
790 
791 	return 0;
792 }
793 
794 
795 /* A7 domain system clock source is SPLL */
796 #define SCG1_RCCR_SCS_NUM	((SCG_SCS_SYS_PLL) << SCG_CCR_SCS_SHIFT)
797 
798 /* A7 Core clck = SPLL PFD0 / 1 = 500MHz / 1 = 500MHz */
799 #define SCG1_RCCR_DIVCORE_NUM	((0x0)  << SCG_CCR_DIVCORE_SHIFT)
800 #define SCG1_RCCR_CFG_MASK	(SCG_CCR_SCS_MASK | SCG_CCR_DIVBUS_MASK)
801 
802 /* A7 Plat clck = A7 Core Clock / 2 = 250MHz / 1 = 250MHz */
803 #define SCG1_RCCR_DIVBUS_NUM	((0x1)  << SCG_CCR_DIVBUS_SHIFT)
804 #define SCG1_RCCR_CFG_NUM	(SCG1_RCCR_SCS_NUM | SCG1_RCCR_DIVBUS_NUM)
805 
806 void scg_a7_rccr_init(void)
807 {
808 	u32 rccr_reg_val = 0;
809 
810 	rccr_reg_val = readl(&scg1_regs->rccr);
811 
812 	rccr_reg_val &= (~SCG1_RCCR_CFG_MASK);
813 	rccr_reg_val |= (SCG1_RCCR_CFG_NUM);
814 
815 	writel(rccr_reg_val, &scg1_regs->rccr);
816 }
817 
818 /* POSTDIV2 = 1 */
819 #define SCG1_SPLL_CFG_POSTDIV2_NUM	((0x0)  << SCG_PLL_CFG_POSTDIV2_SHIFT)
820 /* POSTDIV1 = 1 */
821 #define SCG1_SPLL_CFG_POSTDIV1_NUM	((0x0)  << SCG_PLL_CFG_POSTDIV1_SHIFT)
822 
823 /* MULT = 22 */
824 #define SCG1_SPLL_CFG_MULT_NUM		((22)   << SCG_PLL_CFG_MULT_SHIFT)
825 
826 /* PFD0 output clock selected */
827 #define SCG1_SPLL_CFG_PFDSEL_NUM	((0) << SCG_PLL_CFG_PFDSEL_SHIFT)
828 /* PREDIV = 1 */
829 #define SCG1_SPLL_CFG_PREDIV_NUM	((0x0)  << SCG_PLL_CFG_PREDIV_SHIFT)
830 /* SPLL output clocks (including PFD outputs) selected */
831 #define SCG1_SPLL_CFG_BYPASS_NUM	((0x0)  << SCG_PLL_CFG_BYPASS_SHIFT)
832 /* SPLL PFD output clock selected */
833 #define SCG1_SPLL_CFG_PLLSEL_NUM	((0x1)  << SCG_PLL_CFG_PLLSEL_SHIFT)
834 /* Clock source is System OSC */
835 #define SCG1_SPLL_CFG_CLKSRC_NUM	((0x0)  << SCG_PLL_CFG_CLKSRC_SHIFT)
836 #define SCG1_SPLL_CFG_NUM_24M_OSC	(SCG1_SPLL_CFG_POSTDIV2_NUM	| \
837 					 SCG1_SPLL_CFG_POSTDIV1_NUM     | \
838 					 (22 << SCG_PLL_CFG_MULT_SHIFT) | \
839 					 SCG1_SPLL_CFG_PFDSEL_NUM       | \
840 					 SCG1_SPLL_CFG_PREDIV_NUM       | \
841 					 SCG1_SPLL_CFG_BYPASS_NUM       | \
842 					 SCG1_SPLL_CFG_PLLSEL_NUM       | \
843 					 SCG1_SPLL_CFG_CLKSRC_NUM)
844 /*413Mhz = A7 SPLL(528MHz) * 18/23 */
845 #define SCG1_SPLL_PFD0_FRAC_NUM		((23) << SCG_PLL_PFD0_FRAC_SHIFT)
846 
847 void scg_a7_spll_init(void)
848 {
849 	u32 val = 0;
850 
851 	/* Disable A7 System PLL */
852 	val = readl(&scg1_regs->spllcsr);
853 	val &= ~SCG_SPLL_CSR_SPLLEN_MASK;
854 	writel(val, &scg1_regs->spllcsr);
855 
856 	/*
857 	 * Per block guide,
858 	 * "When changing PFD values, it is recommneded PFDx clock
859 	 * gets gated first by writing a value of 1 to PFDx_CLKGATE register,
860 	 * then program the new PFD value, then poll the PFDx_VALID
861 	 * flag to set before writing a value of 0 to PFDx_CLKGATE
862 	 * to ungate the PFDx clock and allow PFDx clock to run"
863 	 */
864 
865 	/* Gate off A7 SPLL PFD0 ~ PDF4  */
866 	val = readl(&scg1_regs->spllpfd);
867 	val |= (SCG_PLL_PFD3_GATE_MASK |
868 			SCG_PLL_PFD2_GATE_MASK |
869 			SCG_PLL_PFD1_GATE_MASK |
870 			SCG_PLL_PFD0_GATE_MASK);
871 	writel(val, &scg1_regs->spllpfd);
872 
873 	/* ================ A7 SPLL Configuration Start ============== */
874 
875 	/* Configure A7 System PLL */
876 	writel(SCG1_SPLL_CFG_NUM_24M_OSC, &scg1_regs->spllcfg);
877 
878 	/* Enable A7 System PLL */
879 	val = readl(&scg1_regs->spllcsr);
880 	val |= SCG_SPLL_CSR_SPLLEN_MASK;
881 	writel(val, &scg1_regs->spllcsr);
882 
883 	/* Wait for A7 SPLL clock ready */
884 	while (!(readl(&scg1_regs->spllcsr) & SCG_SPLL_CSR_SPLLVLD_MASK))
885 		;
886 
887 	/* Configure A7 SPLL PFD0 */
888 	val = readl(&scg1_regs->spllpfd);
889 	val &= ~SCG_PLL_PFD0_FRAC_MASK;
890 	val |= SCG1_SPLL_PFD0_FRAC_NUM;
891 	writel(val, &scg1_regs->spllpfd);
892 
893 	/* Un-gate A7 SPLL PFD0 */
894 	val = readl(&scg1_regs->spllpfd);
895 	val &= ~SCG_PLL_PFD0_GATE_MASK;
896 	writel(val, &scg1_regs->spllpfd);
897 
898 	/* Wait for A7 SPLL PFD0 clock being valid */
899 	while (!(readl(&scg1_regs->spllpfd) & SCG_PLL_PFD0_VALID_MASK))
900 		;
901 
902 	/* ================ A7 SPLL Configuration End ============== */
903 }
904 
905 /* DDR clock source is APLL PFD0 (396MHz) */
906 #define SCG1_DDRCCR_DDRCS_NUM		((0x0) << SCG_DDRCCR_DDRCS_SHIFT)
907 /* DDR clock = APLL PFD0 / 1 = 396MHz / 1 = 396MHz */
908 #define SCG1_DDRCCR_DDRDIV_NUM		((0x1) << SCG_DDRCCR_DDRDIV_SHIFT)
909 /* DDR clock = APLL PFD0 / 2 = 396MHz / 2 = 198MHz */
910 #define SCG1_DDRCCR_DDRDIV_LF_NUM	((0x2) << SCG_DDRCCR_DDRDIV_SHIFT)
911 #define SCG1_DDRCCR_CFG_NUM		(SCG1_DDRCCR_DDRCS_NUM  | \
912 					 SCG1_DDRCCR_DDRDIV_NUM)
913 #define SCG1_DDRCCR_CFG_LF_NUM		(SCG1_DDRCCR_DDRCS_NUM  | \
914 					 SCG1_DDRCCR_DDRDIV_LF_NUM)
915 void scg_a7_ddrclk_init(void)
916 {
917 	writel(SCG1_DDRCCR_CFG_NUM, &scg1_regs->ddrccr);
918 }
919 
920 /* SCG1(A7) APLLCFG configurations */
921 /* divide by 1 <<28 */
922 #define SCG1_APLL_CFG_POSTDIV2_NUM      ((0x0) << SCG_PLL_CFG_POSTDIV2_SHIFT)
923 /* divide by 1 <<24 */
924 #define SCG1_APLL_CFG_POSTDIV1_NUM      ((0x0) << SCG_PLL_CFG_POSTDIV1_SHIFT)
925 /* MULT is 22  <<16 */
926 #define SCG1_APLL_CFG_MULT_NUM          ((22)  << SCG_PLL_CFG_MULT_SHIFT)
927 /* PFD0 output clock selected  <<14 */
928 #define SCG1_APLL_CFG_PFDSEL_NUM        ((0) << SCG_PLL_CFG_PFDSEL_SHIFT)
929 /* PREDIV = 1	<<8 */
930 #define SCG1_APLL_CFG_PREDIV_NUM        ((0x0) << SCG_PLL_CFG_PREDIV_SHIFT)
931 /* APLL output clocks (including PFD outputs) selected	<<2 */
932 #define SCG1_APLL_CFG_BYPASS_NUM        ((0x0) << SCG_PLL_CFG_BYPASS_SHIFT)
933 /* APLL PFD output clock selected <<1 */
934 #define SCG1_APLL_CFG_PLLSEL_NUM        ((0x0) << SCG_PLL_CFG_PLLSEL_SHIFT)
935 /* Clock source is System OSC <<0 */
936 #define SCG1_APLL_CFG_CLKSRC_NUM        ((0x0) << SCG_PLL_CFG_CLKSRC_SHIFT)
937 
938 /*
939  * A7 APLL = 24MHz / 1 * 22 / 1 / 1 = 528MHz,
940  * system PLL is sourced from APLL,
941  * APLL clock source is system OSC (24MHz)
942  */
943 #define SCG1_APLL_CFG_NUM_24M_OSC (SCG1_APLL_CFG_POSTDIV2_NUM     |   \
944 				   SCG1_APLL_CFG_POSTDIV1_NUM     |   \
945 				   (22 << SCG_PLL_CFG_MULT_SHIFT) |   \
946 				   SCG1_APLL_CFG_PFDSEL_NUM       |   \
947 				   SCG1_APLL_CFG_PREDIV_NUM       |   \
948 				   SCG1_APLL_CFG_BYPASS_NUM       |   \
949 				   SCG1_APLL_CFG_PLLSEL_NUM       |   \
950 				   SCG1_APLL_CFG_CLKSRC_NUM)
951 
952 /* PFD0 Freq = A7 APLL(528MHz) * 18 / 27 = 352MHz */
953 #define SCG1_APLL_PFD0_FRAC_NUM (27)
954 
955 
956 void scg_a7_apll_init(void)
957 {
958 	u32 val = 0;
959 
960 	/* Disable A7 Auxiliary PLL */
961 	val = readl(&scg1_regs->apllcsr);
962 	val &= ~SCG_APLL_CSR_APLLEN_MASK;
963 	writel(val, &scg1_regs->apllcsr);
964 
965 	/* Gate off A7 APLL PFD0 ~ PDF4  */
966 	val = readl(&scg1_regs->apllpfd);
967 	val |= 0x80808080;
968 	writel(val, &scg1_regs->apllpfd);
969 
970 	/* ================ A7 APLL Configuration Start ============== */
971 	/* Configure A7 Auxiliary PLL */
972 	writel(SCG1_APLL_CFG_NUM_24M_OSC, &scg1_regs->apllcfg);
973 
974 	/* Enable A7 Auxiliary PLL */
975 	val = readl(&scg1_regs->apllcsr);
976 	val |= SCG_APLL_CSR_APLLEN_MASK;
977 	writel(val, &scg1_regs->apllcsr);
978 
979 	/* Wait for A7 APLL clock ready */
980 	while (!(readl(&scg1_regs->apllcsr) & SCG_APLL_CSR_APLLVLD_MASK))
981 		;
982 
983 	/* Configure A7 APLL PFD0 */
984 	val = readl(&scg1_regs->apllpfd);
985 	val &= ~SCG_PLL_PFD0_FRAC_MASK;
986 	val |= SCG1_APLL_PFD0_FRAC_NUM;
987 	writel(val, &scg1_regs->apllpfd);
988 
989 	/* Un-gate A7 APLL PFD0 */
990 	val = readl(&scg1_regs->apllpfd);
991 	val &= ~SCG_PLL_PFD0_GATE_MASK;
992 	writel(val, &scg1_regs->apllpfd);
993 
994 	/* Wait for A7 APLL PFD0 clock being valid */
995 	while (!(readl(&scg1_regs->apllpfd) & SCG_PLL_PFD0_VALID_MASK))
996 		;
997 }
998 
999 /* SCG1(A7) FIRC DIV configurations */
1000 /* Disable FIRC DIV3 */
1001 #define SCG1_FIRCDIV_DIV3_NUM           ((0x0) << SCG_FIRCDIV_DIV3_SHIFT)
1002 /* FIRC DIV2 = 48MHz / 1 = 48MHz */
1003 #define SCG1_FIRCDIV_DIV2_NUM           ((0x1) << SCG_FIRCDIV_DIV2_SHIFT)
1004 /* Disable FIRC DIV1 */
1005 #define SCG1_FIRCDIV_DIV1_NUM           ((0x0) << SCG_FIRCDIV_DIV1_SHIFT)
1006 
1007 void scg_a7_firc_init(void)
1008 {
1009 	/* Wait for FIRC clock ready */
1010 	while (!(readl(&scg1_regs->firccsr) & SCG_FIRC_CSR_FIRCVLD_MASK))
1011 		;
1012 
1013 	/* Configure A7 FIRC DIV1 ~ DIV3 */
1014 	writel((SCG1_FIRCDIV_DIV3_NUM |
1015 			SCG1_FIRCDIV_DIV2_NUM |
1016 			SCG1_FIRCDIV_DIV1_NUM), &scg1_regs->fircdiv);
1017 }
1018 
1019 /* SCG1(A7) NICCCR configurations */
1020 /* NIC clock source is DDR clock (396/198MHz) */
1021 #define SCG1_NICCCR_NICCS_NUM		((0x1) << SCG_NICCCR_NICCS_SHIFT)
1022 
1023 /* NIC0 clock = DDR Clock / 2 = 396MHz / 2 = 198MHz */
1024 #define SCG1_NICCCR_NIC0_DIV_NUM	((0x1) << SCG_NICCCR_NIC0_DIV_SHIFT)
1025 /* NIC0 clock = DDR Clock / 1 = 198MHz / 1 = 198MHz */
1026 #define SCG1_NICCCR_NIC0_DIV_LF_NUM	((0x0) << SCG_NICCCR_NIC0_DIV_SHIFT)
1027 /* NIC1 clock = NIC0 Clock / 1 = 198MHz / 2 = 198MHz */
1028 #define SCG1_NICCCR_NIC1_DIV_NUM	((0x0) << SCG_NICCCR_NIC1_DIV_SHIFT)
1029 /* NIC1 bus clock = NIC1 Clock / 3 = 198MHz / 3 = 66MHz */
1030 #define SCG1_NICCCR_NIC1_DIVBUS_NUM	((0x2) << SCG_NICCCR_NIC1_DIVBUS_SHIFT)
1031 #define SCG1_NICCCR_CFG_NUM		(SCG1_NICCCR_NICCS_NUM      | \
1032 					 SCG1_NICCCR_NIC0_DIV_NUM   | \
1033 					 SCG1_NICCCR_NIC1_DIV_NUM   | \
1034 					 SCG1_NICCCR_NIC1_DIVBUS_NUM)
1035 
1036 void scg_a7_nicclk_init(void)
1037 {
1038 	writel(SCG1_NICCCR_CFG_NUM, &scg1_regs->nicccr);
1039 }
1040 
1041 /* SCG1(A7) FIRC DIV configurations */
1042 /* Enable FIRC DIV3 */
1043 #define SCG1_SOSCDIV_DIV3_NUM		((0x1) << SCG_SOSCDIV_DIV3_SHIFT)
1044 /* FIRC DIV2 = 48MHz / 1 = 48MHz */
1045 #define SCG1_SOSCDIV_DIV2_NUM		((0x1) << SCG_SOSCDIV_DIV2_SHIFT)
1046 /* Enable FIRC DIV1 */
1047 #define SCG1_SOSCDIV_DIV1_NUM		((0x1) << SCG_SOSCDIV_DIV1_SHIFT)
1048 
1049 void scg_a7_soscdiv_init(void)
1050 {
1051 	/* Wait for FIRC clock ready */
1052 	while (!(readl(&scg1_regs->sosccsr) & SCG_SOSC_CSR_SOSCVLD_MASK))
1053 		;
1054 
1055 	/* Configure A7 FIRC DIV1 ~ DIV3 */
1056 	writel((SCG1_SOSCDIV_DIV3_NUM | SCG1_SOSCDIV_DIV2_NUM |
1057 	       SCG1_SOSCDIV_DIV1_NUM), &scg1_regs->soscdiv);
1058 }
1059 
1060 void scg_a7_sys_clk_sel(enum scg_sys_src clk)
1061 {
1062 	u32 rccr_reg_val = 0;
1063 
1064 	clk_debug("%s: system clock selected as %s\n", "[SCG]",
1065 		  clk == SCG_SCS_SYS_OSC ? "SYS_OSC" :
1066 		  clk == SCG_SCS_SLOW_IRC  ? "SLOW_IRC" :
1067 		  clk == SCG_SCS_FAST_IRC  ? "FAST_IRC" :
1068 		  clk == SCG_SCS_RTC_OSC   ? "RTC_OSC" :
1069 		  clk == SCG_SCS_AUX_PLL   ? "AUX_PLL" :
1070 		  clk == SCG_SCS_SYS_PLL   ? "SYS_PLL" :
1071 		  clk == SCG_SCS_USBPHY_PLL ? "USBPHY_PLL" :
1072 		  "Invalid source"
1073 	);
1074 
1075 	rccr_reg_val = readl(&scg1_regs->rccr);
1076 	rccr_reg_val &= ~SCG_CCR_SCS_MASK;
1077 	rccr_reg_val |= (clk << SCG_CCR_SCS_SHIFT);
1078 	writel(rccr_reg_val, &scg1_regs->rccr);
1079 }
1080 
1081 void scg_a7_info(void)
1082 {
1083 	debug("SCG Version: 0x%x\n", readl(&scg1_regs->verid));
1084 	debug("SCG Parameter: 0x%x\n", readl(&scg1_regs->param));
1085 	debug("SCG RCCR Value: 0x%x\n", readl(&scg1_regs->rccr));
1086 	debug("SCG Clock Status: 0x%x\n", readl(&scg1_regs->csr));
1087 }
1088