sleep43xx.S 11 KB

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