sleep.S 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. /*
  2. * linux/arch/unicore32/kernel/sleep.S
  3. *
  4. * Code specific to PKUnity SoC and UniCore ISA
  5. *
  6. * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
  7. * Copyright (C) 2001-2010 Guan Xuetao
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 as
  11. * published by the Free Software Foundation.
  12. */
  13. #include <linux/linkage.h>
  14. #include <asm/assembler.h>
  15. #include <mach/hardware.h>
  16. .text
  17. pkunity_cpu_save_cp:
  18. @ get coprocessor registers
  19. movc r3, p0.c7, #0 @ PID
  20. movc r4, p0.c2, #0 @ translation table base addr
  21. movc r5, p0.c1, #0 @ control reg
  22. @ store them plus current virtual stack ptr on stack
  23. mov r6, sp
  24. stm.w (r3 - r6), [sp-]
  25. mov pc, lr
  26. pkunity_cpu_save_sp:
  27. @ preserve phys address of stack
  28. mov r0, sp
  29. stw.w lr, [sp+], #-4
  30. b.l sleep_phys_sp
  31. ldw r1, =sleep_save_sp
  32. stw r0, [r1]
  33. ldw.w pc, [sp]+, #4
  34. /*
  35. * puv3_cpu_suspend()
  36. *
  37. * Forces CPU into sleep state.
  38. *
  39. * r0 = value for PWRMODE M field for desired sleep state
  40. */
  41. ENTRY(puv3_cpu_suspend)
  42. stm.w (r16 - r27, lr), [sp-] @ save registers on stack
  43. stm.w (r4 - r15), [sp-] @ save registers on stack
  44. #ifdef CONFIG_UNICORE_FPU_F64
  45. sfm.w (f0 - f7 ), [sp-]
  46. sfm.w (f8 - f15), [sp-]
  47. sfm.w (f16 - f23), [sp-]
  48. sfm.w (f24 - f31), [sp-]
  49. cff r4, s31
  50. stm.w (r4), [sp-]
  51. #endif
  52. b.l pkunity_cpu_save_cp
  53. b.l pkunity_cpu_save_sp
  54. @ clean data cache
  55. mov r1, #0
  56. movc p0.c5, r1, #14
  57. nop
  58. nop
  59. nop
  60. nop
  61. @ DDR2 BaseAddr
  62. ldw r0, =(PKUNITY_DDR2CTRL_BASE)
  63. @ PM BaseAddr
  64. ldw r1, =(PKUNITY_PM_BASE)
  65. @ set PLL_SYS_CFG reg, 275
  66. movl r6, #0x00002401
  67. stw r6, [r1+], #0x18
  68. @ set PLL_DDR_CFG reg, 66MHz
  69. movl r6, #0x00100c00
  70. stw r6, [r1+], #0x1c
  71. @ set wake up source
  72. movl r8, #0x800001ff @ epip4d
  73. stw r8, [r1+], #0xc
  74. @ set PGSR
  75. movl r5, #0x40000
  76. stw r5, [r1+], #0x10
  77. @ prepare DDR2 refresh settings
  78. ldw r5, [r0+], #0x24
  79. or r5, r5, #0x00000001
  80. @ prepare PMCR for PLL changing
  81. movl r6, #0xc
  82. @ prepare for closing PLL
  83. movl r7, #0x1
  84. @ prepare sleep mode
  85. mov r8, #0x1
  86. @ movl r0, 0x11111111
  87. @ put_word_ocd r0
  88. b pkunity_cpu_do_suspend
  89. .ltorg
  90. .align 5
  91. pkunity_cpu_do_suspend:
  92. b 101f
  93. @ put DDR2 into self-refresh
  94. 100: stw r5, [r0+], #0x24
  95. @ change PLL
  96. stw r6, [r1]
  97. b 1f
  98. .ltorg
  99. .align 5
  100. 101: b 102f
  101. @ wait for PLL changing complete
  102. 1: ldw r6, [r1+], #0x44
  103. csub.a r6, #0x1
  104. bne 1b
  105. b 2f
  106. .ltorg
  107. .align 5
  108. 102: b 100b
  109. @ close PLL
  110. 2: stw r7, [r1+], #0x4
  111. @ enter sleep mode
  112. stw r8, [r1]
  113. 3: b 3b
  114. /*
  115. * puv3_cpu_resume()
  116. *
  117. * entry point from bootloader into kernel during resume
  118. *
  119. * Note: Yes, part of the following code is located into the .data section.
  120. * This is to allow sleep_save_sp to be accessed with a relative load
  121. * while we can't rely on any MMU translation. We could have put
  122. * sleep_save_sp in the .text section as well, but some setups might
  123. * insist on it to be truly read-only.
  124. */
  125. .data
  126. .align 5
  127. ENTRY(puv3_cpu_resume)
  128. @ movl r0, 0x20202020
  129. @ put_word_ocd r0
  130. ldw r0, sleep_save_sp @ stack phys addr
  131. ldw r2, =resume_after_mmu @ its absolute virtual address
  132. ldm (r3 - r6), [r0]+ @ CP regs + virt stack ptr
  133. mov sp, r6 @ CP regs + virt stack ptr
  134. mov r1, #0
  135. movc p0.c6, r1, #6 @ invalidate I & D TLBs
  136. movc p0.c5, r1, #28 @ invalidate I & D caches, BTB
  137. movc p0.c7, r3, #0 @ PID
  138. movc p0.c2, r4, #0 @ translation table base addr
  139. movc p0.c1, r5, #0 @ control reg, turn on mmu
  140. nop
  141. jump r2
  142. nop
  143. nop
  144. nop
  145. nop
  146. nop
  147. sleep_save_sp:
  148. .word 0 @ preserve stack phys ptr here
  149. .text
  150. resume_after_mmu:
  151. @ movl r0, 0x30303030
  152. @ put_word_ocd r0
  153. #ifdef CONFIG_UNICORE_FPU_F64
  154. lfm.w (f0 - f7 ), [sp]+
  155. lfm.w (f8 - f15), [sp]+
  156. lfm.w (f16 - f23), [sp]+
  157. lfm.w (f24 - f31), [sp]+
  158. ldm.w (r4), [sp]+
  159. ctf r4, s31
  160. #endif
  161. ldm.w (r4 - r15), [sp]+ @ restore registers from stack
  162. ldm.w (r16 - r27, pc), [sp]+ @ return to caller