Commit | Line | Data |
---|---|---|
1da177e4 LT |
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 | ||
19 | #include <linux/linkage.h> | |
20 | #include <asm/assembler.h> | |
a09e64fb | 21 | #include <mach/hardware.h> |
1da177e4 | 22 | |
1da177e4 | 23 | .text |
1da177e4 | 24 | /* |
34c79de6 | 25 | * sa1100_finish_suspend() |
1da177e4 LT |
26 | * |
27 | * Causes sa11x0 to enter sleep state | |
28 | * | |
f3bb3d74 | 29 | * Must be aligned to a cacheline. |
1da177e4 | 30 | */ |
f3bb3d74 | 31 | .balign 32 |
34c79de6 | 32 | ENTRY(sa1100_finish_suspend) |
1da177e4 LT |
33 | @ disable clock switching |
34 | mcr p15, 0, r1, c15, c2, 2 | |
35 | ||
f3bb3d74 RK |
36 | ldr r6, =MDREFR |
37 | ldr r4, [r6] | |
38 | orr r4, r4, #MDREFR_K1DB2 | |
39 | ldr r5, =PPCR | |
40 | ||
d0a533b1 | 41 | @ Pre-load __loop_udelay into the I-cache |
f3bb3d74 | 42 | mov r0, #1 |
d0a533b1 | 43 | bl __loop_udelay |
f3bb3d74 RK |
44 | mov r0, r0 |
45 | ||
46 | @ The following must all exist in a single cache line to | |
47 | @ avoid accessing memory until this sequence is complete, | |
48 | @ otherwise we occasionally hang. | |
49 | ||
50 | @ Adjust memory timing before lowering CPU clock | |
51 | str r4, [r6] | |
1da177e4 LT |
52 | |
53 | @ delay 90us and set CPU PLL to lowest speed | |
54 | @ fixes resume problem on high speed SA1110 | |
55 | mov r0, #90 | |
d0a533b1 | 56 | bl __loop_udelay |
1da177e4 | 57 | mov r1, #0 |
f3bb3d74 | 58 | str r1, [r5] |
1da177e4 | 59 | mov r0, #90 |
d0a533b1 | 60 | bl __loop_udelay |
1da177e4 LT |
61 | |
62 | /* | |
63 | * SA1110 SDRAM controller workaround. register values: | |
64 | * | |
65 | * r0 = &MSC0 | |
66 | * r1 = &MSC1 | |
67 | * r2 = &MSC2 | |
68 | * r3 = MSC0 value | |
69 | * r4 = MSC1 value | |
70 | * r5 = MSC2 value | |
71 | * r6 = &MDREFR | |
72 | * r7 = first MDREFR value | |
73 | * r8 = second MDREFR value | |
74 | * r9 = &MDCNFG | |
75 | * r10 = MDCNFG value | |
76 | * r11 = third MDREFR value | |
77 | * r12 = &PMCR | |
78 | * r13 = PMCR value (1) | |
79 | */ | |
80 | ||
81 | ldr r0, =MSC0 | |
82 | ldr r1, =MSC1 | |
83 | ldr r2, =MSC2 | |
84 | ||
93982535 KE |
85 | ldr r3, [r0] |
86 | bic r3, r3, #FMsk(MSC_RT) | |
87 | bic r3, r3, #FMsk(MSC_RT)<<16 | |
1da177e4 | 88 | |
93982535 KE |
89 | ldr r4, [r1] |
90 | bic r4, r4, #FMsk(MSC_RT) | |
91 | bic r4, r4, #FMsk(MSC_RT)<<16 | |
1da177e4 | 92 | |
93982535 KE |
93 | ldr r5, [r2] |
94 | bic r5, r5, #FMsk(MSC_RT) | |
95 | bic r5, r5, #FMsk(MSC_RT)<<16 | |
1da177e4 | 96 | |
93982535 | 97 | ldr r7, [r6] |
f3bb3d74 RK |
98 | bic r7, r7, #0x0000FF00 |
99 | bic r7, r7, #0x000000F0 | |
100 | orr r8, r7, #MDREFR_SLFRSH | |
1da177e4 | 101 | |
93982535 KE |
102 | ldr r9, =MDCNFG |
103 | ldr r10, [r9] | |
104 | bic r10, r10, #(MDCNFG_DE0+MDCNFG_DE1) | |
105 | bic r10, r10, #(MDCNFG_DE2+MDCNFG_DE3) | |
1da177e4 | 106 | |
93982535 KE |
107 | bic r11, r8, #MDREFR_SLFRSH |
108 | bic r11, r11, #MDREFR_E1PIN | |
1da177e4 | 109 | |
93982535 | 110 | ldr r12, =PMCR |
1da177e4 | 111 | |
93982535 | 112 | mov r13, #PMCR_SF |
1da177e4 LT |
113 | |
114 | b sa1110_sdram_controller_fix | |
115 | ||
116 | .align 5 | |
117 | sa1110_sdram_controller_fix: | |
118 | ||
119 | @ Step 1 clear RT field of all MSCx registers | |
120 | str r3, [r0] | |
121 | str r4, [r1] | |
122 | str r5, [r2] | |
123 | ||
124 | @ Step 2 clear DRI field in MDREFR | |
125 | str r7, [r6] | |
126 | ||
127 | @ Step 3 set SLFRSH bit in MDREFR | |
128 | str r8, [r6] | |
129 | ||
130 | @ Step 4 clear DE bis in MDCNFG | |
131 | str r10, [r9] | |
132 | ||
133 | @ Step 5 clear DRAM refresh control register | |
134 | str r11, [r6] | |
135 | ||
136 | @ Wow, now the hardware suspend request pins can be used, that makes them functional for | |
137 | @ about 7 ns out of the entire time that the CPU is running! | |
138 | ||
139 | @ Step 6 set force sleep bit in PMCR | |
140 | ||
141 | str r13, [r12] | |
142 | ||
143 | 20: b 20b @ loop waiting for sleep |