blob: 9d45aa3265b19a399e403045c1cda8ad3cac5130 [file] [log] [blame]
Bryan Wu1394f032007-05-06 14:50:22 -07001/*
2 * File: arch/blackfin/mach-common/dpmc.S
3 * Based on:
4 * Author: LG Soft India
5 *
6 * Created: ?
7 * Description: Watchdog Timer APIs
8 *
9 * Modified:
10 * Copyright 2004-2006 Analog Devices Inc.
11 *
12 * Bugs: Enter bugs at http://blackfin.uclinux.org/
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, see the file COPYING, or write
26 * to the Free Software Foundation, Inc.,
27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28 */
29
30#include <linux/linkage.h>
31#include <asm/blackfin.h>
32#include <asm/mach/irq.h>
33
Bryan Wu1394f032007-05-06 14:50:22 -070034
35.section .l1.text
36
37ENTRY(_sleep_mode)
38 [--SP] = ( R7:0, P5:0 );
39 [--SP] = RETS;
40
41 call _set_sic_iwr;
42
43 R0 = 0xFFFF (Z);
Michael Hennerich4521ef42008-01-11 17:21:41 +080044 call _set_rtc_istat;
Bryan Wu1394f032007-05-06 14:50:22 -070045
46 P0.H = hi(PLL_CTL);
47 P0.L = lo(PLL_CTL);
48 R1 = W[P0](z);
49 BITSET (R1, 3);
50 W[P0] = R1.L;
51
52 CLI R2;
53 SSYNC;
54 IDLE;
55 STI R2;
56
57 call _test_pll_locked;
58
59 R0 = IWR_ENABLE(0);
Michael Hennerichcfefe3c2008-02-09 04:12:37 +080060 R1 = IWR_DISABLE_ALL;
61 R2 = IWR_DISABLE_ALL;
62
Bryan Wu1394f032007-05-06 14:50:22 -070063 call _set_sic_iwr;
64
65 P0.H = hi(PLL_CTL);
66 P0.L = lo(PLL_CTL);
67 R7 = w[p0](z);
68 BITCLR (R7, 3);
69 BITCLR (R7, 5);
70 w[p0] = R7.L;
71 IDLE;
72 call _test_pll_locked;
73
74 RETS = [SP++];
75 ( R7:0, P5:0 ) = [SP++];
76 RTS;
77
78ENTRY(_hibernate_mode)
79 [--SP] = ( R7:0, P5:0 );
80 [--SP] = RETS;
81
82 call _set_sic_iwr;
83
84 R0 = 0xFFFF (Z);
Michael Hennerich4521ef42008-01-11 17:21:41 +080085 call _set_rtc_istat;
Bryan Wu1394f032007-05-06 14:50:22 -070086
87 P0.H = hi(VR_CTL);
88 P0.L = lo(VR_CTL);
89 R1 = W[P0](z);
90 BITSET (R1, 8);
91 BITCLR (R1, 0);
92 BITCLR (R1, 1);
93 W[P0] = R1.L;
94 SSYNC;
95
96 CLI R2;
97 IDLE;
98
99 /* Actually, adding anything may not be necessary...SDRAM contents
100 * are lost
101 */
102
103ENTRY(_deep_sleep)
104 [--SP] = ( R7:0, P5:0 );
105 [--SP] = RETS;
106
107 CLI R4;
108
Michael Hennerichcfefe3c2008-02-09 04:12:37 +0800109 R0 = IWR_ENABLE(0);
110 R1 = IWR_DISABLE_ALL;
111 R2 = IWR_DISABLE_ALL;
112
Bryan Wu1394f032007-05-06 14:50:22 -0700113 call _set_sic_iwr;
114
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800115 call _set_dram_srfs;
Bryan Wu1394f032007-05-06 14:50:22 -0700116
117 /* Clear all the interrupts,bits sticky */
118 R0 = 0xFFFF (Z);
119 call _set_rtc_istat
120
121 P0.H = hi(PLL_CTL);
122 P0.L = lo(PLL_CTL);
123 R0 = W[P0](z);
124 BITSET (R0, 5);
125 W[P0] = R0.L;
126
127 call _test_pll_locked;
128
129 SSYNC;
130 IDLE;
131
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800132 call _unset_dram_srfs;
Bryan Wu1394f032007-05-06 14:50:22 -0700133
134 call _test_pll_locked;
135
136 R0 = IWR_ENABLE(0);
Michael Hennerichcfefe3c2008-02-09 04:12:37 +0800137 R1 = IWR_DISABLE_ALL;
138 R2 = IWR_DISABLE_ALL;
139
Bryan Wu1394f032007-05-06 14:50:22 -0700140 call _set_sic_iwr;
141
142 P0.H = hi(PLL_CTL);
143 P0.L = lo(PLL_CTL);
144 R0 = w[p0](z);
145 BITCLR (R0, 3);
146 BITCLR (R0, 5);
147 BITCLR (R0, 8);
148 w[p0] = R0;
149 IDLE;
150 call _test_pll_locked;
151
152 STI R4;
153
154 RETS = [SP++];
155 ( R7:0, P5:0 ) = [SP++];
156 RTS;
157
158ENTRY(_sleep_deeper)
159 [--SP] = ( R7:0, P5:0 );
160 [--SP] = RETS;
161
162 CLI R4;
163
164 P3 = R0;
Michael Hennerichcfefe3c2008-02-09 04:12:37 +0800165 P4 = R1;
166 P5 = R2;
167
Bryan Wu1394f032007-05-06 14:50:22 -0700168 R0 = IWR_ENABLE(0);
Michael Hennerichcfefe3c2008-02-09 04:12:37 +0800169 R1 = IWR_DISABLE_ALL;
170 R2 = IWR_DISABLE_ALL;
171
Bryan Wu1394f032007-05-06 14:50:22 -0700172 call _set_sic_iwr;
Michael Hennerich4521ef42008-01-11 17:21:41 +0800173 call _set_dram_srfs; /* Set SDRAM Self Refresh */
Bryan Wu1394f032007-05-06 14:50:22 -0700174
175 /* Clear all the interrupts,bits sticky */
176 R0 = 0xFFFF (Z);
Michael Hennerich4521ef42008-01-11 17:21:41 +0800177 call _set_rtc_istat;
Bryan Wu1394f032007-05-06 14:50:22 -0700178 P0.H = hi(PLL_DIV);
179 P0.L = lo(PLL_DIV);
180 R6 = W[P0](z);
181 R0.L = 0xF;
Michael Hennerich4521ef42008-01-11 17:21:41 +0800182 W[P0] = R0.l; /* Set Max VCO to SCLK divider */
Bryan Wu1394f032007-05-06 14:50:22 -0700183
184 P0.H = hi(PLL_CTL);
185 P0.L = lo(PLL_CTL);
186 R5 = W[P0](z);
Robin Getzf16295e2007-08-03 18:07:17 +0800187 R0.L = (CONFIG_MIN_VCO_HZ/CONFIG_CLKIN_HZ) << 9;
Michael Hennerich4521ef42008-01-11 17:21:41 +0800188 W[P0] = R0.l; /* Set Min CLKIN to VCO multiplier */
Bryan Wu1394f032007-05-06 14:50:22 -0700189
190 SSYNC;
191 IDLE;
192
193 call _test_pll_locked;
194
195 P0.H = hi(VR_CTL);
196 P0.L = lo(VR_CTL);
197 R7 = W[P0](z);
198 R1 = 0x6;
199 R1 <<= 16;
200 R2 = 0x0404(Z);
201 R1 = R1|R2;
202
203 R2 = DEPOSIT(R7, R1);
Michael Hennerich4521ef42008-01-11 17:21:41 +0800204 W[P0] = R2; /* Set Min Core Voltage */
Bryan Wu1394f032007-05-06 14:50:22 -0700205
206 SSYNC;
207 IDLE;
208
209 call _test_pll_locked;
210
Michael Hennerich4521ef42008-01-11 17:21:41 +0800211 R0 = P3;
Michael Hennerichcfefe3c2008-02-09 04:12:37 +0800212 R1 = P4;
213 R3 = P5;
Michael Hennerich4521ef42008-01-11 17:21:41 +0800214 call _set_sic_iwr; /* Set Awake from IDLE */
215
Bryan Wu1394f032007-05-06 14:50:22 -0700216 P0.H = hi(PLL_CTL);
217 P0.L = lo(PLL_CTL);
218 R0 = W[P0](z);
219 BITSET (R0, 3);
Michael Hennerich4521ef42008-01-11 17:21:41 +0800220 W[P0] = R0.L; /* Turn CCLK OFF */
Bryan Wu1394f032007-05-06 14:50:22 -0700221 SSYNC;
222 IDLE;
223
224 call _test_pll_locked;
225
226 R0 = IWR_ENABLE(0);
Michael Hennerichcfefe3c2008-02-09 04:12:37 +0800227 R1 = IWR_DISABLE_ALL;
228 R2 = IWR_DISABLE_ALL;
229
Michael Hennerich4521ef42008-01-11 17:21:41 +0800230 call _set_sic_iwr; /* Set Awake from IDLE PLL */
Bryan Wu1394f032007-05-06 14:50:22 -0700231
232 P0.H = hi(VR_CTL);
233 P0.L = lo(VR_CTL);
234 W[P0]= R7;
235
236 SSYNC;
237 IDLE;
238
239 call _test_pll_locked;
240
241 P0.H = hi(PLL_DIV);
242 P0.L = lo(PLL_DIV);
Michael Hennerich4521ef42008-01-11 17:21:41 +0800243 W[P0]= R6; /* Restore CCLK and SCLK divider */
Bryan Wu1394f032007-05-06 14:50:22 -0700244
245 P0.H = hi(PLL_CTL);
246 P0.L = lo(PLL_CTL);
Michael Hennerich4521ef42008-01-11 17:21:41 +0800247 w[p0] = R5; /* Restore VCO multiplier */
Bryan Wu1394f032007-05-06 14:50:22 -0700248 IDLE;
249 call _test_pll_locked;
250
Michael Hennerich4521ef42008-01-11 17:21:41 +0800251 call _unset_dram_srfs; /* SDRAM Self Refresh Off */
Bryan Wu1394f032007-05-06 14:50:22 -0700252
253 STI R4;
254
255 RETS = [SP++];
256 ( R7:0, P5:0 ) = [SP++];
257 RTS;
258
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800259ENTRY(_set_dram_srfs)
260 /* set the dram to self refresh mode */
261#if defined(CONFIG_BF54x)
262 P0.H = hi(EBIU_RSTCTL);
263 P0.L = lo(EBIU_RSTCTL);
264 R2 = [P0];
265 R3.H = hi(SRREQ);
266 R3.L = lo(SRREQ);
267#else
Bryan Wu1394f032007-05-06 14:50:22 -0700268 P0.H = hi(EBIU_SDGCTL);
269 P0.L = lo(EBIU_SDGCTL);
270 R2 = [P0];
271 R3.H = hi(SRFS);
272 R3.L = lo(SRFS);
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800273#endif
Bryan Wu1394f032007-05-06 14:50:22 -0700274 R2 = R2|R3;
275 [P0] = R2;
276 ssync;
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800277#if defined(CONFIG_BF54x)
278.LSRR_MODE:
279 R2 = [P0];
280 CC = BITTST(R2, 4);
281 if !CC JUMP .LSRR_MODE;
282#endif
Bryan Wu1394f032007-05-06 14:50:22 -0700283 RTS;
284
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800285ENTRY(_unset_dram_srfs)
286 /* set the dram out of self refresh mode */
287#if defined(CONFIG_BF54x)
288 P0.H = hi(EBIU_RSTCTL);
289 P0.L = lo(EBIU_RSTCTL);
290 R2 = [P0];
291 R3.H = hi(SRREQ);
292 R3.L = lo(SRREQ);
293#else
Bryan Wu1394f032007-05-06 14:50:22 -0700294 P0.H = hi(EBIU_SDGCTL);
295 P0.L = lo(EBIU_SDGCTL);
296 R2 = [P0];
297 R3.H = hi(SRFS);
298 R3.L = lo(SRFS);
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800299#endif
Bryan Wu1394f032007-05-06 14:50:22 -0700300 R3 = ~R3;
301 R2 = R2&R3;
302 [P0] = R2;
303 ssync;
304 RTS;
305
306ENTRY(_set_sic_iwr)
Michael Hennerichcfefe3c2008-02-09 04:12:37 +0800307#if defined(CONFIG_BF54x) || defined(CONFIG_BF52x) || defined(CONFIG_BF561)
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800308 P0.H = hi(SIC_IWR0);
309 P0.L = lo(SIC_IWR0);
Michael Hennerichcfefe3c2008-02-09 04:12:37 +0800310 P1.H = hi(SIC_IWR1);
311 P1.L = lo(SIC_IWR1);
312 [P1] = R1;
313#if defined(CONFIG_BF54x)
314 P1.H = hi(SIC_IWR2);
315 P1.L = lo(SIC_IWR2);
316 [P1] = R2;
317#endif
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800318#else
Bryan Wu1394f032007-05-06 14:50:22 -0700319 P0.H = hi(SIC_IWR);
320 P0.L = lo(SIC_IWR);
Sonic Zhangfb5f0042007-12-23 23:02:13 +0800321#endif
Bryan Wu1394f032007-05-06 14:50:22 -0700322 [P0] = R0;
Michael Hennerichcfefe3c2008-02-09 04:12:37 +0800323
Bryan Wu1394f032007-05-06 14:50:22 -0700324 SSYNC;
325 RTS;
326
327ENTRY(_set_rtc_istat)
Michael Hennerich39278192008-02-25 14:39:50 +0800328#ifndef CONFIG_BF561
Bryan Wu1394f032007-05-06 14:50:22 -0700329 P0.H = hi(RTC_ISTAT);
330 P0.L = lo(RTC_ISTAT);
331 w[P0] = R0.L;
332 SSYNC;
Michael Hennerich39278192008-02-25 14:39:50 +0800333#endif
Bryan Wu1394f032007-05-06 14:50:22 -0700334 RTS;
335
336ENTRY(_test_pll_locked)
337 P0.H = hi(PLL_STAT);
338 P0.L = lo(PLL_STAT);
3391:
340 R0 = W[P0] (Z);
341 CC = BITTST(R0,5);
342 IF !CC JUMP 1b;
343 RTS;