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/* Save all of the processor general registers and go to sleep. 26 * A wakeup condition will get us back here to restore the registers. 27 */ 28LEAF(au1xxx_save_and_sleep) 29 subu sp, PT_SIZE 30 sw $1, PT_R1(sp) 31 sw $2, PT_R2(sp) 32 sw $3, PT_R3(sp) 33 sw $4, PT_R4(sp) 34 sw $5, PT_R5(sp) 35 sw $6, PT_R6(sp) 36 sw $7, PT_R7(sp) 37 sw $16, PT_R16(sp) 38 sw $17, PT_R17(sp) 39 sw $18, PT_R18(sp) 40 sw $19, PT_R19(sp) 41 sw $20, PT_R20(sp) 42 sw $21, PT_R21(sp) 43 sw $22, PT_R22(sp) 44 sw $23, PT_R23(sp) 45 sw $26, PT_R26(sp) 46 sw $27, PT_R27(sp) 47 sw $28, PT_R28(sp) 48 sw $30, PT_R30(sp) 49 sw $31, PT_R31(sp) 50 mfc0 k0, CP0_STATUS 51 sw k0, 0x20(sp) 52 mfc0 k0, CP0_CONTEXT 53 sw k0, 0x1c(sp) 54 mfc0 k0, CP0_PAGEMASK 55 sw k0, 0x18(sp) 56 mfc0 k0, CP0_CONFIG 57 sw k0, 0x14(sp) 58 59 /* flush caches to make sure context is in memory */ 60 la t1, __flush_cache_all 61 lw t0, 0(t1) 62 jalr t0 63 nop 64 65 /* Now set up the scratch registers so the boot rom will 66 * return to this point upon wakeup. 67 * sys_scratch0 : SP 68 * sys_scratch1 : RA 69 */ 70 lui t3, 0xb190 /* sys_xxx */ 71 sw sp, 0x0018(t3) 72 la k0, 3f /* resume path */ 73 sw k0, 0x001c(t3) 74 75 /* Put SDRAM into self refresh: Preload instructions into cache, 76 * issue a precharge, auto/self refresh, then sleep commands to it. 77 */ 78 la t0, 1f 79 .set mips3 80 cache 0x14, 0(t0) 81 cache 0x14, 32(t0) 82 cache 0x14, 64(t0) 83 cache 0x14, 96(t0) 84 .set mips0 85 861: 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 */ 90 sync 91 sw zero, 0x0020(a0) /* Auto Refresh */ 92 sync 93 sw zero, 0x0030(a0) /* Sleep */ 94 sync 95#endif 96 97#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) 98 sw zero, 0x08c0(a0) /* Precharge */ 99 sync 100 sw zero, 0x08d0(a0) /* Self Refresh */ 101 sync 102 103 /* wait for sdram to enter self-refresh mode */ 104 lui t0, 0x0100 1052: lw t1, 0x0850(a0) /* mem_sdstat */ 106 and t2, t1, t0 107 beq t2, zero, 2b 108 nop 109 110 /* disable SDRAM clocks */ 111 lui t0, 0xcfff 112 ori t0, t0, 0xffff 113 lw t1, 0x0840(a0) /* mem_sdconfiga */ 114 and t1, t0, t1 /* clear CE[1:0] */ 115 sw t1, 0x0840(a0) /* mem_sdconfiga */ 116 sync 117#endif 118 119 /* put power supply and processor to sleep */ 120 sw zero, 0x0078(t3) /* sys_slppwr */ 121 sync 122 sw zero, 0x007c(t3) /* sys_sleep */ 123 sync 124 nop 125 nop 126 nop 127 nop 128 nop 129 nop 130 nop 131 nop 132 133 /* This is where we return upon wakeup. 134 * Reload all of the registers and return. 135 */ 1363: lw k0, 0x20(sp) 137 mtc0 k0, CP0_STATUS 138 lw k0, 0x1c(sp) 139 mtc0 k0, CP0_CONTEXT 140 lw k0, 0x18(sp) 141 mtc0 k0, CP0_PAGEMASK 142 lw k0, 0x14(sp) 143 mtc0 k0, CP0_CONFIG 144 145 /* We need to catch the early Alchemy SOCs with 146 * the write-only Config[OD] bit and set it back to one... 147 */ 148 jal au1x00_fixup_config_od 149 nop 150 lw $1, PT_R1(sp) 151 lw $2, PT_R2(sp) 152 lw $3, PT_R3(sp) 153 lw $4, PT_R4(sp) 154 lw $5, PT_R5(sp) 155 lw $6, PT_R6(sp) 156 lw $7, PT_R7(sp) 157 lw $16, PT_R16(sp) 158 lw $17, PT_R17(sp) 159 lw $18, PT_R18(sp) 160 lw $19, PT_R19(sp) 161 lw $20, PT_R20(sp) 162 lw $21, PT_R21(sp) 163 lw $22, PT_R22(sp) 164 lw $23, PT_R23(sp) 165 lw $26, PT_R26(sp) 166 lw $27, PT_R27(sp) 167 lw $28, PT_R28(sp) 168 lw $30, PT_R30(sp) 169 lw $31, PT_R31(sp) 170 jr ra 171 addiu sp, PT_SIZE 172END(au1xxx_save_and_sleep) 173