aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Miao <realmz6@gmail.com>2012-05-16 06:26:10 -0400
committerBob Liu <lliubbo@gmail.com>2012-05-21 02:54:24 -0400
commit93f89519fd31c21e5d606faf4091f5905db38412 (patch)
tree642d8605e14281e8f69a54e2130a7898754289ba
parentb2cfc653a513f347114c85ed8e75456ea0159c18 (diff)
blackfin: bf60x: add power management support
Add bf60x cpu pm callbacks and change blackfin pm framework to support bf60x. Signed-off-by: Steven Miao <realmz6@gmail.com> Signed-off-by: Bob Liu <lliubbo@gmail.com>
-rw-r--r--arch/blackfin/include/asm/dpmc.h632
-rw-r--r--arch/blackfin/include/asm/pm.h32
-rw-r--r--arch/blackfin/mach-bf609/hibernate.S62
-rw-r--r--arch/blackfin/mach-bf609/include/mach/pm.h21
-rw-r--r--arch/blackfin/mach-bf609/pm.c310
-rw-r--r--arch/blackfin/mach-common/Makefile5
-rw-r--r--arch/blackfin/mach-common/dpmc_modes.S604
-rw-r--r--arch/blackfin/mach-common/pm.c34
8 files changed, 1105 insertions, 595 deletions
diff --git a/arch/blackfin/include/asm/dpmc.h b/arch/blackfin/include/asm/dpmc.h
index c4ec959dad78..b47399cda6ed 100644
--- a/arch/blackfin/include/asm/dpmc.h
+++ b/arch/blackfin/include/asm/dpmc.h
@@ -9,6 +9,637 @@
9#ifndef _BLACKFIN_DPMC_H_ 9#ifndef _BLACKFIN_DPMC_H_
10#define _BLACKFIN_DPMC_H_ 10#define _BLACKFIN_DPMC_H_
11 11
12#ifdef __ASSEMBLY__
13#define PM_REG0 R7
14#define PM_REG1 R6
15#define PM_REG2 R5
16#define PM_REG3 R4
17#define PM_REG4 R3
18#define PM_REG5 R2
19#define PM_REG6 R1
20#define PM_REG7 R0
21#define PM_REG8 P5
22#define PM_REG9 P4
23#define PM_REG10 P3
24#define PM_REG11 P2
25#define PM_REG12 P1
26#define PM_REG13 P0
27
28#define PM_REGSET0 R7:7
29#define PM_REGSET1 R7:6
30#define PM_REGSET2 R7:5
31#define PM_REGSET3 R7:4
32#define PM_REGSET4 R7:3
33#define PM_REGSET5 R7:2
34#define PM_REGSET6 R7:1
35#define PM_REGSET7 R7:0
36#define PM_REGSET8 R7:0, P5:5
37#define PM_REGSET9 R7:0, P5:4
38#define PM_REGSET10 R7:0, P5:3
39#define PM_REGSET11 R7:0, P5:2
40#define PM_REGSET12 R7:0, P5:1
41#define PM_REGSET13 R7:0, P5:0
42
43#define _PM_PUSH(n, x, w, base) PM_REG##n = w[FP + ((x) - (base))];
44#define _PM_POP(n, x, w, base) w[FP + ((x) - (base))] = PM_REG##n;
45#define PM_PUSH_SYNC(n) [--sp] = (PM_REGSET##n);
46#define PM_POP_SYNC(n) (PM_REGSET##n) = [sp++];
47#define PM_PUSH(n, x) PM_REG##n = [FP++];
48#define PM_POP(n, x) [FP--] = PM_REG##n;
49#define PM_CORE_PUSH(n, x) _PM_PUSH(n, x, , COREMMR_BASE)
50#define PM_CORE_POP(n, x) _PM_POP(n, x, , COREMMR_BASE)
51#define PM_SYS_PUSH(n, x) _PM_PUSH(n, x, , SYSMMR_BASE)
52#define PM_SYS_POP(n, x) _PM_POP(n, x, , SYSMMR_BASE)
53#define PM_SYS_PUSH16(n, x) _PM_PUSH(n, x, w, SYSMMR_BASE)
54#define PM_SYS_POP16(n, x) _PM_POP(n, x, w, SYSMMR_BASE)
55
56
57 .macro bfin_cpu_reg_save
58 /*
59 * Save the core regs early so we can blow them away when
60 * saving/restoring MMR states
61 */
62 [--sp] = (R7:0, P5:0);
63 [--sp] = fp;
64 [--sp] = usp;
65
66 [--sp] = i0;
67 [--sp] = i1;
68 [--sp] = i2;
69 [--sp] = i3;
70
71 [--sp] = m0;
72 [--sp] = m1;
73 [--sp] = m2;
74 [--sp] = m3;
75
76 [--sp] = l0;
77 [--sp] = l1;
78 [--sp] = l2;
79 [--sp] = l3;
80
81 [--sp] = b0;
82 [--sp] = b1;
83 [--sp] = b2;
84 [--sp] = b3;
85 [--sp] = a0.x;
86 [--sp] = a0.w;
87 [--sp] = a1.x;
88 [--sp] = a1.w;
89
90 [--sp] = LC0;
91 [--sp] = LC1;
92 [--sp] = LT0;
93 [--sp] = LT1;
94 [--sp] = LB0;
95 [--sp] = LB1;
96
97 /* We can't push RETI directly as that'll change IPEND[4] */
98 r7 = RETI;
99 [--sp] = RETS;
100 [--sp] = ASTAT;
101 [--sp] = CYCLES;
102 [--sp] = CYCLES2;
103 [--sp] = SYSCFG;
104 [--sp] = RETX;
105 [--sp] = SEQSTAT;
106 [--sp] = r7;
107
108 /* Save first func arg in M3 */
109 M3 = R0;
110 .endm
111
112 .macro bfin_cpu_reg_restore
113 /* Restore Core Registers */
114 RETI = [sp++];
115 SEQSTAT = [sp++];
116 RETX = [sp++];
117 SYSCFG = [sp++];
118 CYCLES2 = [sp++];
119 CYCLES = [sp++];
120 ASTAT = [sp++];
121 RETS = [sp++];
122
123 LB1 = [sp++];
124 LB0 = [sp++];
125 LT1 = [sp++];
126 LT0 = [sp++];
127 LC1 = [sp++];
128 LC0 = [sp++];
129
130 a1.w = [sp++];
131 a1.x = [sp++];
132 a0.w = [sp++];
133 a0.x = [sp++];
134 b3 = [sp++];
135 b2 = [sp++];
136 b1 = [sp++];
137 b0 = [sp++];
138
139 l3 = [sp++];
140 l2 = [sp++];
141 l1 = [sp++];
142 l0 = [sp++];
143
144 m3 = [sp++];
145 m2 = [sp++];
146 m1 = [sp++];
147 m0 = [sp++];
148
149 i3 = [sp++];
150 i2 = [sp++];
151 i1 = [sp++];
152 i0 = [sp++];
153
154 usp = [sp++];
155 fp = [sp++];
156 (R7:0, P5:0) = [sp++];
157
158 .endm
159
160 .macro bfin_sys_mmr_save
161 /* Save system MMRs */
162 FP.H = hi(SYSMMR_BASE);
163 FP.L = lo(SYSMMR_BASE);
164#ifdef SIC_IMASK0
165 PM_SYS_PUSH(0, SIC_IMASK0)
166 PM_SYS_PUSH(1, SIC_IMASK1)
167# ifdef SIC_IMASK2
168 PM_SYS_PUSH(2, SIC_IMASK2)
169# endif
170#else
171# ifdef SIC_IMASK
172 PM_SYS_PUSH(0, SIC_IMASK)
173# endif
174#endif
175
176#ifdef SIC_IAR0
177 PM_SYS_PUSH(3, SIC_IAR0)
178 PM_SYS_PUSH(4, SIC_IAR1)
179 PM_SYS_PUSH(5, SIC_IAR2)
180#endif
181#ifdef SIC_IAR3
182 PM_SYS_PUSH(6, SIC_IAR3)
183#endif
184#ifdef SIC_IAR4
185 PM_SYS_PUSH(7, SIC_IAR4)
186 PM_SYS_PUSH(8, SIC_IAR5)
187 PM_SYS_PUSH(9, SIC_IAR6)
188#endif
189#ifdef SIC_IAR7
190 PM_SYS_PUSH(10, SIC_IAR7)
191#endif
192#ifdef SIC_IAR8
193 PM_SYS_PUSH(11, SIC_IAR8)
194 PM_SYS_PUSH(12, SIC_IAR9)
195 PM_SYS_PUSH(13, SIC_IAR10)
196#endif
197 PM_PUSH_SYNC(13)
198#ifdef SIC_IAR11
199 PM_SYS_PUSH(0, SIC_IAR11)
200#endif
201
202#ifdef SIC_IWR
203 PM_SYS_PUSH(1, SIC_IWR)
204#endif
205#ifdef SIC_IWR0
206 PM_SYS_PUSH(1, SIC_IWR0)
207#endif
208#ifdef SIC_IWR1
209 PM_SYS_PUSH(2, SIC_IWR1)
210#endif
211#ifdef SIC_IWR2
212 PM_SYS_PUSH(3, SIC_IWR2)
213#endif
214
215#ifdef PINT0_ASSIGN
216 PM_SYS_PUSH(4, PINT0_MASK_SET)
217 PM_SYS_PUSH(5, PINT1_MASK_SET)
218 PM_SYS_PUSH(6, PINT2_MASK_SET)
219 PM_SYS_PUSH(7, PINT3_MASK_SET)
220 PM_SYS_PUSH(8, PINT0_ASSIGN)
221 PM_SYS_PUSH(9, PINT1_ASSIGN)
222 PM_SYS_PUSH(10, PINT2_ASSIGN)
223 PM_SYS_PUSH(11, PINT3_ASSIGN)
224 PM_SYS_PUSH(12, PINT0_INVERT_SET)
225 PM_SYS_PUSH(13, PINT1_INVERT_SET)
226 PM_PUSH_SYNC(13)
227 PM_SYS_PUSH(0, PINT2_INVERT_SET)
228 PM_SYS_PUSH(1, PINT3_INVERT_SET)
229 PM_SYS_PUSH(2, PINT0_EDGE_SET)
230 PM_SYS_PUSH(3, PINT1_EDGE_SET)
231 PM_SYS_PUSH(4, PINT2_EDGE_SET)
232 PM_SYS_PUSH(5, PINT3_EDGE_SET)
233#endif
234
235#ifdef SYSCR
236 PM_SYS_PUSH16(6, SYSCR)
237#endif
238
239#ifdef EBIU_AMGCTL
240 PM_SYS_PUSH16(7, EBIU_AMGCTL)
241 PM_SYS_PUSH(8, EBIU_AMBCTL0)
242 PM_SYS_PUSH(9, EBIU_AMBCTL1)
243#endif
244#ifdef EBIU_FCTL
245 PM_SYS_PUSH(10, EBIU_MBSCTL)
246 PM_SYS_PUSH(11, EBIU_MODE)
247 PM_SYS_PUSH(12, EBIU_FCTL)
248 PM_PUSH_SYNC(12)
249#else
250 PM_PUSH_SYNC(9)
251#endif
252 .endm
253
254
255 .macro bfin_sys_mmr_restore
256/* Restore System MMRs */
257 FP.H = hi(SYSMMR_BASE);
258 FP.L = lo(SYSMMR_BASE);
259
260#ifdef EBIU_FCTL
261 PM_POP_SYNC(12)
262 PM_SYS_POP(12, EBIU_FCTL)
263 PM_SYS_POP(11, EBIU_MODE)
264 PM_SYS_POP(10, EBIU_MBSCTL)
265#else
266 PM_POP_SYNC(9)
267#endif
268
269#ifdef EBIU_AMBCTL
270 PM_SYS_POP(9, EBIU_AMBCTL1)
271 PM_SYS_POP(8, EBIU_AMBCTL0)
272 PM_SYS_POP16(7, EBIU_AMGCTL)
273#endif
274
275#ifdef SYSCR
276 PM_SYS_POP16(6, SYSCR)
277#endif
278
279#ifdef PINT0_ASSIGN
280 PM_SYS_POP(5, PINT3_EDGE_SET)
281 PM_SYS_POP(4, PINT2_EDGE_SET)
282 PM_SYS_POP(3, PINT1_EDGE_SET)
283 PM_SYS_POP(2, PINT0_EDGE_SET)
284 PM_SYS_POP(1, PINT3_INVERT_SET)
285 PM_SYS_POP(0, PINT2_INVERT_SET)
286 PM_POP_SYNC(13)
287 PM_SYS_POP(13, PINT1_INVERT_SET)
288 PM_SYS_POP(12, PINT0_INVERT_SET)
289 PM_SYS_POP(11, PINT3_ASSIGN)
290 PM_SYS_POP(10, PINT2_ASSIGN)
291 PM_SYS_POP(9, PINT1_ASSIGN)
292 PM_SYS_POP(8, PINT0_ASSIGN)
293 PM_SYS_POP(7, PINT3_MASK_SET)
294 PM_SYS_POP(6, PINT2_MASK_SET)
295 PM_SYS_POP(5, PINT1_MASK_SET)
296 PM_SYS_POP(4, PINT0_MASK_SET)
297#endif
298
299#ifdef SIC_IWR2
300 PM_SYS_POP(3, SIC_IWR2)
301#endif
302#ifdef SIC_IWR1
303 PM_SYS_POP(2, SIC_IWR1)
304#endif
305#ifdef SIC_IWR0
306 PM_SYS_POP(1, SIC_IWR0)
307#endif
308#ifdef SIC_IWR
309 PM_SYS_POP(1, SIC_IWR)
310#endif
311
312#ifdef SIC_IAR11
313 PM_SYS_POP(0, SIC_IAR11)
314#endif
315 PM_POP_SYNC(13)
316#ifdef SIC_IAR8
317 PM_SYS_POP(13, SIC_IAR10)
318 PM_SYS_POP(12, SIC_IAR9)
319 PM_SYS_POP(11, SIC_IAR8)
320#endif
321#ifdef SIC_IAR7
322 PM_SYS_POP(10, SIC_IAR7)
323#endif
324#ifdef SIC_IAR6
325 PM_SYS_POP(9, SIC_IAR6)
326 PM_SYS_POP(8, SIC_IAR5)
327 PM_SYS_POP(7, SIC_IAR4)
328#endif
329#ifdef SIC_IAR3
330 PM_SYS_POP(6, SIC_IAR3)
331#endif
332#ifdef SIC_IAR0
333 PM_SYS_POP(5, SIC_IAR2)
334 PM_SYS_POP(4, SIC_IAR1)
335 PM_SYS_POP(3, SIC_IAR0)
336#endif
337#ifdef SIC_IMASK0
338# ifdef SIC_IMASK2
339 PM_SYS_POP(2, SIC_IMASK2)
340# endif
341 PM_SYS_POP(1, SIC_IMASK1)
342 PM_SYS_POP(0, SIC_IMASK0)
343#else
344# ifdef SIC_IMASK
345 PM_SYS_POP(0, SIC_IMASK)
346# endif
347#endif
348 .endm
349
350 .macro bfin_core_mmr_save
351 /* Save Core MMRs */
352 I0.H = hi(COREMMR_BASE);
353 I0.L = lo(COREMMR_BASE);
354 I1 = I0;
355 I2 = I0;
356 I3 = I0;
357 B0 = I0;
358 B1 = I0;
359 B2 = I0;
360 B3 = I0;
361 I1.L = lo(DCPLB_ADDR0);
362 I2.L = lo(DCPLB_DATA0);
363 I3.L = lo(ICPLB_ADDR0);
364 B0.L = lo(ICPLB_DATA0);
365 B1.L = lo(EVT2);
366 B2.L = lo(IMASK);
367 B3.L = lo(TCNTL);
368
369 /* Event Vectors */
370 FP = B1;
371 PM_PUSH(0, EVT2)
372 PM_PUSH(1, EVT3)
373 FP += 4; /* EVT4 */
374 PM_PUSH(2, EVT5)
375 PM_PUSH(3, EVT6)
376 PM_PUSH(4, EVT7)
377 PM_PUSH(5, EVT8)
378 PM_PUSH_SYNC(5)
379
380 PM_PUSH(0, EVT9)
381 PM_PUSH(1, EVT10)
382 PM_PUSH(2, EVT11)
383 PM_PUSH(3, EVT12)
384 PM_PUSH(4, EVT13)
385 PM_PUSH(5, EVT14)
386 PM_PUSH(6, EVT15)
387
388 /* CEC */
389 FP = B2;
390 PM_PUSH(7, IMASK)
391 FP += 4; /* IPEND */
392 PM_PUSH(8, ILAT)
393 PM_PUSH(9, IPRIO)
394
395 /* Core Timer */
396 FP = B3;
397 PM_PUSH(10, TCNTL)
398 PM_PUSH(11, TPERIOD)
399 PM_PUSH(12, TSCALE)
400 PM_PUSH(13, TCOUNT)
401 PM_PUSH_SYNC(13)
402
403 /* Misc non-contiguous registers */
404 FP = I0;
405 PM_CORE_PUSH(0, DMEM_CONTROL);
406 PM_CORE_PUSH(1, IMEM_CONTROL);
407 PM_CORE_PUSH(2, TBUFCTL);
408 PM_PUSH_SYNC(2)
409
410 /* DCPLB Addr */
411 FP = I1;
412 PM_PUSH(0, DCPLB_ADDR0)
413 PM_PUSH(1, DCPLB_ADDR1)
414 PM_PUSH(2, DCPLB_ADDR2)
415 PM_PUSH(3, DCPLB_ADDR3)
416 PM_PUSH(4, DCPLB_ADDR4)
417 PM_PUSH(5, DCPLB_ADDR5)
418 PM_PUSH(6, DCPLB_ADDR6)
419 PM_PUSH(7, DCPLB_ADDR7)
420 PM_PUSH(8, DCPLB_ADDR8)
421 PM_PUSH(9, DCPLB_ADDR9)
422 PM_PUSH(10, DCPLB_ADDR10)
423 PM_PUSH(11, DCPLB_ADDR11)
424 PM_PUSH(12, DCPLB_ADDR12)
425 PM_PUSH(13, DCPLB_ADDR13)
426 PM_PUSH_SYNC(13)
427 PM_PUSH(0, DCPLB_ADDR14)
428 PM_PUSH(1, DCPLB_ADDR15)
429
430 /* DCPLB Data */
431 FP = I2;
432 PM_PUSH(2, DCPLB_DATA0)
433 PM_PUSH(3, DCPLB_DATA1)
434 PM_PUSH(4, DCPLB_DATA2)
435 PM_PUSH(5, DCPLB_DATA3)
436 PM_PUSH(6, DCPLB_DATA4)
437 PM_PUSH(7, DCPLB_DATA5)
438 PM_PUSH(8, DCPLB_DATA6)
439 PM_PUSH(9, DCPLB_DATA7)
440 PM_PUSH(10, DCPLB_DATA8)
441 PM_PUSH(11, DCPLB_DATA9)
442 PM_PUSH(12, DCPLB_DATA10)
443 PM_PUSH(13, DCPLB_DATA11)
444 PM_PUSH_SYNC(13)
445 PM_PUSH(0, DCPLB_DATA12)
446 PM_PUSH(1, DCPLB_DATA13)
447 PM_PUSH(2, DCPLB_DATA14)
448 PM_PUSH(3, DCPLB_DATA15)
449
450 /* ICPLB Addr */
451 FP = I3;
452 PM_PUSH(4, ICPLB_ADDR0)
453 PM_PUSH(5, ICPLB_ADDR1)
454 PM_PUSH(6, ICPLB_ADDR2)
455 PM_PUSH(7, ICPLB_ADDR3)
456 PM_PUSH(8, ICPLB_ADDR4)
457 PM_PUSH(9, ICPLB_ADDR5)
458 PM_PUSH(10, ICPLB_ADDR6)
459 PM_PUSH(11, ICPLB_ADDR7)
460 PM_PUSH(12, ICPLB_ADDR8)
461 PM_PUSH(13, ICPLB_ADDR9)
462 PM_PUSH_SYNC(13)
463 PM_PUSH(0, ICPLB_ADDR10)
464 PM_PUSH(1, ICPLB_ADDR11)
465 PM_PUSH(2, ICPLB_ADDR12)
466 PM_PUSH(3, ICPLB_ADDR13)
467 PM_PUSH(4, ICPLB_ADDR14)
468 PM_PUSH(5, ICPLB_ADDR15)
469
470 /* ICPLB Data */
471 FP = B0;
472 PM_PUSH(6, ICPLB_DATA0)
473 PM_PUSH(7, ICPLB_DATA1)
474 PM_PUSH(8, ICPLB_DATA2)
475 PM_PUSH(9, ICPLB_DATA3)
476 PM_PUSH(10, ICPLB_DATA4)
477 PM_PUSH(11, ICPLB_DATA5)
478 PM_PUSH(12, ICPLB_DATA6)
479 PM_PUSH(13, ICPLB_DATA7)
480 PM_PUSH_SYNC(13)
481 PM_PUSH(0, ICPLB_DATA8)
482 PM_PUSH(1, ICPLB_DATA9)
483 PM_PUSH(2, ICPLB_DATA10)
484 PM_PUSH(3, ICPLB_DATA11)
485 PM_PUSH(4, ICPLB_DATA12)
486 PM_PUSH(5, ICPLB_DATA13)
487 PM_PUSH(6, ICPLB_DATA14)
488 PM_PUSH(7, ICPLB_DATA15)
489 PM_PUSH_SYNC(7)
490 .endm
491
492 .macro bfin_core_mmr_restore
493 /* Restore Core MMRs */
494 I0.H = hi(COREMMR_BASE);
495 I0.L = lo(COREMMR_BASE);
496 I1 = I0;
497 I2 = I0;
498 I3 = I0;
499 B0 = I0;
500 B1 = I0;
501 B2 = I0;
502 B3 = I0;
503 I1.L = lo(DCPLB_ADDR15);
504 I2.L = lo(DCPLB_DATA15);
505 I3.L = lo(ICPLB_ADDR15);
506 B0.L = lo(ICPLB_DATA15);
507 B1.L = lo(EVT15);
508 B2.L = lo(IPRIO);
509 B3.L = lo(TCOUNT);
510
511 /* ICPLB Data */
512 FP = B0;
513 PM_POP_SYNC(7)
514 PM_POP(7, ICPLB_DATA15)
515 PM_POP(6, ICPLB_DATA14)
516 PM_POP(5, ICPLB_DATA13)
517 PM_POP(4, ICPLB_DATA12)
518 PM_POP(3, ICPLB_DATA11)
519 PM_POP(2, ICPLB_DATA10)
520 PM_POP(1, ICPLB_DATA9)
521 PM_POP(0, ICPLB_DATA8)
522 PM_POP_SYNC(13)
523 PM_POP(13, ICPLB_DATA7)
524 PM_POP(12, ICPLB_DATA6)
525 PM_POP(11, ICPLB_DATA5)
526 PM_POP(10, ICPLB_DATA4)
527 PM_POP(9, ICPLB_DATA3)
528 PM_POP(8, ICPLB_DATA2)
529 PM_POP(7, ICPLB_DATA1)
530 PM_POP(6, ICPLB_DATA0)
531
532 /* ICPLB Addr */
533 FP = I3;
534 PM_POP(5, ICPLB_ADDR15)
535 PM_POP(4, ICPLB_ADDR14)
536 PM_POP(3, ICPLB_ADDR13)
537 PM_POP(2, ICPLB_ADDR12)
538 PM_POP(1, ICPLB_ADDR11)
539 PM_POP(0, ICPLB_ADDR10)
540 PM_POP_SYNC(13)
541 PM_POP(13, ICPLB_ADDR9)
542 PM_POP(12, ICPLB_ADDR8)
543 PM_POP(11, ICPLB_ADDR7)
544 PM_POP(10, ICPLB_ADDR6)
545 PM_POP(9, ICPLB_ADDR5)
546 PM_POP(8, ICPLB_ADDR4)
547 PM_POP(7, ICPLB_ADDR3)
548 PM_POP(6, ICPLB_ADDR2)
549 PM_POP(5, ICPLB_ADDR1)
550 PM_POP(4, ICPLB_ADDR0)
551
552 /* DCPLB Data */
553 FP = I2;
554 PM_POP(3, DCPLB_DATA15)
555 PM_POP(2, DCPLB_DATA14)
556 PM_POP(1, DCPLB_DATA13)
557 PM_POP(0, DCPLB_DATA12)
558 PM_POP_SYNC(13)
559 PM_POP(13, DCPLB_DATA11)
560 PM_POP(12, DCPLB_DATA10)
561 PM_POP(11, DCPLB_DATA9)
562 PM_POP(10, DCPLB_DATA8)
563 PM_POP(9, DCPLB_DATA7)
564 PM_POP(8, DCPLB_DATA6)
565 PM_POP(7, DCPLB_DATA5)
566 PM_POP(6, DCPLB_DATA4)
567 PM_POP(5, DCPLB_DATA3)
568 PM_POP(4, DCPLB_DATA2)
569 PM_POP(3, DCPLB_DATA1)
570 PM_POP(2, DCPLB_DATA0)
571
572 /* DCPLB Addr */
573 FP = I1;
574 PM_POP(1, DCPLB_ADDR15)
575 PM_POP(0, DCPLB_ADDR14)
576 PM_POP_SYNC(13)
577 PM_POP(13, DCPLB_ADDR13)
578 PM_POP(12, DCPLB_ADDR12)
579 PM_POP(11, DCPLB_ADDR11)
580 PM_POP(10, DCPLB_ADDR10)
581 PM_POP(9, DCPLB_ADDR9)
582 PM_POP(8, DCPLB_ADDR8)
583 PM_POP(7, DCPLB_ADDR7)
584 PM_POP(6, DCPLB_ADDR6)
585 PM_POP(5, DCPLB_ADDR5)
586 PM_POP(4, DCPLB_ADDR4)
587 PM_POP(3, DCPLB_ADDR3)
588 PM_POP(2, DCPLB_ADDR2)
589 PM_POP(1, DCPLB_ADDR1)
590 PM_POP(0, DCPLB_ADDR0)
591
592
593 /* Misc non-contiguous registers */
594
595 /* icache & dcache will enable later
596 drop IMEM_CONTROL, DMEM_CONTROL pop
597 */
598 FP = I0;
599 PM_POP_SYNC(2)
600 PM_CORE_POP(2, TBUFCTL)
601 PM_CORE_POP(1, IMEM_CONTROL)
602 PM_CORE_POP(0, DMEM_CONTROL)
603
604 /* Core Timer */
605 FP = B3;
606 R0 = 0x1;
607 [FP - 0xC] = R0;
608
609 PM_POP_SYNC(13)
610 FP = B3;
611 PM_POP(13, TCOUNT)
612 PM_POP(12, TSCALE)
613 PM_POP(11, TPERIOD)
614 PM_POP(10, TCNTL)
615
616 /* CEC */
617 FP = B2;
618 PM_POP(9, IPRIO)
619 PM_POP(8, ILAT)
620 FP += -4; /* IPEND */
621 PM_POP(7, IMASK)
622
623 /* Event Vectors */
624 FP = B1;
625 PM_POP(6, EVT15)
626 PM_POP(5, EVT14)
627 PM_POP(4, EVT13)
628 PM_POP(3, EVT12)
629 PM_POP(2, EVT11)
630 PM_POP(1, EVT10)
631 PM_POP(0, EVT9)
632 PM_POP_SYNC(5)
633 PM_POP(5, EVT8)
634 PM_POP(4, EVT7)
635 PM_POP(3, EVT6)
636 PM_POP(2, EVT5)
637 FP += -4; /* EVT4 */
638 PM_POP(1, EVT3)
639 PM_POP(0, EVT2)
640 .endm
641#endif
642
12#include <mach/pll.h> 643#include <mach/pll.h>
13 644
14/* PLL_CTL Masks */ 645/* PLL_CTL Masks */
@@ -114,6 +745,7 @@
114#define USBWE 0x0800 /* Enable USB Wakeup From Hibernate */ 745#define USBWE 0x0800 /* Enable USB Wakeup From Hibernate */
115#endif 746#endif
116 747
748
117#ifndef __ASSEMBLY__ 749#ifndef __ASSEMBLY__
118 750
119void sleep_mode(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2); 751void sleep_mode(u32 sic_iwr0, u32 sic_iwr1, u32 sic_iwr2);
diff --git a/arch/blackfin/include/asm/pm.h b/arch/blackfin/include/asm/pm.h
new file mode 100644
index 000000000000..da63b46e0c68
--- /dev/null
+++ b/arch/blackfin/include/asm/pm.h
@@ -0,0 +1,32 @@
1/*
2 * Blackfin bf609 power management
3 *
4 * Copyright 2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2
7 */
8
9#ifndef __PM_H__
10#define __PM_H__
11
12#include <mach/pm.h>
13#include <linux/suspend.h>
14
15struct bfin_cpu_pm_fns {
16 void (*save)(unsigned long *);
17 void (*restore)(unsigned long *);
18 int (*valid)(suspend_state_t state);
19 void (*enter)(suspend_state_t state);
20 int (*prepare)(void);
21 void (*finish)(void);
22};
23
24extern struct bfin_cpu_pm_fns *bfin_cpu_pm;
25
26# ifdef CONFIG_BFIN_COREB
27void bfin_coreb_start(void);
28void bfin_coreb_stop(void);
29void bfin_coreb_reset(void);
30# endif
31
32#endif
diff --git a/arch/blackfin/mach-bf609/hibernate.S b/arch/blackfin/mach-bf609/hibernate.S
new file mode 100644
index 000000000000..baedd6e6abf4
--- /dev/null
+++ b/arch/blackfin/mach-bf609/hibernate.S
@@ -0,0 +1,62 @@
1#include <linux/linkage.h>
2#include <asm/blackfin.h>
3#include <asm/dpmc.h>
4
5#define PM_STACK (COREA_L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)
6
7.section .l1.text
8ENTRY(_enter_hibernate)
9 /* switch stack to L1 scratch, prepare for ddr srfr */
10 P0.H = HI(PM_STACK);
11 P0.L = LO(PM_STACK);
12 SP = P0;
13
14 call _bf609_ddr_sr;
15 call _bfin_hibernate_syscontrol;
16
17 P0.H = HI(DPM0_RESTORE4);
18 P0.L = LO(DPM0_RESTORE4);
19 P1.H = _bf609_pm_data;
20 P1.L = _bf609_pm_data;
21 [P0] = P1;
22
23 P0.H = HI(DPM0_CTL);
24 P0.L = LO(DPM0_CTL);
25 R3.H = HI(0x00000010);
26 R3.L = LO(0x00000010);
27 [P0] = R3;
28
29 SSYNC;
30ENDPROC(_enter_hibernate_mode)
31
32.section .text
33ENTRY(_bf609_hibernate)
34 bfin_cpu_reg_save;
35 bfin_core_mmr_save;
36
37 P0.H = _bf609_pm_data;
38 P0.L = _bf609_pm_data;
39 R1.H = 0xDEAD;
40 R1.L = 0xBEEF;
41 R2.H = .Lpm_resume_here;
42 R2.L = .Lpm_resume_here;
43 [P0++] = R1;
44 [P0++] = R2;
45 [P0++] = SP;
46
47 P1.H = _enter_hibernate;
48 P1.L = _enter_hibernate;
49
50 call (P1);
51.Lpm_resume_here:
52
53 bfin_core_mmr_restore;
54 bfin_cpu_reg_restore;
55
56 [--sp] = RETI; /* Clear Global Interrupt Disable */
57 SP += 4;
58
59 RTS;
60
61ENDPROC(_bf609_hibernate)
62
diff --git a/arch/blackfin/mach-bf609/include/mach/pm.h b/arch/blackfin/mach-bf609/include/mach/pm.h
new file mode 100644
index 000000000000..036d9bdc889e
--- /dev/null
+++ b/arch/blackfin/mach-bf609/include/mach/pm.h
@@ -0,0 +1,21 @@
1/*
2 * Blackfin bf609 power management
3 *
4 * Copyright 2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2
7 */
8
9#ifndef __MACH_BF609_PM_H__
10#define __MACH_BF609_PM_H__
11
12#include <linux/suspend.h>
13
14int bfin609_pm_enter(suspend_state_t state);
15int bf609_pm_prepare(void);
16void bf609_pm_finish(void);
17
18void bf609_hibernate(void);
19void bfin_sec_raise_irq(unsigned int sid);
20void coreb_enable(void);
21#endif
diff --git a/arch/blackfin/mach-bf609/pm.c b/arch/blackfin/mach-bf609/pm.c
new file mode 100644
index 000000000000..bbc5a79b5e22
--- /dev/null
+++ b/arch/blackfin/mach-bf609/pm.c
@@ -0,0 +1,310 @@
1/*
2 * Blackfin bf609 power management
3 *
4 * Copyright 2011 Analog Devices Inc.
5 *
6 * Licensed under the GPL-2
7 */
8
9#include <linux/suspend.h>
10#include <linux/io.h>
11#include <linux/interrupt.h>
12#include <linux/gpio.h>
13#include <linux/irq.h>
14
15#include <linux/delay.h>
16
17#include <asm/dpmc.h>
18#include <asm/pm.h>
19#include <mach/pm.h>
20#include <asm/blackfin.h>
21
22/***********************************************************/
23/* */
24/* Wakeup Actions for DPM_RESTORE */
25/* */
26/***********************************************************/
27#define BITP_ROM_WUA_CHKHDR 24
28#define BITP_ROM_WUA_DDRLOCK 7
29#define BITP_ROM_WUA_DDRDLLEN 6
30#define BITP_ROM_WUA_DDR 5
31#define BITP_ROM_WUA_CGU 4
32#define BITP_ROM_WUA_MEMBOOT 2
33#define BITP_ROM_WUA_EN 1
34
35#define BITM_ROM_WUA_CHKHDR (0xFF000000)
36#define ENUM_ROM_WUA_CHKHDR_AD 0xAD000000
37
38#define BITM_ROM_WUA_DDRLOCK (0x00000080)
39#define BITM_ROM_WUA_DDRDLLEN (0x00000040)
40#define BITM_ROM_WUA_DDR (0x00000020)
41#define BITM_ROM_WUA_CGU (0x00000010)
42#define BITM_ROM_WUA_MEMBOOT (0x00000002)
43#define BITM_ROM_WUA_EN (0x00000001)
44
45/***********************************************************/
46/* */
47/* Syscontrol */
48/* */
49/***********************************************************/
50#define BITP_ROM_SYSCTRL_CGU_LOCKINGEN 28 /* unlocks CGU_CTL register */
51#define BITP_ROM_SYSCTRL_WUA_OVERRIDE 24
52#define BITP_ROM_SYSCTRL_WUA_DDRDLLEN 20 /* Saves the DDR DLL and PADS registers to the DPM registers */
53#define BITP_ROM_SYSCTRL_WUA_DDR 19 /* Saves the DDR registers to the DPM registers */
54#define BITP_ROM_SYSCTRL_WUA_CGU 18 /* Saves the CGU registers into DPM registers */
55#define BITP_ROM_SYSCTRL_WUA_DPMWRITE 17 /* Saves the Syscontrol structure structure contents into DPM registers */
56#define BITP_ROM_SYSCTRL_WUA_EN 16 /* reads current PLL and DDR configuration into structure */
57#define BITP_ROM_SYSCTRL_DDR_WRITE 13 /* writes the DDR registers from Syscontrol structure for wakeup initialization of DDR */
58#define BITP_ROM_SYSCTRL_DDR_READ 12 /* Read the DDR registers into the Syscontrol structure for storing prior to hibernate */
59#define BITP_ROM_SYSCTRL_CGU_AUTODIS 11 /* Disables auto handling of UPDT and ALGN fields */
60#define BITP_ROM_SYSCTRL_CGU_CLKOUTSEL 7 /* access CGU_CLKOUTSEL register */
61#define BITP_ROM_SYSCTRL_CGU_DIV 6 /* access CGU_DIV register */
62#define BITP_ROM_SYSCTRL_CGU_STAT 5 /* access CGU_STAT register */
63#define BITP_ROM_SYSCTRL_CGU_CTL 4 /* access CGU_CTL register */
64#define BITP_ROM_SYSCTRL_CGU_RTNSTAT 2 /* Update structure STAT field upon error */
65#define BITP_ROM_SYSCTRL_WRITE 1 /* write registers */
66#define BITP_ROM_SYSCTRL_READ 0 /* read registers */
67
68#define BITM_ROM_SYSCTRL_CGU_READ (0x00000001) /* Read CGU registers */
69#define BITM_ROM_SYSCTRL_CGU_WRITE (0x00000002) /* Write registers */
70#define BITM_ROM_SYSCTRL_CGU_RTNSTAT (0x00000004) /* Update structure STAT field upon error or after a write operation */
71#define BITM_ROM_SYSCTRL_CGU_CTL (0x00000010) /* Access CGU_CTL register */
72#define BITM_ROM_SYSCTRL_CGU_STAT (0x00000020) /* Access CGU_STAT register */
73#define BITM_ROM_SYSCTRL_CGU_DIV (0x00000040) /* Access CGU_DIV register */
74#define BITM_ROM_SYSCTRL_CGU_CLKOUTSEL (0x00000080) /* Access CGU_CLKOUTSEL register */
75#define BITM_ROM_SYSCTRL_CGU_AUTODIS (0x00000800) /* Disables auto handling of UPDT and ALGN fields */
76#define BITM_ROM_SYSCTRL_DDR_READ (0x00001000) /* Reads the contents of the DDR registers and stores them into the structure */
77#define BITM_ROM_SYSCTRL_DDR_WRITE (0x00002000) /* Writes the DDR registers from the structure, only really intented for wakeup functionality and not for full DDR configuration */
78#define BITM_ROM_SYSCTRL_WUA_EN (0x00010000) /* Wakeup entry or exit opertation enable */
79#define BITM_ROM_SYSCTRL_WUA_DPMWRITE (0x00020000) /* When set indicates a restore of the PLL and DDR is to be performed otherwise a save is required */
80#define BITM_ROM_SYSCTRL_WUA_CGU (0x00040000) /* Only applicable for a PLL and DDR save operation to the DPM, saves the current settings if cleared or the contents of the structure if set */
81#define BITM_ROM_SYSCTRL_WUA_DDR (0x00080000) /* Only applicable for a PLL and DDR save operation to the DPM, saves the current settings if cleared or the contents of the structure if set */
82#define BITM_ROM_SYSCTRL_WUA_DDRDLLEN (0x00100000) /* Enables saving/restoring of the DDR DLLCTL register */
83#define BITM_ROM_SYSCTRL_WUA_OVERRIDE (0x01000000)
84#define BITM_ROM_SYSCTRL_CGU_LOCKINGEN (0x10000000) /* Unlocks the CGU_CTL register */
85
86
87/* Structures for the syscontrol() function */
88struct STRUCT_ROM_SYSCTRL {
89 uint32_t ulCGU_CTL;
90 uint32_t ulCGU_STAT;
91 uint32_t ulCGU_DIV;
92 uint32_t ulCGU_CLKOUTSEL;
93 uint32_t ulWUA_Flags;
94 uint32_t ulWUA_BootAddr;
95 uint32_t ulWUA_User;
96 uint32_t ulDDR_CTL;
97 uint32_t ulDDR_CFG;
98 uint32_t ulDDR_TR0;
99 uint32_t ulDDR_TR1;
100 uint32_t ulDDR_TR2;
101 uint32_t ulDDR_MR;
102 uint32_t ulDDR_EMR1;
103 uint32_t ulDDR_EMR2;
104 uint32_t ulDDR_PADCTL;
105 uint32_t ulDDR_DLLCTL;
106 uint32_t ulReserved;
107};
108
109struct bfin_pm_data {
110 uint32_t magic;
111 uint32_t resume_addr;
112 uint32_t sp;
113};
114
115struct bfin_pm_data bf609_pm_data;
116
117struct STRUCT_ROM_SYSCTRL configvalues;
118uint32_t dactionflags;
119
120#define FUNC_ROM_SYSCONTROL 0xC8000080
121__attribute__((l1_data))
122static uint32_t (* const bfrom_SysControl)(uint32_t action_flags, struct STRUCT_ROM_SYSCTRL *settings, void *reserved) = (void *)FUNC_ROM_SYSCONTROL;
123
124__attribute__((l1_text))
125void bfin_cpu_suspend(void)
126{
127 __asm__ __volatile__( \
128 ".align 8;" \
129 "idle;" \
130 : : \
131 );
132}
133
134__attribute__((l1_text))
135void bfin_deepsleep(unsigned long mask)
136{
137 uint32_t dpm0_ctl;
138
139 bfin_write32(DPM0_WAKE_EN, 0x10);
140 bfin_write32(DPM0_WAKE_POL, 0x10);
141 dpm0_ctl = bfin_read32(DPM0_CTL);
142 dpm0_ctl = 0x00000008;
143 bfin_write32(DPM0_CTL, dpm0_ctl);
144 SSYNC();
145 __asm__ __volatile__( \
146 ".align 8;" \
147 "idle;" \
148 : : \
149 );
150}
151
152__attribute__((l1_text))
153void bf609_ddr_sr(void)
154{
155 uint32_t reg;
156
157 reg = bfin_read_DDR0_CTL();
158 reg |= 0x8;
159 bfin_write_DDR0_CTL(reg);
160
161 while (!(bfin_read_DDR0_STAT() & 0x8))
162 continue;
163}
164
165__attribute__((l1_text))
166void bf609_ddr_sr_exit(void)
167{
168 uint32_t reg;
169 while (!(bfin_read_DDR0_STAT() & 0x1))
170 continue;
171
172 reg = bfin_read_DDR0_CTL();
173 reg &= ~0x8;
174 bfin_write_DDR0_CTL(reg);
175
176 while ((bfin_read_DDR0_STAT() & 0x8))
177 continue;
178}
179
180__attribute__((l1_text))
181void bfin_hibernate_syscontrol(void)
182{
183 configvalues.ulWUA_Flags = (0xAD000000 | BITM_ROM_WUA_EN
184 | BITM_ROM_WUA_CGU | BITM_ROM_WUA_DDR | BITM_ROM_WUA_DDRDLLEN);
185
186 dactionflags = (BITM_ROM_SYSCTRL_WUA_EN
187 | BITM_ROM_SYSCTRL_WUA_DPMWRITE | BITM_ROM_SYSCTRL_WUA_CGU
188 | BITM_ROM_SYSCTRL_WUA_DDR | BITM_ROM_SYSCTRL_WUA_DDRDLLEN);
189
190 bfrom_SysControl(dactionflags, &configvalues, NULL);
191
192 bfin_write32(DPM0_RESTORE5, bfin_read32(DPM0_RESTORE5) | 4);
193}
194
195#ifndef CONFIG_BF60x
196# define SIC_SYSIRQ(irq) (irq - (IRQ_CORETMR + 1))
197#else
198# define SIC_SYSIRQ(irq) ((irq) - IVG15)
199#endif
200void bfin_hibernate(unsigned long mask)
201{
202 bfin_write32(DPM0_WAKE_EN, 0x10);
203 bfin_write32(DPM0_WAKE_POL, 0x10);
204 bfin_write32(DPM0_PGCNTR, 0x0000FFFF);
205 bfin_write32(DPM0_HIB_DIS, 0xFFFF);
206
207 printk(KERN_DEBUG "hibernate: restore %x pgcnt %x\n", bfin_read32(DPM0_RESTORE0), bfin_read32(DPM0_PGCNTR));
208
209 bf609_hibernate();
210}
211
212void bf609_cpu_pm_enter(suspend_state_t state)
213{
214 int error;
215 error = irq_set_irq_wake(255, 1);
216 if(error < 0)
217 printk(KERN_DEBUG "Unable to get irq wake\n");
218 error = irq_set_irq_wake(231, 1);
219 if (error < 0)
220 printk(KERN_DEBUG "Unable to get irq wake\n");
221
222 if (state == PM_SUSPEND_STANDBY)
223 bfin_deepsleep(0xffff);
224 else {
225 bfin_hibernate(0xffff);
226 }
227}
228
229int bf609_cpu_pm_prepare(void)
230{
231 return 0;
232}
233
234void bf609_cpu_pm_finish(void)
235{
236
237}
238
239static struct bfin_cpu_pm_fns bf609_cpu_pm = {
240 .enter = bf609_cpu_pm_enter,
241 .prepare = bf609_cpu_pm_prepare,
242 .finish = bf609_cpu_pm_finish,
243};
244
245static irqreturn_t test_isr(int irq, void *dev_id)
246{
247 printk(KERN_DEBUG "gpio irq %d\n", irq);
248 return IRQ_HANDLED;
249}
250
251static irqreturn_t dpm0_isr(int irq, void *dev_id)
252{
253 uint32_t wake_stat;
254
255 wake_stat = bfin_read32(DPM0_WAKE_STAT);
256 printk(KERN_DEBUG "enter %s wake stat %08x\n", __func__, wake_stat);
257
258 bfin_write32(DPM0_WAKE_STAT, wake_stat);
259 return IRQ_HANDLED;
260}
261
262static int __init bf609_init_pm(void)
263{
264 int irq;
265 int error;
266 error = gpio_request(GPIO_PG4, "gpiopg4");
267 if (error < 0) {
268 printk(KERN_DEBUG "failed to request GPIO %d, error %d\n",
269 GPIO_PG4, error);
270 }
271
272 irq = gpio_to_irq(GPIO_PG4);
273 if (irq < 0) {
274 error = irq;
275 printk(KERN_DEBUG "Unable to get irq number for GPIO %d, error %d\n",
276 GPIO_PG4, error);
277 }
278
279 printk(KERN_DEBUG "%s gpio %d irq %d\n", __func__, GPIO_PG4, irq);
280
281 error = request_irq(irq, test_isr, IRQF_TRIGGER_FALLING | IRQF_NO_SUSPEND, "gpiopg4", NULL);
282 if(error < 0)
283 printk(KERN_DEBUG "Unable to get irq\n");
284
285#if 1
286 irq = gpio_to_irq(GPIO_PE12);
287 if (irq < 0) {
288 error = irq;
289 printk(KERN_DEBUG "Unable to get irq number for GPIO %d, error %d\n",
290 GPIO_PE12, error);
291 }
292
293 error = request_irq(irq, test_isr, IRQF_TRIGGER_RISING | IRQF_NO_SUSPEND, "gpiope12", NULL);
294 if(error < 0)
295 printk(KERN_DEBUG "Unable to get irq\n");
296#endif
297
298 error = request_irq(IRQ_CGU_EVT, dpm0_isr, IRQF_NO_SUSPEND, "cgu0 event", NULL);
299 if(error < 0)
300 printk(KERN_DEBUG "Unable to get irq\n");
301
302 error = request_irq(IRQ_DPM, dpm0_isr, IRQF_NO_SUSPEND, "dpm0 event", NULL);
303 if (error < 0)
304 printk(KERN_DEBUG "Unable to get irq\n");
305
306 bfin_cpu_pm = &bf609_cpu_pm;
307 return 0;
308}
309
310late_initcall(bf609_init_pm);
diff --git a/arch/blackfin/mach-common/Makefile b/arch/blackfin/mach-common/Makefile
index ff299f24aba0..75f0ba29ebb9 100644
--- a/arch/blackfin/mach-common/Makefile
+++ b/arch/blackfin/mach-common/Makefile
@@ -6,7 +6,10 @@ obj-y := \
6 cache.o cache-c.o entry.o head.o \ 6 cache.o cache-c.o entry.o head.o \
7 interrupt.o arch_checks.o ints-priority.o 7 interrupt.o arch_checks.o ints-priority.o
8 8
9obj-$(CONFIG_PM) += pm.o dpmc_modes.o 9obj-$(CONFIG_PM) += pm.o
10ifneq ($(CONFIG_BF60x),y)
11obj-$(CONFIG_PM) += dpmc_modes.o
12endif
10obj-$(CONFIG_CPU_FREQ) += cpufreq.o 13obj-$(CONFIG_CPU_FREQ) += cpufreq.o
11obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o 14obj-$(CONFIG_CPU_VOLTAGE) += dpmc.o
12obj-$(CONFIG_SMP) += smp.o 15obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/blackfin/mach-common/dpmc_modes.S b/arch/blackfin/mach-common/dpmc_modes.S
index 1c534d298de4..2bec509cd7e2 100644
--- a/arch/blackfin/mach-common/dpmc_modes.S
+++ b/arch/blackfin/mach-common/dpmc_modes.S
@@ -10,7 +10,7 @@
10#include <asm/dpmc.h> 10#include <asm/dpmc.h>
11 11
12.section .l1.text 12.section .l1.text
13 13#ifndef CONFIG_BF60x
14ENTRY(_sleep_mode) 14ENTRY(_sleep_mode)
15 [--SP] = (R7:4, P5:3); 15 [--SP] = (R7:4, P5:3);
16 [--SP] = RETS; 16 [--SP] = RETS;
@@ -49,6 +49,7 @@ ENTRY(_sleep_mode)
49 (R7:4, P5:3) = [SP++]; 49 (R7:4, P5:3) = [SP++];
50 RTS; 50 RTS;
51ENDPROC(_sleep_mode) 51ENDPROC(_sleep_mode)
52#endif
52 53
53/* 54/*
54 * This func never returns as it puts the part into hibernate, and 55 * This func never returns as it puts the part into hibernate, and
@@ -58,12 +59,14 @@ ENDPROC(_sleep_mode)
58 * 59 *
59 * We accept just one argument -- the value to write to VR_CTL. 60 * We accept just one argument -- the value to write to VR_CTL.
60 */ 61 */
62
61ENTRY(_hibernate_mode) 63ENTRY(_hibernate_mode)
62 /* Save/setup the regs we need early for minor pipeline optimization */ 64 /* Save/setup the regs we need early for minor pipeline optimization */
63 R4 = R0; 65 R4 = R0;
66
67#ifndef CONFIG_BF60x
64 P3.H = hi(VR_CTL); 68 P3.H = hi(VR_CTL);
65 P3.L = lo(VR_CTL); 69 P3.L = lo(VR_CTL);
66
67 /* Disable all wakeup sources */ 70 /* Disable all wakeup sources */
68 R0 = IWR_DISABLE_ALL; 71 R0 = IWR_DISABLE_ALL;
69 R1 = IWR_DISABLE_ALL; 72 R1 = IWR_DISABLE_ALL;
@@ -71,6 +74,7 @@ ENTRY(_hibernate_mode)
71 call _set_sic_iwr; 74 call _set_sic_iwr;
72 call _set_dram_srfs; 75 call _set_dram_srfs;
73 SSYNC; 76 SSYNC;
77#endif
74 78
75 /* Finally, we climb into our cave to hibernate */ 79 /* Finally, we climb into our cave to hibernate */
76 W[P3] = R4.L; 80 W[P3] = R4.L;
@@ -80,6 +84,7 @@ ENTRY(_hibernate_mode)
80 jump .Lforever; 84 jump .Lforever;
81ENDPROC(_hibernate_mode) 85ENDPROC(_hibernate_mode)
82 86
87#ifndef CONFIG_BF60x
83ENTRY(_sleep_deeper) 88ENTRY(_sleep_deeper)
84 [--SP] = (R7:4, P5:3); 89 [--SP] = (R7:4, P5:3);
85 [--SP] = RETS; 90 [--SP] = RETS;
@@ -274,329 +279,13 @@ ENTRY(_test_pll_locked)
274 IF !CC JUMP 1b; 279 IF !CC JUMP 1b;
275 RTS; 280 RTS;
276ENDPROC(_test_pll_locked) 281ENDPROC(_test_pll_locked)
282#endif
277 283
278.section .text 284.section .text
279
280#define PM_REG0 R7
281#define PM_REG1 R6
282#define PM_REG2 R5
283#define PM_REG3 R4
284#define PM_REG4 R3
285#define PM_REG5 R2
286#define PM_REG6 R1
287#define PM_REG7 R0
288#define PM_REG8 P5
289#define PM_REG9 P4
290#define PM_REG10 P3
291#define PM_REG11 P2
292#define PM_REG12 P1
293#define PM_REG13 P0
294
295#define PM_REGSET0 R7:7
296#define PM_REGSET1 R7:6
297#define PM_REGSET2 R7:5
298#define PM_REGSET3 R7:4
299#define PM_REGSET4 R7:3
300#define PM_REGSET5 R7:2
301#define PM_REGSET6 R7:1
302#define PM_REGSET7 R7:0
303#define PM_REGSET8 R7:0, P5:5
304#define PM_REGSET9 R7:0, P5:4
305#define PM_REGSET10 R7:0, P5:3
306#define PM_REGSET11 R7:0, P5:2
307#define PM_REGSET12 R7:0, P5:1
308#define PM_REGSET13 R7:0, P5:0
309
310#define _PM_PUSH(n, x, w, base) PM_REG##n = w[FP + ((x) - (base))];
311#define _PM_POP(n, x, w, base) w[FP + ((x) - (base))] = PM_REG##n;
312#define PM_PUSH_SYNC(n) [--sp] = (PM_REGSET##n);
313#define PM_POP_SYNC(n) (PM_REGSET##n) = [sp++];
314#define PM_PUSH(n, x) PM_REG##n = [FP++];
315#define PM_POP(n, x) [FP--] = PM_REG##n;
316#define PM_CORE_PUSH(n, x) _PM_PUSH(n, x, , COREMMR_BASE)
317#define PM_CORE_POP(n, x) _PM_POP(n, x, , COREMMR_BASE)
318#define PM_SYS_PUSH(n, x) _PM_PUSH(n, x, , SYSMMR_BASE)
319#define PM_SYS_POP(n, x) _PM_POP(n, x, , SYSMMR_BASE)
320#define PM_SYS_PUSH16(n, x) _PM_PUSH(n, x, w, SYSMMR_BASE)
321#define PM_SYS_POP16(n, x) _PM_POP(n, x, w, SYSMMR_BASE)
322
323ENTRY(_do_hibernate) 285ENTRY(_do_hibernate)
324 /* 286 bfin_cpu_reg_save;
325 * Save the core regs early so we can blow them away when 287 bfin_sys_mmr_save;
326 * saving/restoring MMR states 288 bfin_core_mmr_save;
327 */
328 [--sp] = (R7:0, P5:0);
329 [--sp] = fp;
330 [--sp] = usp;
331
332 [--sp] = i0;
333 [--sp] = i1;
334 [--sp] = i2;
335 [--sp] = i3;
336
337 [--sp] = m0;
338 [--sp] = m1;
339 [--sp] = m2;
340 [--sp] = m3;
341
342 [--sp] = l0;
343 [--sp] = l1;
344 [--sp] = l2;
345 [--sp] = l3;
346
347 [--sp] = b0;
348 [--sp] = b1;
349 [--sp] = b2;
350 [--sp] = b3;
351 [--sp] = a0.x;
352 [--sp] = a0.w;
353 [--sp] = a1.x;
354 [--sp] = a1.w;
355
356 [--sp] = LC0;
357 [--sp] = LC1;
358 [--sp] = LT0;
359 [--sp] = LT1;
360 [--sp] = LB0;
361 [--sp] = LB1;
362
363 /* We can't push RETI directly as that'll change IPEND[4] */
364 r7 = RETI;
365 [--sp] = RETS;
366 [--sp] = ASTAT;
367 [--sp] = CYCLES;
368 [--sp] = CYCLES2;
369 [--sp] = SYSCFG;
370 [--sp] = RETX;
371 [--sp] = SEQSTAT;
372 [--sp] = r7;
373
374 /* Save first func arg in M3 */
375 M3 = R0;
376
377 /* Save system MMRs */
378 FP.H = hi(SYSMMR_BASE);
379 FP.L = lo(SYSMMR_BASE);
380
381#ifdef SIC_IMASK0
382 PM_SYS_PUSH(0, SIC_IMASK0)
383 PM_SYS_PUSH(1, SIC_IMASK1)
384# ifdef SIC_IMASK2
385 PM_SYS_PUSH(2, SIC_IMASK2)
386# endif
387#else
388 PM_SYS_PUSH(0, SIC_IMASK)
389#endif
390#ifdef SIC_IAR0
391 PM_SYS_PUSH(3, SIC_IAR0)
392 PM_SYS_PUSH(4, SIC_IAR1)
393 PM_SYS_PUSH(5, SIC_IAR2)
394#endif
395#ifdef SIC_IAR3
396 PM_SYS_PUSH(6, SIC_IAR3)
397#endif
398#ifdef SIC_IAR4
399 PM_SYS_PUSH(7, SIC_IAR4)
400 PM_SYS_PUSH(8, SIC_IAR5)
401 PM_SYS_PUSH(9, SIC_IAR6)
402#endif
403#ifdef SIC_IAR7
404 PM_SYS_PUSH(10, SIC_IAR7)
405#endif
406#ifdef SIC_IAR8
407 PM_SYS_PUSH(11, SIC_IAR8)
408 PM_SYS_PUSH(12, SIC_IAR9)
409 PM_SYS_PUSH(13, SIC_IAR10)
410#endif
411 PM_PUSH_SYNC(13)
412#ifdef SIC_IAR11
413 PM_SYS_PUSH(0, SIC_IAR11)
414#endif
415
416#ifdef SIC_IWR
417 PM_SYS_PUSH(1, SIC_IWR)
418#endif
419#ifdef SIC_IWR0
420 PM_SYS_PUSH(1, SIC_IWR0)
421#endif
422#ifdef SIC_IWR1
423 PM_SYS_PUSH(2, SIC_IWR1)
424#endif
425#ifdef SIC_IWR2
426 PM_SYS_PUSH(3, SIC_IWR2)
427#endif
428
429#ifdef PINT0_ASSIGN
430 PM_SYS_PUSH(4, PINT0_MASK_SET)
431 PM_SYS_PUSH(5, PINT1_MASK_SET)
432 PM_SYS_PUSH(6, PINT2_MASK_SET)
433 PM_SYS_PUSH(7, PINT3_MASK_SET)
434 PM_SYS_PUSH(8, PINT0_ASSIGN)
435 PM_SYS_PUSH(9, PINT1_ASSIGN)
436 PM_SYS_PUSH(10, PINT2_ASSIGN)
437 PM_SYS_PUSH(11, PINT3_ASSIGN)
438 PM_SYS_PUSH(12, PINT0_INVERT_SET)
439 PM_SYS_PUSH(13, PINT1_INVERT_SET)
440 PM_PUSH_SYNC(13)
441 PM_SYS_PUSH(0, PINT2_INVERT_SET)
442 PM_SYS_PUSH(1, PINT3_INVERT_SET)
443 PM_SYS_PUSH(2, PINT0_EDGE_SET)
444 PM_SYS_PUSH(3, PINT1_EDGE_SET)
445 PM_SYS_PUSH(4, PINT2_EDGE_SET)
446 PM_SYS_PUSH(5, PINT3_EDGE_SET)
447#endif
448
449 PM_SYS_PUSH16(6, SYSCR)
450
451 PM_SYS_PUSH16(7, EBIU_AMGCTL)
452 PM_SYS_PUSH(8, EBIU_AMBCTL0)
453 PM_SYS_PUSH(9, EBIU_AMBCTL1)
454#ifdef EBIU_FCTL
455 PM_SYS_PUSH(10, EBIU_MBSCTL)
456 PM_SYS_PUSH(11, EBIU_MODE)
457 PM_SYS_PUSH(12, EBIU_FCTL)
458 PM_PUSH_SYNC(12)
459#else
460 PM_PUSH_SYNC(9)
461#endif
462
463 /* Save Core MMRs */
464 I0.H = hi(COREMMR_BASE);
465 I0.L = lo(COREMMR_BASE);
466 I1 = I0;
467 I2 = I0;
468 I3 = I0;
469 B0 = I0;
470 B1 = I0;
471 B2 = I0;
472 B3 = I0;
473 I1.L = lo(DCPLB_ADDR0);
474 I2.L = lo(DCPLB_DATA0);
475 I3.L = lo(ICPLB_ADDR0);
476 B0.L = lo(ICPLB_DATA0);
477 B1.L = lo(EVT2);
478 B2.L = lo(IMASK);
479 B3.L = lo(TCNTL);
480
481 /* DCPLB Addr */
482 FP = I1;
483 PM_PUSH(0, DCPLB_ADDR0)
484 PM_PUSH(1, DCPLB_ADDR1)
485 PM_PUSH(2, DCPLB_ADDR2)
486 PM_PUSH(3, DCPLB_ADDR3)
487 PM_PUSH(4, DCPLB_ADDR4)
488 PM_PUSH(5, DCPLB_ADDR5)
489 PM_PUSH(6, DCPLB_ADDR6)
490 PM_PUSH(7, DCPLB_ADDR7)
491 PM_PUSH(8, DCPLB_ADDR8)
492 PM_PUSH(9, DCPLB_ADDR9)
493 PM_PUSH(10, DCPLB_ADDR10)
494 PM_PUSH(11, DCPLB_ADDR11)
495 PM_PUSH(12, DCPLB_ADDR12)
496 PM_PUSH(13, DCPLB_ADDR13)
497 PM_PUSH_SYNC(13)
498 PM_PUSH(0, DCPLB_ADDR14)
499 PM_PUSH(1, DCPLB_ADDR15)
500
501 /* DCPLB Data */
502 FP = I2;
503 PM_PUSH(2, DCPLB_DATA0)
504 PM_PUSH(3, DCPLB_DATA1)
505 PM_PUSH(4, DCPLB_DATA2)
506 PM_PUSH(5, DCPLB_DATA3)
507 PM_PUSH(6, DCPLB_DATA4)
508 PM_PUSH(7, DCPLB_DATA5)
509 PM_PUSH(8, DCPLB_DATA6)
510 PM_PUSH(9, DCPLB_DATA7)
511 PM_PUSH(10, DCPLB_DATA8)
512 PM_PUSH(11, DCPLB_DATA9)
513 PM_PUSH(12, DCPLB_DATA10)
514 PM_PUSH(13, DCPLB_DATA11)
515 PM_PUSH_SYNC(13)
516 PM_PUSH(0, DCPLB_DATA12)
517 PM_PUSH(1, DCPLB_DATA13)
518 PM_PUSH(2, DCPLB_DATA14)
519 PM_PUSH(3, DCPLB_DATA15)
520
521 /* ICPLB Addr */
522 FP = I3;
523 PM_PUSH(4, ICPLB_ADDR0)
524 PM_PUSH(5, ICPLB_ADDR1)
525 PM_PUSH(6, ICPLB_ADDR2)
526 PM_PUSH(7, ICPLB_ADDR3)
527 PM_PUSH(8, ICPLB_ADDR4)
528 PM_PUSH(9, ICPLB_ADDR5)
529 PM_PUSH(10, ICPLB_ADDR6)
530 PM_PUSH(11, ICPLB_ADDR7)
531 PM_PUSH(12, ICPLB_ADDR8)
532 PM_PUSH(13, ICPLB_ADDR9)
533 PM_PUSH_SYNC(13)
534 PM_PUSH(0, ICPLB_ADDR10)
535 PM_PUSH(1, ICPLB_ADDR11)
536 PM_PUSH(2, ICPLB_ADDR12)
537 PM_PUSH(3, ICPLB_ADDR13)
538 PM_PUSH(4, ICPLB_ADDR14)
539 PM_PUSH(5, ICPLB_ADDR15)
540
541 /* ICPLB Data */
542 FP = B0;
543 PM_PUSH(6, ICPLB_DATA0)
544 PM_PUSH(7, ICPLB_DATA1)
545 PM_PUSH(8, ICPLB_DATA2)
546 PM_PUSH(9, ICPLB_DATA3)
547 PM_PUSH(10, ICPLB_DATA4)
548 PM_PUSH(11, ICPLB_DATA5)
549 PM_PUSH(12, ICPLB_DATA6)
550 PM_PUSH(13, ICPLB_DATA7)
551 PM_PUSH_SYNC(13)
552 PM_PUSH(0, ICPLB_DATA8)
553 PM_PUSH(1, ICPLB_DATA9)
554 PM_PUSH(2, ICPLB_DATA10)
555 PM_PUSH(3, ICPLB_DATA11)
556 PM_PUSH(4, ICPLB_DATA12)
557 PM_PUSH(5, ICPLB_DATA13)
558 PM_PUSH(6, ICPLB_DATA14)
559 PM_PUSH(7, ICPLB_DATA15)
560
561 /* Event Vectors */
562 FP = B1;
563 PM_PUSH(8, EVT2)
564 PM_PUSH(9, EVT3)
565 FP += 4; /* EVT4 */
566 PM_PUSH(10, EVT5)
567 PM_PUSH(11, EVT6)
568 PM_PUSH(12, EVT7)
569 PM_PUSH(13, EVT8)
570 PM_PUSH_SYNC(13)
571 PM_PUSH(0, EVT9)
572 PM_PUSH(1, EVT10)
573 PM_PUSH(2, EVT11)
574 PM_PUSH(3, EVT12)
575 PM_PUSH(4, EVT13)
576 PM_PUSH(5, EVT14)
577 PM_PUSH(6, EVT15)
578
579 /* CEC */
580 FP = B2;
581 PM_PUSH(7, IMASK)
582 FP += 4; /* IPEND */
583 PM_PUSH(8, ILAT)
584 PM_PUSH(9, IPRIO)
585
586 /* Core Timer */
587 FP = B3;
588 PM_PUSH(10, TCNTL)
589 PM_PUSH(11, TPERIOD)
590 PM_PUSH(12, TSCALE)
591 PM_PUSH(13, TCOUNT)
592 PM_PUSH_SYNC(13)
593
594 /* Misc non-contiguous registers */
595 FP = I0;
596 PM_CORE_PUSH(0, DMEM_CONTROL);
597 PM_CORE_PUSH(1, IMEM_CONTROL);
598 PM_CORE_PUSH(2, TBUFCTL);
599 PM_PUSH_SYNC(2)
600 289
601 /* Setup args to hibernate mode early for pipeline optimization */ 290 /* Setup args to hibernate mode early for pipeline optimization */
602 R0 = M3; 291 R0 = M3;
@@ -618,274 +307,9 @@ ENTRY(_do_hibernate)
618 307
619.Lpm_resume_here: 308.Lpm_resume_here:
620 309
621 /* Restore Core MMRs */ 310 bfin_core_mmr_restore;
622 I0.H = hi(COREMMR_BASE); 311 bfin_sys_mmr_restore;
623 I0.L = lo(COREMMR_BASE); 312 bfin_cpu_reg_restore;
624 I1 = I0;
625 I2 = I0;
626 I3 = I0;
627 B0 = I0;
628 B1 = I0;
629 B2 = I0;
630 B3 = I0;
631 I1.L = lo(DCPLB_ADDR15);
632 I2.L = lo(DCPLB_DATA15);
633 I3.L = lo(ICPLB_ADDR15);
634 B0.L = lo(ICPLB_DATA15);
635 B1.L = lo(EVT15);
636 B2.L = lo(IPRIO);
637 B3.L = lo(TCOUNT);
638
639 /* Misc non-contiguous registers */
640 FP = I0;
641 PM_POP_SYNC(2)
642 PM_CORE_POP(2, TBUFCTL)
643 PM_CORE_POP(1, IMEM_CONTROL)
644 PM_CORE_POP(0, DMEM_CONTROL)
645
646 /* Core Timer */
647 PM_POP_SYNC(13)
648 FP = B3;
649 PM_POP(13, TCOUNT)
650 PM_POP(12, TSCALE)
651 PM_POP(11, TPERIOD)
652 PM_POP(10, TCNTL)
653
654 /* CEC */
655 FP = B2;
656 PM_POP(9, IPRIO)
657 PM_POP(8, ILAT)
658 FP += -4; /* IPEND */
659 PM_POP(7, IMASK)
660
661 /* Event Vectors */
662 FP = B1;
663 PM_POP(6, EVT15)
664 PM_POP(5, EVT14)
665 PM_POP(4, EVT13)
666 PM_POP(3, EVT12)
667 PM_POP(2, EVT11)
668 PM_POP(1, EVT10)
669 PM_POP(0, EVT9)
670 PM_POP_SYNC(13)
671 PM_POP(13, EVT8)
672 PM_POP(12, EVT7)
673 PM_POP(11, EVT6)
674 PM_POP(10, EVT5)
675 FP += -4; /* EVT4 */
676 PM_POP(9, EVT3)
677 PM_POP(8, EVT2)
678
679 /* ICPLB Data */
680 FP = B0;
681 PM_POP(7, ICPLB_DATA15)
682 PM_POP(6, ICPLB_DATA14)
683 PM_POP(5, ICPLB_DATA13)
684 PM_POP(4, ICPLB_DATA12)
685 PM_POP(3, ICPLB_DATA11)
686 PM_POP(2, ICPLB_DATA10)
687 PM_POP(1, ICPLB_DATA9)
688 PM_POP(0, ICPLB_DATA8)
689 PM_POP_SYNC(13)
690 PM_POP(13, ICPLB_DATA7)
691 PM_POP(12, ICPLB_DATA6)
692 PM_POP(11, ICPLB_DATA5)
693 PM_POP(10, ICPLB_DATA4)
694 PM_POP(9, ICPLB_DATA3)
695 PM_POP(8, ICPLB_DATA2)
696 PM_POP(7, ICPLB_DATA1)
697 PM_POP(6, ICPLB_DATA0)
698
699 /* ICPLB Addr */
700 FP = I3;
701 PM_POP(5, ICPLB_ADDR15)
702 PM_POP(4, ICPLB_ADDR14)
703 PM_POP(3, ICPLB_ADDR13)
704 PM_POP(2, ICPLB_ADDR12)
705 PM_POP(1, ICPLB_ADDR11)
706 PM_POP(0, ICPLB_ADDR10)
707 PM_POP_SYNC(13)
708 PM_POP(13, ICPLB_ADDR9)
709 PM_POP(12, ICPLB_ADDR8)
710 PM_POP(11, ICPLB_ADDR7)
711 PM_POP(10, ICPLB_ADDR6)
712 PM_POP(9, ICPLB_ADDR5)
713 PM_POP(8, ICPLB_ADDR4)
714 PM_POP(7, ICPLB_ADDR3)
715 PM_POP(6, ICPLB_ADDR2)
716 PM_POP(5, ICPLB_ADDR1)
717 PM_POP(4, ICPLB_ADDR0)
718
719 /* DCPLB Data */
720 FP = I2;
721 PM_POP(3, DCPLB_DATA15)
722 PM_POP(2, DCPLB_DATA14)
723 PM_POP(1, DCPLB_DATA13)
724 PM_POP(0, DCPLB_DATA12)
725 PM_POP_SYNC(13)
726 PM_POP(13, DCPLB_DATA11)
727 PM_POP(12, DCPLB_DATA10)
728 PM_POP(11, DCPLB_DATA9)
729 PM_POP(10, DCPLB_DATA8)
730 PM_POP(9, DCPLB_DATA7)
731 PM_POP(8, DCPLB_DATA6)
732 PM_POP(7, DCPLB_DATA5)
733 PM_POP(6, DCPLB_DATA4)
734 PM_POP(5, DCPLB_DATA3)
735 PM_POP(4, DCPLB_DATA2)
736 PM_POP(3, DCPLB_DATA1)
737 PM_POP(2, DCPLB_DATA0)
738
739 /* DCPLB Addr */
740 FP = I1;
741 PM_POP(1, DCPLB_ADDR15)
742 PM_POP(0, DCPLB_ADDR14)
743 PM_POP_SYNC(13)
744 PM_POP(13, DCPLB_ADDR13)
745 PM_POP(12, DCPLB_ADDR12)
746 PM_POP(11, DCPLB_ADDR11)
747 PM_POP(10, DCPLB_ADDR10)
748 PM_POP(9, DCPLB_ADDR9)
749 PM_POP(8, DCPLB_ADDR8)
750 PM_POP(7, DCPLB_ADDR7)
751 PM_POP(6, DCPLB_ADDR6)
752 PM_POP(5, DCPLB_ADDR5)
753 PM_POP(4, DCPLB_ADDR4)
754 PM_POP(3, DCPLB_ADDR3)
755 PM_POP(2, DCPLB_ADDR2)
756 PM_POP(1, DCPLB_ADDR1)
757 PM_POP(0, DCPLB_ADDR0)
758
759 /* Restore System MMRs */
760 FP.H = hi(SYSMMR_BASE);
761 FP.L = lo(SYSMMR_BASE);
762
763#ifdef EBIU_FCTL
764 PM_POP_SYNC(12)
765 PM_SYS_POP(12, EBIU_FCTL)
766 PM_SYS_POP(11, EBIU_MODE)
767 PM_SYS_POP(10, EBIU_MBSCTL)
768#else
769 PM_POP_SYNC(9)
770#endif
771 PM_SYS_POP(9, EBIU_AMBCTL1)
772 PM_SYS_POP(8, EBIU_AMBCTL0)
773 PM_SYS_POP16(7, EBIU_AMGCTL)
774
775 PM_SYS_POP16(6, SYSCR)
776
777#ifdef PINT0_ASSIGN
778 PM_SYS_POP(5, PINT3_EDGE_SET)
779 PM_SYS_POP(4, PINT2_EDGE_SET)
780 PM_SYS_POP(3, PINT1_EDGE_SET)
781 PM_SYS_POP(2, PINT0_EDGE_SET)
782 PM_SYS_POP(1, PINT3_INVERT_SET)
783 PM_SYS_POP(0, PINT2_INVERT_SET)
784 PM_POP_SYNC(13)
785 PM_SYS_POP(13, PINT1_INVERT_SET)
786 PM_SYS_POP(12, PINT0_INVERT_SET)
787 PM_SYS_POP(11, PINT3_ASSIGN)
788 PM_SYS_POP(10, PINT2_ASSIGN)
789 PM_SYS_POP(9, PINT1_ASSIGN)
790 PM_SYS_POP(8, PINT0_ASSIGN)
791 PM_SYS_POP(7, PINT3_MASK_SET)
792 PM_SYS_POP(6, PINT2_MASK_SET)
793 PM_SYS_POP(5, PINT1_MASK_SET)
794 PM_SYS_POP(4, PINT0_MASK_SET)
795#endif
796
797#ifdef SIC_IWR2
798 PM_SYS_POP(3, SIC_IWR2)
799#endif
800#ifdef SIC_IWR1
801 PM_SYS_POP(2, SIC_IWR1)
802#endif
803#ifdef SIC_IWR0
804 PM_SYS_POP(1, SIC_IWR0)
805#endif
806#ifdef SIC_IWR
807 PM_SYS_POP(1, SIC_IWR)
808#endif
809
810#ifdef SIC_IAR11
811 PM_SYS_POP(0, SIC_IAR11)
812#endif
813 PM_POP_SYNC(13)
814#ifdef SIC_IAR8
815 PM_SYS_POP(13, SIC_IAR10)
816 PM_SYS_POP(12, SIC_IAR9)
817 PM_SYS_POP(11, SIC_IAR8)
818#endif
819#ifdef SIC_IAR7
820 PM_SYS_POP(10, SIC_IAR7)
821#endif
822#ifdef SIC_IAR6
823 PM_SYS_POP(9, SIC_IAR6)
824 PM_SYS_POP(8, SIC_IAR5)
825 PM_SYS_POP(7, SIC_IAR4)
826#endif
827#ifdef SIC_IAR3
828 PM_SYS_POP(6, SIC_IAR3)
829#endif
830#ifdef SIC_IAR0
831 PM_SYS_POP(5, SIC_IAR2)
832 PM_SYS_POP(4, SIC_IAR1)
833 PM_SYS_POP(3, SIC_IAR0)
834#endif
835#ifdef SIC_IMASK0
836# ifdef SIC_IMASK2
837 PM_SYS_POP(2, SIC_IMASK2)
838# endif
839 PM_SYS_POP(1, SIC_IMASK1)
840 PM_SYS_POP(0, SIC_IMASK0)
841#else
842 PM_SYS_POP(0, SIC_IMASK)
843#endif
844
845 /* Restore Core Registers */
846 RETI = [sp++];
847 SEQSTAT = [sp++];
848 RETX = [sp++];
849 SYSCFG = [sp++];
850 CYCLES2 = [sp++];
851 CYCLES = [sp++];
852 ASTAT = [sp++];
853 RETS = [sp++];
854
855 LB1 = [sp++];
856 LB0 = [sp++];
857 LT1 = [sp++];
858 LT0 = [sp++];
859 LC1 = [sp++];
860 LC0 = [sp++];
861
862 a1.w = [sp++];
863 a1.x = [sp++];
864 a0.w = [sp++];
865 a0.x = [sp++];
866 b3 = [sp++];
867 b2 = [sp++];
868 b1 = [sp++];
869 b0 = [sp++];
870
871 l3 = [sp++];
872 l2 = [sp++];
873 l1 = [sp++];
874 l0 = [sp++];
875
876 m3 = [sp++];
877 m2 = [sp++];
878 m1 = [sp++];
879 m0 = [sp++];
880
881 i3 = [sp++];
882 i2 = [sp++];
883 i1 = [sp++];
884 i0 = [sp++];
885
886 usp = [sp++];
887 fp = [sp++];
888 (R7:0, P5:0) = [sp++];
889 313
890 [--sp] = RETI; /* Clear Global Interrupt Disable */ 314 [--sp] = RETI; /* Clear Global Interrupt Disable */
891 SP += 4; 315 SP += 4;
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c
index 3c648a077e75..c25c2f1c819c 100644
--- a/arch/blackfin/mach-common/pm.c
+++ b/arch/blackfin/mach-common/pm.c
@@ -19,20 +19,33 @@
19#include <asm/gpio.h> 19#include <asm/gpio.h>
20#include <asm/dma.h> 20#include <asm/dma.h>
21#include <asm/dpmc.h> 21#include <asm/dpmc.h>
22#include <asm/pm.h>
22 23
24#ifdef CONFIG_BF60x
25struct bfin_cpu_pm_fns *bfin_cpu_pm;
26#endif
23 27
24void bfin_pm_suspend_standby_enter(void) 28void bfin_pm_suspend_standby_enter(void)
25{ 29{
30#ifndef CONFIG_BF60x
26 bfin_pm_standby_setup(); 31 bfin_pm_standby_setup();
32#endif
27 33
28#ifdef CONFIG_PM_BFIN_SLEEP_DEEPER 34#ifdef CONFIG_BF60x
29 sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); 35 bfin_cpu_pm->enter(PM_SUSPEND_STANDBY);
30#else 36#else
37# ifdef CONFIG_PM_BFIN_SLEEP_DEEPER
38 sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]);
39# else
31 sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); 40 sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]);
41# endif
32#endif 42#endif
33 43
44#ifndef CONFIG_BF60x
34 bfin_pm_standby_restore(); 45 bfin_pm_standby_restore();
46#endif
35 47
48#ifndef CONFIG_BF60x
36#ifdef SIC_IWR0 49#ifdef SIC_IWR0
37 bfin_write_SIC_IWR0(IWR_DISABLE_ALL); 50 bfin_write_SIC_IWR0(IWR_DISABLE_ALL);
38# ifdef SIC_IWR1 51# ifdef SIC_IWR1
@@ -52,6 +65,8 @@ void bfin_pm_suspend_standby_enter(void)
52#else 65#else
53 bfin_write_SIC_IWR(IWR_DISABLE_ALL); 66 bfin_write_SIC_IWR(IWR_DISABLE_ALL);
54#endif 67#endif
68
69#endif
55} 70}
56 71
57int bf53x_suspend_l1_mem(unsigned char *memptr) 72int bf53x_suspend_l1_mem(unsigned char *memptr)
@@ -83,10 +98,13 @@ int bf53x_resume_l1_mem(unsigned char *memptr)
83} 98}
84 99
85#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK) 100#if defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)
101# ifdef CONFIG_BF60x
102__attribute__((l1_text))
103# endif
86static void flushinv_all_dcache(void) 104static void flushinv_all_dcache(void)
87{ 105{
88 u32 way, bank, subbank, set; 106 register u32 way, bank, subbank, set;
89 u32 status, addr; 107 register u32 status, addr;
90 u32 dmem_ctl = bfin_read_DMEM_CONTROL(); 108 u32 dmem_ctl = bfin_read_DMEM_CONTROL();
91 109
92 for (bank = 0; bank < 2; ++bank) { 110 for (bank = 0; bank < 2; ++bank) {
@@ -133,7 +151,11 @@ int bfin_pm_suspend_mem_enter(void)
133 return -ENOMEM; 151 return -ENOMEM;
134 } 152 }
135 153
154#ifndef CONFIG_BF60x
136 wakeup = bfin_read_VR_CTL() & ~FREQ; 155 wakeup = bfin_read_VR_CTL() & ~FREQ;
156#else
157
158#endif
137 wakeup |= SCKELOW; 159 wakeup |= SCKELOW;
138 160
139#ifdef CONFIG_PM_BFIN_WAKE_PH6 161#ifdef CONFIG_PM_BFIN_WAKE_PH6
@@ -159,7 +181,11 @@ int bfin_pm_suspend_mem_enter(void)
159 _disable_icplb(); 181 _disable_icplb();
160 bf53x_suspend_l1_mem(memptr); 182 bf53x_suspend_l1_mem(memptr);
161 183
184#ifndef CONFIG_BF60x
162 do_hibernate(wakeup | vr_wakeup); /* See you later! */ 185 do_hibernate(wakeup | vr_wakeup); /* See you later! */
186#else
187 bfin_cpu_pm->enter(PM_SUSPEND_MEM);
188#endif
163 189
164 bf53x_resume_l1_mem(memptr); 190 bf53x_resume_l1_mem(memptr);
165 191