pxa2x0_apm.c revision 1.1.12.2 1 1.1.12.2 yamt /* $NetBSD: pxa2x0_apm.c,v 1.1.12.2 2009/05/04 08:10:45 yamt Exp $ */
2 1.1.12.2 yamt /* $OpenBSD: pxa2x0_apm.c,v 1.28 2007/03/29 18:42:38 uwe Exp $ */
3 1.1.12.2 yamt
4 1.1.12.2 yamt /*-
5 1.1.12.2 yamt * Copyright (c) 2001 Alexander Guy. All rights reserved.
6 1.1.12.2 yamt * Copyright (c) 1998-2001 Michael Shalayeff. All rights reserved.
7 1.1.12.2 yamt * Copyright (c) 1995 John T. Kohl. All rights reserved.
8 1.1.12.2 yamt *
9 1.1.12.2 yamt * Redistribution and use in source and binary forms, with or without
10 1.1.12.2 yamt * modification, are permitted provided that the following conditions
11 1.1.12.2 yamt * are met:
12 1.1.12.2 yamt * 1. Redistributions of source code must retain the above copyright
13 1.1.12.2 yamt * notice, this list of conditions and the following disclaimer.
14 1.1.12.2 yamt * 2. Redistributions in binary form must reproduce the above copyright
15 1.1.12.2 yamt * notice, this list of conditions and the following disclaimer in the
16 1.1.12.2 yamt * documentation and/or other materials provided with the distribution.
17 1.1.12.2 yamt * 3. All advertising materials mentioning features or use of this software
18 1.1.12.2 yamt * must display the following acknowledgement:
19 1.1.12.2 yamt * This product includes software developed by the University of
20 1.1.12.2 yamt * California, Berkeley and its contributors.
21 1.1.12.2 yamt * 4. Neither the name of the University nor the names of its contributors
22 1.1.12.2 yamt * may be used to endorse or promote products derived from this software
23 1.1.12.2 yamt * without specific prior written permission.
24 1.1.12.2 yamt *
25 1.1.12.2 yamt * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 1.1.12.2 yamt * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 1.1.12.2 yamt * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 1.1.12.2 yamt * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 1.1.12.2 yamt * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 1.1.12.2 yamt * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 1.1.12.2 yamt * OR SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 1.1.12.2 yamt * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 1.1.12.2 yamt * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 1.1.12.2 yamt * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 1.1.12.2 yamt * SUCH DAMAGE.
36 1.1.12.2 yamt *
37 1.1.12.2 yamt */
38 1.1.12.2 yamt
39 1.1.12.2 yamt #include <sys/param.h>
40 1.1.12.2 yamt #include <sys/systm.h>
41 1.1.12.2 yamt #include <sys/kernel.h>
42 1.1.12.2 yamt #include <sys/kthread.h>
43 1.1.12.2 yamt #include <sys/lock.h>
44 1.1.12.2 yamt #include <sys/mount.h> /* for vfs_syncwait() */
45 1.1.12.2 yamt #include <sys/proc.h>
46 1.1.12.2 yamt #include <sys/device.h>
47 1.1.12.2 yamt #include <sys/fcntl.h>
48 1.1.12.2 yamt #include <sys/ioctl.h>
49 1.1.12.2 yamt #include <sys/event.h>
50 1.1.12.2 yamt
51 1.1.12.2 yamt #include <machine/cpu.h>
52 1.1.12.2 yamt #include <machine/apmvar.h>
53 1.1.12.2 yamt
54 1.1.12.2 yamt #include <arm/xscale/pxa2x0reg.h>
55 1.1.12.2 yamt #include <arm/xscale/pxa2x0var.h>
56 1.1.12.2 yamt #include <arm/xscale/pxa2x0_apm.h>
57 1.1.12.2 yamt #include <arm/xscale/pxa2x0_gpio.h>
58 1.1.12.2 yamt
59 1.1.12.2 yamt #if defined(APMDEBUG)
60 1.1.12.2 yamt #define DPRINTF(x) printf x
61 1.1.12.2 yamt #else
62 1.1.12.2 yamt #define DPRINTF(x) /**/
63 1.1.12.2 yamt #endif
64 1.1.12.2 yamt
65 1.1.12.2 yamt #define APM_LOCK(sc) lockmgr(&(sc)->sc_lock, LK_EXCLUSIVE, NULL)
66 1.1.12.2 yamt #define APM_UNLOCK(sc) lockmgr(&(sc)->sc_lock, LK_RELEASE, NULL)
67 1.1.12.2 yamt
68 1.1.12.2 yamt #define APMUNIT(dev) (minor(dev)&0xf0)
69 1.1.12.2 yamt #define APMDEV(dev) (minor(dev)&0x0f)
70 1.1.12.2 yamt #define APMDEV_NORMAL 0
71 1.1.12.2 yamt #define APMDEV_CTL 8
72 1.1.12.2 yamt
73 1.1.12.2 yamt int apm_userstandbys;
74 1.1.12.2 yamt int apm_suspends;
75 1.1.12.2 yamt int apm_battlow;
76 1.1.12.2 yamt
77 1.1.12.2 yamt extern struct cfdriver zapm_cd;
78 1.1.12.2 yamt
79 1.1.12.2 yamt /* battery percentage at which we get verbose in our warnings. This
80 1.1.12.2 yamt value can be changed using sysctl(8), value machdep.apmwarn.
81 1.1.12.2 yamt Setting it to zero kills all warnings */
82 1.1.12.2 yamt int cpu_apmwarn = 10;
83 1.1.12.2 yamt
84 1.1.12.2 yamt void apm_power_print(struct pxa2x0_apm_softc *, struct apm_power_info *);
85 1.1.12.2 yamt void apm_power_info(struct pxa2x0_apm_softc *, struct apm_power_info *);
86 1.1.12.2 yamt void apm_suspend(struct pxa2x0_apm_softc *);
87 1.1.12.2 yamt void apm_resume(struct pxa2x0_apm_softc *);
88 1.1.12.2 yamt int apm_get_event(struct pxa2x0_apm_softc *, u_int *);
89 1.1.12.2 yamt int apm_handle_event(struct pxa2x0_apm_softc *, u_int);
90 1.1.12.2 yamt void apm_thread_create(void *);
91 1.1.12.2 yamt void apm_thread(void *);
92 1.1.12.2 yamt
93 1.1.12.2 yamt #if 0
94 1.1.12.2 yamt extern int perflevel;
95 1.1.12.2 yamt #endif
96 1.1.12.2 yamt
97 1.1.12.2 yamt int freq;
98 1.1.12.2 yamt void pxa2x0_setperf(int speed);
99 1.1.12.2 yamt int pxa2x0_cpuspeed(int *speed);
100 1.1.12.2 yamt
101 1.1.12.2 yamt int apm_record_event(struct pxa2x0_apm_softc *, u_int);
102 1.1.12.2 yamt #if 0
103 1.1.12.2 yamt void filt_apmrdetach(struct knote *kn);
104 1.1.12.2 yamt int filt_apmread(struct knote *kn, long hint);
105 1.1.12.2 yamt int apmkqfilter(dev_t dev, struct knote *kn);
106 1.1.12.2 yamt
107 1.1.12.2 yamt struct filterops apmread_filtops =
108 1.1.12.2 yamt { 1, NULL, filt_apmrdetach, filt_apmread};
109 1.1.12.2 yamt #endif
110 1.1.12.2 yamt
111 1.1.12.2 yamt /*
112 1.1.12.2 yamt * Flags to control kernel display
113 1.1.12.2 yamt * SCFLAG_NOPRINT: do not output APM power messages due to
114 1.1.12.2 yamt * a power change event.
115 1.1.12.2 yamt *
116 1.1.12.2 yamt * SCFLAG_PCTPRINT: do not output APM power messages due to
117 1.1.12.2 yamt * to a power change event unless the battery
118 1.1.12.2 yamt * percentage changes.
119 1.1.12.2 yamt */
120 1.1.12.2 yamt
121 1.1.12.2 yamt #define SCFLAG_NOPRINT 0x0008000
122 1.1.12.2 yamt #define SCFLAG_PCTPRINT 0x0004000
123 1.1.12.2 yamt #define SCFLAG_PRINT (SCFLAG_NOPRINT|SCFLAG_PCTPRINT)
124 1.1.12.2 yamt
125 1.1.12.2 yamt #define SCFLAG_OREAD (1 << 0)
126 1.1.12.2 yamt #define SCFLAG_OWRITE (1 << 1)
127 1.1.12.2 yamt #define SCFLAG_OPEN (SCFLAG_OREAD|SCFLAG_OWRITE)
128 1.1.12.2 yamt
129 1.1.12.2 yamt /* This structure must be kept in sync with pxa2x0_apm_asm.S. */
130 1.1.12.2 yamt struct pxa2x0_memcfg {
131 1.1.12.2 yamt /* SDRAM refresh */
132 1.1.12.2 yamt u_int32_t mdrefr_high; /* 0x00 */
133 1.1.12.2 yamt u_int32_t mdrefr_low; /* 0x04 */
134 1.1.12.2 yamt u_int32_t mdrefr_low2; /* 0x08 */
135 1.1.12.2 yamt /* Synchronous, static, or VLIO interfaces */
136 1.1.12.2 yamt u_int32_t msc_high[3]; /* 0x0c */
137 1.1.12.2 yamt u_int32_t msc_low[3]; /* 0x18 */
138 1.1.12.2 yamt /* XXX move up */
139 1.1.12.2 yamt u_int32_t mdrefr_91; /* 0x24 */
140 1.1.12.2 yamt };
141 1.1.12.2 yamt
142 1.1.12.2 yamt /* XXX */
143 1.1.12.2 yamt #define MDREFR_C3000 (MDREFR_K0DB2 | MDREFR_E1PIN | MDREFR_K1RUN | \
144 1.1.12.2 yamt MDREFR_K1DB2 | MDREFR_K2DB2 | MDREFR_APD)
145 1.1.12.2 yamt #define MSC0_HIGH \
146 1.1.12.2 yamt ( 7 << MSC_RRR_SHIFT << 16) | \
147 1.1.12.2 yamt (15 << MSC_RDN_SHIFT << 16) | \
148 1.1.12.2 yamt (15 << MSC_RDF_SHIFT << 16) | \
149 1.1.12.2 yamt (MSC_RT_NONBURST << 16) | \
150 1.1.12.2 yamt ( 2 << MSC_RRR_SHIFT) | \
151 1.1.12.2 yamt (13 << MSC_RDN_SHIFT) | \
152 1.1.12.2 yamt (13 << MSC_RDF_SHIFT) | \
153 1.1.12.2 yamt MSC_RBW /* PXA271 */ | \
154 1.1.12.2 yamt MSC_RT_NONBURST
155 1.1.12.2 yamt #define MSC1_HIGH \
156 1.1.12.2 yamt ( 7 << MSC_RRR_SHIFT << 16) | \
157 1.1.12.2 yamt (15 << MSC_RDN_SHIFT << 16) | \
158 1.1.12.2 yamt (15 << MSC_RDF_SHIFT << 16) | \
159 1.1.12.2 yamt (MSC_RT_VLIO << 16) | \
160 1.1.12.2 yamt ( 3 << MSC_RRR_SHIFT) | \
161 1.1.12.2 yamt ( 4 << MSC_RDN_SHIFT) | \
162 1.1.12.2 yamt (13 << MSC_RDF_SHIFT) | \
163 1.1.12.2 yamt MSC_RT_VLIO
164 1.1.12.2 yamt #define MSC2_HIGH \
165 1.1.12.2 yamt ( 7 << MSC_RRR_SHIFT << 16) | \
166 1.1.12.2 yamt (15 << MSC_RDN_SHIFT << 16) | \
167 1.1.12.2 yamt (15 << MSC_RDF_SHIFT << 16) | \
168 1.1.12.2 yamt (MSC_RT_NONBURST << 16) | \
169 1.1.12.2 yamt ( 3 << MSC_RRR_SHIFT) | \
170 1.1.12.2 yamt ( 4 << MSC_RDN_SHIFT) | \
171 1.1.12.2 yamt (13 << MSC_RDF_SHIFT) | \
172 1.1.12.2 yamt MSC_RT_VLIO
173 1.1.12.2 yamt #define MSC0_LOW \
174 1.1.12.2 yamt ( 7 << MSC_RRR_SHIFT << 16) | \
175 1.1.12.2 yamt (15 << MSC_RDN_SHIFT << 16) | \
176 1.1.12.2 yamt (15 << MSC_RDF_SHIFT << 16) | \
177 1.1.12.2 yamt (MSC_RT_NONBURST << 16) | \
178 1.1.12.2 yamt ( 1 << MSC_RRR_SHIFT) | \
179 1.1.12.2 yamt ( 8 << MSC_RDN_SHIFT) | \
180 1.1.12.2 yamt ( 8 << MSC_RDF_SHIFT) | \
181 1.1.12.2 yamt MSC_RBW /* PXA271 */ | \
182 1.1.12.2 yamt MSC_RT_NONBURST
183 1.1.12.2 yamt #define MSC1_LOW \
184 1.1.12.2 yamt ( 7 << MSC_RRR_SHIFT << 16) | \
185 1.1.12.2 yamt (15 << MSC_RDN_SHIFT << 16) | \
186 1.1.12.2 yamt (15 << MSC_RDF_SHIFT << 16) | \
187 1.1.12.2 yamt (MSC_RT_VLIO << 16) | \
188 1.1.12.2 yamt ( 1 << MSC_RRR_SHIFT) | \
189 1.1.12.2 yamt ( 2 << MSC_RDN_SHIFT) | \
190 1.1.12.2 yamt ( 6 << MSC_RDF_SHIFT) | \
191 1.1.12.2 yamt MSC_RT_VLIO
192 1.1.12.2 yamt #define MSC2_LOW \
193 1.1.12.2 yamt ( 7 << MSC_RRR_SHIFT << 16) | \
194 1.1.12.2 yamt (15 << MSC_RDN_SHIFT << 16) | \
195 1.1.12.2 yamt (15 << MSC_RDF_SHIFT << 16) | \
196 1.1.12.2 yamt (MSC_RT_NONBURST << 16) | \
197 1.1.12.2 yamt ( 1 << MSC_RRR_SHIFT) | \
198 1.1.12.2 yamt ( 2 << MSC_RDN_SHIFT) | \
199 1.1.12.2 yamt ( 6 << MSC_RDF_SHIFT) | \
200 1.1.12.2 yamt MSC_RT_VLIO
201 1.1.12.2 yamt struct pxa2x0_memcfg pxa2x0_memcfg = {
202 1.1.12.2 yamt (MDREFR_C3000 | 0x030),
203 1.1.12.2 yamt (MDREFR_C3000 | 0x00b),
204 1.1.12.2 yamt (MDREFR_C3000 | 0x017),
205 1.1.12.2 yamt { MSC0_HIGH, MSC1_HIGH, MSC2_HIGH },
206 1.1.12.2 yamt { MSC1_LOW, MSC1_LOW, MSC2_LOW },
207 1.1.12.2 yamt (MDREFR_C3000 | 0x013)
208 1.1.12.2 yamt };
209 1.1.12.2 yamt
210 1.1.12.2 yamt #define PI2C_RETRY_COUNT 10
211 1.1.12.2 yamt /* XXX varies depending on voltage regulator IC. */
212 1.1.12.2 yamt #define PI2C_VOLTAGE_LOW 0x13 /* 1.00V */
213 1.1.12.2 yamt #define PI2C_VOLTAGE_HIGH 0x1a /* 1.35V */
214 1.1.12.2 yamt
215 1.1.12.2 yamt void pxa2x0_pi2c_open(bus_space_tag_t, bus_space_handle_t);
216 1.1.12.2 yamt void pxa2x0_pi2c_close(bus_space_tag_t, bus_space_handle_t);
217 1.1.12.2 yamt int pxa2x0_pi2c_read(bus_space_tag_t, bus_space_handle_t, u_char, u_char *);
218 1.1.12.2 yamt int pxa2x0_pi2c_write(bus_space_tag_t, bus_space_handle_t, u_char, u_char);
219 1.1.12.2 yamt int pxa2x0_pi2c_getvoltage(bus_space_tag_t, bus_space_handle_t, u_char *);
220 1.1.12.2 yamt int pxa2x0_pi2c_setvoltage(bus_space_tag_t, bus_space_handle_t, u_char);
221 1.1.12.2 yamt #if 0
222 1.1.12.2 yamt void pxa2x0_pi2c_print(struct pxa2x0_apm_softc *);
223 1.1.12.2 yamt #endif
224 1.1.12.2 yamt
225 1.1.12.2 yamt /* XXX used in pxa2x0_apm_asm.S */
226 1.1.12.2 yamt bus_space_handle_t pxa2x0_gpio_ioh;
227 1.1.12.2 yamt bus_space_handle_t pxa2x0_clkman_ioh;
228 1.1.12.2 yamt bus_space_handle_t pxa2x0_memctl_ioh;
229 1.1.12.2 yamt
230 1.1.12.2 yamt /* pxa2x0_apm_asm.S */
231 1.1.12.2 yamt void pxa27x_run_mode(void);
232 1.1.12.2 yamt void pxa27x_fastbus_run_mode(int, u_int32_t);
233 1.1.12.2 yamt void pxa27x_frequency_change(int, int, struct pxa2x0_memcfg *);
234 1.1.12.2 yamt void pxa2x0_cpu_suspend(void);
235 1.1.12.2 yamt void pxa2x0_cpu_resume(void);
236 1.1.12.2 yamt void pxa27x_cpu_speed_high(void);
237 1.1.12.2 yamt void pxa27x_cpu_speed_low(void);
238 1.1.12.2 yamt void pxa27x_cpu_speed_91(void);
239 1.1.12.2 yamt void pxa27x_cpu_speed_208(void);
240 1.1.12.2 yamt
241 1.1.12.2 yamt void
242 1.1.12.2 yamt apm_power_print(struct pxa2x0_apm_softc *sc, struct apm_power_info *powerp)
243 1.1.12.2 yamt {
244 1.1.12.2 yamt
245 1.1.12.2 yamt if (powerp->battery_life != APM_BATT_LIFE_UNKNOWN)
246 1.1.12.2 yamt printf("%s: battery life expectancy %d%%\n",
247 1.1.12.2 yamt sc->sc_dev.dv_xname, powerp->battery_life);
248 1.1.12.2 yamt
249 1.1.12.2 yamt printf("%s: AC ", sc->sc_dev.dv_xname);
250 1.1.12.2 yamt switch (powerp->ac_state) {
251 1.1.12.2 yamt case APM_AC_OFF:
252 1.1.12.2 yamt printf("off,");
253 1.1.12.2 yamt break;
254 1.1.12.2 yamt case APM_AC_ON:
255 1.1.12.2 yamt printf("on,");
256 1.1.12.2 yamt break;
257 1.1.12.2 yamt case APM_AC_BACKUP:
258 1.1.12.2 yamt printf("backup power,");
259 1.1.12.2 yamt break;
260 1.1.12.2 yamt default:
261 1.1.12.2 yamt case APM_AC_UNKNOWN:
262 1.1.12.2 yamt printf("unknown,");
263 1.1.12.2 yamt break;
264 1.1.12.2 yamt }
265 1.1.12.2 yamt
266 1.1.12.2 yamt printf(" battery is ");
267 1.1.12.2 yamt switch (powerp->battery_state) {
268 1.1.12.2 yamt case APM_BATT_HIGH:
269 1.1.12.2 yamt printf("high");
270 1.1.12.2 yamt break;
271 1.1.12.2 yamt case APM_BATT_LOW:
272 1.1.12.2 yamt printf("low");
273 1.1.12.2 yamt break;
274 1.1.12.2 yamt case APM_BATT_CRITICAL:
275 1.1.12.2 yamt printf("CRITICAL");
276 1.1.12.2 yamt break;
277 1.1.12.2 yamt case APM_BATT_CHARGING:
278 1.1.12.2 yamt printf("charging");
279 1.1.12.2 yamt break;
280 1.1.12.2 yamt case APM_BATT_UNKNOWN:
281 1.1.12.2 yamt printf("unknown");
282 1.1.12.2 yamt break;
283 1.1.12.2 yamt default:
284 1.1.12.2 yamt printf("undecoded (%x)", powerp->battery_state);
285 1.1.12.2 yamt break;
286 1.1.12.2 yamt }
287 1.1.12.2 yamt
288 1.1.12.2 yamt printf("\n");
289 1.1.12.2 yamt }
290 1.1.12.2 yamt
291 1.1.12.2 yamt void
292 1.1.12.2 yamt apm_power_info(struct pxa2x0_apm_softc *sc,
293 1.1.12.2 yamt struct apm_power_info *power)
294 1.1.12.2 yamt {
295 1.1.12.2 yamt
296 1.1.12.2 yamt power->ac_state = APM_AC_UNKNOWN;
297 1.1.12.2 yamt power->battery_state = APM_BATT_UNKNOWN;
298 1.1.12.2 yamt power->battery_life = 0 /* APM_BATT_LIFE_UNKNOWN */;
299 1.1.12.2 yamt power->minutes_left = 0;
300 1.1.12.2 yamt
301 1.1.12.2 yamt if (sc->sc_power_info != NULL)
302 1.1.12.2 yamt sc->sc_power_info(sc, power);
303 1.1.12.2 yamt }
304 1.1.12.2 yamt
305 1.1.12.2 yamt void
306 1.1.12.2 yamt apm_suspend(struct pxa2x0_apm_softc *sc)
307 1.1.12.2 yamt {
308 1.1.12.2 yamt
309 1.1.12.2 yamt resettodr();
310 1.1.12.2 yamt
311 1.1.12.2 yamt dopowerhooks(PWR_SUSPEND);
312 1.1.12.2 yamt
313 1.1.12.2 yamt #if 0
314 1.1.12.2 yamt if (cold)
315 1.1.12.2 yamt vfs_syncwait(0);
316 1.1.12.2 yamt #endif
317 1.1.12.2 yamt
318 1.1.12.2 yamt if (sc->sc_suspend == NULL)
319 1.1.12.2 yamt pxa2x0_wakeup_config(PXA2X0_WAKEUP_ALL, 1);
320 1.1.12.2 yamt else
321 1.1.12.2 yamt sc->sc_suspend(sc);
322 1.1.12.2 yamt
323 1.1.12.2 yamt pxa2x0_apm_sleep(sc);
324 1.1.12.2 yamt }
325 1.1.12.2 yamt
326 1.1.12.2 yamt void
327 1.1.12.2 yamt apm_resume(struct pxa2x0_apm_softc *sc)
328 1.1.12.2 yamt {
329 1.1.12.2 yamt
330 1.1.12.2 yamt dopowerhooks(PWR_RESUME);
331 1.1.12.2 yamt
332 1.1.12.2 yamt inittodr(0);
333 1.1.12.2 yamt
334 1.1.12.2 yamt /*
335 1.1.12.2 yamt * Clear the OTG Peripheral hold after running the pxaudc and pxaohci
336 1.1.12.2 yamt * powerhooks to re-enable their operation. See 3.8.1.2
337 1.1.12.2 yamt */
338 1.1.12.2 yamt /* XXX ifdef NPXAUDC > 0 */
339 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSSR, PSSR_OTGPH);
340 1.1.12.2 yamt }
341 1.1.12.2 yamt
342 1.1.12.2 yamt #if 0
343 1.1.12.2 yamt int
344 1.1.12.2 yamt apm_get_event(struct pxa2x0_apm_softc *sc, u_int *typep)
345 1.1.12.2 yamt {
346 1.1.12.2 yamt
347 1.1.12.2 yamt if (sc->sc_get_event != NULL)
348 1.1.12.2 yamt return (sc->sc_get_event(sc, typep));
349 1.1.12.2 yamt
350 1.1.12.2 yamt *typep = APM_NOEVENT;
351 1.1.12.2 yamt return (1);
352 1.1.12.2 yamt }
353 1.1.12.2 yamt
354 1.1.12.2 yamt int
355 1.1.12.2 yamt apm_handle_event(struct pxa2x0_apm_softc *sc, u_int type)
356 1.1.12.2 yamt {
357 1.1.12.2 yamt struct apm_power_info power;
358 1.1.12.2 yamt int ret = 0;
359 1.1.12.2 yamt
360 1.1.12.2 yamt switch (type) {
361 1.1.12.2 yamt case APM_NOEVENT:
362 1.1.12.2 yamt ret = 1;
363 1.1.12.2 yamt break;
364 1.1.12.2 yamt case APM_CRIT_SUSPEND_REQ:
365 1.1.12.2 yamt DPRINTF(("suspend required immediately\n"));
366 1.1.12.2 yamt #if 0
367 1.1.12.2 yamt /* XXX apmd would make us suspend again after resume. */
368 1.1.12.2 yamt (void)apm_record_event(sc, type);
369 1.1.12.2 yamt #endif
370 1.1.12.2 yamt /*
371 1.1.12.2 yamt * We ignore APM_CRIT_RESUME and just suspend here as usual
372 1.1.12.2 yamt * to simplify the actual apm_get_event() implementation.
373 1.1.12.2 yamt */
374 1.1.12.2 yamt apm_suspends++;
375 1.1.12.2 yamt ret = 1;
376 1.1.12.2 yamt break;
377 1.1.12.2 yamt case APM_USER_SUSPEND_REQ:
378 1.1.12.2 yamt case APM_SUSPEND_REQ:
379 1.1.12.2 yamt DPRINTF(("suspend requested\n"));
380 1.1.12.2 yamt if (apm_record_event(sc, type)) {
381 1.1.12.2 yamt DPRINTF(("suspend ourselves\n"));
382 1.1.12.2 yamt apm_suspends++;
383 1.1.12.2 yamt }
384 1.1.12.2 yamt break;
385 1.1.12.2 yamt case APM_POWER_CHANGE:
386 1.1.12.2 yamt DPRINTF(("power status change\n"));
387 1.1.12.2 yamt apm_power_info(sc, &power);
388 1.1.12.2 yamt if (power.battery_life != APM_BATT_LIFE_UNKNOWN &&
389 1.1.12.2 yamt power.battery_life < cpu_apmwarn &&
390 1.1.12.2 yamt (sc->sc_flags & SCFLAG_PRINT) != SCFLAG_NOPRINT &&
391 1.1.12.2 yamt ((sc->sc_flags & SCFLAG_PRINT) != SCFLAG_PCTPRINT ||
392 1.1.12.2 yamt sc->sc_batt_life != power.battery_life)) {
393 1.1.12.2 yamt sc->sc_batt_life = power.battery_life;
394 1.1.12.2 yamt apm_power_print(sc, &power);
395 1.1.12.2 yamt }
396 1.1.12.2 yamt apm_record_event(sc, type);
397 1.1.12.2 yamt break;
398 1.1.12.2 yamt case APM_BATTERY_LOW:
399 1.1.12.2 yamt DPRINTF(("Battery low!\n"));
400 1.1.12.2 yamt apm_battlow++;
401 1.1.12.2 yamt apm_record_event(sc, type);
402 1.1.12.2 yamt break;
403 1.1.12.2 yamt default:
404 1.1.12.2 yamt DPRINTF(("apm_handle_event: unsupported event, code %d\n",
405 1.1.12.2 yamt type));
406 1.1.12.2 yamt }
407 1.1.12.2 yamt
408 1.1.12.2 yamt return (ret);
409 1.1.12.2 yamt }
410 1.1.12.2 yamt
411 1.1.12.2 yamt void
412 1.1.12.2 yamt apm_thread_create(void *v)
413 1.1.12.2 yamt {
414 1.1.12.2 yamt struct pxa2x0_apm_softc *sc = v;
415 1.1.12.2 yamt
416 1.1.12.2 yamt if (kthread_create(apm_thread, sc, &sc->sc_thread,
417 1.1.12.2 yamt "%s", sc->sc_dev.dv_xname)) {
418 1.1.12.2 yamt /* apm_disconnect(sc); */
419 1.1.12.2 yamt printf("%s: failed to create kernel thread, disabled",
420 1.1.12.2 yamt sc->sc_dev.dv_xname);
421 1.1.12.2 yamt }
422 1.1.12.2 yamt }
423 1.1.12.2 yamt
424 1.1.12.2 yamt void
425 1.1.12.2 yamt apm_thread(void *v)
426 1.1.12.2 yamt {
427 1.1.12.2 yamt struct pxa2x0_apm_softc *sc = v;
428 1.1.12.2 yamt u_int type;
429 1.1.12.2 yamt
430 1.1.12.2 yamt for (;;) {
431 1.1.12.2 yamt APM_LOCK(sc);
432 1.1.12.2 yamt
433 1.1.12.2 yamt while (1) {
434 1.1.12.2 yamt if (apm_get_event(sc, &type) != 0)
435 1.1.12.2 yamt break;
436 1.1.12.2 yamt if (apm_handle_event(sc, type) != 0)
437 1.1.12.2 yamt break;
438 1.1.12.2 yamt }
439 1.1.12.2 yamt if (apm_suspends || apm_userstandbys /* || apm_battlow*/) {
440 1.1.12.2 yamt apm_suspend(sc);
441 1.1.12.2 yamt apm_resume(sc);
442 1.1.12.2 yamt }
443 1.1.12.2 yamt apm_battlow = apm_suspends = apm_userstandbys = 0;
444 1.1.12.2 yamt
445 1.1.12.2 yamt APM_UNLOCK(sc);
446 1.1.12.2 yamt tsleep(&lbolt, PWAIT, "apmev", 0);
447 1.1.12.2 yamt }
448 1.1.12.2 yamt }
449 1.1.12.2 yamt
450 1.1.12.2 yamt int
451 1.1.12.2 yamt apmopen(dev_t dev, int flag, int mode, struct proc *p)
452 1.1.12.2 yamt {
453 1.1.12.2 yamt struct pxa2x0_apm_softc *sc;
454 1.1.12.2 yamt int error = 0;
455 1.1.12.2 yamt
456 1.1.12.2 yamt /* apm0 only */
457 1.1.12.2 yamt if (!zapm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
458 1.1.12.2 yamt !(sc = zapm_cd.cd_devs[APMUNIT(dev)]))
459 1.1.12.2 yamt return (ENXIO);
460 1.1.12.2 yamt
461 1.1.12.2 yamt DPRINTF(("apmopen: dev %d pid %d flag %x mode %x\n",
462 1.1.12.2 yamt APMDEV(dev), p->p_pid, flag, mode));
463 1.1.12.2 yamt
464 1.1.12.2 yamt switch (APMDEV(dev)) {
465 1.1.12.2 yamt case APMDEV_CTL:
466 1.1.12.2 yamt if (!(flag & FWRITE)) {
467 1.1.12.2 yamt error = EINVAL;
468 1.1.12.2 yamt break;
469 1.1.12.2 yamt }
470 1.1.12.2 yamt if (sc->sc_flags & SCFLAG_OWRITE) {
471 1.1.12.2 yamt error = EBUSY;
472 1.1.12.2 yamt break;
473 1.1.12.2 yamt }
474 1.1.12.2 yamt sc->sc_flags |= SCFLAG_OWRITE;
475 1.1.12.2 yamt break;
476 1.1.12.2 yamt case APMDEV_NORMAL:
477 1.1.12.2 yamt if (!(flag & FREAD) || (flag & FWRITE)) {
478 1.1.12.2 yamt error = EINVAL;
479 1.1.12.2 yamt break;
480 1.1.12.2 yamt }
481 1.1.12.2 yamt sc->sc_flags |= SCFLAG_OREAD;
482 1.1.12.2 yamt break;
483 1.1.12.2 yamt default:
484 1.1.12.2 yamt error = ENXIO;
485 1.1.12.2 yamt break;
486 1.1.12.2 yamt }
487 1.1.12.2 yamt return (error);
488 1.1.12.2 yamt }
489 1.1.12.2 yamt
490 1.1.12.2 yamt int
491 1.1.12.2 yamt apmclose(dev_t dev, int flag, int mode, struct proc *p)
492 1.1.12.2 yamt {
493 1.1.12.2 yamt struct pxa2x0_apm_softc *sc;
494 1.1.12.2 yamt
495 1.1.12.2 yamt /* apm0 only */
496 1.1.12.2 yamt if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
497 1.1.12.2 yamt !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
498 1.1.12.2 yamt return (ENXIO);
499 1.1.12.2 yamt
500 1.1.12.2 yamt DPRINTF(("apmclose: pid %d flag %x mode %x\n", p->p_pid, flag, mode));
501 1.1.12.2 yamt
502 1.1.12.2 yamt switch (APMDEV(dev)) {
503 1.1.12.2 yamt case APMDEV_CTL:
504 1.1.12.2 yamt sc->sc_flags &= ~SCFLAG_OWRITE;
505 1.1.12.2 yamt break;
506 1.1.12.2 yamt case APMDEV_NORMAL:
507 1.1.12.2 yamt sc->sc_flags &= ~SCFLAG_OREAD;
508 1.1.12.2 yamt break;
509 1.1.12.2 yamt }
510 1.1.12.2 yamt return (0);
511 1.1.12.2 yamt }
512 1.1.12.2 yamt
513 1.1.12.2 yamt int
514 1.1.12.2 yamt apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
515 1.1.12.2 yamt {
516 1.1.12.2 yamt struct pxa2x0_apm_softc *sc;
517 1.1.12.2 yamt struct apm_power_info *power;
518 1.1.12.2 yamt int error = 0;
519 1.1.12.2 yamt
520 1.1.12.2 yamt /* apm0 only */
521 1.1.12.2 yamt if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
522 1.1.12.2 yamt !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
523 1.1.12.2 yamt return (ENXIO);
524 1.1.12.2 yamt
525 1.1.12.2 yamt switch (cmd) {
526 1.1.12.2 yamt /* some ioctl names from linux */
527 1.1.12.2 yamt case APM_IOC_STANDBY:
528 1.1.12.2 yamt if ((flag & FWRITE) == 0)
529 1.1.12.2 yamt error = EBADF;
530 1.1.12.2 yamt else
531 1.1.12.2 yamt apm_userstandbys++;
532 1.1.12.2 yamt break;
533 1.1.12.2 yamt case APM_IOC_SUSPEND:
534 1.1.12.2 yamt if ((flag & FWRITE) == 0)
535 1.1.12.2 yamt error = EBADF;
536 1.1.12.2 yamt else
537 1.1.12.2 yamt apm_suspends++; /* XXX */
538 1.1.12.2 yamt break;
539 1.1.12.2 yamt case APM_IOC_PRN_CTL:
540 1.1.12.2 yamt if ((flag & FWRITE) == 0)
541 1.1.12.2 yamt error = EBADF;
542 1.1.12.2 yamt else {
543 1.1.12.2 yamt int flag = *(int *)data;
544 1.1.12.2 yamt DPRINTF(( "APM_IOC_PRN_CTL: %d\n", flag ));
545 1.1.12.2 yamt switch (flag) {
546 1.1.12.2 yamt case APM_PRINT_ON: /* enable printing */
547 1.1.12.2 yamt sc->sc_flags &= ~SCFLAG_PRINT;
548 1.1.12.2 yamt break;
549 1.1.12.2 yamt case APM_PRINT_OFF: /* disable printing */
550 1.1.12.2 yamt sc->sc_flags &= ~SCFLAG_PRINT;
551 1.1.12.2 yamt sc->sc_flags |= SCFLAG_NOPRINT;
552 1.1.12.2 yamt break;
553 1.1.12.2 yamt case APM_PRINT_PCT: /* disable some printing */
554 1.1.12.2 yamt sc->sc_flags &= ~SCFLAG_PRINT;
555 1.1.12.2 yamt sc->sc_flags |= SCFLAG_PCTPRINT;
556 1.1.12.2 yamt break;
557 1.1.12.2 yamt default:
558 1.1.12.2 yamt error = EINVAL;
559 1.1.12.2 yamt break;
560 1.1.12.2 yamt }
561 1.1.12.2 yamt }
562 1.1.12.2 yamt break;
563 1.1.12.2 yamt case APM_IOC_DEV_CTL:
564 1.1.12.2 yamt if ((flag & FWRITE) == 0)
565 1.1.12.2 yamt error = EBADF;
566 1.1.12.2 yamt break;
567 1.1.12.2 yamt case APM_IOC_GETPOWER:
568 1.1.12.2 yamt power = (struct apm_power_info *)data;
569 1.1.12.2 yamt apm_power_info(sc, power);
570 1.1.12.2 yamt break;
571 1.1.12.2 yamt
572 1.1.12.2 yamt default:
573 1.1.12.2 yamt error = ENOTTY;
574 1.1.12.2 yamt }
575 1.1.12.2 yamt
576 1.1.12.2 yamt return (error);
577 1.1.12.2 yamt }
578 1.1.12.2 yamt
579 1.1.12.2 yamt int
580 1.1.12.2 yamt apm_record_event(struct pxa2x0_apm_softc *sc, u_int type)
581 1.1.12.2 yamt {
582 1.1.12.2 yamt static int apm_evindex;
583 1.1.12.2 yamt
584 1.1.12.2 yamt /* skip if no user waiting */
585 1.1.12.2 yamt if ((sc->sc_flags & SCFLAG_OPEN) == 0)
586 1.1.12.2 yamt return (1);
587 1.1.12.2 yamt
588 1.1.12.2 yamt apm_evindex++;
589 1.1.12.2 yamt KNOTE(&sc->sc_note, APM_EVENT_COMPOSE(type, apm_evindex));
590 1.1.12.2 yamt
591 1.1.12.2 yamt return (0);
592 1.1.12.2 yamt }
593 1.1.12.2 yamt
594 1.1.12.2 yamt void
595 1.1.12.2 yamt filt_apmrdetach(struct knote *kn)
596 1.1.12.2 yamt {
597 1.1.12.2 yamt struct pxa2x0_apm_softc *sc =
598 1.1.12.2 yamt (struct pxa2x0_apm_softc *)kn->kn_hook;
599 1.1.12.2 yamt
600 1.1.12.2 yamt SLIST_REMOVE(&sc->sc_note, kn, knote, kn_selnext);
601 1.1.12.2 yamt }
602 1.1.12.2 yamt
603 1.1.12.2 yamt int
604 1.1.12.2 yamt filt_apmread(struct knote *kn, long hint)
605 1.1.12.2 yamt {
606 1.1.12.2 yamt /* XXX weird kqueue_scan() semantics */
607 1.1.12.2 yamt if (hint && !kn->kn_data)
608 1.1.12.2 yamt kn->kn_data = (int)hint;
609 1.1.12.2 yamt
610 1.1.12.2 yamt return (1);
611 1.1.12.2 yamt }
612 1.1.12.2 yamt
613 1.1.12.2 yamt int
614 1.1.12.2 yamt apmkqfilter(dev_t dev, struct knote *kn)
615 1.1.12.2 yamt {
616 1.1.12.2 yamt struct pxa2x0_apm_softc *sc;
617 1.1.12.2 yamt
618 1.1.12.2 yamt /* apm0 only */
619 1.1.12.2 yamt if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
620 1.1.12.2 yamt !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
621 1.1.12.2 yamt return (ENXIO);
622 1.1.12.2 yamt
623 1.1.12.2 yamt switch (kn->kn_filter) {
624 1.1.12.2 yamt case EVFILT_READ:
625 1.1.12.2 yamt kn->kn_fop = &apmread_filtops;
626 1.1.12.2 yamt break;
627 1.1.12.2 yamt default:
628 1.1.12.2 yamt return (1);
629 1.1.12.2 yamt }
630 1.1.12.2 yamt
631 1.1.12.2 yamt kn->kn_hook = (caddr_t)sc;
632 1.1.12.2 yamt SLIST_INSERT_HEAD(&sc->sc_note, kn, kn_selnext);
633 1.1.12.2 yamt
634 1.1.12.2 yamt return (0);
635 1.1.12.2 yamt }
636 1.1.12.2 yamt
637 1.1.12.2 yamt void
638 1.1.12.2 yamt pxa2x0_apm_attach_sub(struct pxa2x0_apm_softc *sc)
639 1.1.12.2 yamt {
640 1.1.12.2 yamt
641 1.1.12.2 yamt sc->sc_iot = &pxa2x0_bs_tag;
642 1.1.12.2 yamt
643 1.1.12.2 yamt if (bus_space_map(sc->sc_iot, PXA2X0_POWMAN_BASE,
644 1.1.12.2 yamt PXA2X0_POWMAN_SIZE, 0, &sc->sc_pm_ioh)) {
645 1.1.12.2 yamt printf("pxa2x0_apm_attach_sub: failed to map POWMAN\n");
646 1.1.12.2 yamt return;
647 1.1.12.2 yamt }
648 1.1.12.2 yamt
649 1.1.12.2 yamt lockinit(&sc->sc_lock, PWAIT, "apmlk", 0, 0);
650 1.1.12.2 yamt
651 1.1.12.2 yamt kthread_create_deferred(apm_thread_create, sc);
652 1.1.12.2 yamt
653 1.1.12.2 yamt printf("\n");
654 1.1.12.2 yamt
655 1.1.12.2 yamt if (bus_space_map(sc->sc_iot, PXA2X0_CLKMAN_BASE, PXA2X0_CLKMAN_SIZE,
656 1.1.12.2 yamt 0, &pxa2x0_clkman_ioh)) {
657 1.1.12.2 yamt printf("%s: failed to map CLKMAN\n", sc->sc_dev.dv_xname);
658 1.1.12.2 yamt return;
659 1.1.12.2 yamt }
660 1.1.12.2 yamt
661 1.1.12.2 yamt if (bus_space_map(sc->sc_iot, PXA2X0_MEMCTL_BASE, PXA2X0_MEMCTL_SIZE,
662 1.1.12.2 yamt 0, &pxa2x0_memctl_ioh)) {
663 1.1.12.2 yamt printf("%s: failed to map MEMCTL\n", sc->sc_dev.dv_xname);
664 1.1.12.2 yamt return;
665 1.1.12.2 yamt }
666 1.1.12.2 yamt sc->sc_memctl_ioh = pxa2x0_memctl_ioh;
667 1.1.12.2 yamt
668 1.1.12.2 yamt if (bus_space_map(sc->sc_iot, PXA2X0_GPIO_BASE, PXA2X0_GPIO_SIZE,
669 1.1.12.2 yamt 0, &pxa2x0_gpio_ioh)) {
670 1.1.12.2 yamt printf("%s: can't map GPIO\n", sc->sc_dev.dv_xname);
671 1.1.12.2 yamt return;
672 1.1.12.2 yamt }
673 1.1.12.2 yamt
674 1.1.12.2 yamt /* Clear all reset status flags. */
675 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_RCSR,
676 1.1.12.2 yamt RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR);
677 1.1.12.2 yamt }
678 1.1.12.2 yamt #endif /* 0 */
679 1.1.12.2 yamt
680 1.1.12.2 yamt void
681 1.1.12.2 yamt pxa2x0_wakeup_config(u_int wsrc, int enable)
682 1.1.12.2 yamt {
683 1.1.12.2 yamt struct pxa2x0_apm_softc *sc;
684 1.1.12.2 yamt u_int32_t prer;
685 1.1.12.2 yamt u_int32_t pfer;
686 1.1.12.2 yamt u_int32_t pkwr;
687 1.1.12.2 yamt
688 1.1.12.2 yamt if (zapm_cd.cd_ndevs < 1 || zapm_cd.cd_devs[0] == NULL)
689 1.1.12.2 yamt return;
690 1.1.12.2 yamt sc = device_private(zapm_cd.cd_devs[0]);
691 1.1.12.2 yamt
692 1.1.12.2 yamt prer = pfer = pkwr = 0;
693 1.1.12.2 yamt
694 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_POWERON) != 0) {
695 1.1.12.2 yamt prer |= (1<<0);
696 1.1.12.2 yamt pfer |= (1<<0);
697 1.1.12.2 yamt pkwr |= (1<<12); /* XXX */
698 1.1.12.2 yamt }
699 1.1.12.2 yamt
700 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_GPIORST) != 0)
701 1.1.12.2 yamt pfer |= (1<<1);
702 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_SD) != 0)
703 1.1.12.2 yamt prer |= (1<<9);
704 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_RC) != 0)
705 1.1.12.2 yamt prer |= (1<<13);
706 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_SYNC) != 0)
707 1.1.12.2 yamt pkwr |= (1<<1);
708 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_KEYNS0) != 0)
709 1.1.12.2 yamt prer |= (1<<12);
710 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_KEYNS1) != 0)
711 1.1.12.2 yamt pkwr |= (1<<2);
712 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_KEYNS2) != 0)
713 1.1.12.2 yamt pkwr |= (1<<9);
714 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_KEYNS3) != 0)
715 1.1.12.2 yamt pkwr |= (1<<3);
716 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_KEYNS4) != 0)
717 1.1.12.2 yamt pkwr |= (1<<4);
718 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_KEYNS5) != 0)
719 1.1.12.2 yamt pkwr |= (1<<6);
720 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_KEYNS6) != 0)
721 1.1.12.2 yamt pkwr |= (1<<7);
722 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_CF0) != 0)
723 1.1.12.2 yamt pkwr |= (1<<11);
724 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_CF1) != 0)
725 1.1.12.2 yamt pkwr |= (1<<10);
726 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_USBD) != 0)
727 1.1.12.2 yamt prer |= (1<<24);
728 1.1.12.2 yamt
729 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_LOCKSW) != 0) {
730 1.1.12.2 yamt prer |= (1<<15);
731 1.1.12.2 yamt pfer |= (1<<15);
732 1.1.12.2 yamt }
733 1.1.12.2 yamt
734 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_JACKIN) != 0) {
735 1.1.12.2 yamt prer |= (1<<23);
736 1.1.12.2 yamt pfer |= (1<<23);
737 1.1.12.2 yamt }
738 1.1.12.2 yamt
739 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_CHRGFULL) != 0)
740 1.1.12.2 yamt pkwr |= (1<<18);
741 1.1.12.2 yamt if ((wsrc & PXA2X0_WAKEUP_RTC) != 0)
742 1.1.12.2 yamt prer |= (1<<31);
743 1.1.12.2 yamt
744 1.1.12.2 yamt if (enable) {
745 1.1.12.2 yamt sc->sc_wakeon |= wsrc;
746 1.1.12.2 yamt prer |= bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh,
747 1.1.12.2 yamt POWMAN_PRER);
748 1.1.12.2 yamt pfer |= bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh,
749 1.1.12.2 yamt POWMAN_PFER);
750 1.1.12.2 yamt pkwr |= bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh,
751 1.1.12.2 yamt POWMAN_PKWR);
752 1.1.12.2 yamt } else {
753 1.1.12.2 yamt sc->sc_wakeon &= ~wsrc;
754 1.1.12.2 yamt prer = bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh,
755 1.1.12.2 yamt POWMAN_PRER) & ~prer;
756 1.1.12.2 yamt pfer = bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh,
757 1.1.12.2 yamt POWMAN_PFER) & ~pfer;
758 1.1.12.2 yamt pkwr = bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh,
759 1.1.12.2 yamt POWMAN_PKWR) & ~pkwr;
760 1.1.12.2 yamt }
761 1.1.12.2 yamt
762 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PKWR, pkwr);
763 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PRER, prer);
764 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PFER, pfer);
765 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PWER,
766 1.1.12.2 yamt prer | pfer);
767 1.1.12.2 yamt }
768 1.1.12.2 yamt
769 1.1.12.2 yamt u_int
770 1.1.12.2 yamt pxa2x0_wakeup_status(void)
771 1.1.12.2 yamt {
772 1.1.12.2 yamt struct pxa2x0_apm_softc *sc;
773 1.1.12.2 yamt u_int32_t rv;
774 1.1.12.2 yamt u_int wsrc;
775 1.1.12.2 yamt
776 1.1.12.2 yamt if (zapm_cd.cd_ndevs < 1 || zapm_cd.cd_devs[0] == NULL)
777 1.1.12.2 yamt return (0);
778 1.1.12.2 yamt
779 1.1.12.2 yamt sc = device_private(zapm_cd.cd_devs[0]);
780 1.1.12.2 yamt wsrc = 0;
781 1.1.12.2 yamt
782 1.1.12.2 yamt rv = bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PEDR);
783 1.1.12.2 yamt if ((rv & (1<<0)) != 0)
784 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_POWERON;
785 1.1.12.2 yamt if ((rv & (1<<1)) != 0)
786 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_GPIORST;
787 1.1.12.2 yamt if ((rv & (1<<9)) != 0)
788 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_SD;
789 1.1.12.2 yamt if ((rv & (1<<12)) != 0)
790 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_KEYNS0;
791 1.1.12.2 yamt if ((rv & (1<<13)) != 0)
792 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_RC;
793 1.1.12.2 yamt if ((rv & (1<<15)) != 0)
794 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_LOCKSW;
795 1.1.12.2 yamt if ((rv & (1<<23)) != 0)
796 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_JACKIN;
797 1.1.12.2 yamt if ((rv & (1<<24)) != 0)
798 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_USBD;
799 1.1.12.2 yamt if ((rv & (1<<31)) != 0)
800 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_RTC;
801 1.1.12.2 yamt
802 1.1.12.2 yamt rv = bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PKSR);
803 1.1.12.2 yamt if ((rv & (1<<1)) != 0)
804 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_SYNC;
805 1.1.12.2 yamt if ((rv & (1<<2)) != 0)
806 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_KEYNS1;
807 1.1.12.2 yamt if ((rv & (1<<9)) != 0)
808 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_KEYNS2;
809 1.1.12.2 yamt if ((rv & (1<<3)) != 0)
810 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_KEYNS3;
811 1.1.12.2 yamt if ((rv & (1<<4)) != 0)
812 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_KEYNS4;
813 1.1.12.2 yamt if ((rv & (1<<6)) != 0)
814 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_KEYNS5;
815 1.1.12.2 yamt if ((rv & (1<<7)) != 0)
816 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_KEYNS6;
817 1.1.12.2 yamt if ((rv & (1<<10)) != 0)
818 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_CF1;
819 1.1.12.2 yamt if ((rv & (1<<11)) != 0)
820 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_CF0;
821 1.1.12.2 yamt if ((rv & (1<<12)) != 0)
822 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_POWERON;
823 1.1.12.2 yamt if ((rv & (1<<18)) != 0)
824 1.1.12.2 yamt wsrc |= PXA2X0_WAKEUP_CHRGFULL;
825 1.1.12.2 yamt
826 1.1.12.2 yamt return (wsrc);
827 1.1.12.2 yamt }
828 1.1.12.2 yamt
829 1.1.12.2 yamt struct pxa2x0_sleep_data {
830 1.1.12.2 yamt /* OS timer registers */
831 1.1.12.2 yamt u_int32_t sd_osmr0, sd_osmr1, sd_osmr2, sd_osmr3;
832 1.1.12.2 yamt u_int32_t sd_oscr0;
833 1.1.12.2 yamt u_int32_t sd_osmr4, sd_osmr5;
834 1.1.12.2 yamt u_int32_t sd_oscr4;
835 1.1.12.2 yamt u_int32_t sd_omcr4, sd_omcr5;
836 1.1.12.2 yamt u_int32_t sd_oier;
837 1.1.12.2 yamt /* GPIO registers */
838 1.1.12.2 yamt u_int32_t sd_gpdr0, sd_gpdr1, sd_gpdr2, sd_gpdr3;
839 1.1.12.2 yamt u_int32_t sd_grer0, sd_grer1, sd_grer2, sd_grer3;
840 1.1.12.2 yamt u_int32_t sd_gfer0, sd_gfer1, sd_gfer2, sd_gfer3;
841 1.1.12.2 yamt u_int32_t sd_gafr0_l, sd_gafr1_l, sd_gafr2_l, sd_gafr3_l;
842 1.1.12.2 yamt u_int32_t sd_gafr0_u, sd_gafr1_u, sd_gafr2_u, sd_gafr3_u;
843 1.1.12.2 yamt u_int32_t sd_gplr0, sd_gplr1, sd_gplr2, sd_gplr3;
844 1.1.12.2 yamt /* Interrupt controller registers */
845 1.1.12.2 yamt u_int32_t sd_iclr;
846 1.1.12.2 yamt u_int32_t sd_icmr;
847 1.1.12.2 yamt u_int32_t sd_iccr;
848 1.1.12.2 yamt /* Memory controller registers */
849 1.1.12.2 yamt u_int32_t sd_mecr;
850 1.1.12.2 yamt u_int32_t sd_mcmem0, sd_mcmem1;
851 1.1.12.2 yamt u_int32_t sd_mcatt0, sd_mcatt1;
852 1.1.12.2 yamt u_int32_t sd_mcio0, sd_mcio1;
853 1.1.12.2 yamt /* Clocks manager registers */
854 1.1.12.2 yamt u_int32_t sd_cken;
855 1.1.12.2 yamt };
856 1.1.12.2 yamt
857 1.1.12.2 yamt void
858 1.1.12.2 yamt pxa2x0_apm_sleep(struct pxa2x0_apm_softc *sc)
859 1.1.12.2 yamt {
860 1.1.12.2 yamt struct pxa2x0_sleep_data sd;
861 1.1.12.2 yamt bus_space_handle_t ost_ioh;
862 1.1.12.2 yamt int save;
863 1.1.12.2 yamt u_int32_t rv;
864 1.1.12.2 yamt
865 1.1.12.2 yamt ost_ioh = (bus_space_handle_t)0;
866 1.1.12.2 yamt if (bus_space_map(sc->sc_iot, PXA2X0_OST_BASE, PXA2X0_OST_SIZE, 0,
867 1.1.12.2 yamt &ost_ioh)) {
868 1.1.12.2 yamt printf("pxa2x0_apm_sleep: can't map OST\n");
869 1.1.12.2 yamt goto out;
870 1.1.12.2 yamt }
871 1.1.12.2 yamt
872 1.1.12.2 yamt save = disable_interrupts(I32_bit|F32_bit);
873 1.1.12.2 yamt
874 1.1.12.2 yamt sd.sd_oscr0 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSCR0);
875 1.1.12.2 yamt sd.sd_oscr4 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSCR4);
876 1.1.12.2 yamt sd.sd_omcr4 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OMCR4);
877 1.1.12.2 yamt sd.sd_omcr5 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OMCR5);
878 1.1.12.2 yamt sd.sd_osmr0 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR0);
879 1.1.12.2 yamt sd.sd_osmr1 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR1);
880 1.1.12.2 yamt sd.sd_osmr2 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR2);
881 1.1.12.2 yamt sd.sd_osmr3 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR3);
882 1.1.12.2 yamt sd.sd_osmr4 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR4);
883 1.1.12.2 yamt sd.sd_osmr5 = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OSMR5);
884 1.1.12.2 yamt sd.sd_oier = bus_space_read_4(sc->sc_iot, ost_ioh, OST_OIER);
885 1.1.12.2 yamt
886 1.1.12.2 yamt /* Bring the PXA27x into 416MHz turbo mode. */
887 1.1.12.2 yamt if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X &&
888 1.1.12.2 yamt bus_space_read_4(sc->sc_iot, pxa2x0_clkman_ioh, CLKMAN_CCCR) !=
889 1.1.12.2 yamt (CCCR_A | CCCR_TURBO_X2 | CCCR_RUN_X16)) {
890 1.1.12.2 yamt #if 0
891 1.1.12.2 yamt pxa27x_cpu_speed_high();
892 1.1.12.2 yamt #else
893 1.1.12.2 yamt #define CLKCFG_T (1<<0) /* turbo */
894 1.1.12.2 yamt #define CLKCFG_F (1<<1) /* frequency change */
895 1.1.12.2 yamt #define CLKCFG_B (1<<3) /* fast-bus */
896 1.1.12.2 yamt pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 |
897 1.1.12.2 yamt CCCR_RUN_X16, CLKCFG_B | CLKCFG_F | CLKCFG_T,
898 1.1.12.2 yamt &pxa2x0_memcfg);
899 1.1.12.2 yamt #endif
900 1.1.12.2 yamt delay(500000); /* XXX */
901 1.1.12.2 yamt }
902 1.1.12.2 yamt
903 1.1.12.2 yamt suspend_again:
904 1.1.12.2 yamt /* Clear wake-up status. */
905 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PEDR,
906 1.1.12.2 yamt 0xffffffff);
907 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PKSR,
908 1.1.12.2 yamt 0xffffffff);
909 1.1.12.2 yamt
910 1.1.12.2 yamt /* XXX control battery charging in sleep mode. */
911 1.1.12.2 yamt
912 1.1.12.2 yamt /* XXX schedule RTC alarm to check the battery, or schedule
913 1.1.12.2 yamt XXX wake-up shortly before an already programmed alarm? */
914 1.1.12.2 yamt
915 1.1.12.2 yamt pxa27x_run_mode();
916 1.1.12.2 yamt #define MDREFR_LOW (MDREFR_C3000 | 0x00b)
917 1.1.12.2 yamt pxa27x_fastbus_run_mode(0, MDREFR_LOW);
918 1.1.12.2 yamt delay(1);
919 1.1.12.2 yamt #if 1
920 1.1.12.2 yamt pxa27x_cpu_speed_91();
921 1.1.12.2 yamt #else
922 1.1.12.2 yamt pxa27x_frequency_change(CCCR_TURBO_X1 | CCCR_RUN_X7, CLKCFG_F,
923 1.1.12.2 yamt &pxa2x0_memcfg);
924 1.1.12.2 yamt #endif
925 1.1.12.2 yamt pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh, PI2C_VOLTAGE_LOW);
926 1.1.12.2 yamt
927 1.1.12.2 yamt sd.sd_gpdr0 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR0);
928 1.1.12.2 yamt sd.sd_gpdr1 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR1);
929 1.1.12.2 yamt sd.sd_gpdr2 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR2);
930 1.1.12.2 yamt sd.sd_gpdr3 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR3);
931 1.1.12.2 yamt
932 1.1.12.2 yamt sd.sd_grer0 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER0);
933 1.1.12.2 yamt sd.sd_grer1 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER1);
934 1.1.12.2 yamt sd.sd_grer2 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER2);
935 1.1.12.2 yamt sd.sd_grer3 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER3);
936 1.1.12.2 yamt
937 1.1.12.2 yamt sd.sd_gfer0 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER0);
938 1.1.12.2 yamt sd.sd_gfer1 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER1);
939 1.1.12.2 yamt sd.sd_gfer2 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER2);
940 1.1.12.2 yamt sd.sd_gfer3 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER3);
941 1.1.12.2 yamt
942 1.1.12.2 yamt sd.sd_gafr0_l = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR0_L);
943 1.1.12.2 yamt sd.sd_gafr1_l = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR1_L);
944 1.1.12.2 yamt sd.sd_gafr2_l = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR2_L);
945 1.1.12.2 yamt sd.sd_gafr3_l = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR3_L);
946 1.1.12.2 yamt
947 1.1.12.2 yamt sd.sd_gafr0_u = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR0_U);
948 1.1.12.2 yamt sd.sd_gafr1_u = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR1_U);
949 1.1.12.2 yamt sd.sd_gafr2_u = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR2_U);
950 1.1.12.2 yamt sd.sd_gafr3_u = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR3_U);
951 1.1.12.2 yamt
952 1.1.12.2 yamt sd.sd_gplr0 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPLR0);
953 1.1.12.2 yamt sd.sd_gplr1 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPLR1);
954 1.1.12.2 yamt sd.sd_gplr2 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPLR2);
955 1.1.12.2 yamt sd.sd_gplr3 = bus_space_read_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPLR3);
956 1.1.12.2 yamt
957 1.1.12.2 yamt sd.sd_iclr = read_icu(INTCTL_ICLR);
958 1.1.12.2 yamt sd.sd_icmr = read_icu(INTCTL_ICMR);
959 1.1.12.2 yamt sd.sd_iccr = read_icu(INTCTL_ICCR);
960 1.1.12.2 yamt write_icu(INTCTL_ICMR, 0);
961 1.1.12.2 yamt
962 1.1.12.2 yamt sd.sd_mecr = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
963 1.1.12.2 yamt MEMCTL_MECR);
964 1.1.12.2 yamt sd.sd_mcmem0 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
965 1.1.12.2 yamt MEMCTL_MCMEM(0));
966 1.1.12.2 yamt sd.sd_mcmem1 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
967 1.1.12.2 yamt MEMCTL_MCMEM(1));
968 1.1.12.2 yamt sd.sd_mcatt0 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
969 1.1.12.2 yamt MEMCTL_MCATT(0));
970 1.1.12.2 yamt sd.sd_mcatt1 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
971 1.1.12.2 yamt MEMCTL_MCATT(1));
972 1.1.12.2 yamt sd.sd_mcio0 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
973 1.1.12.2 yamt MEMCTL_MCIO(0));
974 1.1.12.2 yamt sd.sd_mcio1 = bus_space_read_4(sc->sc_iot, pxa2x0_memctl_ioh,
975 1.1.12.2 yamt MEMCTL_MCIO(1));
976 1.1.12.2 yamt
977 1.1.12.2 yamt sd.sd_cken = bus_space_read_4(sc->sc_iot, pxa2x0_clkman_ioh,
978 1.1.12.2 yamt CLKMAN_CKEN);
979 1.1.12.2 yamt
980 1.1.12.2 yamt /*
981 1.1.12.2 yamt * Stop clocks to all units except to the memory controller, and
982 1.1.12.2 yamt * to the keypad controller if it is enabled as a wake-up source.
983 1.1.12.2 yamt */
984 1.1.12.2 yamt rv = CKEN_MEM;
985 1.1.12.2 yamt if ((sc->sc_wakeon & PXA2X0_WAKEUP_KEYNS_ALL) != 0)
986 1.1.12.2 yamt rv |= CKEN_KEY;
987 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_clkman_ioh, CLKMAN_CKEN, rv);
988 1.1.12.2 yamt
989 1.1.12.2 yamt /* Disable nRESET_OUT. */
990 1.1.12.2 yamt rv = bus_space_read_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSLR);
991 1.1.12.2 yamt #define PSLR_SL_ROD (1<<20)
992 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSLR,
993 1.1.12.2 yamt rv | PSLR_SL_ROD);
994 1.1.12.2 yamt
995 1.1.12.2 yamt /* Clear all reset status flags. */
996 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_RCSR,
997 1.1.12.2 yamt RCSR_GPR | RCSR_SMR | RCSR_WDR | RCSR_HWR);
998 1.1.12.2 yamt
999 1.1.12.2 yamt /* Stop 3/13MHz oscillator; do not float PCMCIA and chip-selects. */
1000 1.1.12.2 yamt rv = PCFR_OPDE;
1001 1.1.12.2 yamt if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X)
1002 1.1.12.2 yamt /* Enable nRESET_GPIO as a GPIO reset input. */
1003 1.1.12.2 yamt rv |= PCFR_GPR_EN;
1004 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PCFR, rv);
1005 1.1.12.2 yamt
1006 1.1.12.2 yamt /* XXX C3000 */
1007 1.1.12.2 yamt #define GPIO_G0_STROBE_BIT 0x0f800000
1008 1.1.12.2 yamt #define GPIO_G1_STROBE_BIT 0x00100000
1009 1.1.12.2 yamt #define GPIO_G2_STROBE_BIT 0x01000000
1010 1.1.12.2 yamt #define GPIO_G3_STROBE_BIT 0x00041880
1011 1.1.12.2 yamt #define GPIO_KEY_STROBE0 88
1012 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR0,
1013 1.1.12.2 yamt 0x00144018);
1014 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR1,
1015 1.1.12.2 yamt 0x00ef0000);
1016 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR2,
1017 1.1.12.2 yamt 0x0121c000);
1018 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR3,
1019 1.1.12.2 yamt 0x00600000);
1020 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR0,
1021 1.1.12.2 yamt 0x00144018 & ~GPIO_G0_STROBE_BIT);
1022 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR1,
1023 1.1.12.2 yamt 0x00ef0000 & ~GPIO_G1_STROBE_BIT);
1024 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR2,
1025 1.1.12.2 yamt 0x0121c000 & ~GPIO_G2_STROBE_BIT);
1026 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR3,
1027 1.1.12.2 yamt 0x00600000 & ~GPIO_G3_STROBE_BIT);
1028 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PGSR2,
1029 1.1.12.2 yamt (0x0121c000 & ~GPIO_G2_STROBE_BIT) |
1030 1.1.12.2 yamt GPIO_BIT(GPIO_KEY_STROBE0));
1031 1.1.12.2 yamt
1032 1.1.12.2 yamt /* C3000 */
1033 1.1.12.2 yamt #define GPIO_EXT_BUS_READY 18
1034 1.1.12.2 yamt pxa2x0_gpio_set_function(GPIO_EXT_BUS_READY, GPIO_SET | GPIO_OUT);
1035 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR0, 0xd01c4418);
1036 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR1, 0xfcefbd21);
1037 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR2, 0x13a5ffff);
1038 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR3, 0x01e3e10c);
1039 1.1.12.2 yamt
1040 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSPR,
1041 1.1.12.2 yamt (u_int32_t)&pxa2x0_cpu_resume - 0xc0200000 + 0xa0200000);
1042 1.1.12.2 yamt
1043 1.1.12.2 yamt pxa2x0_cpu_suspend();
1044 1.1.12.2 yamt
1045 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSPR, 0);
1046 1.1.12.2 yamt
1047 1.1.12.2 yamt pxa2x0_clkman_config(CKEN_SSP|CKEN_PWM0|CKEN_PWM1, 1);
1048 1.1.12.2 yamt pxa2x0_clkman_config(CKEN_KEY, 0);
1049 1.1.12.2 yamt
1050 1.1.12.2 yamt #if 1
1051 1.1.12.2 yamt /* Clear all GPIO interrupt sources. */
1052 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GEDR0, 0xffffffff);
1053 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GEDR1, 0xffffffff);
1054 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GEDR2, 0xffffffff);
1055 1.1.12.2 yamt #endif
1056 1.1.12.2 yamt
1057 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR0, sd.sd_gpdr0);
1058 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR1, sd.sd_gpdr1);
1059 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR2, sd.sd_gpdr2);
1060 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER0, sd.sd_grer0);
1061 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER1, sd.sd_grer1);
1062 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER2, sd.sd_grer2);
1063 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER0, sd.sd_gfer0);
1064 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER1, sd.sd_gfer1);
1065 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER2, sd.sd_gfer2);
1066 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR0_L, sd.sd_gafr0_l);
1067 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR1_L, sd.sd_gafr1_l);
1068 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR2_L, sd.sd_gafr2_l);
1069 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR0_U, sd.sd_gafr0_u);
1070 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR1_U, sd.sd_gafr1_u);
1071 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR2_U, sd.sd_gafr2_u);
1072 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPSR0, sd.sd_gplr0 &
1073 1.1.12.2 yamt sd.sd_gpdr0);
1074 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPSR1, sd.sd_gplr1 &
1075 1.1.12.2 yamt sd.sd_gpdr1);
1076 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPSR2, sd.sd_gplr2 &
1077 1.1.12.2 yamt sd.sd_gpdr2);
1078 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPCR0, ~sd.sd_gplr0 &
1079 1.1.12.2 yamt sd.sd_gpdr0);
1080 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPCR1, ~sd.sd_gplr1 &
1081 1.1.12.2 yamt sd.sd_gpdr1);
1082 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPCR2, ~sd.sd_gplr2 &
1083 1.1.12.2 yamt sd.sd_gpdr2);
1084 1.1.12.2 yamt
1085 1.1.12.2 yamt /* PXA27x */
1086 1.1.12.2 yamt #if 0
1087 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GEDR3, 0xffffffff);
1088 1.1.12.2 yamt #endif
1089 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPDR3, sd.sd_gpdr3);
1090 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GRER3, sd.sd_grer3);
1091 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GFER3, sd.sd_gfer3);
1092 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR3_L, sd.sd_gafr3_l);
1093 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GAFR3_U, sd.sd_gafr3_u);
1094 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPSR3, sd.sd_gplr3 &
1095 1.1.12.2 yamt sd.sd_gpdr3);
1096 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_gpio_ioh, GPIO_GPCR3, ~sd.sd_gplr3 &
1097 1.1.12.2 yamt sd.sd_gpdr3);
1098 1.1.12.2 yamt
1099 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MECR,
1100 1.1.12.2 yamt sd.sd_mecr);
1101 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCMEM(0),
1102 1.1.12.2 yamt sd.sd_mcmem0);
1103 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCMEM(1),
1104 1.1.12.2 yamt sd.sd_mcmem1);
1105 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCATT(0),
1106 1.1.12.2 yamt sd.sd_mcatt0);
1107 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCATT(1),
1108 1.1.12.2 yamt sd.sd_mcatt1);
1109 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCIO(0),
1110 1.1.12.2 yamt sd.sd_mcio0);
1111 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_memctl_ioh, MEMCTL_MCIO(1),
1112 1.1.12.2 yamt sd.sd_mcio1);
1113 1.1.12.2 yamt
1114 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, pxa2x0_clkman_ioh, CLKMAN_CKEN,
1115 1.1.12.2 yamt sd.sd_cken);
1116 1.1.12.2 yamt
1117 1.1.12.2 yamt write_icu(INTCTL_ICLR, sd.sd_iclr);
1118 1.1.12.2 yamt write_icu(INTCTL_ICCR, sd.sd_iccr);
1119 1.1.12.2 yamt write_icu(INTCTL_ICMR, sd.sd_icmr);
1120 1.1.12.2 yamt
1121 1.1.12.2 yamt if ((read_icu(INTCTL_ICIP) & 0x1) != 0)
1122 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PEDR, 0x1);
1123 1.1.12.2 yamt
1124 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR0, sd.sd_osmr0);
1125 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR1, sd.sd_osmr1);
1126 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR2, sd.sd_osmr2);
1127 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR3, sd.sd_osmr3);
1128 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR4, sd.sd_osmr4);
1129 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR5, sd.sd_osmr5);
1130 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, ost_ioh, OST_OMCR4, sd.sd_omcr4);
1131 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, ost_ioh, OST_OMCR5, sd.sd_omcr5);
1132 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSCR0, sd.sd_oscr0);
1133 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSCR4, sd.sd_oscr4);
1134 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, ost_ioh, OST_OIER, sd.sd_oier);
1135 1.1.12.2 yamt
1136 1.1.12.2 yamt pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh, PI2C_VOLTAGE_HIGH);
1137 1.1.12.2 yamt
1138 1.1.12.2 yamt /* Change to 208MHz run mode with fast-bus still disabled. */
1139 1.1.12.2 yamt pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 | CCCR_RUN_X16,
1140 1.1.12.2 yamt CLKCFG_F, &pxa2x0_memcfg);
1141 1.1.12.2 yamt delay(1); /* XXX is the delay long enough, and necessary at all? */
1142 1.1.12.2 yamt pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high);
1143 1.1.12.2 yamt
1144 1.1.12.2 yamt /* Change to 416MHz turbo mode with fast-bus enabled. */
1145 1.1.12.2 yamt pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 | CCCR_RUN_X16,
1146 1.1.12.2 yamt CLKCFG_B | CLKCFG_F | CLKCFG_T, &pxa2x0_memcfg);
1147 1.1.12.2 yamt
1148 1.1.12.2 yamt if (sc->sc_resume != NULL) {
1149 1.1.12.2 yamt if (!sc->sc_resume(sc))
1150 1.1.12.2 yamt goto suspend_again;
1151 1.1.12.2 yamt }
1152 1.1.12.2 yamt
1153 1.1.12.2 yamt /*
1154 1.1.12.2 yamt * Allow immediate entry into deep-sleep mode if power fails.
1155 1.1.12.2 yamt * Resume from immediate deep-sleep is not implemented yet.
1156 1.1.12.2 yamt */
1157 1.1.12.2 yamt bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PMCR, 0);
1158 1.1.12.2 yamt
1159 1.1.12.2 yamt
1160 1.1.12.2 yamt restore_interrupts(save);
1161 1.1.12.2 yamt
1162 1.1.12.2 yamt #if 0
1163 1.1.12.2 yamt pxa2x0_setperf(perflevel);
1164 1.1.12.2 yamt #endif
1165 1.1.12.2 yamt
1166 1.1.12.2 yamt out:
1167 1.1.12.2 yamt if (ost_ioh != (bus_space_handle_t)0)
1168 1.1.12.2 yamt bus_space_unmap(sc->sc_iot, ost_ioh, PXA2X0_OST_SIZE);
1169 1.1.12.2 yamt }
1170 1.1.12.2 yamt
1171 1.1.12.2 yamt void
1172 1.1.12.2 yamt pxa2x0_pi2c_open(bus_space_tag_t iot, bus_space_handle_t ioh)
1173 1.1.12.2 yamt {
1174 1.1.12.2 yamt u_int32_t rv;
1175 1.1.12.2 yamt
1176 1.1.12.2 yamt /* Enable the I2C unit, and disable automatic voltage change. */
1177 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PCFR);
1178 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PCFR, rv | PCFR_PI2C_EN);
1179 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PCFR);
1180 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PCFR, rv & ~PCFR_FVC);
1181 1.1.12.2 yamt delay(1);
1182 1.1.12.2 yamt
1183 1.1.12.2 yamt /* Enable the clock to the power manager I2C unit. */
1184 1.1.12.2 yamt pxa2x0_clkman_config(CKEN_PI2C, 1);
1185 1.1.12.2 yamt delay(1);
1186 1.1.12.2 yamt }
1187 1.1.12.2 yamt
1188 1.1.12.2 yamt void
1189 1.1.12.2 yamt pxa2x0_pi2c_close(bus_space_tag_t iot, bus_space_handle_t ioh)
1190 1.1.12.2 yamt {
1191 1.1.12.2 yamt u_int32_t rv;
1192 1.1.12.2 yamt
1193 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_UR);
1194 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PISAR, 0);
1195 1.1.12.2 yamt delay(1);
1196 1.1.12.2 yamt
1197 1.1.12.2 yamt /* Disable the clock to the power manager I2C unit. */
1198 1.1.12.2 yamt pxa2x0_clkman_config(CKEN_PI2C, 0);
1199 1.1.12.2 yamt delay(1);
1200 1.1.12.2 yamt
1201 1.1.12.2 yamt /* Disable the I2C unit, and disable automatic voltage change. */
1202 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PCFR);
1203 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PCFR,
1204 1.1.12.2 yamt rv & ~(PCFR_PI2C_EN | PCFR_FVC));
1205 1.1.12.2 yamt delay(1);
1206 1.1.12.2 yamt }
1207 1.1.12.2 yamt
1208 1.1.12.2 yamt int
1209 1.1.12.2 yamt pxa2x0_pi2c_read(bus_space_tag_t iot, bus_space_handle_t ioh,
1210 1.1.12.2 yamt u_char slave, u_char *valuep)
1211 1.1.12.2 yamt {
1212 1.1.12.2 yamt u_int32_t rv;
1213 1.1.12.2 yamt int timeout;
1214 1.1.12.2 yamt int tries = PI2C_RETRY_COUNT;
1215 1.1.12.2 yamt
1216 1.1.12.2 yamt retry:
1217 1.1.12.2 yamt
1218 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_UR);
1219 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PISAR, 0x00);
1220 1.1.12.2 yamt delay(1);
1221 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_IUE | PICR_SCLE);
1222 1.1.12.2 yamt
1223 1.1.12.2 yamt /* Write slave device address. */
1224 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PIDBR, (slave<<1) | 0x1);
1225 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
1226 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, rv | PICR_START);
1227 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
1228 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, rv & ~PICR_STOP);
1229 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
1230 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, rv | PICR_TB);
1231 1.1.12.2 yamt
1232 1.1.12.2 yamt timeout = 10000;
1233 1.1.12.2 yamt while ((bus_space_read_4(iot, ioh, POWMAN_PISR) & PISR_ITE) == 0) {
1234 1.1.12.2 yamt if (timeout-- == 0) {
1235 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_ITE);
1236 1.1.12.2 yamt goto err;
1237 1.1.12.2 yamt }
1238 1.1.12.2 yamt delay(1);
1239 1.1.12.2 yamt }
1240 1.1.12.2 yamt
1241 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_ITE);
1242 1.1.12.2 yamt
1243 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
1244 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, rv & ~PICR_START);
1245 1.1.12.2 yamt
1246 1.1.12.2 yamt /* Read data value. */
1247 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
1248 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, rv |
1249 1.1.12.2 yamt (PICR_STOP | PICR_ACKNAK));
1250 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
1251 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, rv | PICR_TB);
1252 1.1.12.2 yamt
1253 1.1.12.2 yamt timeout = 10000;
1254 1.1.12.2 yamt while ((bus_space_read_4(iot, ioh, POWMAN_PISR) & PISR_IRF) == 0) {
1255 1.1.12.2 yamt if (timeout-- == 0) {
1256 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_IRF);
1257 1.1.12.2 yamt goto err;
1258 1.1.12.2 yamt }
1259 1.1.12.2 yamt delay(1);
1260 1.1.12.2 yamt }
1261 1.1.12.2 yamt
1262 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_IRF);
1263 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PIDBR);
1264 1.1.12.2 yamt *valuep = (u_char)rv;
1265 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
1266 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, rv &
1267 1.1.12.2 yamt ~(PICR_STOP | PICR_ACKNAK));
1268 1.1.12.2 yamt
1269 1.1.12.2 yamt return (0);
1270 1.1.12.2 yamt err:
1271 1.1.12.2 yamt if (tries-- >= 0)
1272 1.1.12.2 yamt goto retry;
1273 1.1.12.2 yamt
1274 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_UR);
1275 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PISAR, 0x00);
1276 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_IUE | PICR_SCLE);
1277 1.1.12.2 yamt
1278 1.1.12.2 yamt return (-EIO);
1279 1.1.12.2 yamt }
1280 1.1.12.2 yamt
1281 1.1.12.2 yamt int
1282 1.1.12.2 yamt pxa2x0_pi2c_write(bus_space_tag_t iot, bus_space_handle_t ioh,
1283 1.1.12.2 yamt u_char slave, u_char value)
1284 1.1.12.2 yamt {
1285 1.1.12.2 yamt u_int32_t rv;
1286 1.1.12.2 yamt int timeout;
1287 1.1.12.2 yamt int tries = PI2C_RETRY_COUNT;
1288 1.1.12.2 yamt
1289 1.1.12.2 yamt retry:
1290 1.1.12.2 yamt
1291 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_UR);
1292 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PISAR, 0x00);
1293 1.1.12.2 yamt delay(1);
1294 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_IUE | PICR_SCLE);
1295 1.1.12.2 yamt
1296 1.1.12.2 yamt /* Write slave device address. */
1297 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PIDBR, (slave<<1));
1298 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
1299 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, rv | PICR_START);
1300 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
1301 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, rv & ~PICR_STOP);
1302 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
1303 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, rv | PICR_TB);
1304 1.1.12.2 yamt
1305 1.1.12.2 yamt timeout = 10000;
1306 1.1.12.2 yamt while ((bus_space_read_4(iot, ioh, POWMAN_PISR) & PISR_ITE) == 0) {
1307 1.1.12.2 yamt if (timeout-- == 0) {
1308 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_ITE);
1309 1.1.12.2 yamt goto err;
1310 1.1.12.2 yamt }
1311 1.1.12.2 yamt delay(1);
1312 1.1.12.2 yamt }
1313 1.1.12.2 yamt if ((bus_space_read_4(iot, ioh, POWMAN_PISR) & PISR_ACKNAK) != 0)
1314 1.1.12.2 yamt goto err;
1315 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_ITE);
1316 1.1.12.2 yamt
1317 1.1.12.2 yamt /* Write data. */
1318 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
1319 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, rv & ~PICR_START);
1320 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
1321 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, rv | PICR_STOP);
1322 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PIDBR, value);
1323 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
1324 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, rv | PICR_TB);
1325 1.1.12.2 yamt
1326 1.1.12.2 yamt timeout = 10000;
1327 1.1.12.2 yamt while ((bus_space_read_4(iot, ioh, POWMAN_PISR) & PISR_ITE) == 0) {
1328 1.1.12.2 yamt if (timeout-- == 0) {
1329 1.1.12.2 yamt #if 0
1330 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_ITE);
1331 1.1.12.2 yamt #endif
1332 1.1.12.2 yamt goto err;
1333 1.1.12.2 yamt }
1334 1.1.12.2 yamt delay(1);
1335 1.1.12.2 yamt }
1336 1.1.12.2 yamt if ((bus_space_read_4(iot, ioh, POWMAN_PISR) & PISR_ACKNAK) != 0)
1337 1.1.12.2 yamt goto err;
1338 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_ITE);
1339 1.1.12.2 yamt
1340 1.1.12.2 yamt rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
1341 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, rv & ~PICR_STOP);
1342 1.1.12.2 yamt
1343 1.1.12.2 yamt return (0);
1344 1.1.12.2 yamt err:
1345 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_ITE);
1346 1.1.12.2 yamt if (tries-- >= 0)
1347 1.1.12.2 yamt goto retry;
1348 1.1.12.2 yamt
1349 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_UR);
1350 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PISAR, 0x00);
1351 1.1.12.2 yamt bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_IUE | PICR_SCLE);
1352 1.1.12.2 yamt
1353 1.1.12.2 yamt return (-EIO);
1354 1.1.12.2 yamt }
1355 1.1.12.2 yamt
1356 1.1.12.2 yamt int
1357 1.1.12.2 yamt pxa2x0_pi2c_getvoltage(bus_space_tag_t iot, bus_space_handle_t ioh,
1358 1.1.12.2 yamt u_char *valuep)
1359 1.1.12.2 yamt {
1360 1.1.12.2 yamt int res;
1361 1.1.12.2 yamt
1362 1.1.12.2 yamt pxa2x0_pi2c_open(iot, ioh);
1363 1.1.12.2 yamt res = pxa2x0_pi2c_read(iot, ioh, 0x0c, valuep);
1364 1.1.12.2 yamt pxa2x0_pi2c_close(iot, ioh);
1365 1.1.12.2 yamt return (res);
1366 1.1.12.2 yamt }
1367 1.1.12.2 yamt
1368 1.1.12.2 yamt int
1369 1.1.12.2 yamt pxa2x0_pi2c_setvoltage(bus_space_tag_t iot, bus_space_handle_t ioh,
1370 1.1.12.2 yamt u_char value)
1371 1.1.12.2 yamt {
1372 1.1.12.2 yamt int res;
1373 1.1.12.2 yamt
1374 1.1.12.2 yamt pxa2x0_pi2c_open(iot, ioh);
1375 1.1.12.2 yamt res = pxa2x0_pi2c_write(iot, ioh, 0x0c, value);
1376 1.1.12.2 yamt pxa2x0_pi2c_close(iot, ioh);
1377 1.1.12.2 yamt return (res);
1378 1.1.12.2 yamt }
1379 1.1.12.2 yamt
1380 1.1.12.2 yamt #if 0
1381 1.1.12.2 yamt void
1382 1.1.12.2 yamt pxa2x0_pi2c_print(struct pxa2x0_apm_softc *sc)
1383 1.1.12.2 yamt {
1384 1.1.12.2 yamt u_char value = 0;
1385 1.1.12.2 yamt
1386 1.1.12.2 yamt (void)pxa2x0_pi2c_getvoltage(sc->sc_iot, sc->sc_pm_ioh, &value);
1387 1.1.12.2 yamt printf("xscale core voltage: %s\n", value == PI2C_VOLTAGE_HIGH ?
1388 1.1.12.2 yamt "high" : (value == PI2C_VOLTAGE_LOW ? "low" : "unknown"));
1389 1.1.12.2 yamt }
1390 1.1.12.2 yamt #endif
1391 1.1.12.2 yamt
1392 1.1.12.2 yamt struct {
1393 1.1.12.2 yamt int maxspeed;
1394 1.1.12.2 yamt int numspeeds;
1395 1.1.12.2 yamt int hz [6];
1396 1.1.12.2 yamt int rate [6]; /* could this be simplfied by not having 100% in table? */
1397 1.1.12.2 yamt }
1398 1.1.12.2 yamt speedtables[] = {
1399 1.1.12.2 yamt { 91, 1, { 91 }, { 100 }},
1400 1.1.12.2 yamt { 208, 2, { 91, 208}, {50, 100}},
1401 1.1.12.2 yamt { 416, 3, { 91, 208, 416}, {25, 50, 100}},
1402 1.1.12.2 yamt { 520, 4, { 91, 208, 416, 520}, {18, 40 ,80, 100}},
1403 1.1.12.2 yamt { 624, 5, { 91, 208, 416, 520, 624}, {15, 34, 67, 82, 100}},
1404 1.1.12.2 yamt { 0 }
1405 1.1.12.2 yamt };
1406 1.1.12.2 yamt int xscale_maxspeed = 416; /* XXX */
1407 1.1.12.2 yamt
1408 1.1.12.2 yamt int speed_to_freq(int speed);
1409 1.1.12.2 yamt
1410 1.1.12.2 yamt int
1411 1.1.12.2 yamt speed_to_freq(int speed)
1412 1.1.12.2 yamt {
1413 1.1.12.2 yamt int i, j;
1414 1.1.12.2 yamt int newspeed = 0;
1415 1.1.12.2 yamt int numspeeds;
1416 1.1.12.2 yamt for (i = 0; speedtables[i].maxspeed != 0; i++) {
1417 1.1.12.2 yamt if (speedtables[i].maxspeed != xscale_maxspeed)
1418 1.1.12.2 yamt continue;
1419 1.1.12.2 yamt
1420 1.1.12.2 yamt if (speed <= speedtables[i].rate[0]) {
1421 1.1.12.2 yamt return speedtables[i].hz[0];
1422 1.1.12.2 yamt
1423 1.1.12.2 yamt }
1424 1.1.12.2 yamt numspeeds = speedtables[i].numspeeds;
1425 1.1.12.2 yamt if (speed == speedtables[i].rate[numspeeds-1]) {
1426 1.1.12.2 yamt return speedtables[i].hz[numspeeds-1];
1427 1.1.12.2 yamt }
1428 1.1.12.2 yamt for (j = 1; j < numspeeds; j++) {
1429 1.1.12.2 yamt if (speed < speedtables[i].rate[j]) {
1430 1.1.12.2 yamt return speedtables[i].hz[j-1];
1431 1.1.12.2 yamt }
1432 1.1.12.2 yamt }
1433 1.1.12.2 yamt }
1434 1.1.12.2 yamt return newspeed;
1435 1.1.12.2 yamt }
1436 1.1.12.2 yamt
1437 1.1.12.2 yamt
1438 1.1.12.2 yamt void
1439 1.1.12.2 yamt pxa2x0_setperf(int speed)
1440 1.1.12.2 yamt {
1441 1.1.12.2 yamt struct pxa2x0_apm_softc *sc;
1442 1.1.12.2 yamt int s;
1443 1.1.12.2 yamt int newfreq;
1444 1.1.12.2 yamt
1445 1.1.12.2 yamt sc = device_private(zapm_cd.cd_devs[0]);
1446 1.1.12.2 yamt
1447 1.1.12.2 yamt newfreq = speed_to_freq(speed);
1448 1.1.12.2 yamt
1449 1.1.12.2 yamt if (newfreq == 0) {
1450 1.1.12.2 yamt printf("bogus new frequency 0 for rate %d maxclock %d\n",
1451 1.1.12.2 yamt speed, xscale_maxspeed);
1452 1.1.12.2 yamt }
1453 1.1.12.2 yamt
1454 1.1.12.2 yamt DPRINTF(("setperf speed %d newfreq %d, maxfreq %d\n",
1455 1.1.12.2 yamt speed, newfreq, xscale_maxspeed));
1456 1.1.12.2 yamt
1457 1.1.12.2 yamt s = disable_interrupts(I32_bit|F32_bit);
1458 1.1.12.2 yamt
1459 1.1.12.2 yamt if (newfreq == 91) {
1460 1.1.12.2 yamt if (freq > 91) {
1461 1.1.12.2 yamt pxa27x_run_mode();
1462 1.1.12.2 yamt pxa27x_fastbus_run_mode(0, MDREFR_LOW);
1463 1.1.12.2 yamt pxa27x_cpu_speed_91();
1464 1.1.12.2 yamt pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh,
1465 1.1.12.2 yamt PI2C_VOLTAGE_LOW);
1466 1.1.12.2 yamt freq = 91;
1467 1.1.12.2 yamt }
1468 1.1.12.2 yamt } else if (newfreq == 208) {
1469 1.1.12.2 yamt if (freq < 208)
1470 1.1.12.2 yamt pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh,
1471 1.1.12.2 yamt PI2C_VOLTAGE_HIGH);
1472 1.1.12.2 yamt if (freq != 208) {
1473 1.1.12.2 yamt pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 |
1474 1.1.12.2 yamt CCCR_RUN_X16, CLKCFG_F, &pxa2x0_memcfg);
1475 1.1.12.2 yamt pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high);
1476 1.1.12.2 yamt freq = 208;
1477 1.1.12.2 yamt }
1478 1.1.12.2 yamt } else if (newfreq == 416) {
1479 1.1.12.2 yamt if (freq < 208) {
1480 1.1.12.2 yamt pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh,
1481 1.1.12.2 yamt PI2C_VOLTAGE_HIGH);
1482 1.1.12.2 yamt pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 |
1483 1.1.12.2 yamt CCCR_RUN_X16, CLKCFG_F, &pxa2x0_memcfg);
1484 1.1.12.2 yamt pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high);
1485 1.1.12.2 yamt }
1486 1.1.12.2 yamt if (freq != 416) {
1487 1.1.12.2 yamt pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 |
1488 1.1.12.2 yamt CCCR_RUN_X16, CLKCFG_B | CLKCFG_F | CLKCFG_T,
1489 1.1.12.2 yamt &pxa2x0_memcfg);
1490 1.1.12.2 yamt freq = 416;
1491 1.1.12.2 yamt }
1492 1.1.12.2 yamt } else if (newfreq == 520) {
1493 1.1.12.2 yamt if (freq < 208) {
1494 1.1.12.2 yamt pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh,
1495 1.1.12.2 yamt PI2C_VOLTAGE_HIGH);
1496 1.1.12.2 yamt pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 |
1497 1.1.12.2 yamt CCCR_RUN_X16, CLKCFG_F, &pxa2x0_memcfg);
1498 1.1.12.2 yamt pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high);
1499 1.1.12.2 yamt }
1500 1.1.12.2 yamt if (freq != 520) {
1501 1.1.12.2 yamt pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X25 |
1502 1.1.12.2 yamt CCCR_RUN_X16, CLKCFG_B | CLKCFG_F | CLKCFG_T,
1503 1.1.12.2 yamt &pxa2x0_memcfg);
1504 1.1.12.2 yamt freq = 520;
1505 1.1.12.2 yamt }
1506 1.1.12.2 yamt } else if (newfreq == 624) {
1507 1.1.12.2 yamt if (freq < 208) {
1508 1.1.12.2 yamt pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh,
1509 1.1.12.2 yamt PI2C_VOLTAGE_HIGH);
1510 1.1.12.2 yamt pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 |
1511 1.1.12.2 yamt CCCR_RUN_X16, CLKCFG_F, &pxa2x0_memcfg);
1512 1.1.12.2 yamt pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high);
1513 1.1.12.2 yamt }
1514 1.1.12.2 yamt if (freq != 624) {
1515 1.1.12.2 yamt pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X3 |
1516 1.1.12.2 yamt CCCR_RUN_X16, CLKCFG_B | CLKCFG_F | CLKCFG_T,
1517 1.1.12.2 yamt &pxa2x0_memcfg);
1518 1.1.12.2 yamt freq = 624;
1519 1.1.12.2 yamt }
1520 1.1.12.2 yamt }
1521 1.1.12.2 yamt
1522 1.1.12.2 yamt restore_interrupts(s);
1523 1.1.12.2 yamt }
1524 1.1.12.2 yamt
1525 1.1.12.2 yamt int
1526 1.1.12.2 yamt pxa2x0_cpuspeed(int *freqp)
1527 1.1.12.2 yamt {
1528 1.1.12.2 yamt *freqp = freq;
1529 1.1.12.2 yamt return 0;
1530 1.1.12.2 yamt }
1531 1.1.12.2 yamt
1532 1.1.12.2 yamt void pxa2x0_maxspeed(int *speedp);
1533 1.1.12.2 yamt
1534 1.1.12.2 yamt void
1535 1.1.12.2 yamt pxa2x0_maxspeed(int *speedp)
1536 1.1.12.2 yamt {
1537 1.1.12.2 yamt /* XXX assumes a pxa270 */
1538 1.1.12.2 yamt
1539 1.1.12.2 yamt if (*speedp < 207) {
1540 1.1.12.2 yamt *speedp = 91;
1541 1.1.12.2 yamt } else if (*speedp < 415) {
1542 1.1.12.2 yamt *speedp = 208;
1543 1.1.12.2 yamt } else if (*speedp < 519) {
1544 1.1.12.2 yamt *speedp = 416;
1545 1.1.12.2 yamt } else if (*speedp < 624) {
1546 1.1.12.2 yamt *speedp = 520;
1547 1.1.12.2 yamt #if 0
1548 1.1.12.2 yamt } else if (*speedp < 651) {
1549 1.1.12.2 yamt *speedp = 624;
1550 1.1.12.2 yamt #endif
1551 1.1.12.2 yamt } else {
1552 1.1.12.2 yamt *speedp = 520; /* hope this is safe. */
1553 1.1.12.2 yamt }
1554 1.1.12.2 yamt xscale_maxspeed = *speedp;
1555 1.1.12.2 yamt #if 0
1556 1.1.12.2 yamt pxa2x0_setperf(perflevel);
1557 1.1.12.2 yamt #endif
1558 1.1.12.2 yamt }
1559