power_prep.c revision 1.3.6.3 1 1.3.6.2 tls /* $Id: power_prep.c,v 1.3.6.3 2014/08/20 00:02:56 tls Exp $ */
2 1.3.6.2 tls
3 1.3.6.2 tls /*
4 1.3.6.2 tls * Copyright (c) 2012 The NetBSD Foundation, Inc.
5 1.3.6.2 tls * All rights reserved.
6 1.3.6.2 tls *
7 1.3.6.2 tls * This code is derived from software contributed to The NetBSD Foundation
8 1.3.6.2 tls * by Petri Laakso.
9 1.3.6.2 tls *
10 1.3.6.2 tls * Redistribution and use in source and binary forms, with or without
11 1.3.6.2 tls * modification, are permitted provided that the following conditions
12 1.3.6.2 tls * are met:
13 1.3.6.2 tls * 1. Redistributions of source code must retain the above copyright
14 1.3.6.2 tls * notice, this list of conditions and the following disclaimer.
15 1.3.6.2 tls * 2. Redistributions in binary form must reproduce the above copyright
16 1.3.6.2 tls * notice, this list of conditions and the following disclaimer in the
17 1.3.6.2 tls * documentation and/or other materials provided with the distribution.
18 1.3.6.2 tls *
19 1.3.6.2 tls * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.3.6.2 tls * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.3.6.2 tls * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.3.6.2 tls * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.3.6.2 tls * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.3.6.2 tls * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.3.6.2 tls * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.3.6.2 tls * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.3.6.2 tls * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.3.6.2 tls * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.3.6.2 tls * POSSIBILITY OF SUCH DAMAGE.
30 1.3.6.2 tls */
31 1.3.6.2 tls
32 1.3.6.3 tls #include <sys/cdefs.h>
33 1.3.6.2 tls #include <sys/param.h>
34 1.3.6.2 tls #include <sys/types.h>
35 1.3.6.2 tls
36 1.3.6.2 tls #include <arm/imx/imx23_powerreg.h>
37 1.3.6.2 tls
38 1.3.6.3 tls #include <lib/libkern/libkern.h>
39 1.3.6.2 tls #include <lib/libsa/stand.h>
40 1.3.6.2 tls
41 1.3.6.2 tls #include "common.h"
42 1.3.6.2 tls
43 1.3.6.3 tls #define PWR_CTRL (HW_POWER_BASE + HW_POWER_CTRL)
44 1.3.6.3 tls #define PWR_CTRL_S (HW_POWER_BASE + HW_POWER_CTRL_SET)
45 1.3.6.3 tls #define PWR_CTRL_C (HW_POWER_BASE + HW_POWER_CTRL_CLR)
46 1.3.6.3 tls #define PWR_5VCTRL (HW_POWER_BASE + HW_POWER_5VCTRL)
47 1.3.6.3 tls #define PWR_5VCTRL_S (HW_POWER_BASE + HW_POWER_5VCTRL_SET)
48 1.3.6.3 tls #define PWR_5VCTRL_C (HW_POWER_BASE + HW_POWER_5VCTRL_CLR)
49 1.3.6.3 tls #define PWR_MINPWR (HW_POWER_BASE + HW_POWER_MINPWR)
50 1.3.6.3 tls #define PWR_MINPWR_S (HW_POWER_BASE + HW_POWER_MINPWR_SET)
51 1.3.6.3 tls #define PWR_MINPWR_C (HW_POWER_BASE + HW_POWER_MINPWR_CLR)
52 1.3.6.3 tls #define PWR_CHARGE (HW_POWER_BASE + HW_POWER_CHARGE)
53 1.3.6.3 tls #define PWR_CHARGE_S (HW_POWER_BASE + HW_POWER_CHARGE_SET)
54 1.3.6.3 tls #define PWR_CHARGE_C (HW_POWER_BASE + HW_POWER_CHARGE_CLR)
55 1.3.6.3 tls #define PWR_VDDDCTRL (HW_POWER_BASE + HW_POWER_VDDDCTRL)
56 1.3.6.3 tls #define PWR_VDDACTRL (HW_POWER_BASE + HW_POWER_VDDACTRL)
57 1.3.6.3 tls #define PWR_VDDIOCTRL (HW_POWER_BASE + HW_POWER_VDDIOCTRL)
58 1.3.6.3 tls #define PWR_VDDMEMCTRL (HW_POWER_BASE + HW_POWER_VDDMEMCTRL)
59 1.3.6.3 tls #define PWR_DCDC4P2 (HW_POWER_BASE + HW_POWER_DCDC4P2)
60 1.3.6.3 tls #define PWR_MISC (HW_POWER_BASE + HW_POWER_MISC)
61 1.3.6.3 tls #define PWR_DCLIMITS (HW_POWER_BASE + HW_POWER_DCLIMITS)
62 1.3.6.3 tls #define PWR_LOOPCTRL (HW_POWER_BASE + HW_POWER_LOOPCTRL)
63 1.3.6.3 tls #define PWR_LOOPCTRL_S (HW_POWER_BASE + HW_POWER_LOOPCTRL_SET)
64 1.3.6.3 tls #define PWR_LOOPCTRL_C (HW_POWER_BASE + HW_POWER_LOOPCTRL_CLR)
65 1.3.6.3 tls #define PWR_STATUS (HW_POWER_BASE + HW_POWER_STS)
66 1.3.6.3 tls #define PWR_SPEED (HW_POWER_BASE + HW_POWER_SPEED)
67 1.3.6.3 tls #define PWR_BATTMONITOR (HW_POWER_BASE + HW_POWER_BATTMONITOR)
68 1.3.6.3 tls #define PWR_RESET (HW_POWER_BASE + HW_POWER_RESET)
69 1.3.6.3 tls #define PWR_DEBUG (HW_POWER_BASE + HW_POWER_DEBUG)
70 1.3.6.3 tls #define PWR_SPECIAL (HW_POWER_BASE + HW_POWER_SPECIAL)
71 1.3.6.3 tls #define PWR_VERSION (HW_POWER_BASE + HW_POWER_VERSION)
72 1.3.6.3 tls
73 1.3.6.3 tls #define VBUSVALID_TRSH 5 /* 4.4V */
74 1.3.6.3 tls #define CHARGE_4P2_ILIMIT_MAX 0x3f
75 1.3.6.3 tls #define CMPTRIP 0x1f /* DCDC_4P2 pin >= 1.05 * BATTERY pin. */
76 1.3.6.3 tls #define DROPOUT_CTRL 0xa /* BO 100mV, DCDC selects higher. */
77 1.3.6.3 tls
78 1.3.6.3 tls void en_vbusvalid(void);
79 1.3.6.3 tls int vbusvalid(void);
80 1.3.6.3 tls void power_tune(void);
81 1.3.6.3 tls void en_4p2_reg(void);
82 1.3.6.3 tls void en_4p2_to_dcdc(void);
83 1.3.6.3 tls void power_vddd_from_dcdc(int, int);
84 1.3.6.3 tls void power_vdda_from_dcdc(int, int);
85 1.3.6.3 tls void power_vddio_from_dcdc(int, int);
86 1.3.6.3 tls void power_vddmem(int);
87 1.3.6.3 tls
88 1.3.6.3 tls /*
89 1.3.6.3 tls * Configure the DCDC control logic 5V detection to use VBUSVALID.
90 1.3.6.3 tls */
91 1.3.6.3 tls void
92 1.3.6.3 tls en_vbusvalid(void)
93 1.3.6.3 tls {
94 1.3.6.3 tls uint32_t tmp_r;
95 1.3.6.3 tls
96 1.3.6.3 tls tmp_r = REG_RD(PWR_5VCTRL);
97 1.3.6.3 tls tmp_r &= ~HW_POWER_5VCTRL_VBUSVALID_TRSH;
98 1.3.6.3 tls tmp_r |= __SHIFTIN(VBUSVALID_TRSH, HW_POWER_5VCTRL_VBUSVALID_TRSH);
99 1.3.6.3 tls REG_WR(PWR_5VCTRL, tmp_r);
100 1.3.6.3 tls
101 1.3.6.3 tls REG_WR(PWR_5VCTRL_S, HW_POWER_5VCTRL_PWRUP_VBUS_CMPS);
102 1.3.6.3 tls delay(1000);
103 1.3.6.3 tls
104 1.3.6.3 tls REG_WR(PWR_5VCTRL_S, HW_POWER_5VCTRL_VBUSVALID_5VDETECT);
105 1.3.6.3 tls
106 1.3.6.3 tls return;
107 1.3.6.3 tls }
108 1.3.6.3 tls /*
109 1.3.6.3 tls * Test VBUSVALID.
110 1.3.6.2 tls */
111 1.3.6.2 tls int
112 1.3.6.3 tls vbusvalid(void)
113 1.3.6.2 tls {
114 1.3.6.3 tls if (REG_RD(PWR_STATUS) & HW_POWER_STS_VBUSVALID)
115 1.3.6.3 tls return 1;
116 1.3.6.2 tls else
117 1.3.6.3 tls return 0;
118 1.3.6.2 tls }
119 1.3.6.2 tls /*
120 1.3.6.3 tls * Set various registers.
121 1.3.6.2 tls */
122 1.3.6.3 tls void
123 1.3.6.3 tls power_tune(void)
124 1.3.6.2 tls {
125 1.3.6.3 tls uint32_t tmp_r;
126 1.3.6.2 tls
127 1.3.6.3 tls REG_WR(PWR_LOOPCTRL_S, HW_POWER_LOOPCTRL_TOGGLE_DIF |
128 1.3.6.3 tls HW_POWER_LOOPCTRL_EN_CM_HYST |
129 1.3.6.3 tls HW_POWER_LOOPCTRL_EN_DF_HYST |
130 1.3.6.3 tls HW_POWER_LOOPCTRL_RCSCALE_THRESH |
131 1.3.6.3 tls __SHIFTIN(3, HW_POWER_LOOPCTRL_EN_RCSCALE));
132 1.3.6.3 tls
133 1.3.6.3 tls REG_WR(PWR_MINPWR_S, HW_POWER_MINPWR_DOUBLE_FETS);
134 1.3.6.3 tls
135 1.3.6.3 tls REG_WR(PWR_5VCTRL_S, __SHIFTIN(4, HW_POWER_5VCTRL_HEADROOM_ADJ));
136 1.3.6.3 tls
137 1.3.6.3 tls tmp_r = REG_RD(PWR_DCLIMITS);
138 1.3.6.3 tls tmp_r &= ~HW_POWER_DCLIMITS_POSLIMIT_BUCK;
139 1.3.6.3 tls tmp_r |= __SHIFTIN(0x30, HW_POWER_DCLIMITS_POSLIMIT_BUCK);
140 1.3.6.3 tls REG_WR(PWR_DCLIMITS, tmp_r);
141 1.3.6.2 tls
142 1.3.6.3 tls return;
143 1.3.6.3 tls }
144 1.3.6.3 tls /*
145 1.3.6.3 tls * AN3883.pdf 2.1.3.1 Enabling the 4P2 LinReg
146 1.3.6.3 tls */
147 1.3.6.3 tls void
148 1.3.6.3 tls en_4p2_reg(void)
149 1.3.6.3 tls {
150 1.3.6.3 tls uint32_t tmp_r;
151 1.3.6.3 tls int ilimit;
152 1.3.6.2 tls
153 1.3.6.3 tls /* TRG is 4.2V by default. */
154 1.3.6.3 tls tmp_r = REG_RD(PWR_DCDC4P2);
155 1.3.6.3 tls tmp_r |= HW_POWER_DCDC4P2_ENABLE_4P2;
156 1.3.6.3 tls REG_WR(PWR_DCDC4P2, tmp_r);
157 1.3.6.3 tls
158 1.3.6.3 tls REG_WR(PWR_CHARGE_S, HW_POWER_CHARGE_ENABLE_LOAD);
159 1.3.6.3 tls
160 1.3.6.3 tls /* Set CHARGE_4P2_ILIMIT to minimum. */
161 1.3.6.3 tls REG_WR(PWR_5VCTRL_C, HW_POWER_5VCTRL_CHARGE_4P2_ILIMIT);
162 1.3.6.3 tls REG_WR(PWR_5VCTRL_S, __SHIFTIN(1, HW_POWER_5VCTRL_CHARGE_4P2_ILIMIT));
163 1.3.6.3 tls
164 1.3.6.3 tls /* Power up 4.2V regulation circuit. */
165 1.3.6.3 tls REG_WR(PWR_5VCTRL_C, HW_POWER_5VCTRL_PWD_CHARGE_4P2);
166 1.3.6.3 tls
167 1.3.6.3 tls /* Ungate path from 4P2 reg to DCDC. */
168 1.3.6.3 tls tmp_r = REG_RD(PWR_DCDC4P2);
169 1.3.6.3 tls tmp_r |= HW_POWER_DCDC4P2_ENABLE_DCDC;
170 1.3.6.3 tls REG_WR(PWR_DCDC4P2, tmp_r);
171 1.3.6.3 tls
172 1.3.6.3 tls delay(10000);
173 1.3.6.3 tls
174 1.3.6.3 tls /* Charge 4P2 capacitance. */
175 1.3.6.3 tls tmp_r = REG_RD(PWR_5VCTRL);
176 1.3.6.3 tls for (ilimit = 2; ilimit <= CHARGE_4P2_ILIMIT_MAX; ilimit++) {
177 1.3.6.3 tls tmp_r &= ~HW_POWER_5VCTRL_CHARGE_4P2_ILIMIT;
178 1.3.6.3 tls tmp_r |= __SHIFTIN(ilimit, HW_POWER_5VCTRL_CHARGE_4P2_ILIMIT);
179 1.3.6.3 tls REG_WR(PWR_5VCTRL, tmp_r);
180 1.3.6.3 tls delay(10000);
181 1.3.6.2 tls }
182 1.3.6.2 tls
183 1.3.6.2 tls return;
184 1.3.6.2 tls }
185 1.3.6.2 tls
186 1.3.6.3 tls /*
187 1.3.6.3 tls * AN3883.pdf 2.1.3.3 Enabling 4P2 Input to DC-DC
188 1.3.6.3 tls */
189 1.3.6.3 tls void en_4p2_to_dcdc(void)
190 1.3.6.2 tls {
191 1.3.6.3 tls uint32_t tmp_r;
192 1.3.6.2 tls
193 1.3.6.3 tls tmp_r = REG_RD(PWR_DCDC4P2);
194 1.3.6.2 tls
195 1.3.6.3 tls tmp_r &= ~HW_POWER_DCDC4P2_CMPTRIP;
196 1.3.6.3 tls tmp_r |= __SHIFTIN(CMPTRIP, HW_POWER_DCDC4P2_CMPTRIP);
197 1.3.6.3 tls
198 1.3.6.3 tls tmp_r &= ~HW_POWER_DCDC4P2_DROPOUT_CTRL;
199 1.3.6.3 tls tmp_r |= __SHIFTIN(DROPOUT_CTRL, HW_POWER_DCDC4P2_DROPOUT_CTRL);
200 1.3.6.3 tls
201 1.3.6.3 tls REG_WR(PWR_DCDC4P2, tmp_r);
202 1.3.6.3 tls
203 1.3.6.3 tls REG_WR(PWR_5VCTRL_C, HW_POWER_5VCTRL_DCDC_XFER);
204 1.3.6.3 tls
205 1.3.6.3 tls /* Enabling DCDC triggers 5V brownout. */
206 1.3.6.3 tls REG_WR(PWR_5VCTRL_C, HW_POWER_5VCTRL_PWDN_5VBRNOUT);
207 1.3.6.3 tls REG_WR(PWR_5VCTRL_S, HW_POWER_5VCTRL_ENABLE_DCDC);
208 1.3.6.3 tls delay(10000);
209 1.3.6.3 tls REG_WR(PWR_5VCTRL_S, HW_POWER_5VCTRL_PWDN_5VBRNOUT);
210 1.3.6.3 tls
211 1.3.6.3 tls /* Now DCDC is using 4P2 so I can remove extra temporary load. */
212 1.3.6.3 tls REG_WR(PWR_CHARGE_C, HW_POWER_CHARGE_ENABLE_LOAD);
213 1.3.6.2 tls
214 1.3.6.2 tls return;
215 1.3.6.2 tls }
216 1.3.6.2 tls
217 1.3.6.3 tls /*
218 1.3.6.3 tls * Configure VDDD to source power from DCDC.
219 1.3.6.3 tls */
220 1.3.6.3 tls void
221 1.3.6.3 tls power_vddd_from_dcdc(int target, int brownout)
222 1.3.6.2 tls {
223 1.3.6.3 tls uint32_t tmp_r;
224 1.3.6.2 tls
225 1.3.6.3 tls /* BO_OFFSET must be withing 800mV - 1475mV */
226 1.3.6.3 tls if (brownout > 1475)
227 1.3.6.3 tls brownout = 1475;
228 1.3.6.3 tls else if (brownout < 800)
229 1.3.6.3 tls brownout = 800;
230 1.3.6.3 tls
231 1.3.6.3 tls
232 1.3.6.3 tls /* Set LINREG_OFFSET one step below TRG. */
233 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDDCTRL);
234 1.3.6.3 tls tmp_r &= ~HW_POWER_VDDDCTRL_LINREG_OFFSET;
235 1.3.6.3 tls tmp_r |= __SHIFTIN(2, HW_POWER_VDDDCTRL_LINREG_OFFSET);
236 1.3.6.3 tls REG_WR(PWR_VDDDCTRL, tmp_r);
237 1.3.6.3 tls delay(10000);
238 1.3.6.3 tls
239 1.3.6.3 tls /* Enable VDDD switching converter output. */
240 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDDCTRL);
241 1.3.6.3 tls tmp_r &= ~HW_POWER_VDDDCTRL_DISABLE_FET;
242 1.3.6.3 tls REG_WR(PWR_VDDDCTRL, tmp_r);
243 1.3.6.3 tls delay(10000);
244 1.3.6.3 tls
245 1.3.6.3 tls /* Disable linear regulator output. */
246 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDDCTRL);
247 1.3.6.3 tls tmp_r &= ~HW_POWER_VDDDCTRL_ENABLE_LINREG;
248 1.3.6.3 tls REG_WR(PWR_VDDDCTRL, tmp_r);
249 1.3.6.3 tls delay(10000);
250 1.3.6.3 tls
251 1.3.6.3 tls /* Set target voltage and brownout level. */
252 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDDCTRL);
253 1.3.6.3 tls tmp_r &= ~(HW_POWER_VDDDCTRL_BO_OFFSET | HW_POWER_VDDDCTRL_TRG);
254 1.3.6.3 tls tmp_r |= __SHIFTIN(((target - brownout) / 25),
255 1.3.6.3 tls HW_POWER_VDDDCTRL_BO_OFFSET);
256 1.3.6.3 tls tmp_r |= __SHIFTIN(((target - 800) / 25), HW_POWER_VDDDCTRL_TRG);
257 1.3.6.3 tls REG_WR(PWR_VDDDCTRL, tmp_r);
258 1.3.6.3 tls delay(10000);
259 1.3.6.2 tls
260 1.3.6.3 tls /* Enable PWDN_BRNOUT. */
261 1.3.6.3 tls REG_WR(PWR_CTRL_C, HW_POWER_CTRL_VDDD_BO_IRQ);
262 1.3.6.3 tls
263 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDDCTRL);
264 1.3.6.3 tls tmp_r |= HW_POWER_VDDDCTRL_PWDN_BRNOUT;
265 1.3.6.3 tls REG_WR(PWR_VDDDCTRL, tmp_r);
266 1.3.6.2 tls
267 1.3.6.2 tls return;
268 1.3.6.2 tls }
269 1.3.6.3 tls /*
270 1.3.6.3 tls * Configure VDDA to source power from DCDC.
271 1.3.6.3 tls */
272 1.3.6.3 tls void
273 1.3.6.3 tls power_vdda_from_dcdc(int target, int brownout)
274 1.3.6.3 tls {
275 1.3.6.3 tls uint32_t tmp_r;
276 1.3.6.3 tls
277 1.3.6.3 tls /* BO_OFFSET must be withing 1400mV - 2175mV */
278 1.3.6.3 tls if (brownout > 2275)
279 1.3.6.3 tls brownout = 2275;
280 1.3.6.3 tls else if (brownout < 1400)
281 1.3.6.3 tls brownout = 1400;
282 1.3.6.3 tls
283 1.3.6.3 tls
284 1.3.6.3 tls /* Set LINREG_OFFSET one step below TRG. */
285 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDACTRL);
286 1.3.6.3 tls tmp_r &= ~HW_POWER_VDDACTRL_LINREG_OFFSET;
287 1.3.6.3 tls tmp_r |= __SHIFTIN(2, HW_POWER_VDDACTRL_LINREG_OFFSET);
288 1.3.6.3 tls REG_WR(PWR_VDDACTRL, tmp_r);
289 1.3.6.3 tls delay(10000);
290 1.3.6.3 tls
291 1.3.6.3 tls /* Enable VDDA switching converter output. */
292 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDACTRL);
293 1.3.6.3 tls tmp_r &= ~HW_POWER_VDDACTRL_DISABLE_FET;
294 1.3.6.3 tls REG_WR(PWR_VDDACTRL, tmp_r);
295 1.3.6.3 tls delay(10000);
296 1.3.6.3 tls
297 1.3.6.3 tls /* Disable linear regulator output. */
298 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDACTRL);
299 1.3.6.3 tls tmp_r &= ~HW_POWER_VDDACTRL_ENABLE_LINREG;
300 1.3.6.3 tls REG_WR(PWR_VDDACTRL, tmp_r);
301 1.3.6.3 tls delay(10000);
302 1.3.6.3 tls
303 1.3.6.3 tls /* Set target voltage and brownout level. */
304 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDACTRL);
305 1.3.6.3 tls tmp_r &= ~(HW_POWER_VDDACTRL_BO_OFFSET | HW_POWER_VDDACTRL_TRG);
306 1.3.6.3 tls tmp_r |= __SHIFTIN(((target - brownout) / 25),
307 1.3.6.3 tls HW_POWER_VDDACTRL_BO_OFFSET);
308 1.3.6.3 tls tmp_r |= __SHIFTIN(((target - 1500) / 25), HW_POWER_VDDACTRL_TRG);
309 1.3.6.3 tls REG_WR(PWR_VDDACTRL, tmp_r);
310 1.3.6.3 tls delay(10000);
311 1.3.6.3 tls
312 1.3.6.3 tls /* Enable PWDN_BRNOUT. */
313 1.3.6.3 tls REG_WR(PWR_CTRL_C, HW_POWER_CTRL_VDDA_BO_IRQ);
314 1.3.6.3 tls
315 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDACTRL);
316 1.3.6.3 tls tmp_r |= HW_POWER_VDDACTRL_PWDN_BRNOUT;
317 1.3.6.3 tls REG_WR(PWR_VDDACTRL, tmp_r);
318 1.3.6.2 tls
319 1.3.6.3 tls return;
320 1.3.6.3 tls }
321 1.3.6.3 tls /*
322 1.3.6.3 tls * Configure VDDIO to source power from DCDC.
323 1.3.6.3 tls */
324 1.3.6.3 tls void
325 1.3.6.3 tls power_vddio_from_dcdc(int target, int brownout)
326 1.3.6.2 tls {
327 1.3.6.3 tls uint32_t tmp_r;
328 1.3.6.2 tls
329 1.3.6.3 tls /* BO_OFFSET must be withing 2700mV - 3475mV */
330 1.3.6.3 tls if (brownout > 3475)
331 1.3.6.3 tls brownout = 3475;
332 1.3.6.3 tls else if (brownout < 2700)
333 1.3.6.3 tls brownout = 2700;
334 1.3.6.3 tls
335 1.3.6.3 tls
336 1.3.6.3 tls /* Set LINREG_OFFSET one step below TRG. */
337 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDIOCTRL);
338 1.3.6.3 tls tmp_r &= ~HW_POWER_VDDIOCTRL_LINREG_OFFSET;
339 1.3.6.3 tls tmp_r |= __SHIFTIN(2, HW_POWER_VDDIOCTRL_LINREG_OFFSET);
340 1.3.6.3 tls REG_WR(PWR_VDDIOCTRL, tmp_r);
341 1.3.6.3 tls delay(10000);
342 1.3.6.3 tls
343 1.3.6.3 tls /* Enable VDDIO switching converter output. */
344 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDIOCTRL);
345 1.3.6.3 tls tmp_r &= ~HW_POWER_VDDIOCTRL_DISABLE_FET;
346 1.3.6.3 tls REG_WR(PWR_VDDIOCTRL, tmp_r);
347 1.3.6.3 tls delay(10000);
348 1.3.6.3 tls
349 1.3.6.3 tls /* Set target voltage and brownout level. */
350 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDIOCTRL);
351 1.3.6.3 tls tmp_r &= ~(HW_POWER_VDDIOCTRL_BO_OFFSET | HW_POWER_VDDIOCTRL_TRG);
352 1.3.6.3 tls tmp_r |= __SHIFTIN(((target - brownout) / 25),
353 1.3.6.3 tls HW_POWER_VDDIOCTRL_BO_OFFSET);
354 1.3.6.3 tls tmp_r |= __SHIFTIN(((target - 2800) / 25), HW_POWER_VDDIOCTRL_TRG);
355 1.3.6.3 tls REG_WR(PWR_VDDIOCTRL, tmp_r);
356 1.3.6.3 tls delay(10000);
357 1.3.6.2 tls
358 1.3.6.3 tls /* Enable PWDN_BRNOUT. */
359 1.3.6.3 tls REG_WR(PWR_CTRL_C, HW_POWER_CTRL_VDDIO_BO_IRQ);
360 1.3.6.3 tls
361 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDIOCTRL);
362 1.3.6.3 tls tmp_r |= HW_POWER_VDDIOCTRL_PWDN_BRNOUT;
363 1.3.6.3 tls REG_WR(PWR_VDDIOCTRL, tmp_r);
364 1.3.6.2 tls
365 1.3.6.2 tls return;
366 1.3.6.2 tls }
367 1.3.6.3 tls /*
368 1.3.6.3 tls * AN3883.pdf 2.3.1.2 Setting VDDMEM Target Voltage
369 1.3.6.3 tls */
370 1.3.6.3 tls void
371 1.3.6.3 tls power_vddmem(int target)
372 1.3.6.3 tls {
373 1.3.6.3 tls uint32_t tmp_r;
374 1.3.6.3 tls
375 1.3.6.3 tls /* Set target voltage. */
376 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDMEMCTRL);
377 1.3.6.3 tls tmp_r &= ~(HW_POWER_VDDMEMCTRL_TRG);
378 1.3.6.3 tls tmp_r |= __SHIFTIN(((target - 1700) / 50), HW_POWER_VDDMEMCTRL_TRG);
379 1.3.6.3 tls REG_WR(PWR_VDDMEMCTRL, tmp_r);
380 1.3.6.3 tls delay(10000);
381 1.3.6.3 tls
382 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDMEMCTRL);
383 1.3.6.3 tls tmp_r |= (HW_POWER_VDDMEMCTRL_PULLDOWN_ACTIVE |
384 1.3.6.3 tls HW_POWER_VDDMEMCTRL_ENABLE_ILIMIT |
385 1.3.6.3 tls HW_POWER_VDDMEMCTRL_ENABLE_LINREG);
386 1.3.6.3 tls REG_WR(PWR_VDDMEMCTRL, tmp_r);
387 1.3.6.3 tls
388 1.3.6.3 tls delay(1000);
389 1.3.6.3 tls
390 1.3.6.3 tls tmp_r = REG_RD(PWR_VDDMEMCTRL);
391 1.3.6.3 tls tmp_r &= ~(HW_POWER_VDDMEMCTRL_PULLDOWN_ACTIVE |
392 1.3.6.3 tls HW_POWER_VDDMEMCTRL_ENABLE_ILIMIT);
393 1.3.6.3 tls REG_WR(PWR_VDDMEMCTRL, tmp_r);
394 1.3.6.2 tls
395 1.3.6.2 tls return;
396 1.3.6.2 tls }
397