Tim Wawrzynczak has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/41890 )
Change subject: dptf: Add support for Running Average Power Limits
......................................................................
dptf: Add support for Running Average Power Limits
This change adds support for emitting the PPCC table, which describes
the ranges available as knobs for DPTF to tune. It can support min/max
power, min/max time window for averaging, and the minimum adjustment size
(granularity or step size) of each power limit. The current implementation
only supports PL1 and PL2.
BUG=b:143539650
TEST=compiles
Change-Id: I67e80d661ea5bb79980ef285eca40c9a4b0f1849
Signed-off-by: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
---
M src/acpi/acpigen_dptf.c
M src/drivers/intel/dptf/chip.h
M src/drivers/intel/dptf/dptf.c
M src/include/acpi/acpigen_dptf.h
4 files changed, 73 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/90/41890/1
diff --git a/src/acpi/acpigen_dptf.c b/src/acpi/acpigen_dptf.c
index 0aebf8f..18b5a6c 100644
--- a/src/acpi/acpigen_dptf.c
+++ b/src/acpi/acpigen_dptf.c
@@ -22,6 +22,7 @@
DEFAULT_TRIP_POINT = 0xFFFFFFFFull,
DEFAULT_WEIGHT = 100,
DPTF_MAX_ART_THRESHOLDS = 10,
+ PPCC_REVISION = 2,
};
/* Convert degrees C to 1/10 degree Kelvin for ACPI */
@@ -416,3 +417,46 @@
acpigen_pop_len(); /* Package */
acpigen_pop_len(); /* Scope */
}
+
+void dptf_write_power_limits(const struct dptf_power_limits *limits)
+{
+ char *pkg_count;
+
+ /* Nothing to do */
+ if (!limits->pl1.min_power && !limits->pl2.min_power)
+ return;
+
+ dptf_write_scope(DPTF_CPU);
+ acpigen_write_method("PPCC", 0);
+
+ pkg_count = acpigen_write_package(1); /* 1 for the Revision */
+ acpigen_write_integer(PPCC_REVISION); /* revision */
+
+ if (limits->pl1.min_power) {
+ (*pkg_count)++;
+ acpigen_write_package(6);
+ acpigen_write_integer(0); /* PL1_INDEX */
+ acpigen_write_integer(limits->pl1.min_power);
+ acpigen_write_integer(limits->pl1.max_power);
+ acpigen_write_integer(limits->pl1.time_window_min);
+ acpigen_write_integer(limits->pl1.time_window_max);
+ acpigen_write_integer(limits->pl1.granularity);
+ acpigen_pop_len(); /* inner Package */
+ }
+
+ if (limits->pl2.min_power) {
+ (*pkg_count)++;
+ acpigen_write_package(6);
+ acpigen_write_integer(1); /* PL2_INDEX */
+ acpigen_write_integer(limits->pl1.min_power);
+ acpigen_write_integer(limits->pl1.max_power);
+ acpigen_write_integer(limits->pl1.time_window_min);
+ acpigen_write_integer(limits->pl1.time_window_max);
+ acpigen_write_integer(limits->pl1.granularity);
+ acpigen_pop_len(); /* inner Package */
+ }
+
+ acpigen_pop_len(); /* outer Package */
+ acpigen_pop_len(); /* Method */
+ acpigen_pop_len(); /* Scope */
+}
diff --git a/src/drivers/intel/dptf/chip.h b/src/drivers/intel/dptf/chip.h
index cffc74d..5ea32d9 100644
--- a/src/drivers/intel/dptf/chip.h
+++ b/src/drivers/intel/dptf/chip.h
@@ -17,6 +17,7 @@
struct {
struct dptf_charger_perf charger_perf[DPTF_MAX_CHARGER_PERF_STATES];
struct dptf_fan_perf fan_perf[DPTF_MAX_FAN_PERF_STATES];
+ struct dptf_power_limits power_limits;
} controls;
};
diff --git a/src/drivers/intel/dptf/dptf.c b/src/drivers/intel/dptf/dptf.c
index c075ef1..70af050 100644
--- a/src/drivers/intel/dptf/dptf.c
+++ b/src/drivers/intel/dptf/dptf.c
@@ -76,6 +76,7 @@
/* 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);
+ dptf_write_power_limits(&config->controls.power_limits);
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 dd608d3..33a9961 100644
--- a/src/include/acpi/acpigen_dptf.h
+++ b/src/include/acpi/acpigen_dptf.h
@@ -110,6 +110,26 @@
uint16_t power;
};
+/* Running Average Power Limits (RAPL) */
+struct dptf_power_limit_config {
+ /* Minimum level of power limit, in mW */
+ uint32_t min_power;
+ /* Maximum level of power limit, in mW */
+ uint32_t max_power;
+ /* Minimum time window running average is over, in seconds */
+ uint32_t time_window_min;
+ /* Maximum time window running average is over, in seconds */
+ uint32_t time_window_max;
+ /* Granularity of the power limit setting (between min and max), in mW */
+ uint16_t granularity;
+};
+
+/* Only PL1 and PL2 are controllable via DPTF */
+struct dptf_power_limits {
+ struct dptf_power_limit_config pl1;
+ struct dptf_power_limit_config pl2;
+};
+
/*
* This function writes out \_SB.DPTF.IDSP, which describes the different DPTF policies that
* this implementation is using.
@@ -155,6 +175,13 @@
*/
void dptf_write_fan_perf(const struct dptf_fan_perf *perf, int max_count);
+/*
+ * This function writes out a PPCC table, which indicates power ranges that different Intel
+ * RAPLs can take, as well as the time period they average over and the minimum adjustment
+ * amount.
+ */
+void dptf_write_power_limits(const struct dptf_power_limits *limits);
+
/* Helper method to open the scope for a given participant. */
void dptf_write_scope(enum dptf_participant participant);
--
To view, visit https://review.coreboot.org/c/coreboot/+/41890
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I67e80d661ea5bb79980ef285eca40c9a4b0f1849
Gerrit-Change-Number: 41890
Gerrit-PatchSet: 1
Gerrit-Owner: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
Gerrit-Reviewer: Patrick Rudolph <siro(a)das-labor.org>
Gerrit-MessageType: newchange
Tim Wawrzynczak has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/41889 )
Change subject: dptf: Add support for Fan Performance States
......................................................................
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(a)chromium.org>
---
M src/acpi/acpigen_dptf.c
M src/drivers/intel/dptf/chip.h
M src/drivers/intel/dptf/dptf.c
M src/include/acpi/acpigen_dptf.h
4 files changed, 63 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/89/41889/1
diff --git a/src/acpi/acpigen_dptf.c b/src/acpi/acpigen_dptf.c
index db5d676..0aebf8f 100644
--- a/src/acpi/acpigen_dptf.c
+++ b/src/acpi/acpigen_dptf.c
@@ -19,6 +19,7 @@
enum {
ART_REVISION = 0,
DEFAULT_PRIORITY = 100,
+ DEFAULT_TRIP_POINT = 0xFFFFFFFFull,
DEFAULT_WEIGHT = 100,
DPTF_MAX_ART_THRESHOLDS = 10,
};
@@ -382,3 +383,36 @@
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)
+ {
+ if (!states[i].percent)
+ 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 f13acee..cffc74d 100644
--- a/src/drivers/intel/dptf/chip.h
+++ b/src/drivers/intel/dptf/chip.h
@@ -16,6 +16,7 @@
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 ce77d1c..c075ef1 100644
--- a/src/drivers/intel/dptf/dptf.c
+++ b/src/drivers/intel/dptf/dptf.c
@@ -75,6 +75,7 @@
/* 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 344337d..dd608d3 100644
--- a/src/include/acpi/acpigen_dptf.h
+++ b/src/include/acpi/acpigen_dptf.h
@@ -32,6 +32,10 @@
/* 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,
};
/* Which policies are enabled? */
@@ -94,6 +98,18 @@
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 writes out \_SB.DPTF.IDSP, which describes the different DPTF policies that
* this implementation is using.
@@ -128,6 +144,17 @@
*/
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);
--
To view, visit https://review.coreboot.org/c/coreboot/+/41889
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I5591eb527f496d0c4c613352d2a87625d47d9273
Gerrit-Change-Number: 41889
Gerrit-PatchSet: 1
Gerrit-Owner: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
Gerrit-Reviewer: Patrick Rudolph <siro(a)das-labor.org>
Gerrit-MessageType: newchange
Tim Wawrzynczak has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/41887 )
Change subject: dptf: Add support for Critical Policies
......................................................................
dptf: Add support for Critical Policies
This patch adds support for DPTF Critical Policies, which are consist
of Method definitions only. They are `_CRT` and `_HOT`, which are
defined as temperature thresholds that, when exceeded, will execute a
graceful suspend or a graceful shutdown, respectively.
BUG=b:143539650
TEST=compiles
Change-Id: I711ecdcf17ae8f6e653f33069201da4515ace85e
Signed-off-by: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
---
M src/acpi/acpigen_dptf.c
M src/drivers/intel/dptf/chip.h
M src/drivers/intel/dptf/dptf.c
M src/include/acpi/acpigen_dptf.h
4 files changed, 52 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/87/41887/1
diff --git a/src/acpi/acpigen_dptf.c b/src/acpi/acpigen_dptf.c
index e2e6015..aff0b2d 100644
--- a/src/acpi/acpigen_dptf.c
+++ b/src/acpi/acpigen_dptf.c
@@ -323,3 +323,21 @@
write_thermal_relationship_table(policies, max_count);
write_all_PSV(policies, max_count);
}
+
+void dptf_write_critical_policies(const struct dptf_critical_policy *policies, int max_count)
+{
+ int i;
+
+ for (i = 0; i < max_count; ++i) {
+ if (policies[i].source == DPTF_NONE)
+ break;
+
+ dptf_write_scope(policies[i].source);
+
+ /* Choose _CRT or _HOT */
+ write_simple_return_method(policies[i].type == DPTF_CRITICAL_SUSPEND ?
+ "_CRT" : "_HOT", to_acpi_temp(policies[i].temp));
+
+ acpigen_pop_len(); /* Scope */
+ }
+}
diff --git a/src/drivers/intel/dptf/chip.h b/src/drivers/intel/dptf/chip.h
index 98bb7d8..aa87e0d 100644
--- a/src/drivers/intel/dptf/chip.h
+++ b/src/drivers/intel/dptf/chip.h
@@ -10,6 +10,7 @@
struct {
struct dptf_enabled_policies enabled;
struct dptf_active_policy active[DPTF_MAX_ACTIVE_POLICIES];
+ struct dptf_critical_policy critical[DPTF_MAX_CRITICAL_POLICIES];
struct dptf_passive_policy passive[DPTF_MAX_PASSIVE_POLICIES];
} policies;
};
diff --git a/src/drivers/intel/dptf/dptf.c b/src/drivers/intel/dptf/dptf.c
index df0d428..3a3af68 100644
--- a/src/drivers/intel/dptf/dptf.c
+++ b/src/drivers/intel/dptf/dptf.c
@@ -36,6 +36,11 @@
config->policies.passive[i].target == participant)
return true;
+ /* Critical? */
+ for (i = 0; i < DPTF_MAX_CRITICAL_POLICIES; ++i)
+ if (config->policies.critical[i].source == participant)
+ return true;
+
/* Check fan as well (it's use is implicit in the Active policy) */
if (participant == DPTF_FAN && config->policies.enabled.active)
return true;
@@ -64,6 +69,10 @@
dptf_write_passive_policies(config->policies.passive,
DPTF_MAX_PASSIVE_POLICIES);
+ if (config->policies.enabled.critical)
+ dptf_write_critical_policies(config->policies.critical,
+ DPTF_MAX_CRITICAL_POLICIES);
+
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 3313fbb..14ad2fa 100644
--- a/src/include/acpi/acpigen_dptf.h
+++ b/src/include/acpi/acpigen_dptf.h
@@ -28,6 +28,7 @@
DPTF_MAX_ACX = 10,
DPTF_MAX_ACTIVE_POLICIES = (DPTF_PARTICIPANT_COUNT-1),
DPTF_MAX_PASSIVE_POLICIES = (DPTF_PARTICIPANT_COUNT-1),
+ DPTF_MAX_CRITICAL_POLICIES = (DPTF_PARTICIPANT_COUNT-1),
};
/* Which policies are enabled? */
@@ -66,6 +67,22 @@
uint8_t priority;
};
+/* Critical Policy type: graceful suspend or graceful shutdown */
+enum dptf_critical_policy_type {
+ DPTF_CRITICAL_SUSPEND,
+ DPTF_CRITICAL_SHUTDOWN,
+};
+
+/* Critical Policy */
+struct dptf_critical_policy {
+ /* The device that can trigger a critical event */
+ enum dptf_participant source;
+ /* What type of critical policy */
+ enum dptf_critical_policy_type type;
+ /* Temperature to activate policy, degrees C */
+ uint8_t temp;
+};
+
/*
* This function writes out \_SB.DPTF.IDSP, which describes the different DPTF policies that
* this implementation is using.
@@ -87,6 +104,13 @@
*/
void dptf_write_passive_policies(const struct dptf_passive_policy *policies, int max_count);
+/*
+ * Critical policies are temperature thresholds that, when reached, will cause the system to
+ * take some emergency action in order to eliminate excess temperatures from damaging the
+ * system. The emergency actions are a graceful suspend or a graceful shutdown.
+ */
+void dptf_write_critical_policies(const struct dptf_critical_policy *policies, int max_count);
+
/* Helper method to open the scope for a given participant. */
void dptf_write_scope(enum dptf_participant participant);
--
To view, visit https://review.coreboot.org/c/coreboot/+/41887
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I711ecdcf17ae8f6e653f33069201da4515ace85e
Gerrit-Change-Number: 41887
Gerrit-PatchSet: 1
Gerrit-Owner: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
Gerrit-Reviewer: Patrick Rudolph <siro(a)das-labor.org>
Gerrit-MessageType: newchange
Tim Wawrzynczak has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/41886 )
Change subject: dptf: Add support for Passive Policies
......................................................................
dptf: Add support for Passive Policies
This patch adds support for emitting the Thermal Relationship Table, as
well as _PSV Methods, which together form the basis for DPTF Passive
Policies.
BUG=b:143539650
TEST=compiles
Change-Id: I82e1c9022999b0a2a733aa6cd9c98a850e6f5408
Signed-off-by: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
---
M src/acpi/acpigen_dptf.c
M src/drivers/intel/dptf/chip.h
M src/drivers/intel/dptf/dptf.c
M src/include/acpi/acpigen_dptf.h
4 files changed, 130 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/86/41886/1
diff --git a/src/acpi/acpigen_dptf.c b/src/acpi/acpigen_dptf.c
index dfe5337..e2e6015 100644
--- a/src/acpi/acpigen_dptf.c
+++ b/src/acpi/acpigen_dptf.c
@@ -16,6 +16,7 @@
/* Defaults */
enum {
ART_REVISION = 0,
+ DEFAULT_PRIORITY = 100,
DEFAULT_WEIGHT = 100,
DPTF_MAX_ART_THRESHOLDS = 10,
};
@@ -26,6 +27,12 @@
return deg_c * 10 + 2732;
}
+/* Converts ms to 1/10th second for ACPI */
+static int to_acpi_time(int ms)
+{
+ return ms / 100;
+}
+
/* Writes out a 0-argument non-Serialized Method that returns an Integer */
static void write_simple_return_method(const char *name, int value)
{
@@ -34,6 +41,13 @@
acpigen_pop_len(); /* Method */
}
+/* Writes out 'count' ZEROs in a row */
+static void write_zeros(int count)
+{
+ for (; count; --count)
+ acpigen_write_integer(0);
+}
+
/* Return the assigned namestring of any participant */
static const char *namestring_of(enum dptf_participant participant)
{
@@ -227,3 +241,85 @@
write_active_relationship_table(policies, max_count);
write_active_cooling_methods(policies, max_count);
}
+
+/*
+ * This writes out the Thermal Relationship Table, which describes the thermal relationships
+ * between participants in a thermal zone. This information is used to passively cool (i.e., throttle)
+ * the Source (source of heat), in order to indirectly cool the Target (temperature sensor).
+ */
+static void write_thermal_relationship_table(const struct dptf_passive_policy *policies, int max_count)
+{
+ char *pkg_count;
+ int i;
+
+ /* Nothing to do */
+ if (!max_count || policies[0].source == DPTF_NONE)
+ return;
+
+ acpigen_write_scope(TOPLEVEL_DPTF_SCOPE);
+
+ /*
+ * A _TRT Revision (TRTR) of 1 means that the 'Priority' field is an arbitrary priority
+ * value to be used for this specific relationship. The priority value determines the
+ * order in which various sources are used in a passive thermal action for a given
+ * target.
+ */
+ acpigen_write_name_integer("TRTR", 1);
+
+ /* Thermal Relationship Table */
+ acpigen_write_method("_TRT", 0);
+
+ /* Return this package */
+ acpigen_emit_byte(RETURN_OP);
+ pkg_count = acpigen_write_package(0);
+
+ for (i = 0; i < max_count; ++i) {
+ /* Stop writing the table once an entry is empty */
+ if (policies[i].source == DPTF_NONE)
+ break;
+
+ /* Keep track of outer package item count */
+ (*pkg_count)++;
+
+ acpigen_write_package(8);
+
+ /* Source, Target, Priority, Sampling Period */
+ acpigen_emit_namestring(namestring_of(policies[i].source));
+ acpigen_emit_namestring(namestring_of(policies[i].target));
+ acpigen_write_integer(DEFAULT_IF_0(policies[i].priority, DEFAULT_PRIORITY));
+ acpigen_write_integer(to_acpi_time(policies[i].period));
+
+ /* Reserved */
+ write_zeros(4);
+
+ acpigen_pop_len(); /* Package */
+ }
+
+ acpigen_pop_len(); /* Package */
+ acpigen_pop_len(); /* Method */
+ acpigen_pop_len(); /* Scope */
+}
+
+/*
+ * When a temperature sensor measures above its the temperature returned in its _PSV Method,
+ * DPTF will begin throttling Sources in order to indirectly cool the sensor.
+ */
+static void write_all_PSV(const struct dptf_passive_policy *policies, int max_count)
+{
+ int i;
+
+ for (i = 0; i < max_count; ++i) {
+ if (policies[i].source == DPTF_NONE)
+ break;
+
+ dptf_write_scope(policies[i].target);
+ write_simple_return_method("_PSV", to_acpi_temp(policies[i].temp));
+ acpigen_pop_len(); /* Scope */
+ }
+}
+
+void dptf_write_passive_policies(const struct dptf_passive_policy *policies, int max_count)
+{
+ write_thermal_relationship_table(policies, max_count);
+ write_all_PSV(policies, max_count);
+}
diff --git a/src/drivers/intel/dptf/chip.h b/src/drivers/intel/dptf/chip.h
index bc4235e..98bb7d8 100644
--- a/src/drivers/intel/dptf/chip.h
+++ b/src/drivers/intel/dptf/chip.h
@@ -10,6 +10,7 @@
struct {
struct dptf_enabled_policies enabled;
struct dptf_active_policy active[DPTF_MAX_ACTIVE_POLICIES];
+ struct dptf_passive_policy passive[DPTF_MAX_PASSIVE_POLICIES];
} policies;
};
diff --git a/src/drivers/intel/dptf/dptf.c b/src/drivers/intel/dptf/dptf.c
index a3764fa..df0d428 100644
--- a/src/drivers/intel/dptf/dptf.c
+++ b/src/drivers/intel/dptf/dptf.c
@@ -30,6 +30,12 @@
if (config->policies.active[i].target == participant)
return true;
+ /* Passive? */
+ for (i = 0; i < DPTF_MAX_PASSIVE_POLICIES; ++i)
+ if (config->policies.passive[i].source == participant ||
+ config->policies.passive[i].target == participant)
+ return true;
+
/* Check fan as well (it's use is implicit in the Active policy) */
if (participant == DPTF_FAN && config->policies.enabled.active)
return true;
@@ -54,6 +60,10 @@
dptf_write_active_policies(config->policies.active,
DPTF_MAX_ACTIVE_POLICIES);
+ if (config->policies.enabled.passive)
+ dptf_write_passive_policies(config->policies.passive,
+ DPTF_MAX_PASSIVE_POLICIES);
+
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 24dc279..3313fbb 100644
--- a/src/include/acpi/acpigen_dptf.h
+++ b/src/include/acpi/acpigen_dptf.h
@@ -27,6 +27,7 @@
/* A device can only define _AC0 .. _AC9 (i.e., 10) Active Cooling Methods */
DPTF_MAX_ACX = 10,
DPTF_MAX_ACTIVE_POLICIES = (DPTF_PARTICIPANT_COUNT-1),
+ DPTF_MAX_PASSIVE_POLICIES = (DPTF_PARTICIPANT_COUNT-1),
};
/* Which policies are enabled? */
@@ -51,6 +52,20 @@
} thresholds [DPTF_MAX_ACX];
};
+/* Passive Policy */
+struct dptf_passive_policy {
+ /* The device that can be throttled */
+ enum dptf_participant source;
+ /* The device that controls the throttling */
+ enum dptf_participant target;
+ /* How often to check the temperature for required throttling (ms) */
+ uint16_t period;
+ /* The trip point for turning on throttling (degrees C) */
+ uint8_t temp;
+ /* Relative priority between Policies */
+ uint8_t priority;
+};
+
/*
* This function writes out \_SB.DPTF.IDSP, which describes the different DPTF policies that
* this implementation is using.
@@ -64,6 +79,14 @@
*/
void dptf_write_active_policies(const struct dptf_active_policy *policies, int max_count);
+/*
+ * This function uses the definition of the passive policies to write out _PSV Methods on all
+ * participants that define it. It also writes out the Thermal Relationship Table
+ * (\_SB.DPTF._TRT), which describes various passive (i.e., throttling) policies that can be
+ * applies when temperature sensors reach the _PSV threshold.
+ */
+void dptf_write_passive_policies(const struct dptf_passive_policy *policies, int max_count);
+
/* Helper method to open the scope for a given participant. */
void dptf_write_scope(enum dptf_participant participant);
--
To view, visit https://review.coreboot.org/c/coreboot/+/41886
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I82e1c9022999b0a2a733aa6cd9c98a850e6f5408
Gerrit-Change-Number: 41886
Gerrit-PatchSet: 1
Gerrit-Owner: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
Gerrit-Reviewer: Patrick Rudolph <siro(a)das-labor.org>
Gerrit-MessageType: newchange
Tim Wawrzynczak has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/41885 )
Change subject: dptf: Add support for generation of Active Policies
......................................................................
dptf: Add support for generation of Active Policies
This change adds support for generating the different pieces of DPTF
Active Policies. This includes the Active Relationship Table, in
addition to _ACx methods.
BUG=b:143539650
TEST=compiles
Change-Id: Iea0ccbd96f88d0f3a8f2c77a7d0f3a284e5ee463
Signed-off-by: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
---
M src/acpi/acpigen_dptf.c
M src/drivers/intel/dptf/chip.h
M src/drivers/intel/dptf/dptf.c
M src/include/acpi/acpigen_dptf.h
4 files changed, 204 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/85/41885/1
diff --git a/src/acpi/acpigen_dptf.c b/src/acpi/acpigen_dptf.c
index d0827b6..dfe5337 100644
--- a/src/acpi/acpigen_dptf.c
+++ b/src/acpi/acpigen_dptf.c
@@ -13,6 +13,70 @@
#define DPTF_CRITICAL_POLICY_UUID "97C68AE7-15FA-499c-B8C9-5DA81D606E0A"
#define DPTF_ACTIVE_POLICY_UUID "3A95C389-E4B8-4629-A526-C52C88626BAE"
+/* Defaults */
+enum {
+ ART_REVISION = 0,
+ DEFAULT_WEIGHT = 100,
+ DPTF_MAX_ART_THRESHOLDS = 10,
+};
+
+/* Convert degrees C to 1/10 degree Kelvin for ACPI */
+static int to_acpi_temp(int deg_c)
+{
+ return deg_c * 10 + 2732;
+}
+
+/* Writes out a 0-argument non-Serialized Method that returns an Integer */
+static void write_simple_return_method(const char *name, int value)
+{
+ acpigen_write_method(name, 0);
+ acpigen_write_return_integer(value);
+ acpigen_pop_len(); /* Method */
+}
+
+/* Return the assigned namestring of any participant */
+static const char *namestring_of(enum dptf_participant participant)
+{
+ switch (participant) {
+ case DPTF_CPU:
+ return "TCPU";
+ case DPTF_CHARGER:
+ return "TCHG";
+ case DPTF_FAN:
+ return "TFN1";
+ case DPTF_TSR0:
+ return "TSR0";
+ case DPTF_TSR1:
+ return "TSR1";
+ case DPTF_TSR2:
+ return "TSR2";
+ case DPTF_TSR3:
+ return "TSR3";
+ default:
+ return "";
+ }
+}
+
+/* Helper to get Scope for participants underneath \_SB.DPTF */
+static const char *scope_of(enum dptf_participant participant)
+{
+ static char scope[16];
+
+ if (participant == DPTF_CPU)
+ snprintf(scope, sizeof(scope), "\\_SB.%s", namestring_of(participant));
+ else
+ snprintf(scope, sizeof(scope), TOPLEVEL_DPTF_SCOPE ".%s",
+ namestring_of(participant));
+
+ return scope;
+}
+
+/* Write out scope of a participant */
+void dptf_write_scope(enum dptf_participant participant)
+{
+ acpigen_write_scope(scope_of(participant));
+}
+
/*
* Almost all Intel boards use a Global NVS field named DPTE.
* Writes out a _STA that checks if \DPTE is 1, and returns 0xF if true, 0x0 otherwise.
@@ -68,3 +132,98 @@
acpigen_pop_len(); /* Package */
acpigen_pop_len(); /* Scope */
}
+
+/*
+ * This table describes active cooling relationships between the system's fan and the
+ * temperature sensors that it can have an effect on. As ever-increasing temperature thresholds
+ * are crossed (_AC9.._AC0, low to high), the corresponding fan percentages listed in this table
+ * are used to increase the speed of the fan in order to speed up cooling.
+ */
+static void write_active_relationship_table(const struct dptf_active_policy *policies, int max_count)
+{
+ char *pkg_count;
+ int i, j;
+
+ /* Nothing to do */
+ if (!max_count || policies[0].target == DPTF_NONE)
+ return;
+
+ acpigen_write_scope(TOPLEVEL_DPTF_SCOPE);
+ acpigen_write_method("_ART", 0);
+
+ /* Return this package */
+ acpigen_emit_byte(RETURN_OP);
+
+ /* Keep track of items added to the package */
+ pkg_count = acpigen_write_package(1); /* The '1' here is for the revision */
+ acpigen_write_integer(ART_REVISION);
+
+ for (i = 0; i < max_count; ++i)
+ {
+ /*
+ * These have to be filled out from AC0 down to AC9, filling in only as many
+ * as are used. As soon as one isn't filled in, we're done.
+ */
+ if (policies[i].target == DPTF_NONE)
+ break;
+
+ (*pkg_count)++;
+
+ /* Source, Target, Percent, Fan % for each of _AC0 ... _AC9 */
+ acpigen_write_package(13);
+ acpigen_emit_namestring(namestring_of(DPTF_FAN));
+ acpigen_emit_namestring(namestring_of(policies[i].target));
+ acpigen_write_integer(DEFAULT_IF_0(policies[i].weight, DEFAULT_WEIGHT));
+
+ /* Write out fan %; corresponds with target's _ACx methods */
+ for (j = 0; j < DPTF_MAX_ART_THRESHOLDS; ++j)
+ acpigen_write_integer(policies[i].thresholds[j].fan_pct);
+
+ acpigen_pop_len(); /* inner Package */
+ }
+
+ acpigen_pop_len(); /* outer Package */
+ acpigen_pop_len(); /* Method _ART */
+ acpigen_pop_len(); /* Scope */
+}
+
+/*
+ * _AC9 through _AC0 represent temperature thresholds, in increasing order, defined from _AC0
+ * down, that, when reached, DPTF will activate TFN1 in order to actively cool the temperature
+ * sensor(s). As increasing thresholds are reached, the fan is spun faster.
+ */
+static void write_active_cooling_methods(const struct dptf_active_policy *policies,
+ int max_count)
+{
+ char name[5];
+ int i, j;
+
+ /* Nothing to do */
+ if (!max_count || policies[0].target == DPTF_NONE)
+ return;
+
+ for (i = 0; i < max_count; ++i) {
+ if (policies[i].target == DPTF_NONE)
+ break;
+
+ dptf_write_scope(policies[i].target);
+
+ /* Write out as many of _AC0 through _AC9 that are applicable */
+ for (j = 0; j < DPTF_MAX_ACX; ++j) {
+ if (!policies[i].thresholds[j].temp)
+ break;
+
+ snprintf(name, sizeof(name), "_AC%1X", j);
+ write_simple_return_method(name, to_acpi_temp(
+ policies[i].thresholds[j].temp));
+ }
+
+ acpigen_pop_len(); /* Scope */
+ }
+}
+
+void dptf_write_active_policies(const struct dptf_active_policy *policies, int max_count)
+{
+ write_active_relationship_table(policies, max_count);
+ write_active_cooling_methods(policies, max_count);
+}
diff --git a/src/drivers/intel/dptf/chip.h b/src/drivers/intel/dptf/chip.h
index 9ab7963..bc4235e 100644
--- a/src/drivers/intel/dptf/chip.h
+++ b/src/drivers/intel/dptf/chip.h
@@ -9,6 +9,7 @@
struct drivers_intel_dptf_config {
struct {
struct dptf_enabled_policies enabled;
+ struct dptf_active_policy active[DPTF_MAX_ACTIVE_POLICIES];
} policies;
};
diff --git a/src/drivers/intel/dptf/dptf.c b/src/drivers/intel/dptf/dptf.c
index e3e4efd..a3764fa 100644
--- a/src/drivers/intel/dptf/dptf.c
+++ b/src/drivers/intel/dptf/dptf.c
@@ -23,6 +23,17 @@
static bool is_participant_used(const struct drivers_intel_dptf_config *config,
enum dptf_participant participant)
{
+ int i;
+
+ /* Active? */
+ for (i = 0; i < DPTF_MAX_ACTIVE_POLICIES; ++i)
+ if (config->policies.active[i].target == participant)
+ return true;
+
+ /* Check fan as well (it's use is implicit in the Active policy) */
+ if (participant == DPTF_FAN && config->policies.enabled.active)
+ return true;
+
return false;
}
@@ -39,6 +50,10 @@
/* Policies */
dptf_write_enabled_policies(&config->policies.enabled);
+ if (config->policies.enabled.active)
+ dptf_write_active_policies(config->policies.active,
+ DPTF_MAX_ACTIVE_POLICIES);
+
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 f717296..24dc279 100644
--- a/src/include/acpi/acpigen_dptf.h
+++ b/src/include/acpi/acpigen_dptf.h
@@ -22,6 +22,13 @@
DPTF_PARTICIPANT_COUNT,
};
+/* DPTF compile-time constants */
+enum {
+ /* A device can only define _AC0 .. _AC9 (i.e., 10) Active Cooling Methods */
+ DPTF_MAX_ACX = 10,
+ DPTF_MAX_ACTIVE_POLICIES = (DPTF_PARTICIPANT_COUNT-1),
+};
+
/* Which policies are enabled? */
struct dptf_enabled_policies {
bool passive;
@@ -29,12 +36,34 @@
bool active;
};
+/* Active Policy */
+struct dptf_active_policy {
+ /* Device capable of being affected by the fan */
+ enum dptf_participant target;
+ /* */
+ uint8_t weight;
+ /* When target reaches temperature 'temp', the source will turn on at 'fan_pct' % */
+ struct {
+ /* (degrees C) */
+ uint8_t temp;
+ /* 0 - 100 */
+ uint8_t fan_pct;
+ } thresholds [DPTF_MAX_ACX];
+};
+
/*
* This function writes out \_SB.DPTF.IDSP, which describes the different DPTF policies that
* this implementation is using.
*/
void dptf_write_enabled_policies(const struct dptf_enabled_policies *policies);
+/*
+ * 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
+ * of full speed.
+ */
+void dptf_write_active_policies(const struct dptf_active_policy *policies, int max_count);
+
/* Helper method to open the scope for a given participant. */
void dptf_write_scope(enum dptf_participant participant);
--
To view, visit https://review.coreboot.org/c/coreboot/+/41885
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Iea0ccbd96f88d0f3a8f2c77a7d0f3a284e5ee463
Gerrit-Change-Number: 41885
Gerrit-PatchSet: 1
Gerrit-Owner: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
Gerrit-Reviewer: Patrick Rudolph <siro(a)das-labor.org>
Gerrit-MessageType: newchange
Tim Wawrzynczak has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/42878 )
Change subject: soc/intel/{tiger,jasper}lake: Add IPU to soc_acpi_name
......................................................................
soc/intel/{tiger,jasper}lake: Add IPU to soc_acpi_name
For both Tiger Lake and Jasper Lake, add the DEVFN for Image Processing
Unit (IPU) to soc_acpi_name, which is set to return "IPU0".
Change-Id: Ib11be5be7fbaec688d8788945a3bcab3f8d834a1
Signed-off-by: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
---
M src/soc/intel/jasperlake/chip.c
M src/soc/intel/tigerlake/chip.c
2 files changed, 2 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/78/42878/1
diff --git a/src/soc/intel/jasperlake/chip.c b/src/soc/intel/jasperlake/chip.c
index ff63398..0440451 100644
--- a/src/soc/intel/jasperlake/chip.c
+++ b/src/soc/intel/jasperlake/chip.c
@@ -58,6 +58,7 @@
switch (dev->path.pci.devfn) {
case SA_DEVFN_ROOT: return "MCHC";
+ case SA_DEVFN_IPU: return "IPU0";
case PCH_DEVFN_ISH: return "ISHB";
case PCH_DEVFN_XHCI: return "XHCI";
case PCH_DEVFN_I2C0: return "I2C0";
diff --git a/src/soc/intel/tigerlake/chip.c b/src/soc/intel/tigerlake/chip.c
index 00db2a4..d08355e 100644
--- a/src/soc/intel/tigerlake/chip.c
+++ b/src/soc/intel/tigerlake/chip.c
@@ -67,6 +67,7 @@
case SA_DEVFN_TBT1: return "TRP1";
case SA_DEVFN_TBT2: return "TRP2";
case SA_DEVFN_TBT3: return "TRP3";
+ case SA_DEVFN_IPU: return "IPU0";
case PCH_DEVFN_ISH: return "ISHB";
case PCH_DEVFN_XHCI: return "XHCI";
case PCH_DEVFN_I2C0: return "I2C0";
--
To view, visit https://review.coreboot.org/c/coreboot/+/42878
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: Ib11be5be7fbaec688d8788945a3bcab3f8d834a1
Gerrit-Change-Number: 42878
Gerrit-PatchSet: 1
Gerrit-Owner: Tim Wawrzynczak <twawrzynczak(a)chromium.org>
Gerrit-MessageType: newchange