sleep43xx.S 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  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 <linux/platform_data/pm33xx.h>
  12. #include <asm/assembler.h>
  13. #include <asm/hardware/cache-l2x0.h>
  14. #include <asm/memory.h>
  15. #include "cm33xx.h"
  16. #include "common.h"
  17. #include "iomap.h"
  18. #include "omap-secure.h"
  19. #include "omap44xx.h"
  20. #include "prm33xx.h"
  21. #include "prcm43xx.h"
  22. /* replicated define because linux/bitops.h cannot be included in assembly */
  23. #define BIT(nr) (1 << (nr))
  24. #define AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED 0x00030000
  25. #define AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE 0x0003
  26. #define AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE 0x0002
  27. #define AM43XX_EMIF_POWEROFF_ENABLE 0x1
  28. #define AM43XX_EMIF_POWEROFF_DISABLE 0x0
  29. #define AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP 0x1
  30. #define AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO 0x3
  31. #define AM43XX_CM_BASE 0x44DF0000
  32. #define AM43XX_CM_REGADDR(inst, reg) \
  33. AM33XX_L4_WK_IO_ADDRESS(AM43XX_CM_BASE + (inst) + (reg))
  34. #define AM43XX_CM_MPU_CLKSTCTRL AM43XX_CM_REGADDR(AM43XX_CM_MPU_INST, \
  35. AM43XX_CM_MPU_MPU_CDOFFS)
  36. #define AM43XX_CM_MPU_MPU_CLKCTRL AM43XX_CM_REGADDR(AM43XX_CM_MPU_INST, \
  37. AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET)
  38. #define AM43XX_CM_PER_EMIF_CLKCTRL AM43XX_CM_REGADDR(AM43XX_CM_PER_INST, \
  39. AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET)
  40. #define AM43XX_PRM_EMIF_CTRL_OFFSET 0x0030
  41. #define RTC_SECONDS_REG 0x0
  42. #define RTC_PMIC_REG 0x98
  43. #define RTC_PMIC_POWER_EN BIT(16)
  44. #define RTC_PMIC_EXT_WAKEUP_STS BIT(12)
  45. #define RTC_PMIC_EXT_WAKEUP_POL BIT(4)
  46. #define RTC_PMIC_EXT_WAKEUP_EN BIT(0)
  47. .arm
  48. .align 3
  49. ENTRY(am43xx_do_wfi)
  50. stmfd sp!, {r4 - r11, lr} @ save registers on stack
  51. /* Save wfi_flags arg to data space */
  52. mov r4, r0
  53. adr r3, am43xx_pm_ro_sram_data
  54. ldr r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
  55. str r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
  56. #ifdef CONFIG_CACHE_L2X0
  57. /* Retrieve l2 cache virt address BEFORE we shut off EMIF */
  58. ldr r1, get_l2cache_base
  59. blx r1
  60. mov r8, r0
  61. #endif
  62. /* Only flush cache is we know we are losing MPU context */
  63. tst r4, #WFI_FLAG_FLUSH_CACHE
  64. beq cache_skip_flush
  65. /*
  66. * Flush all data from the L1 and L2 data cache before disabling
  67. * SCTLR.C bit.
  68. */
  69. ldr r1, kernel_flush
  70. blx r1
  71. /*
  72. * Clear the SCTLR.C bit to prevent further data cache
  73. * allocation. Clearing SCTLR.C would make all the data accesses
  74. * strongly ordered and would not hit the cache.
  75. */
  76. mrc p15, 0, r0, c1, c0, 0
  77. bic r0, r0, #(1 << 2) @ Disable the C bit
  78. mcr p15, 0, r0, c1, c0, 0
  79. isb
  80. dsb
  81. /*
  82. * Invalidate L1 and L2 data cache.
  83. */
  84. ldr r1, kernel_flush
  85. blx r1
  86. #ifdef CONFIG_CACHE_L2X0
  87. /*
  88. * Clean and invalidate the L2 cache.
  89. */
  90. #ifdef CONFIG_PL310_ERRATA_727915
  91. mov r0, #0x03
  92. mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
  93. dsb
  94. smc #0
  95. dsb
  96. #endif
  97. mov r0, r8
  98. adr r4, am43xx_pm_ro_sram_data
  99. ldr r3, [r4, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
  100. mov r2, r0
  101. ldr r0, [r2, #L2X0_AUX_CTRL]
  102. str r0, [r3, #AMX3_PM_L2_AUX_CTRL_VAL_OFFSET]
  103. ldr r0, [r2, #L310_PREFETCH_CTRL]
  104. str r0, [r3, #AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET]
  105. ldr r0, l2_val
  106. str r0, [r2, #L2X0_CLEAN_INV_WAY]
  107. wait:
  108. ldr r0, [r2, #L2X0_CLEAN_INV_WAY]
  109. ldr r1, l2_val
  110. ands r0, r0, r1
  111. bne wait
  112. #ifdef CONFIG_PL310_ERRATA_727915
  113. mov r0, #0x00
  114. mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
  115. dsb
  116. smc #0
  117. dsb
  118. #endif
  119. l2x_sync:
  120. mov r0, r8
  121. mov r2, r0
  122. mov r0, #0x0
  123. str r0, [r2, #L2X0_CACHE_SYNC]
  124. sync:
  125. ldr r0, [r2, #L2X0_CACHE_SYNC]
  126. ands r0, r0, #0x1
  127. bne sync
  128. #endif
  129. /* Restore wfi_flags */
  130. adr r3, am43xx_pm_ro_sram_data
  131. ldr r2, [r3, #AMX3_PM_RO_SRAM_DATA_VIRT_OFFSET]
  132. ldr r4, [r2, #AMX3_PM_WFI_FLAGS_OFFSET]
  133. cache_skip_flush:
  134. /*
  135. * If we are trying to enter RTC+DDR mode we must perform
  136. * a read from the rtc address space to ensure translation
  137. * presence in the TLB to avoid page table walk after DDR
  138. * is unavailable.
  139. */
  140. tst r4, #WFI_FLAG_RTC_ONLY
  141. beq skip_rtc_va_refresh
  142. adr r3, am43xx_pm_ro_sram_data
  143. ldr r1, [r3, #AMX3_PM_RTC_BASE_VIRT_OFFSET]
  144. ldr r0, [r1]
  145. skip_rtc_va_refresh:
  146. /* Check if we want self refresh */
  147. tst r4, #WFI_FLAG_SELF_REFRESH
  148. beq emif_skip_enter_sr
  149. adr r9, am43xx_emif_sram_table
  150. ldr r3, [r9, #EMIF_PM_ENTER_SR_OFFSET]
  151. blx r3
  152. emif_skip_enter_sr:
  153. /* Only necessary if PER is losing context */
  154. tst r4, #WFI_FLAG_SAVE_EMIF
  155. beq emif_skip_save
  156. ldr r3, [r9, #EMIF_PM_SAVE_CONTEXT_OFFSET]
  157. blx r3
  158. emif_skip_save:
  159. /* Only can disable EMIF if we have entered self refresh */
  160. tst r4, #WFI_FLAG_SELF_REFRESH
  161. beq emif_skip_disable
  162. /* Disable EMIF */
  163. ldr r1, am43xx_virt_emif_clkctrl
  164. ldr r2, [r1]
  165. bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
  166. str r2, [r1]
  167. wait_emif_disable:
  168. ldr r2, [r1]
  169. mov r3, #AM33XX_CM_CLKCTRL_MODULESTATE_DISABLED
  170. cmp r2, r3
  171. bne wait_emif_disable
  172. emif_skip_disable:
  173. tst r4, #WFI_FLAG_RTC_ONLY
  174. beq skip_rtc_only
  175. adr r3, am43xx_pm_ro_sram_data
  176. ldr r1, [r3, #AMX3_PM_RTC_BASE_VIRT_OFFSET]
  177. ldr r0, [r1, #RTC_PMIC_REG]
  178. orr r0, r0, #RTC_PMIC_POWER_EN
  179. orr r0, r0, #RTC_PMIC_EXT_WAKEUP_STS
  180. orr r0, r0, #RTC_PMIC_EXT_WAKEUP_EN
  181. orr r0, r0, #RTC_PMIC_EXT_WAKEUP_POL
  182. str r0, [r1, #RTC_PMIC_REG]
  183. ldr r0, [r1, #RTC_PMIC_REG]
  184. /* Wait for 2 seconds to lose power */
  185. mov r3, #2
  186. ldr r2, [r1, #RTC_SECONDS_REG]
  187. rtc_loop:
  188. ldr r0, [r1, #RTC_SECONDS_REG]
  189. cmp r0, r2
  190. beq rtc_loop
  191. mov r2, r0
  192. subs r3, r3, #1
  193. bne rtc_loop
  194. b re_enable_emif
  195. skip_rtc_only:
  196. tst r4, #WFI_FLAG_WAKE_M3
  197. beq wkup_m3_skip
  198. /*
  199. * For the MPU WFI to be registered as an interrupt
  200. * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set
  201. * to DISABLED
  202. */
  203. ldr r1, am43xx_virt_mpu_clkctrl
  204. ldr r2, [r1]
  205. bic r2, r2, #AM33XX_CM_CLKCTRL_MODULEMODE_DISABLE
  206. str r2, [r1]
  207. /*
  208. * Put MPU CLKDM to SW_SLEEP
  209. */
  210. ldr r1, am43xx_virt_mpu_clkstctrl
  211. mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_SW_SLEEP
  212. str r2, [r1]
  213. wkup_m3_skip:
  214. /*
  215. * Execute a barrier instruction to ensure that all cache,
  216. * TLB and branch predictor maintenance operations issued
  217. * have completed.
  218. */
  219. dsb
  220. dmb
  221. /*
  222. * Execute a WFI instruction and wait until the
  223. * STANDBYWFI output is asserted to indicate that the
  224. * CPU is in idle and low power state. CPU can specualatively
  225. * prefetch the instructions so add NOPs after WFI. Sixteen
  226. * NOPs as per Cortex-A9 pipeline.
  227. */
  228. wfi
  229. nop
  230. nop
  231. nop
  232. nop
  233. nop
  234. nop
  235. nop
  236. nop
  237. nop
  238. nop
  239. nop
  240. nop
  241. nop
  242. nop
  243. nop
  244. nop
  245. /* We come here in case of an abort due to a late interrupt */
  246. ldr r1, am43xx_virt_mpu_clkstctrl
  247. mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO
  248. str r2, [r1]
  249. /* Set MPU_CLKCTRL.MODULEMODE back to ENABLE */
  250. ldr r1, am43xx_virt_mpu_clkctrl
  251. mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
  252. str r2, [r1]
  253. re_enable_emif:
  254. /* Re-enable EMIF */
  255. ldr r1, am43xx_virt_emif_clkctrl
  256. mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
  257. str r2, [r1]
  258. wait_emif_enable:
  259. ldr r3, [r1]
  260. cmp r2, r3
  261. bne wait_emif_enable
  262. tst r4, #WFI_FLAG_FLUSH_CACHE
  263. beq cache_skip_restore
  264. /*
  265. * Set SCTLR.C bit to allow data cache allocation
  266. */
  267. mrc p15, 0, r0, c1, c0, 0
  268. orr r0, r0, #(1 << 2) @ Enable the C bit
  269. mcr p15, 0, r0, c1, c0, 0
  270. isb
  271. cache_skip_restore:
  272. /* Only necessary if PER is losing context */
  273. tst r4, #WFI_FLAG_SELF_REFRESH
  274. beq emif_skip_exit_sr_abt
  275. adr r9, am43xx_emif_sram_table
  276. ldr r1, [r9, #EMIF_PM_ABORT_SR_OFFSET]
  277. blx r1
  278. emif_skip_exit_sr_abt:
  279. /* Let the suspend code know about the abort */
  280. mov r0, #1
  281. ldmfd sp!, {r4 - r11, pc} @ restore regs and return
  282. ENDPROC(am43xx_do_wfi)
  283. .align
  284. ENTRY(am43xx_resume_offset)
  285. .word . - am43xx_do_wfi
  286. ENTRY(am43xx_resume_from_deep_sleep)
  287. /* Set MPU CLKSTCTRL to HW AUTO so that CPUidle works properly */
  288. ldr r1, am43xx_virt_mpu_clkstctrl
  289. mov r2, #AM43XX_CM_CLKSTCTRL_CLKTRCTRL_HW_AUTO
  290. str r2, [r1]
  291. /* For AM43xx, use EMIF power down until context is restored */
  292. ldr r2, am43xx_phys_emif_poweroff
  293. mov r1, #AM43XX_EMIF_POWEROFF_ENABLE
  294. str r1, [r2, #0x0]
  295. /* Re-enable EMIF */
  296. ldr r1, am43xx_phys_emif_clkctrl
  297. mov r2, #AM33XX_CM_CLKCTRL_MODULEMODE_ENABLE
  298. str r2, [r1]
  299. wait_emif_enable1:
  300. ldr r3, [r1]
  301. cmp r2, r3
  302. bne wait_emif_enable1
  303. adr r9, am43xx_emif_sram_table
  304. ldr r1, [r9, #EMIF_PM_RESTORE_CONTEXT_OFFSET]
  305. blx r1
  306. ldr r1, [r9, #EMIF_PM_EXIT_SR_OFFSET]
  307. blx r1
  308. ldr r2, am43xx_phys_emif_poweroff
  309. mov r1, #AM43XX_EMIF_POWEROFF_DISABLE
  310. str r1, [r2, #0x0]
  311. #ifdef CONFIG_CACHE_L2X0
  312. ldr r2, l2_cache_base
  313. ldr r0, [r2, #L2X0_CTRL]
  314. and r0, #0x0f
  315. cmp r0, #1
  316. beq skip_l2en @ Skip if already enabled
  317. adr r4, am43xx_pm_ro_sram_data
  318. ldr r3, [r4, #AMX3_PM_RO_SRAM_DATA_PHYS_OFFSET]
  319. ldr r0, [r3, #AMX3_PM_L2_PREFETCH_CTRL_VAL_OFFSET]
  320. ldr r12, l2_smc1
  321. dsb
  322. smc #0
  323. dsb
  324. set_aux_ctrl:
  325. ldr r0, [r3, #AMX3_PM_L2_AUX_CTRL_VAL_OFFSET]
  326. ldr r12, l2_smc2
  327. dsb
  328. smc #0
  329. dsb
  330. /* L2 invalidate on resume */
  331. ldr r0, l2_val
  332. ldr r2, l2_cache_base
  333. str r0, [r2, #L2X0_INV_WAY]
  334. wait2:
  335. ldr r0, [r2, #L2X0_INV_WAY]
  336. ldr r1, l2_val
  337. ands r0, r0, r1
  338. bne wait2
  339. #ifdef CONFIG_PL310_ERRATA_727915
  340. mov r0, #0x00
  341. mov r12, #OMAP4_MON_L2X0_DBG_CTRL_INDEX
  342. dsb
  343. smc #0
  344. dsb
  345. #endif
  346. l2x_sync2:
  347. ldr r2, l2_cache_base
  348. mov r0, #0x0
  349. str r0, [r2, #L2X0_CACHE_SYNC]
  350. sync2:
  351. ldr r0, [r2, #L2X0_CACHE_SYNC]
  352. ands r0, r0, #0x1
  353. bne sync2
  354. mov r0, #0x1
  355. ldr r12, l2_smc3
  356. dsb
  357. smc #0
  358. dsb
  359. #endif
  360. skip_l2en:
  361. /* We are back. Branch to the common CPU resume routine */
  362. mov r0, #0
  363. ldr pc, resume_addr
  364. ENDPROC(am43xx_resume_from_deep_sleep)
  365. /*
  366. * Local variables
  367. */
  368. .align
  369. kernel_flush:
  370. .word v7_flush_dcache_all
  371. ddr_start:
  372. .word PAGE_OFFSET
  373. am43xx_phys_emif_poweroff:
  374. .word (AM43XX_CM_BASE + AM43XX_PRM_DEVICE_INST + \
  375. AM43XX_PRM_EMIF_CTRL_OFFSET)
  376. am43xx_virt_mpu_clkstctrl:
  377. .word (AM43XX_CM_MPU_CLKSTCTRL)
  378. am43xx_virt_mpu_clkctrl:
  379. .word (AM43XX_CM_MPU_MPU_CLKCTRL)
  380. am43xx_virt_emif_clkctrl:
  381. .word (AM43XX_CM_PER_EMIF_CLKCTRL)
  382. am43xx_phys_emif_clkctrl:
  383. .word (AM43XX_CM_BASE + AM43XX_CM_PER_INST + \
  384. AM43XX_CM_PER_EMIF_CLKCTRL_OFFSET)
  385. #ifdef CONFIG_CACHE_L2X0
  386. /* L2 cache related defines for AM437x */
  387. get_l2cache_base:
  388. .word omap4_get_l2cache_base
  389. l2_cache_base:
  390. .word OMAP44XX_L2CACHE_BASE
  391. l2_smc1:
  392. .word OMAP4_MON_L2X0_PREFETCH_INDEX
  393. l2_smc2:
  394. .word OMAP4_MON_L2X0_AUXCTRL_INDEX
  395. l2_smc3:
  396. .word OMAP4_MON_L2X0_CTRL_INDEX
  397. l2_val:
  398. .word 0xffff
  399. #endif
  400. .align 3
  401. /* DDR related defines */
  402. ENTRY(am43xx_emif_sram_table)
  403. .space EMIF_PM_FUNCTIONS_SIZE
  404. ENTRY(am43xx_pm_sram)
  405. .word am43xx_do_wfi
  406. .word am43xx_do_wfi_sz
  407. .word am43xx_resume_offset
  408. .word am43xx_emif_sram_table
  409. .word am43xx_pm_ro_sram_data
  410. resume_addr:
  411. .word cpu_resume - PAGE_OFFSET + 0x80000000
  412. .align 3
  413. ENTRY(am43xx_pm_ro_sram_data)
  414. .space AMX3_PM_RO_SRAM_DATA_SIZE
  415. ENTRY(am43xx_do_wfi_sz)
  416. .word . - am43xx_do_wfi