sleep.S 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  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_finish_suspend()
  24. *
  25. * Causes sa11x0 to enter sleep state
  26. *
  27. * Must be aligned to a cacheline.
  28. */
  29. .balign 32
  30. ENTRY(sa1100_finish_suspend)
  31. @ disable clock switching
  32. mcr p15, 0, r1, c15, c2, 2
  33. ldr r6, =MDREFR
  34. ldr r4, [r6]
  35. orr r4, r4, #MDREFR_K1DB2
  36. ldr r5, =PPCR
  37. @ Pre-load __loop_udelay into the I-cache
  38. mov r0, #1
  39. bl __loop_udelay
  40. mov r0, r0
  41. @ The following must all exist in a single cache line to
  42. @ avoid accessing memory until this sequence is complete,
  43. @ otherwise we occasionally hang.
  44. @ Adjust memory timing before lowering CPU clock
  45. str r4, [r6]
  46. @ delay 90us and set CPU PLL to lowest speed
  47. @ fixes resume problem on high speed SA1110
  48. mov r0, #90
  49. bl __loop_udelay
  50. mov r1, #0
  51. str r1, [r5]
  52. mov r0, #90
  53. bl __loop_udelay
  54. /*
  55. * SA1110 SDRAM controller workaround. register values:
  56. *
  57. * r0 = &MSC0
  58. * r1 = &MSC1
  59. * r2 = &MSC2
  60. * r3 = MSC0 value
  61. * r4 = MSC1 value
  62. * r5 = MSC2 value
  63. * r6 = &MDREFR
  64. * r7 = first MDREFR value
  65. * r8 = second MDREFR value
  66. * r9 = &MDCNFG
  67. * r10 = MDCNFG value
  68. * r11 = third MDREFR value
  69. * r12 = &PMCR
  70. * r13 = PMCR value (1)
  71. */
  72. ldr r0, =MSC0
  73. ldr r1, =MSC1
  74. ldr r2, =MSC2
  75. ldr r3, [r0]
  76. bic r3, r3, #FMsk(MSC_RT)
  77. bic r3, r3, #FMsk(MSC_RT)<<16
  78. ldr r4, [r1]
  79. bic r4, r4, #FMsk(MSC_RT)
  80. bic r4, r4, #FMsk(MSC_RT)<<16
  81. ldr r5, [r2]
  82. bic r5, r5, #FMsk(MSC_RT)
  83. bic r5, r5, #FMsk(MSC_RT)<<16
  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