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