diff options
Diffstat (limited to 'arch/mips/alchemy')
-rw-r--r-- | arch/mips/alchemy/common/power.c | 12 | ||||
-rw-r--r-- | arch/mips/alchemy/common/sleeper.S | 81 |
2 files changed, 62 insertions, 31 deletions
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c index 14eb8c492da2..5ef06a164a82 100644 --- a/arch/mips/alchemy/common/power.c +++ b/arch/mips/alchemy/common/power.c | |||
@@ -193,9 +193,15 @@ static void restore_core_regs(void) | |||
193 | 193 | ||
194 | void au_sleep(void) | 194 | void au_sleep(void) |
195 | { | 195 | { |
196 | save_core_regs(); | 196 | int cpuid = alchemy_get_cputype(); |
197 | au1xxx_save_and_sleep(); | 197 | if (cpuid != ALCHEMY_CPU_UNKNOWN) { |
198 | restore_core_regs(); | 198 | save_core_regs(); |
199 | if (cpuid <= ALCHEMY_CPU_AU1500) | ||
200 | alchemy_sleep_au1000(); | ||
201 | else if (cpuid <= ALCHEMY_CPU_AU1200) | ||
202 | alchemy_sleep_au1550(); | ||
203 | restore_core_regs(); | ||
204 | } | ||
199 | } | 205 | } |
200 | 206 | ||
201 | #endif /* CONFIG_PM */ | 207 | #endif /* CONFIG_PM */ |
diff --git a/arch/mips/alchemy/common/sleeper.S b/arch/mips/alchemy/common/sleeper.S index 4f4b16741d12..77f3c743b716 100644 --- a/arch/mips/alchemy/common/sleeper.S +++ b/arch/mips/alchemy/common/sleeper.S | |||
@@ -22,10 +22,9 @@ | |||
22 | .set noat | 22 | .set noat |
23 | .align 5 | 23 | .align 5 |
24 | 24 | ||
25 | /* Save all of the processor general registers and go to sleep. | 25 | |
26 | * A wakeup condition will get us back here to restore the registers. | 26 | /* preparatory stuff */ |
27 | */ | 27 | .macro SETUP_SLEEP |
28 | LEAF(au1xxx_save_and_sleep) | ||
29 | subu sp, PT_SIZE | 28 | subu sp, PT_SIZE |
30 | sw $1, PT_R1(sp) | 29 | sw $1, PT_R1(sp) |
31 | sw $2, PT_R2(sp) | 30 | sw $2, PT_R2(sp) |
@@ -69,12 +68,32 @@ LEAF(au1xxx_save_and_sleep) | |||
69 | */ | 68 | */ |
70 | lui t3, 0xb190 /* sys_xxx */ | 69 | lui t3, 0xb190 /* sys_xxx */ |
71 | sw sp, 0x0018(t3) | 70 | sw sp, 0x0018(t3) |
72 | la k0, 3f /* resume path */ | 71 | la k0, alchemy_sleep_wakeup /* resume path */ |
73 | sw k0, 0x001c(t3) | 72 | sw k0, 0x001c(t3) |
73 | .endm | ||
74 | 74 | ||
75 | /* Put SDRAM into self refresh: Preload instructions into cache, | 75 | .macro DO_SLEEP |
76 | * issue a precharge, auto/self refresh, then sleep commands to it. | 76 | /* put power supply and processor to sleep */ |
77 | */ | 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 | ||
90 | |||
91 | /* sleep code for Au1000/Au1100/Au1500 memory controller type */ | ||
92 | LEAF(alchemy_sleep_au1000) | ||
93 | |||
94 | SETUP_SLEEP | ||
95 | |||
96 | /* cache following instructions, as memory gets put to sleep */ | ||
78 | la t0, 1f | 97 | la t0, 1f |
79 | .set mips3 | 98 | .set mips3 |
80 | cache 0x14, 0(t0) | 99 | cache 0x14, 0(t0) |
@@ -84,17 +103,32 @@ LEAF(au1xxx_save_and_sleep) | |||
84 | .set mips0 | 103 | .set mips0 |
85 | 104 | ||
86 | 1: lui a0, 0xb400 /* mem_xxx */ | 105 | 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 */ | 106 | sw zero, 0x001c(a0) /* Precharge */ |
90 | sync | 107 | sync |
91 | sw zero, 0x0020(a0) /* Auto Refresh */ | 108 | sw zero, 0x0020(a0) /* Auto Refresh */ |
92 | sync | 109 | sync |
93 | sw zero, 0x0030(a0) /* Sleep */ | 110 | sw zero, 0x0030(a0) /* Sleep */ |
94 | sync | 111 | sync |
95 | #endif | ||
96 | 112 | ||
97 | #if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) | 113 | DO_SLEEP |
114 | |||
115 | END(alchemy_sleep_au1000) | ||
116 | |||
117 | /* sleep code for Au1550/Au1200 memory controller type */ | ||
118 | LEAF(alchemy_sleep_au1550) | ||
119 | |||
120 | SETUP_SLEEP | ||
121 | |||
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 | ||
130 | |||
131 | 1: lui a0, 0xb400 /* mem_xxx */ | ||
98 | sw zero, 0x08c0(a0) /* Precharge */ | 132 | sw zero, 0x08c0(a0) /* Precharge */ |
99 | sync | 133 | sync |
100 | sw zero, 0x08d0(a0) /* Self Refresh */ | 134 | sw zero, 0x08d0(a0) /* Self Refresh */ |
@@ -114,26 +148,17 @@ LEAF(au1xxx_save_and_sleep) | |||
114 | and t1, t0, t1 /* clear CE[1:0] */ | 148 | and t1, t0, t1 /* clear CE[1:0] */ |
115 | sw t1, 0x0840(a0) /* mem_sdconfiga */ | 149 | sw t1, 0x0840(a0) /* mem_sdconfiga */ |
116 | sync | 150 | sync |
117 | #endif | ||
118 | 151 | ||
119 | /* put power supply and processor to sleep */ | 152 | DO_SLEEP |
120 | sw zero, 0x0078(t3) /* sys_slppwr */ | 153 | |
121 | sync | 154 | END(alchemy_sleep_au1550) |
122 | sw zero, 0x007c(t3) /* sys_sleep */ | 155 | |
123 | sync | ||
124 | nop | ||
125 | nop | ||
126 | nop | ||
127 | nop | ||
128 | nop | ||
129 | nop | ||
130 | nop | ||
131 | nop | ||
132 | 156 | ||
133 | /* This is where we return upon wakeup. | 157 | /* This is where we return upon wakeup. |
134 | * Reload all of the registers and return. | 158 | * Reload all of the registers and return. |
135 | */ | 159 | */ |
136 | 3: lw k0, 0x20(sp) | 160 | LEAF(alchemy_sleep_wakeup) |
161 | lw k0, 0x20(sp) | ||
137 | mtc0 k0, CP0_STATUS | 162 | mtc0 k0, CP0_STATUS |
138 | lw k0, 0x1c(sp) | 163 | lw k0, 0x1c(sp) |
139 | mtc0 k0, CP0_CONTEXT | 164 | mtc0 k0, CP0_CONTEXT |
@@ -169,4 +194,4 @@ LEAF(au1xxx_save_and_sleep) | |||
169 | lw $31, PT_R31(sp) | 194 | lw $31, PT_R31(sp) |
170 | jr ra | 195 | jr ra |
171 | addiu sp, PT_SIZE | 196 | addiu sp, PT_SIZE |
172 | END(au1xxx_save_and_sleep) | 197 | END(alchemy_sleep_wakeup) |