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 #ifdef CONFIG_SYS_MXS_VDD5V_ONLY 18 #define DCDC4P2_DROPOUT_CONFIG POWER_DCDC4P2_DROPOUT_CTRL_100MV | \ 19 POWER_DCDC4P2_DROPOUT_CTRL_SRC_4P2 20 #else 21 #define DCDC4P2_DROPOUT_CONFIG POWER_DCDC4P2_DROPOUT_CTRL_100MV | \ 22 POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL 23 #endif 24 /** 25 * mxs_power_clock2xtal() - Switch CPU core clock source to 24MHz XTAL 26 * 27 * This function switches the CPU core clock from PLL to 24MHz XTAL 28 * oscilator. This is necessary if the PLL is being reconfigured to 29 * prevent crash of the CPU core. 30 */ 31 static void mxs_power_clock2xtal(void) 32 { 33 struct mxs_clkctrl_regs *clkctrl_regs = 34 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; 35 36 debug("SPL: Switching CPU clock to 24MHz XTAL\n"); 37 38 /* Set XTAL as CPU reference clock */ 39 writel(CLKCTRL_CLKSEQ_BYPASS_CPU, 40 &clkctrl_regs->hw_clkctrl_clkseq_set); 41 } 42 43 /** 44 * mxs_power_clock2pll() - Switch CPU core clock source to PLL 45 * 46 * This function switches the CPU core clock from 24MHz XTAL oscilator 47 * to PLL. This can only be called once the PLL has re-locked and once 48 * the PLL is stable after reconfiguration. 49 */ 50 static void mxs_power_clock2pll(void) 51 { 52 struct mxs_clkctrl_regs *clkctrl_regs = 53 (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; 54 55 debug("SPL: Switching CPU core clock source to PLL\n"); 56 57 /* 58 * TODO: Are we really? It looks like we turn on PLL0, but we then 59 * set the CLKCTRL_CLKSEQ_BYPASS_CPU bit of the (which was already 60 * set by mxs_power_clock2xtal()). Clearing this bit here seems to 61 * introduce some instability (causing the CPU core to hang). Maybe 62 * we aren't giving PLL0 enough time to stabilise? 63 */ 64 setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0, 65 CLKCTRL_PLL0CTRL0_POWER); 66 early_delay(100); 67 68 /* 69 * TODO: Should the PLL0 FORCE_LOCK bit be set here followed be a 70 * wait on the PLL0 LOCK bit? 71 */ 72 setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq, 73 CLKCTRL_CLKSEQ_BYPASS_CPU); 74 } 75 76 /** 77 * mxs_power_set_auto_restart() - Set the auto-restart bit 78 * 79 * This function ungates the RTC block and sets the AUTO_RESTART 80 * bit to work around a design bug on MX28EVK Rev. A . 81 */ 82 83 static void mxs_power_set_auto_restart(void) 84 { 85 struct mxs_rtc_regs *rtc_regs = 86 (struct mxs_rtc_regs *)MXS_RTC_BASE; 87 88 debug("SPL: Setting auto-restart bit\n"); 89 90 writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr); 91 while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST) 92 ; 93 94 writel(RTC_CTRL_CLKGATE, &rtc_regs->hw_rtc_ctrl_clr); 95 while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE) 96 ; 97 98 /* Do nothing if flag already set */ 99 if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART) 100 return; 101 102 while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK) 103 ; 104 105 setbits_le32(&rtc_regs->hw_rtc_persistent0, 106 RTC_PERSISTENT0_AUTO_RESTART); 107 writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_set); 108 writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_clr); 109 while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK) 110 ; 111 while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK) 112 ; 113 } 114 115 /** 116 * mxs_power_set_linreg() - Set linear regulators 25mV below DC-DC converter 117 * 118 * This function configures the VDDIO, VDDA and VDDD linear regulators output 119 * to be 25mV below the VDDIO, VDDA and VDDD output from the DC-DC switching 120 * converter. This is the recommended setting for the case where we use both 121 * linear regulators and DC-DC converter to power the VDDIO rail. 122 */ 123 static void mxs_power_set_linreg(void) 124 { 125 struct mxs_power_regs *power_regs = 126 (struct mxs_power_regs *)MXS_POWER_BASE; 127 128 /* Set linear regulator 25mV below switching converter */ 129 debug("SPL: Setting VDDD 25mV below DC-DC converters\n"); 130 clrsetbits_le32(&power_regs->hw_power_vdddctrl, 131 POWER_VDDDCTRL_LINREG_OFFSET_MASK, 132 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW); 133 134 debug("SPL: Setting VDDA 25mV below DC-DC converters\n"); 135 clrsetbits_le32(&power_regs->hw_power_vddactrl, 136 POWER_VDDACTRL_LINREG_OFFSET_MASK, 137 POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW); 138 139 debug("SPL: Setting VDDIO 25mV below DC-DC converters\n"); 140 clrsetbits_le32(&power_regs->hw_power_vddioctrl, 141 POWER_VDDIOCTRL_LINREG_OFFSET_MASK, 142 POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW); 143 } 144 145 /** 146 * mxs_get_batt_volt() - Measure battery input voltage 147 * 148 * This function retrieves the battery input voltage and returns it. 149 */ 150 static int mxs_get_batt_volt(void) 151 { 152 struct mxs_power_regs *power_regs = 153 (struct mxs_power_regs *)MXS_POWER_BASE; 154 uint32_t volt = readl(&power_regs->hw_power_battmonitor); 155 volt &= POWER_BATTMONITOR_BATT_VAL_MASK; 156 volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET; 157 volt *= 8; 158 159 debug("SPL: Battery Voltage = %dmV\n", volt); 160 return volt; 161 } 162 163 /** 164 * mxs_is_batt_ready() - Test if the battery provides enough voltage to boot 165 * 166 * This function checks if the battery input voltage is higher than 3.6V and 167 * therefore allows the system to successfully boot using this power source. 168 */ 169 static int mxs_is_batt_ready(void) 170 { 171 return (mxs_get_batt_volt() >= 3600); 172 } 173 174 /** 175 * mxs_is_batt_good() - Test if battery is operational at all 176 * 177 * This function starts recharging the battery and tests if the input current 178 * provided by the 5V input recharging the battery is also sufficient to power 179 * the DC-DC converter. 180 */ 181 static int mxs_is_batt_good(void) 182 { 183 struct mxs_power_regs *power_regs = 184 (struct mxs_power_regs *)MXS_POWER_BASE; 185 uint32_t volt = mxs_get_batt_volt(); 186 187 if ((volt >= 2400) && (volt <= 4300)) { 188 debug("SPL: Battery is good\n"); 189 return 1; 190 } 191 192 clrsetbits_le32(&power_regs->hw_power_5vctrl, 193 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, 194 0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); 195 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK, 196 &power_regs->hw_power_5vctrl_clr); 197 198 clrsetbits_le32(&power_regs->hw_power_charge, 199 POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK, 200 POWER_CHARGE_STOP_ILIMIT_10MA | 0x3); 201 202 writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_clr); 203 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK, 204 &power_regs->hw_power_5vctrl_clr); 205 206 early_delay(500000); 207 208 volt = mxs_get_batt_volt(); 209 210 if (volt >= 3500) { 211 debug("SPL: Battery Voltage too high\n"); 212 return 0; 213 } 214 215 if (volt >= 2400) { 216 debug("SPL: Battery is good\n"); 217 return 1; 218 } 219 220 writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK, 221 &power_regs->hw_power_charge_clr); 222 writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set); 223 224 debug("SPL: Battery Voltage too low\n"); 225 return 0; 226 } 227 228 /** 229 * mxs_power_setup_5v_detect() - Start the 5V input detection comparator 230 * 231 * This function enables the 5V detection comparator and sets the 5V valid 232 * threshold to 4.4V . We use 4.4V threshold here to make sure that even 233 * under high load, the voltage drop on the 5V input won't be so critical 234 * to cause undervolt on the 4P2 linear regulator supplying the DC-DC 235 * converter and thus making the system crash. 236 */ 237 static void mxs_power_setup_5v_detect(void) 238 { 239 struct mxs_power_regs *power_regs = 240 (struct mxs_power_regs *)MXS_POWER_BASE; 241 242 /* Start 5V detection */ 243 debug("SPL: Starting 5V input detection comparator\n"); 244 clrsetbits_le32(&power_regs->hw_power_5vctrl, 245 POWER_5VCTRL_VBUSVALID_TRSH_MASK, 246 POWER_5VCTRL_VBUSVALID_TRSH_4V4 | 247 POWER_5VCTRL_PWRUP_VBUS_CMPS); 248 } 249 250 /** 251 * mxs_power_switch_dcdc_clocksource() - Switch PLL clock for DC-DC converters 252 * @freqsel: One of the POWER_MISC_FREQSEL_xxx defines to select the clock 253 * 254 * This function configures and then enables an alternative PLL clock source 255 * for the DC-DC converters. 256 */ 257 void mxs_power_switch_dcdc_clocksource(uint32_t freqsel) 258 { 259 struct mxs_power_regs *power_regs = 260 (struct mxs_power_regs *)MXS_POWER_BASE; 261 262 /* Select clocksource for DC-DC converters */ 263 clrsetbits_le32(&power_regs->hw_power_misc, 264 POWER_MISC_FREQSEL_MASK, 265 freqsel); 266 setbits_le32(&power_regs->hw_power_misc, 267 POWER_MISC_SEL_PLLCLK); 268 } 269 270 /** 271 * mxs_power_setup_dcdc_clocksource() - Setup PLL clock source for DC-DC converters 272 * 273 * Normally, there is no need to switch DC-DC clocksource. This is the reason, 274 * why this function is a stub and does nothing. However, boards can implement 275 * this function when required and call mxs_power_switch_dcdc_clocksource() to 276 * switch to an alternative clock source. 277 */ 278 __weak void mxs_power_setup_dcdc_clocksource(void) 279 { 280 debug("SPL: Using default DC-DC clocksource\n"); 281 } 282 283 /** 284 * mxs_src_power_init() - Preconfigure the power block 285 * 286 * This function configures reasonable values for the DC-DC control loop 287 * and battery monitor. 288 */ 289 static void mxs_src_power_init(void) 290 { 291 struct mxs_power_regs *power_regs = 292 (struct mxs_power_regs *)MXS_POWER_BASE; 293 294 debug("SPL: Pre-Configuring power block\n"); 295 296 /* Improve efficieny and reduce transient ripple */ 297 writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST | 298 POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set); 299 300 clrsetbits_le32(&power_regs->hw_power_dclimits, 301 POWER_DCLIMITS_POSLIMIT_BUCK_MASK, 302 0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET); 303 304 setbits_le32(&power_regs->hw_power_battmonitor, 305 POWER_BATTMONITOR_EN_BATADJ); 306 307 /* Increase the RCSCALE level for quick DCDC response to dynamic load */ 308 clrsetbits_le32(&power_regs->hw_power_loopctrl, 309 POWER_LOOPCTRL_EN_RCSCALE_MASK, 310 POWER_LOOPCTRL_RCSCALE_THRESH | 311 POWER_LOOPCTRL_EN_RCSCALE_8X); 312 313 clrsetbits_le32(&power_regs->hw_power_minpwr, 314 POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS); 315 316 /* 5V to battery handoff ... FIXME */ 317 setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER); 318 early_delay(30); 319 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER); 320 } 321 322 /** 323 * mxs_power_init_4p2_params() - Configure the parameters of the 4P2 regulator 324 * 325 * This function configures the necessary parameters for the 4P2 linear 326 * regulator to supply the DC-DC converter from 5V input. 327 */ 328 static void mxs_power_init_4p2_params(void) 329 { 330 struct mxs_power_regs *power_regs = 331 (struct mxs_power_regs *)MXS_POWER_BASE; 332 333 debug("SPL: Configuring common 4P2 regulator params\n"); 334 335 /* Setup 4P2 parameters */ 336 clrsetbits_le32(&power_regs->hw_power_dcdc4p2, 337 POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK, 338 POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET)); 339 340 clrsetbits_le32(&power_regs->hw_power_5vctrl, 341 POWER_5VCTRL_HEADROOM_ADJ_MASK, 342 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET); 343 344 clrsetbits_le32(&power_regs->hw_power_dcdc4p2, 345 POWER_DCDC4P2_DROPOUT_CTRL_MASK, 346 DCDC4P2_DROPOUT_CONFIG); 347 348 clrsetbits_le32(&power_regs->hw_power_5vctrl, 349 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, 350 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); 351 } 352 353 /** 354 * mxs_enable_4p2_dcdc_input() - Enable or disable the DCDC input from 4P2 355 * @xfer: Select if the input shall be enabled or disabled 356 * 357 * This function enables or disables the 4P2 input into the DC-DC converter. 358 */ 359 static void mxs_enable_4p2_dcdc_input(int xfer) 360 { 361 struct mxs_power_regs *power_regs = 362 (struct mxs_power_regs *)MXS_POWER_BASE; 363 uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo; 364 uint32_t prev_5v_brnout, prev_5v_droop; 365 366 debug("SPL: %s 4P2 DC-DC Input\n", xfer ? "Enabling" : "Disabling"); 367 368 if (xfer && (readl(&power_regs->hw_power_5vctrl) & 369 POWER_5VCTRL_ENABLE_DCDC)) { 370 return; 371 } 372 373 prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) & 374 POWER_5VCTRL_PWDN_5VBRNOUT; 375 prev_5v_droop = readl(&power_regs->hw_power_ctrl) & 376 POWER_CTRL_ENIRQ_VDD5V_DROOP; 377 378 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT); 379 writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF, 380 &power_regs->hw_power_reset); 381 382 clrbits_le32(&power_regs->hw_power_ctrl, POWER_CTRL_ENIRQ_VDD5V_DROOP); 383 384 /* 385 * Recording orignal values that will be modified temporarlily 386 * to handle a chip bug. See chip errata for CQ ENGR00115837 387 */ 388 tmp = readl(&power_regs->hw_power_5vctrl); 389 vbus_thresh = tmp & POWER_5VCTRL_VBUSVALID_TRSH_MASK; 390 vbus_5vdetect = tmp & POWER_5VCTRL_VBUSVALID_5VDETECT; 391 392 pwd_bo = readl(&power_regs->hw_power_minpwr) & POWER_MINPWR_PWD_BO; 393 394 /* 395 * Disable mechanisms that get erroneously tripped by when setting 396 * the DCDC4P2 EN_DCDC 397 */ 398 clrbits_le32(&power_regs->hw_power_5vctrl, 399 POWER_5VCTRL_VBUSVALID_5VDETECT | 400 POWER_5VCTRL_VBUSVALID_TRSH_MASK); 401 402 writel(POWER_MINPWR_PWD_BO, &power_regs->hw_power_minpwr_set); 403 404 if (xfer) { 405 setbits_le32(&power_regs->hw_power_5vctrl, 406 POWER_5VCTRL_DCDC_XFER); 407 early_delay(20); 408 clrbits_le32(&power_regs->hw_power_5vctrl, 409 POWER_5VCTRL_DCDC_XFER); 410 411 setbits_le32(&power_regs->hw_power_5vctrl, 412 POWER_5VCTRL_ENABLE_DCDC); 413 } else { 414 setbits_le32(&power_regs->hw_power_dcdc4p2, 415 POWER_DCDC4P2_ENABLE_DCDC); 416 } 417 418 early_delay(25); 419 420 clrsetbits_le32(&power_regs->hw_power_5vctrl, 421 POWER_5VCTRL_VBUSVALID_TRSH_MASK, vbus_thresh); 422 423 if (vbus_5vdetect) 424 writel(vbus_5vdetect, &power_regs->hw_power_5vctrl_set); 425 426 if (!pwd_bo) 427 clrbits_le32(&power_regs->hw_power_minpwr, POWER_MINPWR_PWD_BO); 428 429 while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) 430 writel(POWER_CTRL_VBUS_VALID_IRQ, 431 &power_regs->hw_power_ctrl_clr); 432 433 if (prev_5v_brnout) { 434 writel(POWER_5VCTRL_PWDN_5VBRNOUT, 435 &power_regs->hw_power_5vctrl_set); 436 writel(POWER_RESET_UNLOCK_KEY, 437 &power_regs->hw_power_reset); 438 } else { 439 writel(POWER_5VCTRL_PWDN_5VBRNOUT, 440 &power_regs->hw_power_5vctrl_clr); 441 writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF, 442 &power_regs->hw_power_reset); 443 } 444 445 while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VDD5V_DROOP_IRQ) 446 writel(POWER_CTRL_VDD5V_DROOP_IRQ, 447 &power_regs->hw_power_ctrl_clr); 448 449 if (prev_5v_droop) 450 clrbits_le32(&power_regs->hw_power_ctrl, 451 POWER_CTRL_ENIRQ_VDD5V_DROOP); 452 else 453 setbits_le32(&power_regs->hw_power_ctrl, 454 POWER_CTRL_ENIRQ_VDD5V_DROOP); 455 } 456 457 /** 458 * mxs_power_init_4p2_regulator() - Start the 4P2 regulator 459 * 460 * This function enables the 4P2 regulator and switches the DC-DC converter 461 * to use the 4P2 input. 462 */ 463 static void mxs_power_init_4p2_regulator(void) 464 { 465 struct mxs_power_regs *power_regs = 466 (struct mxs_power_regs *)MXS_POWER_BASE; 467 uint32_t tmp, tmp2; 468 469 debug("SPL: Enabling 4P2 regulator\n"); 470 471 setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2); 472 473 writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set); 474 475 writel(POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, 476 &power_regs->hw_power_5vctrl_clr); 477 clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_TRG_MASK); 478 479 /* Power up the 4p2 rail and logic/control */ 480 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK, 481 &power_regs->hw_power_5vctrl_clr); 482 483 /* 484 * Start charging up the 4p2 capacitor. We ramp of this charge 485 * gradually to avoid large inrush current from the 5V cable which can 486 * cause transients/problems 487 */ 488 debug("SPL: Charging 4P2 capacitor\n"); 489 mxs_enable_4p2_dcdc_input(0); 490 491 if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) { 492 /* 493 * If we arrived here, we were unable to recover from mx23 chip 494 * errata 5837. 4P2 is disabled and sufficient battery power is 495 * not present. Exiting to not enable DCDC power during 5V 496 * connected state. 497 */ 498 clrbits_le32(&power_regs->hw_power_dcdc4p2, 499 POWER_DCDC4P2_ENABLE_DCDC); 500 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK, 501 &power_regs->hw_power_5vctrl_set); 502 503 debug("SPL: Unable to recover from mx23 errata 5837\n"); 504 hang(); 505 } 506 507 /* 508 * Here we set the 4p2 brownout level to something very close to 4.2V. 509 * We then check the brownout status. If the brownout status is false, 510 * the voltage is already close to the target voltage of 4.2V so we 511 * can go ahead and set the 4P2 current limit to our max target limit. 512 * If the brownout status is true, we need to ramp us the current limit 513 * so that we don't cause large inrush current issues. We step up the 514 * current limit until the brownout status is false or until we've 515 * reached our maximum defined 4p2 current limit. 516 */ 517 debug("SPL: Setting 4P2 brownout level\n"); 518 clrsetbits_le32(&power_regs->hw_power_dcdc4p2, 519 POWER_DCDC4P2_BO_MASK, 520 22 << POWER_DCDC4P2_BO_OFFSET); /* 4.15V */ 521 522 if (!(readl(&power_regs->hw_power_sts) & POWER_STS_DCDC_4P2_BO)) { 523 setbits_le32(&power_regs->hw_power_5vctrl, 524 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); 525 } else { 526 tmp = (readl(&power_regs->hw_power_5vctrl) & 527 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK) >> 528 POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET; 529 while (tmp < 0x3f) { 530 if (!(readl(&power_regs->hw_power_sts) & 531 POWER_STS_DCDC_4P2_BO)) { 532 tmp = readl(&power_regs->hw_power_5vctrl); 533 tmp |= POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK; 534 early_delay(100); 535 writel(tmp, &power_regs->hw_power_5vctrl); 536 break; 537 } else { 538 tmp++; 539 tmp2 = readl(&power_regs->hw_power_5vctrl); 540 tmp2 &= ~POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK; 541 tmp2 |= tmp << 542 POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET; 543 writel(tmp2, &power_regs->hw_power_5vctrl); 544 early_delay(100); 545 } 546 } 547 } 548 549 clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK); 550 writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr); 551 } 552 553 /** 554 * mxs_power_init_dcdc_4p2_source() - Switch DC-DC converter to 4P2 source 555 * 556 * This function configures the DC-DC converter to be supplied from the 4P2 557 * linear regulator. 558 */ 559 static void mxs_power_init_dcdc_4p2_source(void) 560 { 561 struct mxs_power_regs *power_regs = 562 (struct mxs_power_regs *)MXS_POWER_BASE; 563 564 debug("SPL: Switching DC-DC converters to 4P2\n"); 565 566 if (!(readl(&power_regs->hw_power_dcdc4p2) & 567 POWER_DCDC4P2_ENABLE_DCDC)) { 568 debug("SPL: Already switched - aborting\n"); 569 hang(); 570 } 571 572 mxs_enable_4p2_dcdc_input(1); 573 574 if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) { 575 clrbits_le32(&power_regs->hw_power_dcdc4p2, 576 POWER_DCDC4P2_ENABLE_DCDC); 577 writel(POWER_5VCTRL_ENABLE_DCDC, 578 &power_regs->hw_power_5vctrl_clr); 579 writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK, 580 &power_regs->hw_power_5vctrl_set); 581 } 582 } 583 584 /** 585 * mxs_power_enable_4p2() - Power up the 4P2 regulator 586 * 587 * This function drives the process of powering up the 4P2 linear regulator 588 * and switching the DC-DC converter input over to the 4P2 linear regulator. 589 */ 590 static void mxs_power_enable_4p2(void) 591 { 592 struct mxs_power_regs *power_regs = 593 (struct mxs_power_regs *)MXS_POWER_BASE; 594 uint32_t vdddctrl, vddactrl, vddioctrl; 595 uint32_t tmp; 596 597 debug("SPL: Powering up 4P2 regulator\n"); 598 599 vdddctrl = readl(&power_regs->hw_power_vdddctrl); 600 vddactrl = readl(&power_regs->hw_power_vddactrl); 601 vddioctrl = readl(&power_regs->hw_power_vddioctrl); 602 603 setbits_le32(&power_regs->hw_power_vdddctrl, 604 POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG | 605 POWER_VDDDCTRL_PWDN_BRNOUT); 606 607 setbits_le32(&power_regs->hw_power_vddactrl, 608 POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG | 609 POWER_VDDACTRL_PWDN_BRNOUT); 610 611 setbits_le32(&power_regs->hw_power_vddioctrl, 612 POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT); 613 614 mxs_power_init_4p2_params(); 615 mxs_power_init_4p2_regulator(); 616 617 /* Shutdown battery (none present) */ 618 if (!mxs_is_batt_ready()) { 619 clrbits_le32(&power_regs->hw_power_dcdc4p2, 620 POWER_DCDC4P2_BO_MASK); 621 writel(POWER_CTRL_DCDC4P2_BO_IRQ, 622 &power_regs->hw_power_ctrl_clr); 623 writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, 624 &power_regs->hw_power_ctrl_clr); 625 } 626 627 mxs_power_init_dcdc_4p2_source(); 628 629 writel(vdddctrl, &power_regs->hw_power_vdddctrl); 630 early_delay(20); 631 writel(vddactrl, &power_regs->hw_power_vddactrl); 632 early_delay(20); 633 writel(vddioctrl, &power_regs->hw_power_vddioctrl); 634 635 /* 636 * Check if FET is enabled on either powerout and if so, 637 * disable load. 638 */ 639 tmp = 0; 640 tmp |= !(readl(&power_regs->hw_power_vdddctrl) & 641 POWER_VDDDCTRL_DISABLE_FET); 642 tmp |= !(readl(&power_regs->hw_power_vddactrl) & 643 POWER_VDDACTRL_DISABLE_FET); 644 tmp |= !(readl(&power_regs->hw_power_vddioctrl) & 645 POWER_VDDIOCTRL_DISABLE_FET); 646 if (tmp) 647 writel(POWER_CHARGE_ENABLE_LOAD, 648 &power_regs->hw_power_charge_clr); 649 650 debug("SPL: 4P2 regulator powered-up\n"); 651 } 652 653 /** 654 * mxs_boot_valid_5v() - Boot from 5V supply 655 * 656 * This function configures the power block to boot from valid 5V input. 657 * This is called only if the 5V is reliable and can properly supply the 658 * CPU. This function proceeds to configure the 4P2 converter to be supplied 659 * from the 5V input. 660 */ 661 static void mxs_boot_valid_5v(void) 662 { 663 struct mxs_power_regs *power_regs = 664 (struct mxs_power_regs *)MXS_POWER_BASE; 665 666 debug("SPL: Booting from 5V supply\n"); 667 668 /* 669 * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V 670 * disconnect event. FIXME 671 */ 672 writel(POWER_5VCTRL_VBUSVALID_5VDETECT, 673 &power_regs->hw_power_5vctrl_set); 674 675 /* Configure polarity to check for 5V disconnection. */ 676 writel(POWER_CTRL_POLARITY_VBUSVALID | 677 POWER_CTRL_POLARITY_VDD5V_GT_VDDIO, 678 &power_regs->hw_power_ctrl_clr); 679 680 writel(POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_VDD5V_GT_VDDIO_IRQ, 681 &power_regs->hw_power_ctrl_clr); 682 683 mxs_power_enable_4p2(); 684 } 685 686 /** 687 * mxs_powerdown() - Shut down the system 688 * 689 * This function powers down the CPU completely. 690 */ 691 static void mxs_powerdown(void) 692 { 693 struct mxs_power_regs *power_regs = 694 (struct mxs_power_regs *)MXS_POWER_BASE; 695 696 debug("Powering Down\n"); 697 698 writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset); 699 writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF, 700 &power_regs->hw_power_reset); 701 } 702 703 /** 704 * mxs_batt_boot() - Configure the power block to boot from battery input 705 * 706 * This function configures the power block to boot from the battery voltage 707 * supply. 708 */ 709 static void mxs_batt_boot(void) 710 { 711 struct mxs_power_regs *power_regs = 712 (struct mxs_power_regs *)MXS_POWER_BASE; 713 714 debug("SPL: Configuring power block to boot from battery\n"); 715 716 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT); 717 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC); 718 719 clrbits_le32(&power_regs->hw_power_dcdc4p2, 720 POWER_DCDC4P2_ENABLE_DCDC | POWER_DCDC4P2_ENABLE_4P2); 721 writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_clr); 722 723 /* 5V to battery handoff. */ 724 setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER); 725 early_delay(30); 726 clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER); 727 728 writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr); 729 730 clrsetbits_le32(&power_regs->hw_power_minpwr, 731 POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS); 732 733 mxs_power_set_linreg(); 734 735 clrbits_le32(&power_regs->hw_power_vdddctrl, 736 POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG); 737 738 clrbits_le32(&power_regs->hw_power_vddactrl, 739 POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG); 740 741 clrbits_le32(&power_regs->hw_power_vddioctrl, 742 POWER_VDDIOCTRL_DISABLE_FET); 743 744 setbits_le32(&power_regs->hw_power_5vctrl, 745 POWER_5VCTRL_PWD_CHARGE_4P2_MASK); 746 747 setbits_le32(&power_regs->hw_power_5vctrl, 748 POWER_5VCTRL_ENABLE_DCDC); 749 750 clrsetbits_le32(&power_regs->hw_power_5vctrl, 751 POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, 752 0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); 753 754 mxs_power_enable_4p2(); 755 } 756 757 /** 758 * mxs_handle_5v_conflict() - Test if the 5V input is reliable 759 * 760 * This function tests if the 5V input can reliably supply the system. If it 761 * can, then proceed to configuring the system to boot from 5V source, otherwise 762 * try booting from battery supply. If we can not boot from battery supply 763 * either, shut down the system. 764 */ 765 static void mxs_handle_5v_conflict(void) 766 { 767 struct mxs_power_regs *power_regs = 768 (struct mxs_power_regs *)MXS_POWER_BASE; 769 uint32_t tmp; 770 771 debug("SPL: Resolving 5V conflict\n"); 772 773 setbits_le32(&power_regs->hw_power_vddioctrl, 774 POWER_VDDIOCTRL_BO_OFFSET_MASK); 775 776 for (;;) { 777 tmp = readl(&power_regs->hw_power_sts); 778 779 if (tmp & POWER_STS_VDDIO_BO) { 780 /* 781 * VDDIO has a brownout, then the VDD5V_GT_VDDIO becomes 782 * unreliable 783 */ 784 debug("SPL: VDDIO has a brownout\n"); 785 mxs_powerdown(); 786 break; 787 } 788 789 if (tmp & POWER_STS_VDD5V_GT_VDDIO) { 790 debug("SPL: POWER_STS_VDD5V_GT_VDDIO is set\n"); 791 mxs_boot_valid_5v(); 792 break; 793 } else { 794 debug("SPL: POWER_STS_VDD5V_GT_VDDIO is not set\n"); 795 mxs_powerdown(); 796 break; 797 } 798 799 /* 800 * TODO: I can't see this being reached. We'll either 801 * powerdown or boot from a stable 5V supply. 802 */ 803 if (tmp & POWER_STS_PSWITCH_MASK) { 804 debug("SPL: POWER_STS_PSWITCH_MASK is set\n"); 805 mxs_batt_boot(); 806 break; 807 } 808 } 809 } 810 811 /** 812 * mxs_5v_boot() - Configure the power block to boot from 5V input 813 * 814 * This function handles configuration of the power block when supplied by 815 * a 5V input. 816 */ 817 static void mxs_5v_boot(void) 818 { 819 struct mxs_power_regs *power_regs = 820 (struct mxs_power_regs *)MXS_POWER_BASE; 821 822 debug("SPL: Configuring power block to boot from 5V input\n"); 823 824 /* 825 * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID, 826 * but their implementation always returns 1 so we omit it here. 827 */ 828 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { 829 debug("SPL: 5V VDD good\n"); 830 mxs_boot_valid_5v(); 831 return; 832 } 833 834 early_delay(1000); 835 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { 836 debug("SPL: 5V VDD good (after delay)\n"); 837 mxs_boot_valid_5v(); 838 return; 839 } 840 841 debug("SPL: 5V VDD not good\n"); 842 mxs_handle_5v_conflict(); 843 } 844 845 /** 846 * mxs_init_batt_bo() - Configure battery brownout threshold 847 * 848 * This function configures the battery input brownout threshold. The value 849 * at which the battery brownout happens is configured to 3.0V in the code. 850 */ 851 static void mxs_init_batt_bo(void) 852 { 853 struct mxs_power_regs *power_regs = 854 (struct mxs_power_regs *)MXS_POWER_BASE; 855 856 debug("SPL: Initialising battery brown-out level to 3.0V\n"); 857 858 /* Brownout at 3V */ 859 clrsetbits_le32(&power_regs->hw_power_battmonitor, 860 POWER_BATTMONITOR_BRWNOUT_LVL_MASK, 861 15 << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET); 862 863 writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr); 864 writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr); 865 } 866 867 /** 868 * mxs_switch_vddd_to_dcdc_source() - Switch VDDD rail to DC-DC converter 869 * 870 * This function turns off the VDDD linear regulator and therefore makes 871 * the VDDD rail be supplied only by the DC-DC converter. 872 */ 873 static void mxs_switch_vddd_to_dcdc_source(void) 874 { 875 struct mxs_power_regs *power_regs = 876 (struct mxs_power_regs *)MXS_POWER_BASE; 877 878 debug("SPL: Switching VDDD to DC-DC converters\n"); 879 880 clrsetbits_le32(&power_regs->hw_power_vdddctrl, 881 POWER_VDDDCTRL_LINREG_OFFSET_MASK, 882 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW); 883 884 clrbits_le32(&power_regs->hw_power_vdddctrl, 885 POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG | 886 POWER_VDDDCTRL_DISABLE_STEPPING); 887 } 888 889 /** 890 * mxs_power_configure_power_source() - Configure power block source 891 * 892 * This function is the core of the power configuration logic. The function 893 * selects the power block input source and configures the whole power block 894 * accordingly. After the configuration is complete and the system is stable 895 * again, the function switches the CPU clock source back to PLL. Finally, 896 * the function switches the voltage rails to DC-DC converter. 897 */ 898 static void mxs_power_configure_power_source(void) 899 { 900 int batt_ready, batt_good; 901 struct mxs_power_regs *power_regs = 902 (struct mxs_power_regs *)MXS_POWER_BASE; 903 struct mxs_lradc_regs *lradc_regs = 904 (struct mxs_lradc_regs *)MXS_LRADC_BASE; 905 906 debug("SPL: Configuring power source\n"); 907 908 mxs_power_setup_dcdc_clocksource(); 909 mxs_src_power_init(); 910 911 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { 912 batt_ready = mxs_is_batt_ready(); 913 if (batt_ready) { 914 /* 5V source detected, good battery detected. */ 915 mxs_batt_boot(); 916 } else { 917 batt_good = mxs_is_batt_good(); 918 if (!batt_good) { 919 /* 5V source detected, bad battery detected. */ 920 writel(LRADC_CONVERSION_AUTOMATIC, 921 &lradc_regs->hw_lradc_conversion_clr); 922 clrbits_le32(&power_regs->hw_power_battmonitor, 923 POWER_BATTMONITOR_BATT_VAL_MASK); 924 } 925 mxs_5v_boot(); 926 } 927 } else { 928 /* 5V not detected, booting from battery. */ 929 mxs_batt_boot(); 930 } 931 932 /* 933 * TODO: Do not switch CPU clock to PLL if we are VDD5V is sourced 934 * from USB VBUS 935 */ 936 mxs_power_clock2pll(); 937 938 mxs_init_batt_bo(); 939 940 mxs_switch_vddd_to_dcdc_source(); 941 942 #ifdef CONFIG_MX23 943 /* Fire up the VDDMEM LinReg now that we're all set. */ 944 debug("SPL: Enabling mx23 VDDMEM linear regulator\n"); 945 writel(POWER_VDDMEMCTRL_ENABLE_LINREG | POWER_VDDMEMCTRL_ENABLE_ILIMIT, 946 &power_regs->hw_power_vddmemctrl); 947 #endif 948 } 949 950 /** 951 * mxs_enable_output_rail_protection() - Enable power rail protection 952 * 953 * This function enables overload protection on the power rails. This is 954 * triggered if the power rails' voltage drops rapidly due to overload and 955 * in such case, the supply to the powerrail is cut-off, protecting the 956 * CPU from damage. Note that under such condition, the system will likely 957 * crash or misbehave. 958 */ 959 static void mxs_enable_output_rail_protection(void) 960 { 961 struct mxs_power_regs *power_regs = 962 (struct mxs_power_regs *)MXS_POWER_BASE; 963 964 debug("SPL: Enabling output rail protection\n"); 965 966 writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | 967 POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr); 968 969 setbits_le32(&power_regs->hw_power_vdddctrl, 970 POWER_VDDDCTRL_PWDN_BRNOUT); 971 972 setbits_le32(&power_regs->hw_power_vddactrl, 973 POWER_VDDACTRL_PWDN_BRNOUT); 974 975 setbits_le32(&power_regs->hw_power_vddioctrl, 976 POWER_VDDIOCTRL_PWDN_BRNOUT); 977 } 978 979 /** 980 * mxs_get_vddio_power_source_off() - Get VDDIO rail power source 981 * 982 * This function tests if the VDDIO rail is supplied by linear regulator 983 * or by the DC-DC converter. Returns 1 if powered by linear regulator, 984 * returns 0 if powered by the DC-DC converter. 985 */ 986 static int mxs_get_vddio_power_source_off(void) 987 { 988 struct mxs_power_regs *power_regs = 989 (struct mxs_power_regs *)MXS_POWER_BASE; 990 uint32_t tmp; 991 992 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { 993 tmp = readl(&power_regs->hw_power_vddioctrl); 994 if (tmp & POWER_VDDIOCTRL_DISABLE_FET) { 995 if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) == 996 POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) { 997 return 1; 998 } 999 } 1000 1001 if (!(readl(&power_regs->hw_power_5vctrl) & 1002 POWER_5VCTRL_ENABLE_DCDC)) { 1003 if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) == 1004 POWER_VDDIOCTRL_LINREG_OFFSET_0STEPS) { 1005 return 1; 1006 } 1007 } 1008 } 1009 1010 return 0; 1011 1012 } 1013 1014 /** 1015 * mxs_get_vddd_power_source_off() - Get VDDD rail power source 1016 * 1017 * This function tests if the VDDD rail is supplied by linear regulator 1018 * or by the DC-DC converter. Returns 1 if powered by linear regulator, 1019 * returns 0 if powered by the DC-DC converter. 1020 */ 1021 static int mxs_get_vddd_power_source_off(void) 1022 { 1023 struct mxs_power_regs *power_regs = 1024 (struct mxs_power_regs *)MXS_POWER_BASE; 1025 uint32_t tmp; 1026 1027 tmp = readl(&power_regs->hw_power_vdddctrl); 1028 if (tmp & POWER_VDDDCTRL_DISABLE_FET) { 1029 if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) == 1030 POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) { 1031 return 1; 1032 } 1033 } 1034 1035 if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) { 1036 if (!(readl(&power_regs->hw_power_5vctrl) & 1037 POWER_5VCTRL_ENABLE_DCDC)) { 1038 return 1; 1039 } 1040 } 1041 1042 if (!(tmp & POWER_VDDDCTRL_ENABLE_LINREG)) { 1043 if ((tmp & POWER_VDDDCTRL_LINREG_OFFSET_MASK) == 1044 POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW) { 1045 return 1; 1046 } 1047 } 1048 1049 return 0; 1050 } 1051 1052 struct mxs_vddx_cfg { 1053 uint32_t *reg; 1054 uint8_t step_mV; 1055 uint16_t lowest_mV; 1056 int (*powered_by_linreg)(void); 1057 uint32_t trg_mask; 1058 uint32_t bo_irq; 1059 uint32_t bo_enirq; 1060 uint32_t bo_offset_mask; 1061 uint32_t bo_offset_offset; 1062 }; 1063 1064 static const struct mxs_vddx_cfg mxs_vddio_cfg = { 1065 .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)-> 1066 hw_power_vddioctrl), 1067 #if defined(CONFIG_MX23) 1068 .step_mV = 25, 1069 #else 1070 .step_mV = 50, 1071 #endif 1072 .lowest_mV = 2800, 1073 .powered_by_linreg = mxs_get_vddio_power_source_off, 1074 .trg_mask = POWER_VDDIOCTRL_TRG_MASK, 1075 .bo_irq = POWER_CTRL_VDDIO_BO_IRQ, 1076 .bo_enirq = POWER_CTRL_ENIRQ_VDDIO_BO, 1077 .bo_offset_mask = POWER_VDDIOCTRL_BO_OFFSET_MASK, 1078 .bo_offset_offset = POWER_VDDIOCTRL_BO_OFFSET_OFFSET, 1079 }; 1080 1081 static const struct mxs_vddx_cfg mxs_vddd_cfg = { 1082 .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)-> 1083 hw_power_vdddctrl), 1084 .step_mV = 25, 1085 .lowest_mV = 800, 1086 .powered_by_linreg = mxs_get_vddd_power_source_off, 1087 .trg_mask = POWER_VDDDCTRL_TRG_MASK, 1088 .bo_irq = POWER_CTRL_VDDD_BO_IRQ, 1089 .bo_enirq = POWER_CTRL_ENIRQ_VDDD_BO, 1090 .bo_offset_mask = POWER_VDDDCTRL_BO_OFFSET_MASK, 1091 .bo_offset_offset = POWER_VDDDCTRL_BO_OFFSET_OFFSET, 1092 }; 1093 1094 #ifdef CONFIG_MX23 1095 static const struct mxs_vddx_cfg mxs_vddmem_cfg = { 1096 .reg = &(((struct mxs_power_regs *)MXS_POWER_BASE)-> 1097 hw_power_vddmemctrl), 1098 .step_mV = 50, 1099 .lowest_mV = 1700, 1100 .powered_by_linreg = NULL, 1101 .trg_mask = POWER_VDDMEMCTRL_TRG_MASK, 1102 .bo_irq = 0, 1103 .bo_enirq = 0, 1104 .bo_offset_mask = 0, 1105 .bo_offset_offset = 0, 1106 }; 1107 #endif 1108 1109 /** 1110 * mxs_power_set_vddx() - Configure voltage on DC-DC converter rail 1111 * @cfg: Configuration data of the DC-DC converter rail 1112 * @new_target: New target voltage of the DC-DC converter rail 1113 * @new_brownout: New brownout trigger voltage 1114 * 1115 * This function configures the output voltage on the DC-DC converter rail. 1116 * The rail is selected by the @cfg argument. The new voltage target is 1117 * selected by the @new_target and the voltage is specified in mV. The 1118 * new brownout value is selected by the @new_brownout argument and the 1119 * value is also in mV. 1120 */ 1121 static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg, 1122 uint32_t new_target, uint32_t new_brownout) 1123 { 1124 struct mxs_power_regs *power_regs = 1125 (struct mxs_power_regs *)MXS_POWER_BASE; 1126 uint32_t cur_target, diff, bo_int = 0; 1127 uint32_t powered_by_linreg = 0; 1128 int adjust_up, tmp; 1129 1130 new_brownout = DIV_ROUND_CLOSEST(new_target - new_brownout, 1131 cfg->step_mV); 1132 1133 cur_target = readl(cfg->reg); 1134 cur_target &= cfg->trg_mask; 1135 cur_target *= cfg->step_mV; 1136 cur_target += cfg->lowest_mV; 1137 1138 adjust_up = new_target > cur_target; 1139 if (cfg->powered_by_linreg) 1140 powered_by_linreg = cfg->powered_by_linreg(); 1141 1142 if (adjust_up && cfg->bo_irq) { 1143 if (powered_by_linreg) { 1144 bo_int = readl(cfg->reg); 1145 clrbits_le32(cfg->reg, cfg->bo_enirq); 1146 } 1147 setbits_le32(cfg->reg, cfg->bo_offset_mask); 1148 } 1149 1150 do { 1151 if (abs(new_target - cur_target) > 100) { 1152 if (adjust_up) 1153 diff = cur_target + 100; 1154 else 1155 diff = cur_target - 100; 1156 } else { 1157 diff = new_target; 1158 } 1159 1160 diff -= cfg->lowest_mV; 1161 diff /= cfg->step_mV; 1162 1163 clrsetbits_le32(cfg->reg, cfg->trg_mask, diff); 1164 1165 if (powered_by_linreg || 1166 (readl(&power_regs->hw_power_sts) & 1167 POWER_STS_VDD5V_GT_VDDIO)) 1168 early_delay(500); 1169 else { 1170 for (;;) { 1171 tmp = readl(&power_regs->hw_power_sts); 1172 if (tmp & POWER_STS_DC_OK) 1173 break; 1174 } 1175 } 1176 1177 cur_target = readl(cfg->reg); 1178 cur_target &= cfg->trg_mask; 1179 cur_target *= cfg->step_mV; 1180 cur_target += cfg->lowest_mV; 1181 } while (new_target > cur_target); 1182 1183 if (cfg->bo_irq) { 1184 if (adjust_up && powered_by_linreg) { 1185 writel(cfg->bo_irq, &power_regs->hw_power_ctrl_clr); 1186 if (bo_int & cfg->bo_enirq) 1187 setbits_le32(cfg->reg, cfg->bo_enirq); 1188 } 1189 1190 clrsetbits_le32(cfg->reg, cfg->bo_offset_mask, 1191 new_brownout << cfg->bo_offset_offset); 1192 } 1193 } 1194 1195 /** 1196 * mxs_setup_batt_detect() - Start the battery voltage measurement logic 1197 * 1198 * This function starts and configures the LRADC block. This allows the 1199 * power initialization code to measure battery voltage and based on this 1200 * knowledge, decide whether to boot at all, boot from battery or boot 1201 * from 5V input. 1202 */ 1203 static void mxs_setup_batt_detect(void) 1204 { 1205 debug("SPL: Starting battery voltage measurement logic\n"); 1206 1207 mxs_lradc_init(); 1208 mxs_lradc_enable_batt_measurement(); 1209 early_delay(10); 1210 } 1211 1212 /** 1213 * mxs_ungate_power() - Ungate the POWER block 1214 * 1215 * This function ungates clock to the power block. In case the power block 1216 * was still gated at this point, it will not be possible to configure the 1217 * block and therefore the power initialization would fail. This function 1218 * is only needed on i.MX233, on i.MX28 the power block is always ungated. 1219 */ 1220 static void mxs_ungate_power(void) 1221 { 1222 #ifdef CONFIG_MX23 1223 struct mxs_power_regs *power_regs = 1224 (struct mxs_power_regs *)MXS_POWER_BASE; 1225 1226 writel(POWER_CTRL_CLKGATE, &power_regs->hw_power_ctrl_clr); 1227 #endif 1228 } 1229 1230 /** 1231 * mxs_power_init() - The power block init main function 1232 * 1233 * This function calls all the power block initialization functions in 1234 * proper sequence to start the power block. 1235 */ 1236 void mxs_power_init(void) 1237 { 1238 struct mxs_power_regs *power_regs = 1239 (struct mxs_power_regs *)MXS_POWER_BASE; 1240 1241 debug("SPL: Initialising Power Block\n"); 1242 1243 mxs_ungate_power(); 1244 1245 mxs_power_clock2xtal(); 1246 mxs_power_set_auto_restart(); 1247 mxs_power_set_linreg(); 1248 mxs_power_setup_5v_detect(); 1249 1250 mxs_setup_batt_detect(); 1251 1252 mxs_power_configure_power_source(); 1253 mxs_enable_output_rail_protection(); 1254 1255 debug("SPL: Setting VDDIO to 3V3 (brownout @ 3v15)\n"); 1256 mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150); 1257 1258 debug("SPL: Setting VDDD to 1V5 (brownout @ 1v315)\n"); 1259 mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1315); 1260 #ifdef CONFIG_MX23 1261 debug("SPL: Setting mx23 VDDMEM to 2V5 (brownout @ 1v7)\n"); 1262 mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700); 1263 #endif 1264 writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | 1265 POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ | 1266 POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ | 1267 POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr); 1268 1269 writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set); 1270 1271 early_delay(1000); 1272 } 1273 1274 #ifdef CONFIG_SPL_MXS_PSWITCH_WAIT 1275 /** 1276 * mxs_power_wait_pswitch() - Wait for power switch to be pressed 1277 * 1278 * This function waits until the power-switch was pressed to start booting 1279 * the board. 1280 */ 1281 void mxs_power_wait_pswitch(void) 1282 { 1283 struct mxs_power_regs *power_regs = 1284 (struct mxs_power_regs *)MXS_POWER_BASE; 1285 1286 debug("SPL: Waiting for power switch input\n"); 1287 while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK)) 1288 ; 1289 } 1290 #endif 1291