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