Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/acpi Two changes:
details: https://anonhg.NetBSD.org/src/rev/a9f0cd526447
branches: trunk
changeset: 757157:a9f0cd526447
user: jruoho <jruoho%NetBSD.org@localhost>
date: Mon Aug 16 20:07:57 2010 +0000
description:
Two changes:
1. Initialize P-states properly to P0. It is processor-specific
what value we might get without initialization. (Some AMD CPUs
have even specific registers for the state after cold reset.)
2. Following design notes for Windows, set the lowest-power P-state
upon suspend and restore the saved state after resume.
diffstat:
sys/dev/acpi/acpi_cpu.c | 12 +++---
sys/dev/acpi/acpi_cpu_pstate.c | 75 ++++++++++++++++++++++++++++++++++++++---
2 files changed, 75 insertions(+), 12 deletions(-)
diffs (190 lines):
diff -r 7dd4dbe4b6e9 -r a9f0cd526447 sys/dev/acpi/acpi_cpu.c
--- a/sys/dev/acpi/acpi_cpu.c Mon Aug 16 19:39:06 2010 +0000
+++ b/sys/dev/acpi/acpi_cpu.c Mon Aug 16 20:07:57 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu.c,v 1.17 2010/08/16 17:58:42 jruoho Exp $ */
+/* $NetBSD: acpi_cpu.c,v 1.18 2010/08/16 20:07:57 jruoho Exp $ */
/*-
* Copyright (c) 2010 Jukka Ruohonen <jruohonen%iki.fi@localhost>
@@ -27,7 +27,7 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu.c,v 1.17 2010/08/16 17:58:42 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu.c,v 1.18 2010/08/16 20:07:57 jruoho Exp $");
#include <sys/param.h>
#include <sys/cpu.h>
@@ -519,8 +519,6 @@
{
struct acpicpu_softc *sc = device_private(self);
- sc->sc_cold = true;
-
if ((sc->sc_flags & ACPICPU_FLAG_C) != 0)
(void)acpicpu_cstate_suspend(self);
@@ -530,6 +528,8 @@
if ((sc->sc_flags & ACPICPU_FLAG_T) != 0)
(void)acpicpu_tstate_suspend(self);
+ sc->sc_cold = true;
+
return true;
}
@@ -538,6 +538,8 @@
{
struct acpicpu_softc *sc = device_private(self);
+ sc->sc_cold = false;
+
if ((sc->sc_flags & ACPICPU_FLAG_C) != 0)
(void)acpicpu_cstate_resume(self);
@@ -547,8 +549,6 @@
if ((sc->sc_flags & ACPICPU_FLAG_T) != 0)
(void)acpicpu_tstate_resume(self);
- sc->sc_cold = false;
-
return true;
}
diff -r 7dd4dbe4b6e9 -r a9f0cd526447 sys/dev/acpi/acpi_cpu_pstate.c
--- a/sys/dev/acpi/acpi_cpu_pstate.c Mon Aug 16 19:39:06 2010 +0000
+++ b/sys/dev/acpi/acpi_cpu_pstate.c Mon Aug 16 20:07:57 2010 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: acpi_cpu_pstate.c,v 1.24 2010/08/16 17:58:42 jruoho Exp $ */
+/* $NetBSD: acpi_cpu_pstate.c,v 1.25 2010/08/16 20:07:57 jruoho Exp $ */
/*-
* Copyright (c) 2010 Jukka Ruohonen <jruohonen%iki.fi@localhost>
@@ -27,7 +27,7 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_pstate.c,v 1.24 2010/08/16 17:58:42 jruoho Exp $");
+__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_pstate.c,v 1.25 2010/08/16 20:07:57 jruoho Exp $");
#include <sys/param.h>
#include <sys/evcnt.h>
@@ -55,6 +55,8 @@
static void acpicpu_pstate_change(struct acpicpu_softc *);
static void acpicpu_pstate_bios(void);
+static uint32_t acpicpu_pstate_saved;
+
void
acpicpu_pstate_attach(device_t self)
{
@@ -105,7 +107,6 @@
(void)acpicpu_pstate_max(sc);
sc->sc_flags |= ACPICPU_FLAG_P;
- sc->sc_pstate_current = sc->sc_pstate[0].ps_freq;
acpicpu_pstate_bios();
acpicpu_pstate_attach_evcnt(sc);
@@ -225,13 +226,35 @@
acpicpu_pstate_start(device_t self)
{
struct acpicpu_softc *sc = device_private(self);
+ struct acpicpu_pstate *ps;
+ uint32_t i;
int rv;
rv = acpicpu_md_pstate_start();
- if (rv == 0)
- return;
+ if (rv != 0)
+ goto fail;
+
+ /*
+ * Initialize the state to the maximum.
+ */
+ for (i = 0, rv = ENXIO; i < sc->sc_pstate_count; i++) {
+
+ ps = &sc->sc_pstate[i];
+ if (ps->ps_freq != 0) {
+ sc->sc_cold = false;
+ rv = acpicpu_pstate_set(sc, ps->ps_freq);
+ break;
+ }
+ }
+
+ if (rv != 0)
+ goto fail;
+
+ return;
+
+fail:
sc->sc_flags &= ~ACPICPU_FLAG_P;
aprint_error_dev(self, "failed to start P-states (err %d)\n", rv);
}
@@ -239,6 +262,40 @@
bool
acpicpu_pstate_suspend(device_t self)
{
+ struct acpicpu_softc *sc = device_private(self);
+ struct acpicpu_pstate *ps = NULL;
+ int32_t i;
+
+ if (acpicpu_pstate_saved != 0)
+ return true;
+
+ /*
+ * Following design notes for Windows, we set the highest
+ * P-state when entering any of the system sleep states.
+ * When resuming, the saved P-state will be restored.
+ *
+ * Microsoft Corporation: Windows Native Processor
+ * Performance Control. Version 1.1a, November, 2002.
+ */
+ for (i = sc->sc_pstate_count - 1; i >= 0; i--) {
+
+ if (sc->sc_pstate[i].ps_freq != 0) {
+ ps = &sc->sc_pstate[i];
+ break;
+ }
+ }
+
+ if (__predict_false(ps == NULL))
+ return true;
+
+ mutex_enter(&sc->sc_mtx);
+ acpicpu_pstate_saved = sc->sc_pstate_current;
+ mutex_exit(&sc->sc_mtx);
+
+ if (acpicpu_pstate_saved == ps->ps_freq)
+ return true;
+
+ (void)acpicpu_pstate_set(sc, ps->ps_freq);
return true;
}
@@ -246,6 +303,12 @@
bool
acpicpu_pstate_resume(device_t self)
{
+ struct acpicpu_softc *sc = device_private(self);
+
+ if (acpicpu_pstate_saved != 0) {
+ (void)acpicpu_pstate_set(sc, acpicpu_pstate_saved);
+ acpicpu_pstate_saved = 0;
+ }
acpicpu_pstate_callback(self);
@@ -278,7 +341,7 @@
* If the maximum changed, proactively
* raise or lower the target frequency.
*/
- acpicpu_pstate_set(sc, sc->sc_pstate[new].ps_freq);
+ (void)acpicpu_pstate_set(sc, sc->sc_pstate[new].ps_freq);
#endif
}
Home |
Main Index |
Thread Index |
Old Index