spi-topcliff-pch: supports a spi mode setup and bit order setup by IO control
[zen-stable.git] / arch / mips / alchemy / common / sleeper.S
blobc7bcc7e5c822bb571164e27fcfa284838cc92c38
1 /*
2  * Copyright 2002 Embedded Edge, LLC
3  * Author: dan@embeddededge.com
4  *
5  * Sleep helper for Au1xxx sleep mode.
6  *
7  * This program is free software; you can redistribute  it and/or modify it
8  * under  the terms of  the GNU General  Public License as published by the
9  * Free Software Foundation;  either version 2 of the  License, or (at your
10  * option) any later version.
11  */
13 #include <asm/asm.h>
14 #include <asm/mipsregs.h>
15 #include <asm/regdef.h>
16 #include <asm/stackframe.h>
18         .extern __flush_cache_all
20         .text
21         .set noreorder
22         .set noat
23         .align  5
26 /* preparatory stuff */
27 .macro  SETUP_SLEEP
28         subu    sp, PT_SIZE
29         sw      $1, PT_R1(sp)
30         sw      $2, PT_R2(sp)
31         sw      $3, PT_R3(sp)
32         sw      $4, PT_R4(sp)
33         sw      $5, PT_R5(sp)
34         sw      $6, PT_R6(sp)
35         sw      $7, PT_R7(sp)
36         sw      $16, PT_R16(sp)
37         sw      $17, PT_R17(sp)
38         sw      $18, PT_R18(sp)
39         sw      $19, PT_R19(sp)
40         sw      $20, PT_R20(sp)
41         sw      $21, PT_R21(sp)
42         sw      $22, PT_R22(sp)
43         sw      $23, PT_R23(sp)
44         sw      $26, PT_R26(sp)
45         sw      $27, PT_R27(sp)
46         sw      $28, PT_R28(sp)
47         sw      $30, PT_R30(sp)
48         sw      $31, PT_R31(sp)
49         mfc0    k0, CP0_STATUS
50         sw      k0, 0x20(sp)
51         mfc0    k0, CP0_CONTEXT
52         sw      k0, 0x1c(sp)
53         mfc0    k0, CP0_PAGEMASK
54         sw      k0, 0x18(sp)
55         mfc0    k0, CP0_CONFIG
56         sw      k0, 0x14(sp)
58         /* flush caches to make sure context is in memory */
59         la      t1, __flush_cache_all
60         lw      t0, 0(t1)
61         jalr    t0
62          nop
64         /* Now set up the scratch registers so the boot rom will
65          * return to this point upon wakeup.
66          * sys_scratch0 : SP
67          * sys_scratch1 : RA
68          */
69         lui     t3, 0xb190              /* sys_xxx */
70         sw      sp, 0x0018(t3)
71         la      k0, alchemy_sleep_wakeup        /* resume path */
72         sw      k0, 0x001c(t3)
73 .endm
75 .macro  DO_SLEEP
76         /* put power supply and processor to sleep */
77         sw      zero, 0x0078(t3)        /* sys_slppwr */
78         sync
79         sw      zero, 0x007c(t3)        /* sys_sleep */
80         sync
81         nop
82         nop
83         nop
84         nop
85         nop
86         nop
87         nop
88         nop
89 .endm
91 /* sleep code for Au1000/Au1100/Au1500 memory controller type */
92 LEAF(alchemy_sleep_au1000)
94         SETUP_SLEEP
96         /* cache following instructions, as memory gets put to sleep */
97         la      t0, 1f
98         .set    mips3
99         cache   0x14, 0(t0)
100         cache   0x14, 32(t0)
101         cache   0x14, 64(t0)
102         cache   0x14, 96(t0)
103         .set    mips0
105 1:      lui     a0, 0xb400              /* mem_xxx */
106         sw      zero, 0x001c(a0)        /* Precharge */
107         sync
108         sw      zero, 0x0020(a0)        /* Auto Refresh */
109         sync
110         sw      zero, 0x0030(a0)        /* Sleep */
111         sync
113         DO_SLEEP
115 END(alchemy_sleep_au1000)
117 /* sleep code for Au1550/Au1200 memory controller type */
118 LEAF(alchemy_sleep_au1550)
120         SETUP_SLEEP
122         /* cache following instructions, as memory gets put to sleep */
123         la      t0, 1f
124         .set    mips3
125         cache   0x14, 0(t0)
126         cache   0x14, 32(t0)
127         cache   0x14, 64(t0)
128         cache   0x14, 96(t0)
129         .set    mips0
131 1:      lui     a0, 0xb400              /* mem_xxx */
132         sw      zero, 0x08c0(a0)        /* Precharge */
133         sync
134         sw      zero, 0x08d0(a0)        /* Self Refresh */
135         sync
137         /* wait for sdram to enter self-refresh mode */
138         lui     t0, 0x0100
139 2:      lw      t1, 0x0850(a0)          /* mem_sdstat */
140         and     t2, t1, t0
141         beq     t2, zero, 2b
142          nop
144         /* disable SDRAM clocks */
145         lui     t0, 0xcfff
146         ori     t0, t0, 0xffff
147         lw      t1, 0x0840(a0)          /* mem_sdconfiga */
148         and     t1, t0, t1              /* clear CE[1:0] */
149         sw      t1, 0x0840(a0)          /* mem_sdconfiga */
150         sync
152         DO_SLEEP
154 END(alchemy_sleep_au1550)
156 /* sleepcode for Au1300 memory controller type */
157 LEAF(alchemy_sleep_au1300)
159         SETUP_SLEEP
161         /* cache following instructions, as memory gets put to sleep */
162         la      t0, 2f
163         la      t1, 4f
164         subu    t2, t1, t0
166         .set    mips3
168 1:      cache   0x14, 0(t0)
169         subu    t2, t2, 32
170         bgez    t2, 1b
171          addu   t0, t0, 32
173         .set    mips0
175 2:      lui     a0, 0xb400              /* mem_xxx */
177         /* disable all ports in mem_sdportcfga */
178         sw      zero, 0x868(a0)         /* mem_sdportcfga */
179         sync
181         /* disable ODT */
182         li      t0, 0x03010000
183         sw      t0, 0x08d8(a0)          /* mem_sdcmd0 */
184         sw      t0, 0x08dc(a0)          /* mem_sdcmd1 */
185         sync
187         /* precharge */
188         li      t0, 0x23000400
189         sw      t0, 0x08dc(a0)          /* mem_sdcmd1 */
190         sw      t0, 0x08d8(a0)          /* mem_sdcmd0 */
191         sync
193         /* auto refresh */
194         sw      zero, 0x08c8(a0)        /* mem_sdautoref */
195         sync
197         /* block access to the DDR */
198         lw      t0, 0x0848(a0)          /* mem_sdconfigb */
199         li      t1, (1 << 7 | 0x3F)
200         or      t0, t0, t1
201         sw      t0, 0x0848(a0)          /* mem_sdconfigb */
202         sync
204         /* issue the Self Refresh command */
205         li      t0, 0x10000000
206         sw      t0, 0x08dc(a0)          /* mem_sdcmd1 */
207         sw      t0, 0x08d8(a0)          /* mem_sdcmd0 */
208         sync
210         /* wait for sdram to enter self-refresh mode */
211         lui     t0, 0x0300
212 3:      lw      t1, 0x0850(a0)          /* mem_sdstat */
213         and     t2, t1, t0
214         bne     t2, t0, 3b
215          nop
217         /* disable SDRAM clocks */
218         li      t0, ~(3<<28)
219         lw      t1, 0x0840(a0)          /* mem_sdconfiga */
220         and     t1, t1, t0              /* clear CE[1:0] */
221         sw      t1, 0x0840(a0)          /* mem_sdconfiga */
222         sync
224         DO_SLEEP
227 END(alchemy_sleep_au1300)
230         /* This is where we return upon wakeup.
231          * Reload all of the registers and return.
232          */
233 LEAF(alchemy_sleep_wakeup)
234         lw      k0, 0x20(sp)
235         mtc0    k0, CP0_STATUS
236         lw      k0, 0x1c(sp)
237         mtc0    k0, CP0_CONTEXT
238         lw      k0, 0x18(sp)
239         mtc0    k0, CP0_PAGEMASK
240         lw      k0, 0x14(sp)
241         mtc0    k0, CP0_CONFIG
243         /* We need to catch the early Alchemy SOCs with
244          * the write-only Config[OD] bit and set it back to one...
245          */
246         jal     au1x00_fixup_config_od
247          nop
248         lw      $1, PT_R1(sp)
249         lw      $2, PT_R2(sp)
250         lw      $3, PT_R3(sp)
251         lw      $4, PT_R4(sp)
252         lw      $5, PT_R5(sp)
253         lw      $6, PT_R6(sp)
254         lw      $7, PT_R7(sp)
255         lw      $16, PT_R16(sp)
256         lw      $17, PT_R17(sp)
257         lw      $18, PT_R18(sp)
258         lw      $19, PT_R19(sp)
259         lw      $20, PT_R20(sp)
260         lw      $21, PT_R21(sp)
261         lw      $22, PT_R22(sp)
262         lw      $23, PT_R23(sp)
263         lw      $26, PT_R26(sp)
264         lw      $27, PT_R27(sp)
265         lw      $28, PT_R28(sp)
266         lw      $30, PT_R30(sp)
267         lw      $31, PT_R31(sp)
268         jr      ra
269          addiu  sp, PT_SIZE
270 END(alchemy_sleep_wakeup)