]> git.ipfire.org Git - thirdparty/kernel/stable.git/blob - arch/unicore32/kernel/sleep.S
607a104aec595328e6a7cd4af3dc6092e1e36683
[thirdparty/kernel/stable.git] / arch / unicore32 / kernel / sleep.S
1 /*
2 * linux/arch/unicore32/kernel/sleep.S
3 *
4 * Code specific to PKUnity SoC and UniCore ISA
5 *
6 * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
7 * Copyright (C) 2001-2010 Guan Xuetao
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14 #include <linux/linkage.h>
15 #include <asm/assembler.h>
16 #include <mach/hardware.h>
17
18 .text
19
20 pkunity_cpu_save_cp:
21
22 @ get coprocessor registers
23
24 movc r3, p0.c7, #0 @ PID
25 movc r4, p0.c2, #0 @ translation table base addr
26 movc r5, p0.c1, #0 @ control reg
27
28
29 @ store them plus current virtual stack ptr on stack
30 mov r6, sp
31 stm.w (r3 - r6), [sp-]
32
33 mov pc, lr
34
35 pkunity_cpu_save_sp:
36 @ preserve phys address of stack
37 mov r0, sp
38 stw.w lr, [sp+], #-4
39 b.l sleep_phys_sp
40 ldw r1, =sleep_save_sp
41 stw r0, [r1]
42 ldw.w pc, [sp]+, #4
43
44 /*
45 * puv3_cpu_suspend()
46 *
47 * Forces CPU into sleep state.
48 *
49 * r0 = value for PWRMODE M field for desired sleep state
50 */
51
52 ENTRY(puv3_cpu_suspend)
53 stm.w (r16 - r27, lr), [sp-] @ save registers on stack
54 stm.w (r4 - r15), [sp-] @ save registers on stack
55
56 #ifdef CONFIG_UNICORE_FPU_F64
57 sfm.w (f0 - f7 ), [sp-]
58 sfm.w (f8 - f15), [sp-]
59 sfm.w (f16 - f23), [sp-]
60 sfm.w (f24 - f31), [sp-]
61 cff r4, s31
62 stm.w (r4), [sp-]
63 #endif
64 b.l pkunity_cpu_save_cp
65
66 b.l pkunity_cpu_save_sp
67
68 @ clean data cache
69 mov r1, #0
70 movc p0.c5, r1, #14
71 nop
72 nop
73 nop
74 nop
75
76
77
78 @ DDR2 BaseAddr
79 ldw r0, =(PKUNITY_DDR2CTRL_BASE)
80
81 @ PM BaseAddr
82 ldw r1, =(PKUNITY_PM_BASE)
83
84 @ set PLL_SYS_CFG reg, 275
85 movl r6, #0x00002401
86 stw r6, [r1+], #0x18
87 @ set PLL_DDR_CFG reg, 66MHz
88 movl r6, #0x00100c00
89 stw r6, [r1+], #0x1c
90
91 @ set wake up source
92 movl r8, #0x800001ff @ epip4d
93 stw r8, [r1+], #0xc
94
95 @ set PGSR
96 movl r5, #0x40000
97 stw r5, [r1+], #0x10
98
99 @ prepare DDR2 refresh settings
100 ldw r5, [r0+], #0x24
101 or r5, r5, #0x00000001
102
103 @ prepare PMCR for PLL changing
104 movl r6, #0xc
105
106 @ prepare for closing PLL
107 movl r7, #0x1
108
109 @ prepare sleep mode
110 mov r8, #0x1
111
112 @ movl r0, 0x11111111
113 @ put_word_ocd r0
114 b pkunity_cpu_do_suspend
115
116 .ltorg
117 .align 5
118 pkunity_cpu_do_suspend:
119 b 101f
120 @ put DDR2 into self-refresh
121 100: stw r5, [r0+], #0x24
122 @ change PLL
123 stw r6, [r1]
124 b 1f
125
126 .ltorg
127 .align 5
128 101: b 102f
129 @ wait for PLL changing complete
130 1: ldw r6, [r1+], #0x44
131 csub.a r6, #0x1
132 bne 1b
133 b 2f
134
135 .ltorg
136 .align 5
137 102: b 100b
138 @ close PLL
139 2: stw r7, [r1+], #0x4
140 @ enter sleep mode
141 stw r8, [r1]
142 3: b 3b
143
144
145
146
147 /*
148 * puv3_cpu_resume()
149 *
150 * entry point from bootloader into kernel during resume
151 *
152 * Note: Yes, part of the following code is located into the .data section.
153 * This is to allow sleep_save_sp to be accessed with a relative load
154 * while we can't rely on any MMU translation. We could have put
155 * sleep_save_sp in the .text section as well, but some setups might
156 * insist on it to be truly read-only.
157 */
158
159 .data
160 .align 5
161 ENTRY(puv3_cpu_resume)
162 @ movl r0, 0x20202020
163 @ put_word_ocd r0
164
165 ldw r0, sleep_save_sp @ stack phys addr
166 ldw r2, =resume_after_mmu @ its absolute virtual address
167 ldm (r3 - r6), [r0]+ @ CP regs + virt stack ptr
168 mov sp, r6 @ CP regs + virt stack ptr
169
170 mov r1, #0
171 movc p0.c6, r1, #6 @ invalidate I & D TLBs
172 movc p0.c5, r1, #28 @ invalidate I & D caches, BTB
173
174 movc p0.c7, r3, #0 @ PID
175 movc p0.c2, r4, #0 @ translation table base addr
176 movc p0.c1, r5, #0 @ control reg, turn on mmu
177 nop
178 jump r2
179 nop
180 nop
181 nop
182 nop
183 nop
184
185 sleep_save_sp:
186 .word 0 @ preserve stack phys ptr here
187
188 .text
189 resume_after_mmu:
190 @ movl r0, 0x30303030
191 @ put_word_ocd r0
192
193 #ifdef CONFIG_UNICORE_FPU_F64
194 lfm.w (f0 - f7 ), [sp]+
195 lfm.w (f8 - f15), [sp]+
196 lfm.w (f16 - f23), [sp]+
197 lfm.w (f24 - f31), [sp]+
198 ldm.w (r4), [sp]+
199 ctf r4, s31
200 #endif
201 ldm.w (r4 - r15), [sp]+ @ restore registers from stack
202 ldm.w (r16 - r27, pc), [sp]+ @ return to caller