pm_slowclock.S 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. * arch/arm/mach-at91/pm_slow_clock.S
  3. *
  4. * Copyright (C) 2006 Savin Zlobec
  5. *
  6. * AT91SAM9 support:
  7. * Copyright (C) 2007 Anti Sullin <anti.sullin@artecdesign.ee
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 as
  11. * published by the Free Software Foundation.
  12. *
  13. */
  14. #include <linux/linkage.h>
  15. #include <mach/hardware.h>
  16. #include <mach/at91_pmc.h>
  17. #if defined(CONFIG_ARCH_AT91RM9200)
  18. #include <mach/at91rm9200_mc.h>
  19. #include <mach/at91rm9200_sdramc.h>
  20. #elif defined(CONFIG_ARCH_AT91SAM9G45)
  21. #include <mach/at91sam9_ddrsdr.h>
  22. #else
  23. #include <mach/at91sam9_sdramc.h>
  24. #endif
  25. #ifdef CONFIG_ARCH_AT91SAM9263
  26. /*
  27. * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
  28. * handle those cases both here and in the Suspend-To-RAM support.
  29. */
  30. #warning Assuming EB1 SDRAM controller is *NOT* used
  31. #endif
  32. /*
  33. * When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master
  34. * clock during suspend by adjusting its prescalar and divisor.
  35. * NOTE: This hasn't been shown to be stable on SAM9s; and on the RM9200 there
  36. * are errata regarding adjusting the prescalar and divisor.
  37. */
  38. #undef SLOWDOWN_MASTER_CLOCK
  39. #define MCKRDY_TIMEOUT 1000
  40. #define MOSCRDY_TIMEOUT 1000
  41. #define PLLALOCK_TIMEOUT 1000
  42. #define PLLBLOCK_TIMEOUT 1000
  43. pmc .req r0
  44. sdramc .req r1
  45. ramc1 .req r2
  46. tmp1 .req r3
  47. tmp2 .req r4
  48. /*
  49. * Wait until master clock is ready (after switching master clock source)
  50. */
  51. .macro wait_mckrdy
  52. mov tmp2, #MCKRDY_TIMEOUT
  53. 1: sub tmp2, tmp2, #1
  54. cmp tmp2, #0
  55. beq 2f
  56. ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
  57. tst tmp1, #AT91_PMC_MCKRDY
  58. beq 1b
  59. 2:
  60. .endm
  61. /*
  62. * Wait until master oscillator has stabilized.
  63. */
  64. .macro wait_moscrdy
  65. mov tmp2, #MOSCRDY_TIMEOUT
  66. 1: sub tmp2, tmp2, #1
  67. cmp tmp2, #0
  68. beq 2f
  69. ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
  70. tst tmp1, #AT91_PMC_MOSCS
  71. beq 1b
  72. 2:
  73. .endm
  74. /*
  75. * Wait until PLLA has locked.
  76. */
  77. .macro wait_pllalock
  78. mov tmp2, #PLLALOCK_TIMEOUT
  79. 1: sub tmp2, tmp2, #1
  80. cmp tmp2, #0
  81. beq 2f
  82. ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
  83. tst tmp1, #AT91_PMC_LOCKA
  84. beq 1b
  85. 2:
  86. .endm
  87. /*
  88. * Wait until PLLB has locked.
  89. */
  90. .macro wait_pllblock
  91. mov tmp2, #PLLBLOCK_TIMEOUT
  92. 1: sub tmp2, tmp2, #1
  93. cmp tmp2, #0
  94. beq 2f
  95. ldr tmp1, [pmc, #(AT91_PMC_SR - AT91_PMC)]
  96. tst tmp1, #AT91_PMC_LOCKB
  97. beq 1b
  98. 2:
  99. .endm
  100. .text
  101. /* void at91_slow_clock(void __iomem *pmc, void __iomem *sdramc, void __iomem *ramc1) */
  102. ENTRY(at91_slow_clock)
  103. /* Save registers on stack */
  104. stmfd sp!, {r3 - r12, lr}
  105. /*
  106. * Register usage:
  107. * R0 = Base address of AT91_PMC
  108. * R1 = Base address of RAM Controller (SDRAM, DDRSDR, or AT91_SYS)
  109. * R2 = Base address of second RAM Controller or 0 if not present
  110. * R3 = temporary register
  111. * R4 = temporary register
  112. */
  113. /* Drain write buffer */
  114. mov tmp1, #0
  115. mcr p15, 0, tmp1, c7, c10, 4
  116. #ifdef CONFIG_ARCH_AT91RM9200
  117. /* Put SDRAM in self-refresh mode */
  118. mov tmp1, #1
  119. str tmp1, [sdramc, #AT91RM9200_SDRAMC_SRR]
  120. #elif defined(CONFIG_ARCH_AT91SAM9G45)
  121. /* prepare for DDRAM self-refresh mode */
  122. ldr tmp1, [sdramc, #AT91_DDRSDRC_LPR]
  123. str tmp1, .saved_sam9_lpr
  124. bic tmp1, #AT91_DDRSDRC_LPCB
  125. orr tmp1, #AT91_DDRSDRC_LPCB_SELF_REFRESH
  126. /* figure out if we use the second ram controller */
  127. cmp ramc1, #0
  128. ldrne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
  129. strne tmp2, .saved_sam9_lpr1
  130. bicne tmp2, #AT91_DDRSDRC_LPCB
  131. orrne tmp2, #AT91_DDRSDRC_LPCB_SELF_REFRESH
  132. /* Enable DDRAM self-refresh mode */
  133. str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
  134. strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
  135. #else
  136. /* Enable SDRAM self-refresh mode */
  137. ldr tmp1, [sdramc, #AT91_SDRAMC_LPR]
  138. str tmp1, .saved_sam9_lpr
  139. bic tmp1, #AT91_SDRAMC_LPCB
  140. orr tmp1, #AT91_SDRAMC_LPCB_SELF_REFRESH
  141. str tmp1, [sdramc, #AT91_SDRAMC_LPR]
  142. #endif
  143. /* Save Master clock setting */
  144. ldr tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
  145. str tmp1, .saved_mckr
  146. /*
  147. * Set the Master clock source to slow clock
  148. */
  149. bic tmp1, tmp1, #AT91_PMC_CSS
  150. str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
  151. wait_mckrdy
  152. #ifdef SLOWDOWN_MASTER_CLOCK
  153. /*
  154. * Set the Master Clock PRES and MDIV fields.
  155. *
  156. * See AT91RM9200 errata #27 and #28 for details.
  157. */
  158. mov tmp1, #0
  159. str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
  160. wait_mckrdy
  161. #endif
  162. /* Save PLLA setting and disable it */
  163. ldr tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
  164. str tmp1, .saved_pllar
  165. mov tmp1, #AT91_PMC_PLLCOUNT
  166. orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
  167. str tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
  168. /* Save PLLB setting and disable it */
  169. ldr tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
  170. str tmp1, .saved_pllbr
  171. mov tmp1, #AT91_PMC_PLLCOUNT
  172. str tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
  173. /* Turn off the main oscillator */
  174. ldr tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
  175. bic tmp1, tmp1, #AT91_PMC_MOSCEN
  176. str tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
  177. /* Wait for interrupt */
  178. mcr p15, 0, tmp1, c7, c0, 4
  179. /* Turn on the main oscillator */
  180. ldr tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
  181. orr tmp1, tmp1, #AT91_PMC_MOSCEN
  182. str tmp1, [pmc, #(AT91_CKGR_MOR - AT91_PMC)]
  183. wait_moscrdy
  184. /* Restore PLLB setting */
  185. ldr tmp1, .saved_pllbr
  186. str tmp1, [pmc, #(AT91_CKGR_PLLBR - AT91_PMC)]
  187. tst tmp1, #(AT91_PMC_MUL & 0xff0000)
  188. bne 1f
  189. tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
  190. beq 2f
  191. 1:
  192. wait_pllblock
  193. 2:
  194. /* Restore PLLA setting */
  195. ldr tmp1, .saved_pllar
  196. str tmp1, [pmc, #(AT91_CKGR_PLLAR - AT91_PMC)]
  197. tst tmp1, #(AT91_PMC_MUL & 0xff0000)
  198. bne 3f
  199. tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
  200. beq 4f
  201. 3:
  202. wait_pllalock
  203. 4:
  204. #ifdef SLOWDOWN_MASTER_CLOCK
  205. /*
  206. * First set PRES if it was not 0,
  207. * than set CSS and MDIV fields.
  208. *
  209. * See AT91RM9200 errata #27 and #28 for details.
  210. */
  211. ldr tmp1, .saved_mckr
  212. tst tmp1, #AT91_PMC_PRES
  213. beq 2f
  214. and tmp1, tmp1, #AT91_PMC_PRES
  215. str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
  216. wait_mckrdy
  217. #endif
  218. /*
  219. * Restore master clock setting
  220. */
  221. 2: ldr tmp1, .saved_mckr
  222. str tmp1, [pmc, #(AT91_PMC_MCKR - AT91_PMC)]
  223. wait_mckrdy
  224. #ifdef CONFIG_ARCH_AT91RM9200
  225. /* Do nothing - self-refresh is automatically disabled. */
  226. #elif defined(CONFIG_ARCH_AT91SAM9G45)
  227. /* Restore LPR on AT91 with DDRAM */
  228. ldr tmp1, .saved_sam9_lpr
  229. str tmp1, [sdramc, #AT91_DDRSDRC_LPR]
  230. /* if we use the second ram controller */
  231. cmp ramc1, #0
  232. ldrne tmp2, .saved_sam9_lpr1
  233. strne tmp2, [ramc1, #AT91_DDRSDRC_LPR]
  234. #else
  235. /* Restore LPR on AT91 with SDRAM */
  236. ldr tmp1, .saved_sam9_lpr
  237. str tmp1, [sdramc, #AT91_SDRAMC_LPR]
  238. #endif
  239. /* Restore registers, and return */
  240. ldmfd sp!, {r3 - r12, pc}
  241. .saved_mckr:
  242. .word 0
  243. .saved_pllar:
  244. .word 0
  245. .saved_pllbr:
  246. .word 0
  247. .saved_sam9_lpr:
  248. .word 0
  249. .saved_sam9_lpr1:
  250. .word 0
  251. ENTRY(at91_slow_clock_sz)
  252. .word .-at91_slow_clock