dpmc_modes.S 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /*
  2. * Copyright 2004-2008 Analog Devices Inc.
  3. *
  4. * Licensed under the GPL-2 or later.
  5. */
  6. #include <linux/linkage.h>
  7. #include <asm/blackfin.h>
  8. #include <mach/irq.h>
  9. #include <asm/dpmc.h>
  10. .section .l1.text
  11. ENTRY(_sleep_mode)
  12. [--SP] = (R7:4, P5:3);
  13. [--SP] = RETS;
  14. call _set_sic_iwr;
  15. P0.H = hi(PLL_CTL);
  16. P0.L = lo(PLL_CTL);
  17. R1 = W[P0](z);
  18. BITSET (R1, 3);
  19. W[P0] = R1.L;
  20. CLI R2;
  21. SSYNC;
  22. IDLE;
  23. STI R2;
  24. call _test_pll_locked;
  25. R0 = IWR_ENABLE(0);
  26. R1 = IWR_DISABLE_ALL;
  27. R2 = IWR_DISABLE_ALL;
  28. call _set_sic_iwr;
  29. P0.H = hi(PLL_CTL);
  30. P0.L = lo(PLL_CTL);
  31. R7 = w[p0](z);
  32. BITCLR (R7, 3);
  33. BITCLR (R7, 5);
  34. w[p0] = R7.L;
  35. IDLE;
  36. call _test_pll_locked;
  37. RETS = [SP++];
  38. (R7:4, P5:3) = [SP++];
  39. RTS;
  40. ENDPROC(_sleep_mode)
  41. /*
  42. * This func never returns as it puts the part into hibernate, and
  43. * is only called from do_hibernate, so we don't bother saving or
  44. * restoring any of the normal C runtime state. When we wake up,
  45. * the entry point will be in do_hibernate and not here.
  46. *
  47. * We accept just one argument -- the value to write to VR_CTL.
  48. */
  49. ENTRY(_hibernate_mode)
  50. /* Save/setup the regs we need early for minor pipeline optimization */
  51. R4 = R0;
  52. P3.H = hi(VR_CTL);
  53. P3.L = lo(VR_CTL);
  54. /* Disable all wakeup sources */
  55. R0 = IWR_DISABLE_ALL;
  56. R1 = IWR_DISABLE_ALL;
  57. R2 = IWR_DISABLE_ALL;
  58. call _set_sic_iwr;
  59. call _set_dram_srfs;
  60. SSYNC;
  61. /* Finally, we climb into our cave to hibernate */
  62. W[P3] = R4.L;
  63. CLI R2;
  64. IDLE;
  65. .Lforever:
  66. jump .Lforever;
  67. ENDPROC(_hibernate_mode)
  68. ENTRY(_sleep_deeper)
  69. [--SP] = (R7:4, P5:3);
  70. [--SP] = RETS;
  71. CLI R4;
  72. P3 = R0;
  73. P4 = R1;
  74. P5 = R2;
  75. R0 = IWR_ENABLE(0);
  76. R1 = IWR_DISABLE_ALL;
  77. R2 = IWR_DISABLE_ALL;
  78. call _set_sic_iwr;
  79. call _set_dram_srfs; /* Set SDRAM Self Refresh */
  80. P0.H = hi(PLL_DIV);
  81. P0.L = lo(PLL_DIV);
  82. R6 = W[P0](z);
  83. R0.L = 0xF;
  84. W[P0] = R0.l; /* Set Max VCO to SCLK divider */
  85. P0.H = hi(PLL_CTL);
  86. P0.L = lo(PLL_CTL);
  87. R5 = W[P0](z);
  88. R0.L = (CONFIG_MIN_VCO_HZ/CONFIG_CLKIN_HZ) << 9;
  89. W[P0] = R0.l; /* Set Min CLKIN to VCO multiplier */
  90. SSYNC;
  91. IDLE;
  92. call _test_pll_locked;
  93. P0.H = hi(VR_CTL);
  94. P0.L = lo(VR_CTL);
  95. R7 = W[P0](z);
  96. R1 = 0x6;
  97. R1 <<= 16;
  98. R2 = 0x0404(Z);
  99. R1 = R1|R2;
  100. R2 = DEPOSIT(R7, R1);
  101. W[P0] = R2; /* Set Min Core Voltage */
  102. SSYNC;
  103. IDLE;
  104. call _test_pll_locked;
  105. R0 = P3;
  106. R1 = P4;
  107. R3 = P5;
  108. call _set_sic_iwr; /* Set Awake from IDLE */
  109. P0.H = hi(PLL_CTL);
  110. P0.L = lo(PLL_CTL);
  111. R0 = W[P0](z);
  112. BITSET (R0, 3);
  113. W[P0] = R0.L; /* Turn CCLK OFF */
  114. SSYNC;
  115. IDLE;
  116. call _test_pll_locked;
  117. R0 = IWR_ENABLE(0);
  118. R1 = IWR_DISABLE_ALL;
  119. R2 = IWR_DISABLE_ALL;
  120. call _set_sic_iwr; /* Set Awake from IDLE PLL */
  121. P0.H = hi(VR_CTL);
  122. P0.L = lo(VR_CTL);
  123. W[P0]= R7;
  124. SSYNC;
  125. IDLE;
  126. call _test_pll_locked;
  127. P0.H = hi(PLL_DIV);
  128. P0.L = lo(PLL_DIV);
  129. W[P0]= R6; /* Restore CCLK and SCLK divider */
  130. P0.H = hi(PLL_CTL);
  131. P0.L = lo(PLL_CTL);
  132. w[p0] = R5; /* Restore VCO multiplier */
  133. IDLE;
  134. call _test_pll_locked;
  135. call _unset_dram_srfs; /* SDRAM Self Refresh Off */
  136. STI R4;
  137. RETS = [SP++];
  138. (R7:4, P5:3) = [SP++];
  139. RTS;
  140. ENDPROC(_sleep_deeper)
  141. ENTRY(_set_dram_srfs)
  142. /* set the dram to self refresh mode */
  143. SSYNC;
  144. #if defined(EBIU_RSTCTL) /* DDR */
  145. P0.H = hi(EBIU_RSTCTL);
  146. P0.L = lo(EBIU_RSTCTL);
  147. R2 = [P0];
  148. BITSET(R2, 3); /* SRREQ enter self-refresh mode */
  149. [P0] = R2;
  150. SSYNC;
  151. 1:
  152. R2 = [P0];
  153. CC = BITTST(R2, 4);
  154. if !CC JUMP 1b;
  155. #else /* SDRAM */
  156. P0.L = lo(EBIU_SDGCTL);
  157. P0.H = hi(EBIU_SDGCTL);
  158. P1.L = lo(EBIU_SDSTAT);
  159. P1.H = hi(EBIU_SDSTAT);
  160. R2 = [P0];
  161. BITSET(R2, 24); /* SRFS enter self-refresh mode */
  162. [P0] = R2;
  163. SSYNC;
  164. 1:
  165. R2 = w[P1];
  166. SSYNC;
  167. cc = BITTST(R2, 1); /* SDSRA poll self-refresh status */
  168. if !cc jump 1b;
  169. R2 = [P0];
  170. BITCLR(R2, 0); /* SCTLE disable CLKOUT */
  171. [P0] = R2;
  172. #endif
  173. RTS;
  174. ENDPROC(_set_dram_srfs)
  175. ENTRY(_unset_dram_srfs)
  176. /* set the dram out of self refresh mode */
  177. #if defined(EBIU_RSTCTL) /* DDR */
  178. P0.H = hi(EBIU_RSTCTL);
  179. P0.L = lo(EBIU_RSTCTL);
  180. R2 = [P0];
  181. BITCLR(R2, 3); /* clear SRREQ bit */
  182. [P0] = R2;
  183. #elif defined(EBIU_SDGCTL) /* SDRAM */
  184. /* release CLKOUT from self-refresh */
  185. P0.L = lo(EBIU_SDGCTL);
  186. P0.H = hi(EBIU_SDGCTL);
  187. R2 = [P0];
  188. BITSET(R2, 0); /* SCTLE enable CLKOUT */
  189. [P0] = R2
  190. SSYNC;
  191. /* release SDRAM from self-refresh */
  192. R2 = [P0];
  193. BITCLR(R2, 24); /* clear SRFS bit */
  194. [P0] = R2
  195. #endif
  196. SSYNC;
  197. RTS;
  198. ENDPROC(_unset_dram_srfs)
  199. ENTRY(_set_sic_iwr)
  200. #ifdef SIC_IWR0
  201. P0.H = hi(SYSMMR_BASE);
  202. P0.L = lo(SYSMMR_BASE);
  203. [P0 + (SIC_IWR0 - SYSMMR_BASE)] = R0;
  204. [P0 + (SIC_IWR1 - SYSMMR_BASE)] = R1;
  205. # ifdef SIC_IWR2
  206. [P0 + (SIC_IWR2 - SYSMMR_BASE)] = R2;
  207. # endif
  208. #else
  209. P0.H = hi(SIC_IWR);
  210. P0.L = lo(SIC_IWR);
  211. [P0] = R0;
  212. #endif
  213. SSYNC;
  214. RTS;
  215. ENDPROC(_set_sic_iwr)
  216. ENTRY(_test_pll_locked)
  217. P0.H = hi(PLL_STAT);
  218. P0.L = lo(PLL_STAT);
  219. 1:
  220. R0 = W[P0] (Z);
  221. CC = BITTST(R0,5);
  222. IF !CC JUMP 1b;
  223. RTS;
  224. ENDPROC(_test_pll_locked)
  225. .section .text
  226. ENTRY(_do_hibernate)
  227. bfin_cpu_reg_save;
  228. bfin_sys_mmr_save;
  229. bfin_core_mmr_save;
  230. /* Setup args to hibernate mode early for pipeline optimization */
  231. R0 = M3;
  232. P1.H = _hibernate_mode;
  233. P1.L = _hibernate_mode;
  234. /* Save Magic, return address and Stack Pointer */
  235. P0 = 0;
  236. R1.H = 0xDEAD; /* Hibernate Magic */
  237. R1.L = 0xBEEF;
  238. R2.H = .Lpm_resume_here;
  239. R2.L = .Lpm_resume_here;
  240. [P0++] = R1; /* Store Hibernate Magic */
  241. [P0++] = R2; /* Save Return Address */
  242. [P0++] = SP; /* Save Stack Pointer */
  243. /* Must use an indirect call as we need to jump to L1 */
  244. call (P1); /* Goodbye */
  245. .Lpm_resume_here:
  246. bfin_core_mmr_restore;
  247. bfin_sys_mmr_restore;
  248. bfin_cpu_reg_restore;
  249. [--sp] = RETI; /* Clear Global Interrupt Disable */
  250. SP += 4;
  251. RTS;
  252. ENDPROC(_do_hibernate)