Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/acpi Add support for the optional dynamic minimum (i...



details:   https://anonhg.NetBSD.org/src/rev/8a2f59119cfd
branches:  trunk
changeset: 757165:8a2f59119cfd
user:      jruoho <jruoho%NetBSD.org@localhost>
date:      Tue Aug 17 10:17:52 2010 +0000

description:
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)

diffstat:

 sys/dev/acpi/acpi_cpu.c        |   5 +-
 sys/dev/acpi/acpi_cpu.h        |   4 +-
 sys/dev/acpi/acpi_cpu_pstate.c |  71 +++++++++++++++++++++++++++++++++--------
 sys/dev/acpi/acpi_cpu_tstate.c |  23 +++++++++----
 4 files changed, 78 insertions(+), 25 deletions(-)

diffs (271 lines):

diff -r cc600007b945 -r 8a2f59119cfd sys/dev/acpi/acpi_cpu.c
--- a/sys/dev/acpi/acpi_cpu.c   Tue Aug 17 08:40:57 2010 +0000
+++ b/sys/dev/acpi/acpi_cpu.c   Tue Aug 17 10:17:52 2010 +0000
@@ -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 <jruohonen%iki.fi@localhost>
@@ -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);
diff -r cc600007b945 -r 8a2f59119cfd sys/dev/acpi/acpi_cpu.h
--- a/sys/dev/acpi/acpi_cpu.h   Tue Aug 17 08:40:57 2010 +0000
+++ b/sys/dev/acpi/acpi_cpu.h   Tue Aug 17 10:17:52 2010 +0000
@@ -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 <jruohonen%iki.fi@localhost>
@@ -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);
diff -r cc600007b945 -r 8a2f59119cfd sys/dev/acpi/acpi_cpu_pstate.c
--- a/sys/dev/acpi/acpi_cpu_pstate.c    Tue Aug 17 08:40:57 2010 +0000
+++ b/sys/dev/acpi/acpi_cpu_pstate.c    Tue Aug 17 10:17:52 2010 +0000
@@ -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 <jruohonen%iki.fi@localhost>
@@ -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 (sc->sc_pstate[val].ps_freq != 0) {
+                       sc->sc_pstate_max = val;
+                       return 0;
+               }
+       }
 
-       if (ACPI_FAILURE(rv))
-               return 1;
+       return 1;
+}
+
+static int
+acpicpu_pstate_min(struct acpicpu_softc *sc)
+{
+       ACPI_INTEGER val;
+       ACPI_STATUS rv;
 
-       if (val > sc->sc_pstate_count - 1)
-               return 1;
+       /*
+        * 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);
+
+       if (ACPI_SUCCESS(rv) && val < sc->sc_pstate_count) {
 
-       if (sc->sc_pstate[val].ps_freq == 0)
-               return 1;
+               if (sc->sc_pstate[val].ps_freq == 0)
+                       return 1;
 
-       sc->sc_pstate_max = val;
+               if (val >= sc->sc_pstate_max) {
+                       sc->sc_pstate_min = val;
+                       return 0;
+               }
+       }
 
-       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;
diff -r cc600007b945 -r 8a2f59119cfd sys/dev/acpi/acpi_cpu_tstate.c
--- a/sys/dev/acpi/acpi_cpu_tstate.c    Tue Aug 17 08:40:57 2010 +0000
+++ b/sys/dev/acpi/acpi_cpu_tstate.c    Tue Aug 17 10:17:52 2010 +0000
@@ -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 <jruohonen%iki.fi@localhost>
@@ -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) {



Home | Main Index | Thread Index | Old Index