Module Name: src Committed By: jruoho Date: Tue Aug 17 10:17:52 UTC 2010
Modified Files: src/sys/dev/acpi: acpi_cpu.c acpi_cpu.h acpi_cpu_pstate.c acpi_cpu_tstate.c Log Message: Add support for the optional dynamic minimum (in terms of MHz) via _PDL. Comparable to T-states, this gives effectively a window of available performance states for passive cooling. An example: Init: max = 0, min = Pn. Time j. Time j + 1. ----------- ----------- 2000 MHz P0 max P0 P1 P1 max P2 ==> P2 P3 P3 min P4 P4 P5 min P5 500 Mhz Pn Pn ----------- ----------- Search: repeat (i = P0; i <= P5) repeat (i = P1; i <= P3) To generate a diff of this commit: cvs rdiff -u -r1.18 -r1.19 src/sys/dev/acpi/acpi_cpu.c cvs rdiff -u -r1.17 -r1.18 src/sys/dev/acpi/acpi_cpu.h cvs rdiff -u -r1.26 -r1.27 src/sys/dev/acpi/acpi_cpu_pstate.c cvs rdiff -u -r1.11 -r1.12 src/sys/dev/acpi/acpi_cpu_tstate.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/acpi/acpi_cpu.c diff -u src/sys/dev/acpi/acpi_cpu.c:1.18 src/sys/dev/acpi/acpi_cpu.c:1.19 --- src/sys/dev/acpi/acpi_cpu.c:1.18 Mon Aug 16 20:07:57 2010 +++ src/sys/dev/acpi/acpi_cpu.c Tue Aug 17 10:17:52 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_cpu.c,v 1.18 2010/08/16 20:07:57 jruoho Exp $ */ +/* $NetBSD: acpi_cpu.c,v 1.19 2010/08/17 10:17:52 jruoho Exp $ */ /*- * Copyright (c) 2010 Jukka Ruohonen <jruoho...@iki.fi> @@ -27,7 +27,7 @@ * SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_cpu.c,v 1.18 2010/08/16 20:07:57 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_cpu.c,v 1.19 2010/08/17 10:17:52 jruoho Exp $"); #include <sys/param.h> #include <sys/cpu.h> @@ -116,6 +116,7 @@ sc->sc_dev = self; sc->sc_cold = true; sc->sc_mapped = false; + sc->sc_passive = false; sc->sc_iot = aa->aa_iot; sc->sc_node = aa->aa_node; sc->sc_cpuid = acpicpu_id(sc->sc_object.ao_procid); Index: src/sys/dev/acpi/acpi_cpu.h diff -u src/sys/dev/acpi/acpi_cpu.h:1.17 src/sys/dev/acpi/acpi_cpu.h:1.18 --- src/sys/dev/acpi/acpi_cpu.h:1.17 Mon Aug 16 17:58:42 2010 +++ src/sys/dev/acpi/acpi_cpu.h Tue Aug 17 10:17:52 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_cpu.h,v 1.17 2010/08/16 17:58:42 jruoho Exp $ */ +/* $NetBSD: acpi_cpu.h,v 1.18 2010/08/17 10:17:52 jruoho Exp $ */ /*- * Copyright (c) 2010 Jukka Ruohonen <jruoho...@iki.fi> @@ -185,6 +185,7 @@ uint32_t sc_pstate_current; uint32_t sc_pstate_count; uint32_t sc_pstate_max; + uint32_t sc_pstate_min; struct acpicpu_tstate *sc_tstate; struct acpicpu_reg sc_tstate_control; @@ -203,6 +204,7 @@ cpuid_t sc_cpuid; bool sc_cold; bool sc_mapped; + bool sc_passive; }; void acpicpu_cstate_attach(device_t); Index: src/sys/dev/acpi/acpi_cpu_pstate.c diff -u src/sys/dev/acpi/acpi_cpu_pstate.c:1.26 src/sys/dev/acpi/acpi_cpu_pstate.c:1.27 --- src/sys/dev/acpi/acpi_cpu_pstate.c:1.26 Mon Aug 16 20:20:44 2010 +++ src/sys/dev/acpi/acpi_cpu_pstate.c Tue Aug 17 10:17:52 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_cpu_pstate.c,v 1.26 2010/08/16 20:20:44 jruoho Exp $ */ +/* $NetBSD: acpi_cpu_pstate.c,v 1.27 2010/08/17 10:17:52 jruoho Exp $ */ /*- * Copyright (c) 2010 Jukka Ruohonen <jruoho...@iki.fi> @@ -27,7 +27,7 @@ * SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_pstate.c,v 1.26 2010/08/16 20:20:44 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_pstate.c,v 1.27 2010/08/17 10:17:52 jruoho Exp $"); #include <sys/param.h> #include <sys/evcnt.h> @@ -52,6 +52,7 @@ ACPI_OBJECT *); static ACPI_STATUS acpicpu_pstate_pct(struct acpicpu_softc *); static int acpicpu_pstate_max(struct acpicpu_softc *); +static int acpicpu_pstate_min(struct acpicpu_softc *); static void acpicpu_pstate_change(struct acpicpu_softc *); static void acpicpu_pstate_bios(void); @@ -62,6 +63,7 @@ { struct acpicpu_softc *sc = device_private(self); const char *str; + ACPI_HANDLE tmp; ACPI_STATUS rv; rv = acpicpu_pstate_pss(sc); @@ -104,7 +106,13 @@ * standard, and some systems conforming to ACPI 2.0 * do not have _PPC, the method for dynamic maximum. */ - (void)acpicpu_pstate_max(sc); + rv = AcpiGetHandle(sc->sc_node->ad_handle, "_PPC", &tmp); + + if (ACPI_FAILURE(rv)) + aprint_debug_dev(self, "_PPC missing\n"); + + sc->sc_pstate_max = 0; + sc->sc_pstate_min = sc->sc_pstate_count - 1; sc->sc_flags |= ACPICPU_FLAG_P; @@ -236,7 +244,7 @@ goto fail; /* - * Initialize the state to the maximum. + * Initialize the state to P0. */ for (i = 0, rv = ENXIO; i < sc->sc_pstate_count; i++) { @@ -752,31 +760,58 @@ * Evaluate the currently highest P-state that can be used. * If available, we can use either this state or any lower * power (i.e. higher numbered) state from the _PSS object. + * Note that the return value must match the _OST parameter. */ rv = acpi_eval_integer(sc->sc_node->ad_handle, "_PPC", &val); - sc->sc_pstate_max = 0; + if (ACPI_SUCCESS(rv) && val < sc->sc_pstate_count) { - if (ACPI_FAILURE(rv)) - return 1; + if (sc->sc_pstate[val].ps_freq != 0) { + sc->sc_pstate_max = val; + return 0; + } + } - if (val > sc->sc_pstate_count - 1) - return 1; + return 1; +} - if (sc->sc_pstate[val].ps_freq == 0) - return 1; +static int +acpicpu_pstate_min(struct acpicpu_softc *sc) +{ + ACPI_INTEGER val; + ACPI_STATUS rv; - sc->sc_pstate_max = val; + /* + * The _PDL object defines the minimum when passive cooling + * is being performed. If available, we can use the returned + * state or any higher power (i.e. lower numbered) state. + */ + rv = acpi_eval_integer(sc->sc_node->ad_handle, "_PDL", &val); - return 0; + if (ACPI_SUCCESS(rv) && val < sc->sc_pstate_count) { + + if (sc->sc_pstate[val].ps_freq == 0) + return 1; + + if (val >= sc->sc_pstate_max) { + sc->sc_pstate_min = val; + return 0; + } + } + + return 1; } static void acpicpu_pstate_change(struct acpicpu_softc *sc) { + static ACPI_STATUS rv = AE_OK; ACPI_OBJECT_LIST arg; ACPI_OBJECT obj[2]; + sc->sc_pstate_max = 0; + sc->sc_pstate_min = sc->sc_pstate_count - 1; + arg.Count = 2; arg.Pointer = obj; @@ -786,7 +821,13 @@ obj[0].Integer.Value = ACPICPU_P_NOTIFY; obj[1].Integer.Value = acpicpu_pstate_max(sc); - (void)AcpiEvaluateObject(sc->sc_node->ad_handle, "_OST", &arg, NULL); + if (sc->sc_passive != false) + (void)acpicpu_pstate_min(sc); + + if (ACPI_FAILURE(rv)) + return; + + rv = AcpiEvaluateObject(sc->sc_node->ad_handle, "_OST", &arg, NULL); } static void @@ -917,7 +958,7 @@ mutex_enter(&sc->sc_mtx); - for (i = sc->sc_pstate_max; i < sc->sc_pstate_count; i++) { + for (i = sc->sc_pstate_max; i <= sc->sc_pstate_min; i++) { if (sc->sc_pstate[i].ps_freq == 0) continue; Index: src/sys/dev/acpi/acpi_cpu_tstate.c diff -u src/sys/dev/acpi/acpi_cpu_tstate.c:1.11 src/sys/dev/acpi/acpi_cpu_tstate.c:1.12 --- src/sys/dev/acpi/acpi_cpu_tstate.c:1.11 Mon Aug 16 17:58:42 2010 +++ src/sys/dev/acpi/acpi_cpu_tstate.c Tue Aug 17 10:17:52 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_cpu_tstate.c,v 1.11 2010/08/16 17:58:42 jruoho Exp $ */ +/* $NetBSD: acpi_cpu_tstate.c,v 1.12 2010/08/17 10:17:52 jruoho Exp $ */ /*- * Copyright (c) 2010 Jukka Ruohonen <jruoho...@iki.fi> @@ -27,7 +27,7 @@ * SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_tstate.c,v 1.11 2010/08/16 17:58:42 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_tstate.c,v 1.12 2010/08/17 10:17:52 jruoho Exp $"); #include <sys/param.h> #include <sys/evcnt.h> @@ -55,6 +55,7 @@ { struct acpicpu_softc *sc = device_private(self); const char *str; + ACPI_HANDLE tmp; ACPI_STATUS rv; /* @@ -82,7 +83,12 @@ * be absent in some systems, even though it is * required by ACPI 3.0 along with _TSS and _PTC. */ - (void)acpicpu_tstate_change(sc); + rv = AcpiGetHandle(sc->sc_node->ad_handle, "_TPC", &tmp); + + if (ACPI_FAILURE(rv)) { + aprint_debug_dev(self, "_TPC missing\n"); + rv = AE_OK; + } out: if (ACPI_FAILURE(rv)) { @@ -99,6 +105,9 @@ sc->sc_flags |= ACPICPU_FLAG_T_FADT; } + sc->sc_tstate_max = 0; + sc->sc_tstate_min = sc->sc_tstate_count - 1; + sc->sc_flags |= ACPICPU_FLAG_T; acpicpu_tstate_attach_evcnt(sc); @@ -591,15 +600,15 @@ */ rv = acpi_eval_integer(sc->sc_node->ad_handle, "_TPC", &val); - if (ACPI_FAILURE(rv)) - return rv; - - if (val < sc->sc_tstate_count) { + if (ACPI_SUCCESS(rv) && val < sc->sc_tstate_count) { if (sc->sc_tstate[val].ts_percent != 0) sc->sc_tstate_max = val; } + if (sc->sc_passive != true) + return AE_OK; + rv = acpi_eval_integer(sc->sc_node->ad_handle, "_TDL", &val); if (ACPI_SUCCESS(rv) && val < sc->sc_tstate_count) {