blob: 4f4b16741d12e61e57ffb24f791e0fdfbeef1a9d [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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 */
Sergei Shtylyovce28f942008-04-23 22:43:55 +040012
Linus Torvalds1da177e2005-04-16 15:20:36 -070013#include <asm/asm.h>
14#include <asm/mipsregs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070015#include <asm/regdef.h>
16#include <asm/stackframe.h>
17
Manuel Lauss564365b2008-12-21 09:26:25 +010018 .extern __flush_cache_all
19
Linus Torvalds1da177e2005-04-16 15:20:36 -070020 .text
Manuel Lauss564365b2008-12-21 09:26:25 +010021 .set noreorder
22 .set noat
Linus Torvalds1da177e2005-04-16 15:20:36 -070023 .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 */
Manuel Lauss564365b2008-12-21 09:26:25 +010028LEAF(au1xxx_save_and_sleep)
Linus Torvalds1da177e2005-04-16 15:20:36 -070029 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)
Linus Torvalds1da177e2005-04-16 15:20:36 -070037 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)
Linus Torvalds1da177e2005-04-16 15:20:36 -070045 sw $26, PT_R26(sp)
46 sw $27, PT_R27(sp)
47 sw $28, PT_R28(sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -070048 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
Manuel Lauss564365b2008-12-21 09:26:25 +010059 /* 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
Linus Torvalds1da177e2005-04-16 15:20:36 -070065 /* Now set up the scratch registers so the boot rom will
66 * return to this point upon wakeup.
Manuel Lauss564365b2008-12-21 09:26:25 +010067 * sys_scratch0 : SP
68 * sys_scratch1 : RA
Linus Torvalds1da177e2005-04-16 15:20:36 -070069 */
Manuel Lauss564365b2008-12-21 09:26:25 +010070 lui t3, 0xb190 /* sys_xxx */
71 sw sp, 0x0018(t3)
72 la k0, 3f /* resume path */
73 sw k0, 0x001c(t3)
Linus Torvalds1da177e2005-04-16 15:20:36 -070074
Manuel Lauss564365b2008-12-21 09:26:25 +010075 /* 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
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 .set mips3
Ralf Baechlee8c7c482008-09-16 19:12:16 +020080 cache 0x14, 0(t0)
81 cache 0x14, 32(t0)
82 cache 0x14, 64(t0)
83 cache 0x14, 96(t0)
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 .set mips0
85
Manuel Lauss564365b2008-12-21 09:26:25 +0100861: 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 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101 sync
102
Manuel Lauss564365b2008-12-21 09:26:25 +0100103 /* 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 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116 sync
Manuel Lauss564365b2008-12-21 09:26:25 +0100117#endif
118
119 /* put power supply and processor to sleep */
120 sw zero, 0x0078(t3) /* sys_slppwr */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121 sync
Manuel Lauss564365b2008-12-21 09:26:25 +0100122 sw zero, 0x007c(t3) /* sys_sleep */
123 sync
124 nop
125 nop
126 nop
127 nop
128 nop
129 nop
130 nop
131 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132
133 /* This is where we return upon wakeup.
134 * Reload all of the registers and return.
135 */
Manuel Lauss564365b2008-12-21 09:26:25 +01001363: lw k0, 0x20(sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137 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
Sergei Shtylyov9370b352006-05-26 19:44:54 +0400144
Manuel Lauss564365b2008-12-21 09:26:25 +0100145 /* We need to catch the early Alchemy SOCs with
Sergei Shtylyov9370b352006-05-26 19:44:54 +0400146 * the write-only Config[OD] bit and set it back to one...
147 */
148 jal au1x00_fixup_config_od
Manuel Lauss564365b2008-12-21 09:26:25 +0100149 nop
Linus Torvalds1da177e2005-04-16 15:20:36 -0700150 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)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157 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)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700165 lw $26, PT_R26(sp)
166 lw $27, PT_R27(sp)
167 lw $28, PT_R28(sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168 lw $30, PT_R30(sp)
169 lw $31, PT_R31(sp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 jr ra
Manuel Lauss564365b2008-12-21 09:26:25 +0100171 addiu sp, PT_SIZE
172END(au1xxx_save_and_sleep)