sleep.S 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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. */
  28. ENTRY(sa1100_finish_suspend)
  29. @ disable clock switching
  30. mcr p15, 0, r1, c15, c2, 2
  31. @ Adjust memory timing before lowering CPU clock
  32. @ Clock speed adjustment without changing memory timing makes
  33. @ CPU hang in some cases
  34. ldr r0, =MDREFR
  35. ldr r1, [r0]
  36. orr r1, r1, #MDREFR_K1DB2
  37. str r1, [r0]
  38. @ delay 90us and set CPU PLL to lowest speed
  39. @ fixes resume problem on high speed SA1110
  40. mov r0, #90
  41. bl __udelay
  42. ldr r0, =PPCR
  43. mov r1, #0
  44. str r1, [r0]
  45. mov r0, #90
  46. bl __udelay
  47. /*
  48. * SA1110 SDRAM controller workaround. register values:
  49. *
  50. * r0 = &MSC0
  51. * r1 = &MSC1
  52. * r2 = &MSC2
  53. * r3 = MSC0 value
  54. * r4 = MSC1 value
  55. * r5 = MSC2 value
  56. * r6 = &MDREFR
  57. * r7 = first MDREFR value
  58. * r8 = second MDREFR value
  59. * r9 = &MDCNFG
  60. * r10 = MDCNFG value
  61. * r11 = third MDREFR value
  62. * r12 = &PMCR
  63. * r13 = PMCR value (1)
  64. */
  65. ldr r0, =MSC0
  66. ldr r1, =MSC1
  67. ldr r2, =MSC2
  68. ldr r3, [r0]
  69. bic r3, r3, #FMsk(MSC_RT)
  70. bic r3, r3, #FMsk(MSC_RT)<<16
  71. ldr r4, [r1]
  72. bic r4, r4, #FMsk(MSC_RT)
  73. bic r4, r4, #FMsk(MSC_RT)<<16
  74. ldr r5, [r2]
  75. bic r5, r5, #FMsk(MSC_RT)
  76. bic r5, r5, #FMsk(MSC_RT)<<16
  77. ldr r6, =MDREFR
  78. ldr r7, [r6]
  79. bic r7, r7, #0x0000FF00
  80. bic r7, r7, #0x000000F0
  81. orr r8, r7, #MDREFR_SLFRSH
  82. ldr r9, =MDCNFG
  83. ldr r10, [r9]
  84. bic r10, r10, #(MDCNFG_DE0+MDCNFG_DE1)
  85. bic r10, r10, #(MDCNFG_DE2+MDCNFG_DE3)
  86. bic r11, r8, #MDREFR_SLFRSH
  87. bic r11, r11, #MDREFR_E1PIN
  88. ldr r12, =PMCR
  89. mov r13, #PMCR_SF
  90. b sa1110_sdram_controller_fix
  91. .align 5
  92. sa1110_sdram_controller_fix:
  93. @ Step 1 clear RT field of all MSCx registers
  94. str r3, [r0]
  95. str r4, [r1]
  96. str r5, [r2]
  97. @ Step 2 clear DRI field in MDREFR
  98. str r7, [r6]
  99. @ Step 3 set SLFRSH bit in MDREFR
  100. str r8, [r6]
  101. @ Step 4 clear DE bis in MDCNFG
  102. str r10, [r9]
  103. @ Step 5 clear DRAM refresh control register
  104. str r11, [r6]
  105. @ Wow, now the hardware suspend request pins can be used, that makes them functional for
  106. @ about 7 ns out of the entire time that the CPU is running!
  107. @ Step 6 set force sleep bit in PMCR
  108. str r13, [r12]
  109. 20: b 20b @ loop waiting for sleep