pm.h 3.8 KB

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