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