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