summaryrefslogtreecommitdiff
path: root/sys/arch/arm/xscale
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2005-10-31 04:56:15 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2005-10-31 04:56:15 +0000
commit27bd33adf110e69f50421a7db1906522e388aa81 (patch)
treeacce2355872002ffc3d539bc8ff79b21c4013b0f /sys/arch/arm/xscale
parent37f3c5806a6bd8f06216f56000d00c829365e2b7 (diff)
On suspend/resume save the current time to the RTC earlier and restore it later
so that the very long delay operations do not slow the clock unnecessarily. Add early support for hw.setperf and hw.cpuspeed for zaurus, it appears to be able to run at 91MHz and 209MHz as well as the std 416MHz with this change. Hopefully it is doing the speed changes correctly.
Diffstat (limited to 'sys/arch/arm/xscale')
-rw-r--r--sys/arch/arm/xscale/pxa2x0_apm.c70
1 files changed, 65 insertions, 5 deletions
diff --git a/sys/arch/arm/xscale/pxa2x0_apm.c b/sys/arch/arm/xscale/pxa2x0_apm.c
index 780983da4aa..ebe1fd1af0a 100644
--- a/sys/arch/arm/xscale/pxa2x0_apm.c
+++ b/sys/arch/arm/xscale/pxa2x0_apm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pxa2x0_apm.c,v 1.15 2005/08/12 03:23:02 uwe Exp $ */
+/* $OpenBSD: pxa2x0_apm.c,v 1.16 2005/10/31 04:56:14 drahn Exp $ */
/*-
* Copyright (c) 2001 Alexander Guy. All rights reserved.
@@ -92,6 +92,8 @@ int apm_handle_event(struct pxa2x0_apm_softc *, u_int);
void apm_thread_create(void *);
void apm_thread(void *);
+int pxa2x0_setperf(int speed);
+
int apm_record_event(struct pxa2x0_apm_softc *, u_int);
void filt_apmrdetach(struct knote *kn);
int filt_apmread(struct knote *kn, long hint);
@@ -303,6 +305,8 @@ void
apm_suspend(struct pxa2x0_apm_softc *sc)
{
+ resettodr();
+
dopowerhooks(PWR_SUSPEND);
if (cold)
@@ -322,6 +326,8 @@ apm_resume(struct pxa2x0_apm_softc *sc)
dopowerhooks(PWR_RESUME);
+ inittodr(0);
+
/*
* Clear the OTG Peripheral hold after running the pxaudc and pxaohci
* powerhooks to re-enable their operation. See 3.8.1.2
@@ -892,8 +898,6 @@ suspend_again:
/* XXX control battery charging in sleep mode. */
- resettodr();
-
/* XXX schedule RTC alarm to check the battery, or schedule
XXX wake-up shortly before an already programmed alarm? */
@@ -1141,8 +1145,6 @@ suspend_again:
*/
bus_space_write_4(sc->sc_iot, sc->sc_pm_ioh, POWMAN_PMCR, 0);
- inittodr(0);
-
bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR0, sd.sd_osmr0);
bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR1, sd.sd_osmr1);
bus_space_write_4(sc->sc_iot, ost_ioh, OST_OSMR2, sd.sd_osmr2);
@@ -1378,3 +1380,61 @@ pxa2x0_pi2c_print(struct pxa2x0_apm_softc *sc)
}
#endif
+extern int perflevel;
+int
+pxa2x0_setperf(int speed)
+{
+ struct pxa2x0_apm_softc *sc;
+ int s;
+
+ sc = apm_cd.cd_devs[0];
+
+ s = disable_interrupts(I32_bit|F32_bit);
+
+ if (speed <= 30) {
+ pxa27x_run_mode();
+ pxa27x_fastbus_run_mode(0, MDREFR_LOW);
+ delay(1);
+ pxa27x_cpu_speed_91();
+ if (perflevel > 50)
+ pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh,
+ PI2C_VOLTAGE_LOW);
+ perflevel = 25;
+ } else if (speed < 60) {
+ if (perflevel < 50)
+ pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh,
+ PI2C_VOLTAGE_HIGH);
+
+ pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 | CCCR_RUN_X16,
+ CLKCFG_F, &pxa2x0_memcfg);
+
+ /* XXX is the delay long enough, and necessary at all? */
+ delay(1);
+
+ pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high);
+ perflevel = 50;
+ } else {
+ if (perflevel < 50)
+ pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh,
+ PI2C_VOLTAGE_HIGH);
+
+ /* Change to 208Mhz run mode with fast-bus still disabled. */
+ pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 | CCCR_RUN_X16,
+ CLKCFG_F, &pxa2x0_memcfg);
+
+ /* XXX is the delay long enough, and necessary at all? */
+ delay(1);
+
+ pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high);
+
+ /* Change to 416Mhz turbo mode with fast-bus enabled. */
+ pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 | CCCR_RUN_X16,
+ CLKCFG_B | CLKCFG_F | CLKCFG_T, &pxa2x0_memcfg);
+
+ perflevel = 100;
+ }
+
+ restore_interrupts(s);
+
+ return 0;
+}