summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/acpi/acpicpu.c101
1 files changed, 70 insertions, 31 deletions
diff --git a/sys/dev/acpi/acpicpu.c b/sys/dev/acpi/acpicpu.c
index 5bb492448f0..e871cade899 100644
--- a/sys/dev/acpi/acpicpu.c
+++ b/sys/dev/acpi/acpicpu.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpicpu.c,v 1.10 2006/10/12 16:38:21 jordan Exp $ */
+/* $OpenBSD: acpicpu.c,v 1.11 2006/12/19 16:20:01 gwk Exp $ */
/*
* Copyright (c) 2005 Marco Peereboom <marco@openbsd.org>
*
@@ -18,6 +18,7 @@
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/signalvar.h>
+#include <sys/sysctl.h>
#include <sys/systm.h>
#include <sys/device.h>
#include <sys/malloc.h>
@@ -38,6 +39,7 @@
int acpicpu_match(struct device *, void *, void *);
void acpicpu_attach(struct device *, struct device *, void *);
int acpicpu_notify(struct aml_node *, int, void *);
+void acpicpu_setperf(int);
struct acpicpu_softc {
struct device sc_dev;
@@ -65,6 +67,15 @@ struct cfdriver acpicpu_cd = {
NULL, "acpicpu", DV_DULL
};
+extern int setperf_prio;
+
+#ifdef __i386__
+struct acpicpu_softc *acpicpu_sc[I386_MAXPROCS];
+#elif __amd64__
+extern int cpuspeed;
+struct acpicpu_softc *acpicpu_sc[X86_MAXPROCS];
+#endif
+
int
acpicpu_match(struct device *parent, void *match, void *aux)
{
@@ -119,6 +130,13 @@ acpicpu_attach(struct device *parent, struct device *self, void *aux)
aml_register_notify(sc->sc_devnode->parent, NULL,
acpicpu_notify, sc);
+
+ if (setperf_prio < 30) {
+ cpu_setperf = acpicpu_setperf;
+ setperf_prio = 30;
+ }
+ acpicpu_sc[sc->sc_dev.dv_unit] = sc;
+
}
int
@@ -171,35 +189,6 @@ acpicpu_getpct(struct acpicpu_softc *sc)
sc->sc_pct.pct_status.grd_gas.access_size,
sc->sc_pct.pct_status.grd_gas.address);
-#if 0
- char pb[8];
-
- acpi_gasio(sc->sc_acpi, ACPI_IOREAD,
- 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.register_bit_width >> 3,
- pb);
-
- 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.register_bit_width >> 3,
- &sc->sc_pss[3].pss_ctrl);
-
- acpi_gasio(sc->sc_acpi, ACPI_IOREAD,
- 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.register_bit_width >> 3,
- pb);
- printf("acpicpu: %02x %02x %02x %02x\n", pb[0], pb[1], pb[2], pb[3]);
-#endif
-
return (0);
}
@@ -262,6 +251,56 @@ acpicpu_notify(struct aml_node *node, int notify_type, void *arg)
break;
}
-
return (0);
}
+
+void
+acpicpu_setperf(int level) {
+ struct acpicpu_softc *sc;
+ struct acpicpu_pss *pss = NULL;
+ int high, low, freq, i;
+ u_int32_t status;
+
+ 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;
+ }
+ }
+
+ if (pss == NULL)
+ return;
+
+ 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,
+ &status);
+
+ /* Are we already at the requested frequency? */
+ if (status == pss->pss_status)
+ return;
+
+ 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,
+ &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,
+ &status);
+
+ /* Did the transition succeed? */
+ if (status == pss->pss_status)
+#ifdef __i386__
+ pentium_mhz = pss->pss_core_freq;
+#elif __amd64__
+ cpuspeed = pss->pss_core_freq;
+#endif
+ return;
+}