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