sleep.S 4.3 KB
Newer Older
M
Magnus Damm 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * arch/sh/kernel/cpu/sh4a/sleep-sh_mobile.S
 *
 * Sleep mode and Standby modes support for SuperH Mobile
 *
 *  Copyright (C) 2009 Magnus Damm
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */

#include <linux/sys.h>
#include <linux/errno.h>
#include <linux/linkage.h>
#include <asm/asm-offsets.h>
#include <asm/suspend.h>

19 20 21 22 23 24 25 26 27 28
/*
 * Kernel mode register usage, see entry.S:
 *	k0	scratch
 *	k1	scratch
 *	k4	scratch
 */
#define k0	r0
#define k1	r1
#define k4	r4

M
Magnus Damm 已提交
29 30 31 32 33 34
/* manage self-refresh and enter standby mode.
 * this code will be copied to on-chip memory and executed from there.
 */

	.balign 	4096,0,4096
ENTRY(sh_mobile_standby)
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58

	/* save original vbr */
	stc	vbr, r1
	mova	saved_vbr, r0
	mov.l	r1, @r0

	/* point vbr to our on-chip memory page */
	ldc	r5, vbr

	/* save return address */
	mova	saved_spc, r0
	sts	pr, r5
	mov.l	r5, @r0

	/* save sr */
	mova	saved_sr, r0
	stc	sr, r5
	mov.l	r5, @r0

	/* save mode flags */
	mova	saved_mode, r0
	mov.l	r4, @r0

	/* put mode flags in r0 */
M
Magnus Damm 已提交
59 60 61 62
	mov	r4, r0

	tst	#SUSP_SH_SF, r0
	bt	skip_set_sf
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
#ifdef CONFIG_CPU_SUBTYPE_SH7724
	/* DBSC: put memory in self-refresh mode */
	mov.l	dben_reg, r4
	mov.l	dben_data0, r1
	mov.l	r1, @r4

	mov.l	dbrfpdn0_reg, r4
	mov.l	dbrfpdn0_data0, r1
	mov.l	r1, @r4

	mov.l	dbcmdcnt_reg, r4
	mov.l	dbcmdcnt_data0, r1
	mov.l	r1, @r4

	mov.l	dbcmdcnt_reg, r4
	mov.l	dbcmdcnt_data1, r1
	mov.l	r1, @r4

	mov.l	dbrfpdn0_reg, r4
	mov.l	dbrfpdn0_data1, r1
	mov.l	r1, @r4
#else
	/* SBSC: disable power down and put in self-refresh mode */
M
Magnus Damm 已提交
86 87 88 89 90 91 92
	mov.l	1f, r4
	mov.l	2f, r1
	mov.l	@r4, r2
	or	r1, r2
	mov.l   3f, r3
	and	r3, r2
	mov.l	r2, @r4
93
#endif
M
Magnus Damm 已提交
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112

skip_set_sf:
	tst	#SUSP_SH_STANDBY, r0
	bt	test_rstandby

	/* set mode to "software standby mode" */
	bra	do_sleep
	 mov	#0x80, r1

test_rstandby:
	tst	#SUSP_SH_RSTANDBY, r0
	bt	test_ustandby

	/* set mode to "r-standby mode" */
	bra	do_sleep
	 mov	#0x20, r1

test_ustandby:
	tst	#SUSP_SH_USTANDBY, r0
113
	bt	force_sleep
M
Magnus Damm 已提交
114 115

	/* set mode to "u-standby mode" */
116 117
	bra	do_sleep
	 mov	#0x10, r1
M
Magnus Damm 已提交
118

119 120 121 122
force_sleep:

	/* set mode to "sleep mode" */
	mov	#0x00, r1
M
Magnus Damm 已提交
123 124 125 126 127

do_sleep:
	/* setup and enter selected standby mode */
	mov.l	5f, r4
	mov.l	r1, @r4
128
again:
M
Magnus Damm 已提交
129
	sleep
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
	bra	again
	 nop

restore_jump_vbr:
	/* setup spc with return address to c code */
	mov.l	saved_spc, k0
	ldc	k0, spc

	/* restore vbr */
	mov.l	saved_vbr, k0
	ldc	k0, vbr

	/* setup ssr with saved sr */
	mov.l	saved_sr, k0
	ldc	k0, ssr

	/* get mode flags */
	mov.l	saved_mode, k0
M
Magnus Damm 已提交
148 149 150

done_sleep:
	/* reset standby mode to sleep mode */
151 152 153
	mov.l	5f, k4
	mov	#0x00, k1
	mov.l	k1, @k4
M
Magnus Damm 已提交
154

155
	tst	#SUSP_SH_SF, k0
M
Magnus Damm 已提交
156 157
	bt	skip_restore_sf

158 159
#ifdef CONFIG_CPU_SUBTYPE_SH7724
	/* DBSC: put memory in auto-refresh mode */
160 161 162
	mov.l	dbrfpdn0_reg, k4
	mov.l	dbrfpdn0_data0, k1
	mov.l	k1, @k4
163

164
	nop /* sleep 140 ns */
165 166 167 168
	nop
	nop
	nop

169 170 171
	mov.l	dbcmdcnt_reg, k4
	mov.l	dbcmdcnt_data0, k1
	mov.l	k1, @k4
172

173 174 175
	mov.l	dbcmdcnt_reg, k4
	mov.l	dbcmdcnt_data1, k1
	mov.l	k1, @k4
176

177 178 179
	mov.l	dben_reg, k4
	mov.l	dben_data1, k1
	mov.l	k1, @k4
180

181 182 183
	mov.l	dbrfpdn0_reg, k4
	mov.l	dbrfpdn0_data2, k1
	mov.l	k1, @k4
184 185
#else
	/* SBSC: set auto-refresh mode */
186 187 188 189 190 191 192 193 194 195 196 197 198
	mov.l	1f, k4
	mov.l	@k4, k0
	mov.l   4f, k1
	and	k1, k0
	mov.l	k0, @k4
	mov.l	6f, k4
	mov.l	8f, k0
	mov.l	@k4, k1
	mov	#-1, k4
	add	k4, k1
	or	k1, k0
	mov.l	7f, k1
	mov.l	k0, @k1
199
#endif
M
Magnus Damm 已提交
200
skip_restore_sf:
201 202 203 204 205
	/* jump to vbr vector */
	mov.l	saved_vbr, k0
	mov.l	offset_vbr, k4
	add	k4, k0
	jmp	@k0
M
Magnus Damm 已提交
206 207 208
	 nop

	.balign 4
209 210 211 212 213
saved_mode:	.long	0
saved_spc:	.long	0
saved_sr:	.long	0
saved_vbr:	.long	0
offset_vbr:	.long	0x600
214 215 216 217 218 219 220 221 222 223 224 225
#ifdef CONFIG_CPU_SUBTYPE_SH7724
dben_reg:	.long	0xfd000010 /* DBEN */
dben_data0:	.long	0
dben_data1:	.long	1
dbrfpdn0_reg:	.long	0xfd000040 /* DBRFPDN0 */
dbrfpdn0_data0:	.long	0
dbrfpdn0_data1:	.long	1
dbrfpdn0_data2:	.long	0x00010000
dbcmdcnt_reg:	.long	0xfd000014 /* DBCMDCNT */
dbcmdcnt_data0:	.long	2
dbcmdcnt_data1:	.long	4
#else
M
Magnus Damm 已提交
226 227 228 229
1:	.long	0xfe400008 /* SDCR0 */
2:	.long	0x00000400
3:	.long	0xffff7fff
4:	.long	0xfffffbff
230
#endif
M
Magnus Damm 已提交
231 232 233 234 235
5:	.long	0xa4150020 /* STBCR */
6:	.long   0xfe40001c /* RTCOR */
7:	.long   0xfe400018 /* RTCNT */
8:	.long   0xa55a0000

236

M
Magnus Damm 已提交
237 238 239 240
/* interrupt vector @ 0x600 */
	.balign 	0x400,0,0x400
	.long	0xdeadbeef
	.balign 	0x200,0,0x200
241
	bra	restore_jump_vbr
M
Magnus Damm 已提交
242 243 244 245 246
	 nop
sh_mobile_standby_end:

ENTRY(sh_mobile_standby_size)
	.long sh_mobile_standby_end - sh_mobile_standby