pm_suspend.S 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  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. /*BUMEN*/
  129. ldr r0, .sfr
  130. mov tmp1, #0x1
  131. str tmp1, [r0, #0x10]
  132. /* Shutdown */
  133. ldr r0, .shdwc
  134. mov tmp1, #0xA5000000
  135. add tmp1, tmp1, #0x1
  136. str tmp1, [r0, #0]
  137. ENDPROC(at91_backup_mode)
  138. .macro at91_pm_ulp0_mode
  139. ldr pmc, .pmc_base
  140. /* Turn off the crystal oscillator */
  141. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  142. bic tmp1, tmp1, #AT91_PMC_MOSCEN
  143. orr tmp1, tmp1, #AT91_PMC_KEY
  144. str tmp1, [pmc, #AT91_CKGR_MOR]
  145. /* Wait for interrupt */
  146. at91_cpu_idle
  147. /* Turn on the crystal oscillator */
  148. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  149. orr tmp1, tmp1, #AT91_PMC_MOSCEN
  150. orr tmp1, tmp1, #AT91_PMC_KEY
  151. str tmp1, [pmc, #AT91_CKGR_MOR]
  152. wait_moscrdy
  153. .endm
  154. /**
  155. * Note: This procedure only applies on the platform which uses
  156. * the external crystal oscillator as a main clock source.
  157. */
  158. .macro at91_pm_ulp1_mode
  159. ldr pmc, .pmc_base
  160. /* Switch the main clock source to 12-MHz RC oscillator */
  161. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  162. bic tmp1, tmp1, #AT91_PMC_MOSCSEL
  163. bic tmp1, tmp1, #AT91_PMC_KEY_MASK
  164. orr tmp1, tmp1, #AT91_PMC_KEY
  165. str tmp1, [pmc, #AT91_CKGR_MOR]
  166. wait_moscsels
  167. /* Disable the crystal oscillator */
  168. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  169. bic tmp1, tmp1, #AT91_PMC_MOSCEN
  170. bic tmp1, tmp1, #AT91_PMC_KEY_MASK
  171. orr tmp1, tmp1, #AT91_PMC_KEY
  172. str tmp1, [pmc, #AT91_CKGR_MOR]
  173. /* Switch the master clock source to main clock */
  174. ldr tmp1, [pmc, #AT91_PMC_MCKR]
  175. bic tmp1, tmp1, #AT91_PMC_CSS
  176. orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
  177. str tmp1, [pmc, #AT91_PMC_MCKR]
  178. wait_mckrdy
  179. /* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */
  180. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  181. orr tmp1, tmp1, #AT91_PMC_WAITMODE
  182. bic tmp1, tmp1, #AT91_PMC_KEY_MASK
  183. orr tmp1, tmp1, #AT91_PMC_KEY
  184. str tmp1, [pmc, #AT91_CKGR_MOR]
  185. /* Quirk for SAM9X60's PMC */
  186. nop
  187. nop
  188. wait_mckrdy
  189. /* Enable the crystal oscillator */
  190. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  191. orr tmp1, tmp1, #AT91_PMC_MOSCEN
  192. bic tmp1, tmp1, #AT91_PMC_KEY_MASK
  193. orr tmp1, tmp1, #AT91_PMC_KEY
  194. str tmp1, [pmc, #AT91_CKGR_MOR]
  195. wait_moscrdy
  196. /* Switch the master clock source to slow clock */
  197. ldr tmp1, [pmc, #AT91_PMC_MCKR]
  198. bic tmp1, tmp1, #AT91_PMC_CSS
  199. str tmp1, [pmc, #AT91_PMC_MCKR]
  200. wait_mckrdy
  201. /* Switch main clock source to crystal oscillator */
  202. ldr tmp1, [pmc, #AT91_CKGR_MOR]
  203. orr tmp1, tmp1, #AT91_PMC_MOSCSEL
  204. bic tmp1, tmp1, #AT91_PMC_KEY_MASK
  205. orr tmp1, tmp1, #AT91_PMC_KEY
  206. str tmp1, [pmc, #AT91_CKGR_MOR]
  207. wait_moscsels
  208. /* Switch the master clock source to main clock */
  209. ldr tmp1, [pmc, #AT91_PMC_MCKR]
  210. bic tmp1, tmp1, #AT91_PMC_CSS
  211. orr tmp1, tmp1, #AT91_PMC_CSS_MAIN
  212. str tmp1, [pmc, #AT91_PMC_MCKR]
  213. wait_mckrdy
  214. .endm
  215. ENTRY(at91_ulp_mode)
  216. ldr pmc, .pmc_base
  217. /* Save Master clock setting */
  218. ldr tmp1, [pmc, #AT91_PMC_MCKR]
  219. str tmp1, .saved_mckr
  220. /*
  221. * Set the Master clock source to slow clock
  222. */
  223. bic tmp1, tmp1, #AT91_PMC_CSS
  224. str tmp1, [pmc, #AT91_PMC_MCKR]
  225. wait_mckrdy
  226. /* Save PLLA setting and disable it */
  227. ldr tmp1, [pmc, #AT91_CKGR_PLLAR]
  228. str tmp1, .saved_pllar
  229. mov tmp1, #AT91_PMC_PLLCOUNT
  230. orr tmp1, tmp1, #(1 << 29) /* bit 29 always set */
  231. str tmp1, [pmc, #AT91_CKGR_PLLAR]
  232. ldr r0, .pm_mode
  233. cmp r0, #AT91_PM_ULP1
  234. beq ulp1_mode
  235. at91_pm_ulp0_mode
  236. b ulp_exit
  237. ulp1_mode:
  238. at91_pm_ulp1_mode
  239. b ulp_exit
  240. ulp_exit:
  241. ldr pmc, .pmc_base
  242. /* Restore PLLA setting */
  243. ldr tmp1, .saved_pllar
  244. str tmp1, [pmc, #AT91_CKGR_PLLAR]
  245. tst tmp1, #(AT91_PMC_MUL & 0xff0000)
  246. bne 3f
  247. tst tmp1, #(AT91_PMC_MUL & ~0xff0000)
  248. beq 4f
  249. 3:
  250. wait_pllalock
  251. 4:
  252. /*
  253. * Restore master clock setting
  254. */
  255. ldr tmp1, .saved_mckr
  256. str tmp1, [pmc, #AT91_PMC_MCKR]
  257. wait_mckrdy
  258. mov pc, lr
  259. ENDPROC(at91_ulp_mode)
  260. /*
  261. * void at91_sramc_self_refresh(unsigned int is_active)
  262. *
  263. * @input param:
  264. * @r0: 1 - active self-refresh mode
  265. * 0 - exit self-refresh mode
  266. * register usage:
  267. * @r1: memory type
  268. * @r2: base address of the sram controller
  269. */
  270. ENTRY(at91_sramc_self_refresh)
  271. ldr r1, .memtype
  272. ldr r2, .sramc_base
  273. cmp r1, #AT91_MEMCTRL_MC
  274. bne ddrc_sf
  275. /*
  276. * at91rm9200 Memory controller
  277. */
  278. /*
  279. * For exiting the self-refresh mode, do nothing,
  280. * automatically exit the self-refresh mode.
  281. */
  282. tst r0, #SRAMC_SELF_FRESH_ACTIVE
  283. beq exit_sramc_sf
  284. /* Active SDRAM self-refresh mode */
  285. mov r3, #1
  286. str r3, [r2, #AT91_MC_SDRAMC_SRR]
  287. b exit_sramc_sf
  288. ddrc_sf:
  289. cmp r1, #AT91_MEMCTRL_DDRSDR
  290. bne sdramc_sf
  291. /*
  292. * DDR Memory controller
  293. */
  294. tst r0, #SRAMC_SELF_FRESH_ACTIVE
  295. beq ddrc_exit_sf
  296. /* LPDDR1 --> force DDR2 mode during self-refresh */
  297. ldr r3, [r2, #AT91_DDRSDRC_MDR]
  298. str r3, .saved_sam9_mdr
  299. bic r3, r3, #~AT91_DDRSDRC_MD
  300. cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
  301. ldreq r3, [r2, #AT91_DDRSDRC_MDR]
  302. biceq r3, r3, #AT91_DDRSDRC_MD
  303. orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
  304. streq r3, [r2, #AT91_DDRSDRC_MDR]
  305. /* Active DDRC self-refresh mode */
  306. ldr r3, [r2, #AT91_DDRSDRC_LPR]
  307. str r3, .saved_sam9_lpr
  308. bic r3, r3, #AT91_DDRSDRC_LPCB
  309. orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
  310. str r3, [r2, #AT91_DDRSDRC_LPR]
  311. /* If using the 2nd ddr controller */
  312. ldr r2, .sramc1_base
  313. cmp r2, #0
  314. beq no_2nd_ddrc
  315. ldr r3, [r2, #AT91_DDRSDRC_MDR]
  316. str r3, .saved_sam9_mdr1
  317. bic r3, r3, #~AT91_DDRSDRC_MD
  318. cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR
  319. ldreq r3, [r2, #AT91_DDRSDRC_MDR]
  320. biceq r3, r3, #AT91_DDRSDRC_MD
  321. orreq r3, r3, #AT91_DDRSDRC_MD_DDR2
  322. streq r3, [r2, #AT91_DDRSDRC_MDR]
  323. /* Active DDRC self-refresh mode */
  324. ldr r3, [r2, #AT91_DDRSDRC_LPR]
  325. str r3, .saved_sam9_lpr1
  326. bic r3, r3, #AT91_DDRSDRC_LPCB
  327. orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH
  328. str r3, [r2, #AT91_DDRSDRC_LPR]
  329. no_2nd_ddrc:
  330. b exit_sramc_sf
  331. ddrc_exit_sf:
  332. /* Restore MDR in case of LPDDR1 */
  333. ldr r3, .saved_sam9_mdr
  334. str r3, [r2, #AT91_DDRSDRC_MDR]
  335. /* Restore LPR on AT91 with DDRAM */
  336. ldr r3, .saved_sam9_lpr
  337. str r3, [r2, #AT91_DDRSDRC_LPR]
  338. /* If using the 2nd ddr controller */
  339. ldr r2, .sramc1_base
  340. cmp r2, #0
  341. ldrne r3, .saved_sam9_mdr1
  342. strne r3, [r2, #AT91_DDRSDRC_MDR]
  343. ldrne r3, .saved_sam9_lpr1
  344. strne r3, [r2, #AT91_DDRSDRC_LPR]
  345. b exit_sramc_sf
  346. /*
  347. * SDRAMC Memory controller
  348. */
  349. sdramc_sf:
  350. tst r0, #SRAMC_SELF_FRESH_ACTIVE
  351. beq sdramc_exit_sf
  352. /* Active SDRAMC self-refresh mode */
  353. ldr r3, [r2, #AT91_SDRAMC_LPR]
  354. str r3, .saved_sam9_lpr
  355. bic r3, r3, #AT91_SDRAMC_LPCB
  356. orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH
  357. str r3, [r2, #AT91_SDRAMC_LPR]
  358. sdramc_exit_sf:
  359. ldr r3, .saved_sam9_lpr
  360. str r3, [r2, #AT91_SDRAMC_LPR]
  361. exit_sramc_sf:
  362. mov pc, lr
  363. ENDPROC(at91_sramc_self_refresh)
  364. .pmc_base:
  365. .word 0
  366. .sramc_base:
  367. .word 0
  368. .sramc1_base:
  369. .word 0
  370. .shdwc:
  371. .word 0
  372. .sfr:
  373. .word 0
  374. .memtype:
  375. .word 0
  376. .pm_mode:
  377. .word 0
  378. .saved_mckr:
  379. .word 0
  380. .saved_pllar:
  381. .word 0
  382. .saved_sam9_lpr:
  383. .word 0
  384. .saved_sam9_lpr1:
  385. .word 0
  386. .saved_sam9_mdr:
  387. .word 0
  388. .saved_sam9_mdr1:
  389. .word 0
  390. ENTRY(at91_pm_suspend_in_sram_sz)
  391. .word .-at91_pm_suspend_in_sram