From 355e9617f8c5b33402c49658cec44b9bd86694c7 Mon Sep 17 00:00:00 2001 From: Marco Peereboom Date: Fri, 29 Dec 2006 04:28:45 +0000 Subject: 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. --- sys/dev/acpi/acpicpu.c | 80 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 21 deletions(-) (limited to 'sys/dev') 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 * @@ -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); } -- cgit v1.2.3