pm_suspend.S 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  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 "pm.h"
  17. #include "generated/at91_pm_data-offsets.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_suspend_sram_fn(struct at91_pm_data*)
  64. * @input param:
  65. * @r0: base address of struct at91_pm_data
  66. */
  67. /* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
  68. .align 3
  69. ENTRY(at91_pm_suspend_in_sram)
  70. /* Save registers on stack */
  71. stmfd sp!, {r4 - r12, lr}
  72. /* Drain write buffer */
  73. mov tmp1, #0
  74. mcr p15, 0, tmp1, c7, c10, 4
  75. ldr tmp1, [r0, #PM_DATA_PMC]
  76. str tmp1, .pmc_base
  77. ldr tmp1, [r0, #PM_DATA_RAMC0]
  78. str tmp1, .sramc_base
  79. ldr tmp1, [r0, #PM_DATA_RAMC1]
  80. str tmp1, .sramc1_base
  81. ldr tmp1, [r0, #PM_DATA_MEMCTRL]
  82. str tmp1, .memtype
  83. ldr tmp1, [r0, #PM_DATA_MODE]
  84. str tmp1, .pm_mode
  85. /* Both ldrne below are here to preload their address in the TLB */
  86. ldr tmp1, [r0, #PM_DATA_SHDWC]
  87. str tmp1, .shdwc
  88. cmp tmp1, #0
  89. ldrne tmp2, [tmp1, #0]
  90. ldr tmp1, [r0, #PM_DATA_SFRBU]
  91. str tmp1, .sfr
  92. cmp tmp1, #0
  93. ldrne tmp2, [tmp1, #0x10]
  94. /* Active the self-refresh mode */
  95. mov r0, #SRAMC_SELF_FRESH_ACTIVE
  96. bl at91_sramc_self_refresh
  97. ldr r0, .pm_mode
  98. cmp r0, #AT91_PM_SLOW_CLOCK
  99. beq slow_clock
  100. cmp r0, #AT91_PM_BACKUP
  101. beq backup_mode
  102. /* Wait for interrupt */
  103. ldr pmc, .pmc_base
  104. at91_cpu_idle
  105. b exit_suspend
  106. slow_clock:
  107. bl at91_slowck_mode
  108. b exit_suspend
  109. backup_mode:
  110. bl at91_backup_mode
  111. b exit_suspend
  112. exit_suspend:
  113. /* Exit the self-refresh mode */
  114. mov r0, #SRAMC_SELF_FRESH_EXIT
  115. bl at91_sramc_self_refresh
  116. /* Restore registers, and return */
  117. ldmfd sp!, {r4 - r12, pc}
  118. ENDPROC(at91_pm_suspend_in_sram)
  119. ENTRY(at91_backup_mode)
  120. /*BUMEN*/
  121. ldr r0, .sfr
  122. mov tmp1, #0x1
  123. str tmp1, [r0, #0x10]
  124. /* Shutdown */
  125. ldr r0, .shdwc
  126. mov tmp1, #0xA5000000
  127. add tmp1, tmp1, #0x1
  128. str tmp1, [r0, #0]
  129. ENDPROC(at91_backup_mode)
  130. ENTRY(at91_slowck_mode)
  131. ldr pmc, .pmc_base
  132. /* Save Master clock setting */
  133. ldr tmp1, [pmc, #AT91_PMC_MCKR]
  134. str tmp1, .saved_mckr
  135. /*
  136. * Set the Master clock source to slow clock
  137. */
  138. bic tmp1, tmp1, #AT91_PMC_CSS
  139. str tmp1, [pmc, #AT91_PMC_MCKR]
  140. wait_mckrdy
  141. /* Save PLLA setting and disable it */
  142. ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
  143. str tmp1, .saved_pllar
  144. mov tmp1, #AT91_PMC_PLLCOUNT
  145. orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
  146. str tmp1, [pmc, #AT91_CKGR_PLLAR]
  147. /* Turn off the main oscillator */
  148. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  149. bic tmp1, tmp1, #AT91_PMC_MOSCEN
  150. orr tmp1, tmp1, #AT91_PMC_KEY
  151. str tmp1, [pmc, #AT91_CKGR_MOR]
  152. /* Wait for interrupt */
  153. at91_cpu_idle
  154. /* Turn on the main oscillator */
  155. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  156. orr tmp1, tmp1, #AT91_PMC_MOSCEN
  157. orr tmp1, tmp1, #AT91_PMC_KEY
  158. str tmp1, [pmc, #AT91_CKGR_MOR]
  159. wait_moscrdy
  160. /* Restore PLLA setting */
  161. ldr tmp1, .saved_pllar
  162. str tmp1, [pmc, #AT91_CKGR_PLLAR]
  163. tst tmp1, #(AT91_PMC_MUL & 0xff0000)
  164. bne 3f
  165. tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
  166. beq 4f
  167. 3:
  168. wait_pllalock
  169. 4:
  170. /*
  171. * Restore master clock setting
  172. */
  173. ldr tmp1, .saved_mckr
  174. str tmp1, [pmc, #AT91_PMC_MCKR]
  175. wait_mckrdy
  176. mov pc, lr
  177. ENDPROC(at91_slowck_mode)
  178. /*
  179. * void at91_sramc_self_refresh(unsigned int is_active)
  180. *
  181. * @input param:
  182. * @r0: 1 - active self-refresh mode
  183. * 0 - exit self-refresh mode
  184. * register usage:
  185. * @r1: memory type
  186. * @r2: base address of the sram controller
  187. */
  188. ENTRY(at91_sramc_self_refresh)
  189. ldr r1, .memtype
  190. ldr r2, .sramc_base
  191. cmp r1, #AT91_MEMCTRL_MC
  192. bne ddrc_sf
  193. /*
  194. * at91rm9200 Memory controller
  195. */
  196. /*
  197. * For exiting the self-refresh mode, do nothing,
  198. * automatically exit the self-refresh mode.
  199. */
  200. tst r0, #SRAMC_SELF_FRESH_ACTIVE
  201. beq exit_sramc_sf
  202. /* Active SDRAM self-refresh mode */
  203. mov r3, #1
  204. str r3, [r2, #AT91_MC_SDRAMC_SRR]
  205. b exit_sramc_sf
  206. ddrc_sf:
  207. cmp r1, #AT91_MEMCTRL_DDRSDR
  208. bne sdramc_sf
  209. /*
  210. * DDR Memory controller
  211. */
  212. tst r0, #SRAMC_SELF_FRESH_ACTIVE
  213. beq ddrc_exit_sf
  214. /* LPDDR1 --> force DDR2 mode during self-refresh */
  215. ldr r3, [r2, #AT91_DDRSDRC_MDR]
  216. str r3, .saved_sam9_mdr
  217. bic r3, r3, #~AT91_DDRSDRC_MD
  218. cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
  219. ldreq r3, [r2, #AT91_DDRSDRC_MDR]
  220. biceq r3, r3, #AT91_DDRSDRC_MD
  221. orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
  222. streq r3, [r2, #AT91_DDRSDRC_MDR]
  223. /* Active DDRC self-refresh mode */
  224. ldr r3, [r2, #AT91_DDRSDRC_LPR]
  225. str r3, .saved_sam9_lpr
  226. bic r3, r3, #AT91_DDRSDRC_LPCB
  227. orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
  228. str r3, [r2, #AT91_DDRSDRC_LPR]
  229. /* If using the 2nd ddr controller */
  230. ldr r2, .sramc1_base
  231. cmp r2, #0
  232. beq no_2nd_ddrc
  233. ldr r3, [r2, #AT91_DDRSDRC_MDR]
  234. str r3, .saved_sam9_mdr1
  235. bic r3, r3, #~AT91_DDRSDRC_MD
  236. cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
  237. ldreq r3, [r2, #AT91_DDRSDRC_MDR]
  238. biceq r3, r3, #AT91_DDRSDRC_MD
  239. orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
  240. streq r3, [r2, #AT91_DDRSDRC_MDR]
  241. /* Active DDRC self-refresh mode */
  242. ldr r3, [r2, #AT91_DDRSDRC_LPR]
  243. str r3, .saved_sam9_lpr1
  244. bic r3, r3, #AT91_DDRSDRC_LPCB
  245. orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
  246. str r3, [r2, #AT91_DDRSDRC_LPR]
  247. no_2nd_ddrc:
  248. b exit_sramc_sf
  249. ddrc_exit_sf:
  250. /* Restore MDR in case of LPDDR1 */
  251. ldr r3, .saved_sam9_mdr
  252. str r3, [r2, #AT91_DDRSDRC_MDR]
  253. /* Restore LPR on AT91 with DDRAM */
  254. ldr r3, .saved_sam9_lpr
  255. str r3, [r2, #AT91_DDRSDRC_LPR]
  256. /* If using the 2nd ddr controller */
  257. ldr r2, .sramc1_base
  258. cmp r2, #0
  259. ldrne r3, .saved_sam9_mdr1
  260. strne r3, [r2, #AT91_DDRSDRC_MDR]
  261. ldrne r3, .saved_sam9_lpr1
  262. strne r3, [r2, #AT91_DDRSDRC_LPR]
  263. b exit_sramc_sf
  264. /*
  265. * SDRAMC Memory controller
  266. */
  267. sdramc_sf:
  268. tst r0, #SRAMC_SELF_FRESH_ACTIVE
  269. beq sdramc_exit_sf
  270. /* Active SDRAMC self-refresh mode */
  271. ldr r3, [r2, #AT91_SDRAMC_LPR]
  272. str r3, .saved_sam9_lpr
  273. bic r3, r3, #AT91_SDRAMC_LPCB
  274. orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
  275. str r3, [r2, #AT91_SDRAMC_LPR]
  276. sdramc_exit_sf:
  277. ldr r3, .saved_sam9_lpr
  278. str r3, [r2, #AT91_SDRAMC_LPR]
  279. exit_sramc_sf:
  280. mov pc, lr
  281. ENDPROC(at91_sramc_self_refresh)
  282. .pmc_base:
  283. .word 0
  284. .sramc_base:
  285. .word 0
  286. .sramc1_base:
  287. .word 0
  288. .shdwc:
  289. .word 0
  290. .sfr:
  291. .word 0
  292. .memtype:
  293. .word 0
  294. .pm_mode:
  295. .word 0
  296. .saved_mckr:
  297. .word 0
  298. .saved_pllar:
  299. .word 0
  300. .saved_sam9_lpr:
  301. .word 0
  302. .saved_sam9_lpr1:
  303. .word 0
  304. .saved_sam9_mdr:
  305. .word 0
  306. .saved_sam9_mdr1:
  307. .word 0
  308. ENTRY(at91_pm_suspend_in_sram_sz)
  309. .word .-at91_pm_suspend_in_sram