prm44xx.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * OMAP4 PRM module functions
  4. *
  5. * Copyright (C) 2011-2012 Texas Instruments, Inc.
  6. * Copyright (C) 2010 Nokia Corporation
  7. * Benoît Cousson
  8. * Paul Walmsley
  9. * Rajendra Nayak <[email protected]>
  10. */
  11. #include <linux/cpu_pm.h>
  12. #include <linux/kernel.h>
  13. #include <linux/delay.h>
  14. #include <linux/errno.h>
  15. #include <linux/err.h>
  16. #include <linux/io.h>
  17. #include <linux/of_irq.h>
  18. #include <linux/of.h>
  19. #include "soc.h"
  20. #include "iomap.h"
  21. #include "common.h"
  22. #include "vp.h"
  23. #include "prm44xx.h"
  24. #include "prcm43xx.h"
  25. #include "prm-regbits-44xx.h"
  26. #include "prcm44xx.h"
  27. #include "prminst44xx.h"
  28. #include "powerdomain.h"
  29. #include "pm.h"
  30. /* Static data */
  31. static void omap44xx_prm_read_pending_irqs(unsigned long *events);
  32. static void omap44xx_prm_ocp_barrier(void);
  33. static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask);
  34. static void omap44xx_prm_restore_irqen(u32 *saved_mask);
  35. static void omap44xx_prm_reconfigure_io_chain(void);
  36. static const struct omap_prcm_irq omap4_prcm_irqs[] = {
  37. OMAP_PRCM_IRQ("io", 9, 1),
  38. };
  39. static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
  40. .ack = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
  41. .mask = OMAP4_PRM_IRQENABLE_MPU_OFFSET,
  42. .pm_ctrl = OMAP4_PRM_IO_PMCTRL_OFFSET,
  43. .nr_regs = 2,
  44. .irqs = omap4_prcm_irqs,
  45. .nr_irqs = ARRAY_SIZE(omap4_prcm_irqs),
  46. .read_pending_irqs = &omap44xx_prm_read_pending_irqs,
  47. .ocp_barrier = &omap44xx_prm_ocp_barrier,
  48. .save_and_clear_irqen = &omap44xx_prm_save_and_clear_irqen,
  49. .restore_irqen = &omap44xx_prm_restore_irqen,
  50. .reconfigure_io_chain = &omap44xx_prm_reconfigure_io_chain,
  51. };
  52. struct omap_prm_irq_context {
  53. unsigned long irq_enable;
  54. unsigned long pm_ctrl;
  55. };
  56. static struct omap_prm_irq_context omap_prm_context;
  57. /*
  58. * omap44xx_prm_reset_src_map - map from bits in the PRM_RSTST
  59. * hardware register (which are specific to OMAP44xx SoCs) to reset
  60. * source ID bit shifts (which is an OMAP SoC-independent
  61. * enumeration)
  62. */
  63. static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = {
  64. { OMAP4430_GLOBAL_WARM_SW_RST_SHIFT,
  65. OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT },
  66. { OMAP4430_GLOBAL_COLD_RST_SHIFT,
  67. OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT },
  68. { OMAP4430_MPU_SECURITY_VIOL_RST_SHIFT,
  69. OMAP_SECU_VIOL_RST_SRC_ID_SHIFT },
  70. { OMAP4430_MPU_WDT_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
  71. { OMAP4430_SECURE_WDT_RST_SHIFT, OMAP_SECU_WD_RST_SRC_ID_SHIFT },
  72. { OMAP4430_EXTERNAL_WARM_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT },
  73. { OMAP4430_VDD_MPU_VOLT_MGR_RST_SHIFT,
  74. OMAP_VDD_MPU_VM_RST_SRC_ID_SHIFT },
  75. { OMAP4430_VDD_IVA_VOLT_MGR_RST_SHIFT,
  76. OMAP_VDD_IVA_VM_RST_SRC_ID_SHIFT },
  77. { OMAP4430_VDD_CORE_VOLT_MGR_RST_SHIFT,
  78. OMAP_VDD_CORE_VM_RST_SRC_ID_SHIFT },
  79. { OMAP4430_ICEPICK_RST_SHIFT, OMAP_ICEPICK_RST_SRC_ID_SHIFT },
  80. { OMAP4430_C2C_RST_SHIFT, OMAP_C2C_RST_SRC_ID_SHIFT },
  81. { -1, -1 },
  82. };
  83. /* PRM low-level functions */
  84. /* Read a register in a CM/PRM instance in the PRM module */
  85. static u32 omap4_prm_read_inst_reg(s16 inst, u16 reg)
  86. {
  87. return readl_relaxed(prm_base.va + inst + reg);
  88. }
  89. /* Write into a register in a CM/PRM instance in the PRM module */
  90. static void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg)
  91. {
  92. writel_relaxed(val, prm_base.va + inst + reg);
  93. }
  94. /* Read-modify-write a register in a PRM module. Caller must lock */
  95. static u32 omap4_prm_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg)
  96. {
  97. u32 v;
  98. v = omap4_prm_read_inst_reg(inst, reg);
  99. v &= ~mask;
  100. v |= bits;
  101. omap4_prm_write_inst_reg(v, inst, reg);
  102. return v;
  103. }
  104. /* PRM VP */
  105. /*
  106. * struct omap4_vp - OMAP4 VP register access description.
  107. * @irqstatus_mpu: offset to IRQSTATUS_MPU register for VP
  108. * @tranxdone_status: VP_TRANXDONE_ST bitmask in PRM_IRQSTATUS_MPU reg
  109. */
  110. struct omap4_vp {
  111. u32 irqstatus_mpu;
  112. u32 tranxdone_status;
  113. };
  114. static struct omap4_vp omap4_vp[] = {
  115. [OMAP4_VP_VDD_MPU_ID] = {
  116. .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET,
  117. .tranxdone_status = OMAP4430_VP_MPU_TRANXDONE_ST_MASK,
  118. },
  119. [OMAP4_VP_VDD_IVA_ID] = {
  120. .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
  121. .tranxdone_status = OMAP4430_VP_IVA_TRANXDONE_ST_MASK,
  122. },
  123. [OMAP4_VP_VDD_CORE_ID] = {
  124. .irqstatus_mpu = OMAP4_PRM_IRQSTATUS_MPU_OFFSET,
  125. .tranxdone_status = OMAP4430_VP_CORE_TRANXDONE_ST_MASK,
  126. },
  127. };
  128. static u32 omap4_prm_vp_check_txdone(u8 vp_id)
  129. {
  130. struct omap4_vp *vp = &omap4_vp[vp_id];
  131. u32 irqstatus;
  132. irqstatus = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
  133. OMAP4430_PRM_OCP_SOCKET_INST,
  134. vp->irqstatus_mpu);
  135. return irqstatus & vp->tranxdone_status;
  136. }
  137. static void omap4_prm_vp_clear_txdone(u8 vp_id)
  138. {
  139. struct omap4_vp *vp = &omap4_vp[vp_id];
  140. omap4_prminst_write_inst_reg(vp->tranxdone_status,
  141. OMAP4430_PRM_PARTITION,
  142. OMAP4430_PRM_OCP_SOCKET_INST,
  143. vp->irqstatus_mpu);
  144. };
  145. u32 omap4_prm_vcvp_read(u8 offset)
  146. {
  147. s32 inst = omap4_prmst_get_prm_dev_inst();
  148. if (inst == PRM_INSTANCE_UNKNOWN)
  149. return 0;
  150. return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
  151. inst, offset);
  152. }
  153. void omap4_prm_vcvp_write(u32 val, u8 offset)
  154. {
  155. s32 inst = omap4_prmst_get_prm_dev_inst();
  156. if (inst == PRM_INSTANCE_UNKNOWN)
  157. return;
  158. omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION,
  159. inst, offset);
  160. }
  161. u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
  162. {
  163. s32 inst = omap4_prmst_get_prm_dev_inst();
  164. if (inst == PRM_INSTANCE_UNKNOWN)
  165. return 0;
  166. return omap4_prminst_rmw_inst_reg_bits(mask, bits,
  167. OMAP4430_PRM_PARTITION,
  168. inst,
  169. offset);
  170. }
  171. static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs)
  172. {
  173. u32 mask, st;
  174. /* XXX read mask from RAM? */
  175. mask = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
  176. irqen_offs);
  177. st = omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, irqst_offs);
  178. return mask & st;
  179. }
  180. /**
  181. * omap44xx_prm_read_pending_irqs - read pending PRM MPU IRQs into @events
  182. * @events: ptr to two consecutive u32s, preallocated by caller
  183. *
  184. * Read PRM_IRQSTATUS_MPU* bits, AND'ed with the currently-enabled PRM
  185. * MPU IRQs, and store the result into the two u32s pointed to by @events.
  186. * No return value.
  187. */
  188. static void omap44xx_prm_read_pending_irqs(unsigned long *events)
  189. {
  190. int i;
  191. for (i = 0; i < omap4_prcm_irq_setup.nr_regs; i++)
  192. events[i] = _read_pending_irq_reg(omap4_prcm_irq_setup.mask +
  193. i * 4, omap4_prcm_irq_setup.ack + i * 4);
  194. }
  195. /**
  196. * omap44xx_prm_ocp_barrier - force buffered MPU writes to the PRM to complete
  197. *
  198. * Force any buffered writes to the PRM IP block to complete. Needed
  199. * by the PRM IRQ handler, which reads and writes directly to the IP
  200. * block, to avoid race conditions after acknowledging or clearing IRQ
  201. * bits. No return value.
  202. */
  203. static void omap44xx_prm_ocp_barrier(void)
  204. {
  205. omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
  206. OMAP4_REVISION_PRM_OFFSET);
  207. }
  208. /**
  209. * omap44xx_prm_save_and_clear_irqen - save/clear PRM_IRQENABLE_MPU* regs
  210. * @saved_mask: ptr to a u32 array to save IRQENABLE bits
  211. *
  212. * Save the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers to
  213. * @saved_mask. @saved_mask must be allocated by the caller.
  214. * Intended to be used in the PRM interrupt handler suspend callback.
  215. * The OCP barrier is needed to ensure the write to disable PRM
  216. * interrupts reaches the PRM before returning; otherwise, spurious
  217. * interrupts might occur. No return value.
  218. */
  219. static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask)
  220. {
  221. int i;
  222. u16 reg;
  223. for (i = 0; i < omap4_prcm_irq_setup.nr_regs; i++) {
  224. reg = omap4_prcm_irq_setup.mask + i * 4;
  225. saved_mask[i] =
  226. omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
  227. reg);
  228. omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, reg);
  229. }
  230. /* OCP barrier */
  231. omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST,
  232. OMAP4_REVISION_PRM_OFFSET);
  233. }
  234. /**
  235. * omap44xx_prm_restore_irqen - set PRM_IRQENABLE_MPU* registers from args
  236. * @saved_mask: ptr to a u32 array of IRQENABLE bits saved previously
  237. *
  238. * Restore the PRM_IRQENABLE_MPU and PRM_IRQENABLE_MPU_2 registers from
  239. * @saved_mask. Intended to be used in the PRM interrupt handler resume
  240. * callback to restore values saved by omap44xx_prm_save_and_clear_irqen().
  241. * No OCP barrier should be needed here; any pending PRM interrupts will fire
  242. * once the writes reach the PRM. No return value.
  243. */
  244. static void omap44xx_prm_restore_irqen(u32 *saved_mask)
  245. {
  246. int i;
  247. for (i = 0; i < omap4_prcm_irq_setup.nr_regs; i++)
  248. omap4_prm_write_inst_reg(saved_mask[i],
  249. OMAP4430_PRM_OCP_SOCKET_INST,
  250. omap4_prcm_irq_setup.mask + i * 4);
  251. }
  252. /**
  253. * omap44xx_prm_reconfigure_io_chain - clear latches and reconfigure I/O chain
  254. *
  255. * Clear any previously-latched I/O wakeup events and ensure that the
  256. * I/O wakeup gates are aligned with the current mux settings. Works
  257. * by asserting WUCLKIN, waiting for WUCLKOUT to be asserted, and then
  258. * deasserting WUCLKIN and waiting for WUCLKOUT to be deasserted.
  259. * No return value. XXX Are the final two steps necessary?
  260. */
  261. static void omap44xx_prm_reconfigure_io_chain(void)
  262. {
  263. int i = 0;
  264. s32 inst = omap4_prmst_get_prm_dev_inst();
  265. if (inst == PRM_INSTANCE_UNKNOWN)
  266. return;
  267. /* Trigger WUCLKIN enable */
  268. omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK,
  269. OMAP4430_WUCLK_CTRL_MASK,
  270. inst,
  271. omap4_prcm_irq_setup.pm_ctrl);
  272. omap_test_timeout(
  273. (((omap4_prm_read_inst_reg(inst,
  274. omap4_prcm_irq_setup.pm_ctrl) &
  275. OMAP4430_WUCLK_STATUS_MASK) >>
  276. OMAP4430_WUCLK_STATUS_SHIFT) == 1),
  277. MAX_IOPAD_LATCH_TIME, i);
  278. if (i == MAX_IOPAD_LATCH_TIME)
  279. pr_warn("PRM: I/O chain clock line assertion timed out\n");
  280. /* Trigger WUCLKIN disable */
  281. omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 0x0,
  282. inst,
  283. omap4_prcm_irq_setup.pm_ctrl);
  284. omap_test_timeout(
  285. (((omap4_prm_read_inst_reg(inst,
  286. omap4_prcm_irq_setup.pm_ctrl) &
  287. OMAP4430_WUCLK_STATUS_MASK) >>
  288. OMAP4430_WUCLK_STATUS_SHIFT) == 0),
  289. MAX_IOPAD_LATCH_TIME, i);
  290. if (i == MAX_IOPAD_LATCH_TIME)
  291. pr_warn("PRM: I/O chain clock line deassertion timed out\n");
  292. return;
  293. }
  294. /**
  295. * omap44xx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches
  296. *
  297. * Activates the I/O wakeup event latches and allows events logged by
  298. * those latches to signal a wakeup event to the PRCM. For I/O wakeups
  299. * to occur, WAKEUPENABLE bits must be set in the pad mux registers, and
  300. * omap44xx_prm_reconfigure_io_chain() must be called. No return value.
  301. */
  302. static void omap44xx_prm_enable_io_wakeup(void)
  303. {
  304. s32 inst = omap4_prmst_get_prm_dev_inst();
  305. if (inst == PRM_INSTANCE_UNKNOWN)
  306. return;
  307. omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
  308. OMAP4430_GLOBAL_WUEN_MASK,
  309. inst,
  310. omap4_prcm_irq_setup.pm_ctrl);
  311. }
  312. /**
  313. * omap44xx_prm_read_reset_sources - return the last SoC reset source
  314. *
  315. * Return a u32 representing the last reset sources of the SoC. The
  316. * returned reset source bits are standardized across OMAP SoCs.
  317. */
  318. static u32 omap44xx_prm_read_reset_sources(void)
  319. {
  320. struct prm_reset_src_map *p;
  321. u32 r = 0;
  322. u32 v;
  323. s32 inst = omap4_prmst_get_prm_dev_inst();
  324. if (inst == PRM_INSTANCE_UNKNOWN)
  325. return 0;
  326. v = omap4_prm_read_inst_reg(inst,
  327. OMAP4_RM_RSTST);
  328. p = omap44xx_prm_reset_src_map;
  329. while (p->reg_shift >= 0 && p->std_shift >= 0) {
  330. if (v & (1 << p->reg_shift))
  331. r |= 1 << p->std_shift;
  332. p++;
  333. }
  334. return r;
  335. }
  336. /**
  337. * omap44xx_prm_was_any_context_lost_old - was module hardware context lost?
  338. * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
  339. * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
  340. * @idx: CONTEXT register offset
  341. *
  342. * Return 1 if any bits were set in the *_CONTEXT_* register
  343. * identified by (@part, @inst, @idx), which means that some context
  344. * was lost for that module; otherwise, return 0.
  345. */
  346. static bool omap44xx_prm_was_any_context_lost_old(u8 part, s16 inst, u16 idx)
  347. {
  348. return (omap4_prminst_read_inst_reg(part, inst, idx)) ? 1 : 0;
  349. }
  350. /**
  351. * omap44xx_prm_clear_context_lost_flags_old - clear context loss flags
  352. * @part: PRM partition ID (e.g., OMAP4430_PRM_PARTITION)
  353. * @inst: PRM instance offset (e.g., OMAP4430_PRM_MPU_INST)
  354. * @idx: CONTEXT register offset
  355. *
  356. * Clear hardware context loss bits for the module identified by
  357. * (@part, @inst, @idx). No return value. XXX Writes to reserved bits;
  358. * is there a way to avoid this?
  359. */
  360. static void omap44xx_prm_clear_context_loss_flags_old(u8 part, s16 inst,
  361. u16 idx)
  362. {
  363. omap4_prminst_write_inst_reg(0xffffffff, part, inst, idx);
  364. }
  365. /* Powerdomain low-level functions */
  366. static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
  367. {
  368. omap4_prminst_rmw_inst_reg_bits(OMAP_POWERSTATE_MASK,
  369. (pwrst << OMAP_POWERSTATE_SHIFT),
  370. pwrdm->prcm_partition,
  371. pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
  372. return 0;
  373. }
  374. static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
  375. {
  376. u32 v;
  377. v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
  378. OMAP4_PM_PWSTCTRL);
  379. v &= OMAP_POWERSTATE_MASK;
  380. v >>= OMAP_POWERSTATE_SHIFT;
  381. return v;
  382. }
  383. static int omap4_pwrdm_read_pwrst(struct powerdomain *pwrdm)
  384. {
  385. u32 v;
  386. v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
  387. OMAP4_PM_PWSTST);
  388. v &= OMAP_POWERSTATEST_MASK;
  389. v >>= OMAP_POWERSTATEST_SHIFT;
  390. return v;
  391. }
  392. static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
  393. {
  394. u32 v;
  395. v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
  396. OMAP4_PM_PWSTST);
  397. v &= OMAP4430_LASTPOWERSTATEENTERED_MASK;
  398. v >>= OMAP4430_LASTPOWERSTATEENTERED_SHIFT;
  399. return v;
  400. }
  401. static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
  402. {
  403. omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK,
  404. (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT),
  405. pwrdm->prcm_partition,
  406. pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
  407. return 0;
  408. }
  409. static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
  410. {
  411. omap4_prminst_rmw_inst_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK,
  412. OMAP4430_LASTPOWERSTATEENTERED_MASK,
  413. pwrdm->prcm_partition,
  414. pwrdm->prcm_offs, OMAP4_PM_PWSTST);
  415. return 0;
  416. }
  417. static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
  418. {
  419. u32 v;
  420. v = pwrst << __ffs(OMAP4430_LOGICRETSTATE_MASK);
  421. omap4_prminst_rmw_inst_reg_bits(OMAP4430_LOGICRETSTATE_MASK, v,
  422. pwrdm->prcm_partition, pwrdm->prcm_offs,
  423. OMAP4_PM_PWSTCTRL);
  424. return 0;
  425. }
  426. static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
  427. u8 pwrst)
  428. {
  429. u32 m;
  430. m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
  431. omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
  432. pwrdm->prcm_partition, pwrdm->prcm_offs,
  433. OMAP4_PM_PWSTCTRL);
  434. return 0;
  435. }
  436. static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
  437. u8 pwrst)
  438. {
  439. u32 m;
  440. m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
  441. omap4_prminst_rmw_inst_reg_bits(m, (pwrst << __ffs(m)),
  442. pwrdm->prcm_partition, pwrdm->prcm_offs,
  443. OMAP4_PM_PWSTCTRL);
  444. return 0;
  445. }
  446. static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
  447. {
  448. u32 v;
  449. v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
  450. OMAP4_PM_PWSTST);
  451. v &= OMAP4430_LOGICSTATEST_MASK;
  452. v >>= OMAP4430_LOGICSTATEST_SHIFT;
  453. return v;
  454. }
  455. static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
  456. {
  457. u32 v;
  458. v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
  459. OMAP4_PM_PWSTCTRL);
  460. v &= OMAP4430_LOGICRETSTATE_MASK;
  461. v >>= OMAP4430_LOGICRETSTATE_SHIFT;
  462. return v;
  463. }
  464. /**
  465. * omap4_pwrdm_read_prev_logic_pwrst - read the previous logic powerstate
  466. * @pwrdm: struct powerdomain * to read the state for
  467. *
  468. * Reads the previous logic powerstate for a powerdomain. This
  469. * function must determine the previous logic powerstate by first
  470. * checking the previous powerstate for the domain. If that was OFF,
  471. * then logic has been lost. If previous state was RETENTION, the
  472. * function reads the setting for the next retention logic state to
  473. * see the actual value. In every other case, the logic is
  474. * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
  475. * depending whether the logic was retained or not.
  476. */
  477. static int omap4_pwrdm_read_prev_logic_pwrst(struct powerdomain *pwrdm)
  478. {
  479. int state;
  480. state = omap4_pwrdm_read_prev_pwrst(pwrdm);
  481. if (state == PWRDM_POWER_OFF)
  482. return PWRDM_POWER_OFF;
  483. if (state != PWRDM_POWER_RET)
  484. return PWRDM_POWER_RET;
  485. return omap4_pwrdm_read_logic_retst(pwrdm);
  486. }
  487. static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
  488. {
  489. u32 m, v;
  490. m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
  491. v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
  492. OMAP4_PM_PWSTST);
  493. v &= m;
  494. v >>= __ffs(m);
  495. return v;
  496. }
  497. static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
  498. {
  499. u32 m, v;
  500. m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
  501. v = omap4_prminst_read_inst_reg(pwrdm->prcm_partition, pwrdm->prcm_offs,
  502. OMAP4_PM_PWSTCTRL);
  503. v &= m;
  504. v >>= __ffs(m);
  505. return v;
  506. }
  507. /**
  508. * omap4_pwrdm_read_prev_mem_pwrst - reads the previous memory powerstate
  509. * @pwrdm: struct powerdomain * to read mem powerstate for
  510. * @bank: memory bank index
  511. *
  512. * Reads the previous memory powerstate for a powerdomain. This
  513. * function must determine the previous memory powerstate by first
  514. * checking the previous powerstate for the domain. If that was OFF,
  515. * then logic has been lost. If previous state was RETENTION, the
  516. * function reads the setting for the next memory retention state to
  517. * see the actual value. In every other case, the logic is
  518. * retained. Returns either PWRDM_POWER_OFF or PWRDM_POWER_RET
  519. * depending whether logic was retained or not.
  520. */
  521. static int omap4_pwrdm_read_prev_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
  522. {
  523. int state;
  524. state = omap4_pwrdm_read_prev_pwrst(pwrdm);
  525. if (state == PWRDM_POWER_OFF)
  526. return PWRDM_POWER_OFF;
  527. if (state != PWRDM_POWER_RET)
  528. return PWRDM_POWER_RET;
  529. return omap4_pwrdm_read_mem_retst(pwrdm, bank);
  530. }
  531. static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
  532. {
  533. u32 c = 0;
  534. /*
  535. * REVISIT: pwrdm_wait_transition() may be better implemented
  536. * via a callback and a periodic timer check -- how long do we expect
  537. * powerdomain transitions to take?
  538. */
  539. /* XXX Is this udelay() value meaningful? */
  540. while ((omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
  541. pwrdm->prcm_offs,
  542. OMAP4_PM_PWSTST) &
  543. OMAP_INTRANSITION_MASK) &&
  544. (c++ < PWRDM_TRANSITION_BAILOUT))
  545. udelay(1);
  546. if (c > PWRDM_TRANSITION_BAILOUT) {
  547. pr_err("powerdomain: %s: waited too long to complete transition\n",
  548. pwrdm->name);
  549. return -EAGAIN;
  550. }
  551. pr_debug("powerdomain: completed transition in %d loops\n", c);
  552. return 0;
  553. }
  554. static int omap4_check_vcvp(void)
  555. {
  556. if (prm_features & PRM_HAS_VOLTAGE)
  557. return 1;
  558. return 0;
  559. }
  560. /**
  561. * omap4_pwrdm_save_context - Saves the powerdomain state
  562. * @pwrdm: pointer to individual powerdomain
  563. *
  564. * The function saves the powerdomain state control information.
  565. * This is needed in rtc+ddr modes where we lose powerdomain context.
  566. */
  567. static void omap4_pwrdm_save_context(struct powerdomain *pwrdm)
  568. {
  569. pwrdm->context = omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
  570. pwrdm->prcm_offs,
  571. pwrdm->pwrstctrl_offs);
  572. /*
  573. * Do not save LOWPOWERSTATECHANGE, writing a 1 indicates a request,
  574. * reading back a 1 indicates a request in progress.
  575. */
  576. pwrdm->context &= ~OMAP4430_LOWPOWERSTATECHANGE_MASK;
  577. }
  578. /**
  579. * omap4_pwrdm_restore_context - Restores the powerdomain state
  580. * @pwrdm: pointer to individual powerdomain
  581. *
  582. * The function restores the powerdomain state control information.
  583. * This is needed in rtc+ddr modes where we lose powerdomain context.
  584. */
  585. static void omap4_pwrdm_restore_context(struct powerdomain *pwrdm)
  586. {
  587. int st, ctrl;
  588. st = omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
  589. pwrdm->prcm_offs,
  590. pwrdm->pwrstctrl_offs);
  591. omap4_prminst_write_inst_reg(pwrdm->context,
  592. pwrdm->prcm_partition,
  593. pwrdm->prcm_offs,
  594. pwrdm->pwrstctrl_offs);
  595. /* Make sure we only wait for a transition if there is one */
  596. st &= OMAP_POWERSTATEST_MASK;
  597. ctrl = OMAP_POWERSTATEST_MASK & pwrdm->context;
  598. if (st != ctrl)
  599. omap4_pwrdm_wait_transition(pwrdm);
  600. }
  601. struct pwrdm_ops omap4_pwrdm_operations = {
  602. .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst,
  603. .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst,
  604. .pwrdm_read_pwrst = omap4_pwrdm_read_pwrst,
  605. .pwrdm_read_prev_pwrst = omap4_pwrdm_read_prev_pwrst,
  606. .pwrdm_set_lowpwrstchange = omap4_pwrdm_set_lowpwrstchange,
  607. .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst,
  608. .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst,
  609. .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst,
  610. .pwrdm_read_prev_logic_pwrst = omap4_pwrdm_read_prev_logic_pwrst,
  611. .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst,
  612. .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst,
  613. .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst,
  614. .pwrdm_read_prev_mem_pwrst = omap4_pwrdm_read_prev_mem_pwrst,
  615. .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst,
  616. .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst,
  617. .pwrdm_wait_transition = omap4_pwrdm_wait_transition,
  618. .pwrdm_has_voltdm = omap4_check_vcvp,
  619. .pwrdm_save_context = omap4_pwrdm_save_context,
  620. .pwrdm_restore_context = omap4_pwrdm_restore_context,
  621. };
  622. static int omap44xx_prm_late_init(void);
  623. static void prm_save_context(void)
  624. {
  625. omap_prm_context.irq_enable =
  626. omap4_prm_read_inst_reg(AM43XX_PRM_OCP_SOCKET_INST,
  627. omap4_prcm_irq_setup.mask);
  628. omap_prm_context.pm_ctrl =
  629. omap4_prm_read_inst_reg(AM43XX_PRM_DEVICE_INST,
  630. omap4_prcm_irq_setup.pm_ctrl);
  631. }
  632. static void prm_restore_context(void)
  633. {
  634. omap4_prm_write_inst_reg(omap_prm_context.irq_enable,
  635. OMAP4430_PRM_OCP_SOCKET_INST,
  636. omap4_prcm_irq_setup.mask);
  637. omap4_prm_write_inst_reg(omap_prm_context.pm_ctrl,
  638. AM43XX_PRM_DEVICE_INST,
  639. omap4_prcm_irq_setup.pm_ctrl);
  640. }
  641. static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v)
  642. {
  643. switch (cmd) {
  644. case CPU_CLUSTER_PM_ENTER:
  645. if (enable_off_mode)
  646. prm_save_context();
  647. break;
  648. case CPU_CLUSTER_PM_EXIT:
  649. if (enable_off_mode)
  650. prm_restore_context();
  651. break;
  652. }
  653. return NOTIFY_OK;
  654. }
  655. /*
  656. * XXX document
  657. */
  658. static struct prm_ll_data omap44xx_prm_ll_data = {
  659. .read_reset_sources = &omap44xx_prm_read_reset_sources,
  660. .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old,
  661. .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old,
  662. .late_init = &omap44xx_prm_late_init,
  663. .assert_hardreset = omap4_prminst_assert_hardreset,
  664. .deassert_hardreset = omap4_prminst_deassert_hardreset,
  665. .is_hardreset_asserted = omap4_prminst_is_hardreset_asserted,
  666. .reset_system = omap4_prminst_global_warm_sw_reset,
  667. .vp_check_txdone = omap4_prm_vp_check_txdone,
  668. .vp_clear_txdone = omap4_prm_vp_clear_txdone,
  669. };
  670. static const struct omap_prcm_init_data *prm_init_data;
  671. int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
  672. {
  673. static struct notifier_block nb;
  674. omap_prm_base_init();
  675. prm_init_data = data;
  676. if (data->flags & PRM_HAS_IO_WAKEUP)
  677. prm_features |= PRM_HAS_IO_WAKEUP;
  678. if (data->flags & PRM_HAS_VOLTAGE)
  679. prm_features |= PRM_HAS_VOLTAGE;
  680. omap4_prminst_set_prm_dev_inst(data->device_inst_offset);
  681. /* Add AM437X specific differences */
  682. if (of_device_is_compatible(data->np, "ti,am4-prcm")) {
  683. omap4_prcm_irq_setup.nr_irqs = 1;
  684. omap4_prcm_irq_setup.nr_regs = 1;
  685. omap4_prcm_irq_setup.pm_ctrl = AM43XX_PRM_IO_PMCTRL_OFFSET;
  686. omap4_prcm_irq_setup.ack = AM43XX_PRM_IRQSTATUS_MPU_OFFSET;
  687. omap4_prcm_irq_setup.mask = AM43XX_PRM_IRQENABLE_MPU_OFFSET;
  688. }
  689. /* Only AM43XX can lose prm context during rtc-ddr suspend */
  690. if (soc_is_am43xx()) {
  691. nb.notifier_call = cpu_notifier;
  692. cpu_pm_register_notifier(&nb);
  693. }
  694. return prm_register(&omap44xx_prm_ll_data);
  695. }
  696. static int omap44xx_prm_late_init(void)
  697. {
  698. int irq_num;
  699. if (!(prm_features & PRM_HAS_IO_WAKEUP))
  700. return 0;
  701. irq_num = of_irq_get(prm_init_data->np, 0);
  702. if (irq_num == -EPROBE_DEFER)
  703. return irq_num;
  704. omap4_prcm_irq_setup.irq = irq_num;
  705. omap44xx_prm_enable_io_wakeup();
  706. return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
  707. }
  708. static void __exit omap44xx_prm_exit(void)
  709. {
  710. prm_unregister(&omap44xx_prm_ll_data);
  711. }
  712. __exitcall(omap44xx_prm_exit);