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