aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-bsp/u-boot/u-boot-2012.04.01/0053-i.MX28-Add-battery-boot-components-to-SPL.patch
blob: 8da6d971d942f9ef30f49dc598b2e67b508a5ad5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
From 2e5adad8385127605c3ad3e3a006d65deeccde38 Mon Sep 17 00:00:00 2001
From: Marek Vasut <marek.vasut@gmail.com>
Date: Tue, 1 May 2012 11:09:51 +0000
Subject: [PATCH 53/56] i.MX28: Add battery boot components to SPL

Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Detlev Zundel <dzu@denx.de>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Stefano Babic <sbabic@denx.de>
Cc: Wolfgang Denk <wd@denx.de>
---
 arch/arm/cpu/arm926ejs/mx28/spl_power_init.c |  100 +++++++++++++++++++++++---
 1 file changed, 92 insertions(+), 8 deletions(-)

diff --git a/arch/arm/cpu/arm926ejs/mx28/spl_power_init.c b/arch/arm/cpu/arm926ejs/mx28/spl_power_init.c
index ac942b4..4b09b0c 100644
--- a/arch/arm/cpu/arm926ejs/mx28/spl_power_init.c
+++ b/arch/arm/cpu/arm926ejs/mx28/spl_power_init.c
@@ -45,11 +45,11 @@ void mx28_power_clock2pll(void)
 	struct mx28_clkctrl_regs *clkctrl_regs =
 		(struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
 
-	writel(CLKCTRL_PLL0CTRL0_POWER,
-		&clkctrl_regs->hw_clkctrl_pll0ctrl0_set);
+	setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0,
+			CLKCTRL_PLL0CTRL0_POWER);
 	early_delay(100);
-	writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
-		&clkctrl_regs->hw_clkctrl_clkseq_clr);
+	setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq,
+			CLKCTRL_CLKSEQ_BYPASS_CPU);
 }
 
 void mx28_power_clear_auto_restart(void)
@@ -455,9 +455,14 @@ void mx28_power_enable_4p2(void)
 	mx28_power_init_4p2_regulator();
 
 	/* Shutdown battery (none present) */
-	clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK);
-	writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
-	writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr);
+	if (!mx28_is_batt_ready()) {
+		clrbits_le32(&power_regs->hw_power_dcdc4p2,
+				POWER_DCDC4P2_BO_MASK);
+		writel(POWER_CTRL_DCDC4P2_BO_IRQ,
+				&power_regs->hw_power_ctrl_clr);
+		writel(POWER_CTRL_ENIRQ_DCDC4P2_BO,
+				&power_regs->hw_power_ctrl_clr);
+	}
 
 	mx28_power_init_dcdc_4p2_source();
 
@@ -515,6 +520,50 @@ void mx28_powerdown(void)
 		&power_regs->hw_power_reset);
 }
 
+void mx28_batt_boot(void)
+{
+	struct mx28_power_regs *power_regs =
+		(struct mx28_power_regs *)MXS_POWER_BASE;
+
+	clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
+	clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC);
+
+	clrbits_le32(&power_regs->hw_power_dcdc4p2,
+			POWER_DCDC4P2_ENABLE_DCDC | POWER_DCDC4P2_ENABLE_4P2);
+	writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_clr);
+
+	/* 5V to battery handoff. */
+	setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+	early_delay(30);
+	clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+
+	writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr);
+
+	clrsetbits_le32(&power_regs->hw_power_minpwr,
+			POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
+
+	mx28_power_set_linreg();
+
+	clrbits_le32(&power_regs->hw_power_vdddctrl,
+		POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG);
+
+	clrbits_le32(&power_regs->hw_power_vddactrl,
+		POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG);
+
+	clrbits_le32(&power_regs->hw_power_vddioctrl,
+		POWER_VDDIOCTRL_DISABLE_FET);
+
+	setbits_le32(&power_regs->hw_power_5vctrl,
+		POWER_5VCTRL_PWD_CHARGE_4P2_MASK);
+
+	setbits_le32(&power_regs->hw_power_5vctrl,
+		POWER_5VCTRL_ENABLE_DCDC);
+
+	clrsetbits_le32(&power_regs->hw_power_5vctrl,
+		POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
+		0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
+}
+
 void mx28_handle_5v_conflict(void)
 {
 	struct mx28_power_regs *power_regs =
@@ -539,6 +588,11 @@ void mx28_handle_5v_conflict(void)
 			mx28_powerdown();
 			break;
 		}
+
+		if (tmp & POWER_STS_PSWITCH_MASK) {
+			mx28_batt_boot();
+			break;
+		}
 	}
 }
 
@@ -595,12 +649,42 @@ void mx28_switch_vddd_to_dcdc_source(void)
 
 void mx28_power_configure_power_source(void)
 {
+	int batt_ready, batt_good;
+	struct mx28_power_regs *power_regs =
+		(struct mx28_power_regs *)MXS_POWER_BASE;
+	struct mx28_lradc_regs *lradc_regs =
+		(struct mx28_lradc_regs *)MXS_LRADC_BASE;
+
 	mx28_src_power_init();
 
-	mx28_5v_boot();
+	batt_ready = mx28_is_batt_ready();
+
+	if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+		batt_good = mx28_is_batt_good();
+		if (batt_ready) {
+			/* 5V source detected, good battery detected. */
+			mx28_batt_boot();
+		} else {
+			if (batt_good) {
+				/* 5V source detected, low battery detceted. */
+			} else {
+				/* 5V source detected, bad battery detected. */
+				writel(LRADC_CONVERSION_AUTOMATIC,
+					&lradc_regs->hw_lradc_conversion_clr);
+				clrbits_le32(&power_regs->hw_power_battmonitor,
+					POWER_BATTMONITOR_BATT_VAL_MASK);
+			}
+			mx28_5v_boot();
+		}
+	} else {
+		/* 5V not detected, booting from battery. */
+		mx28_batt_boot();
+	}
+
 	mx28_power_clock2pll();
 
 	mx28_init_batt_bo();
+
 	mx28_switch_vddd_to_dcdc_source();
 }
 
-- 
1.7.10