ti-emif-sram-pm.S 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /*
  2. * Low level PM code for TI EMIF
  3. *
  4. * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
  5. * Dave Gerlach
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License as
  9. * published by the Free Software Foundation version 2.
  10. *
  11. * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  12. * kind, whether express or implied; without even the implied warranty
  13. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. */
  16. #include <linux/linkage.h>
  17. #include <asm/asm-offsets.h>
  18. #include <asm/memory.h>
  19. #include <asm/assembler.h>
  20. #include "emif.h"
  21. #define EMIF_POWER_MGMT_WAIT_SELF_REFRESH_8192_CYCLES 0x00a0
  22. #define EMIF_POWER_MGMT_SR_TIMER_MASK 0x00f0
  23. #define EMIF_POWER_MGMT_SELF_REFRESH_MODE 0x0200
  24. #define EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK 0x0700
  25. #define EMIF_SDCFG_TYPE_DDR2 0x2 << SDRAM_TYPE_SHIFT
  26. #define EMIF_STATUS_READY 0x4
  27. #define AM43XX_EMIF_PHY_CTRL_REG_COUNT 0x120
  28. #define EMIF_AM437X_REGISTERS 0x1
  29. .data
  30. .align 3
  31. ENTRY(ti_emif_sram)
  32. /*
  33. * void ti_emif_save_context(void)
  34. *
  35. * Used during suspend to save the context of all required EMIF registers
  36. * to local memory if the EMIF is going to lose context during the sleep
  37. * transition. Operates on the VIRTUAL address of the EMIF.
  38. */
  39. ENTRY(ti_emif_save_context)
  40. stmfd sp!, {r4 - r11, lr} @ save registers on stack
  41. adr r4, ti_emif_pm_sram_data
  42. ldr r0, [r4, #EMIF_PM_BASE_ADDR_VIRT_OFFSET]
  43. ldr r2, [r4, #EMIF_PM_REGS_VIRT_OFFSET]
  44. /* Save EMIF configuration */
  45. ldr r1, [r0, #EMIF_SDRAM_CONFIG]
  46. str r1, [r2, #EMIF_SDCFG_VAL_OFFSET]
  47. ldr r1, [r0, #EMIF_SDRAM_REFRESH_CONTROL]
  48. str r1, [r2, #EMIF_REF_CTRL_VAL_OFFSET]
  49. ldr r1, [r0, #EMIF_SDRAM_TIMING_1]
  50. str r1, [r2, #EMIF_TIMING1_VAL_OFFSET]
  51. ldr r1, [r0, #EMIF_SDRAM_TIMING_2]
  52. str r1, [r2, #EMIF_TIMING2_VAL_OFFSET]
  53. ldr r1, [r0, #EMIF_SDRAM_TIMING_3]
  54. str r1, [r2, #EMIF_TIMING3_VAL_OFFSET]
  55. ldr r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
  56. str r1, [r2, #EMIF_PMCR_VAL_OFFSET]
  57. ldr r1, [r0, #EMIF_POWER_MANAGEMENT_CTRL_SHDW]
  58. str r1, [r2, #EMIF_PMCR_SHDW_VAL_OFFSET]
  59. ldr r1, [r0, #EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG]
  60. str r1, [r2, #EMIF_ZQCFG_VAL_OFFSET]
  61. ldr r1, [r0, #EMIF_DDR_PHY_CTRL_1]
  62. str r1, [r2, #EMIF_DDR_PHY_CTLR_1_OFFSET]
  63. ldr r1, [r0, #EMIF_COS_CONFIG]
  64. str r1, [r2, #EMIF_COS_CONFIG_OFFSET]
  65. ldr r1, [r0, #EMIF_PRIORITY_TO_CLASS_OF_SERVICE_MAPPING]
  66. str r1, [r2, #EMIF_PRIORITY_TO_COS_MAPPING_OFFSET]
  67. ldr r1, [r0, #EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_1_MAPPING]
  68. str r1, [r2, #EMIF_CONNECT_ID_SERV_1_MAP_OFFSET]
  69. ldr r1, [r0, #EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_2_MAPPING]
  70. str r1, [r2, #EMIF_CONNECT_ID_SERV_2_MAP_OFFSET]
  71. ldr r1, [r0, #EMIF_OCP_CONFIG]
  72. str r1, [r2, #EMIF_OCP_CONFIG_VAL_OFFSET]
  73. ldr r5, [r4, #EMIF_PM_CONFIG_OFFSET]
  74. cmp r5, #EMIF_SRAM_AM43_REG_LAYOUT
  75. bne emif_skip_save_extra_regs
  76. ldr r1, [r0, #EMIF_READ_WRITE_LEVELING_RAMP_CONTROL]
  77. str r1, [r2, #EMIF_RD_WR_LEVEL_RAMP_CTRL_OFFSET]
  78. ldr r1, [r0, #EMIF_READ_WRITE_EXECUTION_THRESHOLD]
  79. str r1, [r2, #EMIF_RD_WR_EXEC_THRESH_OFFSET]
  80. ldr r1, [r0, #EMIF_LPDDR2_NVM_TIMING]
  81. str r1, [r2, #EMIF_LPDDR2_NVM_TIM_OFFSET]
  82. ldr r1, [r0, #EMIF_LPDDR2_NVM_TIMING_SHDW]
  83. str r1, [r2, #EMIF_LPDDR2_NVM_TIM_SHDW_OFFSET]
  84. ldr r1, [r0, #EMIF_DLL_CALIB_CTRL]
  85. str r1, [r2, #EMIF_DLL_CALIB_CTRL_VAL_OFFSET]
  86. ldr r1, [r0, #EMIF_DLL_CALIB_CTRL_SHDW]
  87. str r1, [r2, #EMIF_DLL_CALIB_CTRL_VAL_SHDW_OFFSET]
  88. /* Loop and save entire block of emif phy regs */
  89. mov r5, #0x0
  90. add r4, r2, #EMIF_EXT_PHY_CTRL_VALS_OFFSET
  91. add r3, r0, #EMIF_EXT_PHY_CTRL_1
  92. ddr_phy_ctrl_save:
  93. ldr r1, [r3, r5]
  94. str r1, [r4, r5]
  95. add r5, r5, #0x4
  96. cmp r5, #AM43XX_EMIF_PHY_CTRL_REG_COUNT
  97. bne ddr_phy_ctrl_save
  98. emif_skip_save_extra_regs:
  99. ldmfd sp!, {r4 - r11, pc} @ restore regs and return
  100. ENDPROC(ti_emif_save_context)
  101. /*
  102. * void ti_emif_restore_context(void)
  103. *
  104. * Used during resume to restore the context of all required EMIF registers
  105. * from local memory after the EMIF has lost context during a sleep transition.
  106. * Operates on the PHYSICAL address of the EMIF.
  107. */
  108. ENTRY(ti_emif_restore_context)
  109. adr r4, ti_emif_pm_sram_data
  110. ldr r0, [r4, #EMIF_PM_BASE_ADDR_PHYS_OFFSET]
  111. ldr r2, [r4, #EMIF_PM_REGS_PHYS_OFFSET]
  112. /* Config EMIF Timings */
  113. ldr r1, [r2, #EMIF_DDR_PHY_CTLR_1_OFFSET]
  114. str r1, [r0, #EMIF_DDR_PHY_CTRL_1]
  115. str r1, [r0, #EMIF_DDR_PHY_CTRL_1_SHDW]
  116. ldr r1, [r2, #EMIF_TIMING1_VAL_OFFSET]
  117. str r1, [r0, #EMIF_SDRAM_TIMING_1]
  118. str r1, [r0, #EMIF_SDRAM_TIMING_1_SHDW]
  119. ldr r1, [r2, #EMIF_TIMING2_VAL_OFFSET]
  120. str r1, [r0, #EMIF_SDRAM_TIMING_2]
  121. str r1, [r0, #EMIF_SDRAM_TIMING_2_SHDW]
  122. ldr r1, [r2, #EMIF_TIMING3_VAL_OFFSET]
  123. str r1, [r0, #EMIF_SDRAM_TIMING_3]
  124. str r1, [r0, #EMIF_SDRAM_TIMING_3_SHDW]
  125. ldr r1, [r2, #EMIF_REF_CTRL_VAL_OFFSET]
  126. str r1, [r0, #EMIF_SDRAM_REFRESH_CONTROL]
  127. str r1, [r0, #EMIF_SDRAM_REFRESH_CTRL_SHDW]
  128. ldr r1, [r2, #EMIF_PMCR_VAL_OFFSET]
  129. str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
  130. ldr r1, [r2, #EMIF_PMCR_SHDW_VAL_OFFSET]
  131. str r1, [r0, #EMIF_POWER_MANAGEMENT_CTRL_SHDW]
  132. ldr r1, [r2, #EMIF_COS_CONFIG_OFFSET]
  133. str r1, [r0, #EMIF_COS_CONFIG]
  134. ldr r1, [r2, #EMIF_PRIORITY_TO_COS_MAPPING_OFFSET]
  135. str r1, [r0, #EMIF_PRIORITY_TO_CLASS_OF_SERVICE_MAPPING]
  136. ldr r1, [r2, #EMIF_CONNECT_ID_SERV_1_MAP_OFFSET]
  137. str r1, [r0, #EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_1_MAPPING]
  138. ldr r1, [r2, #EMIF_CONNECT_ID_SERV_2_MAP_OFFSET]
  139. str r1, [r0, #EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_2_MAPPING]
  140. ldr r1, [r2, #EMIF_OCP_CONFIG_VAL_OFFSET]
  141. str r1, [r0, #EMIF_OCP_CONFIG]
  142. ldr r5, [r4, #EMIF_PM_CONFIG_OFFSET]
  143. cmp r5, #EMIF_SRAM_AM43_REG_LAYOUT
  144. bne emif_skip_restore_extra_regs
  145. ldr r1, [r2, #EMIF_RD_WR_LEVEL_RAMP_CTRL_OFFSET]
  146. str r1, [r0, #EMIF_READ_WRITE_LEVELING_RAMP_CONTROL]
  147. ldr r1, [r2, #EMIF_RD_WR_EXEC_THRESH_OFFSET]
  148. str r1, [r0, #EMIF_READ_WRITE_EXECUTION_THRESHOLD]
  149. ldr r1, [r2, #EMIF_LPDDR2_NVM_TIM_OFFSET]
  150. str r1, [r0, #EMIF_LPDDR2_NVM_TIMING]
  151. ldr r1, [r2, #EMIF_LPDDR2_NVM_TIM_SHDW_OFFSET]
  152. str r1, [r0, #EMIF_LPDDR2_NVM_TIMING_SHDW]
  153. ldr r1, [r2, #EMIF_DLL_CALIB_CTRL_VAL_OFFSET]
  154. str r1, [r0, #EMIF_DLL_CALIB_CTRL]
  155. ldr r1, [r2, #EMIF_DLL_CALIB_CTRL_VAL_SHDW_OFFSET]
  156. str r1, [r0, #EMIF_DLL_CALIB_CTRL_SHDW]
  157. ldr r1, [r2, #EMIF_ZQCFG_VAL_OFFSET]
  158. str r1, [r0, #EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG]
  159. /* Loop and restore entire block of emif phy regs */
  160. mov r5, #0x0
  161. /* Load ti_emif_regs_amx3 + EMIF_EXT_PHY_CTRL_VALS_OFFSET for address
  162. * to phy register save space
  163. */
  164. add r3, r2, #EMIF_EXT_PHY_CTRL_VALS_OFFSET
  165. add r4, r0, #EMIF_EXT_PHY_CTRL_1
  166. ddr_phy_ctrl_restore:
  167. ldr r1, [r3, r5]
  168. str r1, [r4, r5]
  169. add r5, r5, #0x4
  170. cmp r5, #AM43XX_EMIF_PHY_CTRL_REG_COUNT
  171. bne ddr_phy_ctrl_restore
  172. emif_skip_restore_extra_regs:
  173. /*
  174. * Output impedence calib needed only for DDR3
  175. * but since the initial state of this will be
  176. * disabled for DDR2 no harm in restoring the
  177. * old configuration
  178. */
  179. ldr r1, [r2, #EMIF_ZQCFG_VAL_OFFSET]
  180. str r1, [r0, #EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG]
  181. /* Write to sdcfg last for DDR2 only */
  182. ldr r1, [r2, #EMIF_SDCFG_VAL_OFFSET]
  183. and r2, r1, #SDRAM_TYPE_MASK
  184. cmp r2, #EMIF_SDCFG_TYPE_DDR2
  185. streq r1, [r0, #EMIF_SDRAM_CONFIG]
  186. mov pc, lr
  187. ENDPROC(ti_emif_restore_context)
  188. /*
  189. * void ti_emif_enter_sr(void)
  190. *
  191. * Programs the EMIF to tell the SDRAM to enter into self-refresh
  192. * mode during a sleep transition. Operates on the VIRTUAL address
  193. * of the EMIF.
  194. */
  195. ENTRY(ti_emif_enter_sr)
  196. stmfd sp!, {r4 - r11, lr} @ save registers on stack
  197. adr r4, ti_emif_pm_sram_data
  198. ldr r0, [r4, #EMIF_PM_BASE_ADDR_VIRT_OFFSET]
  199. ldr r2, [r4, #EMIF_PM_REGS_VIRT_OFFSET]
  200. ldr r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
  201. bic r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK
  202. orr r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE
  203. str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
  204. ldmfd sp!, {r4 - r11, pc} @ restore regs and return
  205. ENDPROC(ti_emif_enter_sr)
  206. /*
  207. * void ti_emif_exit_sr(void)
  208. *
  209. * Programs the EMIF to tell the SDRAM to exit self-refresh mode
  210. * after a sleep transition. Operates on the PHYSICAL address of
  211. * the EMIF.
  212. */
  213. ENTRY(ti_emif_exit_sr)
  214. adr r4, ti_emif_pm_sram_data
  215. ldr r0, [r4, #EMIF_PM_BASE_ADDR_PHYS_OFFSET]
  216. ldr r2, [r4, #EMIF_PM_REGS_PHYS_OFFSET]
  217. /*
  218. * Toggle EMIF to exit refresh mode:
  219. * if EMIF lost context, PWR_MGT_CTRL is currently 0, writing disable
  220. * (0x0), wont do diddly squat! so do a toggle from SR(0x2) to disable
  221. * (0x0) here.
  222. * *If* EMIF did not lose context, nothing broken as we write the same
  223. * value(0x2) to reg before we write a disable (0x0).
  224. */
  225. ldr r1, [r2, #EMIF_PMCR_VAL_OFFSET]
  226. bic r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK
  227. orr r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE
  228. str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
  229. bic r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK
  230. str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
  231. /* Wait for EMIF to become ready */
  232. 1: ldr r1, [r0, #EMIF_STATUS]
  233. tst r1, #EMIF_STATUS_READY
  234. beq 1b
  235. mov pc, lr
  236. ENDPROC(ti_emif_exit_sr)
  237. /*
  238. * void ti_emif_abort_sr(void)
  239. *
  240. * Disables self-refresh after a failed transition to a low-power
  241. * state so the kernel can jump back to DDR and follow abort path.
  242. * Operates on the VIRTUAL address of the EMIF.
  243. */
  244. ENTRY(ti_emif_abort_sr)
  245. stmfd sp!, {r4 - r11, lr} @ save registers on stack
  246. adr r4, ti_emif_pm_sram_data
  247. ldr r0, [r4, #EMIF_PM_BASE_ADDR_VIRT_OFFSET]
  248. ldr r2, [r4, #EMIF_PM_REGS_VIRT_OFFSET]
  249. ldr r1, [r2, #EMIF_PMCR_VAL_OFFSET]
  250. bic r1, r1, #EMIF_POWER_MGMT_SELF_REFRESH_MODE_MASK
  251. str r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
  252. /* Wait for EMIF to become ready */
  253. 1: ldr r1, [r0, #EMIF_STATUS]
  254. tst r1, #EMIF_STATUS_READY
  255. beq 1b
  256. ldmfd sp!, {r4 - r11, pc} @ restore regs and return
  257. ENDPROC(ti_emif_abort_sr)
  258. .align 3
  259. ENTRY(ti_emif_pm_sram_data)
  260. .space EMIF_PM_DATA_SIZE
  261. ENTRY(ti_emif_sram_sz)
  262. .word . - ti_emif_save_context