[Blackfin] arch: Functional power management support: Add CPU and platform voltage...
[linux-2.6.git] / arch / blackfin / mach-common / dpmc_modes.S
1 /*
2  * Copyright 2004-2008 Analog Devices Inc.
3  *
4  * Licensed under the GPL-2 or later.
5  */
6
7 #include <linux/linkage.h>
8 #include <asm/blackfin.h>
9 #include <asm/mach/irq.h>
10
11
12 .section .l1.text
13
14 ENTRY(_sleep_mode)
15         [--SP] = ( R7:0, P5:0 );
16         [--SP] =  RETS;
17
18         call _set_sic_iwr;
19
20         R0 = 0xFFFF (Z);
21         call _set_rtc_istat;
22
23         P0.H = hi(PLL_CTL);
24         P0.L = lo(PLL_CTL);
25         R1 = W[P0](z);
26         BITSET (R1, 3);
27         W[P0] = R1.L;
28
29         CLI R2;
30         SSYNC;
31         IDLE;
32         STI R2;
33
34         call _test_pll_locked;
35
36         R0 = IWR_ENABLE(0);
37         R1 = IWR_DISABLE_ALL;
38         R2 = IWR_DISABLE_ALL;
39
40         call _set_sic_iwr;
41
42         P0.H = hi(PLL_CTL);
43         P0.L = lo(PLL_CTL);
44         R7 = w[p0](z);
45         BITCLR (R7, 3);
46         BITCLR (R7, 5);
47         w[p0] = R7.L;
48         IDLE;
49         call _test_pll_locked;
50
51         RETS = [SP++];
52         ( R7:0, P5:0 ) = [SP++];
53         RTS;
54
55 ENTRY(_hibernate_mode)
56         [--SP] = ( R7:0, P5:0 );
57         [--SP] =  RETS;
58
59         call _set_sic_iwr;
60
61         R0 = 0xFFFF (Z);
62         call _set_rtc_istat;
63
64         P0.H = hi(VR_CTL);
65         P0.L = lo(VR_CTL);
66         R1 = W[P0](z);
67         BITSET (R1, 8);
68         BITCLR (R1, 0);
69         BITCLR (R1, 1);
70         W[P0] = R1.L;
71         SSYNC;
72
73         CLI R2;
74         IDLE;
75
76         /* Actually, adding anything may not be necessary...SDRAM contents
77          * are lost
78          */
79
80 ENTRY(_deep_sleep)
81         [--SP] = ( R7:0, P5:0 );
82         [--SP] =  RETS;
83
84         CLI R4;
85
86         R0 = IWR_ENABLE(0);
87         R1 = IWR_DISABLE_ALL;
88         R2 = IWR_DISABLE_ALL;
89
90         call _set_sic_iwr;
91
92         call _set_dram_srfs;
93
94         /* Clear all the interrupts,bits sticky */
95         R0 = 0xFFFF (Z);
96         call _set_rtc_istat
97
98         P0.H = hi(PLL_CTL);
99         P0.L = lo(PLL_CTL);
100         R0 = W[P0](z);
101         BITSET (R0, 5);
102         W[P0] = R0.L;
103
104         call _test_pll_locked;
105
106         SSYNC;
107         IDLE;
108
109         call _unset_dram_srfs;
110
111         call _test_pll_locked;
112
113         R0 = IWR_ENABLE(0);
114         R1 = IWR_DISABLE_ALL;
115         R2 = IWR_DISABLE_ALL;
116
117         call _set_sic_iwr;
118
119         P0.H = hi(PLL_CTL);
120         P0.L = lo(PLL_CTL);
121         R0 = w[p0](z);
122         BITCLR (R0, 3);
123         BITCLR (R0, 5);
124         BITCLR (R0, 8);
125         w[p0] = R0;
126         IDLE;
127         call _test_pll_locked;
128
129         STI R4;
130
131         RETS = [SP++];
132         ( R7:0, P5:0 ) = [SP++];
133         RTS;
134
135 ENTRY(_sleep_deeper)
136         [--SP] = ( R7:0, P5:0 );
137         [--SP] =  RETS;
138
139         CLI R4;
140
141         P3 = R0;
142         P4 = R1;
143         P5 = R2;
144
145         R0 = IWR_ENABLE(0);
146         R1 = IWR_DISABLE_ALL;
147         R2 = IWR_DISABLE_ALL;
148
149         call _set_sic_iwr;
150         call _set_dram_srfs;    /* Set SDRAM Self Refresh */
151
152         /* Clear all the interrupts,bits sticky */
153         R0 = 0xFFFF (Z);
154         call _set_rtc_istat;
155         P0.H = hi(PLL_DIV);
156         P0.L = lo(PLL_DIV);
157         R6 = W[P0](z);
158         R0.L = 0xF;
159         W[P0] = R0.l;           /* Set Max VCO to SCLK divider */
160
161         P0.H = hi(PLL_CTL);
162         P0.L = lo(PLL_CTL);
163         R5 = W[P0](z);
164         R0.L = (CONFIG_MIN_VCO_HZ/CONFIG_CLKIN_HZ) << 9;
165         W[P0] = R0.l;           /* Set Min CLKIN to VCO multiplier */
166
167         SSYNC;
168         IDLE;
169
170         call _test_pll_locked;
171
172         P0.H = hi(VR_CTL);
173         P0.L = lo(VR_CTL);
174         R7 = W[P0](z);
175         R1 = 0x6;
176         R1 <<= 16;
177         R2 = 0x0404(Z);
178         R1 = R1|R2;
179
180         R2 = DEPOSIT(R7, R1);
181         W[P0] = R2;             /* Set Min Core Voltage */
182
183         SSYNC;
184         IDLE;
185
186         call _test_pll_locked;
187
188         R0 = P3;
189         R1 = P4;
190         R3 = P5;
191         call _set_sic_iwr;      /* Set Awake from IDLE */
192
193         P0.H = hi(PLL_CTL);
194         P0.L = lo(PLL_CTL);
195         R0 = W[P0](z);
196         BITSET (R0, 3);
197         W[P0] = R0.L;           /* Turn CCLK OFF */
198         SSYNC;
199         IDLE;
200
201         call _test_pll_locked;
202
203         R0 = IWR_ENABLE(0);
204         R1 = IWR_DISABLE_ALL;
205         R2 = IWR_DISABLE_ALL;
206
207         call _set_sic_iwr;      /* Set Awake from IDLE PLL */
208
209         P0.H = hi(VR_CTL);
210         P0.L = lo(VR_CTL);
211         W[P0]= R7;
212
213         SSYNC;
214         IDLE;
215
216         call _test_pll_locked;
217
218         P0.H = hi(PLL_DIV);
219         P0.L = lo(PLL_DIV);
220         W[P0]= R6;              /* Restore CCLK and SCLK divider */
221
222         P0.H = hi(PLL_CTL);
223         P0.L = lo(PLL_CTL);
224         w[p0] = R5;             /* Restore VCO multiplier */
225         IDLE;
226         call _test_pll_locked;
227
228         call _unset_dram_srfs;  /* SDRAM Self Refresh Off */
229
230         STI R4;
231
232         RETS = [SP++];
233         ( R7:0, P5:0 ) = [SP++];
234         RTS;
235
236 ENTRY(_set_dram_srfs)
237         /*  set the dram to self refresh mode */
238 #if defined(CONFIG_BF54x)
239         P0.H = hi(EBIU_RSTCTL);
240         P0.L = lo(EBIU_RSTCTL);
241         R2 = [P0];
242         R3.H = hi(SRREQ);
243         R3.L = lo(SRREQ);
244 #else
245         P0.H = hi(EBIU_SDGCTL);
246         P0.L = lo(EBIU_SDGCTL);
247         R2 = [P0];
248         R3.H = hi(SRFS);
249         R3.L = lo(SRFS);
250 #endif
251         R2 = R2|R3;
252         [P0] = R2;
253         ssync;
254 #if defined(CONFIG_BF54x)
255 .LSRR_MODE:
256         R2 = [P0];
257         CC = BITTST(R2, 4);
258         if !CC JUMP .LSRR_MODE;
259 #endif
260         RTS;
261
262 ENTRY(_unset_dram_srfs)
263         /*  set the dram out of self refresh mode */
264 #if defined(CONFIG_BF54x)
265         P0.H = hi(EBIU_RSTCTL);
266         P0.L = lo(EBIU_RSTCTL);
267         R2 = [P0];
268         R3.H = hi(SRREQ);
269         R3.L = lo(SRREQ);
270 #else
271         P0.H = hi(EBIU_SDGCTL);
272         P0.L = lo(EBIU_SDGCTL);
273         R2 = [P0];
274         R3.H = hi(SRFS);
275         R3.L = lo(SRFS);
276 #endif
277         R3 = ~R3;
278         R2 = R2&R3;
279         [P0] = R2;
280         ssync;
281         RTS;
282
283 ENTRY(_set_sic_iwr)
284 #if defined(CONFIG_BF54x) || defined(CONFIG_BF52x)  || defined(CONFIG_BF561)
285         P0.H = hi(SIC_IWR0);
286         P0.L = lo(SIC_IWR0);
287         P1.H = hi(SIC_IWR1);
288         P1.L = lo(SIC_IWR1);
289         [P1] = R1;
290 #if defined(CONFIG_BF54x)
291         P1.H = hi(SIC_IWR2);
292         P1.L = lo(SIC_IWR2);
293         [P1] = R2;
294 #endif
295 #else
296         P0.H = hi(SIC_IWR);
297         P0.L = lo(SIC_IWR);
298 #endif
299         [P0] = R0;
300
301         SSYNC;
302         RTS;
303
304 ENTRY(_set_rtc_istat)
305 #ifndef CONFIG_BF561
306         P0.H = hi(RTC_ISTAT);
307         P0.L = lo(RTC_ISTAT);
308         w[P0] = R0.L;
309         SSYNC;
310 #endif
311         RTS;
312
313 ENTRY(_test_pll_locked)
314         P0.H = hi(PLL_STAT);
315         P0.L = lo(PLL_STAT);
316 1:
317         R0 = W[P0] (Z);
318         CC = BITTST(R0,5);
319         IF !CC JUMP 1b;
320         RTS;