Merge ../linus
[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/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}