spl_power_init.c 25 KB

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