s3-mips.S 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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/bmips.h>
  17. #include "pm.h"
  18. .text
  19. .set noreorder
  20. .align 5
  21. .global s3_reentry
  22. /*
  23. * a0: AON_CTRL base register
  24. * a1: D-Cache line size
  25. */
  26. LEAF(brcm_pm_do_s3)
  27. /* Get the address of s3_context */
  28. la t0, gp_regs
  29. sw ra, 0(t0)
  30. sw s0, 4(t0)
  31. sw s1, 8(t0)
  32. sw s2, 12(t0)
  33. sw s3, 16(t0)
  34. sw s4, 20(t0)
  35. sw s5, 24(t0)
  36. sw s6, 28(t0)
  37. sw s7, 32(t0)
  38. sw gp, 36(t0)
  39. sw sp, 40(t0)
  40. sw fp, 44(t0)
  41. /* Save CP0 Status */
  42. mfc0 t1, CP0_STATUS
  43. sw t1, 48(t0)
  44. /* Write-back gp registers - cache will be gone */
  45. addiu t1, a1, -1
  46. not t1
  47. and t0, t1
  48. /* Flush at least 64 bytes */
  49. addiu t2, t0, 64
  50. and t2, t1
  51. 1: cache 0x17, 0(t0)
  52. bne t0, t2, 1b
  53. addu t0, a1
  54. /* Drop to deep standby */
  55. li t1, PM_WARM_CONFIG
  56. sw zero, AON_CTRL_PM_CTRL(a0)
  57. lw zero, AON_CTRL_PM_CTRL(a0)
  58. sw t1, AON_CTRL_PM_CTRL(a0)
  59. lw t1, AON_CTRL_PM_CTRL(a0)
  60. li t1, (PM_WARM_CONFIG | PM_PWR_DOWN)
  61. sw t1, AON_CTRL_PM_CTRL(a0)
  62. lw t1, AON_CTRL_PM_CTRL(a0)
  63. /* Enable CP0 interrupt 2 and wait for interrupt */
  64. mfc0 t0, CP0_STATUS
  65. li t1, ~(ST0_IM | ST0_IE)
  66. and t0, t1
  67. ori t0, STATUSF_IP2
  68. mtc0 t0, CP0_STATUS
  69. nop
  70. nop
  71. nop
  72. ori t0, ST0_IE
  73. mtc0 t0, CP0_STATUS
  74. /* Wait for interrupt */
  75. wait
  76. nop
  77. s3_reentry:
  78. /* Clear call/return stack */
  79. li t0, (0x06 << 16)
  80. mtc0 t0, $22, 2
  81. ssnop
  82. ssnop
  83. ssnop
  84. /* Clear jump target buffer */
  85. li t0, (0x04 << 16)
  86. mtc0 t0, $22, 2
  87. ssnop
  88. ssnop
  89. ssnop
  90. sync
  91. nop
  92. /* Setup mmu defaults */
  93. mtc0 zero, CP0_WIRED
  94. mtc0 zero, CP0_ENTRYHI
  95. li k0, PM_DEFAULT_MASK
  96. mtc0 k0, CP0_PAGEMASK
  97. li sp, BMIPS_WARM_RESTART_VEC
  98. la k0, plat_wired_tlb_setup
  99. jalr k0
  100. nop
  101. /* Restore general purpose registers */
  102. la t0, gp_regs
  103. lw fp, 44(t0)
  104. lw sp, 40(t0)
  105. lw gp, 36(t0)
  106. lw s7, 32(t0)
  107. lw s6, 28(t0)
  108. lw s5, 24(t0)
  109. lw s4, 20(t0)
  110. lw s3, 16(t0)
  111. lw s2, 12(t0)
  112. lw s1, 8(t0)
  113. lw s0, 4(t0)
  114. lw ra, 0(t0)
  115. /* Restore CP0 status */
  116. lw t1, 48(t0)
  117. mtc0 t1, CP0_STATUS
  118. /* Return to caller */
  119. li v0, 0
  120. jr ra
  121. nop
  122. END(brcm_pm_do_s3)