sleep.S 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * linux/arch/arm/mach-pnx4008/sleep.S
  3. *
  4. * PNX4008 support for STOP mode and SDRAM self-refresh
  5. *
  6. * Authors: Dmitry Chigirev, Vitaly Wool <source@mvista.com>
  7. *
  8. * 2005 (c) MontaVista Software, Inc. This file is licensed under
  9. * the terms of the GNU General Public License version 2. This program
  10. * is licensed "as is" without any warranty of any kind, whether express
  11. * or implied.
  12. */
  13. #include <linux/config.h>
  14. #include <linux/linkage.h>
  15. #include <asm/assembler.h>
  16. #include <asm/hardware.h>
  17. #define PWRMAN_VA_BASE IO_ADDRESS(PNX4008_PWRMAN_BASE)
  18. #define PWR_CTRL_REG_OFFS 0x44
  19. #define SDRAM_CFG_VA_BASE IO_ADDRESS(PNX4008_SDRAM_CFG_BASE)
  20. #define MPMC_STATUS_REG_OFFS 0x4
  21. .text
  22. ENTRY(pnx4008_cpu_suspend)
  23. @this function should be entered in Direct run mode.
  24. @ save registers on stack
  25. stmfd sp!, {r0 - r6, lr}
  26. @ setup Power Manager base address in r4
  27. @ and put it's value in r5
  28. mov r4, #(PWRMAN_VA_BASE & 0xff000000)
  29. orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
  30. orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
  31. orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
  32. ldr r5, [r4, #PWR_CTRL_REG_OFFS]
  33. @ setup SDRAM controller base address in r2
  34. @ and put it's value in r3
  35. mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
  36. orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
  37. orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
  38. orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
  39. ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
  40. @ clear SDRAM self-refresh bit latch
  41. and r5, r5, #(~(1 << 8))
  42. @ clear SDRAM self-refresh bit
  43. and r5, r5, #(~(1 << 9))
  44. str r5, [r4, #PWR_CTRL_REG_OFFS]
  45. @ do save current bit settings in r1
  46. mov r1, r5
  47. @ set SDRAM self-refresh bit
  48. orr r5, r5, #(1 << 9)
  49. str r5, [r4, #PWR_CTRL_REG_OFFS]
  50. @ set SDRAM self-refresh bit latch
  51. orr r5, r5, #(1 << 8)
  52. str r5, [r4, #PWR_CTRL_REG_OFFS]
  53. @ clear SDRAM self-refresh bit latch
  54. and r5, r5, #(~(1 << 8))
  55. str r5, [r4, #PWR_CTRL_REG_OFFS]
  56. @ clear SDRAM self-refresh bit
  57. and r5, r5, #(~(1 << 9))
  58. str r5, [r4, #PWR_CTRL_REG_OFFS]
  59. @ wait for SDRAM to get into self-refresh mode
  60. 2: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
  61. tst r3, #(1 << 2)
  62. beq 2b
  63. @ to prepare SDRAM to get out of self-refresh mode after wakeup
  64. orr r5, r5, #(1 << 7)
  65. str r5, [r4, #PWR_CTRL_REG_OFFS]
  66. @ do enter stop mode
  67. orr r5, r5, #(1 << 0)
  68. str r5, [r4, #PWR_CTRL_REG_OFFS]
  69. nop
  70. nop
  71. nop
  72. nop
  73. nop
  74. nop
  75. nop
  76. nop
  77. nop
  78. @ sleeping now...
  79. @ coming out of STOP mode into Direct Run mode
  80. @ clear STOP mode and SDRAM self-refresh bits
  81. str r1, [r4, #PWR_CTRL_REG_OFFS]
  82. @ wait for SDRAM to get out self-refresh mode
  83. 3: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
  84. tst r3, #5
  85. bne 3b
  86. @ restore regs and return
  87. ldmfd sp!, {r0 - r6, pc}
  88. ENTRY(pnx4008_cpu_suspend_sz)
  89. .word . - pnx4008_cpu_suspend
  90. ENTRY(pnx4008_cpu_standby)
  91. @ save registers on stack
  92. stmfd sp!, {r0 - r6, lr}
  93. @ setup Power Manager base address in r4
  94. @ and put it's value in r5
  95. mov r4, #(PWRMAN_VA_BASE & 0xff000000)
  96. orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
  97. orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
  98. orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
  99. ldr r5, [r4, #PWR_CTRL_REG_OFFS]
  100. @ setup SDRAM controller base address in r2
  101. @ and put it's value in r3
  102. mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
  103. orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
  104. orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
  105. orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
  106. ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
  107. @ clear SDRAM self-refresh bit latch
  108. and r5, r5, #(~(1 << 8))
  109. @ clear SDRAM self-refresh bit
  110. and r5, r5, #(~(1 << 9))
  111. str r5, [r4, #PWR_CTRL_REG_OFFS]
  112. @ do save current bit settings in r1
  113. mov r1, r5
  114. @ set SDRAM self-refresh bit
  115. orr r5, r5, #(1 << 9)
  116. str r5, [r4, #PWR_CTRL_REG_OFFS]
  117. @ set SDRAM self-refresh bit latch
  118. orr r5, r5, #(1 << 8)
  119. str r5, [r4, #PWR_CTRL_REG_OFFS]
  120. @ clear SDRAM self-refresh bit latch
  121. and r5, r5, #(~(1 << 8))
  122. str r5, [r4, #PWR_CTRL_REG_OFFS]
  123. @ clear SDRAM self-refresh bit
  124. and r5, r5, #(~(1 << 9))
  125. str r5, [r4, #PWR_CTRL_REG_OFFS]
  126. @ wait for SDRAM to get into self-refresh mode
  127. 2: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
  128. tst r3, #(1 << 2)
  129. beq 2b
  130. @ set 'get out of self-refresh mode after wakeup' bit
  131. orr r5, r5, #(1 << 7)
  132. str r5, [r4, #PWR_CTRL_REG_OFFS]
  133. mcr p15, 0, r0, c7, c0, 4 @ kinda sleeping now...
  134. @ set SDRAM self-refresh bit latch
  135. orr r5, r5, #(1 << 8)
  136. str r5, [r4, #PWR_CTRL_REG_OFFS]
  137. @ clear SDRAM self-refresh bit latch
  138. and r5, r5, #(~(1 << 8))
  139. str r5, [r4, #PWR_CTRL_REG_OFFS]
  140. @ wait for SDRAM to get out self-refresh mode
  141. 3: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
  142. tst r3, #5
  143. bne 3b
  144. @ restore regs and return
  145. ldmfd sp!, {r0 - r6, pc}
  146. ENTRY(pnx4008_cpu_standby_sz)
  147. .word . - pnx4008_cpu_standby
  148. ENTRY(pnx4008_cache_clean_invalidate)
  149. stmfd sp!, {r0 - r6, lr}
  150. #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
  151. mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
  152. #else
  153. 1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate
  154. bne 1b
  155. #endif
  156. ldmfd sp!, {r0 - r6, pc}