ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / arm / mach-pxa / pm.c
1 /*
2  * PXA250/210 Power Management Routines
3  *
4  * Original code for the SA11x0:
5  * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
6  *
7  * Modified for the PXA250 by Nicolas Pitre:
8  * Copyright (c) 2002 Monta Vista Software, Inc.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License.
12  */
13 #include <linux/config.h>
14 #include <linux/init.h>
15 #include <linux/suspend.h>
16 #include <linux/errno.h>
17 #include <linux/time.h>
18
19 #include <asm/hardware.h>
20 #include <asm/memory.h>
21 #include <asm/system.h>
22
23
24 /*
25  * Debug macros
26  */
27 #undef DEBUG
28
29 extern void pxa_cpu_suspend(void);
30 extern void pxa_cpu_resume(void);
31
32 #define SAVE(x)         sleep_save[SLEEP_SAVE_##x] = x
33 #define RESTORE(x)      x = sleep_save[SLEEP_SAVE_##x]
34
35 /*
36  * List of global PXA peripheral registers to preserve.
37  * More ones like CP and general purpose register values are preserved
38  * with the stack pointer in sleep.S.
39  */
40 enum {  SLEEP_SAVE_START = 0,
41
42         SLEEP_SAVE_OSCR, SLEEP_SAVE_OIER,
43         SLEEP_SAVE_OSMR0, SLEEP_SAVE_OSMR1, SLEEP_SAVE_OSMR2, SLEEP_SAVE_OSMR3,
44
45         SLEEP_SAVE_GPDR0, SLEEP_SAVE_GPDR1, SLEEP_SAVE_GPDR2,
46         SLEEP_SAVE_GRER0, SLEEP_SAVE_GRER1, SLEEP_SAVE_GRER2,
47         SLEEP_SAVE_GFER0, SLEEP_SAVE_GFER1, SLEEP_SAVE_GFER2,
48         SLEEP_SAVE_GAFR0_L, SLEEP_SAVE_GAFR1_L, SLEEP_SAVE_GAFR2_L,
49         SLEEP_SAVE_GAFR0_U, SLEEP_SAVE_GAFR1_U, SLEEP_SAVE_GAFR2_U,
50
51         SLEEP_SAVE_FFIER, SLEEP_SAVE_FFLCR, SLEEP_SAVE_FFMCR,
52         SLEEP_SAVE_FFSPR, SLEEP_SAVE_FFISR,
53         SLEEP_SAVE_FFDLL, SLEEP_SAVE_FFDLH,
54
55         SLEEP_SAVE_ICMR,
56         SLEEP_SAVE_CKEN,
57
58         SLEEP_SAVE_CKSUM,
59
60         SLEEP_SAVE_SIZE
61 };
62
63
64 static int pxa_pm_enter(u32 state)
65 {
66         unsigned long sleep_save[SLEEP_SAVE_SIZE];
67         unsigned long checksum = 0;
68         unsigned long delta;
69         int i;
70
71         if (state != PM_SUSPEND_MEM)
72                 return -EINVAL;
73
74         /* preserve current time */
75         delta = xtime.tv_sec - RCNR;
76
77         /*
78          * Temporary solution.  This won't be necessary once
79          * we move pxa support into the serial driver
80          * Save the FF UART
81          */
82         SAVE(FFIER);
83         SAVE(FFLCR);
84         SAVE(FFMCR);
85         SAVE(FFSPR);
86         SAVE(FFISR);
87         FFLCR |= 0x80;
88         SAVE(FFDLL);
89         SAVE(FFDLH);
90         FFLCR &= 0xef;
91
92         /* save vital registers */
93         SAVE(OSCR);
94         SAVE(OSMR0);
95         SAVE(OSMR1);
96         SAVE(OSMR2);
97         SAVE(OSMR3);
98         SAVE(OIER);
99
100         SAVE(GPDR0); SAVE(GPDR1); SAVE(GPDR2);
101         SAVE(GRER0); SAVE(GRER1); SAVE(GRER2);
102         SAVE(GFER0); SAVE(GFER1); SAVE(GFER2);
103         SAVE(GAFR0_L); SAVE(GAFR0_U);
104         SAVE(GAFR1_L); SAVE(GAFR1_U);
105         SAVE(GAFR2_L); SAVE(GAFR2_U);
106
107         SAVE(ICMR);
108         ICMR = 0;
109
110         SAVE(CKEN);
111         CKEN = 0;
112
113         /* Note: wake up source are set up in each machine specific files */
114
115         /* clear GPIO transition detect  bits */
116         GEDR0 = GEDR0; GEDR1 = GEDR1; GEDR2 = GEDR2;
117
118         /* Clear sleep reset status */
119         RCSR = RCSR_SMR;
120
121         /* set resume return address */
122         PSPR = virt_to_phys(pxa_cpu_resume);
123
124         /* before sleeping, calculate and save a checksum */
125         for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
126                 checksum += sleep_save[i];
127         sleep_save[SLEEP_SAVE_CKSUM] = checksum;
128
129         /* *** go zzz *** */
130         pxa_cpu_suspend();
131
132         /* after sleeping, validate the checksum */
133         checksum = 0;
134         for (i = 0; i < SLEEP_SAVE_SIZE - 1; i++)
135                 checksum += sleep_save[i];
136
137         /* if invalid, display message and wait for a hardware reset */
138         if (checksum != sleep_save[SLEEP_SAVE_CKSUM]) {
139 #ifdef CONFIG_ARCH_LUBBOCK
140                 LUB_HEXLED = 0xbadbadc5;
141 #endif
142                 while (1);
143         }
144
145         /* ensure not to come back here if it wasn't intended */
146         PSPR = 0;
147
148         /* restore registers */
149         RESTORE(GPDR0); RESTORE(GPDR1); RESTORE(GPDR2);
150         RESTORE(GRER0); RESTORE(GRER1); RESTORE(GRER2);
151         RESTORE(GFER0); RESTORE(GFER1); RESTORE(GFER2);
152         RESTORE(GAFR0_L); RESTORE(GAFR0_U);
153         RESTORE(GAFR1_L); RESTORE(GAFR1_U);
154         RESTORE(GAFR2_L); RESTORE(GAFR2_U);
155
156         PSSR = PSSR_PH;
157
158         RESTORE(OSMR0);
159         RESTORE(OSMR1);
160         RESTORE(OSMR2);
161         RESTORE(OSMR3);
162         RESTORE(OSCR);
163         RESTORE(OIER);
164
165         RESTORE(CKEN);
166
167         ICLR = 0;
168         ICCR = 1;
169         RESTORE(ICMR);
170
171         /*
172          * Temporary solution.  This won't be necessary once
173          * we move pxa support into the serial driver.
174          * Restore the FF UART.
175          */
176         RESTORE(FFMCR);
177         RESTORE(FFSPR);
178         RESTORE(FFLCR);
179         FFLCR |= 0x80;
180         RESTORE(FFDLH);
181         RESTORE(FFDLL);
182         RESTORE(FFLCR);
183         RESTORE(FFISR);
184         FFFCR = 0x07;
185         RESTORE(FFIER);
186
187         /* restore current time */
188         xtime.tv_sec = RCNR + delta;
189
190 #ifdef DEBUG
191         printk(KERN_DEBUG "*** made it back from resume\n");
192 #endif
193
194         return 0;
195 }
196
197 unsigned long sleep_phys_sp(void *sp)
198 {
199         return virt_to_phys(sp);
200 }
201
202 /*
203  * Called after processes are frozen, but before we shut down devices.
204  */
205 static int pxa_pm_prepare(u32 state)
206 {
207         return 0;
208 }
209
210 /*
211  * Called after devices are re-setup, but before processes are thawed.
212  */
213 static int pxa_pm_finish(u32 state)
214 {
215         return 0;
216 }
217
218 /*
219  * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
220  */
221 static struct pm_ops pxa_pm_ops = {
222         .pm_disk_mode   = PM_DISK_FIRMWARE,
223         .prepare        = pxa_pm_prepare,
224         .enter          = pxa_pm_enter,
225         .finish         = pxa_pm_finish,
226 };
227
228 static int __init pxa_pm_init(void)
229 {
230         pm_set_ops(&pxa_pm_ops);
231         return 0;
232 }
233
234 late_initcall(pxa_pm_init);