summaryrefslogtreecommitdiff
path: root/arch/arm/mach-s3c2443/cc9m2443js-sleep.S
blob: c66ca42ac38e432d7aa45eb47c3b360e3e5a1903 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* linux/arch/arm/mach-s3c24xx/sleep-s3c2443.S
 *
 * $Id: sleep-s3c2443.S,v 1.3 2006/11/08 01:07:53 eyryu Exp $
 *
 * Copyright (c) 2006 Samsung Electronics
 *	Ryu Euiyoul <steven.ryu@samsung.com>
 *
 * S3C Power Manager (Suspend-To-RAM) support
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

@ #include <linux/config.h>
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <mach/hardware.h>


#if 0
#define ENABLE_GPIO_TOGGLE
#endif
	
	.text

/* s3c_cpu_suspend
 *
 * put the cpu into sleep mode
 *
 * entry:
 *	r0 = sleep save block
*/

ENTRY(s3c2443_cpu_suspend)
	stmfd	sp!, { r4 - r12, lr }	@ save registers on stack

	@@ get co-processor registers
	mrc	p15, 0, r4, c3, c0, 0	@ Domain ID
	mrc	p15, 0, r5, c2, c0, 0	@ translation table base address
	mrc	p15, 0, r6, c13, c0, 0	@ PID
	mrc	p15, 0, r7, c1, c0, 0	@ control register

	@ store them plus current virtual stact ptr on stack
	mov	r8, sp
	stmfd	sp!, {r4 - r8}


	mov	r1, #0	
	mcr	p15, 0, r1, c8, c7, 0		@ flush I+D TLBs
	mcr	p15, 0, r1, c7, c7, 0		@ flush I & D caches
	mcr     p15, 0, r1, c9, c0, 0           @ invalidate RB
	
	mov	r0, sp
  	bl	sleep_phys_sp
	ldr	r1, =sleep_save_sp
	str	r0, [r1]

        @@ flush the caches to ensure everything is back out to
        @@ SDRAM before the core powers down

        bl      arm920_flush_kern_cache_all
	
	b	s3c_goto_sleep

	.align	5


 	/* 
	 * Before entering the sleep mode we must store the jump address in the
 	 * configuration register INFORM1
	 */	
s3c_goto_sleep:
        ldr     r0, =0xf4100040 @ =S3C_PWRMODE
        ldr     r1, =0x2BED
        str     r1, [r0]

@ _sleeping:
@ 	nop
@ 	nop
@ 	nop
@ 	b	_sleeping
	.ltorg

	/* s3c_cpu_resume
	 *
	 * resume code entry for bootloader to call
	 *
	 * we must put this code here in the data segment as we have no
	 * other way of restoring the stack pointer after sleep, and we
	 * must not write to the code segment (code is read-only)
	*/
	.data
	.align 5 
ENTRY(s3c2443_cpu_resume)

        @@@@@@@@@ The U-Boot set the registers: r10 -> GPLDAT
#if defined(ENABLE_GPIO_TOGGLE)
        adr     r11, _gplcon_virtual_address
        ldr     r10, [r11]
        mov     r5, #50
_toggle_gpio:
        ldr     r6, [r10]
        eor     r6, r6, #0x800
        str     r6, [r10]
        mov     r4, #0x800000
_dec_timer:
        sub     r4, r4, #1
        cmp     r4, #0
        bne     _dec_timer

        sub     r5, r5, #1
        cmp     r5, #0
        bne     _toggle_gpio
#endif /* ENABLE_GPIO_TOGGLE */
        @@@@@@@@@ The U-Boot set the registers: r5 -> GPLDAT

	
	mov	r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
	msr	cpsr_c, r0

	ldr	r0, sleep_save_sp	@ address of restore block
	ldr	r2, =resume_after_mmu
	ldmfd	r0, {r4 - r7, sp}
	
	mov	r1, #0	
	mcr	p15, 0, r1, c8, c7, 0		@ flush I+D TLBs
	mcr	p15, 0, r1, c7, c7, 0		@ flush I & D caches
	mcr     p15, 0, r1, c9, c0, 0           @ invalidate RB
	mcr     p15, 0, r1, c9, c0, 5           @ allow user space to use RB

	mcr	p15, 0, r4, c3, c0, 0		@ Domain ID
	mcr	p15, 0, r5, c2, c0, 0		@ translation table base
	mcr	p15, 0, r6, c13, c0, 0		@ PID
	b       resume_turn_on_mmu              @ cache align execution

	.align 5 
resume_turn_on_mmu:
        mcr     p15, 0, r7, c1, c0, 0           @ turn on MMU, caches, etc.
	nop 
	mov	pc, r2
	nop
	nop
	nop

	.ltorg
sleep_save_sp:
	.word	0

        @@ DEBUG: Virtual address of the register GPLDAT
_gplcon_virtual_address:
	@ .word   0xfb0000f4
        .word	0x560000f4
	
	.text
resume_after_mmu:
        ldmfd   sp!, { r4 - r12, pc }