1
2
3
4
5
6
7
8
9
10#include <common.h>
11#include <config.h>
12#include <asm/io.h>
13#include <asm/arch/imx-regs.h>
14
15#include "mxs_init.h"
16
17#ifdef CONFIG_SYS_MXS_VDD5V_ONLY
18#define DCDC4P2_DROPOUT_CONFIG POWER_DCDC4P2_DROPOUT_CTRL_100MV | \
19 POWER_DCDC4P2_DROPOUT_CTRL_SRC_4P2
20#else
21#define DCDC4P2_DROPOUT_CONFIG POWER_DCDC4P2_DROPOUT_CTRL_100MV | \
22 POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL
23#endif
24
25
26
27
28
29
30
31static void mxs_power_clock2xtal(void)
32{
33 struct mxs_clkctrl_regs *clkctrl_regs =
34 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
35
36 debug("SPL: Switching CPU clock to 24MHz XTAL\n");
37
38
39 writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
40 &clkctrl_regs->hw_clkctrl_clkseq_set);
41}
42
43
44
45
46
47
48
49
50static void mxs_power_clock2pll(void)
51{
52 struct mxs_clkctrl_regs *clkctrl_regs =
53 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
54
55 debug("SPL: Switching CPU core clock source to PLL\n");
56
57
58
59
60
61
62
63
64 setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0,
65 CLKCTRL_PLL0CTRL0_POWER);
66 early_delay(100);
67
68
69
70
71
72 setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq,
73 CLKCTRL_CLKSEQ_BYPASS_CPU);
74}
75
76
77
78
79
80
81
82
83static void mxs_power_set_auto_restart(void)
84{
85 struct mxs_rtc_regs *rtc_regs =
86 (struct mxs_rtc_regs *)MXS_RTC_BASE;
87
88 debug("SPL: Setting auto-restart bit\n");
89
90 writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr);
91 while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST)
92 ;
93
94 writel(RTC_CTRL_CLKGATE, &rtc_regs->hw_rtc_ctrl_clr);
95 while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE)
96 ;
97
98
99 if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART)
100 return;
101
102 while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
103 ;
104
105 setbits_le32(&rtc_regs->hw_rtc_persistent0,
106 RTC_PERSISTENT0_AUTO_RESTART);
107 writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_set);
108 writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_clr);
109 while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
110 ;
111 while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK)
112 ;
113}
114
115
116
117
118
119
120
121
122
123static void mxs_power_set_linreg(void)
124{
125 struct mxs_power_regs *power_regs =
126 (struct mxs_power_regs *)MXS_POWER_BASE;
127
128
129 debug("SPL: Setting VDDD 25mV below DC-DC converters\n");
130 clrsetbits_le32(&power_regs->hw_power_vdddctrl,
131 POWER_VDDDCTRL_LINREG_OFFSET_MASK,
132 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
133
134 debug("SPL: Setting VDDA 25mV below DC-DC converters\n");
135 clrsetbits_le32(&power_regs->hw_power_vddactrl,
136 POWER_VDDACTRL_LINREG_OFFSET_MASK,
137 POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW);
138
139 debug("SPL: Setting VDDIO 25mV below DC-DC converters\n");
140 clrsetbits_le32(&power_regs->hw_power_vddioctrl,
141 POWER_VDDIOCTRL_LINREG_OFFSET_MASK,
142 POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
143}
144
145
146
147
148
149
150static int mxs_get_batt_volt(void)
151{
152 struct mxs_power_regs *power_regs =
153 (struct mxs_power_regs *)MXS_POWER_BASE;
154 uint32_t volt = readl(&power_regs->hw_power_battmonitor);
155 volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
156 volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
157 volt *= 8;
158
159 debug("SPL: Battery Voltage = %dmV\n", volt);
160 return volt;
161}
162
163
164
165
166
167
168
169static int mxs_is_batt_ready(void)
170{
171 return (mxs_get_batt_volt() >= 3600);
172}
173
174
175
176
177
178
179
180
181static int mxs_is_batt_good(void)
182{
183 struct mxs_power_regs *power_regs =
184 (struct mxs_power_regs *)MXS_POWER_BASE;
185 uint32_t volt = mxs_get_batt_volt();
186
187 if ((volt >= 2400) && (volt <= 4300)) {
188 debug("SPL: Battery is good\n");
189 return 1;
190 }
191
192 clrsetbits_le32(&power_regs->hw_power_5vctrl,
193 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
194 0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
195 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
196 &power_regs->hw_power_5vctrl_clr);
197
198 clrsetbits_le32(&power_regs->hw_power_charge,
199 POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
200 POWER_CHARGE_STOP_ILIMIT_10MA | 0x3);
201
202 writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_clr);
203 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
204 &power_regs->hw_power_5vctrl_clr);
205
206 early_delay(500000);
207
208 volt = mxs_get_batt_volt();
209
210 if (volt >= 3500) {
211 debug("SPL: Battery Voltage too high\n");
212 return 0;
213 }
214
215 if (volt >= 2400) {
216 debug("SPL: Battery is good\n");
217 return 1;
218 }
219
220 writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
221 &power_regs->hw_power_charge_clr);
222 writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
223
224 debug("SPL: Battery Voltage too low\n");
225 return 0;
226}
227
228
229
230
231
232
233
234
235
236
237static void mxs_power_setup_5v_detect(void)
238{
239 struct mxs_power_regs *power_regs =
240 (struct mxs_power_regs *)MXS_POWER_BASE;
241
242
243 debug("SPL: Starting 5V input detection comparator\n");
244 clrsetbits_le32(&power_regs->hw_power_5vctrl,
245 POWER_5VCTRL_VBUSVALID_TRSH_MASK,
246 POWER_5VCTRL_VBUSVALID_TRSH_4V4 |
247 POWER_5VCTRL_PWRUP_VBUS_CMPS);
248}
249
250
251
252
253
254
255
256static void mxs_src_power_init(void)
257{
258 struct mxs_power_regs *power_regs =
259 (struct mxs_power_regs *)MXS_POWER_BASE;
260
261 debug("SPL: Pre-Configuring power block\n");
262
263
264 writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST |
265 POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set);
266
267 clrsetbits_le32(&power_regs->hw_power_dclimits,
268 POWER_DCLIMITS_POSLIMIT_BUCK_MASK,
269 0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET);
270
271 setbits_le32(&power_regs->hw_power_battmonitor,
272 POWER_BATTMONITOR_EN_BATADJ);
273
274
275 clrsetbits_le32(&power_regs->hw_power_loopctrl,
276 POWER_LOOPCTRL_EN_RCSCALE_MASK,
277 POWER_LOOPCTRL_RCSCALE_THRESH |
278 POWER_LOOPCTRL_EN_RCSCALE_8X);
279
280 clrsetbits_le32(&power_regs->hw_power_minpwr,
281 POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
282
283
284 setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
285 early_delay(30);
286 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
287}
288
289
290
291
292
293
294
295static void mxs_power_init_4p2_params(void)
296{
297 struct mxs_power_regs *power_regs =
298 (struct mxs_power_regs *)MXS_POWER_BASE;
299
300 debug("SPL: Configuring common 4P2 regulator params\n");
301
302
303 clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
304 POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK,
305 POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET));
306
307 clrsetbits_le32(&power_regs->hw_power_5vctrl,
308 POWER_5VCTRL_HEADROOM_ADJ_MASK,
309 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET);
310
311 clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
312 POWER_DCDC4P2_DROPOUT_CTRL_MASK,
313 DCDC4P2_DROPOUT_CONFIG);
314
315 clrsetbits_le32(&power_regs->hw_power_5vctrl,
316 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
317 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
318}
319
320
321
322
323
324
325
326static void mxs_enable_4p2_dcdc_input(int xfer)
327{
328 struct mxs_power_regs *power_regs =
329 (struct mxs_power_regs *)MXS_POWER_BASE;
330 uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo;
331 uint32_t prev_5v_brnout, prev_5v_droop;
332
333 debug("SPL: %s 4P2 DC-DC Input\n", xfer ? "Enabling" : "Disabling");
334
335 prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) &
336 POWER_5VCTRL_PWDN_5VBRNOUT;
337 prev_5v_droop = readl(&power_regs->hw_power_ctrl) &
338 POWER_CTRL_ENIRQ_VDD5V_DROOP;
339
340 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
341 writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
342 &power_regs->hw_power_reset);
343
344 clrbits_le32(&power_regs->hw_power_ctrl, POWER_CTRL_ENIRQ_VDD5V_DROOP);
345
346 if (xfer && (readl(&power_regs->hw_power_5vctrl) &
347 POWER_5VCTRL_ENABLE_DCDC)) {
348 return;
349 }
350
351
352
353
354
355 tmp = readl(&power_regs->hw_power_5vctrl);
356 vbus_thresh = tmp & POWER_5VCTRL_VBUSVALID_TRSH_MASK;
357 vbus_5vdetect = tmp & POWER_5VCTRL_VBUSVALID_5VDETECT;
358
359 pwd_bo = readl(&power_regs->hw_power_minpwr) & POWER_MINPWR_PWD_BO;
360
361
362
363
364
365 clrbits_le32(&power_regs->hw_power_5vctrl,
366 POWER_5VCTRL_VBUSVALID_5VDETECT |
367 POWER_5VCTRL_VBUSVALID_TRSH_MASK);
368
369 writel(POWER_MINPWR_PWD_BO, &power_regs->hw_power_minpwr_set);
370
371 if (xfer) {
372 setbits_le32(&power_regs->hw_power_5vctrl,
373 POWER_5VCTRL_DCDC_XFER);
374 early_delay(20);
375 clrbits_le32(&power_regs->hw_power_5vctrl,
376 POWER_5VCTRL_DCDC_XFER);
377
378 setbits_le32(&power_regs->hw_power_5vctrl,
379 POWER_5VCTRL_ENABLE_DCDC);
380 } else {
381 setbits_le32(&power_regs->hw_power_dcdc4p2,
382 POWER_DCDC4P2_ENABLE_DCDC);
383 }
384
385 early_delay(25);
386
387 clrsetbits_le32(&power_regs->hw_power_5vctrl,
388 POWER_5VCTRL_VBUSVALID_TRSH_MASK, vbus_thresh);
389
390 if (vbus_5vdetect)
391 writel(vbus_5vdetect, &power_regs->hw_power_5vctrl_set);
392
393 if (!pwd_bo)
394 clrbits_le32(&power_regs->hw_power_minpwr, POWER_MINPWR_PWD_BO);
395
396 while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ)
397 writel(POWER_CTRL_VBUS_VALID_IRQ,
398 &power_regs->hw_power_ctrl_clr);
399
400 if (prev_5v_brnout) {
401 writel(POWER_5VCTRL_PWDN_5VBRNOUT,
402 &power_regs->hw_power_5vctrl_set);
403 writel(POWER_RESET_UNLOCK_KEY,
404 &power_regs->hw_power_reset);
405 } else {
406 writel(POWER_5VCTRL_PWDN_5VBRNOUT,
407 &power_regs->hw_power_5vctrl_clr);
408 writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
409 &power_regs->hw_power_reset);
410 }
411
412 while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VDD5V_DROOP_IRQ)
413 writel(POWER_CTRL_VDD5V_DROOP_IRQ,
414 &power_regs->hw_power_ctrl_clr);
415
416 if (prev_5v_droop)
417 clrbits_le32(&power_regs->hw_power_ctrl,
418 POWER_CTRL_ENIRQ_VDD5V_DROOP);
419 else
420 setbits_le32(&power_regs->hw_power_ctrl,
421 POWER_CTRL_ENIRQ_VDD5V_DROOP);
422}
423
424
425
426
427
428
429
430static void mxs_power_init_4p2_regulator(void)
431{
432 struct mxs_power_regs *power_regs =
433 (struct mxs_power_regs *)MXS_POWER_BASE;
434 uint32_t tmp, tmp2;
435
436 debug("SPL: Enabling 4P2 regulator\n");
437
438 setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2);
439
440 writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set);
441
442 writel(POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
443 &power_regs->hw_power_5vctrl_clr);
444 clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_TRG_MASK);
445
446
447 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
448 &power_regs->hw_power_5vctrl_clr);
449
450
451
452
453
454
455 debug("SPL: Charging 4P2 capacitor\n");
456 mxs_enable_4p2_dcdc_input(0);
457
458 if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
459
460
461
462
463
464
465 clrbits_le32(&power_regs->hw_power_dcdc4p2,
466 POWER_DCDC4P2_ENABLE_DCDC);
467 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
468 &power_regs->hw_power_5vctrl_set);
469
470 debug("SPL: Unable to recover from mx23 errata 5837\n");
471 hang();
472 }
473
474
475
476
477
478
479
480
481
482
483
484 debug("SPL: Setting 4P2 brownout level\n");
485 clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
486 POWER_DCDC4P2_BO_MASK,
487 22 << POWER_DCDC4P2_BO_OFFSET);
488
489 if (!(readl(&power_regs->hw_power_sts) & POWER_STS_DCDC_4P2_BO)) {
490 setbits_le32(&power_regs->hw_power_5vctrl,
491 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
492 } else {
493 tmp = (readl(&power_regs->hw_power_5vctrl) &
494 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK) >>
495 POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
496 while (tmp < 0x3f) {
497 if (!(readl(&power_regs->hw_power_sts) &
498 POWER_STS_DCDC_4P2_BO)) {
499 tmp = readl(&power_regs->hw_power_5vctrl);
500 tmp |= POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
501 early_delay(100);
502 writel(tmp, &power_regs->hw_power_5vctrl);
503 break;
504 } else {
505 tmp++;
506 tmp2 = readl(&power_regs->hw_power_5vctrl);
507 tmp2 &= ~POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
508 tmp2 |= tmp <<
509 POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
510 writel(tmp2, &power_regs->hw_power_5vctrl);
511 early_delay(100);
512 }
513 }
514 }
515
516 clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK);
517 writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
518}
519
520
521
522
523
524
525
526static void mxs_power_init_dcdc_4p2_source(void)
527{
528 struct mxs_power_regs *power_regs =
529 (struct mxs_power_regs *)MXS_POWER_BASE;
530
531 debug("SPL: Switching DC-DC converters to 4P2\n");
532
533 if (!(readl(&power_regs->hw_power_dcdc4p2) &
534 POWER_DCDC4P2_ENABLE_DCDC)) {
535 debug("SPL: Already switched - aborting\n");
536 hang();
537 }
538
539 mxs_enable_4p2_dcdc_input(1);
540
541 if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
542 clrbits_le32(&power_regs->hw_power_dcdc4p2,
543 POWER_DCDC4P2_ENABLE_DCDC);
544 writel(POWER_5VCTRL_ENABLE_DCDC,
545 &power_regs->hw_power_5vctrl_clr);
546 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
547 &power_regs->hw_power_5vctrl_set);
548 }
549}
550
551
552
553
554
555
556
557static void mxs_power_enable_4p2(void)
558{
559 struct mxs_power_regs *power_regs =
560 (struct mxs_power_regs *)MXS_POWER_BASE;
561 uint32_t vdddctrl, vddactrl, vddioctrl;
562 uint32_t tmp;
563
564 debug("SPL: Powering up 4P2 regulator\n");
565
566 vdddctrl = readl(&power_regs->hw_power_vdddctrl);
567 vddactrl = readl(&power_regs->hw_power_vddactrl);
568 vddioctrl = readl(&power_regs->hw_power_vddioctrl);
569
570 setbits_le32(&power_regs->hw_power_vdddctrl,
571 POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
572 POWER_VDDDCTRL_PWDN_BRNOUT);
573
574 setbits_le32(&power_regs->hw_power_vddactrl,
575 POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG |
576 POWER_VDDACTRL_PWDN_BRNOUT);
577
578 setbits_le32(&power_regs->hw_power_vddioctrl,
579 POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT);
580
581 mxs_power_init_4p2_params();
582 mxs_power_init_4p2_regulator();
583
584
585 if (!mxs_is_batt_ready()) {
586 clrbits_le32(&power_regs->hw_power_dcdc4p2,
587 POWER_DCDC4P2_BO_MASK);
588 writel(POWER_CTRL_DCDC4P2_BO_IRQ,
589 &power_regs->hw_power_ctrl_clr);
590 writel(POWER_CTRL_ENIRQ_DCDC4P2_BO,
591 &power_regs->hw_power_ctrl_clr);
592 }
593
594 mxs_power_init_dcdc_4p2_source();
595
596 writel(vdddctrl, &power_regs->hw_power_vdddctrl);
597 early_delay(20);
598 writel(vddactrl, &power_regs->hw_power_vddactrl);
599 early_delay(20);
600 writel(vddioctrl, &power_regs->hw_power_vddioctrl);
601
602
603
604
605
606 tmp = 0;
607 tmp |= !(readl(&power_regs->hw_power_vdddctrl) &
608 POWER_VDDDCTRL_DISABLE_FET);
609 tmp |= !(readl(&power_regs->hw_power_vddactrl) &
610 POWER_VDDACTRL_DISABLE_FET);
611 tmp |= !(readl(&power_regs->hw_power_vddioctrl) &
612 POWER_VDDIOCTRL_DISABLE_FET);
613 if (tmp)
614 writel(POWER_CHARGE_ENABLE_LOAD,
615 &power_regs->hw_power_charge_clr);
616
617 debug("SPL: 4P2 regulator powered-up\n");
618}
619
620
621
622
623
624
625
626
627
628static void mxs_boot_valid_5v(void)
629{
630 struct mxs_power_regs *power_regs =
631 (struct mxs_power_regs *)MXS_POWER_BASE;
632
633 debug("SPL: Booting from 5V supply\n");
634
635
636
637
638
639 writel(POWER_5VCTRL_VBUSVALID_5VDETECT,
640 &power_regs->hw_power_5vctrl_set);
641
642
643 writel(POWER_CTRL_POLARITY_VBUSVALID |
644 POWER_CTRL_POLARITY_VDD5V_GT_VDDIO,
645 &power_regs->hw_power_ctrl_clr);
646
647 writel(POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_VDD5V_GT_VDDIO_IRQ,
648 &power_regs->hw_power_ctrl_clr);
649
650 mxs_power_enable_4p2();
651}
652
653
654
655
656
657
658static void mxs_powerdown(void)
659{
660 struct mxs_power_regs *power_regs =
661 (struct mxs_power_regs *)MXS_POWER_BASE;
662
663 debug("Powering Down\n");
664
665 writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset);
666 writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
667 &power_regs->hw_power_reset);
668}
669
670
671
672
673
674
675
676static void mxs_batt_boot(void)
677{
678 struct mxs_power_regs *power_regs =
679 (struct mxs_power_regs *)MXS_POWER_BASE;
680
681 debug("SPL: Configuring power block to boot from battery\n");
682
683 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
684 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC);
685
686 clrbits_le32(&power_regs->hw_power_dcdc4p2,
687 POWER_DCDC4P2_ENABLE_DCDC | POWER_DCDC4P2_ENABLE_4P2);
688 writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_clr);
689
690
691 setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
692 early_delay(30);
693 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
694
695 writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr);
696
697 clrsetbits_le32(&power_regs->hw_power_minpwr,
698 POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
699
700 mxs_power_set_linreg();
701
702 clrbits_le32(&power_regs->hw_power_vdddctrl,
703 POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG);
704
705 clrbits_le32(&power_regs->hw_power_vddactrl,
706 POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG);
707
708 clrbits_le32(&power_regs->hw_power_vddioctrl,
709 POWER_VDDIOCTRL_DISABLE_FET);
710
711 setbits_le32(&power_regs->hw_power_5vctrl,
712 POWER_5VCTRL_PWD_CHARGE_4P2_MASK);
713
714 setbits_le32(&power_regs->hw_power_5vctrl,
715 POWER_5VCTRL_ENABLE_DCDC);
716
717 clrsetbits_le32(&power_regs->hw_power_5vctrl,
718 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
719 0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
720
721 mxs_power_enable_4p2();
722}
723
724
725
726
727
728
729
730
731
732static void mxs_handle_5v_conflict(void)
733{
734 struct mxs_power_regs *power_regs =
735 (struct mxs_power_regs *)MXS_POWER_BASE;
736 uint32_t tmp;
737
738 debug("SPL: Resolving 5V conflict\n");
739
740 setbits_le32(&power_regs->hw_power_vddioctrl,
741 POWER_VDDIOCTRL_BO_OFFSET_MASK);
742
743 for (;;) {
744 tmp = readl(&power_regs->hw_power_sts);
745
746 if (tmp & POWER_STS_VDDIO_BO) {
747
748
749
750
751 debug("SPL: VDDIO has a brownout\n");
752 mxs_powerdown();
753 break;
754 }
755
756 if (tmp & POWER_STS_VDD5V_GT_VDDIO) {
757 debug("SPL: POWER_STS_VDD5V_GT_VDDIO is set\n");
758 mxs_boot_valid_5v();
759 break;
760 } else {
761 debug("SPL: POWER_STS_VDD5V_GT_VDDIO is not set\n");
762 mxs_powerdown();
763 break;
764 }
765
766
767
768
769
770 if (tmp & POWER_STS_PSWITCH_MASK) {
771 debug("SPL: POWER_STS_PSWITCH_MASK is set\n");
772 mxs_batt_boot();
773 break;
774 }
775 }
776}
777
778
779
780
781
782
783
784static void mxs_5v_boot(void)
785{
786 struct mxs_power_regs *power_regs =
787 (struct mxs_power_regs *)MXS_POWER_BASE;
788
789 debug("SPL: Configuring power block to boot from 5V input\n");
790
791
792
793
794
795 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
796 debug("SPL: 5V VDD good\n");
797 mxs_boot_valid_5v();
798 return;
799 }
800
801 early_delay(1000);
802 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
803 debug("SPL: 5V VDD good (after delay)\n");
804 mxs_boot_valid_5v();
805 return;
806 }
807
808 debug("SPL: 5V VDD not good\n");
809 mxs_handle_5v_conflict();
810}
811
812
813
814
815
816
817
818static void mxs_init_batt_bo(void)
819{
820 struct mxs_power_regs *power_regs =
821 (struct mxs_power_regs *)MXS_POWER_BASE;
822
823 debug("SPL: Initialising battery brown-out level to 3.0V\n");
824
825
826 clrsetbits_le32(&power_regs->hw_power_battmonitor,
827 POWER_BATTMONITOR_BRWNOUT_LVL_MASK,
828 15 << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
829
830 writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr);
831 writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
832}
833
834
835
836
837
838
839
840static void mxs_switch_vddd_to_dcdc_source(void)
841{
842 struct mxs_power_regs *power_regs =
843 (struct mxs_power_regs *)MXS_POWER_BASE;
844
845 debug("SPL: Switching VDDD to DC-DC converters\n");
846
847 clrsetbits_le32(&power_regs->hw_power_vdddctrl,
848 POWER_VDDDCTRL_LINREG_OFFSET_MASK,
849 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
850
851 clrbits_le32(&power_regs->hw_power_vdddctrl,
852 POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
853 POWER_VDDDCTRL_DISABLE_STEPPING);
854}
855
856
857
858
859
860
861
862
863
864
865static void mxs_power_configure_power_source(void)
866{
867 int batt_ready, batt_good;
868 struct mxs_power_regs *power_regs =
869 (struct mxs_power_regs *)MXS_POWER_BASE;
870 struct mxs_lradc_regs *lradc_regs =
871 (struct mxs_lradc_regs *)MXS_LRADC_BASE;
872
873 debug("SPL: Configuring power source\n");
874
875 mxs_src_power_init();
876
877 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
878 batt_ready = mxs_is_batt_ready();
879 if (batt_ready) {
880
881 mxs_batt_boot();
882 } else {
883 batt_good = mxs_is_batt_good();
884 if (!batt_good) {
885
886 writel(LRADC_CONVERSION_AUTOMATIC,
887 &lradc_regs->hw_lradc_conversion_clr);
888 clrbits_le32(&power_regs->hw_power_battmonitor,
889 POWER_BATTMONITOR_BATT_VAL_MASK);
890 }
891 mxs_5v_boot();
892 }
893 } else {
894
895 mxs_batt_boot();
896 }
897
898
899
900
901
902 mxs_power_clock2pll();
903
904 mxs_init_batt_bo();
905
906 mxs_switch_vddd_to_dcdc_source();
907
908#ifdef CONFIG_MX23
909
910 debug("SPL: Enabling mx23 VDDMEM linear regulator\n");
911 writel(POWER_VDDMEMCTRL_ENABLE_LINREG | POWER_VDDMEMCTRL_ENABLE_ILIMIT,
912 &power_regs->hw_power_vddmemctrl);
913#endif
914}
915
916
917
918
919
920
921
922
923
924
925static void mxs_enable_output_rail_protection(void)
926{
927 struct mxs_power_regs *power_regs =
928 (struct mxs_power_regs *)MXS_POWER_BASE;
929
930 debug("SPL: Enabling output rail protection\n");
931
932 writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
933 POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr);
934
935 setbits_le32(&power_regs->hw_power_vdddctrl,
936 POWER_VDDDCTRL_PWDN_BRNOUT);
937
938 setbits_le32(&power_regs->hw_power_vddactrl,
939 POWER_VDDACTRL_PWDN_BRNOUT);
940
941 setbits_le32(&power_regs->hw_power_vddioctrl,
942 POWER_VDDIOCTRL_PWDN_BRNOUT);
943}
944
945
946
947
948
949
950
951
952static int mxs_get_vddio_power_source_off(void)
953{
954 struct mxs_power_regs *power_regs =
955 (struct mxs_power_regs *)MXS_POWER_BASE;
956 uint32_t tmp;
957
958 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
959 tmp = readl(&power_regs->hw_power_vddioctrl);
960 if (tmp & POWER_VDDIOCTRL_DISABLE_FET) {
961 if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
962 POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) {
963 return 1;
964 }
965 }
966
967 if (!(readl(&power_regs->hw_power_5vctrl) &
968 POWER_5VCTRL_ENABLE_DCDC)) {
969 if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
970 POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) {
971 return 1;
972 }
973 }
974 }
975
976 return 0;
977
978}
979
980
981
982
983
984
985
986
987static int mxs_get_vddd_power_source_off(void)
988{
989 struct mxs_power_regs *power_regs =
990 (struct mxs_power_regs *)MXS_POWER_BASE;
991 uint32_t tmp;
992
993 tmp = readl(&power_regs->hw_power_vdddctrl);
994 if (tmp & POWER_VDDDCTRL_DISABLE_FET) {
995 if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
996 POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
997 return 1;
998 }
999 }
1000
1001 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
1002 if (!(readl(&power_regs->hw_power_5vctrl) &
1003 POWER_5VCTRL_ENABLE_DCDC)) {
1004 return 1;
1005 }
1006 }
1007
1008 if (!(tmp & POWER_VDDDCTRL_ENABLE_LINREG)) {
1009 if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
1010 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW) {
1011 return 1;
1012 }
1013 }
1014
1015 return 0;
1016}
1017
1018struct mxs_vddx_cfg {
1019 uint32_t *reg;
1020 uint8_t step_mV;
1021 uint16_t lowest_mV;
1022 int (*powered_by_linreg)(void);
1023 uint32_t trg_mask;
1024 uint32_t bo_irq;
1025 uint32_t bo_enirq;
1026 uint32_t bo_offset_mask;
1027 uint32_t bo_offset_offset;
1028};
1029
1030static const struct mxs_vddx_cfg mxs_vddio_cfg = {
1031 .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
1032 hw_power_vddioctrl),
1033#if defined(CONFIG_MX23)
1034 .step_mV = 25,
1035#else
1036 .step_mV = 50,
1037#endif
1038 .lowest_mV = 2800,
1039 .powered_by_linreg = mxs_get_vddio_power_source_off,
1040 .trg_mask = POWER_VDDIOCTRL_TRG_MASK,
1041 .bo_irq = POWER_CTRL_VDDIO_BO_IRQ,
1042 .bo_enirq = POWER_CTRL_ENIRQ_VDDIO_BO,
1043 .bo_offset_mask = POWER_VDDIOCTRL_BO_OFFSET_MASK,
1044 .bo_offset_offset = POWER_VDDIOCTRL_BO_OFFSET_OFFSET,
1045};
1046
1047static const struct mxs_vddx_cfg mxs_vddd_cfg = {
1048 .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
1049 hw_power_vdddctrl),
1050 .step_mV = 25,
1051 .lowest_mV = 800,
1052 .powered_by_linreg = mxs_get_vddd_power_source_off,
1053 .trg_mask = POWER_VDDDCTRL_TRG_MASK,
1054 .bo_irq = POWER_CTRL_VDDD_BO_IRQ,
1055 .bo_enirq = POWER_CTRL_ENIRQ_VDDD_BO,
1056 .bo_offset_mask = POWER_VDDDCTRL_BO_OFFSET_MASK,
1057 .bo_offset_offset = POWER_VDDDCTRL_BO_OFFSET_OFFSET,
1058};
1059
1060#ifdef CONFIG_MX23
1061static const struct mxs_vddx_cfg mxs_vddmem_cfg = {
1062 .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
1063 hw_power_vddmemctrl),
1064 .step_mV = 50,
1065 .lowest_mV = 1700,
1066 .powered_by_linreg = NULL,
1067 .trg_mask = POWER_VDDMEMCTRL_TRG_MASK,
1068 .bo_irq = 0,
1069 .bo_enirq = 0,
1070 .bo_offset_mask = 0,
1071 .bo_offset_offset = 0,
1072};
1073#endif
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
1088 uint32_t new_target, uint32_t new_brownout)
1089{
1090 struct mxs_power_regs *power_regs =
1091 (struct mxs_power_regs *)MXS_POWER_BASE;
1092 uint32_t cur_target, diff, bo_int = 0;
1093 uint32_t powered_by_linreg = 0;
1094 int adjust_up, tmp;
1095
1096 new_brownout = DIV_ROUND_CLOSEST(new_target - new_brownout,
1097 cfg->step_mV);
1098
1099 cur_target = readl(cfg->reg);
1100 cur_target &= cfg->trg_mask;
1101 cur_target *= cfg->step_mV;
1102 cur_target += cfg->lowest_mV;
1103
1104 adjust_up = new_target > cur_target;
1105 if (cfg->powered_by_linreg)
1106 powered_by_linreg = cfg->powered_by_linreg();
1107
1108 if (adjust_up && cfg->bo_irq) {
1109 if (powered_by_linreg) {
1110 bo_int = readl(cfg->reg);
1111 clrbits_le32(cfg->reg, cfg->bo_enirq);
1112 }
1113 setbits_le32(cfg->reg, cfg->bo_offset_mask);
1114 }
1115
1116 do {
1117 if (abs(new_target - cur_target) > 100) {
1118 if (adjust_up)
1119 diff = cur_target + 100;
1120 else
1121 diff = cur_target - 100;
1122 } else {
1123 diff = new_target;
1124 }
1125
1126 diff -= cfg->lowest_mV;
1127 diff /= cfg->step_mV;
1128
1129 clrsetbits_le32(cfg->reg, cfg->trg_mask, diff);
1130
1131 if (powered_by_linreg ||
1132 (readl(&power_regs->hw_power_sts) &
1133 POWER_STS_VDD5V_GT_VDDIO))
1134 early_delay(500);
1135 else {
1136 for (;;) {
1137 tmp = readl(&power_regs->hw_power_sts);
1138 if (tmp & POWER_STS_DC_OK)
1139 break;
1140 }
1141 }
1142
1143 cur_target = readl(cfg->reg);
1144 cur_target &= cfg->trg_mask;
1145 cur_target *= cfg->step_mV;
1146 cur_target += cfg->lowest_mV;
1147 } while (new_target > cur_target);
1148
1149 if (cfg->bo_irq) {
1150 if (adjust_up && powered_by_linreg) {
1151 writel(cfg->bo_irq, &power_regs->hw_power_ctrl_clr);
1152 if (bo_int & cfg->bo_enirq)
1153 setbits_le32(cfg->reg, cfg->bo_enirq);
1154 }
1155
1156 clrsetbits_le32(cfg->reg, cfg->bo_offset_mask,
1157 new_brownout << cfg->bo_offset_offset);
1158 }
1159}
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169static void mxs_setup_batt_detect(void)
1170{
1171 debug("SPL: Starting battery voltage measurement logic\n");
1172
1173 mxs_lradc_init();
1174 mxs_lradc_enable_batt_measurement();
1175 early_delay(10);
1176}
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186static void mxs_ungate_power(void)
1187{
1188#ifdef CONFIG_MX23
1189 struct mxs_power_regs *power_regs =
1190 (struct mxs_power_regs *)MXS_POWER_BASE;
1191
1192 writel(POWER_CTRL_CLKGATE, &power_regs->hw_power_ctrl_clr);
1193#endif
1194}
1195
1196
1197
1198
1199
1200
1201
1202void mxs_power_init(void)
1203{
1204 struct mxs_power_regs *power_regs =
1205 (struct mxs_power_regs *)MXS_POWER_BASE;
1206
1207 debug("SPL: Initialising Power Block\n");
1208
1209 mxs_ungate_power();
1210
1211 mxs_power_clock2xtal();
1212 mxs_power_set_auto_restart();
1213 mxs_power_set_linreg();
1214 mxs_power_setup_5v_detect();
1215
1216 mxs_setup_batt_detect();
1217
1218 mxs_power_configure_power_source();
1219 mxs_enable_output_rail_protection();
1220
1221 debug("SPL: Setting VDDIO to 3V3 (brownout @ 3v15)\n");
1222 mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150);
1223
1224 debug("SPL: Setting VDDD to 1V5 (brownout @ 1v0)\n");
1225 mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000);
1226#ifdef CONFIG_MX23
1227 debug("SPL: Setting mx23 VDDMEM to 2V5 (brownout @ 1v7)\n");
1228 mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700);
1229#endif
1230 writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
1231 POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
1232 POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ |
1233 POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
1234
1235 writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set);
1236
1237 early_delay(1000);
1238}
1239
1240#ifdef CONFIG_SPL_MXS_PSWITCH_WAIT
1241
1242
1243
1244
1245
1246
1247void mxs_power_wait_pswitch(void)
1248{
1249 struct mxs_power_regs *power_regs =
1250 (struct mxs_power_regs *)MXS_POWER_BASE;
1251
1252 debug("SPL: Waiting for power switch input\n");
1253 while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK))
1254 ;
1255}
1256#endif
1257