summaryrefslogtreecommitdiff
path: root/sys/dev/acpi
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2006-12-29 04:28:45 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2006-12-29 04:28:45 +0000
commit355e9617f8c5b33402c49658cec44b9bd86694c7 (patch)
tree280969a4b4392fe216335b84c82fdd090ee273c1 /sys/dev/acpi
parentcc118da832a38b108fe278ff10c5e48d561ed542 (diff)
Replace setperf algorithm with a linear version. Also use the aml provided
gasio structure when appropriate instead of always assuming 32 bit access. Fixes my Dell laptop and works on others tested.
Diffstat (limited to 'sys/dev/acpi')
-rw-r--r--sys/dev/acpi/acpicpu.c80
1 files changed, 59 insertions, 21 deletions
diff --git a/sys/dev/acpi/acpicpu.c b/sys/dev/acpi/acpicpu.c
index c76702443c4..95b45c9a242 100644
--- a/sys/dev/acpi/acpicpu.c
+++ b/sys/dev/acpi/acpicpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpicpu.c,v 1.17 2006/12/26 23:58:08 marco Exp $ */
+/* $OpenBSD: acpicpu.c,v 1.18 2006/12/29 04:28:44 marco Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
*
@@ -121,7 +121,6 @@ acpicpu_attach(struct device *parent, struct device *self, void *aux)
}
dnprintf(20, "\n");
#endif
-
/* XXX this needs to be moved to probe routine */
if (acpicpu_getpct(sc))
return;
@@ -138,7 +137,6 @@ acpicpu_attach(struct device *parent, struct device *self, void *aux)
setperf_prio = 30;
}
acpicpu_sc[sc->sc_dev.dv_unit] = sc;
-
}
int
@@ -271,30 +269,67 @@ acpicpu_notify(struct aml_node *node, int notify_type, void *arg)
void
acpicpu_setperf(int level) {
- struct acpicpu_softc *sc;
- struct acpicpu_pss *pss = NULL;
- int high, low, freq, i;
- u_int32_t status;
+ struct acpicpu_softc *sc;
+ struct acpicpu_pss *pss = NULL;
+ int idx;
+ u_int32_t stat_as, ctrl_as, stat_len, ctrl_len;
+ u_int32_t status = 0;
sc = acpicpu_sc[cpu_number()];
- high = sc->sc_pss[0].pss_core_freq;
- low = sc->sc_pss[sc->sc_pss_len - 1].pss_core_freq;
- freq = low + (high - low) * level / 100;
- for (i = 0; i < sc->sc_pss_len; i++) {
- if (sc->sc_pss[i].pss_core_freq <= freq) {
- pss = &sc->sc_pss[i];
- break;
- }
+ dnprintf(10, "%s: acpicpu setperf level %d\n",
+ sc->sc_devnode->parent->name, level);
+
+ if (level < 0 || level > 100) {
+ dnprintf(10, "%s: acpicpu setperf illegal percentage\n",
+ sc->sc_devnode->parent->name);
+ return;
}
- if (pss == NULL)
+ idx = (sc->sc_pss_len - 1) - (level / (100 / sc->sc_pss_len));
+ if (idx < 0)
+ idx = 0; /* compensate */
+ if (idx > sc->sc_pss_len) {
+ /* XXX should never happen */
+ printf("%s: acpicpu setperf index out of range\n",
+ sc->sc_devnode->parent->name);
return;
+ }
+ dnprintf(10, "%s: acpicpu setperf index %d\n",
+ sc->sc_devnode->parent->name, idx);
+
+ pss = &sc->sc_pss[idx];
+
+ /* if not set assume single 32 bit access */
+ stat_as = sc->sc_pct.pct_status.grd_gas.register_bit_width / 8;
+ if (stat_as == 0)
+ stat_as = 4;
+ ctrl_as = sc->sc_pct.pct_ctrl.grd_gas.register_bit_width / 8;
+ if (ctrl_as == 0)
+ ctrl_as = 4;
+ stat_len = sc->sc_pct.pct_status.grd_gas.access_size;
+ if (stat_len == 0)
+ stat_len = stat_as;
+ ctrl_len = sc->sc_pct.pct_ctrl.grd_gas.access_size;
+ if (ctrl_len == 0)
+ ctrl_len = ctrl_as;
+
+#ifdef ACPI_DEBUG
+ /* keep this for now since we will need this for debug in the field */
+ printf("0 status: %x %llx %u %u ctrl: %x %llx %u %u\n",
+ sc->sc_pct.pct_status.grd_gas.address_space_id,
+ sc->sc_pct.pct_status.grd_gas.address,
+ stat_as, stat_len,
+ sc->sc_pct.pct_ctrl.grd_gas.address_space_id,
+ sc->sc_pct.pct_ctrl.grd_gas.address,
+ ctrl_as, ctrl_len);
+#endif
acpi_gasio(sc->sc_acpi, ACPI_IOREAD,
sc->sc_pct.pct_status.grd_gas.address_space_id,
- sc->sc_pct.pct_status.grd_gas.address, 1, 4,
+ sc->sc_pct.pct_status.grd_gas.address, stat_as, stat_len,
&status);
+ dnprintf(20, "status: %u <- %u\n", status, pss->pss_status);
/* Are we already at the requested frequency? */
if (status == pss->pss_status)
@@ -302,17 +337,20 @@ acpicpu_setperf(int level) {
acpi_gasio(sc->sc_acpi, ACPI_IOWRITE,
sc->sc_pct.pct_ctrl.grd_gas.address_space_id,
- sc->sc_pct.pct_ctrl.grd_gas.address, 1, 4,
+ sc->sc_pct.pct_ctrl.grd_gas.address, ctrl_as, ctrl_len,
&pss->pss_ctrl);
+ dnprintf(20, "pss_ctrl: %x\n", pss->pss_ctrl);
acpi_gasio(sc->sc_acpi, ACPI_IOREAD,
sc->sc_pct.pct_status.grd_gas.address_space_id,
- sc->sc_pct.pct_status.grd_gas.address, 1, 4,
+ sc->sc_pct.pct_status.grd_gas.address, stat_as, stat_as,
&status);
+ dnprintf(20, "3 status: %d\n", status);
/* Did the transition succeed? */
if (status == pss->pss_status)
cpuspeed = pss->pss_core_freq;
-
- return;
+ else
+ printf("%s: acpicpu setperf failed to alter frequency\n",
+ sc->sc_devnode->parent->name);
}