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 $ */
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
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
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/kernel.h>
42 #include <sys/kthread.h>
44 #include <sys/mount.h> /* for vfs_syncwait() */
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>
60 #define DPRINTF(x) printf x
62 #define DPRINTF(x) /**/
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
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 */
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 *);
98 void pxa2x0_setperf(int speed
);
99 int pxa2x0_cpuspeed(int *speed
);
101 int apm_record_event(struct pxa2x0_apm_softc
*, u_int
);
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
};
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
{
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 */
139 u_int32_t mdrefr_91
; /* 0x24 */
143 #define MDREFR_C3000 (MDREFR_K0DB2 | MDREFR_E1PIN | MDREFR_K1RUN | \
144 MDREFR_K1DB2 | MDREFR_K2DB2 | MDREFR_APD)
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 */ | \
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) | \
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) | \
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 */ | \
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) | \
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) | \
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
);
222 void pxa2x0_pi2c_print(struct pxa2x0_apm_softc
*);
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);
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
) {
258 printf("backup power,");
266 printf(" battery is ");
267 switch (powerp
->battery_state
) {
274 case APM_BATT_CRITICAL
:
277 case APM_BATT_CHARGING
:
280 case APM_BATT_UNKNOWN
:
284 printf("undecoded (%x)", powerp
->battery_state
);
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
);
306 apm_suspend(struct pxa2x0_apm_softc
*sc
)
311 dopowerhooks(PWR_SUSPEND
);
318 if (sc
->sc_suspend
== NULL
)
319 pxa2x0_wakeup_config(PXA2X0_WAKEUP_ALL
, 1);
323 pxa2x0_apm_sleep(sc
);
327 apm_resume(struct pxa2x0_apm_softc
*sc
)
330 dopowerhooks(PWR_RESUME
);
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
);
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
;
355 apm_handle_event(struct pxa2x0_apm_softc
*sc
, u_int type
)
357 struct apm_power_info power
;
364 case APM_CRIT_SUSPEND_REQ
:
365 DPRINTF(("suspend required immediately\n"));
367 /* XXX apmd would make us suspend again after resume. */
368 (void)apm_record_event(sc
, type
);
371 * We ignore APM_CRIT_RESUME and just suspend here as usual
372 * to simplify the actual apm_get_event() implementation.
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"));
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
);
398 case APM_BATTERY_LOW
:
399 DPRINTF(("Battery low!\n"));
401 apm_record_event(sc
, type
);
404 DPRINTF(("apm_handle_event: unsupported event, code %d\n",
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
);
427 struct pxa2x0_apm_softc
*sc
= v
;
434 if (apm_get_event(sc
, &type
) != 0)
436 if (apm_handle_event(sc
, type
) != 0)
439 if (apm_suspends
|| apm_userstandbys
/* || apm_battlow*/) {
443 apm_battlow
= apm_suspends
= apm_userstandbys
= 0;
446 kpause("apmev", false, hz
, NULL
);
451 apmopen(dev_t dev
, int flag
, int mode
, struct proc
*p
)
453 struct pxa2x0_apm_softc
*sc
;
457 if (!zapm_cd
.cd_ndevs
|| APMUNIT(dev
) != 0 ||
458 !(sc
= zapm_cd
.cd_devs
[APMUNIT(dev
)]))
461 DPRINTF(("apmopen: dev %d pid %d flag %x mode %x\n",
462 APMDEV(dev
), p
->p_pid
, flag
, mode
));
464 switch (APMDEV(dev
)) {
466 if (!(flag
& FWRITE
)) {
470 if (sc
->sc_flags
& SCFLAG_OWRITE
) {
474 sc
->sc_flags
|= SCFLAG_OWRITE
;
477 if (!(flag
& FREAD
) || (flag
& FWRITE
)) {
481 sc
->sc_flags
|= SCFLAG_OREAD
;
491 apmclose(dev_t dev
, int flag
, int mode
, struct proc
*p
)
493 struct pxa2x0_apm_softc
*sc
;
496 if (!apm_cd
.cd_ndevs
|| APMUNIT(dev
) != 0 ||
497 !(sc
= apm_cd
.cd_devs
[APMUNIT(dev
)]))
500 DPRINTF(("apmclose: pid %d flag %x mode %x\n", p
->p_pid
, flag
, mode
));
502 switch (APMDEV(dev
)) {
504 sc
->sc_flags
&= ~SCFLAG_OWRITE
;
507 sc
->sc_flags
&= ~SCFLAG_OREAD
;
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
;
521 if (!apm_cd
.cd_ndevs
|| APMUNIT(dev
) != 0 ||
522 !(sc
= apm_cd
.cd_devs
[APMUNIT(dev
)]))
526 /* some ioctl names from linux */
527 case APM_IOC_STANDBY
:
528 if ((flag
& FWRITE
) == 0)
533 case APM_IOC_SUSPEND
:
534 if ((flag
& FWRITE
) == 0)
537 apm_suspends
++; /* XXX */
539 case APM_IOC_PRN_CTL
:
540 if ((flag
& FWRITE
) == 0)
543 int flag
= *(int *)data
;
544 DPRINTF(( "APM_IOC_PRN_CTL: %d\n", flag
));
546 case APM_PRINT_ON
: /* enable printing */
547 sc
->sc_flags
&= ~SCFLAG_PRINT
;
549 case APM_PRINT_OFF
: /* disable printing */
550 sc
->sc_flags
&= ~SCFLAG_PRINT
;
551 sc
->sc_flags
|= SCFLAG_NOPRINT
;
553 case APM_PRINT_PCT
: /* disable some printing */
554 sc
->sc_flags
&= ~SCFLAG_PRINT
;
555 sc
->sc_flags
|= SCFLAG_PCTPRINT
;
563 case APM_IOC_DEV_CTL
:
564 if ((flag
& FWRITE
) == 0)
567 case APM_IOC_GETPOWER
:
568 power
= (struct apm_power_info
*)data
;
569 apm_power_info(sc
, power
);
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)
589 KNOTE(&sc
->sc_note
, APM_EVENT_COMPOSE(type
, apm_evindex
));
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
;
614 apmkqfilter(dev_t dev
, struct knote
*kn
)
616 struct pxa2x0_apm_softc
*sc
;
619 if (!apm_cd
.cd_ndevs
|| APMUNIT(dev
) != 0 ||
620 !(sc
= apm_cd
.cd_devs
[APMUNIT(dev
)]))
623 switch (kn
->kn_filter
) {
625 kn
->kn_fop
= &apmread_filtops
;
631 kn
->kn_hook
= (caddr_t
)sc
;
632 SLIST_INSERT_HEAD(&sc
->sc_note
, kn
, kn_selnext
);
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");
649 lockinit(&sc
->sc_lock
, PWAIT
, "apmlk", 0, 0);
651 kthread_create_deferred(apm_thread_create
, sc
);
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
);
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
);
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
);
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
);
681 pxa2x0_wakeup_config(u_int wsrc
, int enable
)
683 struct pxa2x0_apm_softc
*sc
;
688 if (zapm_cd
.cd_ndevs
< 1 || zapm_cd
.cd_devs
[0] == NULL
)
690 sc
= device_private(zapm_cd
.cd_devs
[0]);
692 prer
= pfer
= pkwr
= 0;
694 if ((wsrc
& PXA2X0_WAKEUP_POWERON
) != 0) {
697 pkwr
|= (1<<12); /* XXX */
700 if ((wsrc
& PXA2X0_WAKEUP_GPIORST
) != 0)
702 if ((wsrc
& PXA2X0_WAKEUP_SD
) != 0)
704 if ((wsrc
& PXA2X0_WAKEUP_RC
) != 0)
706 if ((wsrc
& PXA2X0_WAKEUP_SYNC
) != 0)
708 if ((wsrc
& PXA2X0_WAKEUP_KEYNS0
) != 0)
710 if ((wsrc
& PXA2X0_WAKEUP_KEYNS1
) != 0)
712 if ((wsrc
& PXA2X0_WAKEUP_KEYNS2
) != 0)
714 if ((wsrc
& PXA2X0_WAKEUP_KEYNS3
) != 0)
716 if ((wsrc
& PXA2X0_WAKEUP_KEYNS4
) != 0)
718 if ((wsrc
& PXA2X0_WAKEUP_KEYNS5
) != 0)
720 if ((wsrc
& PXA2X0_WAKEUP_KEYNS6
) != 0)
722 if ((wsrc
& PXA2X0_WAKEUP_CF0
) != 0)
724 if ((wsrc
& PXA2X0_WAKEUP_CF1
) != 0)
726 if ((wsrc
& PXA2X0_WAKEUP_USBD
) != 0)
729 if ((wsrc
& PXA2X0_WAKEUP_LOCKSW
) != 0) {
734 if ((wsrc
& PXA2X0_WAKEUP_JACKIN
) != 0) {
739 if ((wsrc
& PXA2X0_WAKEUP_CHRGFULL
) != 0)
741 if ((wsrc
& PXA2X0_WAKEUP_RTC
) != 0)
745 sc
->sc_wakeon
|= wsrc
;
746 prer
|= bus_space_read_4(sc
->sc_iot
, sc
->sc_pm_ioh
,
748 pfer
|= bus_space_read_4(sc
->sc_iot
, sc
->sc_pm_ioh
,
750 pkwr
|= bus_space_read_4(sc
->sc_iot
, sc
->sc_pm_ioh
,
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
,
770 pxa2x0_wakeup_status(void)
772 struct pxa2x0_apm_softc
*sc
;
776 if (zapm_cd
.cd_ndevs
< 1 || zapm_cd
.cd_devs
[0] == NULL
)
779 sc
= device_private(zapm_cd
.cd_devs
[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
;
829 struct pxa2x0_sleep_data
{
830 /* OS timer registers */
831 u_int32_t sd_osmr0
, sd_osmr1
, sd_osmr2
, sd_osmr3
;
833 u_int32_t sd_osmr4
, sd_osmr5
;
835 u_int32_t sd_omcr4
, sd_omcr5
;
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 */
848 /* Memory controller registers */
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 */
858 pxa2x0_apm_sleep(struct pxa2x0_apm_softc
*sc
)
860 struct pxa2x0_sleep_data sd
;
861 bus_space_handle_t ost_ioh
;
865 ost_ioh
= (bus_space_handle_t
)0;
866 if (bus_space_map(sc
->sc_iot
, PXA2X0_OST_BASE
, PXA2X0_OST_SIZE
, 0,
868 printf("pxa2x0_apm_sleep: can't map OST\n");
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
)) {
891 pxa27x_cpu_speed_high();
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
,
900 delay(500000); /* XXX */
904 /* Clear wake-up status. */
905 bus_space_write_4(sc
->sc_iot
, sc
->sc_pm_ioh
, POWMAN_PEDR
,
907 bus_space_write_4(sc
->sc_iot
, sc
->sc_pm_ioh
, POWMAN_PKSR
,
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? */
916 #define MDREFR_LOW (MDREFR_C3000 | 0x00b)
917 pxa27x_fastbus_run_mode(0, MDREFR_LOW
);
920 pxa27x_cpu_speed_91();
922 pxa27x_frequency_change(CCCR_TURBO_X1
| CCCR_RUN_X7
, CLKCFG_F
,
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
,
964 sd
.sd_mcmem0
= bus_space_read_4(sc
->sc_iot
, pxa2x0_memctl_ioh
,
966 sd
.sd_mcmem1
= bus_space_read_4(sc
->sc_iot
, pxa2x0_memctl_ioh
,
968 sd
.sd_mcatt0
= bus_space_read_4(sc
->sc_iot
, pxa2x0_memctl_ioh
,
970 sd
.sd_mcatt1
= bus_space_read_4(sc
->sc_iot
, pxa2x0_memctl_ioh
,
972 sd
.sd_mcio0
= bus_space_read_4(sc
->sc_iot
, pxa2x0_memctl_ioh
,
974 sd
.sd_mcio1
= bus_space_read_4(sc
->sc_iot
, pxa2x0_memctl_ioh
,
977 sd
.sd_cken
= bus_space_read_4(sc
->sc_iot
, pxa2x0_clkman_ioh
,
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.
985 if ((sc
->sc_wakeon
& PXA2X0_WAKEUP_KEYNS_ALL
) != 0)
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
,
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. */
1001 if ((cputype
& ~CPU_ID_XSCALE_COREREV_MASK
) == CPU_ID_PXA27X
)
1002 /* Enable nRESET_GPIO as a GPIO reset input. */
1004 bus_space_write_4(sc
->sc_iot
, sc
->sc_pm_ioh
, POWMAN_PCFR
, rv
);
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
,
1014 bus_space_write_4(sc
->sc_iot
, sc
->sc_pm_ioh
, POWMAN_PGSR1
,
1016 bus_space_write_4(sc
->sc_iot
, sc
->sc_pm_ioh
, POWMAN_PGSR2
,
1018 bus_space_write_4(sc
->sc_iot
, sc
->sc_pm_ioh
, POWMAN_PGSR3
,
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
));
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);
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);
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
&
1074 bus_space_write_4(sc
->sc_iot
, pxa2x0_gpio_ioh
, GPIO_GPSR1
, sd
.sd_gplr1
&
1076 bus_space_write_4(sc
->sc_iot
, pxa2x0_gpio_ioh
, GPIO_GPSR2
, sd
.sd_gplr2
&
1078 bus_space_write_4(sc
->sc_iot
, pxa2x0_gpio_ioh
, GPIO_GPCR0
, ~sd
.sd_gplr0
&
1080 bus_space_write_4(sc
->sc_iot
, pxa2x0_gpio_ioh
, GPIO_GPCR1
, ~sd
.sd_gplr1
&
1082 bus_space_write_4(sc
->sc_iot
, pxa2x0_gpio_ioh
, GPIO_GPCR2
, ~sd
.sd_gplr2
&
1087 bus_space_write_4(sc
->sc_iot
, pxa2x0_gpio_ioh
, GPIO_GEDR3
, 0xffffffff);
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
&
1096 bus_space_write_4(sc
->sc_iot
, pxa2x0_gpio_ioh
, GPIO_GPCR3
, ~sd
.sd_gplr3
&
1099 bus_space_write_4(sc
->sc_iot
, pxa2x0_memctl_ioh
, MEMCTL_MECR
,
1101 bus_space_write_4(sc
->sc_iot
, pxa2x0_memctl_ioh
, MEMCTL_MCMEM(0),
1103 bus_space_write_4(sc
->sc_iot
, pxa2x0_memctl_ioh
, MEMCTL_MCMEM(1),
1105 bus_space_write_4(sc
->sc_iot
, pxa2x0_memctl_ioh
, MEMCTL_MCATT(0),
1107 bus_space_write_4(sc
->sc_iot
, pxa2x0_memctl_ioh
, MEMCTL_MCATT(1),
1109 bus_space_write_4(sc
->sc_iot
, pxa2x0_memctl_ioh
, MEMCTL_MCIO(0),
1111 bus_space_write_4(sc
->sc_iot
, pxa2x0_memctl_ioh
, MEMCTL_MCIO(1),
1114 bus_space_write_4(sc
->sc_iot
, pxa2x0_clkman_ioh
, CLKMAN_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
))
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
);
1163 pxa2x0_setperf(perflevel
);
1167 if (ost_ioh
!= (bus_space_handle_t
)0)
1168 bus_space_unmap(sc
->sc_iot
, ost_ioh
, PXA2X0_OST_SIZE
);
1172 pxa2x0_pi2c_open(bus_space_tag_t iot
, bus_space_handle_t ioh
)
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
);
1183 /* Enable the clock to the power manager I2C unit. */
1184 pxa2x0_clkman_config(CKEN_PI2C
, 1);
1189 pxa2x0_pi2c_close(bus_space_tag_t iot
, bus_space_handle_t ioh
)
1193 bus_space_write_4(iot
, ioh
, POWMAN_PICR
, PICR_UR
);
1194 bus_space_write_4(iot
, ioh
, POWMAN_PISAR
, 0);
1197 /* Disable the clock to the power manager I2C unit. */
1198 pxa2x0_clkman_config(CKEN_PI2C
, 0);
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
));
1209 pxa2x0_pi2c_read(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1210 u_char slave
, u_char
*valuep
)
1214 int tries
= PI2C_RETRY_COUNT
;
1218 bus_space_write_4(iot
, ioh
, POWMAN_PICR
, PICR_UR
);
1219 bus_space_write_4(iot
, ioh
, POWMAN_PISAR
, 0x00);
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
);
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
);
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
);
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
);
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
));
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
);
1282 pxa2x0_pi2c_write(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1283 u_char slave
, u_char value
)
1287 int tries
= PI2C_RETRY_COUNT
;
1291 bus_space_write_4(iot
, ioh
, POWMAN_PICR
, PICR_UR
);
1292 bus_space_write_4(iot
, ioh
, POWMAN_PISAR
, 0x00);
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
);
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
);
1313 if ((bus_space_read_4(iot
, ioh
, POWMAN_PISR
) & PISR_ACKNAK
) != 0)
1315 bus_space_write_4(iot
, ioh
, POWMAN_PISR
, PISR_ITE
);
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
);
1327 while ((bus_space_read_4(iot
, ioh
, POWMAN_PISR
) & PISR_ITE
) == 0) {
1328 if (timeout
-- == 0) {
1330 bus_space_write_4(iot
, ioh
, POWMAN_PISR
, PISR_ITE
);
1336 if ((bus_space_read_4(iot
, ioh
, POWMAN_PISR
) & PISR_ACKNAK
) != 0)
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
);
1345 bus_space_write_4(iot
, ioh
, POWMAN_PISR
, PISR_ITE
);
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
);
1357 pxa2x0_pi2c_getvoltage(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1362 pxa2x0_pi2c_open(iot
, ioh
);
1363 res
= pxa2x0_pi2c_read(iot
, ioh
, 0x0c, valuep
);
1364 pxa2x0_pi2c_close(iot
, ioh
);
1369 pxa2x0_pi2c_setvoltage(bus_space_tag_t iot
, bus_space_handle_t ioh
,
1374 pxa2x0_pi2c_open(iot
, ioh
);
1375 res
= pxa2x0_pi2c_write(iot
, ioh
, 0x0c, value
);
1376 pxa2x0_pi2c_close(iot
, ioh
);
1382 pxa2x0_pi2c_print(struct pxa2x0_apm_softc
*sc
)
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"));
1396 int rate
[6]; /* could this be simplfied by not having 100% in table? */
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}},
1406 int xscale_maxspeed
= 416; /* XXX */
1408 int speed_to_freq(int speed
);
1411 speed_to_freq(int speed
)
1416 for (i
= 0; speedtables
[i
].maxspeed
!= 0; i
++) {
1417 if (speedtables
[i
].maxspeed
!= xscale_maxspeed
)
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];
1439 pxa2x0_setperf(int speed
)
1441 struct pxa2x0_apm_softc
*sc
;
1445 sc
= device_private(zapm_cd
.cd_devs
[0]);
1447 newfreq
= speed_to_freq(speed
);
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) {
1462 pxa27x_fastbus_run_mode(0, MDREFR_LOW
);
1463 pxa27x_cpu_speed_91();
1464 pxa2x0_pi2c_setvoltage(sc
->sc_iot
, sc
->sc_pm_ioh
,
1468 } else if (newfreq
== 208) {
1470 pxa2x0_pi2c_setvoltage(sc
->sc_iot
, sc
->sc_pm_ioh
,
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
);
1478 } else if (newfreq
== 416) {
1480 pxa2x0_pi2c_setvoltage(sc
->sc_iot
, sc
->sc_pm_ioh
,
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
);
1487 pxa27x_frequency_change(CCCR_A
| CCCR_TURBO_X2
|
1488 CCCR_RUN_X16
, CLKCFG_B
| CLKCFG_F
| CLKCFG_T
,
1492 } else if (newfreq
== 520) {
1494 pxa2x0_pi2c_setvoltage(sc
->sc_iot
, sc
->sc_pm_ioh
,
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
);
1501 pxa27x_frequency_change(CCCR_A
| CCCR_TURBO_X25
|
1502 CCCR_RUN_X16
, CLKCFG_B
| CLKCFG_F
| CLKCFG_T
,
1506 } else if (newfreq
== 624) {
1508 pxa2x0_pi2c_setvoltage(sc
->sc_iot
, sc
->sc_pm_ioh
,
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
);
1515 pxa27x_frequency_change(CCCR_A
| CCCR_TURBO_X3
|
1516 CCCR_RUN_X16
, CLKCFG_B
| CLKCFG_F
| CLKCFG_T
,
1522 restore_interrupts(s
);
1526 pxa2x0_cpuspeed(int *freqp
)
1532 void pxa2x0_maxspeed(int *speedp
);
1535 pxa2x0_maxspeed(int *speedp
)
1537 /* XXX assumes a pxa270 */
1539 if (*speedp
< 207) {
1541 } else if (*speedp
< 415) {
1543 } else if (*speedp
< 519) {
1545 } else if (*speedp
< 624) {
1548 } else if (*speedp
< 651) {
1552 *speedp
= 520; /* hope this is safe. */
1554 xscale_maxspeed
= *speedp
;
1556 pxa2x0_setperf(perflevel
);