Linux Audio

Check our new training course

Loading...
  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 */