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