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 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { 665 batt_ready = mxs_is_batt_ready(); 666 if (batt_ready) { 667 /* 5V source detected, good battery detected. */ 668 mxs_batt_boot(); 669 } else { 670 batt_good = mxs_is_batt_good(); 671 if (!batt_good) { 672 /* 5V source detected, bad battery detected. */ 673 writel(LRADC_CONVERSION_AUTOMATIC, 674 &lradc_regs->hw_lradc_conversion_clr); 675 clrbits_le32(&power_regs->hw_power_battmonitor, 676 POWER_BATTMONITOR_BATT_VAL_MASK); 677 } 678 mxs_5v_boot(); 679 } 680 } else { 681 /* 5V not detected, booting from battery. */ 682 mxs_batt_boot(); 683 } 684 685 mxs_power_clock2pll(); 686 687 mxs_init_batt_bo(); 688 689 mxs_switch_vddd_to_dcdc_source(); 690 } 691 692 void mxs_enable_output_rail_protection(void) 693 { 694 struct mxs_power_regs *power_regs = 695 (struct mxs_power_regs *)MXS_POWER_BASE; 696 697 writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | 698 POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr); 699 700 setbits_le32(&power_regs->hw_power_vdddctrl, 701 POWER_VDDDCTRL_PWDN_BRNOUT); 702 703 setbits_le32(&power_regs->hw_power_vddactrl, 704 POWER_VDDACTRL_PWDN_BRNOUT); 705 706 setbits_le32(&power_regs->hw_power_vddioctrl, 707 POWER_VDDIOCTRL_PWDN_BRNOUT); 708 } 709 710 int mxs_get_vddio_power_source_off(void) 711 { 712 struct mxs_power_regs *power_regs = 713 (struct mxs_power_regs *)MXS_POWER_BASE; 714 uint32_t tmp; 715 716 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { 717 tmp = readl(&power_regs->hw_power_vddioctrl); 718 if (tmp & POWER_VDDIOCTRL_DISABLE_FET) { 719 if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) == 720 POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) { 721 return 1; 722 } 723 } 724 725 if (!(readl(&power_regs->hw_power_5vctrl) & 726 POWER_5VCTRL_ENABLE_DCDC)) { 727 if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) == 728 POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) { 729 return 1; 730 } 731 } 732 } 733 734 return 0; 735 736 } 737 738 int mxs_get_vddd_power_source_off(void) 739 { 740 struct mxs_power_regs *power_regs = 741 (struct mxs_power_regs *)MXS_POWER_BASE; 742 uint32_t tmp; 743 744 tmp = readl(&power_regs->hw_power_vdddctrl); 745 if (tmp & POWER_VDDDCTRL_DISABLE_FET) { 746 if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) == 747 POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) { 748 return 1; 749 } 750 } 751 752 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { 753 if (!(readl(&power_regs->hw_power_5vctrl) & 754 POWER_5VCTRL_ENABLE_DCDC)) { 755 return 1; 756 } 757 } 758 759 if (!(tmp & POWER_VDDDCTRL_ENABLE_LINREG)) { 760 if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) == 761 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW) { 762 return 1; 763 } 764 } 765 766 return 0; 767 } 768 769 void mxs_power_set_vddio(uint32_t new_target, uint32_t new_brownout) 770 { 771 struct mxs_power_regs *power_regs = 772 (struct mxs_power_regs *)MXS_POWER_BASE; 773 uint32_t cur_target, diff, bo_int = 0; 774 uint32_t powered_by_linreg = 0; 775 776 new_brownout = (new_target - new_brownout + 25) / 50; 777 778 cur_target = readl(&power_regs->hw_power_vddioctrl); 779 cur_target &= POWER_VDDIOCTRL_TRG_MASK; 780 cur_target *= 50; /* 50 mV step*/ 781 cur_target += 2800; /* 2800 mV lowest */ 782 783 powered_by_linreg = mxs_get_vddio_power_source_off(); 784 if (new_target > cur_target) { 785 786 if (powered_by_linreg) { 787 bo_int = readl(&power_regs->hw_power_vddioctrl); 788 clrbits_le32(&power_regs->hw_power_vddioctrl, 789 POWER_CTRL_ENIRQ_VDDIO_BO); 790 } 791 792 setbits_le32(&power_regs->hw_power_vddioctrl, 793 POWER_VDDIOCTRL_BO_OFFSET_MASK); 794 do { 795 if (new_target - cur_target > 100) 796 diff = cur_target + 100; 797 else 798 diff = new_target; 799 800 diff -= 2800; 801 diff /= 50; 802 803 clrsetbits_le32(&power_regs->hw_power_vddioctrl, 804 POWER_VDDIOCTRL_TRG_MASK, diff); 805 806 if (powered_by_linreg || 807 (readl(&power_regs->hw_power_sts) & 808 POWER_STS_VDD5V_GT_VDDIO)) 809 early_delay(500); 810 else { 811 while (!(readl(&power_regs->hw_power_sts) & 812 POWER_STS_DC_OK)) 813 ; 814 815 } 816 817 cur_target = readl(&power_regs->hw_power_vddioctrl); 818 cur_target &= POWER_VDDIOCTRL_TRG_MASK; 819 cur_target *= 50; /* 50 mV step*/ 820 cur_target += 2800; /* 2800 mV lowest */ 821 } while (new_target > cur_target); 822 823 if (powered_by_linreg) { 824 writel(POWER_CTRL_VDDIO_BO_IRQ, 825 &power_regs->hw_power_ctrl_clr); 826 if (bo_int & POWER_CTRL_ENIRQ_VDDIO_BO) 827 setbits_le32(&power_regs->hw_power_vddioctrl, 828 POWER_CTRL_ENIRQ_VDDIO_BO); 829 } 830 } else { 831 do { 832 if (cur_target - new_target > 100) 833 diff = cur_target - 100; 834 else 835 diff = new_target; 836 837 diff -= 2800; 838 diff /= 50; 839 840 clrsetbits_le32(&power_regs->hw_power_vddioctrl, 841 POWER_VDDIOCTRL_TRG_MASK, diff); 842 843 if (powered_by_linreg || 844 (readl(&power_regs->hw_power_sts) & 845 POWER_STS_VDD5V_GT_VDDIO)) 846 early_delay(500); 847 else { 848 while (!(readl(&power_regs->hw_power_sts) & 849 POWER_STS_DC_OK)) 850 ; 851 852 } 853 854 cur_target = readl(&power_regs->hw_power_vddioctrl); 855 cur_target &= POWER_VDDIOCTRL_TRG_MASK; 856 cur_target *= 50; /* 50 mV step*/ 857 cur_target += 2800; /* 2800 mV lowest */ 858 } while (new_target < cur_target); 859 } 860 861 clrsetbits_le32(&power_regs->hw_power_vddioctrl, 862 POWER_VDDIOCTRL_BO_OFFSET_MASK, 863 new_brownout << POWER_VDDIOCTRL_BO_OFFSET_OFFSET); 864 } 865 866 void mxs_power_set_vddd(uint32_t new_target, uint32_t new_brownout) 867 { 868 struct mxs_power_regs *power_regs = 869 (struct mxs_power_regs *)MXS_POWER_BASE; 870 uint32_t cur_target, diff, bo_int = 0; 871 uint32_t powered_by_linreg = 0; 872 873 new_brownout = (new_target - new_brownout + 12) / 25; 874 875 cur_target = readl(&power_regs->hw_power_vdddctrl); 876 cur_target &= POWER_VDDDCTRL_TRG_MASK; 877 cur_target *= 25; /* 25 mV step*/ 878 cur_target += 800; /* 800 mV lowest */ 879 880 powered_by_linreg = mxs_get_vddd_power_source_off(); 881 if (new_target > cur_target) { 882 if (powered_by_linreg) { 883 bo_int = readl(&power_regs->hw_power_vdddctrl); 884 clrbits_le32(&power_regs->hw_power_vdddctrl, 885 POWER_CTRL_ENIRQ_VDDD_BO); 886 } 887 888 setbits_le32(&power_regs->hw_power_vdddctrl, 889 POWER_VDDDCTRL_BO_OFFSET_MASK); 890 891 do { 892 if (new_target - cur_target > 100) 893 diff = cur_target + 100; 894 else 895 diff = new_target; 896 897 diff -= 800; 898 diff /= 25; 899 900 clrsetbits_le32(&power_regs->hw_power_vdddctrl, 901 POWER_VDDDCTRL_TRG_MASK, diff); 902 903 if (powered_by_linreg || 904 (readl(&power_regs->hw_power_sts) & 905 POWER_STS_VDD5V_GT_VDDIO)) 906 early_delay(500); 907 else { 908 while (!(readl(&power_regs->hw_power_sts) & 909 POWER_STS_DC_OK)) 910 ; 911 912 } 913 914 cur_target = readl(&power_regs->hw_power_vdddctrl); 915 cur_target &= POWER_VDDDCTRL_TRG_MASK; 916 cur_target *= 25; /* 25 mV step*/ 917 cur_target += 800; /* 800 mV lowest */ 918 } while (new_target > cur_target); 919 920 if (powered_by_linreg) { 921 writel(POWER_CTRL_VDDD_BO_IRQ, 922 &power_regs->hw_power_ctrl_clr); 923 if (bo_int & POWER_CTRL_ENIRQ_VDDD_BO) 924 setbits_le32(&power_regs->hw_power_vdddctrl, 925 POWER_CTRL_ENIRQ_VDDD_BO); 926 } 927 } else { 928 do { 929 if (cur_target - new_target > 100) 930 diff = cur_target - 100; 931 else 932 diff = new_target; 933 934 diff -= 800; 935 diff /= 25; 936 937 clrsetbits_le32(&power_regs->hw_power_vdddctrl, 938 POWER_VDDDCTRL_TRG_MASK, diff); 939 940 if (powered_by_linreg || 941 (readl(&power_regs->hw_power_sts) & 942 POWER_STS_VDD5V_GT_VDDIO)) 943 early_delay(500); 944 else { 945 while (!(readl(&power_regs->hw_power_sts) & 946 POWER_STS_DC_OK)) 947 ; 948 949 } 950 951 cur_target = readl(&power_regs->hw_power_vdddctrl); 952 cur_target &= POWER_VDDDCTRL_TRG_MASK; 953 cur_target *= 25; /* 25 mV step*/ 954 cur_target += 800; /* 800 mV lowest */ 955 } while (new_target < cur_target); 956 } 957 958 clrsetbits_le32(&power_regs->hw_power_vdddctrl, 959 POWER_VDDDCTRL_BO_OFFSET_MASK, 960 new_brownout << POWER_VDDDCTRL_BO_OFFSET_OFFSET); 961 } 962 963 void mxs_setup_batt_detect(void) 964 { 965 mxs_lradc_init(); 966 mxs_lradc_enable_batt_measurement(); 967 early_delay(10); 968 } 969 970 void mxs_power_init(void) 971 { 972 struct mxs_power_regs *power_regs = 973 (struct mxs_power_regs *)MXS_POWER_BASE; 974 975 mxs_power_clock2xtal(); 976 mxs_power_clear_auto_restart(); 977 mxs_power_set_linreg(); 978 mxs_power_setup_5v_detect(); 979 980 mxs_setup_batt_detect(); 981 982 mxs_power_configure_power_source(); 983 mxs_enable_output_rail_protection(); 984 985 mxs_power_set_vddio(3300, 3150); 986 987 mxs_power_set_vddd(1350, 1200); 988 989 writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | 990 POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ | 991 POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ | 992 POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr); 993 994 writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set); 995 996 early_delay(1000); 997 } 998 999 #ifdef CONFIG_SPL_MX28_PSWITCH_WAIT 1000 void mxs_power_wait_pswitch(void) 1001 { 1002 struct mxs_power_regs *power_regs = 1003 (struct mxs_power_regs *)MXS_POWER_BASE; 1004 1005 while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK)) 1006 ; 1007 } 1008 #endif 1009