powerdomain44xx.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * OMAP4 powerdomain control
  3. *
  4. * Copyright (C) 2009-2010 Texas Instruments, Inc.
  5. * Copyright (C) 2007-2009 Nokia Corporation
  6. *
  7. * Derived from mach-omap2/powerdomain.c written by Paul Walmsley
  8. * Rajendra Nayak <rnayak@ti.com>
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License version 2 as
  12. * published by the Free Software Foundation.
  13. */
  14. #include <linux/io.h>
  15. #include <linux/errno.h>
  16. #include <linux/delay.h>
  17. #include <plat/powerdomain.h>
  18. #include <plat/prcm.h>
  19. #include "prm2xxx_3xxx.h"
  20. #include "prm44xx.h"
  21. #include "prm-regbits-44xx.h"
  22. #include "powerdomains.h"
  23. static int omap4_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst)
  24. {
  25. omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK,
  26. (pwrst << OMAP_POWERSTATE_SHIFT),
  27. pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
  28. return 0;
  29. }
  30. static int omap4_pwrdm_read_next_pwrst(struct powerdomain *pwrdm)
  31. {
  32. return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
  33. OMAP4_PM_PWSTCTRL, OMAP_POWERSTATE_MASK);
  34. }
  35. static int omap4_pwrdm_read_pwrst(struct powerdomain *pwrdm)
  36. {
  37. return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
  38. OMAP4_PM_PWSTST, OMAP_POWERSTATEST_MASK);
  39. }
  40. static int omap4_pwrdm_read_prev_pwrst(struct powerdomain *pwrdm)
  41. {
  42. return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTST,
  43. OMAP4430_LASTPOWERSTATEENTERED_MASK);
  44. }
  45. static int omap4_pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm)
  46. {
  47. omap2_prm_rmw_mod_reg_bits(OMAP4430_LOWPOWERSTATECHANGE_MASK,
  48. (1 << OMAP4430_LOWPOWERSTATECHANGE_SHIFT),
  49. pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
  50. return 0;
  51. }
  52. static int omap4_pwrdm_clear_all_prev_pwrst(struct powerdomain *pwrdm)
  53. {
  54. omap2_prm_rmw_mod_reg_bits(OMAP4430_LASTPOWERSTATEENTERED_MASK,
  55. OMAP4430_LASTPOWERSTATEENTERED_MASK,
  56. pwrdm->prcm_offs, OMAP4_PM_PWSTST);
  57. return 0;
  58. }
  59. static int omap4_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst)
  60. {
  61. u32 v;
  62. v = pwrst << __ffs(OMAP4430_LOGICRETSTATE_MASK);
  63. omap2_prm_rmw_mod_reg_bits(OMAP4430_LOGICRETSTATE_MASK, v,
  64. pwrdm->prcm_offs, OMAP4_PM_PWSTCTRL);
  65. return 0;
  66. }
  67. static int omap4_pwrdm_set_mem_onst(struct powerdomain *pwrdm, u8 bank,
  68. u8 pwrst)
  69. {
  70. u32 m;
  71. m = omap2_pwrdm_get_mem_bank_onstate_mask(bank);
  72. omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
  73. OMAP4_PM_PWSTCTRL);
  74. return 0;
  75. }
  76. static int omap4_pwrdm_set_mem_retst(struct powerdomain *pwrdm, u8 bank,
  77. u8 pwrst)
  78. {
  79. u32 m;
  80. m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
  81. omap2_prm_rmw_mod_reg_bits(m, (pwrst << __ffs(m)), pwrdm->prcm_offs,
  82. OMAP4_PM_PWSTCTRL);
  83. return 0;
  84. }
  85. static int omap4_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm)
  86. {
  87. return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTST,
  88. OMAP4430_LOGICSTATEST_MASK);
  89. }
  90. static int omap4_pwrdm_read_logic_retst(struct powerdomain *pwrdm)
  91. {
  92. return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
  93. OMAP4_PM_PWSTCTRL,
  94. OMAP4430_LOGICRETSTATE_MASK);
  95. }
  96. static int omap4_pwrdm_read_mem_pwrst(struct powerdomain *pwrdm, u8 bank)
  97. {
  98. u32 m;
  99. m = omap2_pwrdm_get_mem_bank_stst_mask(bank);
  100. return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, OMAP4_PM_PWSTST,
  101. m);
  102. }
  103. static int omap4_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank)
  104. {
  105. u32 m;
  106. m = omap2_pwrdm_get_mem_bank_retst_mask(bank);
  107. return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs,
  108. OMAP4_PM_PWSTCTRL, m);
  109. }
  110. static int omap4_pwrdm_wait_transition(struct powerdomain *pwrdm)
  111. {
  112. u32 c = 0;
  113. /*
  114. * REVISIT: pwrdm_wait_transition() may be better implemented
  115. * via a callback and a periodic timer check -- how long do we expect
  116. * powerdomain transitions to take?
  117. */
  118. /* XXX Is this udelay() value meaningful? */
  119. while ((omap2_prm_read_mod_reg(pwrdm->prcm_offs, OMAP4_PM_PWSTST) &
  120. OMAP_INTRANSITION_MASK) &&
  121. (c++ < PWRDM_TRANSITION_BAILOUT))
  122. udelay(1);
  123. if (c > PWRDM_TRANSITION_BAILOUT) {
  124. printk(KERN_ERR "powerdomain: waited too long for "
  125. "powerdomain %s to complete transition\n", pwrdm->name);
  126. return -EAGAIN;
  127. }
  128. pr_debug("powerdomain: completed transition in %d loops\n", c);
  129. return 0;
  130. }
  131. struct pwrdm_ops omap4_pwrdm_operations = {
  132. .pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst,
  133. .pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst,
  134. .pwrdm_read_pwrst = omap4_pwrdm_read_pwrst,
  135. .pwrdm_read_prev_pwrst = omap4_pwrdm_read_prev_pwrst,
  136. .pwrdm_set_lowpwrstchange = omap4_pwrdm_set_lowpwrstchange,
  137. .pwrdm_clear_all_prev_pwrst = omap4_pwrdm_clear_all_prev_pwrst,
  138. .pwrdm_set_logic_retst = omap4_pwrdm_set_logic_retst,
  139. .pwrdm_read_logic_pwrst = omap4_pwrdm_read_logic_pwrst,
  140. .pwrdm_read_logic_retst = omap4_pwrdm_read_logic_retst,
  141. .pwrdm_read_mem_pwrst = omap4_pwrdm_read_mem_pwrst,
  142. .pwrdm_read_mem_retst = omap4_pwrdm_read_mem_retst,
  143. .pwrdm_set_mem_onst = omap4_pwrdm_set_mem_onst,
  144. .pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst,
  145. .pwrdm_wait_transition = omap4_pwrdm_wait_transition,
  146. };