2 * arch/sh/kernel/cpu/sh4a/sleep-sh_mobile.S
4 * Sleep mode and Standby modes support for SuperH Mobile
6 * Copyright (C) 2009 Magnus Damm
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License. See the file "COPYING" in the main directory of this archive
13 #include <linux/sys.h>
14 #include <linux/errno.h>
15 #include <linux/linkage.h>
16 #include <asm/asm-offsets.h>
17 #include <asm/suspend.h>
20 * Kernel mode register usage, see entry.S:
27 /* manage self-refresh and enter standby mode. must be self-contained.
28 * this code will be copied to on-chip memory and executed from there.
31 ENTRY(sh_mobile_sleep_enter_start)
34 mov.l r4, @(SH_SLEEP_MODE, r5)
36 /* save original vbr */
38 mov.l r0, @(SH_SLEEP_VBR, r5)
40 /* point vbr to our on-chip memory page */
43 /* save return address */
45 mov.l r0, @(SH_SLEEP_SPC, r5)
49 mov.l r0, @(SH_SLEEP_SR, r5)
52 mov.l r15, @(SH_SLEEP_SP, r5)
56 mov #SH_SLEEP_REG_STBCR, r0
58 /* save mmu and cache context if needed */
59 mov.l @(SH_SLEEP_MODE, r5), r0
61 bt skip_mmu_save_disable
65 mov #SH_SLEEP_REG_PTEH, r0
68 mov #SH_SLEEP_REG_PTEL, r0
71 mov #SH_SLEEP_REG_TTB, r0
74 mov #SH_SLEEP_REG_TEA, r0
77 mov #SH_SLEEP_REG_MMUCR, r0
80 mov #SH_SLEEP_REG_PTEA, r0
83 mov #SH_SLEEP_REG_PASCR, r0
86 mov #SH_SLEEP_REG_IRMCR, r0
88 /* invalidate TLBs and disable the MMU */
90 mov #SH_SLEEP_REG_MMUCR, r0
95 /* save cache registers and disable caches */
97 mov #SH_SLEEP_REG_CCR, r0
100 mov #SH_SLEEP_REG_RAMCR, r0
103 mov #SH_SLEEP_REG_CCR, r0
108 skip_mmu_save_disable:
109 /* call self-refresh entering code if needed */
110 mov.l @(SH_SLEEP_MODE, r5), r0
114 mov.l @(SH_SLEEP_SF_PRE, r5), r0
119 mov.l @(SH_SLEEP_MODE, r5), r0
120 tst #SUSP_SH_STANDBY, r0
123 /* set mode to "software standby mode" */
128 tst #SUSP_SH_RSTANDBY, r0
131 /* setup BAR register */
133 mov #SH_SLEEP_REG_BAR, r0
134 mov.l @(SH_SLEEP_RESUME, r5), r1
137 /* set mode to "r-standby mode" */
142 tst #SUSP_SH_USTANDBY, r0
145 /* set mode to "u-standby mode" */
151 /* set mode to "sleep mode" */
155 /* setup and enter selected standby mode */
157 mov #SH_SLEEP_REG_STBCR, r0
165 add #SH_SLEEP_BASE_ADDR, r0
167 add #-SH_SLEEP_BASE_ADDR, r0
169 add #SH_SLEEP_BASE_DATA, r0
171 add #-SH_SLEEP_BASE_DATA, r0
176 add #SH_SLEEP_BASE_ADDR, r0
180 ENTRY(sh_mobile_sleep_enter_end)
183 ENTRY(sh_mobile_sleep_resume_start)
185 /* figure out start address */
193 /* store pointer to data area in VBR */
196 /* setup sr with saved sr */
197 mov.l @(SH_SLEEP_SR, k1), k0
200 /* now: user register set! */
203 /* setup spc with return address to c code */
204 mov.l @(SH_SLEEP_SPC, r5), r0
208 mov.l @(SH_SLEEP_VBR, r5), r0
211 /* setup ssr with saved sr */
212 mov.l @(SH_SLEEP_SR, r5), r0
216 mov.l @(SH_SLEEP_SP, r5), r15
218 /* restore sleep mode register */
220 mov #SH_SLEEP_REG_STBCR, r0
222 /* call self-refresh resume code if needed */
223 mov.l @(SH_SLEEP_MODE, r5), r0
227 mov.l @(SH_SLEEP_SF_POST, r5), r0
232 /* restore mmu and cache state if needed */
233 mov.l @(SH_SLEEP_MODE, r5), r0
237 /* restore mmu state */
239 mov #SH_SLEEP_REG_PTEH, r0
242 mov #SH_SLEEP_REG_PTEL, r0
245 mov #SH_SLEEP_REG_TTB, r0
248 mov #SH_SLEEP_REG_TEA, r0
251 mov #SH_SLEEP_REG_PTEA, r0
254 mov #SH_SLEEP_REG_PASCR, r0
257 mov #SH_SLEEP_REG_IRMCR, r0
260 mov #SH_SLEEP_REG_MMUCR, r0
263 /* restore cache settings */
265 mov #SH_SLEEP_REG_RAMCR, r0
269 mov #SH_SLEEP_REG_CCR, r0
277 add #SH_SLEEP_BASE_DATA, r0
279 add #-SH_SLEEP_BASE_DATA, r0
280 add #SH_SLEEP_BASE_ADDR, r0
288 ENTRY(sh_mobile_sleep_resume_end)