sleep.S 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. * (C) Copyright 2010, Amlogic, Inc. http://www.amlogic.com/
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  16. * MA 02111-1307 USA
  17. */
  18. #include <linux/linkage.h>
  19. #include <asm/assembler.h>
  20. #include <mach/memory.h>
  21. #ifdef CONFIG_ARCH_MESON6
  22. #include <mach/io.h>
  23. #include <mach/sleep.h>
  24. #include <mach/pctl.h>
  25. #include <mach/dmc.h>
  26. #else
  27. #include <mach/pctl.h>
  28. #include <mach/dmc.h>
  29. #include <mach/sleep.h>
  30. #endif
  31. #define HIU_GCLK_MPEG (0x50<<2)
  32. #define HHI_MPEG_CLK_CNTL (0x5d<<2)
  33. #define HIU_DDR_PLL_CTRL (0x68<<2)
  34. #define A9_AUTO_CLK0 (0x78<<2)
  35. #define HIU_DDR_RESET (0x102<<2)
  36. #define LED_PWM_REG0 (0x11da<<2)
  37. .text
  38. /*
  39. * Move Meson into deep sleep state
  40. *
  41. * Note: This code is copied to internal SRAM by PM code. When the Meson
  42. * wakes up it continues execution at the point it went to sleep.
  43. */
  44. ENTRY(meson_cpu_suspend)
  45. stmfd sp!, {r0-r12, lr} @ save registers on stack
  46. ldmia r0, {r0-r6}
  47. /*
  48. r0: pctl_reg_base;
  49. r1: mmc_reg_base;
  50. r2: hiu_reg_base;
  51. r3: power_key;
  52. r4: ddr_clk;
  53. r5: ddr_reg_backup;
  54. r6: core_voltage_adjust;
  55. */
  56. /* r9: led_pwm_reg0, r10: value of led_pwm_reg0*/
  57. mov r9, #0
  58. movw r9, #LED_PWM_REG0
  59. add r9, r9, r2
  60. ldr r10, [r9]
  61. /* turn on auto byte bypass */
  62. ldr r8, [r0, #PCTL_IOCR_ADDR]
  63. orr r8, r8, #(1<<25)
  64. str r8, [r0, #PCTL_IOCR_ADDR]
  65. /*
  66. * Switch DDR to self-refresh mode.
  67. */
  68. mov r8, #0x3
  69. str r8, [r0, #PCTL_SCTL_ADDR]
  70. mov r8, #MS_DLY
  71. 0: subs r8, r8, #0x1
  72. bne 0b
  73. /* DDR PHY power saving*/
  74. ldr r8, [r1, #MMC_PHY_CTRL-0x1000]
  75. orr r8, r8, #(1<<0)
  76. orr r8, r8, #(1<<8)
  77. orr r8, r8, #(1<<13)
  78. str r8, [r1, #MMC_PHY_CTRL-0x1000]
  79. /* hold dll reset */
  80. ldr r8, [r0, #PCTL_PHYCR_ADDR]
  81. bic r8, r8, #(1<<6)
  82. str r8, [r0, #PCTL_PHYCR_ADDR]
  83. /* enable dll bypass */
  84. ldr r8, [r0, #PCTL_DLLCR9_ADDR]
  85. orr r8, r8, #(1<<31)
  86. str r8, [r0, #PCTL_DLLCR9_ADDR]
  87. #ifdef TURN_OFF_DDR_PLL
  88. /* turn off ddr pll */
  89. ldr r8, [r2, #HIU_DDR_PLL_CTRL]
  90. orr r8, r8, #(1<<15)
  91. str r8, [r2, #HIU_DDR_PLL_CTRL]
  92. #else
  93. /* lower ddr pll */
  94. // ldr r7, [r2, #HIU_DDR_PLL_CTRL]
  95. // str r4, [r2, #HIU_DDR_PLL_CTRL]
  96. #endif
  97. /* ddr power gate */
  98. // ldr r8, [r2, #HIU_GCLK_MPEG]
  99. // bic r8, r8, #0x41
  100. // str r8, [r2, #HIU_GCLK_MPEG]
  101. /* lower core voltage */
  102. // bic r8, r10, #0x0f
  103. // orr r8, r8, r6
  104. // str r8, [r9]
  105. /* System goes to sleep beyond after this instruction */
  106. // ldr r8, [r2, #A9_AUTO_CLK0]
  107. // orr r8, r8, #(1<<1)
  108. // str r8, [r2, #A9_AUTO_CLK0]
  109. // bic r8, r8, #(1<<1)
  110. // str r8, [r2, #A9_AUTO_CLK0]
  111. wfi
  112. // ldr r8, [r2, #A9_AUTO_CLK0]
  113. // bic r8, r8, #(1<<0)
  114. // str r8, [r2, #A9_AUTO_CLK0]
  115. /* Wake up from sleep */
  116. /* restore core voltage */
  117. // str r10, [r9]
  118. // mov r8, #VOLTAGE_DLY
  119. //2: subs r8, r8, #0x1
  120. // bne 2b
  121. /* ddr power gate */
  122. // ldr r8, [r2, #HIU_GCLK_MPEG]
  123. // orr r8, r8, #0x41
  124. // str r8, [r2, #HIU_GCLK_MPEG]
  125. #ifdef TURN_OFF_DDR_PLL
  126. /* turn on ddr pll */
  127. ldr r8, [r2, #HIU_DDR_PLL_CTRL]
  128. bic r8, r8, #(1<<15)
  129. str r8, [r2, #HIU_DDR_PLL_CTRL]
  130. #else
  131. /* restore ddr pll */
  132. // str r7, [r2, #HIU_DDR_PLL_CTRL]
  133. #endif
  134. /* Wait for PLL to lock */
  135. mov r8, #MS_DLY
  136. 3: subs r8, r8, #0x1
  137. bne 3b
  138. /* disable dll bypass */
  139. ldr r8, [r0, #PCTL_DLLCR9_ADDR]
  140. bic r8, r8, #(1<<31)
  141. str r8, [r0, #PCTL_DLLCR9_ADDR]
  142. /* release reset */
  143. ldr r8, [r0, #PCTL_PHYCR_ADDR]
  144. orr r8, r8, #(1<<6)
  145. str r8, [r0, #PCTL_PHYCR_ADDR]
  146. /* DDR PHY leave power saving mode*/
  147. ldr r8, [r1, #MMC_PHY_CTRL-0x1000]
  148. bic r8, r8, #(1<<8)
  149. str r8, [r1, #MMC_PHY_CTRL-0x1000]
  150. /* ddr back to normal mode */
  151. mov r8, #0x4
  152. str r8, [r0, #PCTL_SCTL_ADDR]
  153. mov r8, #MS_DLY
  154. 9: subs r8, r8, #0x1
  155. bne 9b
  156. /* Restore registers and return */
  157. ldmfd sp!, {r0-r12, pc}
  158. ENDPROC(meson_cpu_suspend)
  159. ENTRY(meson_cpu_suspend_sz)
  160. .word . - meson_cpu_suspend
  161. ENDPROC(meson_cpu_suspend_sz)