summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDale Rahn <drahn@cvs.openbsd.org>2005-12-20 19:23:58 +0000
committerDale Rahn <drahn@cvs.openbsd.org>2005-12-20 19:23:58 +0000
commitd74a218ecd94fee4992ee8d0d8402f7db3390039 (patch)
tree703b2e01238262c361a909f550a5eb9c1a8b639d /sys
parentfa04a33842e1afe447b445cf4dd9d8a7f5d94812 (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.c17
-rw-r--r--sys/arch/arm/include/cpu.h6
-rw-r--r--sys/arch/arm/xscale/pxa2x0_apm.c121
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);
+}