s2-mips.S 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /*
  2. * Copyright (C) 2016 Broadcom Corporation
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 as
  6. * published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <asm/asm.h>
  14. #include <asm/regdef.h>
  15. #include <asm/mipsregs.h>
  16. #include <asm/stackframe.h>
  17. #include "pm.h"
  18. .text
  19. .set noreorder
  20. .align 5
  21. /*
  22. * a0: u32 params array
  23. */
  24. LEAF(brcm_pm_do_s2)
  25. subu sp, 64
  26. sw ra, 0(sp)
  27. sw s0, 4(sp)
  28. sw s1, 8(sp)
  29. sw s2, 12(sp)
  30. sw s3, 16(sp)
  31. sw s4, 20(sp)
  32. sw s5, 24(sp)
  33. sw s6, 28(sp)
  34. sw s7, 32(sp)
  35. /*
  36. * Dereference the params array
  37. * s0: AON_CTRL base register
  38. * s1: DDR_PHY base register
  39. * s2: TIMERS base register
  40. * s3: I-Cache line size
  41. * s4: Restart vector address
  42. * s5: Restart vector size
  43. */
  44. move t0, a0
  45. lw s0, 0(t0)
  46. lw s1, 4(t0)
  47. lw s2, 8(t0)
  48. lw s3, 12(t0)
  49. lw s4, 16(t0)
  50. lw s5, 20(t0)
  51. /* Lock this asm section into the I-cache */
  52. addiu t1, s3, -1
  53. not t1
  54. la t0, brcm_pm_do_s2
  55. and t0, t1
  56. la t2, asm_end
  57. and t2, t1
  58. 1: cache 0x1c, 0(t0)
  59. bne t0, t2, 1b
  60. addu t0, s3
  61. /* Lock the interrupt vector into the I-cache */
  62. move t0, zero
  63. 2: move t1, s4
  64. cache 0x1c, 0(t1)
  65. addu t1, s3
  66. addu t0, s3
  67. ble t0, s5, 2b
  68. nop
  69. sync
  70. /* Power down request */
  71. li t0, PM_S2_COMMAND
  72. sw zero, AON_CTRL_PM_CTRL(s0)
  73. lw zero, AON_CTRL_PM_CTRL(s0)
  74. sw t0, AON_CTRL_PM_CTRL(s0)
  75. lw t0, AON_CTRL_PM_CTRL(s0)
  76. /* Enable CP0 interrupt 2 and wait for interrupt */
  77. mfc0 t0, CP0_STATUS
  78. /* Save cp0 sr for restoring later */
  79. move s6, t0
  80. li t1, ~(ST0_IM | ST0_IE)
  81. and t0, t1
  82. ori t0, STATUSF_IP2
  83. mtc0 t0, CP0_STATUS
  84. nop
  85. nop
  86. nop
  87. ori t0, ST0_IE
  88. mtc0 t0, CP0_STATUS
  89. /* Wait for interrupt */
  90. wait
  91. nop
  92. /* Wait for memc0 */
  93. 1: lw t0, DDR40_PHY_CONTROL_REGS_0_PLL_STATUS(s1)
  94. andi t0, 1
  95. beqz t0, 1b
  96. nop
  97. /* 1ms delay needed for stable recovery */
  98. /* Use TIMER1 to count 1 ms */
  99. li t0, RESET_TIMER
  100. sw t0, TIMER_TIMER1_CTRL(s2)
  101. lw t0, TIMER_TIMER1_CTRL(s2)
  102. li t0, START_TIMER
  103. sw t0, TIMER_TIMER1_CTRL(s2)
  104. lw t0, TIMER_TIMER1_CTRL(s2)
  105. /* Prepare delay */
  106. li t0, TIMER_MASK
  107. lw t1, TIMER_TIMER1_STAT(s2)
  108. and t1, t0
  109. /* 1ms delay */
  110. addi t1, 27000
  111. /* Wait for the timer value to exceed t1 */
  112. 1: lw t0, TIMER_TIMER1_STAT(s2)
  113. sgtu t2, t1, t0
  114. bnez t2, 1b
  115. nop
  116. /* Power back up */
  117. li t1, 1
  118. sw t1, AON_CTRL_HOST_MISC_CMDS(s0)
  119. lw t1, AON_CTRL_HOST_MISC_CMDS(s0)
  120. sw zero, AON_CTRL_PM_CTRL(s0)
  121. lw zero, AON_CTRL_PM_CTRL(s0)
  122. /* Unlock I-cache */
  123. addiu t1, s3, -1
  124. not t1
  125. la t0, brcm_pm_do_s2
  126. and t0, t1
  127. la t2, asm_end
  128. and t2, t1
  129. 1: cache 0x00, 0(t0)
  130. bne t0, t2, 1b
  131. addu t0, s3
  132. /* Unlock interrupt vector */
  133. move t0, zero
  134. 2: move t1, s4
  135. cache 0x00, 0(t1)
  136. addu t1, s3
  137. addu t0, s3
  138. ble t0, s5, 2b
  139. nop
  140. /* Restore cp0 sr */
  141. sync
  142. nop
  143. mtc0 s6, CP0_STATUS
  144. nop
  145. /* Set return value to success */
  146. li v0, 0
  147. /* Return to caller */
  148. lw s7, 32(sp)
  149. lw s6, 28(sp)
  150. lw s5, 24(sp)
  151. lw s4, 20(sp)
  152. lw s3, 16(sp)
  153. lw s2, 12(sp)
  154. lw s1, 8(sp)
  155. lw s0, 4(sp)
  156. lw ra, 0(sp)
  157. addiu sp, 64
  158. jr ra
  159. nop
  160. END(brcm_pm_do_s2)
  161. .globl asm_end
  162. asm_end:
  163. nop