Linux 3.2.23
[linux/fpc-iii.git] / arch / unicore32 / kernel / sleep.S
blob607a104aec595328e6a7cd4af3dc6092e1e36683
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  */
14 #include <linux/linkage.h>
15 #include <asm/assembler.h>
16 #include <mach/hardware.h>
18                 .text
20 pkunity_cpu_save_cp:
22         @ get coprocessor registers
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
29         @ store them plus current virtual stack ptr on stack
30         mov     r6, sp
31         stm.w   (r3 - r6), [sp-]
33         mov     pc, lr
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
45  * puv3_cpu_suspend()
46  *
47  * Forces CPU into sleep state.
48  *
49  * r0 = value for PWRMODE M field for desired sleep state
50  */
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
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
66         b.l     pkunity_cpu_save_sp
68         @ clean data cache
69         mov     r1, #0
70         movc    p0.c5, r1, #14
71         nop
72         nop
73         nop
74         nop
78         @ DDR2 BaseAddr
79         ldw     r0, =(PKUNITY_DDR2CTRL_BASE)
81         @ PM BaseAddr
82         ldw     r1, =(PKUNITY_PM_BASE)
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
91         @ set wake up source
92         movl    r8, #0x800001ff         @ epip4d
93         stw     r8, [r1+], #0xc
95         @ set PGSR
96         movl    r5, #0x40000
97         stw     r5, [r1+], #0x10
99         @ prepare DDR2 refresh settings
100         ldw     r5, [r0+], #0x24
101         or      r5, r5, #0x00000001
103         @ prepare PMCR for PLL changing
104         movl    r6, #0xc
106         @ prepare for closing PLL
107         movl    r7, #0x1
109         @ prepare sleep mode
110         mov     r8, #0x1
112 @       movl    r0, 0x11111111
113 @       put_word_ocd r0
114         b       pkunity_cpu_do_suspend
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
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
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
148  * puv3_cpu_resume()
150  * entry point from bootloader into kernel during resume
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  */
159         .data
160         .align 5
161 ENTRY(puv3_cpu_resume)
162 @       movl    r0, 0x20202020
163 @       put_word_ocd r0
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
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
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
185 sleep_save_sp:
186         .word   0                               @ preserve stack phys ptr here
188         .text
189 resume_after_mmu:
190 @       movl    r0, 0x30303030
191 @       put_word_ocd r0
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