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