1 From 2e5adad8385127605c3ad3e3a006d65deeccde38 Mon Sep 17 00:00:00 2001
2 From: Marek Vasut <marek.vasut@gmail.com>
3 Date: Tue, 1 May 2012 11:09:51 +0000
4 Subject: [PATCH 53/56] i.MX28: Add battery boot components to SPL
6 Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
7 Cc: Detlev Zundel <dzu@denx.de>
8 Cc: Fabio Estevam <fabio.estevam@freescale.com>
9 Cc: Stefano Babic <sbabic@denx.de>
10 Cc: Wolfgang Denk <wd@denx.de>
12 arch/arm/cpu/arm926ejs/mx28/spl_power_init.c | 100 +++++++++++++++++++++++---
13 1 file changed, 92 insertions(+), 8 deletions(-)
15 diff --git a/arch/arm/cpu/arm926ejs/mx28/spl_power_init.c b/arch/arm/cpu/arm926ejs/mx28/spl_power_init.c
16 index ac942b4..4b09b0c 100644
17 --- a/arch/arm/cpu/arm926ejs/mx28/spl_power_init.c
18 +++ b/arch/arm/cpu/arm926ejs/mx28/spl_power_init.c
19 @@ -45,11 +45,11 @@ void mx28_power_clock2pll(void)
20 struct mx28_clkctrl_regs *clkctrl_regs =
21 (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
23 - writel(CLKCTRL_PLL0CTRL0_POWER,
24 - &clkctrl_regs->hw_clkctrl_pll0ctrl0_set);
25 + setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0,
26 + CLKCTRL_PLL0CTRL0_POWER);
28 - writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
29 - &clkctrl_regs->hw_clkctrl_clkseq_clr);
30 + setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq,
31 + CLKCTRL_CLKSEQ_BYPASS_CPU);
34 void mx28_power_clear_auto_restart(void)
35 @@ -455,9 +455,14 @@ void mx28_power_enable_4p2(void)
36 mx28_power_init_4p2_regulator();
38 /* Shutdown battery (none present) */
39 - clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK);
40 - writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
41 - writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr);
42 + if (!mx28_is_batt_ready()) {
43 + clrbits_le32(&power_regs->hw_power_dcdc4p2,
44 + POWER_DCDC4P2_BO_MASK);
45 + writel(POWER_CTRL_DCDC4P2_BO_IRQ,
46 + &power_regs->hw_power_ctrl_clr);
47 + writel(POWER_CTRL_ENIRQ_DCDC4P2_BO,
48 + &power_regs->hw_power_ctrl_clr);
51 mx28_power_init_dcdc_4p2_source();
53 @@ -515,6 +520,50 @@ void mx28_powerdown(void)
54 &power_regs->hw_power_reset);
57 +void mx28_batt_boot(void)
59 + struct mx28_power_regs *power_regs =
60 + (struct mx28_power_regs *)MXS_POWER_BASE;
62 + clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
63 + clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC);
65 + clrbits_le32(&power_regs->hw_power_dcdc4p2,
66 + POWER_DCDC4P2_ENABLE_DCDC | POWER_DCDC4P2_ENABLE_4P2);
67 + writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_clr);
69 + /* 5V to battery handoff. */
70 + setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
72 + clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
74 + writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr);
76 + clrsetbits_le32(&power_regs->hw_power_minpwr,
77 + POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
79 + mx28_power_set_linreg();
81 + clrbits_le32(&power_regs->hw_power_vdddctrl,
82 + POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG);
84 + clrbits_le32(&power_regs->hw_power_vddactrl,
85 + POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG);
87 + clrbits_le32(&power_regs->hw_power_vddioctrl,
88 + POWER_VDDIOCTRL_DISABLE_FET);
90 + setbits_le32(&power_regs->hw_power_5vctrl,
91 + POWER_5VCTRL_PWD_CHARGE_4P2_MASK);
93 + setbits_le32(&power_regs->hw_power_5vctrl,
94 + POWER_5VCTRL_ENABLE_DCDC);
96 + clrsetbits_le32(&power_regs->hw_power_5vctrl,
97 + POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
98 + 0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
101 void mx28_handle_5v_conflict(void)
103 struct mx28_power_regs *power_regs =
104 @@ -539,6 +588,11 @@ void mx28_handle_5v_conflict(void)
109 + if (tmp & POWER_STS_PSWITCH_MASK) {
116 @@ -595,12 +649,42 @@ void mx28_switch_vddd_to_dcdc_source(void)
118 void mx28_power_configure_power_source(void)
120 + int batt_ready, batt_good;
121 + struct mx28_power_regs *power_regs =
122 + (struct mx28_power_regs *)MXS_POWER_BASE;
123 + struct mx28_lradc_regs *lradc_regs =
124 + (struct mx28_lradc_regs *)MXS_LRADC_BASE;
126 mx28_src_power_init();
129 + batt_ready = mx28_is_batt_ready();
131 + if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
132 + batt_good = mx28_is_batt_good();
134 + /* 5V source detected, good battery detected. */
138 + /* 5V source detected, low battery detceted. */
140 + /* 5V source detected, bad battery detected. */
141 + writel(LRADC_CONVERSION_AUTOMATIC,
142 + &lradc_regs->hw_lradc_conversion_clr);
143 + clrbits_le32(&power_regs->hw_power_battmonitor,
144 + POWER_BATTMONITOR_BATT_VAL_MASK);
149 + /* 5V not detected, booting from battery. */
153 mx28_power_clock2pll();
157 mx28_switch_vddd_to_dcdc_source();