| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 |  */ | 
| Sergei Shtylyov | ce28f94 | 2008-04-23 22:43:55 +0400 | [diff] [blame] | 12 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 13 | #include <asm/asm.h> | 
 | 14 | #include <asm/mipsregs.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 15 | #include <asm/regdef.h> | 
 | 16 | #include <asm/stackframe.h> | 
 | 17 |  | 
| Manuel Lauss | 564365b | 2008-12-21 09:26:25 +0100 | [diff] [blame] | 18 | 	.extern __flush_cache_all | 
 | 19 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 20 | 	.text | 
| Manuel Lauss | 564365b | 2008-12-21 09:26:25 +0100 | [diff] [blame] | 21 | 	.set noreorder | 
 | 22 | 	.set noat | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 |  */ | 
| Manuel Lauss | 564365b | 2008-12-21 09:26:25 +0100 | [diff] [blame] | 28 | LEAF(au1xxx_save_and_sleep) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 45 | 	sw	$26, PT_R26(sp) | 
 | 46 | 	sw	$27, PT_R27(sp) | 
 | 47 | 	sw	$28, PT_R28(sp) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 |  | 
| Manuel Lauss | 564365b | 2008-12-21 09:26:25 +0100 | [diff] [blame] | 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 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 65 | 	/* Now set up the scratch registers so the boot rom will | 
 | 66 | 	 * return to this point upon wakeup. | 
| Manuel Lauss | 564365b | 2008-12-21 09:26:25 +0100 | [diff] [blame] | 67 | 	 * sys_scratch0 : SP | 
 | 68 | 	 * sys_scratch1 : RA | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 69 | 	 */ | 
| Manuel Lauss | 564365b | 2008-12-21 09:26:25 +0100 | [diff] [blame] | 70 | 	lui	t3, 0xb190		/* sys_xxx */ | 
 | 71 | 	sw	sp, 0x0018(t3) | 
 | 72 | 	la	k0, 3f			/* resume path */ | 
 | 73 | 	sw	k0, 0x001c(t3) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 74 |  | 
| Manuel Lauss | 564365b | 2008-12-21 09:26:25 +0100 | [diff] [blame] | 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 | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 79 | 	.set	mips3 | 
| Ralf Baechle | e8c7c48 | 2008-09-16 19:12:16 +0200 | [diff] [blame] | 80 | 	cache	0x14, 0(t0) | 
 | 81 | 	cache	0x14, 32(t0) | 
 | 82 | 	cache	0x14, 64(t0) | 
 | 83 | 	cache	0x14, 96(t0) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 84 | 	.set	mips0 | 
 | 85 |  | 
| Manuel Lauss | 564365b | 2008-12-21 09:26:25 +0100 | [diff] [blame] | 86 | 1:	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 Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 101 | 	sync | 
 | 102 |  | 
| Manuel Lauss | 564365b | 2008-12-21 09:26:25 +0100 | [diff] [blame] | 103 | 	/* wait for sdram to enter self-refresh mode */ | 
 | 104 | 	lui 	t0, 0x0100 | 
 | 105 | 2:	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 Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 116 | 	sync | 
| Manuel Lauss | 564365b | 2008-12-21 09:26:25 +0100 | [diff] [blame] | 117 | #endif | 
 | 118 |  | 
 | 119 | 	/* put power supply and processor to sleep */ | 
 | 120 | 	sw	zero, 0x0078(t3)	/* sys_slppwr */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 121 | 	sync | 
| Manuel Lauss | 564365b | 2008-12-21 09:26:25 +0100 | [diff] [blame] | 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 | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 132 |  | 
 | 133 | 	/* This is where we return upon wakeup. | 
 | 134 | 	 * Reload all of the registers and return. | 
 | 135 | 	 */ | 
| Manuel Lauss | 564365b | 2008-12-21 09:26:25 +0100 | [diff] [blame] | 136 | 3:	lw	k0, 0x20(sp) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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 | 
| Sergei Shtylyov | 9370b35 | 2006-05-26 19:44:54 +0400 | [diff] [blame] | 144 |  | 
| Manuel Lauss | 564365b | 2008-12-21 09:26:25 +0100 | [diff] [blame] | 145 | 	/* We need to catch the early Alchemy SOCs with | 
| Sergei Shtylyov | 9370b35 | 2006-05-26 19:44:54 +0400 | [diff] [blame] | 146 | 	 * the write-only Config[OD] bit and set it back to one... | 
 | 147 | 	 */ | 
 | 148 | 	jal	au1x00_fixup_config_od | 
| Manuel Lauss | 564365b | 2008-12-21 09:26:25 +0100 | [diff] [blame] | 149 | 	 nop | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 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) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 165 | 	lw	$26, PT_R26(sp) | 
 | 166 | 	lw	$27, PT_R27(sp) | 
 | 167 | 	lw	$28, PT_R28(sp) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 168 | 	lw	$30, PT_R30(sp) | 
 | 169 | 	lw	$31, PT_R31(sp) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 170 | 	jr	ra | 
| Manuel Lauss | 564365b | 2008-12-21 09:26:25 +0100 | [diff] [blame] | 171 | 	 addiu	sp, PT_SIZE | 
 | 172 | END(au1xxx_save_and_sleep) |