pm.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /*
  2. * Copyright (C) 2014 Imagination Technologies Ltd
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the
  6. * Free Software Foundation; either version 2 of the License, or (at your
  7. * option) any later version.
  8. *
  9. * PM helper macros for CPU power off (e.g. Suspend-to-RAM).
  10. */
  11. #ifndef __ASM_PM_H
  12. #define __ASM_PM_H
  13. #ifdef __ASSEMBLY__
  14. #include <asm/asm-offsets.h>
  15. #include <asm/asm.h>
  16. #include <asm/mipsregs.h>
  17. #include <asm/regdef.h>
  18. /* Save CPU state to stack for suspend to RAM */
  19. .macro SUSPEND_SAVE_REGS
  20. subu sp, PT_SIZE
  21. /* Call preserved GPRs */
  22. LONG_S $16, PT_R16(sp)
  23. LONG_S $17, PT_R17(sp)
  24. LONG_S $18, PT_R18(sp)
  25. LONG_S $19, PT_R19(sp)
  26. LONG_S $20, PT_R20(sp)
  27. LONG_S $21, PT_R21(sp)
  28. LONG_S $22, PT_R22(sp)
  29. LONG_S $23, PT_R23(sp)
  30. LONG_S $28, PT_R28(sp)
  31. LONG_S $30, PT_R30(sp)
  32. LONG_S $31, PT_R31(sp)
  33. /* A couple of CP0 registers with space in pt_regs */
  34. mfc0 k0, CP0_STATUS
  35. LONG_S k0, PT_STATUS(sp)
  36. .endm
  37. /* Restore CPU state from stack after resume from RAM */
  38. .macro RESUME_RESTORE_REGS_RETURN
  39. .set push
  40. .set noreorder
  41. /* A couple of CP0 registers with space in pt_regs */
  42. LONG_L k0, PT_STATUS(sp)
  43. mtc0 k0, CP0_STATUS
  44. /* Call preserved GPRs */
  45. LONG_L $16, PT_R16(sp)
  46. LONG_L $17, PT_R17(sp)
  47. LONG_L $18, PT_R18(sp)
  48. LONG_L $19, PT_R19(sp)
  49. LONG_L $20, PT_R20(sp)
  50. LONG_L $21, PT_R21(sp)
  51. LONG_L $22, PT_R22(sp)
  52. LONG_L $23, PT_R23(sp)
  53. LONG_L $28, PT_R28(sp)
  54. LONG_L $30, PT_R30(sp)
  55. LONG_L $31, PT_R31(sp)
  56. /* Pop and return */
  57. jr ra
  58. addiu sp, PT_SIZE
  59. .set pop
  60. .endm
  61. /* Get address of static suspend state into t1 */
  62. .macro LA_STATIC_SUSPEND
  63. la t1, mips_static_suspend_state
  64. .endm
  65. /* Save important CPU state for early restoration to global data */
  66. .macro SUSPEND_SAVE_STATIC
  67. #ifdef CONFIG_EVA
  68. /*
  69. * Segment configuration is saved in global data where it can be easily
  70. * reloaded without depending on the segment configuration.
  71. */
  72. mfc0 k0, CP0_PAGEMASK, 2 /* SegCtl0 */
  73. LONG_S k0, SSS_SEGCTL0(t1)
  74. mfc0 k0, CP0_PAGEMASK, 3 /* SegCtl1 */
  75. LONG_S k0, SSS_SEGCTL1(t1)
  76. mfc0 k0, CP0_PAGEMASK, 4 /* SegCtl2 */
  77. LONG_S k0, SSS_SEGCTL2(t1)
  78. #endif
  79. /* save stack pointer (pointing to GPRs) */
  80. LONG_S sp, SSS_SP(t1)
  81. .endm
  82. /* Restore important CPU state early from global data */
  83. .macro RESUME_RESTORE_STATIC
  84. #ifdef CONFIG_EVA
  85. /*
  86. * Segment configuration must be restored prior to any access to
  87. * allocated memory, as it may reside outside of the legacy kernel
  88. * segments.
  89. */
  90. LONG_L k0, SSS_SEGCTL0(t1)
  91. mtc0 k0, CP0_PAGEMASK, 2 /* SegCtl0 */
  92. LONG_L k0, SSS_SEGCTL1(t1)
  93. mtc0 k0, CP0_PAGEMASK, 3 /* SegCtl1 */
  94. LONG_L k0, SSS_SEGCTL2(t1)
  95. mtc0 k0, CP0_PAGEMASK, 4 /* SegCtl2 */
  96. tlbw_use_hazard
  97. #endif
  98. /* restore stack pointer (pointing to GPRs) */
  99. LONG_L sp, SSS_SP(t1)
  100. .endm
  101. /* flush caches to make sure context has reached memory */
  102. .macro SUSPEND_CACHE_FLUSH
  103. .extern __wback_cache_all
  104. .set push
  105. .set noreorder
  106. la t1, __wback_cache_all
  107. LONG_L t0, 0(t1)
  108. jalr t0
  109. nop
  110. .set pop
  111. .endm
  112. /* Save suspend state and flush data caches to RAM */
  113. .macro SUSPEND_SAVE
  114. SUSPEND_SAVE_REGS
  115. LA_STATIC_SUSPEND
  116. SUSPEND_SAVE_STATIC
  117. SUSPEND_CACHE_FLUSH
  118. .endm
  119. /* Restore saved state after resume from RAM and return */
  120. .macro RESUME_RESTORE_RETURN
  121. LA_STATIC_SUSPEND
  122. RESUME_RESTORE_STATIC
  123. RESUME_RESTORE_REGS_RETURN
  124. .endm
  125. #else /* __ASSEMBLY__ */
  126. /**
  127. * struct mips_static_suspend_state - Core saved CPU state across S2R.
  128. * @segctl: CP0 Segment control registers.
  129. * @sp: Stack frame where GP register context is saved.
  130. *
  131. * This structure contains minimal CPU state that must be saved in static kernel
  132. * data in order to be able to restore the rest of the state. This includes
  133. * segmentation configuration in the case of EVA being enabled, as they must be
  134. * restored prior to any kmalloc'd memory being referenced (even the stack
  135. * pointer).
  136. */
  137. struct mips_static_suspend_state {
  138. #ifdef CONFIG_EVA
  139. unsigned long segctl[3];
  140. #endif
  141. unsigned long sp;
  142. };
  143. #endif /* !__ASSEMBLY__ */
  144. #endif /* __ASM_PM_HELPERS_H */