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