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