]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
merged tx6dl-devel into denx master branch
[karo-tx-uboot.git] / arch / arm / cpu / arm926ejs / mxs / 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  * SPDX-License-Identifier:     GPL-2.0+
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_SPL_VDDD_VAL
18 #define VDDD_VAL        CONFIG_SYS_SPL_VDDD_VAL
19 #else
20 #define VDDD_VAL        1350
21 #endif
22 #ifdef CONFIG_SYS_SPL_VDDIO_VAL
23 #define VDDIO_VAL       CONFIG_SYS_SPL_VDDIO_VAL
24 #else
25 #define VDDIO_VAL       3300
26 #endif
27 #ifdef CONFIG_SYS_SPL_VDDA_VAL
28 #define VDDA_VAL        CONFIG_SYS_SPL_VDDA_VAL
29 #else
30 #define VDDA_VAL        1800
31 #endif
32 #ifdef CONFIG_SYS_SPL_VDDMEM_VAL
33 #define VDDMEM_VAL      CONFIG_SYS_SPL_VDDMEM_VAL
34 #else
35 #define VDDMEM_VAL      1700
36 #endif
37
38 #ifdef CONFIG_SYS_SPL_VDDD_BO_VAL
39 #define VDDD_BO_VAL     CONFIG_SYS_SPL_VDDD_BO_VAL
40 #else
41 #define VDDD_BO_VAL     150
42 #endif
43 #ifdef CONFIG_SYS_SPL_VDDIO_BO_VAL
44 #define VDDIO_BO_VAL    CONFIG_SYS_SPL_VDDIO_BO_VAL
45 #else
46 #define VDDIO_BO_VAL    150
47 #endif
48 #ifdef CONFIG_SYS_SPL_VDDA_BO_VAL
49 #define VDDA_BO_VAL     CONFIG_SYS_SPL_VDDA_BO_VAL
50 #else
51 #define VDDA_BO_VAL     175
52 #endif
53 #ifdef CONFIG_SYS_SPL_VDDMEM_BO_VAL
54 #define VDDMEM_BO_VAL   CONFIG_SYS_SPL_VDDMEM_BO_VAL
55 #else
56 #define VDDMEM_BO_VAL   25
57 #endif
58
59 #ifdef CONFIG_SYS_SPL_BATT_BO_LEVEL
60 #if CONFIG_SYS_SPL_BATT_BO_LEVEL < 2400 || CONFIG_SYS_SPL_BATT_BO_LEVEL > 3640
61 #error CONFIG_SYS_SPL_BATT_BO_LEVEL out of range
62 #endif
63 #define BATT_BO_VAL     (((CONFIG_SYS_SPL_BATT_BO_LEVEL) - 2400) / 40)
64 #else
65 /* Brownout default at 3V */
66 #define BATT_BO_VAL     ((3000 - 2400) / 40)
67 #endif
68
69 #ifdef CONFIG_SYS_SPL_FIXED_BATT_SUPPLY
70 static const int fixed_batt_supply = 1;
71 #else
72 static const int fixed_batt_supply;
73 #endif
74
75 static struct mxs_power_regs *power_regs = (void *)MXS_POWER_BASE;
76
77 static void mxs_power_clock2xtal(void)
78 {
79         struct mxs_clkctrl_regs *clkctrl_regs =
80                 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
81
82         /* Set XTAL as CPU reference clock */
83         writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
84                 &clkctrl_regs->hw_clkctrl_clkseq_set);
85 }
86
87 static void mxs_power_clock2pll(void)
88 {
89         struct mxs_clkctrl_regs *clkctrl_regs =
90                 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
91
92         setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0,
93                         CLKCTRL_PLL0CTRL0_POWER);
94         early_delay(100);
95         setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq,
96                         CLKCTRL_CLKSEQ_BYPASS_CPU);
97 }
98
99 static int mxs_power_wait_rtc_stat(u32 mask)
100 {
101         int timeout = 5000; /* 3 ms according to i.MX28 Ref. Manual */
102         u32 val;
103         struct mxs_rtc_regs *rtc_regs = (void *)MXS_RTC_BASE;
104
105         while ((val = readl(&rtc_regs->hw_rtc_stat)) & mask) {
106                 early_delay(1);
107                 if (timeout-- < 0)
108                         break;
109         }
110         return !!(readl(&rtc_regs->hw_rtc_stat) & mask);
111 }
112
113 static int mxs_power_set_auto_restart(int on)
114 {
115         struct mxs_rtc_regs *rtc_regs = (void *)MXS_RTC_BASE;
116
117         /*
118          * Due to the hardware design bug of mx28 EVK-A
119          * we need to set the AUTO_RESTART bit.
120          */
121         if (mxs_power_wait_rtc_stat(RTC_STAT_STALE_REGS_PERSISTENT0))
122                 return 1;
123
124         if ((!(readl(&rtc_regs->hw_rtc_persistent0) &
125                                 RTC_PERSISTENT0_AUTO_RESTART) ^ !on) == 0)
126                 return 0;
127
128         if (mxs_power_wait_rtc_stat(RTC_STAT_NEW_REGS_PERSISTENT0))
129                 return 1;
130
131         clrsetbits_le32(&rtc_regs->hw_rtc_persistent0,
132                         !on * RTC_PERSISTENT0_AUTO_RESTART,
133                         !!on * RTC_PERSISTENT0_AUTO_RESTART);
134         if (mxs_power_wait_rtc_stat(RTC_STAT_NEW_REGS_PERSISTENT0))
135                 return 1;
136
137         return 0;
138 }
139
140 static void mxs_power_set_linreg(void)
141 {
142         /* Set linear regulator 25mV below switching converter */
143         clrsetbits_le32(&power_regs->hw_power_vdddctrl,
144                         POWER_VDDDCTRL_LINREG_OFFSET_MASK,
145                         POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
146
147         clrsetbits_le32(&power_regs->hw_power_vddactrl,
148                         POWER_VDDACTRL_LINREG_OFFSET_MASK,
149                         POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW);
150
151         clrsetbits_le32(&power_regs->hw_power_vddioctrl,
152                         POWER_VDDIOCTRL_LINREG_OFFSET_MASK,
153                         POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
154 }
155
156 static int mxs_get_batt_volt(void)
157 {
158         uint32_t volt = readl(&power_regs->hw_power_battmonitor);
159
160         volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
161         volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
162         volt *= 8;
163         return volt;
164 }
165
166 static int mxs_is_batt_ready(void)
167 {
168         return (mxs_get_batt_volt() >= 3600);
169 }
170
171 static int mxs_is_batt_good(void)
172 {
173         uint32_t volt = mxs_get_batt_volt();
174
175         if ((volt >= 2400) && (volt <= 4300))
176                 return 1;
177
178         clrsetbits_le32(&power_regs->hw_power_5vctrl,
179                 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
180                 0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
181         writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
182                 &power_regs->hw_power_5vctrl_clr);
183
184         clrsetbits_le32(&power_regs->hw_power_charge,
185                 POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
186                 POWER_CHARGE_STOP_ILIMIT_10MA | 0x3);
187
188         writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_clr);
189         writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
190                 &power_regs->hw_power_5vctrl_clr);
191
192         early_delay(500000);
193
194         volt = mxs_get_batt_volt();
195
196         if (volt >= 3500)
197                 return 0;
198
199         if (volt >= 2400)
200                 return 1;
201
202         writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
203                 &power_regs->hw_power_charge_clr);
204         writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
205
206         return 0;
207 }
208
209 static void mxs_power_setup_5v_detect(void)
210 {
211         /* Start 5V detection */
212         clrsetbits_le32(&power_regs->hw_power_5vctrl,
213                         POWER_5VCTRL_VBUSVALID_TRSH_MASK,
214                         POWER_5VCTRL_VBUSVALID_TRSH_4V4 |
215                         POWER_5VCTRL_PWRUP_VBUS_CMPS);
216 }
217
218 static void mxs_src_power_init(void)
219 {
220         /* Improve efficieny and reduce transient ripple */
221         writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST |
222                 POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set);
223
224         clrsetbits_le32(&power_regs->hw_power_dclimits,
225                         POWER_DCLIMITS_POSLIMIT_BUCK_MASK,
226                         0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET);
227
228         if (!fixed_batt_supply) {
229                 /* FIXME: This requires the LRADC to be set up! */
230                 setbits_le32(&power_regs->hw_power_battmonitor,
231                         POWER_BATTMONITOR_EN_BATADJ);
232         } else {
233                 clrbits_le32(&power_regs->hw_power_battmonitor,
234                         POWER_BATTMONITOR_EN_BATADJ);
235         }
236
237         /* Increase the RCSCALE level for quick DCDC response to dynamic load */
238         clrsetbits_le32(&power_regs->hw_power_loopctrl,
239                         POWER_LOOPCTRL_EN_RCSCALE_MASK,
240                         POWER_LOOPCTRL_RCSCALE_THRESH |
241                         POWER_LOOPCTRL_EN_RCSCALE_8X);
242
243         clrsetbits_le32(&power_regs->hw_power_minpwr,
244                         POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
245
246         if (!fixed_batt_supply) {
247                 /* 5V to battery handoff ... FIXME */
248                 setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
249                 early_delay(30);
250                 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
251         }
252 }
253
254 static void mxs_power_init_4p2_params(void)
255 {
256         /* Setup 4P2 parameters */
257         clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
258                 POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK,
259                 POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET));
260
261         clrsetbits_le32(&power_regs->hw_power_5vctrl,
262                 POWER_5VCTRL_HEADROOM_ADJ_MASK,
263                 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET);
264
265         clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
266                 POWER_DCDC4P2_DROPOUT_CTRL_MASK,
267                 POWER_DCDC4P2_DROPOUT_CTRL_100MV |
268                 POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL);
269
270         clrsetbits_le32(&power_regs->hw_power_5vctrl,
271                 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
272                 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
273 }
274
275 static void mxs_enable_4p2_dcdc_input(int xfer)
276 {
277         uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo;
278         uint32_t prev_5v_brnout, prev_5v_droop;
279
280         prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) &
281                                 POWER_5VCTRL_PWDN_5VBRNOUT;
282         prev_5v_droop = readl(&power_regs->hw_power_ctrl) &
283                                 POWER_CTRL_ENIRQ_VDD5V_DROOP;
284
285         clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
286         writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
287                 &power_regs->hw_power_reset);
288
289         clrbits_le32(&power_regs->hw_power_ctrl, POWER_CTRL_ENIRQ_VDD5V_DROOP);
290
291         if (xfer && (readl(&power_regs->hw_power_5vctrl) &
292                         POWER_5VCTRL_ENABLE_DCDC)) {
293                 return;
294         }
295
296         /*
297          * Recording orignal values that will be modified temporarlily
298          * to handle a chip bug. See chip errata for CQ ENGR00115837
299          */
300         tmp = readl(&power_regs->hw_power_5vctrl);
301         vbus_thresh = tmp & POWER_5VCTRL_VBUSVALID_TRSH_MASK;
302         vbus_5vdetect = tmp & POWER_5VCTRL_VBUSVALID_5VDETECT;
303
304         pwd_bo = readl(&power_regs->hw_power_minpwr) & POWER_MINPWR_PWD_BO;
305
306         /*
307          * Disable mechanisms that get erroneously tripped by when setting
308          * the DCDC4P2 EN_DCDC
309          */
310         clrbits_le32(&power_regs->hw_power_5vctrl,
311                 POWER_5VCTRL_VBUSVALID_5VDETECT |
312                 POWER_5VCTRL_VBUSVALID_TRSH_MASK);
313
314         writel(POWER_MINPWR_PWD_BO, &power_regs->hw_power_minpwr_set);
315
316         if (xfer) {
317                 setbits_le32(&power_regs->hw_power_5vctrl,
318                                 POWER_5VCTRL_DCDC_XFER);
319                 early_delay(20);
320                 clrbits_le32(&power_regs->hw_power_5vctrl,
321                                 POWER_5VCTRL_DCDC_XFER);
322
323                 setbits_le32(&power_regs->hw_power_5vctrl,
324                                 POWER_5VCTRL_ENABLE_DCDC);
325         } else {
326                 setbits_le32(&power_regs->hw_power_dcdc4p2,
327                                 POWER_DCDC4P2_ENABLE_DCDC);
328         }
329
330         early_delay(25);
331
332         clrsetbits_le32(&power_regs->hw_power_5vctrl,
333                         POWER_5VCTRL_VBUSVALID_TRSH_MASK, vbus_thresh);
334
335         if (vbus_5vdetect)
336                 writel(vbus_5vdetect, &power_regs->hw_power_5vctrl_set);
337
338         if (!pwd_bo)
339                 clrbits_le32(&power_regs->hw_power_minpwr, POWER_MINPWR_PWD_BO);
340
341         while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ)
342                 writel(POWER_CTRL_VBUS_VALID_IRQ,
343                         &power_regs->hw_power_ctrl_clr);
344
345         if (prev_5v_brnout) {
346                 writel(POWER_5VCTRL_PWDN_5VBRNOUT,
347                         &power_regs->hw_power_5vctrl_set);
348                 writel(POWER_RESET_UNLOCK_KEY,
349                         &power_regs->hw_power_reset);
350         } else {
351                 writel(POWER_5VCTRL_PWDN_5VBRNOUT,
352                         &power_regs->hw_power_5vctrl_clr);
353                 writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
354                         &power_regs->hw_power_reset);
355         }
356
357         while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VDD5V_DROOP_IRQ)
358                 writel(POWER_CTRL_VDD5V_DROOP_IRQ,
359                         &power_regs->hw_power_ctrl_clr);
360
361         if (prev_5v_droop)
362                 clrbits_le32(&power_regs->hw_power_ctrl,
363                                 POWER_CTRL_ENIRQ_VDD5V_DROOP);
364         else
365                 setbits_le32(&power_regs->hw_power_ctrl,
366                                 POWER_CTRL_ENIRQ_VDD5V_DROOP);
367 }
368
369 static void mxs_power_init_4p2_regulator(void)
370 {
371         uint32_t tmp, tmp2;
372
373         setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2);
374
375         writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set);
376
377         writel(POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
378                 &power_regs->hw_power_5vctrl_clr);
379         clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_TRG_MASK);
380
381         /* Power up the 4p2 rail and logic/control */
382         writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
383                 &power_regs->hw_power_5vctrl_clr);
384
385         /*
386          * Start charging up the 4p2 capacitor. We ramp of this charge
387          * gradually to avoid large inrush current from the 5V cable which can
388          * cause transients/problems
389          */
390         mxs_enable_4p2_dcdc_input(0);
391
392         if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
393                 /*
394                  * If we arrived here, we were unable to recover from mx23 chip
395                  * errata 5837. 4P2 is disabled and sufficient battery power is
396                  * not present. Exiting to not enable DCDC power during 5V
397                  * connected state.
398                  */
399                 clrbits_le32(&power_regs->hw_power_dcdc4p2,
400                         POWER_DCDC4P2_ENABLE_DCDC);
401                 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
402                         &power_regs->hw_power_5vctrl_set);
403                 hang();
404         }
405
406         /*
407          * Here we set the 4p2 brownout level to something very close to 4.2V.
408          * We then check the brownout status. If the brownout status is false,
409          * the voltage is already close to the target voltage of 4.2V so we
410          * can go ahead and set the 4P2 current limit to our max target limit.
411          * If the brownout status is true, we need to ramp us the current limit
412          * so that we don't cause large inrush current issues. We step up the
413          * current limit until the brownout status is false or until we've
414          * reached our maximum defined 4p2 current limit.
415          */
416         clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
417                         POWER_DCDC4P2_BO_MASK,
418                         22 << POWER_DCDC4P2_BO_OFFSET); /* 4.15V */
419
420         if (!(readl(&power_regs->hw_power_sts) & POWER_STS_DCDC_4P2_BO)) {
421                 setbits_le32(&power_regs->hw_power_5vctrl,
422                         0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
423         } else {
424                 tmp = (readl(&power_regs->hw_power_5vctrl) &
425                         POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK) >>
426                         POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
427                 while (tmp < 0x3f) {
428                         if (!(readl(&power_regs->hw_power_sts) &
429                                         POWER_STS_DCDC_4P2_BO)) {
430                                 tmp = readl(&power_regs->hw_power_5vctrl);
431                                 tmp |= POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
432                                 early_delay(100);
433                                 writel(tmp, &power_regs->hw_power_5vctrl);
434                                 break;
435                         } else {
436                                 tmp++;
437                                 tmp2 = readl(&power_regs->hw_power_5vctrl);
438                                 tmp2 &= ~POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
439                                 tmp2 |= tmp <<
440                                         POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
441                                 writel(tmp2, &power_regs->hw_power_5vctrl);
442                                 early_delay(100);
443                         }
444                 }
445         }
446
447         clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK);
448         writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
449 }
450
451 static void mxs_power_init_dcdc_4p2_source(void)
452 {
453         if (!(readl(&power_regs->hw_power_dcdc4p2) &
454                 POWER_DCDC4P2_ENABLE_DCDC)) {
455                 hang();
456         }
457
458         mxs_enable_4p2_dcdc_input(1);
459
460         if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
461                 clrbits_le32(&power_regs->hw_power_dcdc4p2,
462                         POWER_DCDC4P2_ENABLE_DCDC);
463                 writel(POWER_5VCTRL_ENABLE_DCDC,
464                         &power_regs->hw_power_5vctrl_clr);
465                 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
466                         &power_regs->hw_power_5vctrl_set);
467         }
468 }
469
470 static void mxs_power_enable_4p2(void)
471 {
472         uint32_t vdddctrl, vddactrl, vddioctrl;
473         uint32_t tmp;
474
475         vdddctrl = readl(&power_regs->hw_power_vdddctrl);
476         vddactrl = readl(&power_regs->hw_power_vddactrl);
477         vddioctrl = readl(&power_regs->hw_power_vddioctrl);
478
479         setbits_le32(&power_regs->hw_power_vdddctrl,
480                 POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
481                 POWER_VDDDCTRL_PWDN_BRNOUT);
482
483         setbits_le32(&power_regs->hw_power_vddactrl,
484                 POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG |
485                 POWER_VDDACTRL_PWDN_BRNOUT);
486
487         setbits_le32(&power_regs->hw_power_vddioctrl,
488                 POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT);
489
490         mxs_power_init_4p2_params();
491         mxs_power_init_4p2_regulator();
492
493         /* Shutdown battery (none present) */
494         if (!mxs_is_batt_ready()) {
495                 clrbits_le32(&power_regs->hw_power_dcdc4p2,
496                                 POWER_DCDC4P2_BO_MASK);
497                 writel(POWER_CTRL_DCDC4P2_BO_IRQ,
498                                 &power_regs->hw_power_ctrl_clr);
499                 writel(POWER_CTRL_ENIRQ_DCDC4P2_BO,
500                                 &power_regs->hw_power_ctrl_clr);
501         }
502
503         mxs_power_init_dcdc_4p2_source();
504
505         writel(vdddctrl, &power_regs->hw_power_vdddctrl);
506         early_delay(20);
507         writel(vddactrl, &power_regs->hw_power_vddactrl);
508         early_delay(20);
509         writel(vddioctrl, &power_regs->hw_power_vddioctrl);
510
511         /*
512          * Check if FET is enabled on either powerout and if so,
513          * disable load.
514          */
515         tmp = 0;
516         tmp |= !(readl(&power_regs->hw_power_vdddctrl) &
517                         POWER_VDDDCTRL_DISABLE_FET);
518         tmp |= !(readl(&power_regs->hw_power_vddactrl) &
519                         POWER_VDDACTRL_DISABLE_FET);
520         tmp |= !(readl(&power_regs->hw_power_vddioctrl) &
521                         POWER_VDDIOCTRL_DISABLE_FET);
522         if (tmp)
523                 writel(POWER_CHARGE_ENABLE_LOAD,
524                         &power_regs->hw_power_charge_clr);
525 }
526
527 static void mxs_boot_valid_5v(void)
528 {
529         /*
530          * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
531          * disconnect event. FIXME
532          */
533         writel(POWER_5VCTRL_VBUSVALID_5VDETECT,
534                 &power_regs->hw_power_5vctrl_set);
535
536         /* Configure polarity to check for 5V disconnection. */
537         writel(POWER_CTRL_POLARITY_VBUSVALID |
538                 POWER_CTRL_POLARITY_VDD5V_GT_VDDIO,
539                 &power_regs->hw_power_ctrl_clr);
540
541         writel(POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_VDD5V_GT_VDDIO_IRQ,
542                 &power_regs->hw_power_ctrl_clr);
543
544         mxs_power_enable_4p2();
545 }
546
547 static void mxs_powerdown(void)
548 {
549         writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset);
550         writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
551                 &power_regs->hw_power_reset);
552 }
553
554 static void mxs_batt_boot(void)
555 {
556         clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
557         clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC);
558
559         clrbits_le32(&power_regs->hw_power_dcdc4p2,
560                         POWER_DCDC4P2_ENABLE_DCDC | POWER_DCDC4P2_ENABLE_4P2);
561         writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_clr);
562
563         /* 5V to battery handoff. */
564         setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
565         early_delay(30);
566         clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
567
568         writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr);
569
570         clrsetbits_le32(&power_regs->hw_power_minpwr,
571                         POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
572
573         mxs_power_set_linreg();
574
575         clrbits_le32(&power_regs->hw_power_vdddctrl,
576                 POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG);
577
578         clrbits_le32(&power_regs->hw_power_vddactrl,
579                 POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG);
580
581         clrbits_le32(&power_regs->hw_power_vddioctrl,
582                 POWER_VDDIOCTRL_DISABLE_FET);
583
584         setbits_le32(&power_regs->hw_power_5vctrl,
585                 POWER_5VCTRL_PWD_CHARGE_4P2_MASK);
586
587         setbits_le32(&power_regs->hw_power_5vctrl,
588                 POWER_5VCTRL_ENABLE_DCDC);
589
590         clrsetbits_le32(&power_regs->hw_power_5vctrl,
591                 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
592                 0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
593 }
594
595 static void mxs_handle_5v_conflict(void)
596 {
597         uint32_t tmp;
598
599         setbits_le32(&power_regs->hw_power_vddioctrl,
600                         POWER_VDDIOCTRL_BO_OFFSET_MASK);
601
602         for (;;) {
603                 tmp = readl(&power_regs->hw_power_sts);
604
605                 if (tmp & POWER_STS_VDDIO_BO) {
606                         /*
607                          * VDDIO has a brownout, then the VDD5V_GT_VDDIO becomes
608                          * unreliable
609                          */
610                         mxs_powerdown();
611                         break;
612                 }
613
614                 if (tmp & POWER_STS_VDD5V_GT_VDDIO) {
615                         mxs_boot_valid_5v();
616                         break;
617                 } else {
618                         mxs_powerdown();
619                         break;
620                 }
621
622                 if (tmp & POWER_STS_PSWITCH_MASK) {
623                         mxs_batt_boot();
624                         break;
625                 }
626         }
627 }
628
629 static void mxs_5v_boot(void)
630 {
631         /*
632          * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID,
633          * but their implementation always returns 1 so we omit it here.
634          */
635         if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
636                 mxs_boot_valid_5v();
637                 return;
638         }
639
640         early_delay(1000);
641         if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
642                 mxs_boot_valid_5v();
643                 return;
644         }
645
646         mxs_handle_5v_conflict();
647 }
648
649 static void mxs_fixed_batt_boot(void)
650 {
651         writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
652
653         setbits_le32(&power_regs->hw_power_5vctrl,
654                 POWER_5VCTRL_PWDN_5VBRNOUT |
655                 POWER_5VCTRL_ENABLE_DCDC |
656                 POWER_5VCTRL_ILIMIT_EQ_ZERO |
657                 POWER_5VCTRL_PWDN_5VBRNOUT |
658                 POWER_5VCTRL_PWD_CHARGE_4P2_MASK);
659
660         writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
661
662         clrbits_le32(&power_regs->hw_power_vdddctrl,
663                 POWER_VDDDCTRL_DISABLE_FET |
664                 POWER_VDDDCTRL_ENABLE_LINREG |
665                 POWER_VDDDCTRL_DISABLE_STEPPING);
666
667         clrbits_le32(&power_regs->hw_power_vddactrl,
668                 POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG |
669                 POWER_VDDACTRL_DISABLE_STEPPING);
670
671         clrbits_le32(&power_regs->hw_power_vddioctrl,
672                 POWER_VDDIOCTRL_DISABLE_FET |
673                 POWER_VDDIOCTRL_DISABLE_STEPPING);
674
675         /* Stop 5V detection */
676         writel(POWER_5VCTRL_PWRUP_VBUS_CMPS,
677                 &power_regs->hw_power_5vctrl_clr);
678 }
679
680 static void mxs_init_batt_bo(void)
681 {
682         clrsetbits_le32(&power_regs->hw_power_battmonitor,
683                 POWER_BATTMONITOR_BRWNOUT_LVL_MASK,
684                 BATT_BO_VAL << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
685
686         writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr);
687         writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
688 }
689
690 static void mxs_switch_vddd_to_dcdc_source(void)
691 {
692         clrsetbits_le32(&power_regs->hw_power_vdddctrl,
693                 POWER_VDDDCTRL_LINREG_OFFSET_MASK,
694                 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
695
696         clrbits_le32(&power_regs->hw_power_vdddctrl,
697                 POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
698                 POWER_VDDDCTRL_DISABLE_STEPPING);
699 }
700
701 static void mxs_power_configure_power_source(void)
702 {
703         struct mxs_lradc_regs *lradc_regs =
704                 (struct mxs_lradc_regs *)MXS_LRADC_BASE;
705
706         mxs_src_power_init();
707
708         if (!fixed_batt_supply) {
709                 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
710                         if (mxs_is_batt_ready()) {
711                                 /* 5V source detected, good battery detected. */
712                                 mxs_batt_boot();
713                         } else {
714                                 if (!mxs_is_batt_good()) {
715                                         /* 5V source detected, bad battery detected. */
716                                         writel(LRADC_CONVERSION_AUTOMATIC,
717                                                 &lradc_regs->hw_lradc_conversion_clr);
718                                         clrbits_le32(&power_regs->hw_power_battmonitor,
719                                                 POWER_BATTMONITOR_BATT_VAL_MASK);
720                                 }
721                                 mxs_5v_boot();
722                         }
723                 } else {
724                         /* 5V not detected, booting from battery. */
725                         mxs_batt_boot();
726                 }
727         } else {
728                 mxs_fixed_batt_boot();
729         }
730
731         mxs_power_clock2pll();
732
733         mxs_init_batt_bo();
734
735         mxs_switch_vddd_to_dcdc_source();
736
737 #ifdef CONFIG_MX23
738         /* Fire up the VDDMEM LinReg now that we're all set. */
739         writel(POWER_VDDMEMCTRL_ENABLE_LINREG | POWER_VDDMEMCTRL_ENABLE_ILIMIT,
740                 &power_regs->hw_power_vddmemctrl);
741 #endif
742 }
743
744 static void mxs_enable_output_rail_protection(void)
745 {
746         writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
747                 POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr);
748
749         setbits_le32(&power_regs->hw_power_vdddctrl,
750                         POWER_VDDDCTRL_PWDN_BRNOUT);
751
752         setbits_le32(&power_regs->hw_power_vddactrl,
753                         POWER_VDDACTRL_PWDN_BRNOUT);
754
755         setbits_le32(&power_regs->hw_power_vddioctrl,
756                         POWER_VDDIOCTRL_PWDN_BRNOUT);
757 }
758
759 static int mxs_get_vddio_power_source_off(void)
760 {
761         uint32_t tmp;
762
763         if ((readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) &&
764                 !(readl(&power_regs->hw_power_5vctrl) &
765                         POWER_5VCTRL_ILIMIT_EQ_ZERO)) {
766
767                 tmp = readl(&power_regs->hw_power_vddioctrl);
768                 if (tmp & POWER_VDDIOCTRL_DISABLE_FET) {
769                         if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
770                                 POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) {
771                                 return 1;
772                         }
773                 }
774
775                 if (!(readl(&power_regs->hw_power_5vctrl) &
776                         POWER_5VCTRL_ENABLE_DCDC)) {
777                         if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
778                                 POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) {
779                                 return 1;
780                         }
781                 }
782         }
783
784         return 0;
785 }
786
787 static int mxs_get_vddd_power_source_off(void)
788 {
789         uint32_t tmp;
790
791         tmp = readl(&power_regs->hw_power_vdddctrl);
792         if (tmp & POWER_VDDDCTRL_DISABLE_FET) {
793                 if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
794                         POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
795                         return 1;
796                 }
797         }
798
799         if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
800                 if (!(readl(&power_regs->hw_power_5vctrl) &
801                         POWER_5VCTRL_ENABLE_DCDC)) {
802                         return 1;
803                 }
804         }
805
806         if (!(tmp & POWER_VDDDCTRL_ENABLE_LINREG)) {
807                 if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) ==
808                         POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW) {
809                         return 1;
810                 }
811         }
812
813         return 0;
814 }
815
816 static int mxs_get_vdda_power_source_off(void)
817 {
818         uint32_t tmp;
819
820         tmp = readl(&power_regs->hw_power_vddactrl);
821         if (tmp & POWER_VDDACTRL_DISABLE_FET) {
822                 if ((tmp & POWER_VDDACTRL_LINREG_OFFSET_MASK) ==
823                         POWER_VDDACTRL_LINREG_OFFSET_0STEPS) {
824                         return 1;
825                 }
826         }
827
828         if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
829                 if (!(readl(&power_regs->hw_power_5vctrl) &
830                         POWER_5VCTRL_ENABLE_DCDC)) {
831                         return 1;
832                 }
833         }
834
835         if (!(tmp & POWER_VDDACTRL_ENABLE_LINREG)) {
836                 if ((tmp & POWER_VDDACTRL_LINREG_OFFSET_MASK) ==
837                         POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW) {
838                         return 1;
839                 }
840         }
841
842         return 0;
843 }
844
845 struct mxs_vddx_cfg {
846         uint32_t                *reg;
847         uint8_t                 step_mV;
848         uint16_t                lowest_mV;
849         uint16_t                highest_mV;
850         int                     (*powered_by_linreg)(void);
851         uint32_t                trg_mask;
852         uint32_t                bo_irq;
853         uint32_t                bo_enirq;
854         uint32_t                bo_offset_mask;
855         uint32_t                bo_offset_offset;
856 };
857
858 #define POWER_REG(n)            &((struct mxs_power_regs *)MXS_POWER_BASE)->n
859
860 static const struct mxs_vddx_cfg mxs_vddio_cfg = {
861         .reg                    = POWER_REG(hw_power_vddioctrl),
862 #if defined(CONFIG_MX23)
863         .step_mV                = 25,
864 #else
865         .step_mV                = 50,
866 #endif
867         .lowest_mV              = 2800,
868         .highest_mV             = 3600,
869         .powered_by_linreg      = mxs_get_vddio_power_source_off,
870         .trg_mask               = POWER_VDDIOCTRL_TRG_MASK,
871         .bo_irq                 = POWER_CTRL_VDDIO_BO_IRQ,
872         .bo_enirq               = POWER_CTRL_ENIRQ_VDDIO_BO,
873         .bo_offset_mask         = POWER_VDDIOCTRL_BO_OFFSET_MASK,
874         .bo_offset_offset       = POWER_VDDIOCTRL_BO_OFFSET_OFFSET,
875 };
876
877 static const struct mxs_vddx_cfg mxs_vddd_cfg = {
878         .reg                    = POWER_REG(hw_power_vdddctrl),
879         .step_mV                = 25,
880         .lowest_mV              = 800,
881         .highest_mV             = 1575,
882         .powered_by_linreg      = mxs_get_vddd_power_source_off,
883         .trg_mask               = POWER_VDDDCTRL_TRG_MASK,
884         .bo_irq                 = POWER_CTRL_VDDD_BO_IRQ,
885         .bo_enirq               = POWER_CTRL_ENIRQ_VDDD_BO,
886         .bo_offset_mask         = POWER_VDDDCTRL_BO_OFFSET_MASK,
887         .bo_offset_offset       = POWER_VDDDCTRL_BO_OFFSET_OFFSET,
888 };
889
890 static const struct mxs_vddx_cfg mxs_vdda_cfg = {
891         .reg                    = POWER_REG(hw_power_vddactrl),
892         .step_mV                = 50,
893         .lowest_mV              = 2800,
894         .highest_mV             = 3600,
895         .powered_by_linreg      = mxs_get_vdda_power_source_off,
896         .trg_mask               = POWER_VDDACTRL_TRG_MASK,
897         .bo_irq                 = POWER_CTRL_VDDA_BO_IRQ,
898         .bo_enirq               = POWER_CTRL_ENIRQ_VDDA_BO,
899         .bo_offset_mask         = POWER_VDDACTRL_BO_OFFSET_MASK,
900         .bo_offset_offset       = POWER_VDDACTRL_BO_OFFSET_OFFSET,
901 };
902
903 #ifdef CONFIG_MX23
904 static const struct mxs_vddx_cfg mxs_vddmem_cfg = {
905         .reg                    = POWER_REG(hw_power_vddmemctrl),
906         .step_mV                = 50,
907         .lowest_mV              = 1500,
908         .highest_mV             = 1700,
909         .powered_by_linreg      = NULL,
910         .trg_mask               = POWER_VDDMEMCTRL_TRG_MASK,
911         .bo_irq                 = 0,
912         .bo_enirq               = 0,
913         .bo_offset_mask         = 0,
914         .bo_offset_offset       = 0,
915 };
916 #endif
917
918 static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
919                                 uint32_t new_target, uint32_t new_brownout)
920 {
921         uint32_t cur_target, diff, bo_int = 0;
922         int powered_by_linreg = 0;
923         int adjust_up;
924
925         if (new_target < cfg->lowest_mV)
926                 new_target = cfg->lowest_mV;
927         if (new_target > cfg->highest_mV)
928                 new_target = cfg->highest_mV;
929
930         new_brownout = DIV_ROUND(new_target - new_brownout, cfg->step_mV);
931
932         cur_target = readl(cfg->reg);
933         cur_target &= cfg->trg_mask;
934         cur_target *= cfg->step_mV;
935         cur_target += cfg->lowest_mV;
936
937         adjust_up = new_target > cur_target;
938         if (cfg->powered_by_linreg)
939                 powered_by_linreg = cfg->powered_by_linreg();
940
941         if (adjust_up && cfg->bo_irq) {
942                 if (powered_by_linreg) {
943                         bo_int = readl(cfg->reg);
944                         clrbits_le32(cfg->reg, cfg->bo_enirq);
945                 }
946                 setbits_le32(cfg->reg, cfg->bo_offset_mask);
947         }
948
949         do {
950                 if (abs(new_target - cur_target) > 100) {
951                         if (adjust_up)
952                                 diff = cur_target + 100;
953                         else
954                                 diff = cur_target - 100;
955                 } else {
956                         diff = new_target;
957                 }
958
959                 diff -= cfg->lowest_mV;
960                 diff /= cfg->step_mV;
961
962                 clrsetbits_le32(cfg->reg, cfg->trg_mask, diff);
963
964                 if (powered_by_linreg ||
965                         (readl(&power_regs->hw_power_sts) &
966                                 POWER_STS_VDD5V_GT_VDDIO)) {
967                         early_delay(500);
968                 } else {
969                         while (!(readl(&power_regs->hw_power_sts) &
970                                         POWER_STS_DC_OK)) {
971
972                         }
973                 }
974
975                 cur_target = readl(cfg->reg);
976                 cur_target &= cfg->trg_mask;
977                 cur_target *= cfg->step_mV;
978                 cur_target += cfg->lowest_mV;
979         } while (new_target > cur_target);
980
981         if (cfg->bo_irq) {
982                 if (adjust_up && powered_by_linreg) {
983                         writel(cfg->bo_irq, &power_regs->hw_power_ctrl_clr);
984                         if (bo_int & cfg->bo_enirq)
985                                 setbits_le32(cfg->reg, cfg->bo_enirq);
986                 }
987
988                 clrsetbits_le32(cfg->reg, cfg->bo_offset_mask,
989                                 new_brownout << cfg->bo_offset_offset);
990         }
991 }
992
993 static void mxs_setup_batt_detect(void)
994 {
995         mxs_lradc_init();
996         mxs_lradc_enable_batt_measurement();
997         early_delay(10);
998 }
999
1000 static void mxs_ungate_power(void)
1001 {
1002 #ifdef CONFIG_MX23
1003         writel(POWER_CTRL_CLKGATE, &power_regs->hw_power_ctrl_clr);
1004 #endif
1005 }
1006
1007 #ifdef CONFIG_CONFIG_MACH_MX28EVK
1008 #define auto_restart 1
1009 #else
1010 #define auto_restart 0
1011 #endif
1012
1013 void mxs_power_init(void)
1014 {
1015         mxs_ungate_power();
1016
1017         mxs_power_clock2xtal();
1018         if (mxs_power_set_auto_restart(auto_restart)) {
1019                 serial_puts("Inconsistent value in RTC_PERSISTENT0 register; power-on-reset required\n");
1020         }
1021         mxs_power_set_linreg();
1022
1023         if (!fixed_batt_supply) {
1024                 mxs_power_setup_5v_detect();
1025                 mxs_setup_batt_detect();
1026         }
1027
1028         mxs_power_configure_power_source();
1029         mxs_enable_output_rail_protection();
1030
1031         mxs_power_set_vddx(&mxs_vddio_cfg, VDDIO_VAL, VDDIO_BO_VAL);
1032         mxs_power_set_vddx(&mxs_vddd_cfg, VDDD_VAL, VDDD_BO_VAL);
1033         mxs_power_set_vddx(&mxs_vdda_cfg, VDDA_VAL, VDDA_BO_VAL);
1034 #ifdef CONFIG_MX23
1035         mxs_power_set_vddx(&mxs_vddmem_cfg, VDDMEM_VAL, VDDMEM_BO_VAL);
1036
1037         setbits_le32(&power_regs->hw_power_vddmemctrl,
1038                 POWER_VDDMEMCTRL_ENABLE_LINREG);
1039         early_delay(500);
1040         clrbits_le32(&power_regs->hw_power_vddmemctrl,
1041                 POWER_VDDMEMCTRL_ENABLE_ILIMIT);
1042 #else
1043         clrbits_le32(&power_regs->hw_power_vddmemctrl,
1044                 POWER_VDDMEMCTRL_ENABLE_LINREG);
1045 #endif
1046         writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
1047                 POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
1048                 POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ |
1049                 POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
1050         if (!fixed_batt_supply)
1051                 writel(POWER_5VCTRL_PWDN_5VBRNOUT,
1052                         &power_regs->hw_power_5vctrl_set);
1053 }
1054
1055 #ifdef  CONFIG_SPL_MXS_PSWITCH_WAIT
1056 void mxs_power_wait_pswitch(void)
1057 {
1058         while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK))
1059                 ;
1060 }
1061 #endif