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