aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Wawrzynczak <twawrzynczak@chromium.org>2020-05-29 14:39:02 -0600
committerPatrick Georgi <pgeorgi@google.com>2020-07-07 17:23:01 +0000
commit2ad8ffed6fc3d0865d8dc066dcbf6ef2e369794c (patch)
tree65b322f3ee2f04ab8ca8bfbf632ba260426cb4dd
parent46f6fcf88f2db397759f69d0c7ddf11d88b61e03 (diff)
dptf: Add support for Fan Performance States
This change adds support for generating the _FPS table for the DPTF Fan object. The table describes different levels of fan activity that may be applied to the system in order to actively cool it. The information includes fan speed at a (rough) percentage level, fan speed in RPM, potential noise level in centibels, and power in mA. BUG=b:143539650 TEST=compiles Change-Id: I5591eb527f496d0c4c613352d2a87625d47d9273 Signed-off-by: Tim Wawrzynczak <twawrzynczak@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/41889 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
-rw-r--r--src/acpi/acpigen_dptf.c37
-rw-r--r--src/drivers/intel/dptf/chip.h1
-rw-r--r--src/drivers/intel/dptf/dptf.c1
-rw-r--r--src/include/acpi/acpigen_dptf.h27
4 files changed, 66 insertions, 0 deletions
diff --git a/src/acpi/acpigen_dptf.c b/src/acpi/acpigen_dptf.c
index c18caf673e..6caf8bfcaf 100644
--- a/src/acpi/acpigen_dptf.c
+++ b/src/acpi/acpigen_dptf.c
@@ -12,6 +12,7 @@
enum {
ART_REVISION = 0,
DEFAULT_PRIORITY = 100,
+ DEFAULT_TRIP_POINT = 0xFFFFFFFFull,
DEFAULT_WEIGHT = 100,
DPTF_MAX_ART_THRESHOLDS = 10,
};
@@ -321,3 +322,39 @@ void dptf_write_charger_perf(const struct dptf_charger_perf *states, int max_cou
acpigen_pop_len(); /* Method PPSS */
acpigen_pop_len(); /* Scope */
}
+
+void dptf_write_fan_perf(const struct dptf_fan_perf *states, int max_count)
+{
+ char *pkg_count;
+ int i;
+
+ if (!max_count || !states[0].percent)
+ return;
+
+ dptf_write_scope(DPTF_FAN);
+
+ /* _FPS - Fan Performance States */
+ acpigen_write_name("_FPS");
+ pkg_count = acpigen_write_package(0);
+
+ for (i = 0; i < max_count; ++i) {
+ /*
+ * Some _FPS tables do include a last entry where Percent is 0, but Power is
+ * called out, so this table is finished when both are zero.
+ */
+ if (!states[i].percent && !states[i].power)
+ break;
+
+ (*pkg_count)++;
+ acpigen_write_package(5);
+ acpigen_write_integer(states[i].percent);
+ acpigen_write_integer(DEFAULT_TRIP_POINT);
+ acpigen_write_integer(states[i].speed);
+ acpigen_write_integer(states[i].noise_level);
+ acpigen_write_integer(states[i].power);
+ acpigen_pop_len(); /* inner Package */
+ }
+
+ acpigen_pop_len(); /* Package */
+ acpigen_pop_len(); /* Scope */
+}
diff --git a/src/drivers/intel/dptf/chip.h b/src/drivers/intel/dptf/chip.h
index 528ba8354e..cc4ae47caf 100644
--- a/src/drivers/intel/dptf/chip.h
+++ b/src/drivers/intel/dptf/chip.h
@@ -14,6 +14,7 @@ struct drivers_intel_dptf_config {
struct {
struct dptf_charger_perf charger_perf[DPTF_MAX_CHARGER_PERF_STATES];
+ struct dptf_fan_perf fan_perf[DPTF_MAX_FAN_PERF_STATES];
} controls;
};
diff --git a/src/drivers/intel/dptf/dptf.c b/src/drivers/intel/dptf/dptf.c
index a20087fff3..bfc04200e0 100644
--- a/src/drivers/intel/dptf/dptf.c
+++ b/src/drivers/intel/dptf/dptf.c
@@ -74,6 +74,7 @@ static void dptf_fill_ssdt(const struct device *dev)
/* Controls */
dptf_write_charger_perf(config->controls.charger_perf, DPTF_MAX_CHARGER_PERF_STATES);
+ dptf_write_fan_perf(config->controls.fan_perf, DPTF_MAX_FAN_PERF_STATES);
printk(BIOS_INFO, "\\_SB.DPTF: %s at %s\n", dev->chip_ops->name, dev_path(dev));
}
diff --git a/src/include/acpi/acpigen_dptf.h b/src/include/acpi/acpigen_dptf.h
index 7588752aac..3452f79578 100644
--- a/src/include/acpi/acpigen_dptf.h
+++ b/src/include/acpi/acpigen_dptf.h
@@ -32,6 +32,10 @@ enum {
/* Maximum found by automatic inspection (awk) */
DPTF_MAX_CHARGER_PERF_STATES = 10,
+ DPTF_MAX_FAN_PERF_STATES = 10,
+
+ /* From ACPI spec 6.3 */
+ DPTF_FIELD_UNUSED = 0xFFFFFFFFull,
};
/* Active Policy */
@@ -87,6 +91,18 @@ struct dptf_charger_perf {
uint16_t raw_perf;
};
+/* Different levels of fan activity, chosen by active policies */
+struct dptf_fan_perf {
+ /* Fan percentage level */
+ uint8_t percent;
+ /* Fan speed, in RPM */
+ uint16_t speed;
+ /* Noise level, in 0.1 dBs */
+ uint16_t noise_level;
+ /* Power in mA */
+ uint16_t power;
+};
+
/*
* This function provides tables of temperature and corresponding fan or percent. When the
* temperature thresholds are met (_AC0 - _AC9), the fan is driven to corresponding percentage
@@ -115,6 +131,17 @@ void dptf_write_critical_policies(const struct dptf_critical_policy *policies, i
*/
void dptf_write_charger_perf(const struct dptf_charger_perf *perf, int max_count);
+/*
+ * This function writes an ACPI table describing various performance levels possible for active
+ * policies. They indicate, for a given fan percentage level:
+ * 1) What the corresponding speed is (in RPM)
+ * 2) The expected noise level (in tenths of decibels AKA centibels, or DPTF_FIELD_UNUSED)
+ * 3) The power consumption (in mW, or DPTF_FIELD_UNUSED to indicate this field is unused).
+ * 4) The corresponding active cooling trip point (from _ART) (typically left as
+ * DPTF_FIELD_UNUSED).
+ */
+void dptf_write_fan_perf(const struct dptf_fan_perf *perf, int max_count);
+
/* Helper method to open the scope for a given participant. */
void dptf_write_scope(enum dptf_participant participant);