mpc52xx_sleep.S 2.6 KB

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