prm2xxx.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * OMAP2xxx PRM module functions
  4. *
  5. * Copyright (C) 2010-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/kernel.h>
  12. #include <linux/errno.h>
  13. #include <linux/err.h>
  14. #include <linux/io.h>
  15. #include <linux/irq.h>
  16. #include "powerdomain.h"
  17. #include "clockdomain.h"
  18. #include "prm2xxx.h"
  19. #include "cm2xxx_3xxx.h"
  20. #include "prm-regbits-24xx.h"
  21. /*
  22. * OMAP24xx PM_PWSTCTRL_*.POWERSTATE and PM_PWSTST_*.LASTSTATEENTERED bits -
  23. * these are reversed from the bits used on OMAP3+
  24. */
  25. #define OMAP24XX_PWRDM_POWER_ON 0x0
  26. #define OMAP24XX_PWRDM_POWER_RET 0x1
  27. #define OMAP24XX_PWRDM_POWER_OFF 0x3
  28. /*
  29. * omap2xxx_prm_reset_src_map - map from bits in the PRM_RSTST_WKUP
  30. * hardware register (which are specific to the OMAP2xxx SoCs) to
  31. * reset source ID bit shifts (which is an OMAP SoC-independent
  32. * enumeration)
  33. */
  34. static struct prm_reset_src_map omap2xxx_prm_reset_src_map[] = {
  35. { OMAP_GLOBALCOLD_RST_SHIFT, OMAP_GLOBAL_COLD_RST_SRC_ID_SHIFT },
  36. { OMAP_GLOBALWARM_RST_SHIFT, OMAP_GLOBAL_WARM_RST_SRC_ID_SHIFT },
  37. { OMAP24XX_SECU_VIOL_RST_SHIFT, OMAP_SECU_VIOL_RST_SRC_ID_SHIFT },
  38. { OMAP24XX_MPU_WD_RST_SHIFT, OMAP_MPU_WD_RST_SRC_ID_SHIFT },
  39. { OMAP24XX_SECU_WD_RST_SHIFT, OMAP_SECU_WD_RST_SRC_ID_SHIFT },
  40. { OMAP24XX_EXTWMPU_RST_SHIFT, OMAP_EXTWARM_RST_SRC_ID_SHIFT },
  41. { -1, -1 },
  42. };
  43. /**
  44. * omap2xxx_prm_read_reset_sources - return the last SoC reset source
  45. *
  46. * Return a u32 representing the last reset sources of the SoC. The
  47. * returned reset source bits are standardized across OMAP SoCs.
  48. */
  49. static u32 omap2xxx_prm_read_reset_sources(void)
  50. {
  51. struct prm_reset_src_map *p;
  52. u32 r = 0;
  53. u32 v;
  54. v = omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTST);
  55. p = omap2xxx_prm_reset_src_map;
  56. while (p->reg_shift >= 0 && p->std_shift >= 0) {
  57. if (v & (1 << p->reg_shift))
  58. r |= 1 << p->std_shift;
  59. p++;
  60. }
  61. return r;
  62. }
  63. /**
  64. * omap2xxx_pwrst_to_common_pwrst - convert OMAP2xxx pwrst to common pwrst
  65. * @omap2xxx_pwrst: OMAP2xxx hardware power state to convert
  66. *
  67. * Return the common power state bits corresponding to the OMAP2xxx
  68. * hardware power state bits @omap2xxx_pwrst, or -EINVAL upon error.
  69. */
  70. static int omap2xxx_pwrst_to_common_pwrst(u8 omap2xxx_pwrst)
  71. {
  72. u8 pwrst;
  73. switch (omap2xxx_pwrst) {
  74. case OMAP24XX_PWRDM_POWER_OFF:
  75. pwrst = PWRDM_POWER_OFF;
  76. break;
  77. case OMAP24XX_PWRDM_POWER_RET:
  78. pwrst = PWRDM_POWER_RET;
  79. break;
  80. case OMAP24XX_PWRDM_POWER_ON:
  81. pwrst = PWRDM_POWER_ON;
  82. break;
  83. default:
  84. return -EINVAL;
  85. }
  86. return pwrst;
  87. }
  88. /**
  89. * omap2xxx_prm_dpll_reset - use DPLL reset to reboot the OMAP SoC
  90. *
  91. * Set the DPLL reset bit, which should reboot the SoC. This is the
  92. * recommended way to restart the SoC. No return value.
  93. */
  94. static void omap2xxx_prm_dpll_reset(void)
  95. {
  96. omap2_prm_set_mod_reg_bits(OMAP_RST_DPLL3_MASK, WKUP_MOD,
  97. OMAP2_RM_RSTCTRL);
  98. /* OCP barrier */
  99. omap2_prm_read_mod_reg(WKUP_MOD, OMAP2_RM_RSTCTRL);
  100. }
  101. /**
  102. * omap2xxx_prm_clear_mod_irqs - clear wakeup status bits for a module
  103. * @module: PRM module to clear wakeups from
  104. * @regs: register offset to clear
  105. * @wkst_mask: wakeup status mask to clear
  106. *
  107. * Clears wakeup status bits for a given module, so that the device can
  108. * re-enter idle.
  109. */
  110. static int omap2xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 wkst_mask)
  111. {
  112. u32 wkst;
  113. wkst = omap2_prm_read_mod_reg(module, regs);
  114. wkst &= wkst_mask;
  115. omap2_prm_write_mod_reg(wkst, module, regs);
  116. return 0;
  117. }
  118. int omap2xxx_clkdm_sleep(struct clockdomain *clkdm)
  119. {
  120. omap2_prm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
  121. clkdm->pwrdm.ptr->prcm_offs,
  122. OMAP2_PM_PWSTCTRL);
  123. return 0;
  124. }
  125. int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm)
  126. {
  127. omap2_prm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK,
  128. clkdm->pwrdm.ptr->prcm_offs,
  129. OMAP2_PM_PWSTCTRL);
  130. return 0;
  131. }
  132. static int omap2xxx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
  133. {
  134. u8 omap24xx_pwrst;
  135. switch (pwrst) {
  136. case PWRDM_POWER_OFF:
  137. omap24xx_pwrst = OMAP24XX_PWRDM_POWER_OFF;
  138. break;
  139. case PWRDM_POWER_RET:
  140. omap24xx_pwrst = OMAP24XX_PWRDM_POWER_RET;
  141. break;
  142. case PWRDM_POWER_ON:
  143. omap24xx_pwrst = OMAP24XX_PWRDM_POWER_ON;
  144. break;
  145. default:
  146. return -EINVAL;
  147. }
  148. omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
  149. (omap24xx_pwrst << OMAP_POWERSTATE_SHIFT),
  150. pwrdm->prcm_offs, OMAP2_PM_PWSTCTRL);
  151. return 0;
  152. }
  153. static int omap2xxx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
  154. {
  155. u8 omap2xxx_pwrst;
  156. omap2xxx_pwrst = omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
  157. OMAP2_PM_PWSTCTRL,
  158. OMAP_POWERSTATE_MASK);
  159. return omap2xxx_pwrst_to_common_pwrst(omap2xxx_pwrst);
  160. }
  161. static int omap2xxx_pwrdm_read_pwrst(struct powerdomain *pwrdm)
  162. {
  163. u8 omap2xxx_pwrst;
  164. omap2xxx_pwrst = omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
  165. OMAP2_PM_PWSTST,
  166. OMAP_POWERSTATEST_MASK);
  167. return omap2xxx_pwrst_to_common_pwrst(omap2xxx_pwrst);
  168. }
  169. struct pwrdm_ops omap2_pwrdm_operations = {
  170. .pwrdm_set_next_pwrst = omap2xxx_pwrdm_set_next_pwrst,
  171. .pwrdm_read_next_pwrst = omap2xxx_pwrdm_read_next_pwrst,
  172. .pwrdm_read_pwrst = omap2xxx_pwrdm_read_pwrst,
  173. .pwrdm_set_logic_retst = omap2_pwrdm_set_logic_retst,
  174. .pwrdm_set_mem_onst = omap2_pwrdm_set_mem_onst,
  175. .pwrdm_set_mem_retst = omap2_pwrdm_set_mem_retst,
  176. .pwrdm_read_mem_pwrst = omap2_pwrdm_read_mem_pwrst,
  177. .pwrdm_read_mem_retst = omap2_pwrdm_read_mem_retst,
  178. .pwrdm_wait_transition = omap2_pwrdm_wait_transition,
  179. };
  180. /*
  181. *
  182. */
  183. static struct prm_ll_data omap2xxx_prm_ll_data = {
  184. .read_reset_sources = &omap2xxx_prm_read_reset_sources,
  185. .assert_hardreset = &omap2_prm_assert_hardreset,
  186. .deassert_hardreset = &omap2_prm_deassert_hardreset,
  187. .is_hardreset_asserted = &omap2_prm_is_hardreset_asserted,
  188. .reset_system = &omap2xxx_prm_dpll_reset,
  189. .clear_mod_irqs = &omap2xxx_prm_clear_mod_irqs,
  190. };
  191. int __init omap2xxx_prm_init(const struct omap_prcm_init_data *data)
  192. {
  193. return prm_register(&omap2xxx_prm_ll_data);
  194. }
  195. static void __exit omap2xxx_prm_exit(void)
  196. {
  197. prm_unregister(&omap2xxx_prm_ll_data);
  198. }
  199. __exitcall(omap2xxx_prm_exit);