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