pm_slowclock.S 6.9 KB

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