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