Module Name: src Committed By: jruoho Date: Fri Jul 23 08:11:49 UTC 2010
Modified Files: src/sys/dev/acpi: acpi_cpu.h acpi_cpu_cstate.c Log Message: Add a new flag that determines whether we should check for bus master activity (BM_STS) by reading from the PM1 register. According to the Intel processor specification for ACPI, the FFH GAS encoding may provide a hint that the check is not required. This may help some systems to enter C2/C3 even when e.g. usb(4) keeps the BM_STS bit always enabled. To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/sys/dev/acpi/acpi_cpu.h cvs rdiff -u -r1.6 -r1.7 src/sys/dev/acpi/acpi_cpu_cstate.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.h diff -u src/sys/dev/acpi/acpi_cpu.h:1.4 src/sys/dev/acpi/acpi_cpu.h:1.5 --- src/sys/dev/acpi/acpi_cpu.h:1.4 Fri Jul 23 05:32:02 2010 +++ src/sys/dev/acpi/acpi_cpu.h Fri Jul 23 08:11:49 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_cpu.h,v 1.4 2010/07/23 05:32:02 jruoho Exp $ */ +/* $NetBSD: acpi_cpu.h,v 1.5 2010/07/23 08:11:49 jruoho Exp $ */ /*- * Copyright (c) 2010 Jukka Ruohonen <jruoho...@iki.fi> @@ -53,6 +53,12 @@ #define ACPICPU_PDC_P_HW __BIT(11) /* Px hardware coordination */ /* + * See ibid., table 4. + */ +#define ACPICPU_PDC_GAS_HW __BIT(0) /* hw-coordinated state */ +#define ACPICPU_PDC_GAS_BM __BIT(1) /* bus master check required */ + +/* * Notify values. */ #define ACPICPU_P_NOTIFY 0x80 /* _PPC */ @@ -73,19 +79,17 @@ #define ACPICPU_C_STATE_FFH 0x02 #define ACPICPU_C_STATE_SYSIO 0x03 -/* - * Global flags in the softc. - */ #define ACPICPU_FLAG_C __BIT(0) #define ACPICPU_FLAG_P __BIT(1) #define ACPICPU_FLAG_T __BIT(2) #define ACPICPU_FLAG_C_CST __BIT(3) #define ACPICPU_FLAG_C_FADT __BIT(4) #define ACPICPU_FLAG_C_BM __BIT(5) -#define ACPICPU_FLAG_C_ARB __BIT(6) -#define ACPICPU_FLAG_C_NOC3 __BIT(7) -#define ACPICPU_FLAG_C_MWAIT __BIT(8) -#define ACPICPU_FLAG_C_C1E __BIT(9) +#define ACPICPU_FLAG_C_BM_STS __BIT(6) +#define ACPICPU_FLAG_C_ARB __BIT(7) +#define ACPICPU_FLAG_C_NOC3 __BIT(8) +#define ACPICPU_FLAG_C_MWAIT __BIT(9) +#define ACPICPU_FLAG_C_C1E __BIT(10) struct acpicpu_cstate { uint64_t cs_stat; @@ -93,6 +97,7 @@ uint32_t cs_power; /* mW */ uint32_t cs_latency; /* us */ int cs_method; + int cs_flags; }; struct acpicpu_csd { Index: src/sys/dev/acpi/acpi_cpu_cstate.c diff -u src/sys/dev/acpi/acpi_cpu_cstate.c:1.6 src/sys/dev/acpi/acpi_cpu_cstate.c:1.7 --- src/sys/dev/acpi/acpi_cpu_cstate.c:1.6 Fri Jul 23 05:32:02 2010 +++ src/sys/dev/acpi/acpi_cpu_cstate.c Fri Jul 23 08:11:49 2010 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_cpu_cstate.c,v 1.6 2010/07/23 05:32:02 jruoho Exp $ */ +/* $NetBSD: acpi_cpu_cstate.c,v 1.7 2010/07/23 08:11:49 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_cstate.c,v 1.6 2010/07/23 05:32:02 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_cstate.c,v 1.7 2010/07/23 08:11:49 jruoho Exp $"); #include <sys/param.h> #include <sys/cpu.h> @@ -171,8 +171,9 @@ } aprint_debug_dev(sc->sc_dev, "C%d: %5s, " - "latency %4u, power %4u, addr 0x%06x\n", i, method, - cs->cs_latency, cs->cs_power, (uint32_t)cs->cs_addr); + "latency %4u, power %4u, addr 0x%06x, flags 0x%02x\n", + i, method, cs->cs_latency, cs->cs_power, + (uint32_t)cs->cs_addr, cs->cs_flags); } } @@ -336,6 +337,8 @@ (void)memset(&state, 0, sizeof(*cs)); + state.cs_flags = ACPICPU_FLAG_C_BM_STS; + if (elm->Type != ACPI_TYPE_PACKAGE) { rv = AE_TYPE; goto out; @@ -456,6 +459,16 @@ } } + if (sc->sc_cap != 0) { + + /* + * The _CST FFH GAS encoding may contain + * additional hints on Intel processors. + */ + if ((reg->reg_accesssize & ACPICPU_PDC_GAS_BM) == 0) + state.cs_flags &= ~ACPICPU_FLAG_C_BM_STS; + } + break; default: @@ -483,8 +496,9 @@ cs[type].cs_addr = state.cs_addr; cs[type].cs_power = state.cs_power; - cs[type].cs_latency = state.cs_latency; + cs[type].cs_flags = state.cs_flags; cs[type].cs_method = state.cs_method; + cs[type].cs_latency = state.cs_latency; out: if (ACPI_FAILURE(rv)) @@ -733,13 +747,13 @@ state = acpicpu_cstate_latency(sc); /* - * Check for bus master activity. Note that - * particularly usb(4) causes high activity, - * which may prevent the use of C3 states. + * Check for bus master activity. Note that particularly usb(4) + * causes high activity, which may prevent the use of C3 states. */ - if (acpicpu_cstate_bm_check() != false) { + if ((sc->sc_cstate[state].cs_flags & ACPICPU_FLAG_C_BM_STS) != 0) { - state--; + if (acpicpu_cstate_bm_check() != false) + state--; if (__predict_false(sc->sc_cstate[state].cs_method == 0)) state = ACPI_STATE_C1;