blob: 1a1c09287222fdbcba5edfc489b5a647079bae5e [file] [log] [blame]
Bryan Wu1394f032007-05-06 14:50:22 -07001/*
Michael Hennerich14b03202008-05-07 11:41:26 +08002 * Copyright 2004-2008 Analog Devices Inc.
Bryan Wu1394f032007-05-06 14:50:22 -07003 *
Michael Hennerich14b03202008-05-07 11:41:26 +08004 * Licensed under the GPL-2 or later.
Bryan Wu1394f032007-05-06 14:50:22 -07005 */
6
7#include <linux/linkage.h>
8#include <asm/blackfin.h>
Bryan Wu639f6572008-08-27 10:51:02 +08009#include <mach/irq.h>
Michael Hennerich1efc80b2008-07-19 16:57:32 +080010#include <asm/dpmc.h>
Bryan Wu1394f032007-05-06 14:50:22 -070011
12.section .l1.text
13
14ENTRY(_sleep_mode)
15 [--SP] = ( R7:0, P5:0 );
16 [--SP] = RETS;
17
18 call _set_sic_iwr;
19
Bryan Wu1394f032007-05-06 14:50:22 -070020 P0.H = hi(PLL_CTL);
21 P0.L = lo(PLL_CTL);
22 R1 = W[P0](z);
23 BITSET (R1, 3);
24 W[P0] = R1.L;
25
26 CLI R2;
27 SSYNC;
28 IDLE;
29 STI R2;
30
31 call _test_pll_locked;
32
33 R0 = IWR_ENABLE(0);
Michael Hennerichcfefe3c2008-02-09 04:12:37 +080034 R1 = IWR_DISABLE_ALL;
35 R2 = IWR_DISABLE_ALL;
36
Bryan Wu1394f032007-05-06 14:50:22 -070037 call _set_sic_iwr;
38
39 P0.H = hi(PLL_CTL);
40 P0.L = lo(PLL_CTL);
41 R7 = w[p0](z);
42 BITCLR (R7, 3);
43 BITCLR (R7, 5);
44 w[p0] = R7.L;
45 IDLE;
46 call _test_pll_locked;
47
48 RETS = [SP++];
49 ( R7:0, P5:0 ) = [SP++];
50 RTS;
Mike Frysinger1a8caee2008-07-16 17:07:26 +080051ENDPROC(_sleep_mode)
Bryan Wu1394f032007-05-06 14:50:22 -070052
Mike Frysingereed7b832011-06-26 23:11:19 -040053/*
54 * This func never returns as it puts the part into hibernate, and
55 * is only called from do_hibernate, so we don't bother saving or
56 * restoring any of the normal C runtime state. When we wake up,
57 * the entry point will be in do_hibernate and not here.
58 *
59 * We accept just one argument -- the value to write to VR_CTL.
60 */
Bryan Wu1394f032007-05-06 14:50:22 -070061ENTRY(_hibernate_mode)
Mike Frysingereed7b832011-06-26 23:11:19 -040062 /* Save/setup the regs we need early for minor pipeline optimization */
63 R4 = R0;
64 P3.H = hi(VR_CTL);
65 P3.L = lo(VR_CTL);
Bryan Wu1394f032007-05-06 14:50:22 -070066
Mike Frysingereed7b832011-06-26 23:11:19 -040067 /* Disable all wakeup sources */
Michael Hennerich1efc80b2008-07-19 16:57:32 +080068 R0 = IWR_DISABLE_ALL;
69 R1 = IWR_DISABLE_ALL;
70 R2 = IWR_DISABLE_ALL;
Bryan Wu1394f032007-05-06 14:50:22 -070071 call _set_sic_iwr;
Michael Hennerich1efc80b2008-07-19 16:57:32 +080072 call _set_dram_srfs;
73 SSYNC;
Bryan Wu1394f032007-05-06 14:50:22 -070074
Mike Frysingereed7b832011-06-26 23:11:19 -040075 /* Finally, we climb into our cave to hibernate */
76 W[P3] = R4.L;
Bryan Wu1394f032007-05-06 14:50:22 -070077 CLI R2;
78 IDLE;
Michael Hennerich1efc80b2008-07-19 16:57:32 +080079.Lforever:
80 jump .Lforever;
Mike Frysinger1a8caee2008-07-16 17:07:26 +080081ENDPROC(_hibernate_mode)
Bryan Wu1394f032007-05-06 14:50:22 -070082
Bryan Wu1394f032007-05-06 14:50:22 -070083ENTRY(_sleep_deeper)
84 [--SP] = ( R7:0, P5:0 );
85 [--SP] = RETS;
86
87 CLI R4;
88
89 P3 = R0;
Michael Hennerichcfefe3c2008-02-09 04:12:37 +080090 P4 = R1;
91 P5 = R2;
92
Bryan Wu1394f032007-05-06 14:50:22 -070093 R0 = IWR_ENABLE(0);
Michael Hennerichcfefe3c2008-02-09 04:12:37 +080094 R1 = IWR_DISABLE_ALL;
95 R2 = IWR_DISABLE_ALL;
96
Bryan Wu1394f032007-05-06 14:50:22 -070097 call _set_sic_iwr;
Michael Hennerich4521ef42008-01-11 17:21:41 +080098 call _set_dram_srfs; /* Set SDRAM Self Refresh */
Bryan Wu1394f032007-05-06 14:50:22 -070099
Bryan Wu1394f032007-05-06 14:50:22 -0700100 P0.H = hi(PLL_DIV);
101 P0.L = lo(PLL_DIV);
102 R6 = W[P0](z);
103 R0.L = 0xF;
Michael Hennerich4521ef42008-01-11 17:21:41 +0800104 W[P0] = R0.l; /* Set Max VCO to SCLK divider */
Bryan Wu1394f032007-05-06 14:50:22 -0700105
106 P0.H = hi(PLL_CTL);
107 P0.L = lo(PLL_CTL);
108 R5 = W[P0](z);
Robin Getzf16295e2007-08-03 18:07:17 +0800109 R0.L = (CONFIG_MIN_VCO_HZ/CONFIG_CLKIN_HZ) << 9;
Michael Hennerich4521ef42008-01-11 17:21:41 +0800110 W[P0] = R0.l; /* Set Min CLKIN to VCO multiplier */
Bryan Wu1394f032007-05-06 14:50:22 -0700111
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 Hennerich4521ef42008-01-11 17:21:41 +0800126 W[P0] = R2; /* Set Min Core Voltage */
Bryan Wu1394f032007-05-06 14:50:22 -0700127
128 SSYNC;
129 IDLE;
130
131 call _test_pll_locked;
132
Michael Hennerich4521ef42008-01-11 17:21:41 +0800133 R0 = P3;
Michael Hennerichcfefe3c2008-02-09 04:12:37 +0800134 R1 = P4;
135 R3 = P5;
Michael Hennerich4521ef42008-01-11 17:21:41 +0800136 call _set_sic_iwr; /* Set Awake from IDLE */
137
Bryan Wu1394f032007-05-06 14:50:22 -0700138 P0.H = hi(PLL_CTL);
139 P0.L = lo(PLL_CTL);
140 R0 = W[P0](z);
141 BITSET (R0, 3);
Michael Hennerich4521ef42008-01-11 17:21:41 +0800142 W[P0] = R0.L; /* Turn CCLK OFF */
Bryan Wu1394f032007-05-06 14:50:22 -0700143 SSYNC;
144 IDLE;
145
146 call _test_pll_locked;
147
148 R0 = IWR_ENABLE(0);
Michael Hennerichcfefe3c2008-02-09 04:12:37 +0800149 R1 = IWR_DISABLE_ALL;
150 R2 = IWR_DISABLE_ALL;
151
Michael Hennerich4521ef42008-01-11 17:21:41 +0800152 call _set_sic_iwr; /* Set Awake from IDLE PLL */
Bryan Wu1394f032007-05-06 14:50:22 -0700153
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 Hennerich4521ef42008-01-11 17:21:41 +0800165 W[P0]= R6; /* Restore CCLK and SCLK divider */
Bryan Wu1394f032007-05-06 14:50:22 -0700166
167 P0.H = hi(PLL_CTL);
168 P0.L = lo(PLL_CTL);
Michael Hennerich4521ef42008-01-11 17:21:41 +0800169 w[p0] = R5; /* Restore VCO multiplier */
Bryan Wu1394f032007-05-06 14:50:22 -0700170 IDLE;
171 call _test_pll_locked;
172
Michael Hennerich4521ef42008-01-11 17:21:41 +0800173 call _unset_dram_srfs; /* SDRAM Self Refresh Off */
Bryan Wu1394f032007-05-06 14:50:22 -0700174
175 STI R4;
176
177 RETS = [SP++];
178 ( R7:0, P5:0 ) = [SP++];
179 RTS;
Mike Frysinger1a8caee2008-07-16 17:07:26 +0800180ENDPROC(_sleep_deeper)
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800181
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800182ENTRY(_set_dram_srfs)
183 /* set the dram to self refresh mode */
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800184 SSYNC;
185#if defined(EBIU_RSTCTL) /* DDR */
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800186 P0.H = hi(EBIU_RSTCTL);
187 P0.L = lo(EBIU_RSTCTL);
188 R2 = [P0];
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800189 BITSET(R2, 3); /* SRREQ enter self-refresh mode */
Bryan Wu1394f032007-05-06 14:50:22 -0700190 [P0] = R2;
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800191 SSYNC;
1921:
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800193 R2 = [P0];
194 CC = BITTST(R2, 4);
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800195 if !CC JUMP 1b;
196#else /* SDRAM */
197 P0.L = lo(EBIU_SDGCTL);
198 P0.H = hi(EBIU_SDGCTL);
199 R2 = [P0];
200 BITSET(R2, 24); /* SRFS enter self-refresh mode */
201 [P0] = R2;
202 SSYNC;
203
204 P0.L = lo(EBIU_SDSTAT);
205 P0.H = hi(EBIU_SDSTAT);
2061:
207 R2 = w[P0];
208 SSYNC;
209 cc = BITTST(R2, 1); /* SDSRA poll self-refresh status */
210 if !cc jump 1b;
211
212 P0.L = lo(EBIU_SDGCTL);
213 P0.H = hi(EBIU_SDGCTL);
214 R2 = [P0];
215 BITCLR(R2, 0); /* SCTLE disable CLKOUT */
216 [P0] = R2;
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800217#endif
Bryan Wu1394f032007-05-06 14:50:22 -0700218 RTS;
Mike Frysinger1a8caee2008-07-16 17:07:26 +0800219ENDPROC(_set_dram_srfs)
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800220
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800221ENTRY(_unset_dram_srfs)
222 /* set the dram out of self refresh mode */
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800223#if defined(EBIU_RSTCTL) /* DDR */
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800224 P0.H = hi(EBIU_RSTCTL);
225 P0.L = lo(EBIU_RSTCTL);
226 R2 = [P0];
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800227 BITCLR(R2, 3); /* clear SRREQ bit */
Bryan Wu1394f032007-05-06 14:50:22 -0700228 [P0] = R2;
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800229#elif defined(EBIU_SDGCTL) /* SDRAM */
230
231 P0.L = lo(EBIU_SDGCTL); /* release CLKOUT from self-refresh */
232 P0.H = hi(EBIU_SDGCTL);
233 R2 = [P0];
234 BITSET(R2, 0); /* SCTLE enable CLKOUT */
235 [P0] = R2
236 SSYNC;
237
238 P0.L = lo(EBIU_SDGCTL); /* release SDRAM from self-refresh */
239 P0.H = hi(EBIU_SDGCTL);
240 R2 = [P0];
241 BITCLR(R2, 24); /* clear SRFS bit */
242 [P0] = R2
243#endif
244 SSYNC;
Bryan Wu1394f032007-05-06 14:50:22 -0700245 RTS;
Mike Frysinger1a8caee2008-07-16 17:07:26 +0800246ENDPROC(_unset_dram_srfs)
Bryan Wu1394f032007-05-06 14:50:22 -0700247
248ENTRY(_set_sic_iwr)
Mike Frysinger85c27372011-06-26 13:55:24 -0400249#ifdef SIC_IWR0
Mike Frysinger4705a252011-06-26 14:07:17 -0400250 P0.H = hi(SYSMMR_BASE);
251 P0.L = lo(SYSMMR_BASE);
252 [P0 + (SIC_IWR0 - SYSMMR_BASE)] = R0;
253 [P0 + (SIC_IWR1 - SYSMMR_BASE)] = R1;
Mike Frysinger85c27372011-06-26 13:55:24 -0400254# ifdef SIC_IWR2
Mike Frysinger4705a252011-06-26 14:07:17 -0400255 [P0 + (SIC_IWR2 - SYSMMR_BASE)] = R2;
Mike Frysinger85c27372011-06-26 13:55:24 -0400256# endif
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800257#else
Bryan Wu1394f032007-05-06 14:50:22 -0700258 P0.H = hi(SIC_IWR);
259 P0.L = lo(SIC_IWR);
Bryan Wu1394f032007-05-06 14:50:22 -0700260 [P0] = R0;
Mike Frysinger4705a252011-06-26 14:07:17 -0400261#endif
Michael Hennerichcfefe3c2008-02-09 04:12:37 +0800262
Bryan Wu1394f032007-05-06 14:50:22 -0700263 SSYNC;
264 RTS;
Mike Frysinger1a8caee2008-07-16 17:07:26 +0800265ENDPROC(_set_sic_iwr)
Bryan Wu1394f032007-05-06 14:50:22 -0700266
Bryan Wu1394f032007-05-06 14:50:22 -0700267ENTRY(_test_pll_locked)
268 P0.H = hi(PLL_STAT);
269 P0.L = lo(PLL_STAT);
2701:
271 R0 = W[P0] (Z);
272 CC = BITTST(R0,5);
273 IF !CC JUMP 1b;
274 RTS;
Mike Frysinger1a8caee2008-07-16 17:07:26 +0800275ENDPROC(_test_pll_locked)
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800276
277.section .text
278
Mike Frysingereed7b832011-06-26 23:11:19 -0400279#define PM_REG0 R7
280#define PM_REG1 R6
281#define PM_REG2 R5
282#define PM_REG3 R4
283#define PM_REG4 R3
284#define PM_REG5 R2
285#define PM_REG6 R1
286#define PM_REG7 R0
287#define PM_REG8 P5
288#define PM_REG9 P4
289#define PM_REG10 P3
290#define PM_REG11 P2
291#define PM_REG12 P1
292#define PM_REG13 P0
Mike Frysinger584ecba2011-06-26 14:11:24 -0400293
Mike Frysingereed7b832011-06-26 23:11:19 -0400294#define PM_REGSET0 R7:7
295#define PM_REGSET1 R7:6
296#define PM_REGSET2 R7:5
297#define PM_REGSET3 R7:4
298#define PM_REGSET4 R7:3
299#define PM_REGSET5 R7:2
300#define PM_REGSET6 R7:1
301#define PM_REGSET7 R7:0
302#define PM_REGSET8 R7:0, P5:5
303#define PM_REGSET9 R7:0, P5:4
304#define PM_REGSET10 R7:0, P5:3
305#define PM_REGSET11 R7:0, P5:2
306#define PM_REGSET12 R7:0, P5:1
307#define PM_REGSET13 R7:0, P5:0
Mike Frysinger584ecba2011-06-26 14:11:24 -0400308
Mike Frysingereed7b832011-06-26 23:11:19 -0400309#define _PM_PUSH(n, x, w, base) PM_REG##n = w[FP + ((x) - (base))];
310#define _PM_POP(n, x, w, base) w[FP + ((x) - (base))] = PM_REG##n;
311#define PM_PUSH_SYNC(n) [--sp] = (PM_REGSET##n);
312#define PM_POP_SYNC(n) (PM_REGSET##n) = [sp++];
313#define PM_PUSH(n, x) PM_REG##n = [FP++];
314#define PM_POP(n, x) [FP--] = PM_REG##n;
315#define PM_CORE_PUSH(n, x) _PM_PUSH(n, x, , COREMMR_BASE)
316#define PM_CORE_POP(n, x) _PM_POP(n, x, , COREMMR_BASE)
317#define PM_SYS_PUSH(n, x) _PM_PUSH(n, x, , SYSMMR_BASE)
318#define PM_SYS_POP(n, x) _PM_POP(n, x, , SYSMMR_BASE)
319#define PM_SYS_PUSH16(n, x) _PM_PUSH(n, x, w, SYSMMR_BASE)
320#define PM_SYS_POP16(n, x) _PM_POP(n, x, w, SYSMMR_BASE)
Mike Frysinger584ecba2011-06-26 14:11:24 -0400321
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800322ENTRY(_do_hibernate)
Mike Frysingereed7b832011-06-26 23:11:19 -0400323 /*
324 * Save the core regs early so we can blow them away when
325 * saving/restoring MMR states
326 */
327 [--sp] = (R7:0, P5:0);
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800328 [--sp] = fp;
329 [--sp] = usp;
330
331 [--sp] = i0;
332 [--sp] = i1;
333 [--sp] = i2;
334 [--sp] = i3;
335
336 [--sp] = m0;
337 [--sp] = m1;
338 [--sp] = m2;
339 [--sp] = m3;
340
341 [--sp] = l0;
342 [--sp] = l1;
343 [--sp] = l2;
344 [--sp] = l3;
345
346 [--sp] = b0;
347 [--sp] = b1;
348 [--sp] = b2;
349 [--sp] = b3;
350 [--sp] = a0.x;
351 [--sp] = a0.w;
352 [--sp] = a1.x;
353 [--sp] = a1.w;
354
355 [--sp] = LC0;
356 [--sp] = LC1;
357 [--sp] = LT0;
358 [--sp] = LT1;
359 [--sp] = LB0;
360 [--sp] = LB1;
361
Mike Frysingereed7b832011-06-26 23:11:19 -0400362 /* We can't push RETI directly as that'll change IPEND[4] */
363 r7 = RETI;
364 [--sp] = RETS;
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800365 [--sp] = ASTAT;
366 [--sp] = CYCLES;
367 [--sp] = CYCLES2;
Mike Frysingereed7b832011-06-26 23:11:19 -0400368 [--sp] = SYSCFG;
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800369 [--sp] = RETX;
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800370 [--sp] = SEQSTAT;
Mike Frysingereed7b832011-06-26 23:11:19 -0400371 [--sp] = r7;
372
373 /* Save first func arg in M3 */
374 M3 = R0;
375
376 /* Save system MMRs */
377 FP.H = hi(SYSMMR_BASE);
378 FP.L = lo(SYSMMR_BASE);
379
380#ifdef SIC_IMASK0
381 PM_SYS_PUSH(0, SIC_IMASK0)
382 PM_SYS_PUSH(1, SIC_IMASK1)
383# ifdef SIC_IMASK2
384 PM_SYS_PUSH(2, SIC_IMASK2)
385# endif
386#else
387 PM_SYS_PUSH(0, SIC_IMASK)
388#endif
389#ifdef SIC_IAR0
390 PM_SYS_PUSH(3, SIC_IAR0)
391 PM_SYS_PUSH(4, SIC_IAR1)
392 PM_SYS_PUSH(5, SIC_IAR2)
393#endif
394#ifdef SIC_IAR3
395 PM_SYS_PUSH(6, SIC_IAR3)
396#endif
397#ifdef SIC_IAR4
398 PM_SYS_PUSH(7, SIC_IAR4)
399 PM_SYS_PUSH(8, SIC_IAR5)
400 PM_SYS_PUSH(9, SIC_IAR6)
401#endif
402#ifdef SIC_IAR7
403 PM_SYS_PUSH(10, SIC_IAR7)
404#endif
405#ifdef SIC_IAR8
406 PM_SYS_PUSH(11, SIC_IAR8)
407 PM_SYS_PUSH(12, SIC_IAR9)
408 PM_SYS_PUSH(13, SIC_IAR10)
409#endif
410 PM_PUSH_SYNC(13)
411#ifdef SIC_IAR11
412 PM_SYS_PUSH(0, SIC_IAR11)
413#endif
414
415#ifdef SIC_IWR
416 PM_SYS_PUSH(1, SIC_IWR)
417#endif
418#ifdef SIC_IWR0
419 PM_SYS_PUSH(1, SIC_IWR0)
420#endif
421#ifdef SIC_IWR1
422 PM_SYS_PUSH(2, SIC_IWR1)
423#endif
424#ifdef SIC_IWR2
425 PM_SYS_PUSH(3, SIC_IWR2)
426#endif
427
428#ifdef PINT0_ASSIGN
429 PM_SYS_PUSH(4, PINT0_MASK_SET)
430 PM_SYS_PUSH(5, PINT1_MASK_SET)
431 PM_SYS_PUSH(6, PINT2_MASK_SET)
432 PM_SYS_PUSH(7, PINT3_MASK_SET)
433 PM_SYS_PUSH(8, PINT0_ASSIGN)
434 PM_SYS_PUSH(9, PINT1_ASSIGN)
435 PM_SYS_PUSH(10, PINT2_ASSIGN)
436 PM_SYS_PUSH(11, PINT3_ASSIGN)
437 PM_SYS_PUSH(12, PINT0_INVERT_SET)
438 PM_SYS_PUSH(13, PINT1_INVERT_SET)
439 PM_PUSH_SYNC(13)
440 PM_SYS_PUSH(0, PINT2_INVERT_SET)
441 PM_SYS_PUSH(1, PINT3_INVERT_SET)
442 PM_SYS_PUSH(2, PINT0_EDGE_SET)
443 PM_SYS_PUSH(3, PINT1_EDGE_SET)
444 PM_SYS_PUSH(4, PINT2_EDGE_SET)
445 PM_SYS_PUSH(5, PINT3_EDGE_SET)
446#endif
447
448 PM_SYS_PUSH16(6, SYSCR)
449
450 PM_SYS_PUSH16(7, EBIU_AMGCTL)
451 PM_SYS_PUSH(8, EBIU_AMBCTL0)
452 PM_SYS_PUSH(9, EBIU_AMBCTL1)
453#ifdef EBIU_FCTL
454 PM_SYS_PUSH(10, EBIU_MBSCTL)
455 PM_SYS_PUSH(11, EBIU_MODE)
456 PM_SYS_PUSH(12, EBIU_FCTL)
457 PM_PUSH_SYNC(12)
458#else
459 PM_PUSH_SYNC(9)
460#endif
461
462#ifdef PORTCIO_FER
463 /* 16bit loads can only be done with dregs */
464 PM_SYS_PUSH16(0, PORTCIO_DIR)
465 PM_SYS_PUSH16(1, PORTCIO_INEN)
466 PM_SYS_PUSH16(2, PORTCIO)
467 PM_SYS_PUSH16(3, PORTCIO_FER)
468 PM_SYS_PUSH16(4, PORTDIO_DIR)
469 PM_SYS_PUSH16(5, PORTDIO_INEN)
470 PM_SYS_PUSH16(6, PORTDIO)
471 PM_SYS_PUSH16(7, PORTDIO_FER)
472 PM_PUSH_SYNC(7)
473 PM_SYS_PUSH16(0, PORTEIO_DIR)
474 PM_SYS_PUSH16(1, PORTEIO_INEN)
475 PM_SYS_PUSH16(2, PORTEIO)
476 PM_SYS_PUSH16(3, PORTEIO_FER)
477 PM_PUSH_SYNC(3)
478#endif
479
480 /* Save Core MMRs */
481 I0.H = hi(COREMMR_BASE);
482 I0.L = lo(COREMMR_BASE);
483 I1 = I0;
484 I2 = I0;
485 I3 = I0;
486 B0 = I0;
487 B1 = I0;
488 B2 = I0;
489 B3 = I0;
490 I1.L = lo(DCPLB_ADDR0);
491 I2.L = lo(DCPLB_DATA0);
492 I3.L = lo(ICPLB_ADDR0);
493 B0.L = lo(ICPLB_DATA0);
494 B1.L = lo(EVT2);
495 B2.L = lo(IMASK);
496 B3.L = lo(TCNTL);
497
498 /* DCPLB Addr */
499 FP = I1;
500 PM_PUSH(0, DCPLB_ADDR0)
501 PM_PUSH(1, DCPLB_ADDR1)
502 PM_PUSH(2, DCPLB_ADDR2)
503 PM_PUSH(3, DCPLB_ADDR3)
504 PM_PUSH(4, DCPLB_ADDR4)
505 PM_PUSH(5, DCPLB_ADDR5)
506 PM_PUSH(6, DCPLB_ADDR6)
507 PM_PUSH(7, DCPLB_ADDR7)
508 PM_PUSH(8, DCPLB_ADDR8)
509 PM_PUSH(9, DCPLB_ADDR9)
510 PM_PUSH(10, DCPLB_ADDR10)
511 PM_PUSH(11, DCPLB_ADDR11)
512 PM_PUSH(12, DCPLB_ADDR12)
513 PM_PUSH(13, DCPLB_ADDR13)
514 PM_PUSH_SYNC(13)
515 PM_PUSH(0, DCPLB_ADDR14)
516 PM_PUSH(1, DCPLB_ADDR15)
517
518 /* DCPLB Data */
519 FP = I2;
520 PM_PUSH(2, DCPLB_DATA0)
521 PM_PUSH(3, DCPLB_DATA1)
522 PM_PUSH(4, DCPLB_DATA2)
523 PM_PUSH(5, DCPLB_DATA3)
524 PM_PUSH(6, DCPLB_DATA4)
525 PM_PUSH(7, DCPLB_DATA5)
526 PM_PUSH(8, DCPLB_DATA6)
527 PM_PUSH(9, DCPLB_DATA7)
528 PM_PUSH(10, DCPLB_DATA8)
529 PM_PUSH(11, DCPLB_DATA9)
530 PM_PUSH(12, DCPLB_DATA10)
531 PM_PUSH(13, DCPLB_DATA11)
532 PM_PUSH_SYNC(13)
533 PM_PUSH(0, DCPLB_DATA12)
534 PM_PUSH(1, DCPLB_DATA13)
535 PM_PUSH(2, DCPLB_DATA14)
536 PM_PUSH(3, DCPLB_DATA15)
537
538 /* ICPLB Addr */
539 FP = I3;
540 PM_PUSH(4, ICPLB_ADDR0)
541 PM_PUSH(5, ICPLB_ADDR1)
542 PM_PUSH(6, ICPLB_ADDR2)
543 PM_PUSH(7, ICPLB_ADDR3)
544 PM_PUSH(8, ICPLB_ADDR4)
545 PM_PUSH(9, ICPLB_ADDR5)
546 PM_PUSH(10, ICPLB_ADDR6)
547 PM_PUSH(11, ICPLB_ADDR7)
548 PM_PUSH(12, ICPLB_ADDR8)
549 PM_PUSH(13, ICPLB_ADDR9)
550 PM_PUSH_SYNC(13)
551 PM_PUSH(0, ICPLB_ADDR10)
552 PM_PUSH(1, ICPLB_ADDR11)
553 PM_PUSH(2, ICPLB_ADDR12)
554 PM_PUSH(3, ICPLB_ADDR13)
555 PM_PUSH(4, ICPLB_ADDR14)
556 PM_PUSH(5, ICPLB_ADDR15)
557
558 /* ICPLB Data */
559 FP = B0;
560 PM_PUSH(6, ICPLB_DATA0)
561 PM_PUSH(7, ICPLB_DATA1)
562 PM_PUSH(8, ICPLB_DATA2)
563 PM_PUSH(9, ICPLB_DATA3)
564 PM_PUSH(10, ICPLB_DATA4)
565 PM_PUSH(11, ICPLB_DATA5)
566 PM_PUSH(12, ICPLB_DATA6)
567 PM_PUSH(13, ICPLB_DATA7)
568 PM_PUSH_SYNC(13)
569 PM_PUSH(0, ICPLB_DATA8)
570 PM_PUSH(1, ICPLB_DATA9)
571 PM_PUSH(2, ICPLB_DATA10)
572 PM_PUSH(3, ICPLB_DATA11)
573 PM_PUSH(4, ICPLB_DATA12)
574 PM_PUSH(5, ICPLB_DATA13)
575 PM_PUSH(6, ICPLB_DATA14)
576 PM_PUSH(7, ICPLB_DATA15)
577
578 /* Event Vectors */
579 FP = B1;
580 PM_PUSH(8, EVT2)
581 PM_PUSH(9, EVT3)
582 FP += 4; /* EVT4 */
583 PM_PUSH(10, EVT5)
584 PM_PUSH(11, EVT6)
585 PM_PUSH(12, EVT7)
586 PM_PUSH(13, EVT8)
587 PM_PUSH_SYNC(13)
588 PM_PUSH(0, EVT9)
589 PM_PUSH(1, EVT10)
590 PM_PUSH(2, EVT11)
591 PM_PUSH(3, EVT12)
592 PM_PUSH(4, EVT13)
593 PM_PUSH(5, EVT14)
594 PM_PUSH(6, EVT15)
595
596 /* CEC */
597 FP = B2;
598 PM_PUSH(7, IMASK)
599 FP += 4; /* IPEND */
600 PM_PUSH(8, ILAT)
601 PM_PUSH(9, IPRIO)
602
603 /* Core Timer */
604 FP = B3;
605 PM_PUSH(10, TCNTL)
606 PM_PUSH(11, TPERIOD)
607 PM_PUSH(12, TSCALE)
608 PM_PUSH(13, TCOUNT)
609 PM_PUSH_SYNC(13)
610
611 /* Misc non-contiguous registers */
612 FP = I0;
613 PM_CORE_PUSH(0, DMEM_CONTROL);
614 PM_CORE_PUSH(1, IMEM_CONTROL);
615 PM_CORE_PUSH(2, TBUFCTL);
616 PM_PUSH_SYNC(2)
617
618 /* Setup args to hibernate mode early for pipeline optimization */
619 R0 = M3;
620 P1.H = _hibernate_mode;
621 P1.L = _hibernate_mode;
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800622
623 /* Save Magic, return address and Stack Pointer */
Mike Frysingereed7b832011-06-26 23:11:19 -0400624 P0 = 0;
625 R1.H = 0xDEAD; /* Hibernate Magic */
626 R1.L = 0xBEEF;
627 R2.H = .Lpm_resume_here;
628 R2.L = .Lpm_resume_here;
629 [P0++] = R1; /* Store Hibernate Magic */
630 [P0++] = R2; /* Save Return Address */
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800631 [P0++] = SP; /* Save Stack Pointer */
Mike Frysingereed7b832011-06-26 23:11:19 -0400632
633 /* Must use an indirect call as we need to jump to L1 */
634 call (P1); /* Goodbye */
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800635
Mike Frysinger1a8caee2008-07-16 17:07:26 +0800636.Lpm_resume_here:
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800637
Mike Frysingereed7b832011-06-26 23:11:19 -0400638 /* Restore Core MMRs */
639 I0.H = hi(COREMMR_BASE);
640 I0.L = lo(COREMMR_BASE);
641 I1 = I0;
642 I2 = I0;
643 I3 = I0;
644 B0 = I0;
645 B1 = I0;
646 B2 = I0;
647 B3 = I0;
648 I1.L = lo(DCPLB_ADDR15);
649 I2.L = lo(DCPLB_DATA15);
650 I3.L = lo(ICPLB_ADDR15);
651 B0.L = lo(ICPLB_DATA15);
652 B1.L = lo(EVT15);
653 B2.L = lo(IPRIO);
654 B3.L = lo(TCOUNT);
655
656 /* Misc non-contiguous registers */
657 FP = I0;
658 PM_POP_SYNC(2)
659 PM_CORE_POP(2, TBUFCTL)
660 PM_CORE_POP(1, IMEM_CONTROL)
661 PM_CORE_POP(0, DMEM_CONTROL)
662
663 /* Core Timer */
664 PM_POP_SYNC(13)
665 FP = B3;
666 PM_POP(13, TCOUNT)
667 PM_POP(12, TSCALE)
668 PM_POP(11, TPERIOD)
669 PM_POP(10, TCNTL)
670
671 /* CEC */
672 FP = B2;
673 PM_POP(9, IPRIO)
674 PM_POP(8, ILAT)
675 FP += -4; /* IPEND */
676 PM_POP(7, IMASK)
677
678 /* Event Vectors */
679 FP = B1;
680 PM_POP(6, EVT15)
681 PM_POP(5, EVT14)
682 PM_POP(4, EVT13)
683 PM_POP(3, EVT12)
684 PM_POP(2, EVT11)
685 PM_POP(1, EVT10)
686 PM_POP(0, EVT9)
687 PM_POP_SYNC(13)
688 PM_POP(13, EVT8)
689 PM_POP(12, EVT7)
690 PM_POP(11, EVT6)
691 PM_POP(10, EVT5)
692 FP += -4; /* EVT4 */
693 PM_POP(9, EVT3)
694 PM_POP(8, EVT2)
695
696 /* ICPLB Data */
697 FP = B0;
698 PM_POP(7, ICPLB_DATA15)
699 PM_POP(6, ICPLB_DATA14)
700 PM_POP(5, ICPLB_DATA13)
701 PM_POP(4, ICPLB_DATA12)
702 PM_POP(3, ICPLB_DATA11)
703 PM_POP(2, ICPLB_DATA10)
704 PM_POP(1, ICPLB_DATA9)
705 PM_POP(0, ICPLB_DATA8)
706 PM_POP_SYNC(13)
707 PM_POP(13, ICPLB_DATA7)
708 PM_POP(12, ICPLB_DATA6)
709 PM_POP(11, ICPLB_DATA5)
710 PM_POP(10, ICPLB_DATA4)
711 PM_POP(9, ICPLB_DATA3)
712 PM_POP(8, ICPLB_DATA2)
713 PM_POP(7, ICPLB_DATA1)
714 PM_POP(6, ICPLB_DATA0)
715
716 /* ICPLB Addr */
717 FP = I3;
718 PM_POP(5, ICPLB_ADDR15)
719 PM_POP(4, ICPLB_ADDR14)
720 PM_POP(3, ICPLB_ADDR13)
721 PM_POP(2, ICPLB_ADDR12)
722 PM_POP(1, ICPLB_ADDR11)
723 PM_POP(0, ICPLB_ADDR10)
724 PM_POP_SYNC(13)
725 PM_POP(13, ICPLB_ADDR9)
726 PM_POP(12, ICPLB_ADDR8)
727 PM_POP(11, ICPLB_ADDR7)
728 PM_POP(10, ICPLB_ADDR6)
729 PM_POP(9, ICPLB_ADDR5)
730 PM_POP(8, ICPLB_ADDR4)
731 PM_POP(7, ICPLB_ADDR3)
732 PM_POP(6, ICPLB_ADDR2)
733 PM_POP(5, ICPLB_ADDR1)
734 PM_POP(4, ICPLB_ADDR0)
735
736 /* DCPLB Data */
737 FP = I2;
738 PM_POP(3, DCPLB_DATA15)
739 PM_POP(2, DCPLB_DATA14)
740 PM_POP(1, DCPLB_DATA13)
741 PM_POP(0, DCPLB_DATA12)
742 PM_POP_SYNC(13)
743 PM_POP(13, DCPLB_DATA11)
744 PM_POP(12, DCPLB_DATA10)
745 PM_POP(11, DCPLB_DATA9)
746 PM_POP(10, DCPLB_DATA8)
747 PM_POP(9, DCPLB_DATA7)
748 PM_POP(8, DCPLB_DATA6)
749 PM_POP(7, DCPLB_DATA5)
750 PM_POP(6, DCPLB_DATA4)
751 PM_POP(5, DCPLB_DATA3)
752 PM_POP(4, DCPLB_DATA2)
753 PM_POP(3, DCPLB_DATA1)
754 PM_POP(2, DCPLB_DATA0)
755
756 /* DCPLB Addr */
757 FP = I1;
758 PM_POP(1, DCPLB_ADDR15)
759 PM_POP(0, DCPLB_ADDR14)
760 PM_POP_SYNC(13)
761 PM_POP(13, DCPLB_ADDR13)
762 PM_POP(12, DCPLB_ADDR12)
763 PM_POP(11, DCPLB_ADDR11)
764 PM_POP(10, DCPLB_ADDR10)
765 PM_POP(9, DCPLB_ADDR9)
766 PM_POP(8, DCPLB_ADDR8)
767 PM_POP(7, DCPLB_ADDR7)
768 PM_POP(6, DCPLB_ADDR6)
769 PM_POP(5, DCPLB_ADDR5)
770 PM_POP(4, DCPLB_ADDR4)
771 PM_POP(3, DCPLB_ADDR3)
772 PM_POP(2, DCPLB_ADDR2)
773 PM_POP(1, DCPLB_ADDR1)
774 PM_POP(0, DCPLB_ADDR0)
775
776 /* Restore System MMRs */
777 FP.H = hi(SYSMMR_BASE);
778 FP.L = lo(SYSMMR_BASE);
779
780#ifdef PORTCIO_FER
781 PM_POP_SYNC(3)
782 PM_SYS_POP16(3, PORTEIO_FER)
783 PM_SYS_POP16(2, PORTEIO)
784 PM_SYS_POP16(1, PORTEIO_INEN)
785 PM_SYS_POP16(0, PORTEIO_DIR)
786 PM_POP_SYNC(7)
787 PM_SYS_POP16(7, PORTDIO_FER)
788 PM_SYS_POP16(6, PORTDIO)
789 PM_SYS_POP16(5, PORTDIO_INEN)
790 PM_SYS_POP16(4, PORTDIO_DIR)
791 PM_SYS_POP16(3, PORTCIO_FER)
792 PM_SYS_POP16(2, PORTCIO)
793 PM_SYS_POP16(1, PORTCIO_INEN)
794 PM_SYS_POP16(0, PORTCIO_DIR)
795#endif
796
797#ifdef EBIU_FCTL
798 PM_POP_SYNC(12)
799 PM_SYS_POP(12, EBIU_FCTL)
800 PM_SYS_POP(11, EBIU_MODE)
801 PM_SYS_POP(10, EBIU_MBSCTL)
802#else
803 PM_POP_SYNC(9)
804#endif
805 PM_SYS_POP(9, EBIU_AMBCTL1)
806 PM_SYS_POP(8, EBIU_AMBCTL0)
807 PM_SYS_POP16(7, EBIU_AMGCTL)
808
809 PM_SYS_POP16(6, SYSCR)
810
811#ifdef PINT0_ASSIGN
812 PM_SYS_POP(5, PINT3_EDGE_SET)
813 PM_SYS_POP(4, PINT2_EDGE_SET)
814 PM_SYS_POP(3, PINT1_EDGE_SET)
815 PM_SYS_POP(2, PINT0_EDGE_SET)
816 PM_SYS_POP(1, PINT3_INVERT_SET)
817 PM_SYS_POP(0, PINT2_INVERT_SET)
818 PM_POP_SYNC(13)
819 PM_SYS_POP(13, PINT1_INVERT_SET)
820 PM_SYS_POP(12, PINT0_INVERT_SET)
821 PM_SYS_POP(11, PINT3_ASSIGN)
822 PM_SYS_POP(10, PINT2_ASSIGN)
823 PM_SYS_POP(9, PINT1_ASSIGN)
824 PM_SYS_POP(8, PINT0_ASSIGN)
825 PM_SYS_POP(7, PINT3_MASK_SET)
826 PM_SYS_POP(6, PINT2_MASK_SET)
827 PM_SYS_POP(5, PINT1_MASK_SET)
828 PM_SYS_POP(4, PINT0_MASK_SET)
829#endif
830
831#ifdef SIC_IWR2
832 PM_SYS_POP(3, SIC_IWR2)
833#endif
834#ifdef SIC_IWR1
835 PM_SYS_POP(2, SIC_IWR1)
836#endif
837#ifdef SIC_IWR0
838 PM_SYS_POP(1, SIC_IWR0)
839#endif
840#ifdef SIC_IWR
841 PM_SYS_POP(1, SIC_IWR)
842#endif
843
844#ifdef SIC_IAR11
845 PM_SYS_POP(0, SIC_IAR11)
846#endif
847 PM_POP_SYNC(13)
848#ifdef SIC_IAR8
849 PM_SYS_POP(13, SIC_IAR10)
850 PM_SYS_POP(12, SIC_IAR9)
851 PM_SYS_POP(11, SIC_IAR8)
852#endif
853#ifdef SIC_IAR7
854 PM_SYS_POP(10, SIC_IAR7)
855#endif
856#ifdef SIC_IAR6
857 PM_SYS_POP(9, SIC_IAR6)
858 PM_SYS_POP(8, SIC_IAR5)
859 PM_SYS_POP(7, SIC_IAR4)
860#endif
861#ifdef SIC_IAR3
862 PM_SYS_POP(6, SIC_IAR3)
863#endif
864#ifdef SIC_IAR0
865 PM_SYS_POP(5, SIC_IAR2)
866 PM_SYS_POP(4, SIC_IAR1)
867 PM_SYS_POP(3, SIC_IAR0)
868#endif
869#ifdef SIC_IMASK0
870# ifdef SIC_IMASK2
871 PM_SYS_POP(2, SIC_IMASK2)
872# endif
873 PM_SYS_POP(1, SIC_IMASK1)
874 PM_SYS_POP(0, SIC_IMASK0)
875#else
876 PM_SYS_POP(0, SIC_IMASK)
877#endif
878
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800879 /* Restore Core Registers */
Mike Frysingereed7b832011-06-26 23:11:19 -0400880 RETI = [sp++];
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800881 SEQSTAT = [sp++];
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800882 RETX = [sp++];
Mike Frysingereed7b832011-06-26 23:11:19 -0400883 SYSCFG = [sp++];
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800884 CYCLES2 = [sp++];
885 CYCLES = [sp++];
886 ASTAT = [sp++];
Mike Frysingereed7b832011-06-26 23:11:19 -0400887 RETS = [sp++];
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800888
889 LB1 = [sp++];
890 LB0 = [sp++];
891 LT1 = [sp++];
892 LT0 = [sp++];
893 LC1 = [sp++];
894 LC0 = [sp++];
895
896 a1.w = [sp++];
897 a1.x = [sp++];
898 a0.w = [sp++];
899 a0.x = [sp++];
900 b3 = [sp++];
901 b2 = [sp++];
902 b1 = [sp++];
903 b0 = [sp++];
904
905 l3 = [sp++];
906 l2 = [sp++];
907 l1 = [sp++];
908 l0 = [sp++];
909
910 m3 = [sp++];
911 m2 = [sp++];
912 m1 = [sp++];
913 m0 = [sp++];
914
915 i3 = [sp++];
916 i2 = [sp++];
917 i1 = [sp++];
918 i0 = [sp++];
919
920 usp = [sp++];
921 fp = [sp++];
Mike Frysingereed7b832011-06-26 23:11:19 -0400922 (R7:0, P5:0) = [sp++];
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800923
924 [--sp] = RETI; /* Clear Global Interrupt Disable */
925 SP += 4;
926
Michael Hennerich1efc80b2008-07-19 16:57:32 +0800927 RTS;
Mike Frysinger1a8caee2008-07-16 17:07:26 +0800928ENDPROC(_do_hibernate)