pm34xx.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. /*
  2. * OMAP3 Power Management Routines
  3. *
  4. * Copyright (C) 2006-2008 Nokia Corporation
  5. * Tony Lindgren <tony@atomide.com>
  6. * Jouni Hogander
  7. *
  8. * Copyright (C) 2005 Texas Instruments, Inc.
  9. * Richard Woodruff <r-woodruff2@ti.com>
  10. *
  11. * Based on pm.c for omap1
  12. *
  13. * This program is free software; you can redistribute it and/or modify
  14. * it under the terms of the GNU General Public License version 2 as
  15. * published by the Free Software Foundation.
  16. */
  17. #include <linux/pm.h>
  18. #include <linux/suspend.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/module.h>
  21. #include <linux/list.h>
  22. #include <linux/err.h>
  23. #include <linux/gpio.h>
  24. #include <mach/sram.h>
  25. #include <mach/clockdomain.h>
  26. #include <mach/powerdomain.h>
  27. #include <mach/control.h>
  28. #include <mach/serial.h>
  29. #include "cm.h"
  30. #include "cm-regbits-34xx.h"
  31. #include "prm-regbits-34xx.h"
  32. #include "prm.h"
  33. #include "pm.h"
  34. struct power_state {
  35. struct powerdomain *pwrdm;
  36. u32 next_state;
  37. u32 saved_state;
  38. struct list_head node;
  39. };
  40. static LIST_HEAD(pwrst_list);
  41. static void (*_omap_sram_idle)(u32 *addr, int save_state);
  42. static struct powerdomain *mpu_pwrdm;
  43. /* PRCM Interrupt Handler for wakeups */
  44. static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id)
  45. {
  46. u32 wkst, irqstatus_mpu;
  47. u32 fclk, iclk;
  48. /* WKUP */
  49. wkst = prm_read_mod_reg(WKUP_MOD, PM_WKST);
  50. if (wkst) {
  51. iclk = cm_read_mod_reg(WKUP_MOD, CM_ICLKEN);
  52. fclk = cm_read_mod_reg(WKUP_MOD, CM_FCLKEN);
  53. cm_set_mod_reg_bits(wkst, WKUP_MOD, CM_ICLKEN);
  54. cm_set_mod_reg_bits(wkst, WKUP_MOD, CM_FCLKEN);
  55. prm_write_mod_reg(wkst, WKUP_MOD, PM_WKST);
  56. while (prm_read_mod_reg(WKUP_MOD, PM_WKST))
  57. cpu_relax();
  58. cm_write_mod_reg(iclk, WKUP_MOD, CM_ICLKEN);
  59. cm_write_mod_reg(fclk, WKUP_MOD, CM_FCLKEN);
  60. }
  61. /* CORE */
  62. wkst = prm_read_mod_reg(CORE_MOD, PM_WKST1);
  63. if (wkst) {
  64. iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN1);
  65. fclk = cm_read_mod_reg(CORE_MOD, CM_FCLKEN1);
  66. cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN1);
  67. cm_set_mod_reg_bits(wkst, CORE_MOD, CM_FCLKEN1);
  68. prm_write_mod_reg(wkst, CORE_MOD, PM_WKST1);
  69. while (prm_read_mod_reg(CORE_MOD, PM_WKST1))
  70. cpu_relax();
  71. cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN1);
  72. cm_write_mod_reg(fclk, CORE_MOD, CM_FCLKEN1);
  73. }
  74. wkst = prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3);
  75. if (wkst) {
  76. iclk = cm_read_mod_reg(CORE_MOD, CM_ICLKEN3);
  77. fclk = cm_read_mod_reg(CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
  78. cm_set_mod_reg_bits(wkst, CORE_MOD, CM_ICLKEN3);
  79. cm_set_mod_reg_bits(wkst, CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
  80. prm_write_mod_reg(wkst, CORE_MOD, OMAP3430ES2_PM_WKST3);
  81. while (prm_read_mod_reg(CORE_MOD, OMAP3430ES2_PM_WKST3))
  82. cpu_relax();
  83. cm_write_mod_reg(iclk, CORE_MOD, CM_ICLKEN3);
  84. cm_write_mod_reg(fclk, CORE_MOD, OMAP3430ES2_CM_FCLKEN3);
  85. }
  86. /* PER */
  87. wkst = prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST);
  88. if (wkst) {
  89. iclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_ICLKEN);
  90. fclk = cm_read_mod_reg(OMAP3430_PER_MOD, CM_FCLKEN);
  91. cm_set_mod_reg_bits(wkst, OMAP3430_PER_MOD, CM_ICLKEN);
  92. cm_set_mod_reg_bits(wkst, OMAP3430_PER_MOD, CM_FCLKEN);
  93. prm_write_mod_reg(wkst, OMAP3430_PER_MOD, PM_WKST);
  94. while (prm_read_mod_reg(OMAP3430_PER_MOD, PM_WKST))
  95. cpu_relax();
  96. cm_write_mod_reg(iclk, OMAP3430_PER_MOD, CM_ICLKEN);
  97. cm_write_mod_reg(fclk, OMAP3430_PER_MOD, CM_FCLKEN);
  98. }
  99. if (omap_rev() > OMAP3430_REV_ES1_0) {
  100. /* USBHOST */
  101. wkst = prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD, PM_WKST);
  102. if (wkst) {
  103. iclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
  104. CM_ICLKEN);
  105. fclk = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
  106. CM_FCLKEN);
  107. cm_set_mod_reg_bits(wkst, OMAP3430ES2_USBHOST_MOD,
  108. CM_ICLKEN);
  109. cm_set_mod_reg_bits(wkst, OMAP3430ES2_USBHOST_MOD,
  110. CM_FCLKEN);
  111. prm_write_mod_reg(wkst, OMAP3430ES2_USBHOST_MOD,
  112. PM_WKST);
  113. while (prm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
  114. PM_WKST))
  115. cpu_relax();
  116. cm_write_mod_reg(iclk, OMAP3430ES2_USBHOST_MOD,
  117. CM_ICLKEN);
  118. cm_write_mod_reg(fclk, OMAP3430ES2_USBHOST_MOD,
  119. CM_FCLKEN);
  120. }
  121. }
  122. irqstatus_mpu = prm_read_mod_reg(OCP_MOD,
  123. OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
  124. prm_write_mod_reg(irqstatus_mpu, OCP_MOD,
  125. OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
  126. while (prm_read_mod_reg(OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET))
  127. cpu_relax();
  128. return IRQ_HANDLED;
  129. }
  130. static void omap_sram_idle(void)
  131. {
  132. /* Variable to tell what needs to be saved and restored
  133. * in omap_sram_idle*/
  134. /* save_state = 0 => Nothing to save and restored */
  135. /* save_state = 1 => Only L1 and logic lost */
  136. /* save_state = 2 => Only L2 lost */
  137. /* save_state = 3 => L1, L2 and logic lost */
  138. int save_state = 0, mpu_next_state;
  139. if (!_omap_sram_idle)
  140. return;
  141. mpu_next_state = pwrdm_read_next_pwrst(mpu_pwrdm);
  142. switch (mpu_next_state) {
  143. case PWRDM_POWER_RET:
  144. /* No need to save context */
  145. save_state = 0;
  146. break;
  147. default:
  148. /* Invalid state */
  149. printk(KERN_ERR "Invalid mpu state in sram_idle\n");
  150. return;
  151. }
  152. omap2_gpio_prepare_for_retention();
  153. omap_uart_prepare_idle(0);
  154. omap_uart_prepare_idle(1);
  155. omap_uart_prepare_idle(2);
  156. _omap_sram_idle(NULL, save_state);
  157. cpu_init();
  158. omap_uart_resume_idle(2);
  159. omap_uart_resume_idle(1);
  160. omap_uart_resume_idle(0);
  161. omap2_gpio_resume_after_retention();
  162. }
  163. /*
  164. * Check if functional clocks are enabled before entering
  165. * sleep. This function could be behind CONFIG_PM_DEBUG
  166. * when all drivers are configuring their sysconfig registers
  167. * properly and using their clocks properly.
  168. */
  169. static int omap3_fclks_active(void)
  170. {
  171. u32 fck_core1 = 0, fck_core3 = 0, fck_sgx = 0, fck_dss = 0,
  172. fck_cam = 0, fck_per = 0, fck_usbhost = 0;
  173. fck_core1 = cm_read_mod_reg(CORE_MOD,
  174. CM_FCLKEN1);
  175. if (omap_rev() > OMAP3430_REV_ES1_0) {
  176. fck_core3 = cm_read_mod_reg(CORE_MOD,
  177. OMAP3430ES2_CM_FCLKEN3);
  178. fck_sgx = cm_read_mod_reg(OMAP3430ES2_SGX_MOD,
  179. CM_FCLKEN);
  180. fck_usbhost = cm_read_mod_reg(OMAP3430ES2_USBHOST_MOD,
  181. CM_FCLKEN);
  182. } else
  183. fck_sgx = cm_read_mod_reg(GFX_MOD,
  184. OMAP3430ES2_CM_FCLKEN3);
  185. fck_dss = cm_read_mod_reg(OMAP3430_DSS_MOD,
  186. CM_FCLKEN);
  187. fck_cam = cm_read_mod_reg(OMAP3430_CAM_MOD,
  188. CM_FCLKEN);
  189. fck_per = cm_read_mod_reg(OMAP3430_PER_MOD,
  190. CM_FCLKEN);
  191. /* Ignore UART clocks. These are handled by UART core (serial.c) */
  192. fck_core1 &= ~(OMAP3430_EN_UART1 | OMAP3430_EN_UART2);
  193. fck_per &= ~OMAP3430_EN_UART3;
  194. if (fck_core1 | fck_core3 | fck_sgx | fck_dss |
  195. fck_cam | fck_per | fck_usbhost)
  196. return 1;
  197. return 0;
  198. }
  199. static int omap3_can_sleep(void)
  200. {
  201. if (!omap_uart_can_sleep())
  202. return 0;
  203. if (omap3_fclks_active())
  204. return 0;
  205. return 1;
  206. }
  207. /* This sets pwrdm state (other than mpu & core. Currently only ON &
  208. * RET are supported. Function is assuming that clkdm doesn't have
  209. * hw_sup mode enabled. */
  210. static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state)
  211. {
  212. u32 cur_state;
  213. int sleep_switch = 0;
  214. int ret = 0;
  215. if (pwrdm == NULL || IS_ERR(pwrdm))
  216. return -EINVAL;
  217. while (!(pwrdm->pwrsts & (1 << state))) {
  218. if (state == PWRDM_POWER_OFF)
  219. return ret;
  220. state--;
  221. }
  222. cur_state = pwrdm_read_next_pwrst(pwrdm);
  223. if (cur_state == state)
  224. return ret;
  225. if (pwrdm_read_pwrst(pwrdm) < PWRDM_POWER_ON) {
  226. omap2_clkdm_wakeup(pwrdm->pwrdm_clkdms[0]);
  227. sleep_switch = 1;
  228. pwrdm_wait_transition(pwrdm);
  229. }
  230. ret = pwrdm_set_next_pwrst(pwrdm, state);
  231. if (ret) {
  232. printk(KERN_ERR "Unable to set state of powerdomain: %s\n",
  233. pwrdm->name);
  234. goto err;
  235. }
  236. if (sleep_switch) {
  237. omap2_clkdm_allow_idle(pwrdm->pwrdm_clkdms[0]);
  238. pwrdm_wait_transition(pwrdm);
  239. }
  240. err:
  241. return ret;
  242. }
  243. static void omap3_pm_idle(void)
  244. {
  245. local_irq_disable();
  246. local_fiq_disable();
  247. if (!omap3_can_sleep())
  248. goto out;
  249. if (omap_irq_pending())
  250. goto out;
  251. omap_sram_idle();
  252. out:
  253. local_fiq_enable();
  254. local_irq_enable();
  255. }
  256. static int omap3_pm_prepare(void)
  257. {
  258. disable_hlt();
  259. return 0;
  260. }
  261. static int omap3_pm_suspend(void)
  262. {
  263. struct power_state *pwrst;
  264. int state, ret = 0;
  265. /* Read current next_pwrsts */
  266. list_for_each_entry(pwrst, &pwrst_list, node)
  267. pwrst->saved_state = pwrdm_read_next_pwrst(pwrst->pwrdm);
  268. /* Set ones wanted by suspend */
  269. list_for_each_entry(pwrst, &pwrst_list, node) {
  270. if (set_pwrdm_state(pwrst->pwrdm, pwrst->next_state))
  271. goto restore;
  272. if (pwrdm_clear_all_prev_pwrst(pwrst->pwrdm))
  273. goto restore;
  274. }
  275. omap_uart_prepare_suspend();
  276. omap_sram_idle();
  277. restore:
  278. /* Restore next_pwrsts */
  279. list_for_each_entry(pwrst, &pwrst_list, node) {
  280. set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
  281. state = pwrdm_read_prev_pwrst(pwrst->pwrdm);
  282. if (state > pwrst->next_state) {
  283. printk(KERN_INFO "Powerdomain (%s) didn't enter "
  284. "target state %d\n",
  285. pwrst->pwrdm->name, pwrst->next_state);
  286. ret = -1;
  287. }
  288. }
  289. if (ret)
  290. printk(KERN_ERR "Could not enter target state in pm_suspend\n");
  291. else
  292. printk(KERN_INFO "Successfully put all powerdomains "
  293. "to target state\n");
  294. return ret;
  295. }
  296. static int omap3_pm_enter(suspend_state_t state)
  297. {
  298. int ret = 0;
  299. switch (state) {
  300. case PM_SUSPEND_STANDBY:
  301. case PM_SUSPEND_MEM:
  302. ret = omap3_pm_suspend();
  303. break;
  304. default:
  305. ret = -EINVAL;
  306. }
  307. return ret;
  308. }
  309. static void omap3_pm_finish(void)
  310. {
  311. enable_hlt();
  312. }
  313. static struct platform_suspend_ops omap_pm_ops = {
  314. .prepare = omap3_pm_prepare,
  315. .enter = omap3_pm_enter,
  316. .finish = omap3_pm_finish,
  317. .valid = suspend_valid_only_mem,
  318. };
  319. /**
  320. * omap3_iva_idle(): ensure IVA is in idle so it can be put into
  321. * retention
  322. *
  323. * In cases where IVA2 is activated by bootcode, it may prevent
  324. * full-chip retention or off-mode because it is not idle. This
  325. * function forces the IVA2 into idle state so it can go
  326. * into retention/off and thus allow full-chip retention/off.
  327. *
  328. **/
  329. static void __init omap3_iva_idle(void)
  330. {
  331. /* ensure IVA2 clock is disabled */
  332. cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
  333. /* if no clock activity, nothing else to do */
  334. if (!(cm_read_mod_reg(OMAP3430_IVA2_MOD, OMAP3430_CM_CLKSTST) &
  335. OMAP3430_CLKACTIVITY_IVA2_MASK))
  336. return;
  337. /* Reset IVA2 */
  338. prm_write_mod_reg(OMAP3430_RST1_IVA2 |
  339. OMAP3430_RST2_IVA2 |
  340. OMAP3430_RST3_IVA2,
  341. OMAP3430_IVA2_MOD, RM_RSTCTRL);
  342. /* Enable IVA2 clock */
  343. cm_write_mod_reg(OMAP3430_CM_FCLKEN_IVA2_EN_IVA2,
  344. OMAP3430_IVA2_MOD, CM_FCLKEN);
  345. /* Set IVA2 boot mode to 'idle' */
  346. omap_ctrl_writel(OMAP3_IVA2_BOOTMOD_IDLE,
  347. OMAP343X_CONTROL_IVA2_BOOTMOD);
  348. /* Un-reset IVA2 */
  349. prm_write_mod_reg(0, OMAP3430_IVA2_MOD, RM_RSTCTRL);
  350. /* Disable IVA2 clock */
  351. cm_write_mod_reg(0, OMAP3430_IVA2_MOD, CM_FCLKEN);
  352. /* Reset IVA2 */
  353. prm_write_mod_reg(OMAP3430_RST1_IVA2 |
  354. OMAP3430_RST2_IVA2 |
  355. OMAP3430_RST3_IVA2,
  356. OMAP3430_IVA2_MOD, RM_RSTCTRL);
  357. }
  358. static void __init omap3_d2d_idle(void)
  359. {
  360. u16 mask, padconf;
  361. /* In a stand alone OMAP3430 where there is not a stacked
  362. * modem for the D2D Idle Ack and D2D MStandby must be pulled
  363. * high. S CONTROL_PADCONF_SAD2D_IDLEACK and
  364. * CONTROL_PADCONF_SAD2D_MSTDBY to have a pull up. */
  365. mask = (1 << 4) | (1 << 3); /* pull-up, enabled */
  366. padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_MSTANDBY);
  367. padconf |= mask;
  368. omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_MSTANDBY);
  369. padconf = omap_ctrl_readw(OMAP3_PADCONF_SAD2D_IDLEACK);
  370. padconf |= mask;
  371. omap_ctrl_writew(padconf, OMAP3_PADCONF_SAD2D_IDLEACK);
  372. /* reset modem */
  373. prm_write_mod_reg(OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RSTPWRON |
  374. OMAP3430_RM_RSTCTRL_CORE_MODEM_SW_RST,
  375. CORE_MOD, RM_RSTCTRL);
  376. prm_write_mod_reg(0, CORE_MOD, RM_RSTCTRL);
  377. }
  378. static void __init prcm_setup_regs(void)
  379. {
  380. /* XXX Reset all wkdeps. This should be done when initializing
  381. * powerdomains */
  382. prm_write_mod_reg(0, OMAP3430_IVA2_MOD, PM_WKDEP);
  383. prm_write_mod_reg(0, MPU_MOD, PM_WKDEP);
  384. prm_write_mod_reg(0, OMAP3430_DSS_MOD, PM_WKDEP);
  385. prm_write_mod_reg(0, OMAP3430_NEON_MOD, PM_WKDEP);
  386. prm_write_mod_reg(0, OMAP3430_CAM_MOD, PM_WKDEP);
  387. prm_write_mod_reg(0, OMAP3430_PER_MOD, PM_WKDEP);
  388. if (omap_rev() > OMAP3430_REV_ES1_0) {
  389. prm_write_mod_reg(0, OMAP3430ES2_SGX_MOD, PM_WKDEP);
  390. prm_write_mod_reg(0, OMAP3430ES2_USBHOST_MOD, PM_WKDEP);
  391. } else
  392. prm_write_mod_reg(0, GFX_MOD, PM_WKDEP);
  393. /*
  394. * Enable interface clock autoidle for all modules.
  395. * Note that in the long run this should be done by clockfw
  396. */
  397. cm_write_mod_reg(
  398. OMAP3430_AUTO_MODEM |
  399. OMAP3430ES2_AUTO_MMC3 |
  400. OMAP3430ES2_AUTO_ICR |
  401. OMAP3430_AUTO_AES2 |
  402. OMAP3430_AUTO_SHA12 |
  403. OMAP3430_AUTO_DES2 |
  404. OMAP3430_AUTO_MMC2 |
  405. OMAP3430_AUTO_MMC1 |
  406. OMAP3430_AUTO_MSPRO |
  407. OMAP3430_AUTO_HDQ |
  408. OMAP3430_AUTO_MCSPI4 |
  409. OMAP3430_AUTO_MCSPI3 |
  410. OMAP3430_AUTO_MCSPI2 |
  411. OMAP3430_AUTO_MCSPI1 |
  412. OMAP3430_AUTO_I2C3 |
  413. OMAP3430_AUTO_I2C2 |
  414. OMAP3430_AUTO_I2C1 |
  415. OMAP3430_AUTO_UART2 |
  416. OMAP3430_AUTO_UART1 |
  417. OMAP3430_AUTO_GPT11 |
  418. OMAP3430_AUTO_GPT10 |
  419. OMAP3430_AUTO_MCBSP5 |
  420. OMAP3430_AUTO_MCBSP1 |
  421. OMAP3430ES1_AUTO_FAC | /* This is es1 only */
  422. OMAP3430_AUTO_MAILBOXES |
  423. OMAP3430_AUTO_OMAPCTRL |
  424. OMAP3430ES1_AUTO_FSHOSTUSB |
  425. OMAP3430_AUTO_HSOTGUSB |
  426. OMAP3430_AUTO_SAD2D |
  427. OMAP3430_AUTO_SSI,
  428. CORE_MOD, CM_AUTOIDLE1);
  429. cm_write_mod_reg(
  430. OMAP3430_AUTO_PKA |
  431. OMAP3430_AUTO_AES1 |
  432. OMAP3430_AUTO_RNG |
  433. OMAP3430_AUTO_SHA11 |
  434. OMAP3430_AUTO_DES1,
  435. CORE_MOD, CM_AUTOIDLE2);
  436. if (omap_rev() > OMAP3430_REV_ES1_0) {
  437. cm_write_mod_reg(
  438. OMAP3430_AUTO_MAD2D |
  439. OMAP3430ES2_AUTO_USBTLL,
  440. CORE_MOD, CM_AUTOIDLE3);
  441. }
  442. cm_write_mod_reg(
  443. OMAP3430_AUTO_WDT2 |
  444. OMAP3430_AUTO_WDT1 |
  445. OMAP3430_AUTO_GPIO1 |
  446. OMAP3430_AUTO_32KSYNC |
  447. OMAP3430_AUTO_GPT12 |
  448. OMAP3430_AUTO_GPT1 ,
  449. WKUP_MOD, CM_AUTOIDLE);
  450. cm_write_mod_reg(
  451. OMAP3430_AUTO_DSS,
  452. OMAP3430_DSS_MOD,
  453. CM_AUTOIDLE);
  454. cm_write_mod_reg(
  455. OMAP3430_AUTO_CAM,
  456. OMAP3430_CAM_MOD,
  457. CM_AUTOIDLE);
  458. cm_write_mod_reg(
  459. OMAP3430_AUTO_GPIO6 |
  460. OMAP3430_AUTO_GPIO5 |
  461. OMAP3430_AUTO_GPIO4 |
  462. OMAP3430_AUTO_GPIO3 |
  463. OMAP3430_AUTO_GPIO2 |
  464. OMAP3430_AUTO_WDT3 |
  465. OMAP3430_AUTO_UART3 |
  466. OMAP3430_AUTO_GPT9 |
  467. OMAP3430_AUTO_GPT8 |
  468. OMAP3430_AUTO_GPT7 |
  469. OMAP3430_AUTO_GPT6 |
  470. OMAP3430_AUTO_GPT5 |
  471. OMAP3430_AUTO_GPT4 |
  472. OMAP3430_AUTO_GPT3 |
  473. OMAP3430_AUTO_GPT2 |
  474. OMAP3430_AUTO_MCBSP4 |
  475. OMAP3430_AUTO_MCBSP3 |
  476. OMAP3430_AUTO_MCBSP2,
  477. OMAP3430_PER_MOD,
  478. CM_AUTOIDLE);
  479. if (omap_rev() > OMAP3430_REV_ES1_0) {
  480. cm_write_mod_reg(
  481. OMAP3430ES2_AUTO_USBHOST,
  482. OMAP3430ES2_USBHOST_MOD,
  483. CM_AUTOIDLE);
  484. }
  485. /*
  486. * Set all plls to autoidle. This is needed until autoidle is
  487. * enabled by clockfw
  488. */
  489. cm_write_mod_reg(1 << OMAP3430_AUTO_IVA2_DPLL_SHIFT,
  490. OMAP3430_IVA2_MOD, CM_AUTOIDLE2);
  491. cm_write_mod_reg(1 << OMAP3430_AUTO_MPU_DPLL_SHIFT,
  492. MPU_MOD,
  493. CM_AUTOIDLE2);
  494. cm_write_mod_reg((1 << OMAP3430_AUTO_PERIPH_DPLL_SHIFT) |
  495. (1 << OMAP3430_AUTO_CORE_DPLL_SHIFT),
  496. PLL_MOD,
  497. CM_AUTOIDLE);
  498. cm_write_mod_reg(1 << OMAP3430ES2_AUTO_PERIPH2_DPLL_SHIFT,
  499. PLL_MOD,
  500. CM_AUTOIDLE2);
  501. /*
  502. * Enable control of expternal oscillator through
  503. * sys_clkreq. In the long run clock framework should
  504. * take care of this.
  505. */
  506. prm_rmw_mod_reg_bits(OMAP_AUTOEXTCLKMODE_MASK,
  507. 1 << OMAP_AUTOEXTCLKMODE_SHIFT,
  508. OMAP3430_GR_MOD,
  509. OMAP3_PRM_CLKSRC_CTRL_OFFSET);
  510. /* setup wakup source */
  511. prm_write_mod_reg(OMAP3430_EN_IO | OMAP3430_EN_GPIO1 |
  512. OMAP3430_EN_GPT1 | OMAP3430_EN_GPT12,
  513. WKUP_MOD, PM_WKEN);
  514. /* No need to write EN_IO, that is always enabled */
  515. prm_write_mod_reg(OMAP3430_EN_GPIO1 | OMAP3430_EN_GPT1 |
  516. OMAP3430_EN_GPT12,
  517. WKUP_MOD, OMAP3430_PM_MPUGRPSEL);
  518. /* For some reason IO doesn't generate wakeup event even if
  519. * it is selected to mpu wakeup goup */
  520. prm_write_mod_reg(OMAP3430_IO_EN | OMAP3430_WKUP_EN,
  521. OCP_MOD, OMAP3_PRM_IRQENABLE_MPU_OFFSET);
  522. /* Don't attach IVA interrupts */
  523. prm_write_mod_reg(0, WKUP_MOD, OMAP3430_PM_IVAGRPSEL);
  524. prm_write_mod_reg(0, CORE_MOD, OMAP3430_PM_IVAGRPSEL1);
  525. prm_write_mod_reg(0, CORE_MOD, OMAP3430ES2_PM_IVAGRPSEL3);
  526. prm_write_mod_reg(0, OMAP3430_PER_MOD, OMAP3430_PM_IVAGRPSEL);
  527. /* Clear any pending 'reset' flags */
  528. prm_write_mod_reg(0xffffffff, MPU_MOD, RM_RSTST);
  529. prm_write_mod_reg(0xffffffff, CORE_MOD, RM_RSTST);
  530. prm_write_mod_reg(0xffffffff, OMAP3430_PER_MOD, RM_RSTST);
  531. prm_write_mod_reg(0xffffffff, OMAP3430_EMU_MOD, RM_RSTST);
  532. prm_write_mod_reg(0xffffffff, OMAP3430_NEON_MOD, RM_RSTST);
  533. prm_write_mod_reg(0xffffffff, OMAP3430_DSS_MOD, RM_RSTST);
  534. prm_write_mod_reg(0xffffffff, OMAP3430ES2_USBHOST_MOD, RM_RSTST);
  535. /* Clear any pending PRCM interrupts */
  536. prm_write_mod_reg(0, OCP_MOD, OMAP3_PRM_IRQSTATUS_MPU_OFFSET);
  537. omap3_iva_idle();
  538. omap3_d2d_idle();
  539. }
  540. static int __init pwrdms_setup(struct powerdomain *pwrdm)
  541. {
  542. struct power_state *pwrst;
  543. if (!pwrdm->pwrsts)
  544. return 0;
  545. pwrst = kmalloc(sizeof(struct power_state), GFP_KERNEL);
  546. if (!pwrst)
  547. return -ENOMEM;
  548. pwrst->pwrdm = pwrdm;
  549. pwrst->next_state = PWRDM_POWER_RET;
  550. list_add(&pwrst->node, &pwrst_list);
  551. if (pwrdm_has_hdwr_sar(pwrdm))
  552. pwrdm_enable_hdwr_sar(pwrdm);
  553. return set_pwrdm_state(pwrst->pwrdm, pwrst->next_state);
  554. }
  555. /*
  556. * Enable hw supervised mode for all clockdomains if it's
  557. * supported. Initiate sleep transition for other clockdomains, if
  558. * they are not used
  559. */
  560. static int __init clkdms_setup(struct clockdomain *clkdm)
  561. {
  562. if (clkdm->flags & CLKDM_CAN_ENABLE_AUTO)
  563. omap2_clkdm_allow_idle(clkdm);
  564. else if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP &&
  565. atomic_read(&clkdm->usecount) == 0)
  566. omap2_clkdm_sleep(clkdm);
  567. return 0;
  568. }
  569. int __init omap3_pm_init(void)
  570. {
  571. struct power_state *pwrst, *tmp;
  572. int ret;
  573. if (!cpu_is_omap34xx())
  574. return -ENODEV;
  575. printk(KERN_ERR "Power Management for TI OMAP3.\n");
  576. /* XXX prcm_setup_regs needs to be before enabling hw
  577. * supervised mode for powerdomains */
  578. prcm_setup_regs();
  579. ret = request_irq(INT_34XX_PRCM_MPU_IRQ,
  580. (irq_handler_t)prcm_interrupt_handler,
  581. IRQF_DISABLED, "prcm", NULL);
  582. if (ret) {
  583. printk(KERN_ERR "request_irq failed to register for 0x%x\n",
  584. INT_34XX_PRCM_MPU_IRQ);
  585. goto err1;
  586. }
  587. ret = pwrdm_for_each(pwrdms_setup);
  588. if (ret) {
  589. printk(KERN_ERR "Failed to setup powerdomains\n");
  590. goto err2;
  591. }
  592. (void) clkdm_for_each(clkdms_setup);
  593. mpu_pwrdm = pwrdm_lookup("mpu_pwrdm");
  594. if (mpu_pwrdm == NULL) {
  595. printk(KERN_ERR "Failed to get mpu_pwrdm\n");
  596. goto err2;
  597. }
  598. _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
  599. omap34xx_cpu_suspend_sz);
  600. suspend_set_ops(&omap_pm_ops);
  601. pm_idle = omap3_pm_idle;
  602. err1:
  603. return ret;
  604. err2:
  605. free_irq(INT_34XX_PRCM_MPU_IRQ, NULL);
  606. list_for_each_entry_safe(pwrst, tmp, &pwrst_list, node) {
  607. list_del(&pwrst->node);
  608. kfree(pwrst);
  609. }
  610. return ret;
  611. }
  612. late_initcall(omap3_pm_init);