Pull bugzilla-9345 into release branch
[linux-2.6] / arch / blackfin / mach-common / dpmc.S
1 /*
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
34 .text
35
36 ENTRY(_unmask_wdog_wakeup_evt)
37         [--SP] = ( R7:0, P5:0 );
38 #if defined(CONFIG_BF561)
39         P0.H = hi(SICA_IWR1);
40         P0.L = lo(SICA_IWR1);
41 #else
42         P0.h = HI(SIC_IWR);
43         P0.l = LO(SIC_IWR);
44 #endif
45         R7 = [P0];
46 #if defined(CONFIG_BF561)
47         BITSET(R7, 27);
48 #else
49         BITSET(R7,(IRQ_WATCH - IVG7));
50 #endif
51         [P0] = R7;
52         SSYNC;
53
54         ( R7:0, P5:0 ) = [SP++];
55         RTS;
56
57 .LWRITE_TO_STAT:
58         /* When watch dog timer is enabled, a write to STAT will load the
59          * contents of CNT to STAT
60          */
61         R7 = 0x0000(z);
62 #if defined(CONFIG_BF561)
63         P0.h = HI(WDOGA_STAT);
64         P0.l = LO(WDOGA_STAT);
65 #else
66         P0.h = HI(WDOG_STAT);
67         P0.l = LO(WDOG_STAT);
68 #endif
69         [P0] = R7;
70         SSYNC;
71         JUMP .LSKIP_WRITE_TO_STAT;
72
73 ENTRY(_program_wdog_timer)
74         [--SP] = ( R7:0, P5:0 );
75 #if defined(CONFIG_BF561)
76         P0.h = HI(WDOGA_CNT);
77         P0.l = LO(WDOGA_CNT);
78 #else
79         P0.h = HI(WDOG_CNT);
80         P0.l = LO(WDOG_CNT);
81 #endif
82         [P0] = R0;
83         SSYNC;
84
85 #if defined(CONFIG_BF561)
86         P0.h = HI(WDOGA_CTL);
87         P0.l = LO(WDOGA_CTL);
88 #else
89         P0.h = HI(WDOG_CTL);
90         P0.l = LO(WDOG_CTL);
91 #endif
92         R7 = W[P0](Z);
93         CC = BITTST(R7,1);
94         if !CC JUMP .LWRITE_TO_STAT;
95         CC = BITTST(R7,2);
96         if !CC JUMP .LWRITE_TO_STAT;
97
98 .LSKIP_WRITE_TO_STAT:
99 #if defined(CONFIG_BF561)
100         P0.h = HI(WDOGA_CTL);
101         P0.l = LO(WDOGA_CTL);
102 #else
103         P0.h = HI(WDOG_CTL);
104         P0.l = LO(WDOG_CTL);
105 #endif
106         R7 = W[P0](Z);
107         BITCLR(R7,1);   /* Enable GP event */
108         BITSET(R7,2);
109         W[P0] = R7.L;
110         SSYNC;
111         NOP;
112
113         R7 = W[P0](Z);
114         BITCLR(R7,4);   /* Enable the wdog counter */
115         W[P0] = R7.L;
116         SSYNC;
117
118         ( R7:0, P5:0 ) = [SP++];
119         RTS;
120
121 ENTRY(_clear_wdog_wakeup_evt)
122         [--SP] = ( R7:0, P5:0 );
123
124 #if defined(CONFIG_BF561)
125         P0.h = HI(WDOGA_CTL);
126         P0.l = LO(WDOGA_CTL);
127 #else
128         P0.h = HI(WDOG_CTL);
129         P0.l = LO(WDOG_CTL);
130 #endif
131         R7 = 0x0AD6(Z);
132         W[P0] = R7.L;
133         SSYNC;
134
135         R7 = W[P0](Z);
136         BITSET(R7,15);
137         W[P0] = R7.L;
138         SSYNC;
139
140         R7 = W[P0](Z);
141         BITSET(R7,1);
142         BITSET(R7,2);
143         W[P0] = R7.L;
144         SSYNC;
145
146         ( R7:0, P5:0 ) = [SP++];
147         RTS;
148
149 ENTRY(_disable_wdog_timer)
150         [--SP] = ( R7:0, P5:0 );
151 #if defined(CONFIG_BF561)
152         P0.h = HI(WDOGA_CTL);
153         P0.l = LO(WDOGA_CTL);
154 #else
155         P0.h = HI(WDOG_CTL);
156         P0.l = LO(WDOG_CTL);
157 #endif
158         R7 = 0xAD6(Z);
159         W[P0] = R7.L;
160         SSYNC;
161         ( R7:0, P5:0 ) = [SP++];
162         RTS;
163
164 #if !defined(CONFIG_BF561)
165
166 .section .l1.text
167
168 ENTRY(_sleep_mode)
169         [--SP] = ( R7:0, P5:0 );
170         [--SP] =  RETS;
171
172         call _set_sic_iwr;
173
174         R0 = 0xFFFF (Z);
175         call _set_rtc_istat
176
177         P0.H = hi(PLL_CTL);
178         P0.L = lo(PLL_CTL);
179         R1 = W[P0](z);
180         BITSET (R1, 3);
181         W[P0] = R1.L;
182
183         CLI R2;
184         SSYNC;
185         IDLE;
186         STI R2;
187
188         call _test_pll_locked;
189
190         R0 = IWR_ENABLE(0);
191         call _set_sic_iwr;
192
193         P0.H = hi(PLL_CTL);
194         P0.L = lo(PLL_CTL);
195         R7 = w[p0](z);
196         BITCLR (R7, 3);
197         BITCLR (R7, 5);
198         w[p0] = R7.L;
199         IDLE;
200         call _test_pll_locked;
201
202         RETS = [SP++];
203         ( R7:0, P5:0 ) = [SP++];
204         RTS;
205
206 ENTRY(_hibernate_mode)
207         [--SP] = ( R7:0, P5:0 );
208         [--SP] =  RETS;
209
210         call _set_sic_iwr;
211
212         R0 = 0xFFFF (Z);
213         call _set_rtc_istat
214
215         P0.H = hi(VR_CTL);
216         P0.L = lo(VR_CTL);
217         R1 = W[P0](z);
218         BITSET (R1, 8);
219         BITCLR (R1, 0);
220         BITCLR (R1, 1);
221         W[P0] = R1.L;
222         SSYNC;
223
224         CLI R2;
225         IDLE;
226
227         /* Actually, adding anything may not be necessary...SDRAM contents
228          * are lost
229          */
230
231 ENTRY(_deep_sleep)
232         [--SP] = ( R7:0, P5:0 );
233         [--SP] =  RETS;
234
235         CLI R4;
236
237         call _set_sic_iwr;
238
239         call _set_sdram_srfs;
240
241         /* Clear all the interrupts,bits sticky */
242         R0 = 0xFFFF (Z);
243         call _set_rtc_istat
244
245         P0.H = hi(PLL_CTL);
246         P0.L = lo(PLL_CTL);
247         R0 = W[P0](z);
248         BITSET (R0, 5);
249         W[P0] = R0.L;
250
251         call _test_pll_locked;
252
253         SSYNC;
254         IDLE;
255
256         call _unset_sdram_srfs;
257
258         call _test_pll_locked;
259
260         R0 = IWR_ENABLE(0);
261         call _set_sic_iwr;
262
263         P0.H = hi(PLL_CTL);
264         P0.L = lo(PLL_CTL);
265         R0 = w[p0](z);
266         BITCLR (R0, 3);
267         BITCLR (R0, 5);
268         BITCLR (R0, 8);
269         w[p0] = R0;
270         IDLE;
271         call _test_pll_locked;
272
273         STI R4;
274
275         RETS = [SP++];
276         ( R7:0, P5:0 ) = [SP++];
277         RTS;
278
279 ENTRY(_sleep_deeper)
280         [--SP] = ( R7:0, P5:0 );
281         [--SP] =  RETS;
282
283         CLI R4;
284
285         P3 = R0;
286         R0 = IWR_ENABLE(0);
287         call _set_sic_iwr;
288         call _set_sdram_srfs;
289
290         /* Clear all the interrupts,bits sticky */
291         R0 = 0xFFFF (Z);
292         call _set_rtc_istat
293
294         P0.H = hi(PLL_DIV);
295         P0.L = lo(PLL_DIV);
296         R6 = W[P0](z);
297         R0.L = 0xF;
298         W[P0] = R0.l;
299
300         P0.H = hi(PLL_CTL);
301         P0.L = lo(PLL_CTL);
302         R5 = W[P0](z);
303         R0.L = (CONFIG_MIN_VCO_HZ/CONFIG_CLKIN_HZ) << 9;
304         W[P0] = R0.l;
305
306         SSYNC;
307         IDLE;
308
309         call _test_pll_locked;
310
311         P0.H = hi(VR_CTL);
312         P0.L = lo(VR_CTL);
313         R7 = W[P0](z);
314         R1 = 0x6;
315         R1 <<= 16;
316         R2 = 0x0404(Z);
317         R1 = R1|R2;
318
319         R2 = DEPOSIT(R7, R1);
320         W[P0] = R2;
321
322         SSYNC;
323         IDLE;
324
325         call _test_pll_locked;
326
327         P0.H = hi(PLL_CTL);
328         P0.L = lo(PLL_CTL);
329         R0 = W[P0](z);
330         BITSET (R0, 3);
331         W[P0] = R0.L;
332
333         R0 = P3;
334         call _set_sic_iwr;
335
336         SSYNC;
337         IDLE;
338
339         call _test_pll_locked;
340
341         R0 = IWR_ENABLE(0);
342         call _set_sic_iwr;
343
344         P0.H = hi(VR_CTL);
345         P0.L = lo(VR_CTL);
346         W[P0]= R7;
347
348         SSYNC;
349         IDLE;
350
351         call _test_pll_locked;
352
353         P0.H = hi(PLL_DIV);
354         P0.L = lo(PLL_DIV);
355         W[P0]= R6;
356
357         P0.H = hi(PLL_CTL);
358         P0.L = lo(PLL_CTL);
359         w[p0] = R5;
360         IDLE;
361         call _test_pll_locked;
362
363         call _unset_sdram_srfs;
364
365         STI R4;
366
367         RETS = [SP++];
368         ( R7:0, P5:0 ) = [SP++];
369         RTS;
370
371 ENTRY(_set_sdram_srfs)
372         /*  set the sdram to self refresh mode */
373         P0.H = hi(EBIU_SDGCTL);
374         P0.L = lo(EBIU_SDGCTL);
375         R2 = [P0];
376         R3.H = hi(SRFS);
377         R3.L = lo(SRFS);
378         R2 = R2|R3;
379         [P0] = R2;
380         ssync;
381         RTS;
382
383 ENTRY(_unset_sdram_srfs)
384         /*  set the sdram out of self refresh mode */
385         P0.H = hi(EBIU_SDGCTL);
386         P0.L = lo(EBIU_SDGCTL);
387         R2 = [P0];
388         R3.H = hi(SRFS);
389         R3.L = lo(SRFS);
390         R3 = ~R3;
391         R2 = R2&R3;
392         [P0] = R2;
393         ssync;
394         RTS;
395
396 ENTRY(_set_sic_iwr)
397         P0.H = hi(SIC_IWR);
398         P0.L = lo(SIC_IWR);
399         [P0] = R0;
400         SSYNC;
401         RTS;
402
403 ENTRY(_set_rtc_istat)
404         P0.H = hi(RTC_ISTAT);
405         P0.L = lo(RTC_ISTAT);
406         w[P0] = R0.L;
407         SSYNC;
408         RTS;
409
410 ENTRY(_test_pll_locked)
411         P0.H = hi(PLL_STAT);
412         P0.L = lo(PLL_STAT);
413 1:
414         R0 = W[P0] (Z);
415         CC = BITTST(R0,5);
416         IF !CC JUMP 1b;
417         RTS;
418 #endif