xref: /openbmc/linux/arch/sh/kernel/cpu/shmobile/sleep.S (revision 237674e0)
1/*
2 * arch/sh/kernel/cpu/sh4a/sleep-sh_mobile.S
3 *
4 * Sleep mode and Standby modes support for SuperH Mobile
5 *
6 *  Copyright (C) 2009 Magnus Damm
7 *
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
10 * for more details.
11 */
12
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>
18
19/* manage self-refresh and enter standby mode.
20 * this code will be copied to on-chip memory and executed from there.
21 */
22
23	.balign 	4096,0,4096
24ENTRY(sh_mobile_standby)
25	mov	r4, r0
26
27	tst	#SUSP_SH_SF, r0
28	bt	skip_set_sf
29#ifdef CONFIG_CPU_SUBTYPE_SH7724
30	/* DBSC: put memory in self-refresh mode */
31
32	mov.l	dben_reg, r4
33	mov.l	dben_data0, r1
34	mov.l	r1, @r4
35
36	mov.l	dbrfpdn0_reg, r4
37	mov.l	dbrfpdn0_data0, r1
38	mov.l	r1, @r4
39
40	mov.l	dbcmdcnt_reg, r4
41	mov.l	dbcmdcnt_data0, r1
42	mov.l	r1, @r4
43
44	mov.l	dbcmdcnt_reg, r4
45	mov.l	dbcmdcnt_data1, r1
46	mov.l	r1, @r4
47
48	mov.l	dbrfpdn0_reg, r4
49	mov.l	dbrfpdn0_data1, r1
50	mov.l	r1, @r4
51#else
52	/* SBSC: disable power down and put in self-refresh mode */
53	mov.l	1f, r4
54	mov.l	2f, r1
55	mov.l	@r4, r2
56	or	r1, r2
57	mov.l   3f, r3
58	and	r3, r2
59	mov.l	r2, @r4
60#endif
61
62skip_set_sf:
63	tst	#SUSP_SH_SLEEP, r0
64	bt	test_standby
65
66	/* set mode to "sleep mode" */
67	bra	do_sleep
68	 mov	#0x00, r1
69
70test_standby:
71	tst	#SUSP_SH_STANDBY, r0
72	bt	test_rstandby
73
74	/* set mode to "software standby mode" */
75	bra	do_sleep
76	 mov	#0x80, r1
77
78test_rstandby:
79	tst	#SUSP_SH_RSTANDBY, r0
80	bt	test_ustandby
81
82	/* set mode to "r-standby mode" */
83	bra	do_sleep
84	 mov	#0x20, r1
85
86test_ustandby:
87	tst	#SUSP_SH_USTANDBY, r0
88	bt	done_sleep
89
90	/* set mode to "u-standby mode" */
91	mov	#0x10, r1
92
93	/* fall-through */
94
95do_sleep:
96	/* setup and enter selected standby mode */
97	mov.l	5f, r4
98	mov.l	r1, @r4
99	sleep
100
101done_sleep:
102	/* reset standby mode to sleep mode */
103	mov.l	5f, r4
104	mov	#0x00, r1
105	mov.l	r1, @r4
106
107	tst	#SUSP_SH_SF, r0
108	bt	skip_restore_sf
109
110#ifdef CONFIG_CPU_SUBTYPE_SH7724
111	/* DBSC: put memory in auto-refresh mode */
112
113	mov.l	dbrfpdn0_reg, r4
114	mov.l	dbrfpdn0_data0, r1
115	mov.l	r1, @r4
116
117	/* sleep 140 ns */
118	nop
119	nop
120	nop
121	nop
122
123	mov.l	dbcmdcnt_reg, r4
124	mov.l	dbcmdcnt_data0, r1
125	mov.l	r1, @r4
126
127	mov.l	dbcmdcnt_reg, r4
128	mov.l	dbcmdcnt_data1, r1
129	mov.l	r1, @r4
130
131	mov.l	dben_reg, r4
132	mov.l	dben_data1, r1
133	mov.l	r1, @r4
134
135	mov.l	dbrfpdn0_reg, r4
136	mov.l	dbrfpdn0_data2, r1
137	mov.l	r1, @r4
138#else
139	/* SBSC: set auto-refresh mode */
140	mov.l	1f, r4
141	mov.l	@r4, r2
142	mov.l   4f, r3
143	and	r3, r2
144	mov.l	r2, @r4
145	mov.l	6f, r4
146	mov.l	7f, r1
147	mov.l	8f, r2
148	mov.l	@r4, r3
149	mov	#-1, r4
150	add	r4, r3
151	or	r2, r3
152	mov.l	r3, @r1
153#endif
154skip_restore_sf:
155	rts
156	 nop
157
158	.balign 4
159#ifdef CONFIG_CPU_SUBTYPE_SH7724
160dben_reg:	.long	0xfd000010 /* DBEN */
161dben_data0:	.long	0
162dben_data1:	.long	1
163dbrfpdn0_reg:	.long	0xfd000040 /* DBRFPDN0 */
164dbrfpdn0_data0:	.long	0
165dbrfpdn0_data1:	.long	1
166dbrfpdn0_data2:	.long	0x00010000
167dbcmdcnt_reg:	.long	0xfd000014 /* DBCMDCNT */
168dbcmdcnt_data0:	.long	2
169dbcmdcnt_data1:	.long	4
170#else
1711:	.long	0xfe400008 /* SDCR0 */
1722:	.long	0x00000400
1733:	.long	0xffff7fff
1744:	.long	0xfffffbff
175#endif
1765:	.long	0xa4150020 /* STBCR */
1776:	.long   0xfe40001c /* RTCOR */
1787:	.long   0xfe400018 /* RTCNT */
1798:	.long   0xa55a0000
180
181/* interrupt vector @ 0x600 */
182	.balign 	0x400,0,0x400
183	.long	0xdeadbeef
184	.balign 	0x200,0,0x200
185	/* sh7722 will end up here in sleep mode */
186	rte
187	 nop
188sh_mobile_standby_end:
189
190ENTRY(sh_mobile_standby_size)
191	.long sh_mobile_standby_end - sh_mobile_standby
192