pm_slowclock.S 6.6 KB

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