psc.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /*
  2. * Keystone: PSC configuration module
  3. *
  4. * (C) Copyright 2012-2014
  5. * Texas Instruments Incorporated, <www.ti.com>
  6. *
  7. * SPDX-License-Identifier: GPL-2.0+
  8. */
  9. #include <common.h>
  10. #include <asm-generic/errno.h>
  11. #include <asm/io.h>
  12. #include <asm/processor.h>
  13. #include <asm/arch/psc_defs.h>
  14. int psc_delay(void)
  15. {
  16. udelay(10);
  17. return 10;
  18. }
  19. /*
  20. * FUNCTION PURPOSE: Wait for end of transitional state
  21. *
  22. * DESCRIPTION: Polls pstat for the selected domain and waits for transitions
  23. * to be complete.
  24. *
  25. * Since this is boot loader code it is *ASSUMED* that interrupts
  26. * are disabled and no other core is mucking around with the psc
  27. * at the same time.
  28. *
  29. * Returns 0 when the domain is free. Returns -1 if a timeout
  30. * occurred waiting for the completion.
  31. */
  32. int psc_wait(u32 domain_num)
  33. {
  34. u32 retry;
  35. u32 ptstat;
  36. /*
  37. * Do nothing if the power domain is in transition. This should never
  38. * happen since the boot code is the only software accesses psc.
  39. * It's still remotely possible that the hardware state machines
  40. * initiate transitions.
  41. * Don't trap if the domain (or a module in this domain) is
  42. * stuck in transition.
  43. */
  44. retry = 0;
  45. do {
  46. ptstat = __raw_readl(KS2_PSC_BASE + PSC_REG_PSTAT);
  47. ptstat = ptstat & (1 << domain_num);
  48. } while ((ptstat != 0) && ((retry += psc_delay()) <
  49. PSC_PTSTAT_TIMEOUT_LIMIT));
  50. if (retry >= PSC_PTSTAT_TIMEOUT_LIMIT)
  51. return -1;
  52. return 0;
  53. }
  54. u32 psc_get_domain_num(u32 mod_num)
  55. {
  56. u32 domain_num;
  57. /* Get the power domain associated with the module number */
  58. domain_num = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
  59. domain_num = PSC_REG_MDCFG_GET_PD(domain_num);
  60. return domain_num;
  61. }
  62. /*
  63. * FUNCTION PURPOSE: Power up/down a module
  64. *
  65. * DESCRIPTION: Powers up/down the requested module and the associated power
  66. * domain if required. No action is taken it the module is
  67. * already powered up/down.
  68. *
  69. * This only controls modules. The domain in which the module
  70. * resides will be left in the power on state. Multiple modules
  71. * can exist in a power domain, so powering down the domain based
  72. * on a single module is not done.
  73. *
  74. * Returns 0 on success, -1 if the module can't be powered up, or
  75. * if there is a timeout waiting for the transition.
  76. */
  77. int psc_set_state(u32 mod_num, u32 state)
  78. {
  79. u32 domain_num;
  80. u32 pdctl;
  81. u32 mdctl;
  82. u32 ptcmd;
  83. u32 reset_iso;
  84. u32 v;
  85. /*
  86. * Get the power domain associated with the module number, and reset
  87. * isolation functionality
  88. */
  89. v = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
  90. domain_num = PSC_REG_MDCFG_GET_PD(v);
  91. reset_iso = PSC_REG_MDCFG_GET_RESET_ISO(v);
  92. /* Wait for the status of the domain/module to be non-transitional */
  93. if (psc_wait(domain_num) != 0)
  94. return -1;
  95. /*
  96. * Perform configuration even if the current status matches the
  97. * existing state
  98. *
  99. * Set the next state of the power domain to on. It's OK if the domain
  100. * is always on. This code will not ever power down a domain, so no
  101. * change is made if the new state is power down.
  102. */
  103. if (state == PSC_REG_VAL_MDCTL_NEXT_ON) {
  104. pdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
  105. pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl,
  106. PSC_REG_VAL_PDCTL_NEXT_ON);
  107. __raw_writel(pdctl, KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
  108. }
  109. /* Set the next state for the module to enabled/disabled */
  110. mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
  111. mdctl = PSC_REG_MDCTL_SET_NEXT(mdctl, state);
  112. mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, reset_iso);
  113. __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
  114. /* Trigger the enable */
  115. ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
  116. ptcmd |= (u32)(1<<domain_num);
  117. __raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
  118. /* Wait on the complete */
  119. return psc_wait(domain_num);
  120. }
  121. /*
  122. * FUNCTION PURPOSE: Power up a module
  123. *
  124. * DESCRIPTION: Powers up the requested module and the associated power domain
  125. * if required. No action is taken it the module is already
  126. * powered up.
  127. *
  128. * Returns 0 on success, -1 if the module can't be powered up, or
  129. * if there is a timeout waiting for the transition.
  130. */
  131. int psc_enable_module(u32 mod_num)
  132. {
  133. u32 mdctl;
  134. /* Set the bit to apply reset */
  135. mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
  136. if ((mdctl & 0x3f) == PSC_REG_VAL_MDSTAT_STATE_ON)
  137. return 0;
  138. return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_ON);
  139. }
  140. /*
  141. * FUNCTION PURPOSE: Power down a module
  142. *
  143. * DESCRIPTION: Powers down the requested module.
  144. *
  145. * Returns 0 on success, -1 on failure or timeout.
  146. */
  147. int psc_disable_module(u32 mod_num)
  148. {
  149. u32 mdctl;
  150. /* Set the bit to apply reset */
  151. mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
  152. if ((mdctl & 0x3f) == 0)
  153. return 0;
  154. mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0);
  155. __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
  156. return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE);
  157. }
  158. /*
  159. * FUNCTION PURPOSE: Set the reset isolation bit in mdctl
  160. *
  161. * DESCRIPTION: The reset isolation enable bit is set. The state of the module
  162. * is not changed. Returns 0 if the module config showed that
  163. * reset isolation is supported. Returns 1 otherwise. This is not
  164. * an error, but setting the bit in mdctl has no effect.
  165. */
  166. int psc_set_reset_iso(u32 mod_num)
  167. {
  168. u32 v;
  169. u32 mdctl;
  170. /* Set the reset isolation bit */
  171. mdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
  172. mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, 1);
  173. __raw_writel(mdctl, KS2_PSC_BASE + PSC_REG_MDCTL(mod_num));
  174. v = __raw_readl(KS2_PSC_BASE + PSC_REG_MDCFG(mod_num));
  175. if (PSC_REG_MDCFG_GET_RESET_ISO(v) == 1)
  176. return 0;
  177. return 1;
  178. }
  179. /*
  180. * FUNCTION PURPOSE: Disable a power domain
  181. *
  182. * DESCRIPTION: The power domain is disabled
  183. */
  184. int psc_disable_domain(u32 domain_num)
  185. {
  186. u32 pdctl;
  187. u32 ptcmd;
  188. pdctl = __raw_readl(KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
  189. pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl, PSC_REG_VAL_PDCTL_NEXT_OFF);
  190. pdctl = PSC_REG_PDCTL_SET_PDMODE(pdctl, PSC_REG_VAL_PDCTL_PDMODE_SLEEP);
  191. __raw_writel(pdctl, KS2_PSC_BASE + PSC_REG_PDCTL(domain_num));
  192. ptcmd = __raw_readl(KS2_PSC_BASE + PSC_REG_PTCMD);
  193. ptcmd |= (u32)(1 << domain_num);
  194. __raw_writel(ptcmd, KS2_PSC_BASE + PSC_REG_PTCMD);
  195. return psc_wait(domain_num);
  196. }