GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / arch / frv / kernel / sleep.S
blobf373dd7d72b712fb9445dc503b41304f603b163b
1 /* sleep.S: power saving mode entry
2  *
3  * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
4  * Written by David Woodhouse (dwmw2@infradead.org)
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  */
13 #include <linux/sys.h>
14 #include <linux/linkage.h>
15 #include <asm/setup.h>
16 #include <asm/segment.h>
17 #include <asm/page.h>
18 #include <asm/ptrace.h>
19 #include <asm/errno.h>
20 #include <asm/cache.h>
21 #include <asm/spr-regs.h>
23 #define __addr_MASK     0xfeff9820      /* interrupt controller mask */
25 #define __addr_FR55X_DRCN       0xfeff0218      /* Address of DRCN register */
26 #define FR55X_DSTS_OFFSET       -4              /* Offset from DRCN to DSTS */
27 #define FR55X_SDRAMC_DSTS_SSI   0x00000002      /* indicates that the SDRAM is in self-refresh mode */
29 #define __addr_FR4XX_DRCN       0xfe000430      /* Address of DRCN register */
30 #define FR4XX_DSTS_OFFSET       -8              /* Offset from DRCN to DSTS */
31 #define FR4XX_SDRAMC_DSTS_SSI   0x00000001      /* indicates that the SDRAM is in self-refresh mode */
33 #define SDRAMC_DRCN_SR  0x00000001      /* transition SDRAM into self-refresh mode */
35         .section        .bss
36         .balign         8
37         .globl          __sleep_save_area
38 __sleep_save_area:
39         .space          16
42         .text
43         .balign         4
45 .macro li v r
46         sethi.p         %hi(\v),\r
47         setlo           %lo(\v),\r
48 .endm
50 #ifdef CONFIG_PM
51 ###############################################################################
53 # CPU suspension routine
54 # - void frv_cpu_suspend(unsigned long pdm_mode)
56 ###############################################################################
57         .globl          frv_cpu_suspend
58         .type           frv_cpu_suspend,@function
59 frv_cpu_suspend:
61         #----------------------------------------------------
62         # save hsr0, psr, isr, and lr for resume code
63         #----------------------------------------------------
64         li              __sleep_save_area,gr11
66         movsg           hsr0,gr4
67         movsg           psr,gr5
68         movsg           isr,gr6
69         movsg           lr,gr7
70         stdi            gr4,@(gr11,#0)
71         stdi            gr6,@(gr11,#8)
73         # store the return address from sleep in GR14, and its complement in GR13 as a check
74         li              __ramboot_resume,gr14
75 #ifdef CONFIG_MMU
76         # Resume via RAMBOOT# will turn MMU off, so bootloader needs a physical address.
77         sethi.p         %hi(__page_offset),gr13
78         setlo           %lo(__page_offset),gr13
79         sub             gr14,gr13,gr14
80 #endif
81         not             gr14,gr13
83         #----------------------------------------------------
84         # preload and lock into icache that code which may have to run
85         # when dram is in self-refresh state.
86         #----------------------------------------------------
87         movsg           hsr0, gr3
88         li              HSR0_ICE,gr4
89         or              gr3,gr4,gr3
90         movgs           gr3,hsr0
91         or              gr3,gr8,gr7     // add the sleep bits for later
93         li              #__icache_lock_start,gr3
94         li              #__icache_lock_end,gr4
95 1:      icpl            gr3,gr0,#1
96         addi            gr3,#L1_CACHE_BYTES,gr3
97         cmp             gr4,gr3,icc0
98         bhi             icc0,#0,1b
100         # disable exceptions
101         movsg           psr,gr8
102         andi.p          gr8,#~PSR_PIL,gr8
103         andi            gr8,~PSR_ET,gr8
104         movgs           gr8,psr
105         ori             gr8,#PSR_ET,gr8
107         srli            gr8,#28,gr4
108         subicc          gr4,#3,gr0,icc0
109         beq             icc0,#0,1f
110         # FR4xx
111         li              __addr_FR4XX_DRCN,gr4
112         li              FR4XX_SDRAMC_DSTS_SSI,gr5
113         li              FR4XX_DSTS_OFFSET,gr6
114         bra             __icache_lock_start
116         # FR5xx
117         li              __addr_FR55X_DRCN,gr4
118         li              FR55X_SDRAMC_DSTS_SSI,gr5
119         li              FR55X_DSTS_OFFSET,gr6
120         bra             __icache_lock_start
122         .size           frv_cpu_suspend, .-frv_cpu_suspend
125 # the final part of the sleep sequence...
126 # - we want it to be be cacheline aligned so we can lock it into the icache easily
127 #  On entry:    gr7 holds desired hsr0 sleep value
128 #               gr8 holds desired psr sleep value
130         .balign         L1_CACHE_BYTES
131         .type           __icache_lock_start,@function
132 __icache_lock_start:
134         #----------------------------------------------------
135         # put SDRAM in self-refresh mode
136         #----------------------------------------------------
138         # Flush all data in the cache using the DCEF instruction.
139         dcef            @(gr0,gr0),#1
141         # Stop DMAC transfer
143         # Execute dummy load from SDRAM
144         ldi             @(gr11,#0),gr11
146         # put the SDRAM into self-refresh mode
147         ld              @(gr4,gr0),gr11
148         ori             gr11,#SDRAMC_DRCN_SR,gr11
149         st              gr11,@(gr4,gr0)
150         membar
152         # wait for SDRAM to reach self-refresh mode
153 1:      ld              @(gr4,gr6),gr11
154         andcc           gr11,gr5,gr11,icc0
155         beq             icc0,#0,1b
157         #  Set the GPIO register so that the IRQ[3:0] pins become valid, as required.
158         #  Set the clock mode (CLKC register) as required.
159         #     - At this time, also set the CLKC register P0 bit.
161         # Set the HSR0 register PDM field.
162         movgs           gr7,hsr0
164         # Execute NOP 32 times.
165         .rept           32
166         nop
167         .endr
170         # Set the PSR register ET bit to 1 to enable interrupts.
171         movgs           gr8,psr
173         ###################################################
174         # this is only reached if waking up via interrupt
175         ###################################################
177         # Execute NOP 32 times.
178         .rept           32
179         nop
180         .endr
182         #----------------------------------------------------
183         # wake SDRAM from self-refresh mode
184         #----------------------------------------------------
185         ld              @(gr4,gr0),gr11
186         andi            gr11,#~SDRAMC_DRCN_SR,gr11
187         st              gr11,@(gr4,gr0)
188         membar
190         ld              @(gr4,gr6),gr11 // Wait for it to come back...
191         andcc           gr11,gr5,gr0,icc0
192         bne             icc0,0,2b
194         # wait for the SDRAM to stabilise
195         li              0x0100000,gr3
196 3:      subicc          gr3,#1,gr3,icc0
197         bne             icc0,#0,3b
199         # now that DRAM is back, this is the end of the code which gets
200         # locked in icache.
201 __icache_lock_end:
202         .size           __icache_lock_start, .-__icache_lock_start
204         # Fall-through to the RAMBOOT# wakeup path
206 ###############################################################################
208 #  resume from suspend re-entry point reached via RAMBOOT# and bootloader
210 ###############################################################################
211 __ramboot_resume:
213         #----------------------------------------------------
214         # restore hsr0, psr, isr, and leave saved lr in gr7
215         #----------------------------------------------------
216         li              __sleep_save_area,gr11
217 #ifdef CONFIG_MMU
218         movsg           hsr0,gr4
219         sethi.p         %hi(HSR0_EXMMU),gr3
220         setlo           %lo(HSR0_EXMMU),gr3
221         andcc           gr3,gr4,gr0,icc0
222         bne             icc0,#0,2f
224         # need to use physical address
225         sethi.p         %hi(__page_offset),gr3
226         setlo           %lo(__page_offset),gr3
227         sub             gr11,gr3,gr11
229         # flush all tlb entries
230         setlos          #64,gr4
231         setlos.p        #PAGE_SIZE,gr5
232         setlos          #0,gr6
234         tlbpr           gr6,gr0,#6,#0
235         subicc.p        gr4,#1,gr4,icc0
236         add             gr6,gr5,gr6
237         bne             icc0,#2,1b
239         # need a temporary mapping for the current physical address we are
240         # using between time MMU is enabled and jump to virtual address is
241         # made.
242         sethi.p         %hi(0x00000000),gr4
243         setlo           %lo(0x00000000),gr4             ; physical address
244         setlos          #xAMPRx_L|xAMPRx_M|xAMPRx_SS_256Mb|xAMPRx_S_KERNEL|xAMPRx_V,gr5
245         or              gr4,gr5,gr5
247         movsg           cxnr,gr13
248         or              gr4,gr13,gr4
250         movgs           gr4,iamlr1                      ; mapped from real address 0
251         movgs           gr5,iampr1                      ; cached kernel memory at 0x00000000
253 #endif
255         lddi            @(gr11,#0),gr4 ; hsr0, psr
256         lddi            @(gr11,#8),gr6 ; isr, lr
257         movgs           gr4,hsr0
258         bar
260 #ifdef CONFIG_MMU
261         sethi.p         %hi(1f),gr11
262         setlo           %lo(1f),gr11
263         jmpl            @(gr11,gr0)
265         movgs           gr0,iampr1      ; get rid of temporary mapping
266 #endif
267         movgs           gr5,psr
268         movgs           gr6,isr
270         #----------------------------------------------------
271         # unlock the icache which was locked before going to sleep
272         #----------------------------------------------------
273         li              __icache_lock_start,gr3
274         li              __icache_lock_end,gr4
275 1:      icul            gr3
276         addi            gr3,#L1_CACHE_BYTES,gr3
277         cmp             gr4,gr3,icc0
278         bhi             icc0,#0,1b
280         #----------------------------------------------------
281         # back to business as usual
282         #----------------------------------------------------
283         jmpl            @(gr7,gr0)              ;
285 #endif /* CONFIG_PM */
287 ###############################################################################
289 # CPU core sleep mode routine
291 ###############################################################################
292         .globl          frv_cpu_core_sleep
293         .type           frv_cpu_core_sleep,@function
294 frv_cpu_core_sleep:
296         # Preload into icache.
297         li              #__core_sleep_icache_lock_start,gr3
298         li              #__core_sleep_icache_lock_end,gr4
300 1:      icpl            gr3,gr0,#1
301         addi            gr3,#L1_CACHE_BYTES,gr3
302         cmp             gr4,gr3,icc0
303         bhi             icc0,#0,1b
305         bra     __core_sleep_icache_lock_start
307         .balign L1_CACHE_BYTES
308 __core_sleep_icache_lock_start:
310         # (1) Set the PSR register ET bit to 0 to disable interrupts.
311         movsg           psr,gr8
312         andi.p          gr8,#~(PSR_PIL),gr8
313         andi            gr8,#~(PSR_ET),gr4
314         movgs           gr4,psr
316         # (3) Flush all data in the cache using the DCEF instruction.
317         dcef            @(gr0,gr0),#1
319         # (4) Execute the memory barrier instruction
320         membar
322         # (5) Set the GPIO register so that the IRQ[3:0] pins become valid, as required.
323         # (6) Set the clock mode (CLKC register) as required.
324         #     - At this time, also set the CLKC register P0 bit.
325         # (7) Set the HSR0 register PDM field to  001 .
326         movsg           hsr0,gr4
327         ori             gr4,HSR0_PDM_CORE_SLEEP,gr4
328         movgs           gr4,hsr0
330         # (8) Execute NOP 32 times.
331         .rept           32
332         nop
333         .endr
336         # (10) Set the PSR register ET bit to 1 to enable interrupts.
337         movgs           gr8,psr
339 __core_sleep_icache_lock_end:
341         # Unlock from icache
342         li      __core_sleep_icache_lock_start,gr3
343         li      __core_sleep_icache_lock_end,gr4
344 1:      icul            gr3
345         addi            gr3,#L1_CACHE_BYTES,gr3
346         cmp             gr4,gr3,icc0
347         bhi             icc0,#0,1b
349         bralr
351         .size           frv_cpu_core_sleep, .-frv_cpu_core_sleep