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