Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Copyright (C) 2014 Imagination Technologies Ltd
0004  *
0005  * PM helper macros for CPU power off (e.g. Suspend-to-RAM).
0006  */
0007 
0008 #ifndef __ASM_PM_H
0009 #define __ASM_PM_H
0010 
0011 #ifdef __ASSEMBLY__
0012 
0013 #include <asm/asm-offsets.h>
0014 #include <asm/asm.h>
0015 #include <asm/mipsregs.h>
0016 #include <asm/regdef.h>
0017 
0018 /* Save CPU state to stack for suspend to RAM */
0019 .macro SUSPEND_SAVE_REGS
0020     subu    sp, PT_SIZE
0021     /* Call preserved GPRs */
0022     LONG_S  $16, PT_R16(sp)
0023     LONG_S  $17, PT_R17(sp)
0024     LONG_S  $18, PT_R18(sp)
0025     LONG_S  $19, PT_R19(sp)
0026     LONG_S  $20, PT_R20(sp)
0027     LONG_S  $21, PT_R21(sp)
0028     LONG_S  $22, PT_R22(sp)
0029     LONG_S  $23, PT_R23(sp)
0030     LONG_S  $28, PT_R28(sp)
0031     LONG_S  $30, PT_R30(sp)
0032     LONG_S  $31, PT_R31(sp)
0033     /* A couple of CP0 registers with space in pt_regs */
0034     mfc0    k0, CP0_STATUS
0035     LONG_S  k0, PT_STATUS(sp)
0036 .endm
0037 
0038 /* Restore CPU state from stack after resume from RAM */
0039 .macro RESUME_RESTORE_REGS_RETURN
0040     .set    push
0041     .set    noreorder
0042     /* A couple of CP0 registers with space in pt_regs */
0043     LONG_L  k0, PT_STATUS(sp)
0044     mtc0    k0, CP0_STATUS
0045     /* Call preserved GPRs */
0046     LONG_L  $16, PT_R16(sp)
0047     LONG_L  $17, PT_R17(sp)
0048     LONG_L  $18, PT_R18(sp)
0049     LONG_L  $19, PT_R19(sp)
0050     LONG_L  $20, PT_R20(sp)
0051     LONG_L  $21, PT_R21(sp)
0052     LONG_L  $22, PT_R22(sp)
0053     LONG_L  $23, PT_R23(sp)
0054     LONG_L  $28, PT_R28(sp)
0055     LONG_L  $30, PT_R30(sp)
0056     LONG_L  $31, PT_R31(sp)
0057     /* Pop and return */
0058     jr  ra
0059      addiu  sp, PT_SIZE
0060     .set    pop
0061 .endm
0062 
0063 /* Get address of static suspend state into t1 */
0064 .macro LA_STATIC_SUSPEND
0065     la  t1, mips_static_suspend_state
0066 .endm
0067 
0068 /* Save important CPU state for early restoration to global data */
0069 .macro SUSPEND_SAVE_STATIC
0070 #ifdef CONFIG_EVA
0071     /*
0072      * Segment configuration is saved in global data where it can be easily
0073      * reloaded without depending on the segment configuration.
0074      */
0075     mfc0    k0, CP0_PAGEMASK, 2 /* SegCtl0 */
0076     LONG_S  k0, SSS_SEGCTL0(t1)
0077     mfc0    k0, CP0_PAGEMASK, 3 /* SegCtl1 */
0078     LONG_S  k0, SSS_SEGCTL1(t1)
0079     mfc0    k0, CP0_PAGEMASK, 4 /* SegCtl2 */
0080     LONG_S  k0, SSS_SEGCTL2(t1)
0081 #endif
0082     /* save stack pointer (pointing to GPRs) */
0083     LONG_S  sp, SSS_SP(t1)
0084 .endm
0085 
0086 /* Restore important CPU state early from global data */
0087 .macro RESUME_RESTORE_STATIC
0088 #ifdef CONFIG_EVA
0089     /*
0090      * Segment configuration must be restored prior to any access to
0091      * allocated memory, as it may reside outside of the legacy kernel
0092      * segments.
0093      */
0094     LONG_L  k0, SSS_SEGCTL0(t1)
0095     mtc0    k0, CP0_PAGEMASK, 2 /* SegCtl0 */
0096     LONG_L  k0, SSS_SEGCTL1(t1)
0097     mtc0    k0, CP0_PAGEMASK, 3 /* SegCtl1 */
0098     LONG_L  k0, SSS_SEGCTL2(t1)
0099     mtc0    k0, CP0_PAGEMASK, 4 /* SegCtl2 */
0100     tlbw_use_hazard
0101 #endif
0102     /* restore stack pointer (pointing to GPRs) */
0103     LONG_L  sp, SSS_SP(t1)
0104 .endm
0105 
0106 /* flush caches to make sure context has reached memory */
0107 .macro SUSPEND_CACHE_FLUSH
0108     .extern __wback_cache_all
0109     .set    push
0110     .set    noreorder
0111     la  t1, __wback_cache_all
0112     LONG_L  t0, 0(t1)
0113     jalr    t0
0114      nop
0115     .set    pop
0116  .endm
0117 
0118 /* Save suspend state and flush data caches to RAM */
0119 .macro SUSPEND_SAVE
0120     SUSPEND_SAVE_REGS
0121     LA_STATIC_SUSPEND
0122     SUSPEND_SAVE_STATIC
0123     SUSPEND_CACHE_FLUSH
0124 .endm
0125 
0126 /* Restore saved state after resume from RAM and return */
0127 .macro RESUME_RESTORE_RETURN
0128     LA_STATIC_SUSPEND
0129     RESUME_RESTORE_STATIC
0130     RESUME_RESTORE_REGS_RETURN
0131 .endm
0132 
0133 #else /* __ASSEMBLY__ */
0134 
0135 /**
0136  * struct mips_static_suspend_state - Core saved CPU state across S2R.
0137  * @segctl: CP0 Segment control registers.
0138  * @sp:     Stack frame where GP register context is saved.
0139  *
0140  * This structure contains minimal CPU state that must be saved in static kernel
0141  * data in order to be able to restore the rest of the state. This includes
0142  * segmentation configuration in the case of EVA being enabled, as they must be
0143  * restored prior to any kmalloc'd memory being referenced (even the stack
0144  * pointer).
0145  */
0146 struct mips_static_suspend_state {
0147 #ifdef CONFIG_EVA
0148     unsigned long segctl[3];
0149 #endif
0150     unsigned long sp;
0151 };
0152 
0153 #endif /* !__ASSEMBLY__ */
0154 
0155 #endif /* __ASM_PM_HELPERS_H */