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