pm_suspend.S 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  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 for main oscillator selection is done
  41. */
  42. .macro wait_moscsels
  43. 1: ldr tmp1, [pmc, #AT91_PMC_SR]
  44. tst tmp1, #AT91_PMC_MOSCSELS
  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. * Put the processor to enter the idle state
  57. */
  58. .macro at91_cpu_idle
  59. #if defined(CONFIG_CPU_V7)
  60. mov tmp1, #AT91_PMC_PCK
  61. str tmp1, [pmc, #AT91_PMC_SCDR]
  62. dsb
  63. wfi @ Wait For Interrupt
  64. #else
  65. mcr p15, 0, tmp1, c7, c0, 4
  66. #endif
  67. .endm
  68. .text
  69. .arm
  70. /*
  71. * void at91_suspend_sram_fn(struct at91_pm_data*)
  72. * @input param:
  73. * @r0: base address of struct at91_pm_data
  74. */
  75. /* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */
  76. .align 3
  77. ENTRY(at91_pm_suspend_in_sram)
  78. /* Save registers on stack */
  79. stmfd sp!, {r4 - r12, lr}
  80. /* Drain write buffer */
  81. mov tmp1, #0
  82. mcr p15, 0, tmp1, c7, c10, 4
  83. ldr tmp1, [r0, #PM_DATA_PMC]
  84. str tmp1, .pmc_base
  85. ldr tmp1, [r0, #PM_DATA_RAMC0]
  86. str tmp1, .sramc_base
  87. ldr tmp1, [r0, #PM_DATA_RAMC1]
  88. str tmp1, .sramc1_base
  89. ldr tmp1, [r0, #PM_DATA_MEMCTRL]
  90. str tmp1, .memtype
  91. ldr tmp1, [r0, #PM_DATA_MODE]
  92. str tmp1, .pm_mode
  93. /* Both ldrne below are here to preload their address in the TLB */
  94. ldr tmp1, [r0, #PM_DATA_SHDWC]
  95. str tmp1, .shdwc
  96. cmp tmp1, #0
  97. ldrne tmp2, [tmp1, #0]
  98. ldr tmp1, [r0, #PM_DATA_SFRBU]
  99. str tmp1, .sfr
  100. cmp tmp1, #0
  101. ldrne tmp2, [tmp1, #0x10]
  102. /* Active the self-refresh mode */
  103. mov r0, #SRAMC_SELF_FRESH_ACTIVE
  104. bl at91_sramc_self_refresh
  105. ldr r0, .pm_mode
  106. cmp r0, #AT91_PM_STANDBY
  107. beq standby
  108. cmp r0, #AT91_PM_BACKUP
  109. beq backup_mode
  110. bl at91_ulp_mode
  111. b exit_suspend
  112. standby:
  113. /* Wait for interrupt */
  114. ldr pmc, .pmc_base
  115. at91_cpu_idle
  116. b exit_suspend
  117. backup_mode:
  118. bl at91_backup_mode
  119. b exit_suspend
  120. exit_suspend:
  121. /* Exit the self-refresh mode */
  122. mov r0, #SRAMC_SELF_FRESH_EXIT
  123. bl at91_sramc_self_refresh
  124. /* Restore registers, and return */
  125. ldmfd sp!, {r4 - r12, pc}
  126. ENDPROC(at91_pm_suspend_in_sram)
  127. ENTRY(at91_backup_mode)
  128. /* Switch the master clock source to slow clock. */
  129. ldr pmc, .pmc_base
  130. ldr tmp1, [pmc, #AT91_PMC_MCKR]
  131. bic tmp1, tmp1, #AT91_PMC_CSS
  132. str tmp1, [pmc, #AT91_PMC_MCKR]
  133. wait_mckrdy
  134. /*BUMEN*/
  135. ldr r0, .sfr
  136. mov tmp1, #0x1
  137. str tmp1, [r0, #0x10]
  138. /* Shutdown */
  139. ldr r0, .shdwc
  140. mov tmp1, #0xA5000000
  141. add tmp1, tmp1, #0x1
  142. str tmp1, [r0, #0]
  143. ENDPROC(at91_backup_mode)
  144. .macro at91_pm_ulp0_mode
  145. ldr pmc, .pmc_base
  146. /* Turn off the crystal oscillator */
  147. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  148. bic tmp1, tmp1, #AT91_PMC_MOSCEN
  149. orr tmp1, tmp1, #AT91_PMC_KEY
  150. str tmp1, [pmc, #AT91_CKGR_MOR]
  151. /* Wait for interrupt */
  152. at91_cpu_idle
  153. /* Turn on the crystal oscillator */
  154. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  155. orr tmp1, tmp1, #AT91_PMC_MOSCEN
  156. orr tmp1, tmp1, #AT91_PMC_KEY
  157. str tmp1, [pmc, #AT91_CKGR_MOR]
  158. wait_moscrdy
  159. .endm
  160. /**
  161. * Note: This procedure only applies on the platform which uses
  162. * the external crystal oscillator as a main clock source.
  163. */
  164. .macro at91_pm_ulp1_mode
  165. ldr pmc, .pmc_base
  166. /* Switch the main clock source to 12-MHz RC oscillator */
  167. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  168. bic tmp1, tmp1, #AT91_PMC_MOSCSEL
  169. bic tmp1, tmp1, #AT91_PMC_KEY_MASK
  170. orr tmp1, tmp1, #AT91_PMC_KEY
  171. str tmp1, [pmc, #AT91_CKGR_MOR]
  172. wait_moscsels
  173. /* Disable the crystal oscillator */
  174. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  175. bic tmp1, tmp1, #AT91_PMC_MOSCEN
  176. bic tmp1, tmp1, #AT91_PMC_KEY_MASK
  177. orr tmp1, tmp1, #AT91_PMC_KEY
  178. str tmp1, [pmc, #AT91_CKGR_MOR]
  179. /* Switch the master clock source to main clock */
  180. ldr tmp1, [pmc, #AT91_PMC_MCKR]
  181. bic tmp1, tmp1, #AT91_PMC_CSS
  182. orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
  183. str tmp1, [pmc, #AT91_PMC_MCKR]
  184. wait_mckrdy
  185. /* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */
  186. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  187. orr tmp1, tmp1, #AT91_PMC_WAITMODE
  188. bic tmp1, tmp1, #AT91_PMC_KEY_MASK
  189. orr tmp1, tmp1, #AT91_PMC_KEY
  190. str tmp1, [pmc, #AT91_CKGR_MOR]
  191. wait_mckrdy
  192. /* Enable the crystal oscillator */
  193. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  194. orr tmp1, tmp1, #AT91_PMC_MOSCEN
  195. bic tmp1, tmp1, #AT91_PMC_KEY_MASK
  196. orr tmp1, tmp1, #AT91_PMC_KEY
  197. str tmp1, [pmc, #AT91_CKGR_MOR]
  198. wait_moscrdy
  199. /* Switch the master clock source to slow clock */
  200. ldr tmp1, [pmc, #AT91_PMC_MCKR]
  201. bic tmp1, tmp1, #AT91_PMC_CSS
  202. str tmp1, [pmc, #AT91_PMC_MCKR]
  203. wait_mckrdy
  204. /* Switch main clock source to crystal oscillator */
  205. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  206. orr tmp1, tmp1, #AT91_PMC_MOSCSEL
  207. bic tmp1, tmp1, #AT91_PMC_KEY_MASK
  208. orr tmp1, tmp1, #AT91_PMC_KEY
  209. str tmp1, [pmc, #AT91_CKGR_MOR]
  210. wait_moscsels
  211. /* Switch the master clock source to main clock */
  212. ldr tmp1, [pmc, #AT91_PMC_MCKR]
  213. bic tmp1, tmp1, #AT91_PMC_CSS
  214. orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
  215. str tmp1, [pmc, #AT91_PMC_MCKR]
  216. wait_mckrdy
  217. .endm
  218. ENTRY(at91_ulp_mode)
  219. ldr pmc, .pmc_base
  220. /* Save Master clock setting */
  221. ldr tmp1, [pmc, #AT91_PMC_MCKR]
  222. str tmp1, .saved_mckr
  223. /*
  224. * Set the Master clock source to slow clock
  225. */
  226. bic tmp1, tmp1, #AT91_PMC_CSS
  227. str tmp1, [pmc, #AT91_PMC_MCKR]
  228. wait_mckrdy
  229. /* Save PLLA setting and disable it */
  230. ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
  231. str tmp1, .saved_pllar
  232. mov tmp1, #AT91_PMC_PLLCOUNT
  233. orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
  234. str tmp1, [pmc, #AT91_CKGR_PLLAR]
  235. ldr r0, .pm_mode
  236. cmp r0, #AT91_PM_ULP1
  237. beq ulp1_mode
  238. at91_pm_ulp0_mode
  239. b ulp_exit
  240. ulp1_mode:
  241. at91_pm_ulp1_mode
  242. b ulp_exit
  243. ulp_exit:
  244. ldr pmc, .pmc_base
  245. /* Restore PLLA setting */
  246. ldr tmp1, .saved_pllar
  247. str tmp1, [pmc, #AT91_CKGR_PLLAR]
  248. tst tmp1, #(AT91_PMC_MUL & 0xff0000)
  249. bne 3f
  250. tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
  251. beq 4f
  252. 3:
  253. wait_pllalock
  254. 4:
  255. /*
  256. * Restore master clock setting
  257. */
  258. ldr tmp1, .saved_mckr
  259. str tmp1, [pmc, #AT91_PMC_MCKR]
  260. wait_mckrdy
  261. mov pc, lr
  262. ENDPROC(at91_ulp_mode)
  263. /*
  264. * void at91_sramc_self_refresh(unsigned int is_active)
  265. *
  266. * @input param:
  267. * @r0: 1 - active self-refresh mode
  268. * 0 - exit self-refresh mode
  269. * register usage:
  270. * @r1: memory type
  271. * @r2: base address of the sram controller
  272. */
  273. ENTRY(at91_sramc_self_refresh)
  274. ldr r1, .memtype
  275. ldr r2, .sramc_base
  276. cmp r1, #AT91_MEMCTRL_MC
  277. bne ddrc_sf
  278. /*
  279. * at91rm9200 Memory controller
  280. */
  281. /*
  282. * For exiting the self-refresh mode, do nothing,
  283. * automatically exit the self-refresh mode.
  284. */
  285. tst r0, #SRAMC_SELF_FRESH_ACTIVE
  286. beq exit_sramc_sf
  287. /* Active SDRAM self-refresh mode */
  288. mov r3, #1
  289. str r3, [r2, #AT91_MC_SDRAMC_SRR]
  290. b exit_sramc_sf
  291. ddrc_sf:
  292. cmp r1, #AT91_MEMCTRL_DDRSDR
  293. bne sdramc_sf
  294. /*
  295. * DDR Memory controller
  296. */
  297. tst r0, #SRAMC_SELF_FRESH_ACTIVE
  298. beq ddrc_exit_sf
  299. /* LPDDR1 --> force DDR2 mode during self-refresh */
  300. ldr r3, [r2, #AT91_DDRSDRC_MDR]
  301. str r3, .saved_sam9_mdr
  302. bic r3, r3, #~AT91_DDRSDRC_MD
  303. cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
  304. ldreq r3, [r2, #AT91_DDRSDRC_MDR]
  305. biceq r3, r3, #AT91_DDRSDRC_MD
  306. orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
  307. streq r3, [r2, #AT91_DDRSDRC_MDR]
  308. /* Active DDRC self-refresh mode */
  309. ldr r3, [r2, #AT91_DDRSDRC_LPR]
  310. str r3, .saved_sam9_lpr
  311. bic r3, r3, #AT91_DDRSDRC_LPCB
  312. orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
  313. str r3, [r2, #AT91_DDRSDRC_LPR]
  314. /* If using the 2nd ddr controller */
  315. ldr r2, .sramc1_base
  316. cmp r2, #0
  317. beq no_2nd_ddrc
  318. ldr r3, [r2, #AT91_DDRSDRC_MDR]
  319. str r3, .saved_sam9_mdr1
  320. bic r3, r3, #~AT91_DDRSDRC_MD
  321. cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
  322. ldreq r3, [r2, #AT91_DDRSDRC_MDR]
  323. biceq r3, r3, #AT91_DDRSDRC_MD
  324. orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
  325. streq r3, [r2, #AT91_DDRSDRC_MDR]
  326. /* Active DDRC self-refresh mode */
  327. ldr r3, [r2, #AT91_DDRSDRC_LPR]
  328. str r3, .saved_sam9_lpr1
  329. bic r3, r3, #AT91_DDRSDRC_LPCB
  330. orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
  331. str r3, [r2, #AT91_DDRSDRC_LPR]
  332. no_2nd_ddrc:
  333. b exit_sramc_sf
  334. ddrc_exit_sf:
  335. /* Restore MDR in case of LPDDR1 */
  336. ldr r3, .saved_sam9_mdr
  337. str r3, [r2, #AT91_DDRSDRC_MDR]
  338. /* Restore LPR on AT91 with DDRAM */
  339. ldr r3, .saved_sam9_lpr
  340. str r3, [r2, #AT91_DDRSDRC_LPR]
  341. /* If using the 2nd ddr controller */
  342. ldr r2, .sramc1_base
  343. cmp r2, #0
  344. ldrne r3, .saved_sam9_mdr1
  345. strne r3, [r2, #AT91_DDRSDRC_MDR]
  346. ldrne r3, .saved_sam9_lpr1
  347. strne r3, [r2, #AT91_DDRSDRC_LPR]
  348. b exit_sramc_sf
  349. /*
  350. * SDRAMC Memory controller
  351. */
  352. sdramc_sf:
  353. tst r0, #SRAMC_SELF_FRESH_ACTIVE
  354. beq sdramc_exit_sf
  355. /* Active SDRAMC self-refresh mode */
  356. ldr r3, [r2, #AT91_SDRAMC_LPR]
  357. str r3, .saved_sam9_lpr
  358. bic r3, r3, #AT91_SDRAMC_LPCB
  359. orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
  360. str r3, [r2, #AT91_SDRAMC_LPR]
  361. sdramc_exit_sf:
  362. ldr r3, .saved_sam9_lpr
  363. str r3, [r2, #AT91_SDRAMC_LPR]
  364. exit_sramc_sf:
  365. mov pc, lr
  366. ENDPROC(at91_sramc_self_refresh)
  367. .pmc_base:
  368. .word 0
  369. .sramc_base:
  370. .word 0
  371. .sramc1_base:
  372. .word 0
  373. .shdwc:
  374. .word 0
  375. .sfr:
  376. .word 0
  377. .memtype:
  378. .word 0
  379. .pm_mode:
  380. .word 0
  381. .saved_mckr:
  382. .word 0
  383. .saved_pllar:
  384. .word 0
  385. .saved_sam9_lpr:
  386. .word 0
  387. .saved_sam9_lpr1:
  388. .word 0
  389. .saved_sam9_mdr:
  390. .word 0
  391. .saved_sam9_mdr1:
  392. .word 0
  393. ENTRY(at91_pm_suspend_in_sram_sz)
  394. .word .-at91_pm_suspend_in_sram