Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-pnx4008/sleep.S
10817 views
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 <[email protected]>
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}
196
197