sleep.S 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /*
  2. * SA11x0 Assembler Sleep/WakeUp Management Routines
  3. *
  4. * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License.
  8. *
  9. * History:
  10. *
  11. * 2001-02-06: Cliff Brake Initial code
  12. *
  13. * 2001-08-29: Nicolas Pitre Simplified.
  14. *
  15. * 2002-05-27: Nicolas Pitre Revisited, more cleanup and simplification.
  16. * Storage is on the stack now.
  17. */
  18. #include <linux/linkage.h>
  19. #include <asm/assembler.h>
  20. #include <mach/hardware.h>
  21. .text
  22. /*
  23. * sa1100_cpu_suspend()
  24. *
  25. * Causes sa11x0 to enter sleep state
  26. *
  27. */
  28. ENTRY(sa1100_cpu_suspend)
  29. stmfd sp!, {r4 - r12, lr} @ save registers on stack
  30. mov r1, r0
  31. adr r3, BSYM(sa1100_finish_suspend)
  32. bl cpu_suspend
  33. ldmfd sp!, {r4 - r12, pc} @ return to caller
  34. sa1100_finish_suspend:
  35. @ disable clock switching
  36. mcr p15, 0, r1, c15, c2, 2
  37. @ Adjust memory timing before lowering CPU clock
  38. @ Clock speed adjustment without changing memory timing makes
  39. @ CPU hang in some cases
  40. ldr r0, =MDREFR
  41. ldr r1, [r0]
  42. orr r1, r1, #MDREFR_K1DB2
  43. str r1, [r0]
  44. @ delay 90us and set CPU PLL to lowest speed
  45. @ fixes resume problem on high speed SA1110
  46. mov r0, #90
  47. bl __udelay
  48. ldr r0, =PPCR
  49. mov r1, #0
  50. str r1, [r0]
  51. mov r0, #90
  52. bl __udelay
  53. /*
  54. * SA1110 SDRAM controller workaround. register values:
  55. *
  56. * r0 = &MSC0
  57. * r1 = &MSC1
  58. * r2 = &MSC2
  59. * r3 = MSC0 value
  60. * r4 = MSC1 value
  61. * r5 = MSC2 value
  62. * r6 = &MDREFR
  63. * r7 = first MDREFR value
  64. * r8 = second MDREFR value
  65. * r9 = &MDCNFG
  66. * r10 = MDCNFG value
  67. * r11 = third MDREFR value
  68. * r12 = &PMCR
  69. * r13 = PMCR value (1)
  70. */
  71. ldr r0, =MSC0
  72. ldr r1, =MSC1
  73. ldr r2, =MSC2
  74. ldr r3, [r0]
  75. bic r3, r3, #FMsk(MSC_RT)
  76. bic r3, r3, #FMsk(MSC_RT)<<16
  77. ldr r4, [r1]
  78. bic r4, r4, #FMsk(MSC_RT)
  79. bic r4, r4, #FMsk(MSC_RT)<<16
  80. ldr r5, [r2]
  81. bic r5, r5, #FMsk(MSC_RT)
  82. bic r5, r5, #FMsk(MSC_RT)<<16
  83. ldr r6, =MDREFR
  84. ldr r7, [r6]
  85. bic r7, r7, #0x0000FF00
  86. bic r7, r7, #0x000000F0
  87. orr r8, r7, #MDREFR_SLFRSH
  88. ldr r9, =MDCNFG
  89. ldr r10, [r9]
  90. bic r10, r10, #(MDCNFG_DE0+MDCNFG_DE1)
  91. bic r10, r10, #(MDCNFG_DE2+MDCNFG_DE3)
  92. bic r11, r8, #MDREFR_SLFRSH
  93. bic r11, r11, #MDREFR_E1PIN
  94. ldr r12, =PMCR
  95. mov r13, #PMCR_SF
  96. b sa1110_sdram_controller_fix
  97. .align 5
  98. sa1110_sdram_controller_fix:
  99. @ Step 1 clear RT field of all MSCx registers
  100. str r3, [r0]
  101. str r4, [r1]
  102. str r5, [r2]
  103. @ Step 2 clear DRI field in MDREFR
  104. str r7, [r6]
  105. @ Step 3 set SLFRSH bit in MDREFR
  106. str r8, [r6]
  107. @ Step 4 clear DE bis in MDCNFG
  108. str r10, [r9]
  109. @ Step 5 clear DRAM refresh control register
  110. str r11, [r6]
  111. @ Wow, now the hardware suspend request pins can be used, that makes them functional for
  112. @ about 7 ns out of the entire time that the CPU is running!
  113. @ Step 6 set force sleep bit in PMCR
  114. str r13, [r12]
  115. 20: b 20b @ loop waiting for sleep