Full support for Ginger Console
[linux-ginger.git] / arch / mips / alchemy / common / sleeper.S
blob4f4b16741d12e61e57ffb24f791e0fdfbeef1a9d
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
25 /* Save all of the processor general registers and go to sleep.
26  * A wakeup condition will get us back here to restore the registers.
27  */
28 LEAF(au1xxx_save_and_sleep)
29         subu    sp, PT_SIZE
30         sw      $1, PT_R1(sp)
31         sw      $2, PT_R2(sp)
32         sw      $3, PT_R3(sp)
33         sw      $4, PT_R4(sp)
34         sw      $5, PT_R5(sp)
35         sw      $6, PT_R6(sp)
36         sw      $7, PT_R7(sp)
37         sw      $16, PT_R16(sp)
38         sw      $17, PT_R17(sp)
39         sw      $18, PT_R18(sp)
40         sw      $19, PT_R19(sp)
41         sw      $20, PT_R20(sp)
42         sw      $21, PT_R21(sp)
43         sw      $22, PT_R22(sp)
44         sw      $23, PT_R23(sp)
45         sw      $26, PT_R26(sp)
46         sw      $27, PT_R27(sp)
47         sw      $28, PT_R28(sp)
48         sw      $30, PT_R30(sp)
49         sw      $31, PT_R31(sp)
50         mfc0    k0, CP0_STATUS
51         sw      k0, 0x20(sp)
52         mfc0    k0, CP0_CONTEXT
53         sw      k0, 0x1c(sp)
54         mfc0    k0, CP0_PAGEMASK
55         sw      k0, 0x18(sp)
56         mfc0    k0, CP0_CONFIG
57         sw      k0, 0x14(sp)
59         /* flush caches to make sure context is in memory */
60         la      t1, __flush_cache_all
61         lw      t0, 0(t1)
62         jalr    t0
63          nop
65         /* Now set up the scratch registers so the boot rom will
66          * return to this point upon wakeup.
67          * sys_scratch0 : SP
68          * sys_scratch1 : RA
69          */
70         lui     t3, 0xb190              /* sys_xxx */
71         sw      sp, 0x0018(t3)
72         la      k0, 3f                  /* resume path */
73         sw      k0, 0x001c(t3)
75         /* Put SDRAM into self refresh:  Preload instructions into cache,
76          * issue a precharge, auto/self refresh, then sleep commands to it.
77          */
78         la      t0, 1f
79         .set    mips3
80         cache   0x14, 0(t0)
81         cache   0x14, 32(t0)
82         cache   0x14, 64(t0)
83         cache   0x14, 96(t0)
84         .set    mips0
86 1:      lui     a0, 0xb400              /* mem_xxx */
87 #if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100) || \
88     defined(CONFIG_SOC_AU1500)
89         sw      zero, 0x001c(a0)        /* Precharge */
90         sync
91         sw      zero, 0x0020(a0)        /* Auto Refresh */
92         sync
93         sw      zero, 0x0030(a0)        /* Sleep */
94         sync
95 #endif
97 #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
98         sw      zero, 0x08c0(a0)        /* Precharge */
99         sync
100         sw      zero, 0x08d0(a0)        /* Self Refresh */
101         sync
103         /* wait for sdram to enter self-refresh mode */
104         lui     t0, 0x0100
105 2:      lw      t1, 0x0850(a0)          /* mem_sdstat */
106         and     t2, t1, t0
107         beq     t2, zero, 2b
108          nop
110         /* disable SDRAM clocks */
111         lui     t0, 0xcfff
112         ori     t0, t0, 0xffff
113         lw      t1, 0x0840(a0)          /* mem_sdconfiga */
114         and     t1, t0, t1              /* clear CE[1:0] */
115         sw      t1, 0x0840(a0)          /* mem_sdconfiga */
116         sync
117 #endif
119         /* put power supply and processor to sleep */
120         sw      zero, 0x0078(t3)        /* sys_slppwr */
121         sync
122         sw      zero, 0x007c(t3)        /* sys_sleep */
123         sync
124         nop
125         nop
126         nop
127         nop
128         nop
129         nop
130         nop
131         nop
133         /* This is where we return upon wakeup.
134          * Reload all of the registers and return.
135          */
136 3:      lw      k0, 0x20(sp)
137         mtc0    k0, CP0_STATUS
138         lw      k0, 0x1c(sp)
139         mtc0    k0, CP0_CONTEXT
140         lw      k0, 0x18(sp)
141         mtc0    k0, CP0_PAGEMASK
142         lw      k0, 0x14(sp)
143         mtc0    k0, CP0_CONFIG
145         /* We need to catch the early Alchemy SOCs with
146          * the write-only Config[OD] bit and set it back to one...
147          */
148         jal     au1x00_fixup_config_od
149          nop
150         lw      $1, PT_R1(sp)
151         lw      $2, PT_R2(sp)
152         lw      $3, PT_R3(sp)
153         lw      $4, PT_R4(sp)
154         lw      $5, PT_R5(sp)
155         lw      $6, PT_R6(sp)
156         lw      $7, PT_R7(sp)
157         lw      $16, PT_R16(sp)
158         lw      $17, PT_R17(sp)
159         lw      $18, PT_R18(sp)
160         lw      $19, PT_R19(sp)
161         lw      $20, PT_R20(sp)
162         lw      $21, PT_R21(sp)
163         lw      $22, PT_R22(sp)
164         lw      $23, PT_R23(sp)
165         lw      $26, PT_R26(sp)
166         lw      $27, PT_R27(sp)
167         lw      $28, PT_R28(sp)
168         lw      $30, PT_R30(sp)
169         lw      $31, PT_R31(sp)
170         jr      ra
171          addiu  sp, PT_SIZE
172 END(au1xxx_save_and_sleep)