mpc52xx_sleep.S 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #include <asm/reg.h>
  2. #include <asm/ppc_asm.h>
  3. #include <asm/processor.h>
  4. .text
  5. _GLOBAL(mpc52xx_deep_sleep)
  6. mpc52xx_deep_sleep: /* args r3-r6: SRAM, SDRAM regs, CDM regs, INTR regs */
  7. /* enable interrupts */
  8. mfmsr r7
  9. ori r7, r7, 0x8000 /* EE */
  10. mtmsr r7
  11. sync; isync;
  12. li r10, 0 /* flag that irq handler sets */
  13. /* enable tmr7 (or any other) interrupt */
  14. lwz r8, 0x14(r6) /* intr->main_mask */
  15. ori r8, r8, 0x1
  16. xori r8, r8, 0x1
  17. stw r8, 0x14(r6)
  18. sync
  19. /* emulate tmr7 interrupt */
  20. li r8, 0x1
  21. stw r8, 0x40(r6) /* intr->main_emulate */
  22. sync
  23. /* wait for it to happen */
  24. 1:
  25. cmpi cr0, r10, 1
  26. bne cr0, 1b
  27. /* lock icache */
  28. mfspr r10, SPRN_HID0
  29. ori r10, r10, 0x2000
  30. sync; isync;
  31. mtspr SPRN_HID0, r10
  32. sync; isync;
  33. mflr r9 /* save LR */
  34. /* jump to sram */
  35. mtlr r3
  36. blrl
  37. mtlr r9 /* restore LR */
  38. /* unlock icache */
  39. mfspr r10, SPRN_HID0
  40. ori r10, r10, 0x2000
  41. xori r10, r10, 0x2000
  42. sync; isync;
  43. mtspr SPRN_HID0, r10
  44. sync; isync;
  45. /* return to C code */
  46. blr
  47. _GLOBAL(mpc52xx_ds_sram)
  48. mpc52xx_ds_sram:
  49. /* put SDRAM into self-refresh */
  50. lwz r8, 0x4(r4) /* sdram->ctrl */
  51. oris r8, r8, 0x8000 /* mode_en */
  52. stw r8, 0x4(r4)
  53. sync
  54. ori r8, r8, 0x0002 /* soft_pre */
  55. stw r8, 0x4(r4)
  56. sync
  57. xori r8, r8, 0x0002
  58. xoris r8, r8, 0x8000 /* !mode_en */
  59. stw r8, 0x4(r4)
  60. sync
  61. oris r8, r8, 0x5000
  62. xoris r8, r8, 0x4000 /* ref_en !cke */
  63. stw r8, 0x4(r4)
  64. sync
  65. /* disable SDRAM clock */
  66. lwz r8, 0x14(r5) /* cdm->clkenable */
  67. ori r8, r8, 0x0008
  68. xori r8, r8, 0x0008
  69. stw r8, 0x14(r5)
  70. sync
  71. /* put mpc5200 to sleep */
  72. mfmsr r10
  73. oris r10, r10, 0x0004 /* POW = 1 */
  74. sync; isync;
  75. mtmsr r10
  76. sync; isync;
  77. /* enable clock */
  78. lwz r8, 0x14(r5)
  79. ori r8, r8, 0x0008
  80. stw r8, 0x14(r5)
  81. sync
  82. /* get ram out of self-refresh */
  83. lwz r8, 0x4(r4)
  84. oris r8, r8, 0x5000 /* cke ref_en */
  85. stw r8, 0x4(r4)
  86. sync
  87. blr
  88. _GLOBAL(mpc52xx_ds_sram_size)
  89. mpc52xx_ds_sram_size:
  90. .long $-mpc52xx_ds_sram
  91. /* ### interrupt handler for wakeup from deep-sleep ### */
  92. _GLOBAL(mpc52xx_ds_cached)
  93. mpc52xx_ds_cached:
  94. mtspr SPRN_SPRG0, r7
  95. mtspr SPRN_SPRG1, r8
  96. /* disable emulated interrupt */
  97. mfspr r7, 311 /* MBAR */
  98. addi r7, r7, 0x540 /* intr->main_emul */
  99. li r8, 0
  100. stw r8, 0(r7)
  101. sync
  102. dcbf 0, r7
  103. /* acknowledge wakeup, so CCS releases power pown */
  104. mfspr r7, 311 /* MBAR */
  105. addi r7, r7, 0x524 /* intr->enc_status */
  106. lwz r8, 0(r7)
  107. ori r8, r8, 0x0400
  108. stw r8, 0(r7)
  109. sync
  110. dcbf 0, r7
  111. /* flag - we handled the interrupt */
  112. li r10, 1
  113. mfspr r8, SPRN_SPRG1
  114. mfspr r7, SPRN_SPRG0
  115. rfi
  116. _GLOBAL(mpc52xx_ds_cached_size)
  117. mpc52xx_ds_cached_size:
  118. .long $-mpc52xx_ds_cached