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 $	*/
3
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.
8 *
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.
24 *
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.
36 *
37 */
38
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>
50
51#include <machine/cpu.h>
52#include <machine/apmvar.h>
53
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>
58
59#if defined(APMDEBUG)
60#define DPRINTF(x)	printf x
61#else
62#define	DPRINTF(x)	/**/
63#endif
64
65#define APM_LOCK(sc)    lockmgr(&(sc)->sc_lock, LK_EXCLUSIVE, NULL)
66#define APM_UNLOCK(sc)  lockmgr(&(sc)->sc_lock, LK_RELEASE, NULL)
67
68#define	APMUNIT(dev)	(minor(dev)&0xf0)
69#define	APMDEV(dev)	(minor(dev)&0x0f)
70#define APMDEV_NORMAL	0
71#define APMDEV_CTL	8
72
73int	apm_userstandbys;
74int	apm_suspends;
75int	apm_battlow;
76
77extern struct cfdriver zapm_cd;
78
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 */
82int	cpu_apmwarn = 10;
83
84void	apm_power_print(struct pxa2x0_apm_softc *, struct apm_power_info *);
85void	apm_power_info(struct pxa2x0_apm_softc *, struct apm_power_info *);
86void	apm_suspend(struct pxa2x0_apm_softc *);
87void	apm_resume(struct pxa2x0_apm_softc *);
88int	apm_get_event(struct pxa2x0_apm_softc *, u_int *);
89int	apm_handle_event(struct pxa2x0_apm_softc *, u_int);
90void	apm_thread_create(void *);
91void	apm_thread(void *);
92
93#if 0
94extern int perflevel;
95#endif
96
97int	freq;
98void	pxa2x0_setperf(int speed);
99int	pxa2x0_cpuspeed(int *speed);
100
101int	apm_record_event(struct pxa2x0_apm_softc *, u_int);
102#if 0
103void	filt_apmrdetach(struct knote *kn);
104int	filt_apmread(struct knote *kn, long hint);
105int	apmkqfilter(dev_t dev, struct knote *kn);
106
107struct filterops apmread_filtops =
108	{ 1, NULL, filt_apmrdetach, filt_apmread};
109#endif
110
111/*
112 * Flags to control kernel display
113 *	SCFLAG_NOPRINT:		do not output APM power messages due to
114 *				a power change event.
115 *
116 *	SCFLAG_PCTPRINT:	do not output APM power messages due to
117 *				to a power change event unless the battery
118 *				percentage changes.
119 */
120
121#define SCFLAG_NOPRINT	0x0008000
122#define SCFLAG_PCTPRINT	0x0004000
123#define SCFLAG_PRINT	(SCFLAG_NOPRINT|SCFLAG_PCTPRINT)
124
125#define	SCFLAG_OREAD 	(1 << 0)
126#define	SCFLAG_OWRITE	(1 << 1)
127#define	SCFLAG_OPEN	(SCFLAG_OREAD|SCFLAG_OWRITE)
128
129/* This structure must be kept in sync with pxa2x0_apm_asm.S. */
130struct 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 */
140};
141
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
201struct 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)
208};
209
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 */
214
215void	pxa2x0_pi2c_open(bus_space_tag_t, bus_space_handle_t);
216void	pxa2x0_pi2c_close(bus_space_tag_t, bus_space_handle_t);
217int	pxa2x0_pi2c_read(bus_space_tag_t, bus_space_handle_t, u_char, u_char *);
218int	pxa2x0_pi2c_write(bus_space_tag_t, bus_space_handle_t, u_char, u_char);
219int	pxa2x0_pi2c_getvoltage(bus_space_tag_t, bus_space_handle_t, u_char *);
220int	pxa2x0_pi2c_setvoltage(bus_space_tag_t, bus_space_handle_t, u_char);
221#if 0
222void	pxa2x0_pi2c_print(struct pxa2x0_apm_softc *);
223#endif
224
225/* XXX used in pxa2x0_apm_asm.S */
226bus_space_handle_t pxa2x0_gpio_ioh;
227bus_space_handle_t pxa2x0_clkman_ioh;
228bus_space_handle_t pxa2x0_memctl_ioh;
229
230/* pxa2x0_apm_asm.S */
231void	pxa27x_run_mode(void);
232void	pxa27x_fastbus_run_mode(int, u_int32_t);
233void	pxa27x_frequency_change(int, int, struct pxa2x0_memcfg *);
234void	pxa2x0_cpu_suspend(void);
235void	pxa2x0_cpu_resume(void);
236void	pxa27x_cpu_speed_high(void);
237void	pxa27x_cpu_speed_low(void);
238void	pxa27x_cpu_speed_91(void);
239void	pxa27x_cpu_speed_208(void);
240
241void
242apm_power_print(struct pxa2x0_apm_softc *sc, struct apm_power_info *powerp)
243{
244
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);
248
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;
264	}
265
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;
286	}
287
288	printf("\n");
289}
290
291void
292apm_power_info(struct pxa2x0_apm_softc *sc,
293    struct apm_power_info *power)
294{
295
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;
300
301	if (sc->sc_power_info != NULL)
302		sc->sc_power_info(sc, power);
303}
304
305void
306apm_suspend(struct pxa2x0_apm_softc *sc)
307{
308
309	resettodr();
310
311	dopowerhooks(PWR_SUSPEND);
312
313#if 0
314	if (cold)
315		vfs_syncwait(0);
316#endif
317
318	if (sc->sc_suspend == NULL)
319		pxa2x0_wakeup_config(PXA2X0_WAKEUP_ALL, 1);
320	else
321		sc->sc_suspend(sc);
322
323	pxa2x0_apm_sleep(sc);
324}
325
326void
327apm_resume(struct pxa2x0_apm_softc *sc)
328{
329
330	dopowerhooks(PWR_RESUME);
331
332	inittodr(0);
333
334	/*
335	 * Clear the OTG Peripheral hold after running the pxaudc and pxaohci
336	 * powerhooks to re-enable their operation. See 3.8.1.2
337	 */
338	/* XXX ifdef NPXAUDC > 0 */
339	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSSR, PSSR_OTGPH);
340}
341
342#if 0
343int
344apm_get_event(struct pxa2x0_apm_softc *sc, u_int *typep)
345{
346
347	if (sc->sc_get_event != NULL)
348		return (sc->sc_get_event(sc, typep));
349
350	*typep = APM_NOEVENT;
351	return (1);
352}
353
354int
355apm_handle_event(struct pxa2x0_apm_softc *sc, u_int type)
356{
357	struct	apm_power_info power;
358	int	ret = 0;
359
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
370		/*
371		 * We ignore APM_CRIT_RESUME and just suspend here as usual
372		 * to simplify the actual apm_get_event() implementation.
373		 */
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++;
383		}
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);
395		}
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));
406	}
407
408	return (ret);
409}
410
411void
412apm_thread_create(void *v)
413{
414	struct pxa2x0_apm_softc *sc = v;
415
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);
421	}
422}
423
424void
425apm_thread(void *v)
426{
427	struct pxa2x0_apm_softc *sc = v;
428	u_int	type;
429
430	for (;;) {
431		APM_LOCK(sc);
432
433		while (1) {
434			if (apm_get_event(sc, &type) != 0)
435				break;
436			if (apm_handle_event(sc, type) != 0)
437				break;
438		}
439		if (apm_suspends || apm_userstandbys /* || apm_battlow*/) {
440			apm_suspend(sc);
441			apm_resume(sc);
442		}
443		apm_battlow = apm_suspends = apm_userstandbys = 0;
444
445		APM_UNLOCK(sc);
446		kpause("apmev", false, hz, NULL);
447	}
448}
449
450int
451apmopen(dev_t dev, int flag, int mode, struct proc *p)
452{
453	struct pxa2x0_apm_softc *sc;
454	int error = 0;
455
456	/* apm0 only */
457	if (!zapm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
458	    !(sc = zapm_cd.cd_devs[APMUNIT(dev)]))
459		return (ENXIO);
460
461	DPRINTF(("apmopen: dev %d pid %d flag %x mode %x\n",
462		APMDEV(dev), p->p_pid, flag, mode));
463
464	switch (APMDEV(dev)) {
465	case APMDEV_CTL:
466		if (!(flag & FWRITE)) {
467			error = EINVAL;
468			break;
469		}
470		if (sc->sc_flags & SCFLAG_OWRITE) {
471			error = EBUSY;
472			break;
473		}
474		sc->sc_flags |= SCFLAG_OWRITE;
475		break;
476	case APMDEV_NORMAL:
477		if (!(flag & FREAD) || (flag & FWRITE)) {
478			error = EINVAL;
479			break;
480		}
481		sc->sc_flags |= SCFLAG_OREAD;
482		break;
483	default:
484		error = ENXIO;
485		break;
486	}
487	return (error);
488}
489
490int
491apmclose(dev_t dev, int flag, int mode, struct proc *p)
492{
493	struct pxa2x0_apm_softc *sc;
494
495	/* apm0 only */
496	if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
497	    !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
498		return (ENXIO);
499
500	DPRINTF(("apmclose: pid %d flag %x mode %x\n", p->p_pid, flag, mode));
501
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;
509	}
510	return (0);
511}
512
513int
514apmioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
515{
516	struct pxa2x0_apm_softc *sc;
517	struct apm_power_info *power;
518	int error = 0;
519
520	/* apm0 only */
521	if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
522	    !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
523		return (ENXIO);
524
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;
560			}
561		}
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;
571
572	default:
573		error = ENOTTY;
574	}
575
576	return (error);
577}
578
579int
580apm_record_event(struct pxa2x0_apm_softc *sc, u_int type)
581{
582	static int apm_evindex;
583
584	/* skip if no user waiting */
585	if ((sc->sc_flags & SCFLAG_OPEN) == 0)
586		return (1);
587
588	apm_evindex++;
589	KNOTE(&sc->sc_note, APM_EVENT_COMPOSE(type, apm_evindex));
590
591	return (0);
592}
593
594void
595filt_apmrdetach(struct knote *kn)
596{
597	struct pxa2x0_apm_softc *sc =
598	    (struct pxa2x0_apm_softc *)kn->kn_hook;
599
600	SLIST_REMOVE(&sc->sc_note, kn, knote, kn_selnext);
601}
602
603int
604filt_apmread(struct knote *kn, long hint)
605{
606	/* XXX weird kqueue_scan() semantics */
607	if (hint && !kn->kn_data)
608		kn->kn_data = (int)hint;
609
610	return (1);
611}
612
613int
614apmkqfilter(dev_t dev, struct knote *kn)
615{
616	struct pxa2x0_apm_softc *sc;
617
618	/* apm0 only */
619	if (!apm_cd.cd_ndevs || APMUNIT(dev) != 0 ||
620	    !(sc = apm_cd.cd_devs[APMUNIT(dev)]))
621		return (ENXIO);
622
623	switch (kn->kn_filter) {
624	case EVFILT_READ:
625		kn->kn_fop = &apmread_filtops;
626		break;
627	default:
628		return (1);
629	}
630
631	kn->kn_hook = (caddr_t)sc;
632	SLIST_INSERT_HEAD(&sc->sc_note, kn, kn_selnext);
633
634	return (0);
635}
636
637void
638pxa2x0_apm_attach_sub(struct pxa2x0_apm_softc *sc)
639{
640
641	sc->sc_iot = &pxa2x0_bs_tag;
642
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;
647	}
648
649	lockinit(&sc->sc_lock, PWAIT, "apmlk", 0, 0);
650
651	kthread_create_deferred(apm_thread_create, sc);
652
653	printf("\n");
654
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;
659	}
660
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;
665	}
666	sc->sc_memctl_ioh = pxa2x0_memctl_ioh;
667
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;
672	}
673
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);
677}
678#endif /* 0 */
679
680void
681pxa2x0_wakeup_config(u_int wsrc, int enable)
682{
683	struct pxa2x0_apm_softc *sc;
684	u_int32_t prer;
685	u_int32_t pfer;
686	u_int32_t pkwr;
687
688	if (zapm_cd.cd_ndevs < 1 || zapm_cd.cd_devs[0] == NULL)
689		return;
690	sc = device_private(zapm_cd.cd_devs[0]);
691
692	prer = pfer = pkwr = 0;
693
694	if ((wsrc & PXA2X0_WAKEUP_POWERON) != 0) {
695		prer |= (1<<0);
696		pfer |= (1<<0);
697		pkwr |= (1<<12); /* XXX */
698	}
699
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);
728
729	if ((wsrc & PXA2X0_WAKEUP_LOCKSW) != 0) {
730		prer |= (1<<15);
731		pfer |= (1<<15);
732	}
733
734	if ((wsrc & PXA2X0_WAKEUP_JACKIN) != 0) {
735		prer |= (1<<23);
736		pfer |= (1<<23);
737	}
738
739	if ((wsrc & PXA2X0_WAKEUP_CHRGFULL) != 0)
740		pkwr |= (1<<18);
741	if ((wsrc & PXA2X0_WAKEUP_RTC) != 0)
742		prer |= (1<<31);
743
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;
760	}
761
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);
767}
768
769u_int
770pxa2x0_wakeup_status(void)
771{
772	struct pxa2x0_apm_softc *sc;
773	u_int32_t rv;
774	u_int	wsrc;
775
776	if (zapm_cd.cd_ndevs < 1 || zapm_cd.cd_devs[0] == NULL)
777		return (0);
778
779	sc = device_private(zapm_cd.cd_devs[0]);
780	wsrc = 0;
781
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;
801
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;
825
826	return (wsrc);
827}
828
829struct 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;
855};
856
857void
858pxa2x0_apm_sleep(struct pxa2x0_apm_softc *sc)
859{
860	struct pxa2x0_sleep_data sd;
861	bus_space_handle_t ost_ioh;
862	int save;
863	u_int32_t rv;
864
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;
870	}
871
872	save = disable_interrupts(I32_bit|F32_bit);
873
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);
885
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 */
901	}
902
903suspend_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);
909
910	/* XXX control battery charging in sleep mode. */
911
912	/* XXX schedule RTC alarm to check the battery, or schedule
913	   XXX wake-up shortly before an already programmed alarm? */
914
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);
926
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);
931
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);
936
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);
941
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);
946
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);
951
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);
956
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);
961
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));
976
977	sd.sd_cken = bus_space_read_4(sc->sc_iot, pxa2x0_clkman_ioh,
978	    CLKMAN_CKEN);
979
980	/*
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.
983	 */
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);
988
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);
994
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);
998
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);
1005
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));
1031
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);
1039
1040	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSPR,
1041	    (u_int32_t)&pxa2x0_cpu_resume - 0xc0200000 + 0xa0200000);
1042
1043	pxa2x0_cpu_suspend();
1044
1045	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PSPR, 0);
1046
1047	pxa2x0_clkman_config(CKEN_SSP|CKEN_PWM0|CKEN_PWM1, 1);
1048	pxa2x0_clkman_config(CKEN_KEY, 0);
1049
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
1056
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);
1084
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);
1098
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);
1113
1114	bus_space_write_4(sc->sc_iot, pxa2x0_clkman_ioh, CLKMAN_CKEN,
1115	    sd.sd_cken);
1116
1117	write_icu(INTCTL_ICLR, sd.sd_iclr);
1118	write_icu(INTCTL_ICCR, sd.sd_iccr);
1119	write_icu(INTCTL_ICMR, sd.sd_icmr);
1120
1121	if ((read_icu(INTCTL_ICIP) & 0x1) != 0)
1122		bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PEDR, 0x1);
1123
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);
1135
1136	pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh, PI2C_VOLTAGE_HIGH);
1137
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);
1143
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);
1147
1148	if (sc->sc_resume != NULL) {
1149		if (!sc->sc_resume(sc))
1150			goto suspend_again;
1151	}
1152
1153	/*
1154	 * Allow immediate entry into deep-sleep mode if power fails.
1155	 * Resume from immediate deep-sleep is not implemented yet.
1156	 */
1157	bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PMCR, 0);
1158
1159
1160	restore_interrupts(save);
1161
1162#if 0
1163	pxa2x0_setperf(perflevel);
1164#endif
1165
1166out:
1167	if (ost_ioh != (bus_space_handle_t)0)
1168		bus_space_unmap(sc->sc_iot, ost_ioh, PXA2X0_OST_SIZE);
1169}
1170
1171void
1172pxa2x0_pi2c_open(bus_space_tag_t iot, bus_space_handle_t ioh)
1173{
1174	u_int32_t rv;
1175
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);
1182
1183	/* Enable the clock to the power manager I2C unit. */
1184	pxa2x0_clkman_config(CKEN_PI2C, 1);
1185	delay(1);
1186}
1187
1188void
1189pxa2x0_pi2c_close(bus_space_tag_t iot, bus_space_handle_t ioh)
1190{
1191	u_int32_t rv;
1192
1193	bus_space_write_4(iot, ioh, POWMAN_PICR, PICR_UR);
1194	bus_space_write_4(iot, ioh, POWMAN_PISAR, 0);
1195	delay(1);
1196
1197	/* Disable the clock to the power manager I2C unit. */
1198	pxa2x0_clkman_config(CKEN_PI2C, 0);
1199	delay(1);
1200
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);
1206}
1207
1208int
1209pxa2x0_pi2c_read(bus_space_tag_t iot, bus_space_handle_t ioh,
1210    u_char slave, u_char *valuep)
1211{
1212	u_int32_t rv;
1213	int timeout;
1214	int tries = PI2C_RETRY_COUNT;
1215
1216retry:
1217
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);
1222
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);
1231
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;
1237		}
1238		delay(1);
1239	}
1240
1241	bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_ITE);
1242
1243	rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
1244	bus_space_write_4(iot, ioh, POWMAN_PICR, rv & ~PICR_START);
1245
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);
1252
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;
1258		}
1259		delay(1);
1260	}
1261
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));
1268
1269	return (0);
1270err:
1271	if (tries-- >= 0)
1272		goto retry;
1273
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);
1277
1278	return (-EIO);
1279}
1280
1281int
1282pxa2x0_pi2c_write(bus_space_tag_t iot, bus_space_handle_t ioh,
1283    u_char slave, u_char value)
1284{
1285	u_int32_t rv;
1286	int timeout;
1287	int tries = PI2C_RETRY_COUNT;
1288
1289retry:
1290
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);
1295
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);
1304
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;
1310		}
1311		delay(1);
1312	}
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);
1316
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);
1325
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;
1333		}
1334		delay(1);
1335	}
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);
1339
1340	rv = bus_space_read_4(iot, ioh, POWMAN_PICR);
1341	bus_space_write_4(iot, ioh, POWMAN_PICR, rv & ~PICR_STOP);
1342
1343	return (0);
1344err:
1345	bus_space_write_4(iot, ioh, POWMAN_PISR, PISR_ITE);
1346	if (tries-- >= 0)
1347		goto retry;
1348
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);
1352
1353	return (-EIO);
1354}
1355
1356int
1357pxa2x0_pi2c_getvoltage(bus_space_tag_t iot, bus_space_handle_t ioh,
1358    u_char *valuep)
1359{
1360	int res;
1361
1362	pxa2x0_pi2c_open(iot, ioh);
1363	res = pxa2x0_pi2c_read(iot, ioh, 0x0c, valuep);
1364	pxa2x0_pi2c_close(iot, ioh);
1365	return (res);
1366}
1367
1368int
1369pxa2x0_pi2c_setvoltage(bus_space_tag_t iot, bus_space_handle_t ioh,
1370    u_char value)
1371{
1372	int res;
1373
1374	pxa2x0_pi2c_open(iot, ioh);
1375	res = pxa2x0_pi2c_write(iot, ioh, 0x0c, value);
1376	pxa2x0_pi2c_close(iot, ioh);
1377	return (res);
1378}
1379
1380#if 0
1381void
1382pxa2x0_pi2c_print(struct pxa2x0_apm_softc *sc)
1383{
1384	u_char value = 0;
1385
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"));
1389}
1390#endif
1391
1392struct {
1393	int maxspeed;
1394	int numspeeds;
1395	int hz [6];
1396	int rate [6]; /* could this be simplfied by not having 100% in table? */
1397}
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 }
1405	};
1406int xscale_maxspeed = 416; /* XXX */
1407
1408int speed_to_freq(int speed);
1409
1410int
1411speed_to_freq(int speed)
1412{
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;
1419
1420		if (speed <= speedtables[i].rate[0]) {
1421			return speedtables[i].hz[0];
1422
1423		}
1424		numspeeds = speedtables[i].numspeeds;
1425		if (speed == speedtables[i].rate[numspeeds-1]) {
1426			return speedtables[i].hz[numspeeds-1];
1427		}
1428		for (j = 1; j < numspeeds; j++) {
1429			if (speed < speedtables[i].rate[j]) {
1430				return speedtables[i].hz[j-1];
1431			}
1432		}
1433	}
1434	return newspeed;
1435}
1436
1437
1438void
1439pxa2x0_setperf(int speed)
1440{
1441	struct pxa2x0_apm_softc *sc;
1442	int s;
1443	int newfreq;
1444
1445	sc = device_private(zapm_cd.cd_devs[0]);
1446
1447	newfreq = speed_to_freq(speed);
1448
1449	if (newfreq == 0) {
1450		printf("bogus new frequency 0 for rate %d maxclock %d\n",
1451		    speed, xscale_maxspeed);
1452	}
1453
1454	DPRINTF(("setperf speed %d newfreq %d, maxfreq %d\n",
1455		speed, newfreq, xscale_maxspeed));
1456
1457	s = disable_interrupts(I32_bit|F32_bit);
1458
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;
1467		}
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;
1477		}
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);
1485		}
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;
1491		}
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);
1499		}
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;
1505		}
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);
1513		}
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;
1519		}
1520	}
1521
1522	restore_interrupts(s);
1523}
1524
1525int
1526pxa2x0_cpuspeed(int *freqp)
1527{
1528	*freqp = freq;
1529	return 0;
1530}
1531
1532void pxa2x0_maxspeed(int *speedp);
1533
1534void
1535pxa2x0_maxspeed(int *speedp)
1536{
1537	/* XXX assumes a pxa270 */
1538
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. */
1553	}
1554	xscale_maxspeed = *speedp;
1555#if 0
1556	pxa2x0_setperf(perflevel);
1557#endif
1558}
1559