Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 1 | /* |
Michael Hennerich | 14b0320 | 2008-05-07 11:41:26 +0800 | [diff] [blame] | 2 | * Copyright 2004-2008 Analog Devices Inc. |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 3 | * |
Michael Hennerich | 14b0320 | 2008-05-07 11:41:26 +0800 | [diff] [blame] | 4 | * Licensed under the GPL-2 or later. |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 5 | */ |
| 6 | |
| 7 | #include <linux/linkage.h> |
| 8 | #include <asm/blackfin.h> |
Bryan Wu | 639f657 | 2008-08-27 10:51:02 +0800 | [diff] [blame] | 9 | #include <mach/irq.h> |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 10 | #include <asm/dpmc.h> |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 11 | |
| 12 | .section .l1.text |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 13 | ENTRY(_sleep_mode) |
Mike Frysinger | da31d6f | 2011-06-27 15:43:56 -0400 | [diff] [blame] | 14 | [--SP] = (R7:4, P5:3); |
| 15 | [--SP] = RETS; |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 16 | |
| 17 | call _set_sic_iwr; |
| 18 | |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 19 | P0.H = hi(PLL_CTL); |
| 20 | P0.L = lo(PLL_CTL); |
| 21 | R1 = W[P0](z); |
| 22 | BITSET (R1, 3); |
| 23 | W[P0] = R1.L; |
| 24 | |
| 25 | CLI R2; |
| 26 | SSYNC; |
| 27 | IDLE; |
| 28 | STI R2; |
| 29 | |
| 30 | call _test_pll_locked; |
| 31 | |
| 32 | R0 = IWR_ENABLE(0); |
Michael Hennerich | cfefe3c | 2008-02-09 04:12:37 +0800 | [diff] [blame] | 33 | R1 = IWR_DISABLE_ALL; |
| 34 | R2 = IWR_DISABLE_ALL; |
| 35 | |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 36 | call _set_sic_iwr; |
| 37 | |
| 38 | P0.H = hi(PLL_CTL); |
| 39 | P0.L = lo(PLL_CTL); |
| 40 | R7 = w[p0](z); |
| 41 | BITCLR (R7, 3); |
| 42 | BITCLR (R7, 5); |
| 43 | w[p0] = R7.L; |
| 44 | IDLE; |
| 45 | call _test_pll_locked; |
| 46 | |
| 47 | RETS = [SP++]; |
Mike Frysinger | da31d6f | 2011-06-27 15:43:56 -0400 | [diff] [blame] | 48 | (R7:4, P5:3) = [SP++]; |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 49 | RTS; |
Mike Frysinger | 1a8caee | 2008-07-16 17:07:26 +0800 | [diff] [blame] | 50 | ENDPROC(_sleep_mode) |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 51 | |
Mike Frysinger | eed7b83 | 2011-06-26 23:11:19 -0400 | [diff] [blame] | 52 | /* |
| 53 | * This func never returns as it puts the part into hibernate, and |
| 54 | * is only called from do_hibernate, so we don't bother saving or |
| 55 | * restoring any of the normal C runtime state. When we wake up, |
| 56 | * the entry point will be in do_hibernate and not here. |
| 57 | * |
| 58 | * We accept just one argument -- the value to write to VR_CTL. |
| 59 | */ |
Steven Miao | 93f8951 | 2012-05-16 18:26:10 +0800 | [diff] [blame] | 60 | |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 61 | ENTRY(_hibernate_mode) |
Mike Frysinger | eed7b83 | 2011-06-26 23:11:19 -0400 | [diff] [blame] | 62 | /* Save/setup the regs we need early for minor pipeline optimization */ |
| 63 | R4 = R0; |
Steven Miao | 93f8951 | 2012-05-16 18:26:10 +0800 | [diff] [blame] | 64 | |
Mike Frysinger | eed7b83 | 2011-06-26 23:11:19 -0400 | [diff] [blame] | 65 | P3.H = hi(VR_CTL); |
| 66 | P3.L = lo(VR_CTL); |
Mike Frysinger | eed7b83 | 2011-06-26 23:11:19 -0400 | [diff] [blame] | 67 | /* Disable all wakeup sources */ |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 68 | R0 = IWR_DISABLE_ALL; |
| 69 | R1 = IWR_DISABLE_ALL; |
| 70 | R2 = IWR_DISABLE_ALL; |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 71 | call _set_sic_iwr; |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 72 | call _set_dram_srfs; |
| 73 | SSYNC; |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 74 | |
Mike Frysinger | eed7b83 | 2011-06-26 23:11:19 -0400 | [diff] [blame] | 75 | /* Finally, we climb into our cave to hibernate */ |
| 76 | W[P3] = R4.L; |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 77 | CLI R2; |
| 78 | IDLE; |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 79 | .Lforever: |
| 80 | jump .Lforever; |
Mike Frysinger | 1a8caee | 2008-07-16 17:07:26 +0800 | [diff] [blame] | 81 | ENDPROC(_hibernate_mode) |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 82 | |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 83 | ENTRY(_sleep_deeper) |
Mike Frysinger | da31d6f | 2011-06-27 15:43:56 -0400 | [diff] [blame] | 84 | [--SP] = (R7:4, P5:3); |
| 85 | [--SP] = RETS; |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 86 | |
| 87 | CLI R4; |
| 88 | |
| 89 | P3 = R0; |
Michael Hennerich | cfefe3c | 2008-02-09 04:12:37 +0800 | [diff] [blame] | 90 | P4 = R1; |
| 91 | P5 = R2; |
| 92 | |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 93 | R0 = IWR_ENABLE(0); |
Michael Hennerich | cfefe3c | 2008-02-09 04:12:37 +0800 | [diff] [blame] | 94 | R1 = IWR_DISABLE_ALL; |
| 95 | R2 = IWR_DISABLE_ALL; |
| 96 | |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 97 | call _set_sic_iwr; |
Michael Hennerich | 4521ef4 | 2008-01-11 17:21:41 +0800 | [diff] [blame] | 98 | call _set_dram_srfs; /* Set SDRAM Self Refresh */ |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 99 | |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 100 | P0.H = hi(PLL_DIV); |
| 101 | P0.L = lo(PLL_DIV); |
| 102 | R6 = W[P0](z); |
| 103 | R0.L = 0xF; |
Michael Hennerich | 4521ef4 | 2008-01-11 17:21:41 +0800 | [diff] [blame] | 104 | W[P0] = R0.l; /* Set Max VCO to SCLK divider */ |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 105 | |
| 106 | P0.H = hi(PLL_CTL); |
| 107 | P0.L = lo(PLL_CTL); |
| 108 | R5 = W[P0](z); |
Robin Getz | f16295e | 2007-08-03 18:07:17 +0800 | [diff] [blame] | 109 | R0.L = (CONFIG_MIN_VCO_HZ/CONFIG_CLKIN_HZ) << 9; |
Michael Hennerich | 4521ef4 | 2008-01-11 17:21:41 +0800 | [diff] [blame] | 110 | W[P0] = R0.l; /* Set Min CLKIN to VCO multiplier */ |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 111 | |
| 112 | SSYNC; |
| 113 | IDLE; |
| 114 | |
| 115 | call _test_pll_locked; |
| 116 | |
| 117 | P0.H = hi(VR_CTL); |
| 118 | P0.L = lo(VR_CTL); |
| 119 | R7 = W[P0](z); |
| 120 | R1 = 0x6; |
| 121 | R1 <<= 16; |
| 122 | R2 = 0x0404(Z); |
| 123 | R1 = R1|R2; |
| 124 | |
| 125 | R2 = DEPOSIT(R7, R1); |
Michael Hennerich | 4521ef4 | 2008-01-11 17:21:41 +0800 | [diff] [blame] | 126 | W[P0] = R2; /* Set Min Core Voltage */ |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 127 | |
| 128 | SSYNC; |
| 129 | IDLE; |
| 130 | |
| 131 | call _test_pll_locked; |
| 132 | |
Michael Hennerich | 4521ef4 | 2008-01-11 17:21:41 +0800 | [diff] [blame] | 133 | R0 = P3; |
Michael Hennerich | cfefe3c | 2008-02-09 04:12:37 +0800 | [diff] [blame] | 134 | R1 = P4; |
| 135 | R3 = P5; |
Michael Hennerich | 4521ef4 | 2008-01-11 17:21:41 +0800 | [diff] [blame] | 136 | call _set_sic_iwr; /* Set Awake from IDLE */ |
| 137 | |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 138 | P0.H = hi(PLL_CTL); |
| 139 | P0.L = lo(PLL_CTL); |
| 140 | R0 = W[P0](z); |
| 141 | BITSET (R0, 3); |
Michael Hennerich | 4521ef4 | 2008-01-11 17:21:41 +0800 | [diff] [blame] | 142 | W[P0] = R0.L; /* Turn CCLK OFF */ |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 143 | SSYNC; |
| 144 | IDLE; |
| 145 | |
| 146 | call _test_pll_locked; |
| 147 | |
| 148 | R0 = IWR_ENABLE(0); |
Michael Hennerich | cfefe3c | 2008-02-09 04:12:37 +0800 | [diff] [blame] | 149 | R1 = IWR_DISABLE_ALL; |
| 150 | R2 = IWR_DISABLE_ALL; |
| 151 | |
Michael Hennerich | 4521ef4 | 2008-01-11 17:21:41 +0800 | [diff] [blame] | 152 | call _set_sic_iwr; /* Set Awake from IDLE PLL */ |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 153 | |
| 154 | P0.H = hi(VR_CTL); |
| 155 | P0.L = lo(VR_CTL); |
| 156 | W[P0]= R7; |
| 157 | |
| 158 | SSYNC; |
| 159 | IDLE; |
| 160 | |
| 161 | call _test_pll_locked; |
| 162 | |
| 163 | P0.H = hi(PLL_DIV); |
| 164 | P0.L = lo(PLL_DIV); |
Michael Hennerich | 4521ef4 | 2008-01-11 17:21:41 +0800 | [diff] [blame] | 165 | W[P0]= R6; /* Restore CCLK and SCLK divider */ |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 166 | |
| 167 | P0.H = hi(PLL_CTL); |
| 168 | P0.L = lo(PLL_CTL); |
Michael Hennerich | 4521ef4 | 2008-01-11 17:21:41 +0800 | [diff] [blame] | 169 | w[p0] = R5; /* Restore VCO multiplier */ |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 170 | IDLE; |
| 171 | call _test_pll_locked; |
| 172 | |
Michael Hennerich | 4521ef4 | 2008-01-11 17:21:41 +0800 | [diff] [blame] | 173 | call _unset_dram_srfs; /* SDRAM Self Refresh Off */ |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 174 | |
| 175 | STI R4; |
| 176 | |
| 177 | RETS = [SP++]; |
Mike Frysinger | da31d6f | 2011-06-27 15:43:56 -0400 | [diff] [blame] | 178 | (R7:4, P5:3) = [SP++]; |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 179 | RTS; |
Mike Frysinger | 1a8caee | 2008-07-16 17:07:26 +0800 | [diff] [blame] | 180 | ENDPROC(_sleep_deeper) |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 181 | |
Sonic Zhang | fb5f004 | 2007-12-23 23:02:13 +0800 | [diff] [blame] | 182 | ENTRY(_set_dram_srfs) |
| 183 | /* set the dram to self refresh mode */ |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 184 | SSYNC; |
| 185 | #if defined(EBIU_RSTCTL) /* DDR */ |
Sonic Zhang | fb5f004 | 2007-12-23 23:02:13 +0800 | [diff] [blame] | 186 | P0.H = hi(EBIU_RSTCTL); |
| 187 | P0.L = lo(EBIU_RSTCTL); |
| 188 | R2 = [P0]; |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 189 | BITSET(R2, 3); /* SRREQ enter self-refresh mode */ |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 190 | [P0] = R2; |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 191 | SSYNC; |
| 192 | 1: |
Sonic Zhang | fb5f004 | 2007-12-23 23:02:13 +0800 | [diff] [blame] | 193 | R2 = [P0]; |
| 194 | CC = BITTST(R2, 4); |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 195 | if !CC JUMP 1b; |
| 196 | #else /* SDRAM */ |
| 197 | P0.L = lo(EBIU_SDGCTL); |
| 198 | P0.H = hi(EBIU_SDGCTL); |
Mike Frysinger | 9e770f7 | 2011-06-27 15:46:40 -0400 | [diff] [blame] | 199 | P1.L = lo(EBIU_SDSTAT); |
| 200 | P1.H = hi(EBIU_SDSTAT); |
| 201 | |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 202 | R2 = [P0]; |
| 203 | BITSET(R2, 24); /* SRFS enter self-refresh mode */ |
| 204 | [P0] = R2; |
| 205 | SSYNC; |
| 206 | |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 207 | 1: |
Mike Frysinger | 9e770f7 | 2011-06-27 15:46:40 -0400 | [diff] [blame] | 208 | R2 = w[P1]; |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 209 | SSYNC; |
| 210 | cc = BITTST(R2, 1); /* SDSRA poll self-refresh status */ |
| 211 | if !cc jump 1b; |
| 212 | |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 213 | R2 = [P0]; |
| 214 | BITCLR(R2, 0); /* SCTLE disable CLKOUT */ |
| 215 | [P0] = R2; |
Sonic Zhang | fb5f004 | 2007-12-23 23:02:13 +0800 | [diff] [blame] | 216 | #endif |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 217 | RTS; |
Mike Frysinger | 1a8caee | 2008-07-16 17:07:26 +0800 | [diff] [blame] | 218 | ENDPROC(_set_dram_srfs) |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 219 | |
Sonic Zhang | fb5f004 | 2007-12-23 23:02:13 +0800 | [diff] [blame] | 220 | ENTRY(_unset_dram_srfs) |
| 221 | /* set the dram out of self refresh mode */ |
Mike Frysinger | 9e770f7 | 2011-06-27 15:46:40 -0400 | [diff] [blame] | 222 | |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 223 | #if defined(EBIU_RSTCTL) /* DDR */ |
Sonic Zhang | fb5f004 | 2007-12-23 23:02:13 +0800 | [diff] [blame] | 224 | P0.H = hi(EBIU_RSTCTL); |
| 225 | P0.L = lo(EBIU_RSTCTL); |
| 226 | R2 = [P0]; |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 227 | BITCLR(R2, 3); /* clear SRREQ bit */ |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 228 | [P0] = R2; |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 229 | #elif defined(EBIU_SDGCTL) /* SDRAM */ |
Mike Frysinger | 9e770f7 | 2011-06-27 15:46:40 -0400 | [diff] [blame] | 230 | /* release CLKOUT from self-refresh */ |
| 231 | P0.L = lo(EBIU_SDGCTL); |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 232 | P0.H = hi(EBIU_SDGCTL); |
Mike Frysinger | 9e770f7 | 2011-06-27 15:46:40 -0400 | [diff] [blame] | 233 | |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 234 | R2 = [P0]; |
| 235 | BITSET(R2, 0); /* SCTLE enable CLKOUT */ |
| 236 | [P0] = R2 |
| 237 | SSYNC; |
| 238 | |
Mike Frysinger | 9e770f7 | 2011-06-27 15:46:40 -0400 | [diff] [blame] | 239 | /* release SDRAM from self-refresh */ |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 240 | R2 = [P0]; |
| 241 | BITCLR(R2, 24); /* clear SRFS bit */ |
| 242 | [P0] = R2 |
| 243 | #endif |
Mike Frysinger | 9e770f7 | 2011-06-27 15:46:40 -0400 | [diff] [blame] | 244 | |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 245 | SSYNC; |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 246 | RTS; |
Mike Frysinger | 1a8caee | 2008-07-16 17:07:26 +0800 | [diff] [blame] | 247 | ENDPROC(_unset_dram_srfs) |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 248 | |
| 249 | ENTRY(_set_sic_iwr) |
Mike Frysinger | 85c2737 | 2011-06-26 13:55:24 -0400 | [diff] [blame] | 250 | #ifdef SIC_IWR0 |
Mike Frysinger | 4705a25 | 2011-06-26 14:07:17 -0400 | [diff] [blame] | 251 | P0.H = hi(SYSMMR_BASE); |
| 252 | P0.L = lo(SYSMMR_BASE); |
| 253 | [P0 + (SIC_IWR0 - SYSMMR_BASE)] = R0; |
| 254 | [P0 + (SIC_IWR1 - SYSMMR_BASE)] = R1; |
Mike Frysinger | 85c2737 | 2011-06-26 13:55:24 -0400 | [diff] [blame] | 255 | # ifdef SIC_IWR2 |
Mike Frysinger | 4705a25 | 2011-06-26 14:07:17 -0400 | [diff] [blame] | 256 | [P0 + (SIC_IWR2 - SYSMMR_BASE)] = R2; |
Mike Frysinger | 85c2737 | 2011-06-26 13:55:24 -0400 | [diff] [blame] | 257 | # endif |
Sonic Zhang | fb5f004 | 2007-12-23 23:02:13 +0800 | [diff] [blame] | 258 | #else |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 259 | P0.H = hi(SIC_IWR); |
| 260 | P0.L = lo(SIC_IWR); |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 261 | [P0] = R0; |
Mike Frysinger | 4705a25 | 2011-06-26 14:07:17 -0400 | [diff] [blame] | 262 | #endif |
Michael Hennerich | cfefe3c | 2008-02-09 04:12:37 +0800 | [diff] [blame] | 263 | |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 264 | SSYNC; |
| 265 | RTS; |
Mike Frysinger | 1a8caee | 2008-07-16 17:07:26 +0800 | [diff] [blame] | 266 | ENDPROC(_set_sic_iwr) |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 267 | |
Bryan Wu | 1394f03 | 2007-05-06 14:50:22 -0700 | [diff] [blame] | 268 | ENTRY(_test_pll_locked) |
| 269 | P0.H = hi(PLL_STAT); |
| 270 | P0.L = lo(PLL_STAT); |
| 271 | 1: |
| 272 | R0 = W[P0] (Z); |
| 273 | CC = BITTST(R0,5); |
| 274 | IF !CC JUMP 1b; |
| 275 | RTS; |
Mike Frysinger | 1a8caee | 2008-07-16 17:07:26 +0800 | [diff] [blame] | 276 | ENDPROC(_test_pll_locked) |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 277 | |
| 278 | .section .text |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 279 | ENTRY(_do_hibernate) |
Steven Miao | 93f8951 | 2012-05-16 18:26:10 +0800 | [diff] [blame] | 280 | bfin_cpu_reg_save; |
| 281 | bfin_sys_mmr_save; |
| 282 | bfin_core_mmr_save; |
Mike Frysinger | eed7b83 | 2011-06-26 23:11:19 -0400 | [diff] [blame] | 283 | |
| 284 | /* Setup args to hibernate mode early for pipeline optimization */ |
| 285 | R0 = M3; |
| 286 | P1.H = _hibernate_mode; |
| 287 | P1.L = _hibernate_mode; |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 288 | |
| 289 | /* Save Magic, return address and Stack Pointer */ |
Mike Frysinger | eed7b83 | 2011-06-26 23:11:19 -0400 | [diff] [blame] | 290 | P0 = 0; |
| 291 | R1.H = 0xDEAD; /* Hibernate Magic */ |
| 292 | R1.L = 0xBEEF; |
| 293 | R2.H = .Lpm_resume_here; |
| 294 | R2.L = .Lpm_resume_here; |
| 295 | [P0++] = R1; /* Store Hibernate Magic */ |
| 296 | [P0++] = R2; /* Save Return Address */ |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 297 | [P0++] = SP; /* Save Stack Pointer */ |
Mike Frysinger | eed7b83 | 2011-06-26 23:11:19 -0400 | [diff] [blame] | 298 | |
| 299 | /* Must use an indirect call as we need to jump to L1 */ |
| 300 | call (P1); /* Goodbye */ |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 301 | |
Mike Frysinger | 1a8caee | 2008-07-16 17:07:26 +0800 | [diff] [blame] | 302 | .Lpm_resume_here: |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 303 | |
Steven Miao | 93f8951 | 2012-05-16 18:26:10 +0800 | [diff] [blame] | 304 | bfin_core_mmr_restore; |
| 305 | bfin_sys_mmr_restore; |
| 306 | bfin_cpu_reg_restore; |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 307 | |
| 308 | [--sp] = RETI; /* Clear Global Interrupt Disable */ |
| 309 | SP += 4; |
| 310 | |
Michael Hennerich | 1efc80b | 2008-07-19 16:57:32 +0800 | [diff] [blame] | 311 | RTS; |
Mike Frysinger | 1a8caee | 2008-07-16 17:07:26 +0800 | [diff] [blame] | 312 | ENDPROC(_do_hibernate) |