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