aboutsummaryrefslogtreecommitdiffstats
path: root/arch/frv/kernel/sleep.S
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/frv/kernel/sleep.S
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'arch/frv/kernel/sleep.S')
-rw-r--r--arch/frv/kernel/sleep.S374
1 files changed, 374 insertions, 0 deletions
diff --git a/arch/frv/kernel/sleep.S b/arch/frv/kernel/sleep.S
new file mode 100644
index 000000000000..e6079b8cac60
--- /dev/null
+++ b/arch/frv/kernel/sleep.S
@@ -0,0 +1,374 @@
1/* sleep.S: power saving mode entry
2 *
3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4 * Written by David Woodhouse (dwmw2@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13#include <linux/sys.h>
14#include <linux/config.h>
15#include <linux/linkage.h>
16#include <asm/setup.h>
17#include <asm/segment.h>
18#include <asm/page.h>
19#include <asm/ptrace.h>
20#include <asm/errno.h>
21#include <asm/cache.h>
22#include <asm/spr-regs.h>
23
24#define __addr_MASK 0xfeff9820 /* interrupt controller mask */
25
26#define __addr_FR55X_DRCN 0xfeff0218 /* Address of DRCN register */
27#define FR55X_DSTS_OFFSET -4 /* Offset from DRCN to DSTS */
28#define FR55X_SDRAMC_DSTS_SSI 0x00000002 /* indicates that the SDRAM is in self-refresh mode */
29
30#define __addr_FR4XX_DRCN 0xfe000430 /* Address of DRCN register */
31#define FR4XX_DSTS_OFFSET -8 /* Offset from DRCN to DSTS */
32#define FR4XX_SDRAMC_DSTS_SSI 0x00000001 /* indicates that the SDRAM is in self-refresh mode */
33
34#define SDRAMC_DRCN_SR 0x00000001 /* transition SDRAM into self-refresh mode */
35
36 .section .bss
37 .balign 8
38 .globl __sleep_save_area
39__sleep_save_area:
40 .space 16
41
42
43 .text
44 .balign 4
45
46.macro li v r
47 sethi.p %hi(\v),\r
48 setlo %lo(\v),\r
49.endm
50
51#ifdef CONFIG_PM
52###############################################################################
53#
54# CPU suspension routine
55# - void frv_cpu_suspend(unsigned long pdm_mode)
56#
57###############################################################################
58 .globl frv_cpu_suspend
59 .type frv_cpu_suspend,@function
60frv_cpu_suspend:
61
62 #----------------------------------------------------
63 # save hsr0, psr, isr, and lr for resume code
64 #----------------------------------------------------
65 li __sleep_save_area,gr11
66
67 movsg hsr0,gr4
68 movsg psr,gr5
69 movsg isr,gr6
70 movsg lr,gr7
71 stdi gr4,@(gr11,#0)
72 stdi gr6,@(gr11,#8)
73
74 # store the return address from sleep in GR14, and its complement in GR13 as a check
75 li __ramboot_resume,gr14
76#ifdef CONFIG_MMU
77 # Resume via RAMBOOT# will turn MMU off, so bootloader needs a physical address.
78 sethi.p %hi(__page_offset),gr13
79 setlo %lo(__page_offset),gr13
80 sub gr14,gr13,gr14
81#endif
82 not gr14,gr13
83
84 #----------------------------------------------------
85 # preload and lock into icache that code which may have to run
86 # when dram is in self-refresh state.
87 #----------------------------------------------------
88 movsg hsr0, gr3
89 li HSR0_ICE,gr4
90 or gr3,gr4,gr3
91 movgs gr3,hsr0
92 or gr3,gr8,gr7 // add the sleep bits for later
93
94 li #__icache_lock_start,gr3
95 li #__icache_lock_end,gr4
961: icpl gr3,gr0,#1
97 addi gr3,#L1_CACHE_BYTES,gr3
98 cmp gr4,gr3,icc0
99 bhi icc0,#0,1b
100
101 # disable exceptions
102 movsg psr,gr8
103 andi.p gr8,#~PSR_PIL,gr8
104 andi gr8,~PSR_ET,gr8
105 movgs gr8,psr
106 ori gr8,#PSR_ET,gr8
107
108 srli gr8,#28,gr4
109 subicc gr4,#3,gr0,icc0
110 beq icc0,#0,1f
111 # FR4xx
112 li __addr_FR4XX_DRCN,gr4
113 li FR4XX_SDRAMC_DSTS_SSI,gr5
114 li FR4XX_DSTS_OFFSET,gr6
115 bra __icache_lock_start
1161:
117 # FR5xx
118 li __addr_FR55X_DRCN,gr4
119 li FR55X_SDRAMC_DSTS_SSI,gr5
120 li FR55X_DSTS_OFFSET,gr6
121 bra __icache_lock_start
122
123 .size frv_cpu_suspend, .-frv_cpu_suspend
124
125#
126# the final part of the sleep sequence...
127# - we want it to be be cacheline aligned so we can lock it into the icache easily
128# On entry: gr7 holds desired hsr0 sleep value
129# gr8 holds desired psr sleep value
130#
131 .balign L1_CACHE_BYTES
132 .type __icache_lock_start,@function
133__icache_lock_start:
134
135 #----------------------------------------------------
136 # put SDRAM in self-refresh mode
137 #----------------------------------------------------
138
139 # Flush all data in the cache using the DCEF instruction.
140 dcef @(gr0,gr0),#1
141
142 # Stop DMAC transfer
143
144 # Execute dummy load from SDRAM
145 ldi @(gr11,#0),gr11
146
147 # put the SDRAM into self-refresh mode
148 ld @(gr4,gr0),gr11
149 ori gr11,#SDRAMC_DRCN_SR,gr11
150 st gr11,@(gr4,gr0)
151 membar
152
153 # wait for SDRAM to reach self-refresh mode
1541: ld @(gr4,gr6),gr11
155 andcc gr11,gr5,gr11,icc0
156 beq icc0,#0,1b
157
158 # Set the GPIO register so that the IRQ[3:0] pins become valid, as required.
159 # Set the clock mode (CLKC register) as required.
160 # - At this time, also set the CLKC register P0 bit.
161
162 # Set the HSR0 register PDM field.
163 movgs gr7,hsr0
164
165 # Execute NOP 32 times.
166 .rept 32
167 nop
168 .endr
169
170#if 0 // Fujitsu recommend to skip this and will update docs.
171 # Release the interrupt mask setting of the MASK register of the
172 # interrupt controller if necessary.
173 sti gr10,@(gr9,#0)
174 membar
175#endif
176
177 # Set the PSR register ET bit to 1 to enable interrupts.
178 movgs gr8,psr
179
180 ###################################################
181 # this is only reached if waking up via interrupt
182 ###################################################
183
184 # Execute NOP 32 times.
185 .rept 32
186 nop
187 .endr
188
189 #----------------------------------------------------
190 # wake SDRAM from self-refresh mode
191 #----------------------------------------------------
192 ld @(gr4,gr0),gr11
193 andi gr11,#~SDRAMC_DRCN_SR,gr11
194 st gr11,@(gr4,gr0)
195 membar
1962:
197 ld @(gr4,gr6),gr11 // Wait for it to come back...
198 andcc gr11,gr5,gr0,icc0
199 bne icc0,0,2b
200
201 # wait for the SDRAM to stabilise
202 li 0x0100000,gr3
2033: subicc gr3,#1,gr3,icc0
204 bne icc0,#0,3b
205
206 # now that DRAM is back, this is the end of the code which gets
207 # locked in icache.
208__icache_lock_end:
209 .size __icache_lock_start, .-__icache_lock_start
210
211 # Fall-through to the RAMBOOT# wakeup path
212
213###############################################################################
214#
215# resume from suspend re-entry point reached via RAMBOOT# and bootloader
216#
217###############################################################################
218__ramboot_resume:
219
220 #----------------------------------------------------
221 # restore hsr0, psr, isr, and leave saved lr in gr7
222 #----------------------------------------------------
223 li __sleep_save_area,gr11
224#ifdef CONFIG_MMU
225 movsg hsr0,gr4
226 sethi.p %hi(HSR0_EXMMU),gr3
227 setlo %lo(HSR0_EXMMU),gr3
228 andcc gr3,gr4,gr0,icc0
229 bne icc0,#0,2f
230
231 # need to use physical address
232 sethi.p %hi(__page_offset),gr3
233 setlo %lo(__page_offset),gr3
234 sub gr11,gr3,gr11
235
236 # flush all tlb entries
237 setlos #64,gr4
238 setlos.p #PAGE_SIZE,gr5
239 setlos #0,gr6
2401:
241 tlbpr gr6,gr0,#6,#0
242 subicc.p gr4,#1,gr4,icc0
243 add gr6,gr5,gr6
244 bne icc0,#2,1b
245
246 # need a temporary mapping for the current physical address we are
247 # using between time MMU is enabled and jump to virtual address is
248 # made.
249 sethi.p %hi(0x00000000),gr4
250 setlo %lo(0x00000000),gr4 ; physical address
251 setlos #xAMPRx_L|xAMPRx_M|xAMPRx_SS_256Mb|xAMPRx_S_KERNEL|xAMPRx_V,gr5
252 or gr4,gr5,gr5
253
254 movsg cxnr,gr13
255 or gr4,gr13,gr4
256
257 movgs gr4,iamlr1 ; mapped from real address 0
258 movgs gr5,iampr1 ; cached kernel memory at 0x00000000
2592:
260#endif
261
262 lddi @(gr11,#0),gr4 ; hsr0, psr
263 lddi @(gr11,#8),gr6 ; isr, lr
264 movgs gr4,hsr0
265 bar
266
267#ifdef CONFIG_MMU
268 sethi.p %hi(1f),gr11
269 setlo %lo(1f),gr11
270 jmpl @(gr11,gr0)
2711:
272 movgs gr0,iampr1 ; get rid of temporary mapping
273#endif
274 movgs gr5,psr
275 movgs gr6,isr
276
277 #----------------------------------------------------
278 # unlock the icache which was locked before going to sleep
279 #----------------------------------------------------
280 li __icache_lock_start,gr3
281 li __icache_lock_end,gr4
2821: icul gr3
283 addi gr3,#L1_CACHE_BYTES,gr3
284 cmp gr4,gr3,icc0
285 bhi icc0,#0,1b
286
287 #----------------------------------------------------
288 # back to business as usual
289 #----------------------------------------------------
290 jmpl @(gr7,gr0) ;
291
292#endif /* CONFIG_PM */
293
294###############################################################################
295#
296# CPU core sleep mode routine
297#
298###############################################################################
299 .globl frv_cpu_core_sleep
300 .type frv_cpu_core_sleep,@function
301frv_cpu_core_sleep:
302
303 # Preload into icache.
304 li #__core_sleep_icache_lock_start,gr3
305 li #__core_sleep_icache_lock_end,gr4
306
3071: icpl gr3,gr0,#1
308 addi gr3,#L1_CACHE_BYTES,gr3
309 cmp gr4,gr3,icc0
310 bhi icc0,#0,1b
311
312 bra __core_sleep_icache_lock_start
313
314 .balign L1_CACHE_BYTES
315__core_sleep_icache_lock_start:
316
317 # (1) Set the PSR register ET bit to 0 to disable interrupts.
318 movsg psr,gr8
319 andi.p gr8,#~(PSR_PIL),gr8
320 andi gr8,#~(PSR_ET),gr4
321 movgs gr4,psr
322
323#if 0 // Fujitsu recommend to skip this and will update docs.
324 # (2) Set '1' to all bits in the MASK register of the interrupt
325 # controller and mask interrupts.
326 sethi.p %hi(__addr_MASK),gr9
327 setlo %lo(__addr_MASK),gr9
328 sethi.p %hi(0xffff0000),gr4
329 setlo %lo(0xffff0000),gr4
330 ldi @(gr9,#0),gr10
331 sti gr4,@(gr9,#0)
332#endif
333 # (3) Flush all data in the cache using the DCEF instruction.
334 dcef @(gr0,gr0),#1
335
336 # (4) Execute the memory barrier instruction
337 membar
338
339 # (5) Set the GPIO register so that the IRQ[3:0] pins become valid, as required.
340 # (6) Set the clock mode (CLKC register) as required.
341 # - At this time, also set the CLKC register P0 bit.
342 # (7) Set the HSR0 register PDM field to 001 .
343 movsg hsr0,gr4
344 ori gr4,HSR0_PDM_CORE_SLEEP,gr4
345 movgs gr4,hsr0
346
347 # (8) Execute NOP 32 times.
348 .rept 32
349 nop
350 .endr
351
352#if 0 // Fujitsu recommend to skip this and will update docs.
353 # (9) Release the interrupt mask setting of the MASK register of the
354 # interrupt controller if necessary.
355 sti gr10,@(gr9,#0)
356 membar
357#endif
358
359 # (10) Set the PSR register ET bit to 1 to enable interrupts.
360 movgs gr8,psr
361
362__core_sleep_icache_lock_end:
363
364 # Unlock from icache
365 li __core_sleep_icache_lock_start,gr3
366 li __core_sleep_icache_lock_end,gr4
3671: icul gr3
368 addi gr3,#L1_CACHE_BYTES,gr3
369 cmp gr4,gr3,icc0
370 bhi icc0,#0,1b
371
372 bralr
373
374 .size frv_cpu_core_sleep, .-frv_cpu_core_sleep