]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/arm926ejs/mx28/spl_power_init.c
FIXED_BATT_SUPPLY working!?
[karo-tx-uboot.git] / arch / arm / cpu / arm926ejs / mx28 / spl_power_init.c
1 /*
2  * Freescale i.MX28 Boot PMIC init
3  *
4  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
5  * on behalf of DENX Software Engineering GmbH
6  *
7  * See file CREDITS for list of people who contributed to this
8  * project.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23  * MA 02111-1307 USA
24  */
25
26 #include <common.h>
27 #include <config.h>
28 #include <asm/io.h>
29 #include <asm/arch/imx-regs.h>
30
31 #include "mx28_init.h"
32
33 extern void dprintf(const char *fmt, ...);
34
35 #undef __arch_getl
36 #undef __arch_putl
37
38 #define __arch_getl(a)  arch_getl(a, __func__, __LINE__)
39 static inline unsigned int arch_getl(volatile void *addr,
40                         const char *fn, unsigned int ln)
41 {
42         volatile unsigned int *a = addr;
43         unsigned int val = *a;
44         dprintf("%s@%d: Read %x from %p\n", fn, ln, val, addr);
45         return val;
46 }
47
48 #define __arch_putl(v, a)       arch_putl(v, a, __func__, __LINE__)
49 static inline void arch_putl(unsigned int val, volatile void *addr,
50                         const char *fn, unsigned int ln)
51 {
52         volatile unsigned int *a = addr;
53
54         dprintf("%s@%d: Writing %x to %p\n", fn, ln, val, addr);
55         *a = val;
56 }
57
58 #define __static
59
60 __static int mx28_power_vdd5v_gt_vddio(void)
61 {
62 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
63         struct mx28_power_regs *power_regs =
64                 (struct mx28_power_regs *)MXS_POWER_BASE;
65         int power_sts = readl(&power_regs->hw_power_sts);
66
67         dprintf("%s@%d: 0\n", __func__, __LINE__,
68                 !!(power_sts & POWER_STS_VDD5V_GT_VDDIO));
69         return power_sts & POWER_STS_VDD5V_GT_VDDIO;
70 #else
71         dprintf("%s@%d: 0\n", __func__, __LINE__);
72         return 0;
73 #endif
74 }
75
76 __static int mx28_power_vbus_valid(void)
77 {
78 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
79         struct mx28_power_regs *power_regs =
80                 (struct mx28_power_regs *)MXS_POWER_BASE;
81         int power_5vctrl = readl(&power_regs->hw_power_5vctrl);
82
83         dprintf("%s@%d: 0\n", __func__, __LINE__,
84                 !!(power_5vctrl & POWER_5VCTRL_VBUSVALID_5VDETECT));
85         return power_5vctrl & POWER_5VCTRL_VBUSVALID_5VDETECT;
86 #else
87         dprintf("%s@%d: 0\n", __func__, __LINE__);
88         return 0;
89 #endif
90 }
91
92 static void memdump(unsigned long addr, unsigned long len)
93 {
94         int i;
95         uint32_t *ptr = (void *)addr;
96
97         for (i = 0; i < len; i++) {
98                 if (i % 4 == 0)
99                         dprintf("\n%p:", &ptr[i]);
100                 dprintf(" %x", ptr[i]);
101         }
102         dprintf("\n");
103 }
104
105 //#undef CONFIG_SPL_FIXED_BATT_SUPPLY
106
107 __static void mx28_power_clock2xtal(void)
108 {
109         struct mx28_clkctrl_regs *clkctrl_regs =
110                 (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
111
112         dprintf("%s@%d: \n", __func__, __LINE__);
113         /* Set XTAL as CPU reference clock */
114         writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
115                 &clkctrl_regs->hw_clkctrl_clkseq_set);
116 }
117
118 __static void mx28_power_clock2pll(void)
119 {
120         struct mx28_clkctrl_regs *clkctrl_regs =
121                 (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
122
123         dprintf("%s@%d: \n", __func__, __LINE__);
124         writel(CLKCTRL_PLL0CTRL0_POWER,
125                 &clkctrl_regs->hw_clkctrl_pll0ctrl0_set);
126         early_delay(100);
127         writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
128                 &clkctrl_regs->hw_clkctrl_clkseq_clr);
129 }
130
131 __static void mx28_power_clear_auto_restart(void)
132 {
133         struct mx28_rtc_regs *rtc_regs =
134                 (struct mx28_rtc_regs *)MXS_RTC_BASE;
135
136         dprintf("%s@%d: \n", __func__, __LINE__);
137         writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr);
138         while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST)
139                 ;
140
141         writel(RTC_CTRL_CLKGATE, &rtc_regs->hw_rtc_ctrl_clr);
142         while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE)
143                 ;
144 #ifdef CONFIG_MACH_MX28EVK
145         /*
146          * Due to the hardware design bug of mx28 EVK-A
147          * we need to set the AUTO_RESTART bit.
148          */
149         if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART)
150                 return;
151
152         while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
153                 ;
154
155         setbits_le32(&rtc_regs->hw_rtc_persistent0,
156                         RTC_PERSISTENT0_AUTO_RESTART);
157         writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_set);
158         writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_clr);
159         while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
160                 ;
161         while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK)
162                 ;
163 #endif
164 }
165
166 __static void mx28_power_set_linreg(void)
167 {
168         struct mx28_power_regs *power_regs =
169                 (struct mx28_power_regs *)MXS_POWER_BASE;
170
171         dprintf("%s@%d: \n", __func__, __LINE__);
172         /* Set linear regulator 25mV below switching converter */
173         clrsetbits_le32(&power_regs->hw_power_vdddctrl,
174                         POWER_VDDDCTRL_LINREG_OFFSET_MASK,
175                         POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_ABOVE);
176
177         clrsetbits_le32(&power_regs->hw_power_vddactrl,
178                         POWER_VDDACTRL_LINREG_OFFSET_MASK,
179                         POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW);
180
181         clrsetbits_le32(&power_regs->hw_power_vddioctrl,
182                         POWER_VDDIOCTRL_LINREG_OFFSET_MASK,
183                         POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
184         dprintf("vddioctrl=%x\n", readl(&power_regs->hw_power_vddioctrl));
185 }
186
187 __static void mx28_power_setup_5v_detect(void)
188 {
189         struct mx28_power_regs *power_regs =
190                 (struct mx28_power_regs *)MXS_POWER_BASE;
191
192         dprintf("%s@%d: \n", __func__, __LINE__);
193         /* Start 5V detection */
194         clrsetbits_le32(&power_regs->hw_power_5vctrl,
195                         POWER_5VCTRL_VBUSVALID_TRSH_MASK,
196                         POWER_5VCTRL_VBUSVALID_TRSH_4V4 |
197                         POWER_5VCTRL_PWRUP_VBUS_CMPS);
198 }
199
200 __static void mx28_src_power_init(void)
201 {
202         struct mx28_power_regs *power_regs =
203                 (struct mx28_power_regs *)MXS_POWER_BASE;
204
205         dprintf("%s@%d: \n", __func__, __LINE__);
206         /* Improve efficieny and reduce transient ripple */
207         writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST |
208                 POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set);
209
210         clrsetbits_le32(&power_regs->hw_power_dclimits,
211                         POWER_DCLIMITS_POSLIMIT_BUCK_MASK,
212                         0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET);
213
214         setbits_le32(&power_regs->hw_power_battmonitor,
215                         POWER_BATTMONITOR_EN_BATADJ);
216
217         /* Increase the RCSCALE level for quick DCDC response to dynamic load */
218         clrsetbits_le32(&power_regs->hw_power_loopctrl,
219                         POWER_LOOPCTRL_EN_RCSCALE_MASK,
220                         POWER_LOOPCTRL_RCSCALE_THRESH |
221                         POWER_LOOPCTRL_EN_RCSCALE_8X);
222
223         clrsetbits_le32(&power_regs->hw_power_minpwr,
224                         POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
225 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
226         /* 5V to battery handoff ... FIXME */
227         setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
228         early_delay(30);
229         clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
230 #endif
231 }
232
233 __static void mx28_power_init_4p2_params(void)
234 {
235         struct mx28_power_regs *power_regs =
236                 (struct mx28_power_regs *)MXS_POWER_BASE;
237
238         dprintf("%s@%d: \n", __func__, __LINE__);
239         /* Setup 4P2 parameters */
240         clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
241                 POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK,
242                 POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET));
243
244         clrsetbits_le32(&power_regs->hw_power_5vctrl,
245                 POWER_5VCTRL_HEADROOM_ADJ_MASK,
246                 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET);
247
248         clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
249                 POWER_DCDC4P2_DROPOUT_CTRL_MASK,
250                 POWER_DCDC4P2_DROPOUT_CTRL_100MV |
251                 POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL);
252
253         clrsetbits_le32(&power_regs->hw_power_5vctrl,
254                 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
255                 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
256         dprintf("5vctrl=%x\n", readl(&power_regs->hw_power_5vctrl));
257         dprintf("dcdc4p2=%x\n", readl(&power_regs->hw_power_dcdc4p2));
258 }
259
260 __static void mx28_enable_4p2_dcdc_input(int xfer)
261 {
262         struct mx28_power_regs *power_regs =
263                 (struct mx28_power_regs *)MXS_POWER_BASE;
264         uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo;
265         uint32_t prev_5v_brnout, prev_5v_droop;
266
267         dprintf("%s@%d: %d\n", __func__, __LINE__, xfer);
268         prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) &
269                                 POWER_5VCTRL_PWDN_5VBRNOUT;
270         prev_5v_droop = readl(&power_regs->hw_power_ctrl) &
271                                 POWER_CTRL_ENIRQ_VDD5V_DROOP;
272
273         clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
274         writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
275                 &power_regs->hw_power_reset);
276
277         clrbits_le32(&power_regs->hw_power_ctrl, POWER_CTRL_ENIRQ_VDD5V_DROOP);
278
279         if (xfer && (readl(&power_regs->hw_power_5vctrl) &
280                         POWER_5VCTRL_ENABLE_DCDC)) {
281                 return;
282         }
283
284         /*
285          * Recording orignal values that will be modified temporarlily
286          * to handle a chip bug. See chip errata for CQ ENGR00115837
287          */
288         tmp = readl(&power_regs->hw_power_5vctrl);
289         vbus_thresh = tmp & POWER_5VCTRL_VBUSVALID_TRSH_MASK;
290         vbus_5vdetect = mx28_power_vbus_valid();
291
292         pwd_bo = readl(&power_regs->hw_power_minpwr) & POWER_MINPWR_PWD_BO;
293
294         /*
295          * Disable mechanisms that get erroneously tripped by when setting
296          * the DCDC4P2 EN_DCDC
297          */
298         clrbits_le32(&power_regs->hw_power_5vctrl,
299                 POWER_5VCTRL_VBUSVALID_5VDETECT |
300                 POWER_5VCTRL_VBUSVALID_TRSH_MASK);
301
302         writel(POWER_MINPWR_PWD_BO, &power_regs->hw_power_minpwr_set);
303
304         if (xfer) {
305                 setbits_le32(&power_regs->hw_power_5vctrl,
306                                 POWER_5VCTRL_DCDC_XFER);
307                 early_delay(20);
308                 clrbits_le32(&power_regs->hw_power_5vctrl,
309                                 POWER_5VCTRL_DCDC_XFER);
310
311                 setbits_le32(&power_regs->hw_power_5vctrl,
312                                 POWER_5VCTRL_ENABLE_DCDC);
313         } else {
314                 setbits_le32(&power_regs->hw_power_dcdc4p2,
315                                 POWER_DCDC4P2_ENABLE_DCDC);
316         }
317
318         early_delay(25);
319
320         clrsetbits_le32(&power_regs->hw_power_5vctrl,
321                         POWER_5VCTRL_VBUSVALID_TRSH_MASK, vbus_thresh);
322
323         if (vbus_5vdetect)
324                 writel(vbus_5vdetect, &power_regs->hw_power_5vctrl_set);
325
326         if (!pwd_bo)
327                 clrbits_le32(&power_regs->hw_power_minpwr, POWER_MINPWR_PWD_BO);
328
329         while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ)
330                 writel(POWER_CTRL_VBUS_VALID_IRQ,
331                         &power_regs->hw_power_ctrl_clr);
332
333         if (prev_5v_brnout) {
334                 writel(POWER_5VCTRL_PWDN_5VBRNOUT,
335                         &power_regs->hw_power_5vctrl_set);
336                 writel(POWER_RESET_UNLOCK_KEY,
337                         &power_regs->hw_power_reset);
338         } else {
339                 writel(POWER_5VCTRL_PWDN_5VBRNOUT,
340                         &power_regs->hw_power_5vctrl_clr);
341                 writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
342                         &power_regs->hw_power_reset);
343         }
344
345         while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VDD5V_DROOP_IRQ)
346                 writel(POWER_CTRL_VDD5V_DROOP_IRQ,
347                         &power_regs->hw_power_ctrl_clr);
348
349         if (prev_5v_droop)
350                 setbits_le32(&power_regs->hw_power_ctrl,
351                                 POWER_CTRL_ENIRQ_VDD5V_DROOP);
352         else
353                 clrbits_le32(&power_regs->hw_power_ctrl,
354                                 POWER_CTRL_ENIRQ_VDD5V_DROOP);
355 }
356
357 __static void mx28_power_init_4p2_regulator(void)
358 {
359         struct mx28_power_regs *power_regs =
360                 (struct mx28_power_regs *)MXS_POWER_BASE;
361         uint32_t tmp, tmp2;
362
363         dprintf("%s@%d: \n", __func__, __LINE__);
364         setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2);
365
366         writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set);
367
368         writel(POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
369                 &power_regs->hw_power_5vctrl_clr);
370         clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_TRG_MASK);
371
372         /* Power up the 4p2 rail and logic/control */
373         writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
374                 &power_regs->hw_power_5vctrl_clr);
375
376         /*
377          * Start charging up the 4p2 capacitor. We ramp of this charge
378          * gradually to avoid large inrush current from the 5V cable which can
379          * cause transients/problems
380          */
381         mx28_enable_4p2_dcdc_input(0);
382
383         if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
384                 /*
385                  * If we arrived here, we were unable to recover from mx23 chip
386                  * errata 5837. 4P2 is disabled and sufficient battery power is
387                  * not present. Exiting to not enable DCDC power during 5V
388                  * connected state.
389                  */
390                 clrbits_le32(&power_regs->hw_power_dcdc4p2,
391                         POWER_DCDC4P2_ENABLE_DCDC);
392                 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
393                         &power_regs->hw_power_5vctrl_set);
394                 hang();
395         }
396
397         /*
398          * Here we set the 4p2 brownout level to something very close to 4.2V.
399          * We then check the brownout status. If the brownout status is false,
400          * the voltage is already close to the target voltage of 4.2V so we
401          * can go ahead and set the 4P2 current limit to our max target limit.
402          * If the brownout status is true, we need to ramp us the current limit
403          * so that we don't cause large inrush current issues. We step up the
404          * current limit until the brownout status is false or until we've
405          * reached our maximum defined 4p2 current limit.
406          */
407         clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
408                         POWER_DCDC4P2_BO_MASK,
409                         22 << POWER_DCDC4P2_BO_OFFSET); /* 4.15V */
410
411         if (!(readl(&power_regs->hw_power_sts) & POWER_STS_DCDC_4P2_BO)) {
412                 setbits_le32(&power_regs->hw_power_5vctrl,
413                         0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
414         } else {
415                 tmp = (readl(&power_regs->hw_power_5vctrl) &
416                         POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK) >>
417                         POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
418                 while (tmp < 0x3f) {
419                         if (!(readl(&power_regs->hw_power_sts) &
420                                         POWER_STS_DCDC_4P2_BO)) {
421                                 tmp = readl(&power_regs->hw_power_5vctrl);
422                                 tmp |= POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
423                                 early_delay(100);
424                                 writel(tmp, &power_regs->hw_power_5vctrl);
425                                 break;
426                         } else {
427                                 tmp++;
428                                 tmp2 = readl(&power_regs->hw_power_5vctrl);
429                                 tmp2 &= ~POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
430                                 tmp2 |= tmp <<
431                                         POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
432                                 writel(tmp2, &power_regs->hw_power_5vctrl);
433                                 early_delay(100);
434                         }
435                 }
436         }
437
438         clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK);
439         writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
440 }
441
442 __static void mx28_power_init_dcdc_4p2_source(void)
443 {
444         struct mx28_power_regs *power_regs =
445                 (struct mx28_power_regs *)MXS_POWER_BASE;
446
447         dprintf("%s@%d: \n", __func__, __LINE__);
448 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
449         if (!(readl(&power_regs->hw_power_dcdc4p2) &
450                 POWER_DCDC4P2_ENABLE_DCDC)) {
451                 hang();
452         }
453
454         mx28_enable_4p2_dcdc_input(1);
455
456         if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
457                 clrbits_le32(&power_regs->hw_power_dcdc4p2,
458                         POWER_DCDC4P2_ENABLE_DCDC);
459                 writel(POWER_5VCTRL_ENABLE_DCDC,
460                         &power_regs->hw_power_5vctrl_clr);
461                 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
462                         &power_regs->hw_power_5vctrl_set);
463         }
464 #else
465         clrbits_le32(&power_regs->hw_power_dcdc4p2,
466                 POWER_DCDC4P2_ENABLE_4P2 | POWER_DCDC4P2_ENABLE_DCDC);
467 #endif
468 }
469
470 __static void mx28_power_enable_4p2(void)
471 {
472         struct mx28_power_regs *power_regs =
473                 (struct mx28_power_regs *)MXS_POWER_BASE;
474         uint32_t vdddctrl, vddactrl, vddioctrl;
475         uint32_t tmp;
476
477         dprintf("%s@%d: \n", __func__, __LINE__);
478         vdddctrl = readl(&power_regs->hw_power_vdddctrl);
479         vddactrl = readl(&power_regs->hw_power_vddactrl);
480         vddioctrl = readl(&power_regs->hw_power_vddioctrl);
481
482         setbits_le32(&power_regs->hw_power_vdddctrl,
483                 POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
484                 POWER_VDDDCTRL_PWDN_BRNOUT);
485
486         setbits_le32(&power_regs->hw_power_vddactrl,
487                 POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG |
488                 POWER_VDDACTRL_PWDN_BRNOUT);
489
490         setbits_le32(&power_regs->hw_power_vddioctrl,
491                 POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT);
492
493         mx28_power_init_4p2_params();
494         mx28_power_init_4p2_regulator();
495
496         /* Shutdown battery (none present) */
497         clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK);
498         writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
499         writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr);
500
501         mx28_power_init_dcdc_4p2_source();
502
503         readl(&power_regs->hw_power_vdddctrl);
504         readl(&power_regs->hw_power_vddactrl);
505         readl(&power_regs->hw_power_vddioctrl);
506         writel(vdddctrl, &power_regs->hw_power_vdddctrl);
507         early_delay(20);
508         memdump(0x80044000, 0x60);
509         writel(vddactrl, &power_regs->hw_power_vddactrl);
510         early_delay(20);
511         writel(vddioctrl, &power_regs->hw_power_vddioctrl);
512
513         /*
514          * Check if FET is enabled on either powerout and if so,
515          * disable load.
516          */
517         tmp = 0;
518         tmp |= !(readl(&power_regs->hw_power_vdddctrl) &
519                         POWER_VDDDCTRL_DISABLE_FET);
520         tmp |= !(readl(&power_regs->hw_power_vddactrl) &
521                         POWER_VDDACTRL_DISABLE_FET);
522         tmp |= !(readl(&power_regs->hw_power_vddioctrl) &
523                         POWER_VDDIOCTRL_DISABLE_FET);
524         if (tmp)
525                 writel(POWER_CHARGE_ENABLE_LOAD,
526                         &power_regs->hw_power_charge_clr);
527 }
528
529 __static void mx28_boot_valid_5v(void)
530 {
531         struct mx28_power_regs *power_regs =
532                 (struct mx28_power_regs *)MXS_POWER_BASE;
533
534         dprintf("%s@%d: \n", __func__, __LINE__);
535         /*
536          * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
537          * disconnect event. FIXME
538          */
539         writel(POWER_5VCTRL_VBUSVALID_5VDETECT,
540                 &power_regs->hw_power_5vctrl_set);
541
542         /* Configure polarity to check for 5V disconnection. */
543         writel(POWER_CTRL_POLARITY_VBUSVALID |
544                 POWER_CTRL_POLARITY_VDD5V_GT_VDDIO,
545                 &power_regs->hw_power_ctrl_clr);
546
547         writel(POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_VDD5V_GT_VDDIO_IRQ,
548                 &power_regs->hw_power_ctrl_clr);
549
550         mx28_power_enable_4p2();
551 }
552
553 void mx28_powerdown(void)
554 {
555         struct mx28_power_regs *power_regs =
556                 (struct mx28_power_regs *)MXS_POWER_BASE;
557
558         dprintf("%s@%d: \n", __func__, __LINE__);
559         writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset);
560         writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
561                 &power_regs->hw_power_reset);
562 }
563
564 __static inline void mx28_handle_5v_conflict(void)
565 {
566         struct mx28_power_regs *power_regs =
567                 (struct mx28_power_regs *)MXS_POWER_BASE;
568         uint32_t tmp;
569
570         dprintf("%s@%d: \n", __func__, __LINE__);
571         setbits_le32(&power_regs->hw_power_vddioctrl,
572                         POWER_VDDIOCTRL_BO_OFFSET_MASK);
573
574         for (;;) {
575                 tmp = readl(&power_regs->hw_power_sts);
576
577                 if (tmp & POWER_STS_VDDIO_BO) {
578                         mx28_powerdown();
579                         break;
580                 }
581
582                 if (tmp & POWER_STS_VDD5V_GT_VDDIO) {
583                         mx28_boot_valid_5v();
584                         break;
585                 } else {
586                         mx28_powerdown();
587                         break;
588                 }
589         }
590 }
591
592 __static int mx28_get_batt_volt(void)
593 {
594         struct mx28_power_regs *power_regs =
595                 (struct mx28_power_regs *)MXS_POWER_BASE;
596         uint32_t volt = readl(&power_regs->hw_power_battmonitor);
597
598         dprintf("%s@%d: \n", __func__, __LINE__);
599         volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
600         volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
601         volt *= 8;
602         return volt;
603 }
604
605 #define __maybe_unused __attribute__((unused))
606
607 __static int __maybe_unused mx28_is_batt_ready(void)
608 {
609         dprintf("%s@%d: \n", __func__, __LINE__);
610         return (mx28_get_batt_volt() >= 3600);
611 }
612
613 __static void mx28_5v_boot(void)
614 {
615         struct mx28_power_regs *power_regs =
616                 (struct mx28_power_regs *)MXS_POWER_BASE;
617
618         dprintf("%s@%d: \n", __func__, __LINE__);
619 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
620         /*
621          * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID,
622          * but their implementation always returns 1 so we omit it here.
623          */
624         if (mx28_power_vdd5v_gt_vddio()) {
625                 mx28_boot_valid_5v();
626                 return;
627         }
628
629         early_delay(1000);
630         if (mx28_power_vdd5v_gt_vddio()) {
631                 mx28_boot_valid_5v();
632                 return;
633         }
634
635         mx28_handle_5v_conflict();
636 #else
637         writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
638         writel(1 << POWER_5VCTRL_PWD_CHARGE_4P2_OFFSET, &power_regs->hw_power_5vctrl_set);
639
640         clrsetbits_le32(&power_regs->hw_power_vdddctrl,
641                         POWER_VDDDCTRL_DISABLE_FET,
642                         POWER_VDDDCTRL_ENABLE_LINREG |
643                         POWER_VDDDCTRL_DISABLE_STEPPING);
644 #endif
645 }
646
647 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
648 #define BATT_BO_VALUE   15
649 #else
650 /* Brownout at 3.08V */
651 #define BATT_BO_VALUE   17
652 #endif
653
654 __static void mx28_init_batt_bo(void)
655 {
656         struct mx28_power_regs *power_regs =
657                 (struct mx28_power_regs *)MXS_POWER_BASE;
658
659         dprintf("%s@%d: \n", __func__, __LINE__);
660 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
661         /* Brownout at 3V */
662         clrsetbits_le32(&power_regs->hw_power_battmonitor,
663                 POWER_BATTMONITOR_BRWNOUT_LVL_MASK,
664                 15 << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
665
666         writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr);
667         writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
668 #else
669         clrbits_le32(&power_regs->hw_power_battmonitor,
670                 POWER_BATTMONITOR_PWDN_BATTBRNOUT);
671         writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr);
672 #endif
673 }
674
675 __static void mx28_switch_vddd_to_dcdc_source(void)
676 {
677         struct mx28_power_regs *power_regs =
678                 (struct mx28_power_regs *)MXS_POWER_BASE;
679
680         dprintf("%s@%d: \n", __func__, __LINE__);
681         clrsetbits_le32(&power_regs->hw_power_vdddctrl,
682                 POWER_VDDDCTRL_LINREG_OFFSET_MASK,
683                 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
684
685         clrbits_le32(&power_regs->hw_power_vdddctrl,
686                 POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
687                 POWER_VDDDCTRL_DISABLE_STEPPING);
688 }
689
690 __static int __maybe_unused mx28_is_batt_good(void)
691 {
692         struct mx28_power_regs *power_regs =
693                 (struct mx28_power_regs *)MXS_POWER_BASE;
694         uint32_t volt;
695
696         dprintf("%s@%d: \n", __func__, __LINE__);
697         volt = readl(&power_regs->hw_power_battmonitor);
698         volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
699         volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
700         volt *= 8;
701
702         if ((volt >= 2400) && (volt <= 4300))
703                 return 1;
704
705         clrsetbits_le32(&power_regs->hw_power_5vctrl,
706                 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
707                 0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
708         writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
709                 &power_regs->hw_power_5vctrl_clr);
710
711         clrsetbits_le32(&power_regs->hw_power_charge,
712                 POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
713                 POWER_CHARGE_STOP_ILIMIT_10MA | 0x3);
714
715         writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_clr);
716         writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
717                 &power_regs->hw_power_5vctrl_clr);
718
719         early_delay(500000);
720
721         volt = readl(&power_regs->hw_power_battmonitor);
722         volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
723         volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
724         volt *= 8;
725
726         if (volt >= 3500)
727                 return 0;
728
729         if (volt >= 2400)
730                 return 1;
731
732         writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
733                 &power_regs->hw_power_charge_clr);
734         writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
735
736         return 0;
737 }
738
739 __static void mx28_power_configure_power_source(void)
740 {
741         dprintf("%s@%d: \n", __func__, __LINE__);
742
743         mx28_src_power_init();
744         mx28_5v_boot();
745
746         mx28_power_clock2pll();
747
748         mx28_init_batt_bo();
749
750 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY_
751         mx28_switch_vddd_to_dcdc_source();
752 #endif
753 }
754
755 __static void mx28_enable_output_rail_protection(void)
756 {
757         struct mx28_power_regs *power_regs =
758                 (struct mx28_power_regs *)MXS_POWER_BASE;
759
760         writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
761                 POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr);
762 #if 0
763         setbits_le32(&power_regs->hw_power_vdddctrl,
764                         POWER_VDDDCTRL_PWDN_BRNOUT);
765
766         setbits_le32(&power_regs->hw_power_vddactrl,
767                         POWER_VDDACTRL_PWDN_BRNOUT);
768 #endif
769         setbits_le32(&power_regs->hw_power_vddioctrl,
770                         POWER_VDDIOCTRL_PWDN_BRNOUT);
771 }
772
773 __static int mx28_get_vddio_power_source_off(void)
774 {
775 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY_
776         struct mx28_power_regs *power_regs =
777                 (struct mx28_power_regs *)MXS_POWER_BASE;
778         uint32_t tmp;
779
780         dprintf("%s@%d: \n", __func__, __LINE__);
781         if (mx28_power_vdd5v_gt_vddio()) {
782                 tmp = readl(&power_regs->hw_power_vddioctrl);
783                 if (tmp & POWER_VDDIOCTRL_DISABLE_FET) {
784                         if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
785                                 POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
786                                 dprintf("%s@%d: 1\n", __func__, __LINE__);
787                                 return 1;
788                         }
789                 }
790
791                 if (!(readl(&power_regs->hw_power_5vctrl) &
792                         POWER_5VCTRL_ENABLE_DCDC)) {
793                         if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
794                                 POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
795                                 dprintf("%s@%d: 1\n", __func__, __LINE__);
796                                 return 1;
797                         }
798                 }
799         }
800         dprintf("%s@%d: 0\n", __func__, __LINE__);
801         return 0;
802 #else
803         dprintf("%s@%d: 1\n", __func__, __LINE__);
804         return 1;
805 #endif
806 }
807
808 __static int mx28_get_vddd_power_source_off(void)
809 {
810 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY_
811         struct mx28_power_regs *power_regs =
812                 (struct mx28_power_regs *)MXS_POWER_BASE;
813         uint32_t tmp;
814
815         dprintf("%s@%d: \n", __func__, __LINE__);
816         tmp = readl(&power_regs->hw_power_vdddctrl);
817         if (tmp & POWER_VDDDCTRL_DISABLE_FET) {
818                 if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
819                         POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
820                         dprintf("%s@%d: 1\n", __func__, __LINE__);
821                         return 1;
822                 }
823         }
824
825         if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
826                 if (!(readl(&power_regs->hw_power_5vctrl) &
827                         POWER_5VCTRL_ENABLE_DCDC)) {
828                         dprintf("%s@%d: 1\n", __func__, __LINE__);
829                         return 1;
830                 }
831         }
832
833         if (!(tmp & POWER_VDDDCTRL_ENABLE_LINREG)) {
834                 if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
835                         POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW) {
836                         dprintf("%s@%d: 1\n", __func__, __LINE__);
837                         return 1;
838                 }
839         }
840         dprintf("%s@%d: 0\n", __func__, __LINE__);
841         return 0;
842 #else
843         dprintf("%s@%d: 1\n", __func__, __LINE__);
844         return 1;
845 #endif
846 }
847
848 __static void mx28_power_set_vddio(uint32_t new_target, uint32_t new_brownout)
849 {
850         struct mx28_power_regs *power_regs =
851                 (struct mx28_power_regs *)MXS_POWER_BASE;
852         uint32_t cur_target, diff, bo_int = 0;
853         uint32_t powered_by_linreg;
854
855         dprintf("%s@%d: \n", __func__, __LINE__);
856         new_brownout = (new_target - new_brownout) / 25;
857         if (new_brownout > 7) {
858                 dprintf("Bad VDDD brownout offset\n");
859                 new_brownout = 7;
860         }
861
862         cur_target = readl(&power_regs->hw_power_vddioctrl);
863         cur_target &= POWER_VDDIOCTRL_TRG_MASK;
864         cur_target *= 50;       /* 50 mV step*/
865         cur_target += 2800;     /* 2800 mV lowest */
866
867         powered_by_linreg = mx28_get_vddio_power_source_off();
868         if (new_target != cur_target)
869                 dprintf("%s@%d: stepping VDDIO from %u to %u\n", __func__, __LINE__,
870                         cur_target, new_target);
871         else
872                 dprintf("%s@%d: VDDIO is at %u\n", __func__, __LINE__,
873                         cur_target, new_target);
874         if (new_target > cur_target) {
875
876                 if (powered_by_linreg) {
877                         bo_int = readl(&power_regs->hw_power_vddioctrl);
878                         clrbits_le32(&power_regs->hw_power_vddioctrl,
879                                         POWER_CTRL_ENIRQ_VDDIO_BO);
880                 }
881
882                 setbits_le32(&power_regs->hw_power_vddioctrl,
883                                 POWER_VDDIOCTRL_BO_OFFSET_MASK);
884                 do {
885                         if (new_target - cur_target > 100)
886                                 diff = cur_target + 100;
887                         else
888                                 diff = new_target;
889
890                         diff -= 2800;
891                         diff /= 50;
892
893                         clrsetbits_le32(&power_regs->hw_power_vddioctrl,
894                                 POWER_VDDIOCTRL_TRG_MASK, diff);
895                         dprintf("vddioctrl=%x\n", readl(&power_regs->hw_power_vddioctrl));
896
897                         if (powered_by_linreg)
898                                 early_delay(1500);
899                         else {
900                                 while (!(readl(&power_regs->hw_power_sts) &
901                                         POWER_STS_DC_OK))
902                                         ;
903
904                         }
905
906                         cur_target = readl(&power_regs->hw_power_vddioctrl);
907                         cur_target &= POWER_VDDIOCTRL_TRG_MASK;
908                         cur_target *= 50;       /* 50 mV step*/
909                         cur_target += 2800;     /* 2800 mV lowest */
910                 } while (new_target > cur_target);
911
912                 if (powered_by_linreg) {
913                         writel(POWER_CTRL_VDDIO_BO_IRQ,
914                                 &power_regs->hw_power_ctrl_clr);
915                         if (bo_int & POWER_CTRL_ENIRQ_VDDIO_BO)
916                                 setbits_le32(&power_regs->hw_power_vddioctrl,
917                                                 POWER_CTRL_ENIRQ_VDDIO_BO);
918                         dprintf("vddioctrl=%x\n", readl(&power_regs->hw_power_vddioctrl));
919                 }
920                 dprintf("%s@%d: Done\n", __func__, __LINE__);
921         } else {
922                 do {
923                         if (cur_target - new_target > 100)
924                                 diff = cur_target - 100;
925                         else
926                                 diff = new_target;
927
928                         diff -= 2800;
929                         diff /= 50;
930
931                         clrsetbits_le32(&power_regs->hw_power_vddioctrl,
932                                 POWER_VDDIOCTRL_TRG_MASK, diff);
933
934                         if (powered_by_linreg)
935                                 early_delay(1500);
936                         else {
937                                 while (!(readl(&power_regs->hw_power_sts) &
938                                         POWER_STS_DC_OK))
939                                         ;
940
941                         }
942
943                         cur_target = readl(&power_regs->hw_power_vddioctrl);
944                         cur_target &= POWER_VDDIOCTRL_TRG_MASK;
945                         cur_target *= 50;       /* 50 mV step*/
946                         cur_target += 2800;     /* 2800 mV lowest */
947                 } while (new_target < cur_target);
948                 dprintf("%s@%d: Done\n", __func__, __LINE__);
949         }
950
951         clrsetbits_le32(&power_regs->hw_power_vddioctrl,
952                         POWER_VDDDCTRL_BO_OFFSET_MASK,
953                         new_brownout << POWER_VDDDCTRL_BO_OFFSET_OFFSET);
954                         dprintf("vddioctrl=%x\n", readl(&power_regs->hw_power_vddioctrl));
955 }
956
957 __static void mx28_power_set_vddd(uint32_t new_target, uint32_t new_brownout)
958 {
959         struct mx28_power_regs *power_regs =
960                 (struct mx28_power_regs *)MXS_POWER_BASE;
961         uint32_t cur_target, diff, bo_int = 0;
962         uint32_t powered_by_linreg;
963
964         dprintf("%s@%d: \n", __func__, __LINE__);
965         new_brownout = (new_target - new_brownout) / 25;
966         if (new_brownout > 7) {
967                 dprintf("Bad VDDD brownout offset\n");
968                 new_brownout = 7;
969         }
970         cur_target = readl(&power_regs->hw_power_vdddctrl);
971         cur_target &= POWER_VDDDCTRL_TRG_MASK;
972         cur_target *= 25;       /* 25 mV step*/
973         cur_target += 800;      /* 800 mV lowest */
974
975         powered_by_linreg = mx28_get_vddd_power_source_off();
976         if (new_target != cur_target)
977                 dprintf("%s@%d: stepping VDDD from %u to %u\n", __func__, __LINE__,
978                         cur_target, new_target);
979         else
980                 dprintf("%s@%d: VDDD is at %u\n", __func__, __LINE__,
981                         cur_target, new_target);
982         if (new_target > cur_target) {
983                 if (powered_by_linreg) {
984                         bo_int = readl(&power_regs->hw_power_vdddctrl);
985                         clrbits_le32(&power_regs->hw_power_vdddctrl,
986                                         POWER_CTRL_ENIRQ_VDDD_BO);
987                 }
988
989                 setbits_le32(&power_regs->hw_power_vdddctrl,
990                                 POWER_VDDDCTRL_BO_OFFSET_MASK);
991
992                 do {
993                         if (new_target - cur_target > 100)
994                                 diff = cur_target + 100;
995                         else
996                                 diff = new_target;
997
998                         diff -= 800;
999                         diff /= 25;
1000
1001                         clrsetbits_le32(&power_regs->hw_power_vdddctrl,
1002                                 POWER_VDDDCTRL_TRG_MASK, diff);
1003
1004                         if (powered_by_linreg)
1005                                 early_delay(1500);
1006                         else {
1007                                 while (!(readl(&power_regs->hw_power_sts) &
1008                                         POWER_STS_DC_OK))
1009                                         ;
1010
1011                         }
1012
1013                         cur_target = readl(&power_regs->hw_power_vdddctrl);
1014                         cur_target &= POWER_VDDDCTRL_TRG_MASK;
1015                         cur_target *= 25;       /* 25 mV step*/
1016                         cur_target += 800;      /* 800 mV lowest */
1017                 } while (new_target > cur_target);
1018
1019                 if (powered_by_linreg) {
1020                         writel(POWER_CTRL_VDDD_BO_IRQ,
1021                                 &power_regs->hw_power_ctrl_clr);
1022                         if (bo_int & POWER_CTRL_ENIRQ_VDDD_BO)
1023                                 setbits_le32(&power_regs->hw_power_vdddctrl,
1024                                                 POWER_CTRL_ENIRQ_VDDD_BO);
1025                 }
1026                 dprintf("%s@%d: Done\n", __func__, __LINE__);
1027         } else {
1028                 do {
1029                         if (cur_target - new_target > 100)
1030                                 diff = cur_target - 100;
1031                         else
1032                                 diff = new_target;
1033
1034                         diff -= 800;
1035                         diff /= 25;
1036
1037                         clrsetbits_le32(&power_regs->hw_power_vdddctrl,
1038                                         POWER_VDDDCTRL_TRG_MASK, diff);
1039
1040                         if (powered_by_linreg)
1041                                 early_delay(1500);
1042                         else {
1043                                 while (!(readl(&power_regs->hw_power_sts) &
1044                                         POWER_STS_DC_OK))
1045                                         ;
1046
1047                         }
1048
1049                         cur_target = readl(&power_regs->hw_power_vdddctrl);
1050                         cur_target &= POWER_VDDDCTRL_TRG_MASK;
1051                         cur_target *= 25;       /* 25 mV step*/
1052                         cur_target += 800;      /* 800 mV lowest */
1053                 } while (new_target < cur_target);
1054                 dprintf("%s@%d: Done\n", __func__, __LINE__);
1055         }
1056
1057         clrsetbits_le32(&power_regs->hw_power_vdddctrl,
1058                         POWER_VDDDCTRL_BO_OFFSET_MASK,
1059                         new_brownout << POWER_VDDDCTRL_BO_OFFSET_OFFSET);
1060 }
1061
1062 void mx28_power_init(void)
1063 {
1064         struct mx28_power_regs *power_regs =
1065                 (struct mx28_power_regs *)MXS_POWER_BASE;
1066
1067         dprintf("%s: %s %s\n", __func__, __DATE__, __TIME__);
1068         dprintf("ctrl=%x\n", readl(&power_regs->hw_power_ctrl));
1069         dprintf("sts=%x\n", readl(&power_regs->hw_power_sts));
1070 #ifdef CONFIG_SPL_FIXED_BATT_SUPPLY_
1071         writel(0x00018024, &power_regs->hw_power_ctrl);
1072         writel(0x20100592, &power_regs->hw_power_5vctrl);
1073         writel(0x00000018, &power_regs->hw_power_dcdc4p2);
1074         writel(0x0061071c, &power_regs->hw_power_vdddctrl);
1075         writel(0x0000270c, &power_regs->hw_power_vddactrl);
1076         writel(0x0004260a, &power_regs->hw_power_vddioctrl);
1077 #else
1078         dprintf("%s@%d\n", __func__, __LINE__);
1079         mx28_power_clock2xtal();
1080         dprintf("%s@%d\n", __func__, __LINE__);
1081         mx28_power_clear_auto_restart();
1082         dprintf("%s@%d\n", __func__, __LINE__);
1083         mx28_power_set_linreg();
1084         dprintf("%s@%d\n", __func__, __LINE__);
1085 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
1086         mx28_power_setup_5v_detect();
1087         dprintf("%s@%d\n", __func__, __LINE__);
1088         mx28_power_configure_power_source();
1089 //      dprintf("%s@%d\n", __func__, __LINE__);
1090 //      mx28_enable_output_rail_protection();
1091         dprintf("%s@%d\n", __func__, __LINE__);
1092
1093         mx28_power_set_vddio(3300, 3150);
1094         dprintf("%s@%d\n", __func__, __LINE__);
1095
1096         mx28_power_set_vddd(1500, 1325);
1097         dprintf("%s@%d\n", __func__, __LINE__);
1098
1099         writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
1100                 POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
1101                 POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ |
1102                 POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
1103
1104 #ifndef CONFIG_SPL_FIXED_BATT_SUPPLY
1105         writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set);
1106 #endif
1107         early_delay(1000);
1108 #else
1109         dprintf("%s@%d\n", __func__, __LINE__);
1110         mx28_src_power_init();
1111         dprintf("%s@%d\n", __func__, __LINE__);
1112         mx28_5v_boot();
1113         dprintf("%s@%d\n", __func__, __LINE__);
1114         mx28_power_clock2pll();
1115         dprintf("%s@%d\n", __func__, __LINE__);
1116         mx28_init_batt_bo();
1117         dprintf("%s@%d\n", __func__, __LINE__);
1118         mx28_switch_vddd_to_dcdc_source();
1119
1120         dprintf("%s@%d\n", __func__, __LINE__);
1121         mx28_power_set_vddio(3300, 3150);
1122
1123         dprintf("%s@%d\n", __func__, __LINE__);
1124         mx28_power_set_vddd(1500, 1325);
1125         dprintf("%s@%d\n", __func__, __LINE__);
1126
1127         writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
1128                 POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
1129                 POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ |
1130                 POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
1131 #endif
1132 #endif
1133         dprintf("sts=%x\n", readl(&power_regs->hw_power_sts));
1134         dprintf("vddioctrl=%x\n", readl(&power_regs->hw_power_vddioctrl));
1135         dprintf("vdddctrl=%x\n", readl(&power_regs->hw_power_vdddctrl));
1136         dprintf("5vctrl=%x\n", readl(&power_regs->hw_power_5vctrl));
1137         dprintf("dcdc4p2=%x\n", readl(&power_regs->hw_power_dcdc4p2));
1138         dprintf("%s@%d: Finished\n", __func__, __LINE__);
1139         memdump(0x80044000, 0x60);
1140 }
1141
1142 #ifdef  CONFIG_SPL_MX28_PSWITCH_WAIT
1143 void mx28_power_wait_pswitch(void)
1144 {
1145         struct mx28_power_regs *power_regs =
1146                 (struct mx28_power_regs *)MXS_POWER_BASE;
1147
1148         dprintf("%s@%d: \n", __func__, __LINE__);
1149         while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK))
1150                 ;
1151 }
1152 #endif