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