Merge branch 'devel' of master.kernel.org:/home/rmk/linux-2.6-serial
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / arch / arm / mach-pnx4008 / sleep.S
1 /*
2 * linux/arch/arm/mach-pnx4008/sleep.S
3 *
4 * PNX4008 support for STOP mode and SDRAM self-refresh
5 *
6 * Authors: Dmitry Chigirev, Vitaly Wool <source@mvista.com>
7 *
8 * 2005 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13
14 #include <linux/config.h>
15 #include <linux/linkage.h>
16 #include <asm/assembler.h>
17 #include <asm/hardware.h>
18
19 #define PWRMAN_VA_BASE IO_ADDRESS(PNX4008_PWRMAN_BASE)
20 #define PWR_CTRL_REG_OFFS 0x44
21
22 #define SDRAM_CFG_VA_BASE IO_ADDRESS(PNX4008_SDRAM_CFG_BASE)
23 #define MPMC_STATUS_REG_OFFS 0x4
24
25 .text
26
27 ENTRY(pnx4008_cpu_suspend)
28 @this function should be entered in Direct run mode.
29
30 @ save registers on stack
31 stmfd sp!, {r0 - r6, lr}
32
33 @ setup Power Manager base address in r4
34 @ and put it's value in r5
35 mov r4, #(PWRMAN_VA_BASE & 0xff000000)
36 orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
37 orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
38 orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
39 ldr r5, [r4, #PWR_CTRL_REG_OFFS]
40
41 @ setup SDRAM controller base address in r2
42 @ and put it's value in r3
43 mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
44 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
45 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
46 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
47 ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
48
49 @ clear SDRAM self-refresh bit latch
50 and r5, r5, #(~(1 << 8))
51 @ clear SDRAM self-refresh bit
52 and r5, r5, #(~(1 << 9))
53 str r5, [r4, #PWR_CTRL_REG_OFFS]
54
55 @ do save current bit settings in r1
56 mov r1, r5
57
58 @ set SDRAM self-refresh bit
59 orr r5, r5, #(1 << 9)
60 str r5, [r4, #PWR_CTRL_REG_OFFS]
61
62 @ set SDRAM self-refresh bit latch
63 orr r5, r5, #(1 << 8)
64 str r5, [r4, #PWR_CTRL_REG_OFFS]
65
66 @ clear SDRAM self-refresh bit latch
67 and r5, r5, #(~(1 << 8))
68 str r5, [r4, #PWR_CTRL_REG_OFFS]
69
70 @ clear SDRAM self-refresh bit
71 and r5, r5, #(~(1 << 9))
72 str r5, [r4, #PWR_CTRL_REG_OFFS]
73
74 @ wait for SDRAM to get into self-refresh mode
75 2: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
76 tst r3, #(1 << 2)
77 beq 2b
78
79 @ to prepare SDRAM to get out of self-refresh mode after wakeup
80 orr r5, r5, #(1 << 7)
81 str r5, [r4, #PWR_CTRL_REG_OFFS]
82
83 @ do enter stop mode
84 orr r5, r5, #(1 << 0)
85 str r5, [r4, #PWR_CTRL_REG_OFFS]
86 nop
87 nop
88 nop
89 nop
90 nop
91 nop
92 nop
93 nop
94 nop
95
96 @ sleeping now...
97
98 @ coming out of STOP mode into Direct Run mode
99 @ clear STOP mode and SDRAM self-refresh bits
100 str r1, [r4, #PWR_CTRL_REG_OFFS]
101
102 @ wait for SDRAM to get out self-refresh mode
103 3: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
104 tst r3, #5
105 bne 3b
106
107 @ restore regs and return
108 ldmfd sp!, {r0 - r6, pc}
109
110 ENTRY(pnx4008_cpu_suspend_sz)
111 .word . - pnx4008_cpu_suspend
112
113 ENTRY(pnx4008_cpu_standby)
114 @ save registers on stack
115 stmfd sp!, {r0 - r6, lr}
116
117 @ setup Power Manager base address in r4
118 @ and put it's value in r5
119 mov r4, #(PWRMAN_VA_BASE & 0xff000000)
120 orr r4, r4, #(PWRMAN_VA_BASE & 0x00ff0000)
121 orr r4, r4, #(PWRMAN_VA_BASE & 0x0000ff00)
122 orr r4, r4, #(PWRMAN_VA_BASE & 0x000000ff)
123 ldr r5, [r4, #PWR_CTRL_REG_OFFS]
124
125 @ setup SDRAM controller base address in r2
126 @ and put it's value in r3
127 mov r2, #(SDRAM_CFG_VA_BASE & 0xff000000)
128 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x00ff0000)
129 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x0000ff00)
130 orr r2, r2, #(SDRAM_CFG_VA_BASE & 0x000000ff)
131 ldr r3, [r2, #MPMC_STATUS_REG_OFFS] @extra read - HW bug workaround
132
133 @ clear SDRAM self-refresh bit latch
134 and r5, r5, #(~(1 << 8))
135 @ clear SDRAM self-refresh bit
136 and r5, r5, #(~(1 << 9))
137 str r5, [r4, #PWR_CTRL_REG_OFFS]
138
139 @ do save current bit settings in r1
140 mov r1, r5
141
142 @ set SDRAM self-refresh bit
143 orr r5, r5, #(1 << 9)
144 str r5, [r4, #PWR_CTRL_REG_OFFS]
145
146 @ set SDRAM self-refresh bit latch
147 orr r5, r5, #(1 << 8)
148 str r5, [r4, #PWR_CTRL_REG_OFFS]
149
150 @ clear SDRAM self-refresh bit latch
151 and r5, r5, #(~(1 << 8))
152 str r5, [r4, #PWR_CTRL_REG_OFFS]
153
154 @ clear SDRAM self-refresh bit
155 and r5, r5, #(~(1 << 9))
156 str r5, [r4, #PWR_CTRL_REG_OFFS]
157
158 @ wait for SDRAM to get into self-refresh mode
159 2: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
160 tst r3, #(1 << 2)
161 beq 2b
162
163 @ set 'get out of self-refresh mode after wakeup' bit
164 orr r5, r5, #(1 << 7)
165 str r5, [r4, #PWR_CTRL_REG_OFFS]
166
167 mcr p15, 0, r0, c7, c0, 4 @ kinda sleeping now...
168
169 @ set SDRAM self-refresh bit latch
170 orr r5, r5, #(1 << 8)
171 str r5, [r4, #PWR_CTRL_REG_OFFS]
172
173 @ clear SDRAM self-refresh bit latch
174 and r5, r5, #(~(1 << 8))
175 str r5, [r4, #PWR_CTRL_REG_OFFS]
176
177 @ wait for SDRAM to get out self-refresh mode
178 3: ldr r3, [r2, #MPMC_STATUS_REG_OFFS]
179 tst r3, #5
180 bne 3b
181
182 @ restore regs and return
183 ldmfd sp!, {r0 - r6, pc}
184
185 ENTRY(pnx4008_cpu_standby_sz)
186 .word . - pnx4008_cpu_standby
187
188 ENTRY(pnx4008_cache_clean_invalidate)
189 stmfd sp!, {r0 - r6, lr}
190 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
191 mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
192 #else
193 1: mrc p15, 0, r15, c7, c14, 3 @ test,clean,invalidate
194 bne 1b
195 #endif
196 ldmfd sp!, {r0 - r6, pc}