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