pm_slowclock.S 6.6 KB

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