diff options
Diffstat (limited to 'arch/blackfin/mach-common')
-rw-r--r-- | arch/blackfin/mach-common/arch_checks.c | 6 | ||||
-rw-r--r-- | arch/blackfin/mach-common/dpmc_modes.S | 607 | ||||
-rw-r--r-- | arch/blackfin/mach-common/entry.S | 50 | ||||
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 4 | ||||
-rw-r--r-- | arch/blackfin/mach-common/pm.c | 225 |
5 files changed, 829 insertions, 63 deletions
diff --git a/arch/blackfin/mach-common/arch_checks.c b/arch/blackfin/mach-common/arch_checks.c index caaab49e9cfa..f9160d83b91f 100644 --- a/arch/blackfin/mach-common/arch_checks.c +++ b/arch/blackfin/mach-common/arch_checks.c | |||
@@ -53,9 +53,3 @@ | |||
53 | # endif | 53 | # endif |
54 | 54 | ||
55 | #endif /* CONFIG_BFIN_KERNEL_CLOCK */ | 55 | #endif /* CONFIG_BFIN_KERNEL_CLOCK */ |
56 | |||
57 | #ifdef CONFIG_MEM_SIZE | ||
58 | #if (CONFIG_MEM_SIZE % 4) | ||
59 | #error "SDRAM mem size must be multible of 4MB" | ||
60 | #endif | ||
61 | #endif | ||
diff --git a/arch/blackfin/mach-common/dpmc_modes.S b/arch/blackfin/mach-common/dpmc_modes.S index b7981d31c392..5e3f1d8a4fb8 100644 --- a/arch/blackfin/mach-common/dpmc_modes.S +++ b/arch/blackfin/mach-common/dpmc_modes.S | |||
@@ -7,7 +7,7 @@ | |||
7 | #include <linux/linkage.h> | 7 | #include <linux/linkage.h> |
8 | #include <asm/blackfin.h> | 8 | #include <asm/blackfin.h> |
9 | #include <asm/mach/irq.h> | 9 | #include <asm/mach/irq.h> |
10 | 10 | #include <asm/dpmc.h> | |
11 | 11 | ||
12 | .section .l1.text | 12 | .section .l1.text |
13 | 13 | ||
@@ -51,31 +51,32 @@ ENTRY(_sleep_mode) | |||
51 | RETS = [SP++]; | 51 | RETS = [SP++]; |
52 | ( R7:0, P5:0 ) = [SP++]; | 52 | ( R7:0, P5:0 ) = [SP++]; |
53 | RTS; | 53 | RTS; |
54 | ENDPROC(_sleep_mode) | ||
54 | 55 | ||
55 | ENTRY(_hibernate_mode) | 56 | ENTRY(_hibernate_mode) |
56 | [--SP] = ( R7:0, P5:0 ); | 57 | [--SP] = ( R7:0, P5:0 ); |
57 | [--SP] = RETS; | 58 | [--SP] = RETS; |
58 | 59 | ||
60 | R3 = R0; | ||
61 | R0 = IWR_DISABLE_ALL; | ||
62 | R1 = IWR_DISABLE_ALL; | ||
63 | R2 = IWR_DISABLE_ALL; | ||
59 | call _set_sic_iwr; | 64 | call _set_sic_iwr; |
65 | call _set_dram_srfs; | ||
66 | SSYNC; | ||
60 | 67 | ||
61 | R0 = 0xFFFF (Z); | 68 | R0 = 0xFFFF (Z); |
62 | call _set_rtc_istat; | 69 | call _set_rtc_istat; |
63 | 70 | ||
64 | P0.H = hi(VR_CTL); | 71 | P0.H = hi(VR_CTL); |
65 | P0.L = lo(VR_CTL); | 72 | P0.L = lo(VR_CTL); |
66 | R1 = W[P0](z); | ||
67 | BITSET (R1, 8); | ||
68 | BITCLR (R1, 0); | ||
69 | BITCLR (R1, 1); | ||
70 | W[P0] = R1.L; | ||
71 | SSYNC; | ||
72 | 73 | ||
74 | W[P0] = R3.L; | ||
73 | CLI R2; | 75 | CLI R2; |
74 | IDLE; | 76 | IDLE; |
75 | 77 | .Lforever: | |
76 | /* Actually, adding anything may not be necessary...SDRAM contents | 78 | jump .Lforever; |
77 | * are lost | 79 | ENDPROC(_hibernate_mode) |
78 | */ | ||
79 | 80 | ||
80 | ENTRY(_deep_sleep) | 81 | ENTRY(_deep_sleep) |
81 | [--SP] = ( R7:0, P5:0 ); | 82 | [--SP] = ( R7:0, P5:0 ); |
@@ -131,6 +132,7 @@ ENTRY(_deep_sleep) | |||
131 | RETS = [SP++]; | 132 | RETS = [SP++]; |
132 | ( R7:0, P5:0 ) = [SP++]; | 133 | ( R7:0, P5:0 ) = [SP++]; |
133 | RTS; | 134 | RTS; |
135 | ENDPROC(_deep_sleep) | ||
134 | 136 | ||
135 | ENTRY(_sleep_deeper) | 137 | ENTRY(_sleep_deeper) |
136 | [--SP] = ( R7:0, P5:0 ); | 138 | [--SP] = ( R7:0, P5:0 ); |
@@ -232,53 +234,73 @@ ENTRY(_sleep_deeper) | |||
232 | RETS = [SP++]; | 234 | RETS = [SP++]; |
233 | ( R7:0, P5:0 ) = [SP++]; | 235 | ( R7:0, P5:0 ) = [SP++]; |
234 | RTS; | 236 | RTS; |
237 | ENDPROC(_sleep_deeper) | ||
235 | 238 | ||
236 | ENTRY(_set_dram_srfs) | 239 | ENTRY(_set_dram_srfs) |
237 | /* set the dram to self refresh mode */ | 240 | /* set the dram to self refresh mode */ |
238 | #if defined(CONFIG_BF54x) | 241 | SSYNC; |
242 | #if defined(EBIU_RSTCTL) /* DDR */ | ||
239 | P0.H = hi(EBIU_RSTCTL); | 243 | P0.H = hi(EBIU_RSTCTL); |
240 | P0.L = lo(EBIU_RSTCTL); | 244 | P0.L = lo(EBIU_RSTCTL); |
241 | R2 = [P0]; | 245 | R2 = [P0]; |
242 | R3.H = hi(SRREQ); | 246 | BITSET(R2, 3); /* SRREQ enter self-refresh mode */ |
243 | R3.L = lo(SRREQ); | 247 | [P0] = R2; |
244 | #else | 248 | SSYNC; |
245 | P0.H = hi(EBIU_SDGCTL); | 249 | 1: |
250 | R2 = [P0]; | ||
251 | CC = BITTST(R2, 4); | ||
252 | if !CC JUMP 1b; | ||
253 | #else /* SDRAM */ | ||
246 | P0.L = lo(EBIU_SDGCTL); | 254 | P0.L = lo(EBIU_SDGCTL); |
255 | P0.H = hi(EBIU_SDGCTL); | ||
247 | R2 = [P0]; | 256 | R2 = [P0]; |
248 | R3.H = hi(SRFS); | 257 | BITSET(R2, 24); /* SRFS enter self-refresh mode */ |
249 | R3.L = lo(SRFS); | ||
250 | #endif | ||
251 | R2 = R2|R3; | ||
252 | [P0] = R2; | 258 | [P0] = R2; |
253 | ssync; | 259 | SSYNC; |
254 | #if defined(CONFIG_BF54x) | 260 | |
255 | .LSRR_MODE: | 261 | P0.L = lo(EBIU_SDSTAT); |
262 | P0.H = hi(EBIU_SDSTAT); | ||
263 | 1: | ||
264 | R2 = w[P0]; | ||
265 | SSYNC; | ||
266 | cc = BITTST(R2, 1); /* SDSRA poll self-refresh status */ | ||
267 | if !cc jump 1b; | ||
268 | |||
269 | P0.L = lo(EBIU_SDGCTL); | ||
270 | P0.H = hi(EBIU_SDGCTL); | ||
256 | R2 = [P0]; | 271 | R2 = [P0]; |
257 | CC = BITTST(R2, 4); | 272 | BITCLR(R2, 0); /* SCTLE disable CLKOUT */ |
258 | if !CC JUMP .LSRR_MODE; | 273 | [P0] = R2; |
259 | #endif | 274 | #endif |
260 | RTS; | 275 | RTS; |
276 | ENDPROC(_set_dram_srfs) | ||
261 | 277 | ||
262 | ENTRY(_unset_dram_srfs) | 278 | ENTRY(_unset_dram_srfs) |
263 | /* set the dram out of self refresh mode */ | 279 | /* set the dram out of self refresh mode */ |
264 | #if defined(CONFIG_BF54x) | 280 | #if defined(EBIU_RSTCTL) /* DDR */ |
265 | P0.H = hi(EBIU_RSTCTL); | 281 | P0.H = hi(EBIU_RSTCTL); |
266 | P0.L = lo(EBIU_RSTCTL); | 282 | P0.L = lo(EBIU_RSTCTL); |
267 | R2 = [P0]; | 283 | R2 = [P0]; |
268 | R3.H = hi(SRREQ); | 284 | BITCLR(R2, 3); /* clear SRREQ bit */ |
269 | R3.L = lo(SRREQ); | 285 | [P0] = R2; |
270 | #else | 286 | #elif defined(EBIU_SDGCTL) /* SDRAM */ |
287 | |||
288 | P0.L = lo(EBIU_SDGCTL); /* release CLKOUT from self-refresh */ | ||
289 | P0.H = hi(EBIU_SDGCTL); | ||
290 | R2 = [P0]; | ||
291 | BITSET(R2, 0); /* SCTLE enable CLKOUT */ | ||
292 | [P0] = R2 | ||
293 | SSYNC; | ||
294 | |||
295 | P0.L = lo(EBIU_SDGCTL); /* release SDRAM from self-refresh */ | ||
271 | P0.H = hi(EBIU_SDGCTL); | 296 | P0.H = hi(EBIU_SDGCTL); |
272 | P0.L = lo(EBIU_SDGCTL); | ||
273 | R2 = [P0]; | 297 | R2 = [P0]; |
274 | R3.H = hi(SRFS); | 298 | BITCLR(R2, 24); /* clear SRFS bit */ |
275 | R3.L = lo(SRFS); | 299 | [P0] = R2 |
276 | #endif | 300 | #endif |
277 | R3 = ~R3; | 301 | SSYNC; |
278 | R2 = R2&R3; | ||
279 | [P0] = R2; | ||
280 | ssync; | ||
281 | RTS; | 302 | RTS; |
303 | ENDPROC(_unset_dram_srfs) | ||
282 | 304 | ||
283 | ENTRY(_set_sic_iwr) | 305 | ENTRY(_set_sic_iwr) |
284 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) | 306 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) |
@@ -300,6 +322,7 @@ ENTRY(_set_sic_iwr) | |||
300 | 322 | ||
301 | SSYNC; | 323 | SSYNC; |
302 | RTS; | 324 | RTS; |
325 | ENDPROC(_set_sic_iwr) | ||
303 | 326 | ||
304 | ENTRY(_set_rtc_istat) | 327 | ENTRY(_set_rtc_istat) |
305 | #ifndef CONFIG_BF561 | 328 | #ifndef CONFIG_BF561 |
@@ -307,8 +330,14 @@ ENTRY(_set_rtc_istat) | |||
307 | P0.L = lo(RTC_ISTAT); | 330 | P0.L = lo(RTC_ISTAT); |
308 | w[P0] = R0.L; | 331 | w[P0] = R0.L; |
309 | SSYNC; | 332 | SSYNC; |
333 | #elif (ANOMALY_05000371) | ||
334 | nop; | ||
335 | nop; | ||
336 | nop; | ||
337 | nop; | ||
310 | #endif | 338 | #endif |
311 | RTS; | 339 | RTS; |
340 | ENDPROC(_set_rtc_istat) | ||
312 | 341 | ||
313 | ENTRY(_test_pll_locked) | 342 | ENTRY(_test_pll_locked) |
314 | P0.H = hi(PLL_STAT); | 343 | P0.H = hi(PLL_STAT); |
@@ -318,3 +347,509 @@ ENTRY(_test_pll_locked) | |||
318 | CC = BITTST(R0,5); | 347 | CC = BITTST(R0,5); |
319 | IF !CC JUMP 1b; | 348 | IF !CC JUMP 1b; |
320 | RTS; | 349 | RTS; |
350 | ENDPROC(_test_pll_locked) | ||
351 | |||
352 | .section .text | ||
353 | |||
354 | ENTRY(_do_hibernate) | ||
355 | [--SP] = ( R7:0, P5:0 ); | ||
356 | [--SP] = RETS; | ||
357 | /* Save System MMRs */ | ||
358 | R2 = R0; | ||
359 | P0.H = hi(PLL_CTL); | ||
360 | P0.L = lo(PLL_CTL); | ||
361 | |||
362 | #ifdef SIC_IMASK0 | ||
363 | PM_SYS_PUSH(SIC_IMASK0) | ||
364 | #endif | ||
365 | #ifdef SIC_IMASK1 | ||
366 | PM_SYS_PUSH(SIC_IMASK1) | ||
367 | #endif | ||
368 | #ifdef SIC_IMASK2 | ||
369 | PM_SYS_PUSH(SIC_IMASK2) | ||
370 | #endif | ||
371 | #ifdef SIC_IMASK | ||
372 | PM_SYS_PUSH(SIC_IMASK) | ||
373 | #endif | ||
374 | #ifdef SICA_IMASK0 | ||
375 | PM_SYS_PUSH(SICA_IMASK0) | ||
376 | #endif | ||
377 | #ifdef SICA_IMASK1 | ||
378 | PM_SYS_PUSH(SICA_IMASK1) | ||
379 | #endif | ||
380 | #ifdef SIC_IAR2 | ||
381 | PM_SYS_PUSH(SIC_IAR0) | ||
382 | PM_SYS_PUSH(SIC_IAR1) | ||
383 | PM_SYS_PUSH(SIC_IAR2) | ||
384 | #endif | ||
385 | #ifdef SIC_IAR3 | ||
386 | PM_SYS_PUSH(SIC_IAR3) | ||
387 | #endif | ||
388 | #ifdef SIC_IAR4 | ||
389 | PM_SYS_PUSH(SIC_IAR4) | ||
390 | PM_SYS_PUSH(SIC_IAR5) | ||
391 | PM_SYS_PUSH(SIC_IAR6) | ||
392 | #endif | ||
393 | #ifdef SIC_IAR7 | ||
394 | PM_SYS_PUSH(SIC_IAR7) | ||
395 | #endif | ||
396 | #ifdef SIC_IAR8 | ||
397 | PM_SYS_PUSH(SIC_IAR8) | ||
398 | PM_SYS_PUSH(SIC_IAR9) | ||
399 | PM_SYS_PUSH(SIC_IAR10) | ||
400 | PM_SYS_PUSH(SIC_IAR11) | ||
401 | #endif | ||
402 | |||
403 | #ifdef SICA_IAR0 | ||
404 | PM_SYS_PUSH(SICA_IAR0) | ||
405 | PM_SYS_PUSH(SICA_IAR1) | ||
406 | PM_SYS_PUSH(SICA_IAR2) | ||
407 | PM_SYS_PUSH(SICA_IAR3) | ||
408 | PM_SYS_PUSH(SICA_IAR4) | ||
409 | PM_SYS_PUSH(SICA_IAR5) | ||
410 | PM_SYS_PUSH(SICA_IAR6) | ||
411 | PM_SYS_PUSH(SICA_IAR7) | ||
412 | #endif | ||
413 | |||
414 | #ifdef SIC_IWR | ||
415 | PM_SYS_PUSH(SIC_IWR) | ||
416 | #endif | ||
417 | #ifdef SIC_IWR0 | ||
418 | PM_SYS_PUSH(SIC_IWR0) | ||
419 | #endif | ||
420 | #ifdef SIC_IWR1 | ||
421 | PM_SYS_PUSH(SIC_IWR1) | ||
422 | #endif | ||
423 | #ifdef SIC_IWR2 | ||
424 | PM_SYS_PUSH(SIC_IWR2) | ||
425 | #endif | ||
426 | #ifdef SICA_IWR0 | ||
427 | PM_SYS_PUSH(SICA_IWR0) | ||
428 | #endif | ||
429 | #ifdef SICA_IWR1 | ||
430 | PM_SYS_PUSH(SICA_IWR1) | ||
431 | #endif | ||
432 | |||
433 | #ifdef PINT0_ASSIGN | ||
434 | PM_SYS_PUSH(PINT0_ASSIGN) | ||
435 | PM_SYS_PUSH(PINT1_ASSIGN) | ||
436 | PM_SYS_PUSH(PINT2_ASSIGN) | ||
437 | PM_SYS_PUSH(PINT3_ASSIGN) | ||
438 | #endif | ||
439 | |||
440 | PM_SYS_PUSH(EBIU_AMBCTL0) | ||
441 | PM_SYS_PUSH(EBIU_AMBCTL1) | ||
442 | PM_SYS_PUSH16(EBIU_AMGCTL) | ||
443 | |||
444 | #ifdef EBIU_FCTL | ||
445 | PM_SYS_PUSH(EBIU_MBSCTL) | ||
446 | PM_SYS_PUSH(EBIU_MODE) | ||
447 | PM_SYS_PUSH(EBIU_FCTL) | ||
448 | #endif | ||
449 | |||
450 | PM_SYS_PUSH16(SYSCR) | ||
451 | |||
452 | /* Save Core MMRs */ | ||
453 | P0.H = hi(SRAM_BASE_ADDRESS); | ||
454 | P0.L = lo(SRAM_BASE_ADDRESS); | ||
455 | |||
456 | PM_PUSH(DMEM_CONTROL) | ||
457 | PM_PUSH(DCPLB_ADDR0) | ||
458 | PM_PUSH(DCPLB_ADDR1) | ||
459 | PM_PUSH(DCPLB_ADDR2) | ||
460 | PM_PUSH(DCPLB_ADDR3) | ||
461 | PM_PUSH(DCPLB_ADDR4) | ||
462 | PM_PUSH(DCPLB_ADDR5) | ||
463 | PM_PUSH(DCPLB_ADDR6) | ||
464 | PM_PUSH(DCPLB_ADDR7) | ||
465 | PM_PUSH(DCPLB_ADDR8) | ||
466 | PM_PUSH(DCPLB_ADDR9) | ||
467 | PM_PUSH(DCPLB_ADDR10) | ||
468 | PM_PUSH(DCPLB_ADDR11) | ||
469 | PM_PUSH(DCPLB_ADDR12) | ||
470 | PM_PUSH(DCPLB_ADDR13) | ||
471 | PM_PUSH(DCPLB_ADDR14) | ||
472 | PM_PUSH(DCPLB_ADDR15) | ||
473 | PM_PUSH(DCPLB_DATA0) | ||
474 | PM_PUSH(DCPLB_DATA1) | ||
475 | PM_PUSH(DCPLB_DATA2) | ||
476 | PM_PUSH(DCPLB_DATA3) | ||
477 | PM_PUSH(DCPLB_DATA4) | ||
478 | PM_PUSH(DCPLB_DATA5) | ||
479 | PM_PUSH(DCPLB_DATA6) | ||
480 | PM_PUSH(DCPLB_DATA7) | ||
481 | PM_PUSH(DCPLB_DATA8) | ||
482 | PM_PUSH(DCPLB_DATA9) | ||
483 | PM_PUSH(DCPLB_DATA10) | ||
484 | PM_PUSH(DCPLB_DATA11) | ||
485 | PM_PUSH(DCPLB_DATA12) | ||
486 | PM_PUSH(DCPLB_DATA13) | ||
487 | PM_PUSH(DCPLB_DATA14) | ||
488 | PM_PUSH(DCPLB_DATA15) | ||
489 | PM_PUSH(IMEM_CONTROL) | ||
490 | PM_PUSH(ICPLB_ADDR0) | ||
491 | PM_PUSH(ICPLB_ADDR1) | ||
492 | PM_PUSH(ICPLB_ADDR2) | ||
493 | PM_PUSH(ICPLB_ADDR3) | ||
494 | PM_PUSH(ICPLB_ADDR4) | ||
495 | PM_PUSH(ICPLB_ADDR5) | ||
496 | PM_PUSH(ICPLB_ADDR6) | ||
497 | PM_PUSH(ICPLB_ADDR7) | ||
498 | PM_PUSH(ICPLB_ADDR8) | ||
499 | PM_PUSH(ICPLB_ADDR9) | ||
500 | PM_PUSH(ICPLB_ADDR10) | ||
501 | PM_PUSH(ICPLB_ADDR11) | ||
502 | PM_PUSH(ICPLB_ADDR12) | ||
503 | PM_PUSH(ICPLB_ADDR13) | ||
504 | PM_PUSH(ICPLB_ADDR14) | ||
505 | PM_PUSH(ICPLB_ADDR15) | ||
506 | PM_PUSH(ICPLB_DATA0) | ||
507 | PM_PUSH(ICPLB_DATA1) | ||
508 | PM_PUSH(ICPLB_DATA2) | ||
509 | PM_PUSH(ICPLB_DATA3) | ||
510 | PM_PUSH(ICPLB_DATA4) | ||
511 | PM_PUSH(ICPLB_DATA5) | ||
512 | PM_PUSH(ICPLB_DATA6) | ||
513 | PM_PUSH(ICPLB_DATA7) | ||
514 | PM_PUSH(ICPLB_DATA8) | ||
515 | PM_PUSH(ICPLB_DATA9) | ||
516 | PM_PUSH(ICPLB_DATA10) | ||
517 | PM_PUSH(ICPLB_DATA11) | ||
518 | PM_PUSH(ICPLB_DATA12) | ||
519 | PM_PUSH(ICPLB_DATA13) | ||
520 | PM_PUSH(ICPLB_DATA14) | ||
521 | PM_PUSH(ICPLB_DATA15) | ||
522 | PM_PUSH(EVT0) | ||
523 | PM_PUSH(EVT1) | ||
524 | PM_PUSH(EVT2) | ||
525 | PM_PUSH(EVT3) | ||
526 | PM_PUSH(EVT4) | ||
527 | PM_PUSH(EVT5) | ||
528 | PM_PUSH(EVT6) | ||
529 | PM_PUSH(EVT7) | ||
530 | PM_PUSH(EVT8) | ||
531 | PM_PUSH(EVT9) | ||
532 | PM_PUSH(EVT10) | ||
533 | PM_PUSH(EVT11) | ||
534 | PM_PUSH(EVT12) | ||
535 | PM_PUSH(EVT13) | ||
536 | PM_PUSH(EVT14) | ||
537 | PM_PUSH(EVT15) | ||
538 | PM_PUSH(IMASK) | ||
539 | PM_PUSH(ILAT) | ||
540 | PM_PUSH(IPRIO) | ||
541 | PM_PUSH(TCNTL) | ||
542 | PM_PUSH(TPERIOD) | ||
543 | PM_PUSH(TSCALE) | ||
544 | PM_PUSH(TCOUNT) | ||
545 | PM_PUSH(TBUFCTL) | ||
546 | |||
547 | /* Save Core Registers */ | ||
548 | [--sp] = SYSCFG; | ||
549 | [--sp] = ( R7:0, P5:0 ); | ||
550 | [--sp] = fp; | ||
551 | [--sp] = usp; | ||
552 | |||
553 | [--sp] = i0; | ||
554 | [--sp] = i1; | ||
555 | [--sp] = i2; | ||
556 | [--sp] = i3; | ||
557 | |||
558 | [--sp] = m0; | ||
559 | [--sp] = m1; | ||
560 | [--sp] = m2; | ||
561 | [--sp] = m3; | ||
562 | |||
563 | [--sp] = l0; | ||
564 | [--sp] = l1; | ||
565 | [--sp] = l2; | ||
566 | [--sp] = l3; | ||
567 | |||
568 | [--sp] = b0; | ||
569 | [--sp] = b1; | ||
570 | [--sp] = b2; | ||
571 | [--sp] = b3; | ||
572 | [--sp] = a0.x; | ||
573 | [--sp] = a0.w; | ||
574 | [--sp] = a1.x; | ||
575 | [--sp] = a1.w; | ||
576 | |||
577 | [--sp] = LC0; | ||
578 | [--sp] = LC1; | ||
579 | [--sp] = LT0; | ||
580 | [--sp] = LT1; | ||
581 | [--sp] = LB0; | ||
582 | [--sp] = LB1; | ||
583 | |||
584 | [--sp] = ASTAT; | ||
585 | [--sp] = CYCLES; | ||
586 | [--sp] = CYCLES2; | ||
587 | |||
588 | [--sp] = RETS; | ||
589 | r0 = RETI; | ||
590 | [--sp] = r0; | ||
591 | [--sp] = RETX; | ||
592 | [--sp] = RETN; | ||
593 | [--sp] = RETE; | ||
594 | [--sp] = SEQSTAT; | ||
595 | |||
596 | /* Save Magic, return address and Stack Pointer */ | ||
597 | P0.H = 0; | ||
598 | P0.L = 0; | ||
599 | R0.H = 0xDEAD; /* Hibernate Magic */ | ||
600 | R0.L = 0xBEEF; | ||
601 | [P0++] = R0; /* Store Hibernate Magic */ | ||
602 | R0.H = .Lpm_resume_here; | ||
603 | R0.L = .Lpm_resume_here; | ||
604 | [P0++] = R0; /* Save Return Address */ | ||
605 | [P0++] = SP; /* Save Stack Pointer */ | ||
606 | P0.H = _hibernate_mode; | ||
607 | P0.L = _hibernate_mode; | ||
608 | R0 = R2; | ||
609 | call (P0); /* Goodbye */ | ||
610 | |||
611 | .Lpm_resume_here: | ||
612 | |||
613 | /* Restore Core Registers */ | ||
614 | SEQSTAT = [sp++]; | ||
615 | RETE = [sp++]; | ||
616 | RETN = [sp++]; | ||
617 | RETX = [sp++]; | ||
618 | r0 = [sp++]; | ||
619 | RETI = r0; | ||
620 | RETS = [sp++]; | ||
621 | |||
622 | CYCLES2 = [sp++]; | ||
623 | CYCLES = [sp++]; | ||
624 | ASTAT = [sp++]; | ||
625 | |||
626 | LB1 = [sp++]; | ||
627 | LB0 = [sp++]; | ||
628 | LT1 = [sp++]; | ||
629 | LT0 = [sp++]; | ||
630 | LC1 = [sp++]; | ||
631 | LC0 = [sp++]; | ||
632 | |||
633 | a1.w = [sp++]; | ||
634 | a1.x = [sp++]; | ||
635 | a0.w = [sp++]; | ||
636 | a0.x = [sp++]; | ||
637 | b3 = [sp++]; | ||
638 | b2 = [sp++]; | ||
639 | b1 = [sp++]; | ||
640 | b0 = [sp++]; | ||
641 | |||
642 | l3 = [sp++]; | ||
643 | l2 = [sp++]; | ||
644 | l1 = [sp++]; | ||
645 | l0 = [sp++]; | ||
646 | |||
647 | m3 = [sp++]; | ||
648 | m2 = [sp++]; | ||
649 | m1 = [sp++]; | ||
650 | m0 = [sp++]; | ||
651 | |||
652 | i3 = [sp++]; | ||
653 | i2 = [sp++]; | ||
654 | i1 = [sp++]; | ||
655 | i0 = [sp++]; | ||
656 | |||
657 | usp = [sp++]; | ||
658 | fp = [sp++]; | ||
659 | |||
660 | ( R7 : 0, P5 : 0) = [ SP ++ ]; | ||
661 | SYSCFG = [sp++]; | ||
662 | |||
663 | /* Restore Core MMRs */ | ||
664 | |||
665 | PM_POP(TBUFCTL) | ||
666 | PM_POP(TCOUNT) | ||
667 | PM_POP(TSCALE) | ||
668 | PM_POP(TPERIOD) | ||
669 | PM_POP(TCNTL) | ||
670 | PM_POP(IPRIO) | ||
671 | PM_POP(ILAT) | ||
672 | PM_POP(IMASK) | ||
673 | PM_POP(EVT15) | ||
674 | PM_POP(EVT14) | ||
675 | PM_POP(EVT13) | ||
676 | PM_POP(EVT12) | ||
677 | PM_POP(EVT11) | ||
678 | PM_POP(EVT10) | ||
679 | PM_POP(EVT9) | ||
680 | PM_POP(EVT8) | ||
681 | PM_POP(EVT7) | ||
682 | PM_POP(EVT6) | ||
683 | PM_POP(EVT5) | ||
684 | PM_POP(EVT4) | ||
685 | PM_POP(EVT3) | ||
686 | PM_POP(EVT2) | ||
687 | PM_POP(EVT1) | ||
688 | PM_POP(EVT0) | ||
689 | PM_POP(ICPLB_DATA15) | ||
690 | PM_POP(ICPLB_DATA14) | ||
691 | PM_POP(ICPLB_DATA13) | ||
692 | PM_POP(ICPLB_DATA12) | ||
693 | PM_POP(ICPLB_DATA11) | ||
694 | PM_POP(ICPLB_DATA10) | ||
695 | PM_POP(ICPLB_DATA9) | ||
696 | PM_POP(ICPLB_DATA8) | ||
697 | PM_POP(ICPLB_DATA7) | ||
698 | PM_POP(ICPLB_DATA6) | ||
699 | PM_POP(ICPLB_DATA5) | ||
700 | PM_POP(ICPLB_DATA4) | ||
701 | PM_POP(ICPLB_DATA3) | ||
702 | PM_POP(ICPLB_DATA2) | ||
703 | PM_POP(ICPLB_DATA1) | ||
704 | PM_POP(ICPLB_DATA0) | ||
705 | PM_POP(ICPLB_ADDR15) | ||
706 | PM_POP(ICPLB_ADDR14) | ||
707 | PM_POP(ICPLB_ADDR13) | ||
708 | PM_POP(ICPLB_ADDR12) | ||
709 | PM_POP(ICPLB_ADDR11) | ||
710 | PM_POP(ICPLB_ADDR10) | ||
711 | PM_POP(ICPLB_ADDR9) | ||
712 | PM_POP(ICPLB_ADDR8) | ||
713 | PM_POP(ICPLB_ADDR7) | ||
714 | PM_POP(ICPLB_ADDR6) | ||
715 | PM_POP(ICPLB_ADDR5) | ||
716 | PM_POP(ICPLB_ADDR4) | ||
717 | PM_POP(ICPLB_ADDR3) | ||
718 | PM_POP(ICPLB_ADDR2) | ||
719 | PM_POP(ICPLB_ADDR1) | ||
720 | PM_POP(ICPLB_ADDR0) | ||
721 | PM_POP(IMEM_CONTROL) | ||
722 | PM_POP(DCPLB_DATA15) | ||
723 | PM_POP(DCPLB_DATA14) | ||
724 | PM_POP(DCPLB_DATA13) | ||
725 | PM_POP(DCPLB_DATA12) | ||
726 | PM_POP(DCPLB_DATA11) | ||
727 | PM_POP(DCPLB_DATA10) | ||
728 | PM_POP(DCPLB_DATA9) | ||
729 | PM_POP(DCPLB_DATA8) | ||
730 | PM_POP(DCPLB_DATA7) | ||
731 | PM_POP(DCPLB_DATA6) | ||
732 | PM_POP(DCPLB_DATA5) | ||
733 | PM_POP(DCPLB_DATA4) | ||
734 | PM_POP(DCPLB_DATA3) | ||
735 | PM_POP(DCPLB_DATA2) | ||
736 | PM_POP(DCPLB_DATA1) | ||
737 | PM_POP(DCPLB_DATA0) | ||
738 | PM_POP(DCPLB_ADDR15) | ||
739 | PM_POP(DCPLB_ADDR14) | ||
740 | PM_POP(DCPLB_ADDR13) | ||
741 | PM_POP(DCPLB_ADDR12) | ||
742 | PM_POP(DCPLB_ADDR11) | ||
743 | PM_POP(DCPLB_ADDR10) | ||
744 | PM_POP(DCPLB_ADDR9) | ||
745 | PM_POP(DCPLB_ADDR8) | ||
746 | PM_POP(DCPLB_ADDR7) | ||
747 | PM_POP(DCPLB_ADDR6) | ||
748 | PM_POP(DCPLB_ADDR5) | ||
749 | PM_POP(DCPLB_ADDR4) | ||
750 | PM_POP(DCPLB_ADDR3) | ||
751 | PM_POP(DCPLB_ADDR2) | ||
752 | PM_POP(DCPLB_ADDR1) | ||
753 | PM_POP(DCPLB_ADDR0) | ||
754 | PM_POP(DMEM_CONTROL) | ||
755 | |||
756 | /* Restore System MMRs */ | ||
757 | |||
758 | P0.H = hi(PLL_CTL); | ||
759 | P0.L = lo(PLL_CTL); | ||
760 | PM_SYS_POP16(SYSCR) | ||
761 | |||
762 | #ifdef EBIU_FCTL | ||
763 | PM_SYS_POP(EBIU_FCTL) | ||
764 | PM_SYS_POP(EBIU_MODE) | ||
765 | PM_SYS_POP(EBIU_MBSCTL) | ||
766 | #endif | ||
767 | PM_SYS_POP16(EBIU_AMGCTL) | ||
768 | PM_SYS_POP(EBIU_AMBCTL1) | ||
769 | PM_SYS_POP(EBIU_AMBCTL0) | ||
770 | |||
771 | #ifdef PINT0_ASSIGN | ||
772 | PM_SYS_POP(PINT3_ASSIGN) | ||
773 | PM_SYS_POP(PINT2_ASSIGN) | ||
774 | PM_SYS_POP(PINT1_ASSIGN) | ||
775 | PM_SYS_POP(PINT0_ASSIGN) | ||
776 | #endif | ||
777 | |||
778 | #ifdef SICA_IWR1 | ||
779 | PM_SYS_POP(SICA_IWR1) | ||
780 | #endif | ||
781 | #ifdef SICA_IWR0 | ||
782 | PM_SYS_POP(SICA_IWR0) | ||
783 | #endif | ||
784 | #ifdef SIC_IWR2 | ||
785 | PM_SYS_POP(SIC_IWR2) | ||
786 | #endif | ||
787 | #ifdef SIC_IWR1 | ||
788 | PM_SYS_POP(SIC_IWR1) | ||
789 | #endif | ||
790 | #ifdef SIC_IWR0 | ||
791 | PM_SYS_POP(SIC_IWR0) | ||
792 | #endif | ||
793 | #ifdef SIC_IWR | ||
794 | PM_SYS_POP(SIC_IWR) | ||
795 | #endif | ||
796 | |||
797 | #ifdef SICA_IAR0 | ||
798 | PM_SYS_POP(SICA_IAR7) | ||
799 | PM_SYS_POP(SICA_IAR6) | ||
800 | PM_SYS_POP(SICA_IAR5) | ||
801 | PM_SYS_POP(SICA_IAR4) | ||
802 | PM_SYS_POP(SICA_IAR3) | ||
803 | PM_SYS_POP(SICA_IAR2) | ||
804 | PM_SYS_POP(SICA_IAR1) | ||
805 | PM_SYS_POP(SICA_IAR0) | ||
806 | #endif | ||
807 | |||
808 | #ifdef SIC_IAR8 | ||
809 | PM_SYS_POP(SIC_IAR11) | ||
810 | PM_SYS_POP(SIC_IAR10) | ||
811 | PM_SYS_POP(SIC_IAR9) | ||
812 | PM_SYS_POP(SIC_IAR8) | ||
813 | #endif | ||
814 | #ifdef SIC_IAR7 | ||
815 | PM_SYS_POP(SIC_IAR7) | ||
816 | #endif | ||
817 | #ifdef SIC_IAR6 | ||
818 | PM_SYS_POP(SIC_IAR6) | ||
819 | PM_SYS_POP(SIC_IAR5) | ||
820 | PM_SYS_POP(SIC_IAR4) | ||
821 | #endif | ||
822 | #ifdef SIC_IAR3 | ||
823 | PM_SYS_POP(SIC_IAR3) | ||
824 | #endif | ||
825 | #ifdef SIC_IAR2 | ||
826 | PM_SYS_POP(SIC_IAR2) | ||
827 | PM_SYS_POP(SIC_IAR1) | ||
828 | PM_SYS_POP(SIC_IAR0) | ||
829 | #endif | ||
830 | #ifdef SICA_IMASK1 | ||
831 | PM_SYS_POP(SICA_IMASK1) | ||
832 | #endif | ||
833 | #ifdef SICA_IMASK0 | ||
834 | PM_SYS_POP(SICA_IMASK0) | ||
835 | #endif | ||
836 | #ifdef SIC_IMASK | ||
837 | PM_SYS_POP(SIC_IMASK) | ||
838 | #endif | ||
839 | #ifdef SIC_IMASK2 | ||
840 | PM_SYS_POP(SIC_IMASK2) | ||
841 | #endif | ||
842 | #ifdef SIC_IMASK1 | ||
843 | PM_SYS_POP(SIC_IMASK1) | ||
844 | #endif | ||
845 | #ifdef SIC_IMASK0 | ||
846 | PM_SYS_POP(SIC_IMASK0) | ||
847 | #endif | ||
848 | |||
849 | [--sp] = RETI; /* Clear Global Interrupt Disable */ | ||
850 | SP += 4; | ||
851 | |||
852 | RETS = [SP++]; | ||
853 | ( R7:0, P5:0 ) = [SP++]; | ||
854 | RTS; | ||
855 | ENDPROC(_do_hibernate) | ||
diff --git a/arch/blackfin/mach-common/entry.S b/arch/blackfin/mach-common/entry.S index 038f70e0be65..eceb484d90f9 100644 --- a/arch/blackfin/mach-common/entry.S +++ b/arch/blackfin/mach-common/entry.S | |||
@@ -158,23 +158,45 @@ ENTRY(_ex_single_step) | |||
158 | cc = r7 == r6; | 158 | cc = r7 == r6; |
159 | if cc jump _bfin_return_from_exception; | 159 | if cc jump _bfin_return_from_exception; |
160 | 160 | ||
161 | /* Don't do single step in hardware exception handler */ | ||
162 | p5.l = lo(IPEND); | ||
163 | p5.h = hi(IPEND); | ||
164 | r6 = [p5]; | ||
165 | cc = bittst(r6, 5); | ||
166 | if cc jump _bfin_return_from_exception; | ||
167 | |||
168 | #ifdef CONFIG_KGDB | ||
169 | /* skip single step if current interrupt priority is higher than | ||
170 | * that of the first instruction, from which gdb starts single step */ | ||
171 | r6 >>= 6; | ||
172 | r7 = 10; | ||
173 | .Lfind_priority_start: | ||
174 | cc = bittst(r6, 0); | ||
175 | if cc jump .Lfind_priority_done; | ||
176 | r6 >>= 1; | ||
177 | r7 += -1; | ||
178 | cc = r7 == 0; | ||
179 | if cc jump .Lfind_priority_done; | ||
180 | jump.s .Lfind_priority_start; | ||
181 | .Lfind_priority_done: | ||
182 | p4.l = _debugger_step; | ||
183 | p4.h = _debugger_step; | ||
184 | r6 = [p4]; | ||
185 | cc = r6 == 0; | ||
186 | if cc jump .Ldo_single_step; | ||
187 | r6 += -1; | ||
188 | cc = r6 < r7; | ||
189 | if cc jump _bfin_return_from_exception; | ||
190 | .Ldo_single_step: | ||
191 | #endif | ||
192 | |||
161 | /* If we were in user mode, do the single step normally. */ | 193 | /* If we were in user mode, do the single step normally. */ |
162 | p5.l = lo(IPEND); | ||
163 | p5.h = hi(IPEND); | ||
164 | r6 = [p5]; | 194 | r6 = [p5]; |
165 | r7 = 0xffe0 (z); | 195 | r7 = 0xffe0 (z); |
166 | r7 = r7 & r6; | 196 | r7 = r7 & r6; |
167 | cc = r7 == 0; | 197 | cc = r7 == 0; |
168 | if !cc jump 1f; | 198 | if cc jump 1f; |
169 | |||
170 | /* Single stepping only a single instruction, so clear the trace | ||
171 | * bit here. */ | ||
172 | r7 = syscfg; | ||
173 | bitclr (r7, 0); | ||
174 | syscfg = R7; | ||
175 | jump _ex_trap_c; | ||
176 | 199 | ||
177 | 1: | ||
178 | /* | 200 | /* |
179 | * We were in an interrupt handler. By convention, all of them save | 201 | * We were in an interrupt handler. By convention, all of them save |
180 | * SYSCFG with their first instruction, so by checking whether our | 202 | * SYSCFG with their first instruction, so by checking whether our |
@@ -202,11 +224,15 @@ ENTRY(_ex_single_step) | |||
202 | cc = R7 == R6; | 224 | cc = R7 == R6; |
203 | if !cc jump _bfin_return_from_exception; | 225 | if !cc jump _bfin_return_from_exception; |
204 | 226 | ||
227 | 1: | ||
228 | /* Single stepping only a single instruction, so clear the trace | ||
229 | * bit here. */ | ||
205 | r7 = syscfg; | 230 | r7 = syscfg; |
206 | bitclr (r7, 0); | 231 | bitclr (r7, 0); |
207 | syscfg = R7; | 232 | syscfg = R7; |
208 | 233 | ||
209 | /* Fall through to _bfin_return_from_exception. */ | 234 | jump _ex_trap_c; |
235 | |||
210 | ENDPROC(_ex_single_step) | 236 | ENDPROC(_ex_single_step) |
211 | 237 | ||
212 | ENTRY(_bfin_return_from_exception) | 238 | ENTRY(_bfin_return_from_exception) |
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index f5fd768022ea..64d746114e4b 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c | |||
@@ -459,6 +459,8 @@ static struct irq_chip bfin_gpio_irqchip = { | |||
459 | .mask = bfin_gpio_mask_irq, | 459 | .mask = bfin_gpio_mask_irq, |
460 | .mask_ack = bfin_gpio_mask_ack_irq, | 460 | .mask_ack = bfin_gpio_mask_ack_irq, |
461 | .unmask = bfin_gpio_unmask_irq, | 461 | .unmask = bfin_gpio_unmask_irq, |
462 | .disable = bfin_gpio_mask_irq, | ||
463 | .enable = bfin_gpio_unmask_irq, | ||
462 | .set_type = bfin_gpio_irq_type, | 464 | .set_type = bfin_gpio_irq_type, |
463 | .startup = bfin_gpio_irq_startup, | 465 | .startup = bfin_gpio_irq_startup, |
464 | .shutdown = bfin_gpio_irq_shutdown, | 466 | .shutdown = bfin_gpio_irq_shutdown, |
@@ -846,6 +848,8 @@ static struct irq_chip bfin_gpio_irqchip = { | |||
846 | .mask = bfin_gpio_mask_irq, | 848 | .mask = bfin_gpio_mask_irq, |
847 | .mask_ack = bfin_gpio_mask_ack_irq, | 849 | .mask_ack = bfin_gpio_mask_ack_irq, |
848 | .unmask = bfin_gpio_unmask_irq, | 850 | .unmask = bfin_gpio_unmask_irq, |
851 | .disable = bfin_gpio_mask_irq, | ||
852 | .enable = bfin_gpio_unmask_irq, | ||
849 | .set_type = bfin_gpio_irq_type, | 853 | .set_type = bfin_gpio_irq_type, |
850 | .startup = bfin_gpio_irq_startup, | 854 | .startup = bfin_gpio_irq_startup, |
851 | .shutdown = bfin_gpio_irq_shutdown, | 855 | .shutdown = bfin_gpio_irq_shutdown, |
diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index 0be805ca423f..4fe6a2366b13 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c | |||
@@ -38,8 +38,9 @@ | |||
38 | #include <linux/io.h> | 38 | #include <linux/io.h> |
39 | #include <linux/irq.h> | 39 | #include <linux/irq.h> |
40 | 40 | ||
41 | #include <asm/dpmc.h> | ||
42 | #include <asm/gpio.h> | 41 | #include <asm/gpio.h> |
42 | #include <asm/dma.h> | ||
43 | #include <asm/dpmc.h> | ||
43 | 44 | ||
44 | #ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_H | 45 | #ifdef CONFIG_PM_WAKEUP_GPIO_POLAR_H |
45 | #define WAKEUP_TYPE PM_WAKE_HIGH | 46 | #define WAKEUP_TYPE PM_WAKE_HIGH |
@@ -61,16 +62,17 @@ | |||
61 | #define WAKEUP_TYPE PM_WAKE_BOTH_EDGES | 62 | #define WAKEUP_TYPE PM_WAKE_BOTH_EDGES |
62 | #endif | 63 | #endif |
63 | 64 | ||
65 | |||
64 | void bfin_pm_suspend_standby_enter(void) | 66 | void bfin_pm_suspend_standby_enter(void) |
65 | { | 67 | { |
68 | unsigned long flags; | ||
69 | |||
66 | #ifdef CONFIG_PM_WAKEUP_BY_GPIO | 70 | #ifdef CONFIG_PM_WAKEUP_BY_GPIO |
67 | gpio_pm_wakeup_request(CONFIG_PM_WAKEUP_GPIO_NUMBER, WAKEUP_TYPE); | 71 | gpio_pm_wakeup_request(CONFIG_PM_WAKEUP_GPIO_NUMBER, WAKEUP_TYPE); |
68 | #endif | 72 | #endif |
69 | 73 | ||
70 | u32 flags; | ||
71 | |||
72 | local_irq_save(flags); | 74 | local_irq_save(flags); |
73 | bfin_pm_setup(); | 75 | bfin_pm_standby_setup(); |
74 | 76 | ||
75 | #ifdef CONFIG_PM_BFIN_SLEEP_DEEPER | 77 | #ifdef CONFIG_PM_BFIN_SLEEP_DEEPER |
76 | sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); | 78 | sleep_deeper(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); |
@@ -78,7 +80,7 @@ void bfin_pm_suspend_standby_enter(void) | |||
78 | sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); | 80 | sleep_mode(bfin_sic_iwr[0], bfin_sic_iwr[1], bfin_sic_iwr[2]); |
79 | #endif | 81 | #endif |
80 | 82 | ||
81 | bfin_pm_restore(); | 83 | bfin_pm_standby_restore(); |
82 | 84 | ||
83 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) | 85 | #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561) |
84 | bfin_write_SIC_IWR0(IWR_ENABLE_ALL); | 86 | bfin_write_SIC_IWR0(IWR_ENABLE_ALL); |
@@ -93,6 +95,195 @@ void bfin_pm_suspend_standby_enter(void) | |||
93 | local_irq_restore(flags); | 95 | local_irq_restore(flags); |
94 | } | 96 | } |
95 | 97 | ||
98 | int bf53x_suspend_l1_mem(unsigned char *memptr) | ||
99 | { | ||
100 | dma_memcpy(memptr, (const void *) L1_CODE_START, L1_CODE_LENGTH); | ||
101 | dma_memcpy(memptr + L1_CODE_LENGTH, (const void *) L1_DATA_A_START, | ||
102 | L1_DATA_A_LENGTH); | ||
103 | dma_memcpy(memptr + L1_CODE_LENGTH + L1_DATA_A_LENGTH, | ||
104 | (const void *) L1_DATA_B_START, L1_DATA_B_LENGTH); | ||
105 | memcpy(memptr + L1_CODE_LENGTH + L1_DATA_A_LENGTH + | ||
106 | L1_DATA_B_LENGTH, (const void *) L1_SCRATCH_START, | ||
107 | L1_SCRATCH_LENGTH); | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | int bf53x_resume_l1_mem(unsigned char *memptr) | ||
113 | { | ||
114 | dma_memcpy((void *) L1_CODE_START, memptr, L1_CODE_LENGTH); | ||
115 | dma_memcpy((void *) L1_DATA_A_START, memptr + L1_CODE_LENGTH, | ||
116 | L1_DATA_A_LENGTH); | ||
117 | dma_memcpy((void *) L1_DATA_B_START, memptr + L1_CODE_LENGTH + | ||
118 | L1_DATA_A_LENGTH, L1_DATA_B_LENGTH); | ||
119 | memcpy((void *) L1_SCRATCH_START, memptr + L1_CODE_LENGTH + | ||
120 | L1_DATA_A_LENGTH + L1_DATA_B_LENGTH, L1_SCRATCH_LENGTH); | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | #ifdef CONFIG_BFIN_WB | ||
126 | static void flushinv_all_dcache(void) | ||
127 | { | ||
128 | u32 way, bank, subbank, set; | ||
129 | u32 status, addr; | ||
130 | u32 dmem_ctl = bfin_read_DMEM_CONTROL(); | ||
131 | |||
132 | for (bank = 0; bank < 2; ++bank) { | ||
133 | if (!(dmem_ctl & (1 << (DMC1_P - bank)))) | ||
134 | continue; | ||
135 | |||
136 | for (way = 0; way < 2; ++way) | ||
137 | for (subbank = 0; subbank < 4; ++subbank) | ||
138 | for (set = 0; set < 64; ++set) { | ||
139 | |||
140 | bfin_write_DTEST_COMMAND( | ||
141 | way << 26 | | ||
142 | bank << 23 | | ||
143 | subbank << 16 | | ||
144 | set << 5 | ||
145 | ); | ||
146 | CSYNC(); | ||
147 | status = bfin_read_DTEST_DATA0(); | ||
148 | |||
149 | /* only worry about valid/dirty entries */ | ||
150 | if ((status & 0x3) != 0x3) | ||
151 | continue; | ||
152 | |||
153 | /* construct the address using the tag */ | ||
154 | addr = (status & 0xFFFFC800) | (subbank << 12) | (set << 5); | ||
155 | |||
156 | /* flush it */ | ||
157 | __asm__ __volatile__("FLUSHINV[%0];" : : "a"(addr)); | ||
158 | } | ||
159 | } | ||
160 | } | ||
161 | #endif | ||
162 | |||
163 | static inline void dcache_disable(void) | ||
164 | { | ||
165 | #ifdef CONFIG_BFIN_DCACHE | ||
166 | unsigned long ctrl; | ||
167 | |||
168 | #ifdef CONFIG_BFIN_WB | ||
169 | flushinv_all_dcache(); | ||
170 | #endif | ||
171 | SSYNC(); | ||
172 | ctrl = bfin_read_DMEM_CONTROL(); | ||
173 | ctrl &= ~ENDCPLB; | ||
174 | bfin_write_DMEM_CONTROL(ctrl); | ||
175 | SSYNC(); | ||
176 | #endif | ||
177 | } | ||
178 | |||
179 | static inline void dcache_enable(void) | ||
180 | { | ||
181 | #ifdef CONFIG_BFIN_DCACHE | ||
182 | unsigned long ctrl; | ||
183 | SSYNC(); | ||
184 | ctrl = bfin_read_DMEM_CONTROL(); | ||
185 | ctrl |= ENDCPLB; | ||
186 | bfin_write_DMEM_CONTROL(ctrl); | ||
187 | SSYNC(); | ||
188 | #endif | ||
189 | } | ||
190 | |||
191 | static inline void icache_disable(void) | ||
192 | { | ||
193 | #ifdef CONFIG_BFIN_ICACHE | ||
194 | unsigned long ctrl; | ||
195 | SSYNC(); | ||
196 | ctrl = bfin_read_IMEM_CONTROL(); | ||
197 | ctrl &= ~ENICPLB; | ||
198 | bfin_write_IMEM_CONTROL(ctrl); | ||
199 | SSYNC(); | ||
200 | #endif | ||
201 | } | ||
202 | |||
203 | static inline void icache_enable(void) | ||
204 | { | ||
205 | #ifdef CONFIG_BFIN_ICACHE | ||
206 | unsigned long ctrl; | ||
207 | SSYNC(); | ||
208 | ctrl = bfin_read_IMEM_CONTROL(); | ||
209 | ctrl |= ENICPLB; | ||
210 | bfin_write_IMEM_CONTROL(ctrl); | ||
211 | SSYNC(); | ||
212 | #endif | ||
213 | } | ||
214 | |||
215 | int bfin_pm_suspend_mem_enter(void) | ||
216 | { | ||
217 | unsigned long flags; | ||
218 | int wakeup, ret; | ||
219 | |||
220 | unsigned char *memptr = kmalloc(L1_CODE_LENGTH + L1_DATA_A_LENGTH | ||
221 | + L1_DATA_B_LENGTH + L1_SCRATCH_LENGTH, | ||
222 | GFP_KERNEL); | ||
223 | |||
224 | if (memptr == NULL) { | ||
225 | panic("bf53x_suspend_l1_mem malloc failed"); | ||
226 | return -ENOMEM; | ||
227 | } | ||
228 | |||
229 | wakeup = bfin_read_VR_CTL() & ~FREQ; | ||
230 | wakeup |= SCKELOW; | ||
231 | |||
232 | /* FIXME: merge this somehow with set_irq_wake */ | ||
233 | #ifdef CONFIG_PM_BFIN_WAKE_RTC | ||
234 | wakeup |= WAKE; | ||
235 | #endif | ||
236 | #ifdef CONFIG_PM_BFIN_WAKE_PH6 | ||
237 | wakeup |= PHYWE; | ||
238 | #endif | ||
239 | #ifdef CONFIG_PM_BFIN_WAKE_CAN | ||
240 | wakeup |= CANWE; | ||
241 | #endif | ||
242 | #ifdef CONFIG_PM_BFIN_WAKE_GP | ||
243 | wakeup |= GPWE; | ||
244 | #endif | ||
245 | #ifdef CONFIG_PM_BFIN_WAKE_USB | ||
246 | wakeup |= USBWE; | ||
247 | #endif | ||
248 | #ifdef CONFIG_PM_BFIN_WAKE_KEYPAD | ||
249 | wakeup |= KPADWE; | ||
250 | #endif | ||
251 | #ifdef CONFIG_PM_BFIN_WAKE_ROTARY | ||
252 | wakeup |= ROTWE; | ||
253 | #endif | ||
254 | |||
255 | local_irq_save(flags); | ||
256 | |||
257 | ret = blackfin_dma_suspend(); | ||
258 | |||
259 | if (ret) { | ||
260 | local_irq_restore(flags); | ||
261 | kfree(memptr); | ||
262 | return ret; | ||
263 | } | ||
264 | |||
265 | bfin_gpio_pm_hibernate_suspend(); | ||
266 | |||
267 | dcache_disable(); | ||
268 | icache_disable(); | ||
269 | bf53x_suspend_l1_mem(memptr); | ||
270 | |||
271 | do_hibernate(wakeup); /* Goodbye */ | ||
272 | |||
273 | bf53x_resume_l1_mem(memptr); | ||
274 | |||
275 | icache_enable(); | ||
276 | dcache_enable(); | ||
277 | |||
278 | bfin_gpio_pm_hibernate_restore(); | ||
279 | blackfin_dma_resume(); | ||
280 | |||
281 | local_irq_restore(flags); | ||
282 | kfree(memptr); | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
96 | /* | 287 | /* |
97 | * bfin_pm_valid - Tell the PM core that we only support the standby sleep | 288 | * bfin_pm_valid - Tell the PM core that we only support the standby sleep |
98 | * state | 289 | * state |
@@ -101,7 +292,24 @@ void bfin_pm_suspend_standby_enter(void) | |||
101 | */ | 292 | */ |
102 | static int bfin_pm_valid(suspend_state_t state) | 293 | static int bfin_pm_valid(suspend_state_t state) |
103 | { | 294 | { |
104 | return (state == PM_SUSPEND_STANDBY); | 295 | return (state == PM_SUSPEND_STANDBY |
296 | #ifndef BF533_FAMILY | ||
297 | /* | ||
298 | * On BF533/2/1: | ||
299 | * If we enter Hibernate the SCKE Pin is driven Low, | ||
300 | * so that the SDRAM enters Self Refresh Mode. | ||
301 | * However when the reset sequence that follows hibernate | ||
302 | * state is executed, SCKE is driven High, taking the | ||
303 | * SDRAM out of Self Refresh. | ||
304 | * | ||
305 | * If you reconfigure and access the SDRAM "very quickly", | ||
306 | * you are likely to avoid errors, otherwise the SDRAM | ||
307 | * start losing its contents. | ||
308 | * An external HW workaround is possible using logic gates. | ||
309 | */ | ||
310 | || state == PM_SUSPEND_MEM | ||
311 | #endif | ||
312 | ); | ||
105 | } | 313 | } |
106 | 314 | ||
107 | /* | 315 | /* |
@@ -115,10 +323,9 @@ static int bfin_pm_enter(suspend_state_t state) | |||
115 | case PM_SUSPEND_STANDBY: | 323 | case PM_SUSPEND_STANDBY: |
116 | bfin_pm_suspend_standby_enter(); | 324 | bfin_pm_suspend_standby_enter(); |
117 | break; | 325 | break; |
118 | |||
119 | case PM_SUSPEND_MEM: | 326 | case PM_SUSPEND_MEM: |
120 | return -ENOTSUPP; | 327 | bfin_pm_suspend_mem_enter(); |
121 | 328 | break; | |
122 | default: | 329 | default: |
123 | return -EINVAL; | 330 | return -EINVAL; |
124 | } | 331 | } |