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) {

Reply via email to