1
2
3
4
5
6
7
8
9
10
11#include <common.h>
12#include <errno.h>
13#include <asm/io.h>
14#include <asm/arch/clock.h>
15#include <asm/arch/tegra.h>
16#include <asm/arch-tegra/clk_rst.h>
17#include <asm/arch-tegra/timer.h>
18#include <div64.h>
19#include <fdtdec.h>
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35enum clock_type_id {
36 CLOCK_TYPE_AXPT,
37 CLOCK_TYPE_MCPA,
38 CLOCK_TYPE_MCPT,
39 CLOCK_TYPE_PCM,
40 CLOCK_TYPE_PCMT,
41 CLOCK_TYPE_PCMT16,
42 CLOCK_TYPE_PCXTS,
43 CLOCK_TYPE_PDCT,
44
45 CLOCK_TYPE_COUNT,
46 CLOCK_TYPE_NONE = -1,
47};
48
49enum {
50 CLOCK_MAX_MUX = 4
51};
52
53
54
55
56
57
58
59
60#define CLK(x) CLOCK_ID_ ## x
61static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX] = {
62 { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC) },
63 { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO) },
64 { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC) },
65 { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE) },
66 { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC) },
67 { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC) },
68 { CLK(PERIPH), CLK(CGENERAL), CLK(XCPU), CLK(OSC) },
69 { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC) },
70};
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85enum periphc_internal_id {
86
87 PERIPHC_I2S1,
88 PERIPHC_I2S2,
89 PERIPHC_SPDIF_OUT,
90 PERIPHC_SPDIF_IN,
91 PERIPHC_PWM,
92 PERIPHC_SPI1,
93 PERIPHC_SPI2,
94 PERIPHC_SPI3,
95
96
97 PERIPHC_XIO,
98 PERIPHC_I2C1,
99 PERIPHC_DVC_I2C,
100 PERIPHC_TWC,
101 PERIPHC_0c,
102 PERIPHC_10,
103 PERIPHC_DISP1,
104 PERIPHC_DISP2,
105
106
107 PERIPHC_CVE,
108 PERIPHC_IDE0,
109 PERIPHC_VI,
110 PERIPHC_1c,
111 PERIPHC_SDMMC1,
112 PERIPHC_SDMMC2,
113 PERIPHC_G3D,
114 PERIPHC_G2D,
115
116
117 PERIPHC_NDFLASH,
118 PERIPHC_SDMMC4,
119 PERIPHC_VFIR,
120 PERIPHC_EPP,
121 PERIPHC_MPE,
122 PERIPHC_MIPI,
123 PERIPHC_UART1,
124 PERIPHC_UART2,
125
126
127 PERIPHC_HOST1X,
128 PERIPHC_21,
129 PERIPHC_TVO,
130 PERIPHC_HDMI,
131 PERIPHC_24,
132 PERIPHC_TVDAC,
133 PERIPHC_I2C2,
134 PERIPHC_EMC,
135
136
137 PERIPHC_UART3,
138 PERIPHC_29,
139 PERIPHC_VI_SENSOR,
140 PERIPHC_2b,
141 PERIPHC_2c,
142 PERIPHC_SPI4,
143 PERIPHC_I2C3,
144 PERIPHC_SDMMC3,
145
146
147 PERIPHC_UART4,
148 PERIPHC_UART5,
149 PERIPHC_VDE,
150 PERIPHC_OWR,
151 PERIPHC_NOR,
152 PERIPHC_CSITE,
153
154 PERIPHC_COUNT,
155
156 PERIPHC_NONE = -1,
157};
158
159
160
161
162
163#define TYPE(name, type) type
164static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = {
165
166 TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT),
167 TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT),
168 TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT),
169 TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PCM),
170 TYPE(PERIPHC_PWM, CLOCK_TYPE_PCXTS),
171 TYPE(PERIPHC_SPI1, CLOCK_TYPE_PCMT),
172 TYPE(PERIPHC_SPI22, CLOCK_TYPE_PCMT),
173 TYPE(PERIPHC_SPI3, CLOCK_TYPE_PCMT),
174
175
176 TYPE(PERIPHC_XIO, CLOCK_TYPE_PCMT),
177 TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT16),
178 TYPE(PERIPHC_DVC_I2C, CLOCK_TYPE_PCMT16),
179 TYPE(PERIPHC_TWC, CLOCK_TYPE_PCMT),
180 TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
181 TYPE(PERIPHC_SPI1, CLOCK_TYPE_PCMT),
182 TYPE(PERIPHC_DISP1, CLOCK_TYPE_PDCT),
183 TYPE(PERIPHC_DISP2, CLOCK_TYPE_PDCT),
184
185
186 TYPE(PERIPHC_CVE, CLOCK_TYPE_PDCT),
187 TYPE(PERIPHC_IDE0, CLOCK_TYPE_PCMT),
188 TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA),
189 TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
190 TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PCMT),
191 TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PCMT),
192 TYPE(PERIPHC_G3D, CLOCK_TYPE_MCPA),
193 TYPE(PERIPHC_G2D, CLOCK_TYPE_MCPA),
194
195
196 TYPE(PERIPHC_NDFLASH, CLOCK_TYPE_PCMT),
197 TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PCMT),
198 TYPE(PERIPHC_VFIR, CLOCK_TYPE_PCMT),
199 TYPE(PERIPHC_EPP, CLOCK_TYPE_MCPA),
200 TYPE(PERIPHC_MPE, CLOCK_TYPE_MCPA),
201 TYPE(PERIPHC_MIPI, CLOCK_TYPE_PCMT),
202 TYPE(PERIPHC_UART1, CLOCK_TYPE_PCMT),
203 TYPE(PERIPHC_UART2, CLOCK_TYPE_PCMT),
204
205
206 TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MCPA),
207 TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
208 TYPE(PERIPHC_TVO, CLOCK_TYPE_PDCT),
209 TYPE(PERIPHC_HDMI, CLOCK_TYPE_PDCT),
210 TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
211 TYPE(PERIPHC_TVDAC, CLOCK_TYPE_PDCT),
212 TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT16),
213 TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT),
214
215
216 TYPE(PERIPHC_UART3, CLOCK_TYPE_PCMT),
217 TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
218 TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA),
219 TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
220 TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE),
221 TYPE(PERIPHC_SPI4, CLOCK_TYPE_PCMT),
222 TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT16),
223 TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT),
224
225
226 TYPE(PERIPHC_UART4, CLOCK_TYPE_PCMT),
227 TYPE(PERIPHC_UART5, CLOCK_TYPE_PCMT),
228 TYPE(PERIPHC_VDE, CLOCK_TYPE_PCMT),
229 TYPE(PERIPHC_OWR, CLOCK_TYPE_PCMT),
230 TYPE(PERIPHC_NOR, CLOCK_TYPE_PCMT),
231 TYPE(PERIPHC_CSITE, CLOCK_TYPE_PCMT),
232};
233
234
235
236
237
238
239
240
241
242#define NONE(name) (-1)
243#define OFFSET(name, value) PERIPHC_ ## name
244static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = {
245
246 NONE(CPU),
247 NONE(RESERVED1),
248 NONE(RESERVED2),
249 NONE(AC97),
250 NONE(RTC),
251 NONE(TMR),
252 PERIPHC_UART1,
253 PERIPHC_UART2,
254
255
256 NONE(GPIO),
257 PERIPHC_SDMMC2,
258 NONE(SPDIF),
259 PERIPHC_I2S1,
260 PERIPHC_I2C1,
261 PERIPHC_NDFLASH,
262 PERIPHC_SDMMC1,
263 PERIPHC_SDMMC4,
264
265
266 PERIPHC_TWC,
267 PERIPHC_PWM,
268 PERIPHC_I2S2,
269 PERIPHC_EPP,
270 PERIPHC_VI,
271 PERIPHC_G2D,
272 NONE(USBD),
273 NONE(ISP),
274
275
276 PERIPHC_G3D,
277 PERIPHC_IDE0,
278 PERIPHC_DISP2,
279 PERIPHC_DISP1,
280 PERIPHC_HOST1X,
281 NONE(VCP),
282 NONE(RESERVED30),
283 NONE(CACHE2),
284
285
286 NONE(MEM),
287 NONE(AHBDMA),
288 NONE(APBDMA),
289 NONE(RESERVED35),
290 NONE(KBC),
291 NONE(STAT_MON),
292 NONE(PMC),
293 NONE(FUSE),
294
295
296 NONE(KFUSE),
297 NONE(SBC1),
298 PERIPHC_NOR,
299 PERIPHC_SPI1,
300 PERIPHC_SPI2,
301 PERIPHC_XIO,
302 PERIPHC_SPI3,
303 PERIPHC_DVC_I2C,
304
305
306 NONE(DSI),
307 PERIPHC_TVO,
308 PERIPHC_MIPI,
309 PERIPHC_HDMI,
310 PERIPHC_CSITE,
311 PERIPHC_TVDAC,
312 PERIPHC_I2C2,
313 PERIPHC_UART3,
314
315
316 NONE(RESERVED56),
317 PERIPHC_EMC,
318 NONE(USB2),
319 NONE(USB3),
320 PERIPHC_MPE,
321 PERIPHC_VDE,
322 NONE(BSEA),
323 NONE(BSEV),
324
325
326 NONE(SPEEDO),
327 PERIPHC_UART4,
328 PERIPHC_UART5,
329 PERIPHC_I2C3,
330 PERIPHC_SPI4,
331 PERIPHC_SDMMC3,
332 NONE(PCIE),
333 PERIPHC_OWR,
334
335
336 NONE(AFI),
337 NONE(CORESIGHT),
338 NONE(PCIEXCLK),
339 NONE(AVPUCQ),
340 NONE(RESERVED76),
341 NONE(RESERVED77),
342 NONE(RESERVED78),
343 NONE(RESERVED79),
344
345
346 NONE(RESERVED80),
347 NONE(RESERVED81),
348 NONE(RESERVED82),
349 NONE(RESERVED83),
350 NONE(IRAMA),
351 NONE(IRAMB),
352 NONE(IRAMC),
353 NONE(IRAMD),
354
355
356 NONE(CRAM2),
357};
358
359
360
361
362struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = {
363
364
365
366
367
368
369 { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x0F,
370 .lock_ena = 24, .lock_det = 27, .kcp_shift = 28, .kcp_mask = 3, .kvco_shift = 27, .kvco_mask = 1 },
371 { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 0, .p_mask = 0,
372 .lock_ena = 0, .lock_det = 27, .kcp_shift = 1, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },
373 { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07,
374 .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },
375 { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07,
376 .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },
377 { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x01,
378 .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },
379 { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07,
380 .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },
381 { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x0F,
382 .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 0, .kvco_mask = 0 },
383 { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF, .p_shift = 0, .p_mask = 0,
384 .lock_ena = 9, .lock_det = 11, .kcp_shift = 6, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 },
385 { .m_shift = 0, .m_mask = 0x0F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07,
386 .lock_ena = 18, .lock_det = 0, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF },
387};
388
389
390
391
392
393enum clock_osc_freq clock_get_osc_freq(void)
394{
395 struct clk_rst_ctlr *clkrst =
396 (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
397 u32 reg;
398
399 reg = readl(&clkrst->crc_osc_ctrl);
400 return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
401}
402
403
404u32 *get_periph_source_reg(enum periph_id periph_id)
405{
406 struct clk_rst_ctlr *clkrst =
407 (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
408 enum periphc_internal_id internal_id;
409
410 assert(clock_periph_id_isvalid(periph_id));
411 internal_id = periph_id_to_internal_id[periph_id];
412 assert(internal_id != -1);
413 return &clkrst->crc_clk_src[internal_id];
414}
415
416int get_periph_clock_info(enum periph_id periph_id, int *mux_bits,
417 int *divider_bits, int *type)
418{
419 enum periphc_internal_id internal_id;
420
421 if (!clock_periph_id_isvalid(periph_id))
422 return -1;
423
424 internal_id = periph_id_to_internal_id[periph_id];
425 if (!periphc_internal_id_isvalid(internal_id))
426 return -1;
427
428 *type = clock_periph_type[internal_id];
429 if (!clock_type_id_isvalid(*type))
430 return -1;
431
432
433
434
435
436 if (*type == CLOCK_TYPE_PCXTS)
437 *mux_bits = MASK_BITS_31_28;
438 else
439 *mux_bits = MASK_BITS_31_30;
440 if (*type == CLOCK_TYPE_PCMT16)
441 *divider_bits = 16;
442 else
443 *divider_bits = 8;
444
445 return 0;
446}
447
448enum clock_id get_periph_clock_id(enum periph_id periph_id, int source)
449{
450 enum periphc_internal_id internal_id;
451 int type;
452
453 if (!clock_periph_id_isvalid(periph_id))
454 return CLOCK_ID_NONE;
455
456 internal_id = periph_id_to_internal_id[periph_id];
457 if (!periphc_internal_id_isvalid(internal_id))
458 return CLOCK_ID_NONE;
459
460 type = clock_periph_type[internal_id];
461 if (!clock_type_id_isvalid(type))
462 return CLOCK_ID_NONE;
463
464 return clock_source[type][source];
465}
466
467
468
469
470
471
472
473
474
475
476
477
478
479int get_periph_clock_source(enum periph_id periph_id,
480 enum clock_id parent, int *mux_bits, int *divider_bits)
481{
482 enum clock_type_id type;
483 int mux, err;
484
485 err = get_periph_clock_info(periph_id, mux_bits, divider_bits, &type);
486 assert(!err);
487
488 for (mux = 0; mux < CLOCK_MAX_MUX; mux++)
489 if (clock_source[type][mux] == parent)
490 return mux;
491
492
493
494
495
496
497 assert(type == CLOCK_TYPE_PCXTS);
498 assert(parent == CLOCK_ID_SFROM32KHZ);
499 if (type == CLOCK_TYPE_PCXTS && parent == CLOCK_ID_SFROM32KHZ)
500 return 4;
501
502
503 printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id,
504 parent);
505 return -1;
506}
507
508void clock_set_enable(enum periph_id periph_id, int enable)
509{
510 struct clk_rst_ctlr *clkrst =
511 (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
512 u32 *clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)];
513 u32 reg;
514
515
516 assert(clock_periph_id_isvalid(periph_id));
517 reg = readl(clk);
518 if (enable)
519 reg |= PERIPH_MASK(periph_id);
520 else
521 reg &= ~PERIPH_MASK(periph_id);
522 writel(reg, clk);
523}
524
525void reset_set_enable(enum periph_id periph_id, int enable)
526{
527 struct clk_rst_ctlr *clkrst =
528 (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
529 u32 *reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)];
530 u32 reg;
531
532
533 assert(clock_periph_id_isvalid(periph_id));
534 reg = readl(reset);
535 if (enable)
536 reg |= PERIPH_MASK(periph_id);
537 else
538 reg &= ~PERIPH_MASK(periph_id);
539 writel(reg, reset);
540}
541
542#if CONFIG_IS_ENABLED(OF_CONTROL)
543
544
545
546
547
548
549
550
551enum periph_id clk_id_to_periph_id(int clk_id)
552{
553 if (clk_id > PERIPH_ID_COUNT)
554 return PERIPH_ID_NONE;
555
556 switch (clk_id) {
557 case PERIPH_ID_RESERVED1:
558 case PERIPH_ID_RESERVED2:
559 case PERIPH_ID_RESERVED30:
560 case PERIPH_ID_RESERVED35:
561 case PERIPH_ID_RESERVED56:
562 case PERIPH_ID_PCIEXCLK:
563 case PERIPH_ID_RESERVED76:
564 case PERIPH_ID_RESERVED77:
565 case PERIPH_ID_RESERVED78:
566 case PERIPH_ID_RESERVED79:
567 case PERIPH_ID_RESERVED80:
568 case PERIPH_ID_RESERVED81:
569 case PERIPH_ID_RESERVED82:
570 case PERIPH_ID_RESERVED83:
571 case PERIPH_ID_RESERVED91:
572 return PERIPH_ID_NONE;
573 default:
574 return clk_id;
575 }
576}
577#endif
578
579void clock_early_init(void)
580{
581
582
583
584
585
586
587 switch (clock_get_osc_freq()) {
588 case CLOCK_OSC_FREQ_12_0:
589 clock_set_rate(CLOCK_ID_PERIPH, 432, 12, 1, 8);
590 clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8);
591 break;
592
593 case CLOCK_OSC_FREQ_26_0:
594 clock_set_rate(CLOCK_ID_PERIPH, 432, 26, 1, 8);
595 clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8);
596 break;
597
598 case CLOCK_OSC_FREQ_13_0:
599 clock_set_rate(CLOCK_ID_PERIPH, 432, 13, 1, 8);
600 clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8);
601 break;
602 case CLOCK_OSC_FREQ_19_2:
603 default:
604
605
606
607
608
609 break;
610 }
611}
612
613void arch_timer_init(void)
614{
615}
616
617#define PMC_SATA_PWRGT 0x1ac
618#define PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE (1 << 5)
619#define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL (1 << 4)
620
621#define PLLE_SS_CNTL 0x68
622#define PLLE_SS_CNTL_SSCINCINTRV(x) (((x) & 0x3f) << 24)
623#define PLLE_SS_CNTL_SSCINC(x) (((x) & 0xff) << 16)
624#define PLLE_SS_CNTL_SSCBYP (1 << 12)
625#define PLLE_SS_CNTL_INTERP_RESET (1 << 11)
626#define PLLE_SS_CNTL_BYPASS_SS (1 << 10)
627#define PLLE_SS_CNTL_SSCMAX(x) (((x) & 0x1ff) << 0)
628
629#define PLLE_BASE 0x0e8
630#define PLLE_BASE_ENABLE_CML (1 << 31)
631#define PLLE_BASE_ENABLE (1 << 30)
632#define PLLE_BASE_PLDIV_CML(x) (((x) & 0xf) << 24)
633#define PLLE_BASE_PLDIV(x) (((x) & 0x3f) << 16)
634#define PLLE_BASE_NDIV(x) (((x) & 0xff) << 8)
635#define PLLE_BASE_MDIV(x) (((x) & 0xff) << 0)
636
637#define PLLE_MISC 0x0ec
638#define PLLE_MISC_SETUP_BASE(x) (((x) & 0xffff) << 16)
639#define PLLE_MISC_PLL_READY (1 << 15)
640#define PLLE_MISC_LOCK (1 << 11)
641#define PLLE_MISC_LOCK_ENABLE (1 << 9)
642#define PLLE_MISC_SETUP_EXT(x) (((x) & 0x3) << 2)
643
644static int tegra_plle_train(void)
645{
646 unsigned int timeout = 2000;
647 unsigned long value;
648
649 value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT);
650 value |= PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE;
651 writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT);
652
653 value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT);
654 value |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL;
655 writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT);
656
657 value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT);
658 value &= ~PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE;
659 writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT);
660
661 do {
662 value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC);
663 if (value & PLLE_MISC_PLL_READY)
664 break;
665
666 udelay(100);
667 } while (--timeout);
668
669 if (timeout == 0) {
670 error("timeout waiting for PLLE to become ready");
671 return -ETIMEDOUT;
672 }
673
674 return 0;
675}
676
677int tegra_plle_enable(void)
678{
679 unsigned int timeout = 1000;
680 u32 value;
681 int err;
682
683
684 value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE);
685 value &= ~PLLE_BASE_ENABLE_CML;
686 value &= ~PLLE_BASE_ENABLE;
687 writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE);
688
689
690 value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC);
691 value &= ~PLLE_MISC_LOCK_ENABLE;
692 value &= ~PLLE_MISC_SETUP_BASE(0xffff);
693 value &= ~PLLE_MISC_SETUP_EXT(0x3);
694 writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC);
695
696 value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC);
697 if ((value & PLLE_MISC_PLL_READY) == 0) {
698 err = tegra_plle_train();
699 if (err < 0) {
700 error("failed to train PLLE: %d", err);
701 return err;
702 }
703 }
704
705 value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC);
706 value |= PLLE_MISC_SETUP_BASE(0x7);
707 value |= PLLE_MISC_LOCK_ENABLE;
708 value |= PLLE_MISC_SETUP_EXT(0);
709 writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC);
710
711 value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
712 value |= PLLE_SS_CNTL_SSCBYP | PLLE_SS_CNTL_INTERP_RESET |
713 PLLE_SS_CNTL_BYPASS_SS;
714 writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
715
716 value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE);
717 value |= PLLE_BASE_ENABLE_CML | PLLE_BASE_ENABLE;
718 writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE);
719
720 do {
721 value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC);
722 if (value & PLLE_MISC_LOCK)
723 break;
724
725 udelay(2);
726 } while (--timeout);
727
728 if (timeout == 0) {
729 error("timeout waiting for PLLE to lock");
730 return -ETIMEDOUT;
731 }
732
733 udelay(50);
734
735 value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
736 value &= ~PLLE_SS_CNTL_SSCINCINTRV(0x3f);
737 value |= PLLE_SS_CNTL_SSCINCINTRV(0x18);
738
739 value &= ~PLLE_SS_CNTL_SSCINC(0xff);
740 value |= PLLE_SS_CNTL_SSCINC(0x01);
741
742 value &= ~PLLE_SS_CNTL_SSCBYP;
743 value &= ~PLLE_SS_CNTL_INTERP_RESET;
744 value &= ~PLLE_SS_CNTL_BYPASS_SS;
745
746 value &= ~PLLE_SS_CNTL_SSCMAX(0x1ff);
747 value |= PLLE_SS_CNTL_SSCMAX(0x24);
748 writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL);
749
750 return 0;
751}
752
753struct periph_clk_init periph_clk_init_table[] = {
754 { PERIPH_ID_SPI1, CLOCK_ID_PERIPH },
755 { PERIPH_ID_SBC1, CLOCK_ID_PERIPH },
756 { PERIPH_ID_SBC2, CLOCK_ID_PERIPH },
757 { PERIPH_ID_SBC3, CLOCK_ID_PERIPH },
758 { PERIPH_ID_SBC4, CLOCK_ID_PERIPH },
759 { PERIPH_ID_HOST1X, CLOCK_ID_PERIPH },
760 { PERIPH_ID_DISP1, CLOCK_ID_CGENERAL },
761 { PERIPH_ID_NDFLASH, CLOCK_ID_PERIPH },
762 { PERIPH_ID_SDMMC1, CLOCK_ID_PERIPH },
763 { PERIPH_ID_SDMMC2, CLOCK_ID_PERIPH },
764 { PERIPH_ID_SDMMC3, CLOCK_ID_PERIPH },
765 { PERIPH_ID_SDMMC4, CLOCK_ID_PERIPH },
766 { PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ },
767 { PERIPH_ID_DVC_I2C, CLOCK_ID_PERIPH },
768 { PERIPH_ID_I2C1, CLOCK_ID_PERIPH },
769 { PERIPH_ID_I2C2, CLOCK_ID_PERIPH },
770 { PERIPH_ID_I2C3, CLOCK_ID_PERIPH },
771 { -1, },
772};
773