aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/alchemy
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/alchemy')
-rw-r--r--arch/mips/alchemy/common/power.c12
-rw-r--r--arch/mips/alchemy/common/sleeper.S81
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
194void au_sleep(void) 194void 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
28LEAF(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 */
92LEAF(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
861: lui a0, 0xb400 /* mem_xxx */ 1051: 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
115END(alchemy_sleep_au1000)
116
117/* sleep code for Au1550/Au1200 memory controller type */
118LEAF(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
1311: 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 154END(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 */
1363: lw k0, 0x20(sp) 160LEAF(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
172END(au1xxx_save_and_sleep) 197END(alchemy_sleep_wakeup)