pm_slowclock.S 6.8 KB

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