sleep43xx.S 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Low level suspend code for AM43XX SoCs
  4. *
  5. * Copyright (C) 2013-2018 Texas Instruments Incorporated - http://www.ti.com/
  6. * Dave Gerlach, Vaibhav Bedia
  7. */
  8. #include <generated/ti-pm-asm-offsets.h>
  9. #include <linux/linkage.h>
  10. #include <linux/ti-emif-sram.h>
  11. #include <asm/assembler.h>
  12. #include <asm/hardware/cache-l2x0.h>
  13. #include <asm/memory.h>
  14. #include "cm33xx.h"
  15. #include "common.h"
  16. #include "iomap.h"
  17. #include "omap-secure.h"
  18. #include "omap44xx.h"
  19. #include "prm33xx.h"
  20. #include "prcm43xx.h"
  21. #define AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED 0x00030000
  22. #define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE 0x0003
  23. #define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 0x0002
  24. #define AM43XX_EMIF_POWEROFF_ENABLE 0x1
  25. #define AM43XX_EMIF_POWEROFF_DISABLE 0x0
  26. #define AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP 0x1
  27. #define AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO 0x3
  28. #define AM43XX_CM_BASE 0x44DF0000
  29. #define AM43XX_CM_REGADDR(inst, reg) \
  30. AM33XX_L4_WK_IO_ADDRESS(AM43XX_CM_BASE + (inst) + (reg))
  31. #define AM43XX_CM_MPU_CLKSTCTRL AM43XX_CM_REGADDR(AM43XX_CM_MPU_INST, \
  32. AM43XX_CM_MPU_MPU_CDOFFS)
  33. #define AM43XX_CM_MPU_MPU_CLKCTRL AM43XX_CM_REGADDR(AM43XX_CM_MPU_INST, \
  34. AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET)
  35. #define AM43XX_CM_PER_EMIF_CLKCTRL AM43XX_CM_REGADDR(AM43XX_CM_PER_INST, \
  36. AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET)
  37. #define AM43XX_PRM_EMIF_CTRL_OFFSET 0x0030
  38. .arm
  39. .align 3
  40. ENTRY(am43xx_do_wfi)
  41. stmfd sp!, {r4 - r11, lr} @ save registers on stack
  42. #ifdef CONFIG_CACHE_L2X0
  43. /* Retrieve l2 cache virt address BEFORE we shut off EMIF */
  44. ldr r1, get_l2cache_base
  45. blx r1
  46. mov r8, r0
  47. #endif
  48. /*
  49. * Flush all data from the L1 and L2 data cache before disabling
  50. * SCTLR.C bit.
  51. */
  52. ldr r1, kernel_flush
  53. blx r1
  54. /*
  55. * Clear the SCTLR.C bit to prevent further data cache
  56. * allocation. Clearing SCTLR.C would make all the data accesses
  57. * strongly ordered and would not hit the cache.
  58. */
  59. mrc p15, 0, r0, c1, c0, 0
  60. bic r0, r0, #(1 << 2) @ Disable the C bit
  61. mcr p15, 0, r0, c1, c0, 0
  62. isb
  63. dsb
  64. /*
  65. * Invalidate L1 and L2 data cache.
  66. */
  67. ldr r1, kernel_flush
  68. blx r1
  69. #ifdef CONFIG_CACHE_L2X0
  70. /*
  71. * Clean and invalidate the L2 cache.
  72. */
  73. #ifdef CONFIG_PL310_ERRATA_727915
  74. mov r0, #0x03
  75. mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
  76. dsb
  77. smc #0
  78. dsb
  79. #endif
  80. mov r0, r8
  81. adr r4, am43xx_pm_ro_sram_data
  82. ldr r3, [r4, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
  83. mov r2, r0
  84. ldr r0, [r2, #L2X0_AUX_CTRL]
  85. str r0, [r3, #AMX3_PM_L2_AUX_CTRL_VAL_OFFSET]
  86. ldr r0, [r2, #L310_PREFETCH_CTRL]
  87. str r0, [r3, #AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET]
  88. ldr r0, l2_val
  89. str r0, [r2, #L2X0_CLEAN_INV_WAY]
  90. wait:
  91. ldr r0, [r2, #L2X0_CLEAN_INV_WAY]
  92. ldr r1, l2_val
  93. ands r0, r0, r1
  94. bne wait
  95. #ifdef CONFIG_PL310_ERRATA_727915
  96. mov r0, #0x00
  97. mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
  98. dsb
  99. smc #0
  100. dsb
  101. #endif
  102. l2x_sync:
  103. mov r0, r8
  104. mov r2, r0
  105. mov r0, #0x0
  106. str r0, [r2, #L2X0_CACHE_SYNC]
  107. sync:
  108. ldr r0, [r2, #L2X0_CACHE_SYNC]
  109. ands r0, r0, #0x1
  110. bne sync
  111. #endif
  112. adr r9, am43xx_emif_sram_table
  113. ldr r3, [r9, #EMIF_PM_ENTER_SR_OFFSET]
  114. blx r3
  115. ldr r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET]
  116. blx r3
  117. /* Disable EMIF */
  118. ldr r1, am43xx_virt_emif_clkctrl
  119. ldr r2, [r1]
  120. bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
  121. str r2, [r1]
  122. wait_emif_disable:
  123. ldr r2, [r1]
  124. mov r3, #AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED
  125. cmp r2, r3
  126. bne wait_emif_disable
  127. /*
  128. * For the MPU WFI to be registered as an interrupt
  129. * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set
  130. * to DISABLED
  131. */
  132. ldr r1, am43xx_virt_mpu_clkctrl
  133. ldr r2, [r1]
  134. bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
  135. str r2, [r1]
  136. /*
  137. * Put MPU CLKDM to SW_SLEEP
  138. */
  139. ldr r1, am43xx_virt_mpu_clkstctrl
  140. mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP
  141. str r2, [r1]
  142. /*
  143. * Execute a barrier instruction to ensure that all cache,
  144. * TLB and branch predictor maintenance operations issued
  145. * have completed.
  146. */
  147. dsb
  148. dmb
  149. /*
  150. * Execute a WFI instruction and wait until the
  151. * STANDBYWFI output is asserted to indicate that the
  152. * CPU is in idle and low power state. CPU can specualatively
  153. * prefetch the instructions so add NOPs after WFI. Sixteen
  154. * NOPs as per Cortex-A9 pipeline.
  155. */
  156. wfi
  157. nop
  158. nop
  159. nop
  160. nop
  161. nop
  162. nop
  163. nop
  164. nop
  165. nop
  166. nop
  167. nop
  168. nop
  169. nop
  170. nop
  171. nop
  172. nop
  173. /* We come here in case of an abort due to a late interrupt */
  174. ldr r1, am43xx_virt_mpu_clkstctrl
  175. mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO
  176. str r2, [r1]
  177. /* Set MPU_CLKCTRL.MODULEMODE back to ENABLE */
  178. ldr r1, am43xx_virt_mpu_clkctrl
  179. mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
  180. str r2, [r1]
  181. /* Re-enable EMIF */
  182. ldr r1, am43xx_virt_emif_clkctrl
  183. mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
  184. str r2, [r1]
  185. wait_emif_enable:
  186. ldr r3, [r1]
  187. cmp r2, r3
  188. bne wait_emif_enable
  189. /*
  190. * Set SCTLR.C bit to allow data cache allocation
  191. */
  192. mrc p15, 0, r0, c1, c0, 0
  193. orr r0, r0, #(1 << 2) @ Enable the C bit
  194. mcr p15, 0, r0, c1, c0, 0
  195. isb
  196. ldr r1, [r9, #EMIF_PM_ABORT_SR_OFFSET]
  197. blx r1
  198. /* Let the suspend code know about the abort */
  199. mov r0, #1
  200. ldmfd sp!, {r4 - r11, pc} @ restore regs and return
  201. ENDPROC(am43xx_do_wfi)
  202. .align
  203. ENTRY(am43xx_resume_offset)
  204. .word . - am43xx_do_wfi
  205. ENTRY(am43xx_resume_from_deep_sleep)
  206. /* Set MPU CLKSTCTRL to HW AUTO so that CPUidle works properly */
  207. ldr r1, am43xx_virt_mpu_clkstctrl
  208. mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO
  209. str r2, [r1]
  210. /* For AM43xx, use EMIF power down until context is restored */
  211. ldr r2, am43xx_phys_emif_poweroff
  212. mov r1, #AM43XX_EMIF_POWEROFF_ENABLE
  213. str r1, [r2, #0x0]
  214. /* Re-enable EMIF */
  215. ldr r1, am43xx_phys_emif_clkctrl
  216. mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
  217. str r2, [r1]
  218. wait_emif_enable1:
  219. ldr r3, [r1]
  220. cmp r2, r3
  221. bne wait_emif_enable1
  222. adr r9, am43xx_emif_sram_table
  223. ldr r1, [r9, #EMIF_PM_RESTORE_CONTEXT_OFFSET]
  224. blx r1
  225. ldr r1, [r9, #EMIF_PM_EXIT_SR_OFFSET]
  226. blx r1
  227. ldr r2, am43xx_phys_emif_poweroff
  228. mov r1, #AM43XX_EMIF_POWEROFF_DISABLE
  229. str r1, [r2, #0x0]
  230. #ifdef CONFIG_CACHE_L2X0
  231. ldr r2, l2_cache_base
  232. ldr r0, [r2, #L2X0_CTRL]
  233. and r0, #0x0f
  234. cmp r0, #1
  235. beq skip_l2en @ Skip if already enabled
  236. adr r4, am43xx_pm_ro_sram_data
  237. ldr r3, [r4, #AMX3_PM_RO_SRAM_DATA_PHYS_OFFSET]
  238. ldr r0, [r3, #AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET]
  239. ldr r12, l2_smc1
  240. dsb
  241. smc #0
  242. dsb
  243. set_aux_ctrl:
  244. ldr r0, [r3, #AMX3_PM_L2_AUX_CTRL_VAL_OFFSET]
  245. ldr r12, l2_smc2
  246. dsb
  247. smc #0
  248. dsb
  249. /* L2 invalidate on resume */
  250. ldr r0, l2_val
  251. ldr r2, l2_cache_base
  252. str r0, [r2, #L2X0_INV_WAY]
  253. wait2:
  254. ldr r0, [r2, #L2X0_INV_WAY]
  255. ldr r1, l2_val
  256. ands r0, r0, r1
  257. bne wait2
  258. #ifdef CONFIG_PL310_ERRATA_727915
  259. mov r0, #0x00
  260. mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
  261. dsb
  262. smc #0
  263. dsb
  264. #endif
  265. l2x_sync2:
  266. ldr r2, l2_cache_base
  267. mov r0, #0x0
  268. str r0, [r2, #L2X0_CACHE_SYNC]
  269. sync2:
  270. ldr r0, [r2, #L2X0_CACHE_SYNC]
  271. ands r0, r0, #0x1
  272. bne sync2
  273. mov r0, #0x1
  274. ldr r12, l2_smc3
  275. dsb
  276. smc #0
  277. dsb
  278. #endif
  279. skip_l2en:
  280. /* We are back. Branch to the common CPU resume routine */
  281. mov r0, #0
  282. ldr pc, resume_addr
  283. ENDPROC(am43xx_resume_from_deep_sleep)
  284. /*
  285. * Local variables
  286. */
  287. .align
  288. resume_addr:
  289. .word cpu_resume - PAGE_OFFSET + 0x80000000
  290. kernel_flush:
  291. .word v7_flush_dcache_all
  292. ddr_start:
  293. .word PAGE_OFFSET
  294. am43xx_phys_emif_poweroff:
  295. .word (AM43XX_CM_BASE + AM43XX_PRM_DEVICE_INST + \
  296. AM43XX_PRM_EMIF_CTRL_OFFSET)
  297. am43xx_virt_mpu_clkstctrl:
  298. .word (AM43XX_CM_MPU_CLKSTCTRL)
  299. am43xx_virt_mpu_clkctrl:
  300. .word (AM43XX_CM_MPU_MPU_CLKCTRL)
  301. am43xx_virt_emif_clkctrl:
  302. .word (AM43XX_CM_PER_EMIF_CLKCTRL)
  303. am43xx_phys_emif_clkctrl:
  304. .word (AM43XX_CM_BASE + AM43XX_CM_PER_INST + \
  305. AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET)
  306. #ifdef CONFIG_CACHE_L2X0
  307. /* L2 cache related defines for AM437x */
  308. get_l2cache_base:
  309. .word omap4_get_l2cache_base
  310. l2_cache_base:
  311. .word OMAP44XX_L2CACHE_BASE
  312. l2_smc1:
  313. .word OMAP4_MON_L2X0_PREFETCH_INDEX
  314. l2_smc2:
  315. .word OMAP4_MON_L2X0_AUXCTRL_INDEX
  316. l2_smc3:
  317. .word OMAP4_MON_L2X0_CTRL_INDEX
  318. l2_val:
  319. .word 0xffff
  320. #endif
  321. .align 3
  322. /* DDR related defines */
  323. ENTRY(am43xx_emif_sram_table)
  324. .space EMIF_PM_FUNCTIONS_SIZE
  325. ENTRY(am43xx_pm_sram)
  326. .word am43xx_do_wfi
  327. .word am43xx_do_wfi_sz
  328. .word am43xx_resume_offset
  329. .word am43xx_emif_sram_table
  330. .word am43xx_pm_ro_sram_data
  331. .align 3
  332. ENTRY(am43xx_pm_ro_sram_data)
  333. .space AMX3_PM_RO_SRAM_DATA_SIZE
  334. ENTRY(am43xx_do_wfi_sz)
  335. .word . - am43xx_do_wfi