pm_suspend.S 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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/at91_ramc.h>
  17. #include "pm.h"
  18. #define SRAMC_SELF_FRESH_ACTIVE 0x01
  19. #define SRAMC_SELF_FRESH_EXIT 0x00
  20. pmc .req r0
  21. tmp1 .req r4
  22. tmp2 .req r5
  23. /*
  24. * Wait until master clock is ready (after switching master clock source)
  25. */
  26. .macro wait_mckrdy
  27. 1: ldr tmp1, [pmc, #AT91_PMC_SR]
  28. tst tmp1, #AT91_PMC_MCKRDY
  29. beq 1b
  30. .endm
  31. /*
  32. * Wait until master oscillator has stabilized.
  33. */
  34. .macro wait_moscrdy
  35. 1: ldr tmp1, [pmc, #AT91_PMC_SR]
  36. tst tmp1, #AT91_PMC_MOSCS
  37. beq 1b
  38. .endm
  39. /*
  40. * Wait until PLLA has locked.
  41. */
  42. .macro wait_pllalock
  43. 1: ldr tmp1, [pmc, #AT91_PMC_SR]
  44. tst tmp1, #AT91_PMC_LOCKA
  45. beq 1b
  46. .endm
  47. /*
  48. * Put the processor to enter the idle state
  49. */
  50. .macro at91_cpu_idle
  51. #if defined(CONFIG_CPU_V7)
  52. mov tmp1, #AT91_PMC_PCK
  53. str tmp1, [pmc, #AT91_PMC_SCDR]
  54. dsb
  55. wfi @ Wait For Interrupt
  56. #else
  57. mcr p15, 0, tmp1, c7, c0, 4
  58. #endif
  59. .endm
  60. .text
  61. .arm
  62. /*
  63. * void at91_pm_suspend_in_sram(void __iomem *pmc, void __iomem *sdramc,
  64. * void __iomem *ramc1, int memctrl)
  65. * @input param:
  66. * @r0: base address of AT91_PMC
  67. * @r1: base address of SDRAM Controller (SDRAM, DDRSDR, or AT91_SYS)
  68. * @r2: base address of second SDRAM Controller or 0 if not present
  69. * @r3: pm information
  70. */
  71. ENTRY(at91_pm_suspend_in_sram)
  72. /* Save registers on stack */
  73. stmfd sp!, {r4 - r12, lr}
  74. /* Drain write buffer */
  75. mov tmp1, #0
  76. mcr p15, 0, tmp1, c7, c10, 4
  77. str r0, .pmc_base
  78. str r1, .sramc_base
  79. str r2, .sramc1_base
  80. and r0, r3, #AT91_PM_MEMTYPE_MASK
  81. str r0, .memtype
  82. lsr r0, r3, #AT91_PM_MODE_OFFSET
  83. and r0, r0, #AT91_PM_MODE_MASK
  84. str r0, .pm_mode
  85. /* Active the self-refresh mode */
  86. mov r0, #SRAMC_SELF_FRESH_ACTIVE
  87. bl at91_sramc_self_refresh
  88. ldr r0, .pm_mode
  89. tst r0, #AT91_PM_SLOW_CLOCK
  90. beq skip_disable_main_clock
  91. ldr pmc, .pmc_base
  92. /* Save Master clock setting */
  93. ldr tmp1, [pmc, #AT91_PMC_MCKR]
  94. str tmp1, .saved_mckr
  95. /*
  96. * Set the Master clock source to slow clock
  97. */
  98. bic tmp1, tmp1, #AT91_PMC_CSS
  99. str tmp1, [pmc, #AT91_PMC_MCKR]
  100. wait_mckrdy
  101. /* Save PLLA setting and disable it */
  102. ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
  103. str tmp1, .saved_pllar
  104. mov tmp1, #AT91_PMC_PLLCOUNT
  105. orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
  106. str tmp1, [pmc, #AT91_CKGR_PLLAR]
  107. /* Turn off the main oscillator */
  108. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  109. bic tmp1, tmp1, #AT91_PMC_MOSCEN
  110. orr tmp1, tmp1, #AT91_PMC_KEY
  111. str tmp1, [pmc, #AT91_CKGR_MOR]
  112. skip_disable_main_clock:
  113. ldr pmc, .pmc_base
  114. /* Wait for interrupt */
  115. at91_cpu_idle
  116. ldr r0, .pm_mode
  117. tst r0, #AT91_PM_SLOW_CLOCK
  118. beq skip_enable_main_clock
  119. ldr pmc, .pmc_base
  120. /* Turn on the main oscillator */
  121. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  122. orr tmp1, tmp1, #AT91_PMC_MOSCEN
  123. orr tmp1, tmp1, #AT91_PMC_KEY
  124. str tmp1, [pmc, #AT91_CKGR_MOR]
  125. wait_moscrdy
  126. /* Restore PLLA setting */
  127. ldr tmp1, .saved_pllar
  128. str tmp1, [pmc, #AT91_CKGR_PLLAR]
  129. tst tmp1, #(AT91_PMC_MUL & 0xff0000)
  130. bne 3f
  131. tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
  132. beq 4f
  133. 3:
  134. wait_pllalock
  135. 4:
  136. /*
  137. * Restore master clock setting
  138. */
  139. ldr tmp1, .saved_mckr
  140. str tmp1, [pmc, #AT91_PMC_MCKR]
  141. wait_mckrdy
  142. skip_enable_main_clock:
  143. /* Exit the self-refresh mode */
  144. mov r0, #SRAMC_SELF_FRESH_EXIT
  145. bl at91_sramc_self_refresh
  146. /* Restore registers, and return */
  147. ldmfd sp!, {r4 - r12, pc}
  148. ENDPROC(at91_pm_suspend_in_sram)
  149. /*
  150. * void at91_sramc_self_refresh(unsigned int is_active)
  151. *
  152. * @input param:
  153. * @r0: 1 - active self-refresh mode
  154. * 0 - exit self-refresh mode
  155. * register usage:
  156. * @r1: memory type
  157. * @r2: base address of the sram controller
  158. */
  159. ENTRY(at91_sramc_self_refresh)
  160. ldr r1, .memtype
  161. ldr r2, .sramc_base
  162. cmp r1, #AT91_MEMCTRL_MC
  163. bne ddrc_sf
  164. /*
  165. * at91rm9200 Memory controller
  166. */
  167. /*
  168. * For exiting the self-refresh mode, do nothing,
  169. * automatically exit the self-refresh mode.
  170. */
  171. tst r0, #SRAMC_SELF_FRESH_ACTIVE
  172. beq exit_sramc_sf
  173. /* Active SDRAM self-refresh mode */
  174. mov r3, #1
  175. str r3, [r2, #AT91RM9200_SDRAMC_SRR]
  176. b exit_sramc_sf
  177. ddrc_sf:
  178. cmp r1, #AT91_MEMCTRL_DDRSDR
  179. bne sdramc_sf
  180. /*
  181. * DDR Memory controller
  182. */
  183. tst r0, #SRAMC_SELF_FRESH_ACTIVE
  184. beq ddrc_exit_sf
  185. /* LPDDR1 --> force DDR2 mode during self-refresh */
  186. ldr r3, [r2, #AT91_DDRSDRC_MDR]
  187. str r3, .saved_sam9_mdr
  188. bic r3, r3, #~AT91_DDRSDRC_MD
  189. cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
  190. ldreq r3, [r2, #AT91_DDRSDRC_MDR]
  191. biceq r3, r3, #AT91_DDRSDRC_MD
  192. orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
  193. streq r3, [r2, #AT91_DDRSDRC_MDR]
  194. /* Active DDRC self-refresh mode */
  195. ldr r3, [r2, #AT91_DDRSDRC_LPR]
  196. str r3, .saved_sam9_lpr
  197. bic r3, r3, #AT91_DDRSDRC_LPCB
  198. orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
  199. str r3, [r2, #AT91_DDRSDRC_LPR]
  200. /* If using the 2nd ddr controller */
  201. ldr r2, .sramc1_base
  202. cmp r2, #0
  203. beq no_2nd_ddrc
  204. ldr r3, [r2, #AT91_DDRSDRC_MDR]
  205. str r3, .saved_sam9_mdr1
  206. bic r3, r3, #~AT91_DDRSDRC_MD
  207. cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
  208. ldreq r3, [r2, #AT91_DDRSDRC_MDR]
  209. biceq r3, r3, #AT91_DDRSDRC_MD
  210. orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
  211. streq r3, [r2, #AT91_DDRSDRC_MDR]
  212. /* Active DDRC self-refresh mode */
  213. ldr r3, [r2, #AT91_DDRSDRC_LPR]
  214. str r3, .saved_sam9_lpr1
  215. bic r3, r3, #AT91_DDRSDRC_LPCB
  216. orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
  217. str r3, [r2, #AT91_DDRSDRC_LPR]
  218. no_2nd_ddrc:
  219. b exit_sramc_sf
  220. ddrc_exit_sf:
  221. /* Restore MDR in case of LPDDR1 */
  222. ldr r3, .saved_sam9_mdr
  223. str r3, [r2, #AT91_DDRSDRC_MDR]
  224. /* Restore LPR on AT91 with DDRAM */
  225. ldr r3, .saved_sam9_lpr
  226. str r3, [r2, #AT91_DDRSDRC_LPR]
  227. /* If using the 2nd ddr controller */
  228. ldr r2, .sramc1_base
  229. cmp r2, #0
  230. ldrne r3, .saved_sam9_mdr1
  231. strne r3, [r2, #AT91_DDRSDRC_MDR]
  232. ldrne r3, .saved_sam9_lpr1
  233. strne r3, [r2, #AT91_DDRSDRC_LPR]
  234. b exit_sramc_sf
  235. /*
  236. * SDRAMC Memory controller
  237. */
  238. sdramc_sf:
  239. tst r0, #SRAMC_SELF_FRESH_ACTIVE
  240. beq sdramc_exit_sf
  241. /* Active SDRAMC self-refresh mode */
  242. ldr r3, [r2, #AT91_SDRAMC_LPR]
  243. str r3, .saved_sam9_lpr
  244. bic r3, r3, #AT91_SDRAMC_LPCB
  245. orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
  246. str r3, [r2, #AT91_SDRAMC_LPR]
  247. sdramc_exit_sf:
  248. ldr r3, .saved_sam9_lpr
  249. str r3, [r2, #AT91_SDRAMC_LPR]
  250. exit_sramc_sf:
  251. mov pc, lr
  252. ENDPROC(at91_sramc_self_refresh)
  253. .pmc_base:
  254. .word 0
  255. .sramc_base:
  256. .word 0
  257. .sramc1_base:
  258. .word 0
  259. .memtype:
  260. .word 0
  261. .pm_mode:
  262. .word 0
  263. .saved_mckr:
  264. .word 0
  265. .saved_pllar:
  266. .word 0
  267. .saved_sam9_lpr:
  268. .word 0
  269. .saved_sam9_lpr1:
  270. .word 0
  271. .saved_sam9_mdr:
  272. .word 0
  273. .saved_sam9_mdr1:
  274. .word 0
  275. ENTRY(at91_pm_suspend_in_sram_sz)
  276. .word .-at91_pm_suspend_in_sram