diff options
author | Dale Rahn <drahn@cvs.openbsd.org> | 2005-12-20 19:23:58 +0000 |
---|---|---|
committer | Dale Rahn <drahn@cvs.openbsd.org> | 2005-12-20 19:23:58 +0000 |
commit | d74a218ecd94fee4992ee8d0d8402f7db3390039 (patch) | |
tree | 703b2e01238262c361a909f550a5eb9c1a8b639d /sys | |
parent | fa04a33842e1afe447b445cf4dd9d8a7f5d94812 (diff) |
Add machdep.maxspeed sysctl to change the meaning of hw.setperf=100 on zaurus,
This will scale the speed for hw.setperf, this allows limiting apm -A
to lower speed, or even overclocking. ok deraadt@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/arm/arm/arm32_machdep.c | 17 | ||||
-rw-r--r-- | sys/arch/arm/include/cpu.h | 6 | ||||
-rw-r--r-- | sys/arch/arm/xscale/pxa2x0_apm.c | 121 |
3 files changed, 136 insertions, 8 deletions
diff --git a/sys/arch/arm/arm/arm32_machdep.c b/sys/arch/arm/arm/arm32_machdep.c index ffe1de40673..a8ea8ba2fd3 100644 --- a/sys/arch/arm/arm/arm32_machdep.c +++ b/sys/arch/arm/arm/arm32_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: arm32_machdep.c,v 1.15 2005/08/06 14:26:51 miod Exp $ */ +/* $OpenBSD: arm32_machdep.c,v 1.16 2005/12/20 19:23:57 drahn Exp $ */ /* $NetBSD: arm32_machdep.c,v 1.42 2003/12/30 12:33:15 pk Exp $ */ /* @@ -139,6 +139,7 @@ struct ztsscale { int ts_maxy; }; extern struct ztsscale zts_scale; +extern int xscale_maxspeed; #endif /* Prototypes */ @@ -512,6 +513,20 @@ cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) return (err); } #endif +#ifdef __zaurus__ /* ??? */ + case CPU_MAXSPEED: + { + int err = EINVAL; + void pxa2x0_maxspeed(int *); + if (!newp && newlen == 0) + return (sysctl_int(oldp, oldlenp, 0, 0, + &xscale_maxspeed)); + err = (sysctl_int(oldp, oldlenp, newp, newlen, + &xscale_maxspeed)); + pxa2x0_maxspeed(&xscale_maxspeed); + return err; + } +#endif default: return (EOPNOTSUPP); diff --git a/sys/arch/arm/include/cpu.h b/sys/arch/arm/include/cpu.h index f62e306c4e8..016b6b4f6f6 100644 --- a/sys/arch/arm/include/cpu.h +++ b/sys/arch/arm/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.9 2005/04/24 18:55:49 uwe Exp $ */ +/* $OpenBSD: cpu.h,v 1.10 2005/12/20 19:23:57 drahn Exp $ */ /* $NetBSD: cpu.h,v 1.34 2003/06/23 11:01:08 martin Exp $ */ /* @@ -64,7 +64,8 @@ #define CPU_KBDRESET 8 /* int: console keyboard reset */ #define CPU_ZTSRAWMODE 9 /* int: zts returns unscaled x/y */ #define CPU_ZTSSCALE 10 /* struct: zts scaling parameters */ -#define CPU_MAXID 11 /* number of valid machdep ids */ +#define CPU_MAXSPEED 11 /* number of valid machdep ids */ +#define CPU_MAXID 12 /* number of valid machdep ids */ #define CTL_MACHDEP_NAMES { \ { 0, 0 }, \ @@ -78,6 +79,7 @@ { "kbdreset", CTLTYPE_INT }, \ { "ztsrawmode", CTLTYPE_INT }, \ { "ztsscale", CTLTYPE_STRUCT }, \ + { "maxspeed", CTLTYPE_INT } \ } #ifdef _KERNEL diff --git a/sys/arch/arm/xscale/pxa2x0_apm.c b/sys/arch/arm/xscale/pxa2x0_apm.c index 8b2f570b0e5..9c24231c5ac 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.22 2005/12/20 02:37:09 drahn Exp $ */ +/* $OpenBSD: pxa2x0_apm.c,v 1.23 2005/12/20 19:23:57 drahn Exp $ */ /*- * Copyright (c) 2001 Alexander Guy. All rights reserved. @@ -1393,17 +1393,73 @@ pxa2x0_pi2c_print(struct pxa2x0_apm_softc *sc) } #endif +struct { + int maxspeed; + int numspeeds; + int hz [6]; + int rate [6]; /* could this be simplfied by not having 100% in table? */ +} +speedtables[] = { + { 91, 1, { 91 }, { 100 }}, + { 208, 2, { 91, 208}, {50, 100}}, + { 416, 3, { 91, 208, 416}, {25, 50, 100}}, + { 520, 4, { 91, 208, 416, 520}, {18, 40 ,80, 100}}, + { 624, 5, { 91, 208, 416, 520, 624}, {15, 34, 67, 82, 100}}, + { 0 } +}; +int xscale_maxspeed = 416; /* XXX */ + +int speed_to_freq(int speed); + +int +speed_to_freq(int speed) +{ + int i, j; + int newspeed = 0; + int numspeeds; + for (i = 0; speedtables[i].maxspeed != 0; i++) { + if (speedtables[i].maxspeed != xscale_maxspeed) + continue; + + if (speed <= speedtables[i].rate[0]) { + return speedtables[i].hz[0]; + + } + numspeeds = speedtables[i].numspeeds; + if (speed == speedtables[i].rate[numspeeds-1]) { + return speedtables[i].hz[numspeeds-1]; + } + for (j = 1; j < numspeeds; j++) { + if (speed < speedtables[i].rate[j]) { + return speedtables[i].hz[j-1]; + } + } + } + return newspeed; +} + + int pxa2x0_setperf(int speed) { struct pxa2x0_apm_softc *sc; int s; + int newfreq; sc = apm_cd.cd_devs[0]; + newfreq = speed_to_freq(speed); + + if (newfreq == 0) { + printf("bogus new frequency 0 for rate %d maxclock %d\n", + speed, xscale_maxspeed); + } + printf("setperf speed %d newfreq %d, maxfreq %d\n", + speed, newfreq, xscale_maxspeed); + s = disable_interrupts(I32_bit|F32_bit); - if (speed <= 30) { + if (newfreq == 91) { if (freq > 91) { pxa27x_run_mode(); pxa27x_fastbus_run_mode(0, MDREFR_LOW); @@ -1412,7 +1468,7 @@ pxa2x0_setperf(int speed) PI2C_VOLTAGE_LOW); freq = 91; } - } else if (speed < 60) { + } else if (newfreq == 208) { if (freq < 208) pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh, PI2C_VOLTAGE_HIGH); @@ -1422,7 +1478,7 @@ pxa2x0_setperf(int speed) pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high); freq = 208; } - } else { + } else if (newfreq == 416) { if (freq < 208) { pxa2x0_pi2c_setvoltage(sc->sc_iot, sc->sc_pm_ioh, PI2C_VOLTAGE_HIGH); @@ -1430,12 +1486,41 @@ pxa2x0_setperf(int speed) CCCR_RUN_X16, CLKCFG_F, &pxa2x0_memcfg); pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high); } - if (freq < 416) { + if (freq != 416) { pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X2 | CCCR_RUN_X16, CLKCFG_B | CLKCFG_F | CLKCFG_T, &pxa2x0_memcfg); freq = 416; } + } else if (newfreq == 520) { + if (freq < 208) { + 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); + pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high); + } + if (freq != 520) { + printf("would switch to 520\n"); + pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X25 | + CCCR_RUN_X16, CLKCFG_B | CLKCFG_F | CLKCFG_T, + &pxa2x0_memcfg); + freq = 520; + } + } else if (newfreq == 624) { + if (freq < 208) { + 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); + pxa27x_fastbus_run_mode(1, pxa2x0_memcfg.mdrefr_high); + } + if (freq != 624) { + pxa27x_frequency_change(CCCR_A | CCCR_TURBO_X3 | + CCCR_RUN_X16, CLKCFG_B | CLKCFG_F | CLKCFG_T, + &pxa2x0_memcfg); + freq = 624; + } } restore_interrupts(s); @@ -1449,3 +1534,29 @@ pxa2x0_cpuspeed(int *freqp) *freqp = freq; return 0; } + +void pxa2x0_maxspeed(int *speedp); + +void +pxa2x0_maxspeed(int *speedp) +{ + /* XXX assumes a pxa270 */ + + if (*speedp < 207) { + *speedp = 91; + } else if (*speedp < 415) { + *speedp = 208; + } else if (*speedp < 519) { + *speedp = 416; + } else if (*speedp < 624) { + *speedp = 520; +#if 0 + } else if (*speedp < 651) { + *speedp = 624; +#endif + } else { + *speedp = 520; /* hope this is safe. */ + } + xscale_maxspeed = *speedp; + pxa2x0_setperf(perflevel); +} |