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