diff options
author | Bill Richardson <wfrichar@chromium.org> | 2013-12-13 12:22:42 -0800 |
---|---|---|
committer | chrome-internal-fetch <chrome-internal-fetch@google.com> | 2013-12-16 22:57:54 +0000 |
commit | 700adf4dea7f12fef6e8f12d34005d82ca58a3a2 (patch) | |
tree | a168e24f6a2a59e8592ec79e78bfb02d547c1033 | |
parent | c450c2b2202cb3d835a0d8d709b5182c96c92c88 (diff) | |
download | chrome-ec-700adf4dea7f12fef6e8f12d34005d82ca58a3a2.tar.gz |
Let AP read sensor IDs when DPTF thermal thresholds crossed
The spec does not mandate any way to read back the threshold settings
themselves, but when a threshold is crossed the AP needs a way to determine
which sensor(s) are responsible. Each reading of the EC_ACPI_MEM_TEMP_ID
register clears and returns one sensor ID that has crossed one of its
thresholds (in either direction) since the last read. A value of 0xFF means
"no new thresholds have tripped". Changing or enabling the thresholds for
any sensor will clear the unread event count for that sensor.
BUG=chrome-os-partner:23970
BRANCH=none
TEST=manual
On the host, set a couple of thresholds to low values so they trip
immediately (I'm testing on Link):
# dptf() {
[ "$#" -eq "2" ] || return;
iotools io_write8 0x66 0x81
iotools io_write8 0x62 $1
iotools io_write8 0x62 $2
}
#
# dptf 5 0
# dptf 6 10
# dptf 7 3
# dptf 5 2
# dptf 6 10
# dptf 7 2
On the EC console, see that two thresholds have triggered, and that there
are two bits set in the AP seen mask:
[45.755365 DPTF sensor 0, threshold -63 C, index 1, enabled]
[45.768940 DPTF sensor 2, threshold -63 C, index 0, enabled]
[46.169490 DPTF over threshold [0][1]
[46.169820 DPTF over threshold [2][0]
> dptftemp
sensor thresh0 thresh1
0 --- 210* I2C-USB C-Die
1 --- --- I2C-USB C-Object
2 210* --- I2C-PCH D-Die
3 --- --- I2C-PCH D-Object
4 --- --- I2C-Hinge C-Die
5 --- --- I2C-Hinge C-Object
6 --- --- I2C-Charger D-Die
7 --- --- I2C-Charger D-Object
8 --- --- ECInternal
9 --- --- PECI
AP seen mask: 0x00000005
>
Read the EC_ACPI_MEM_TEMP_ID register from the host, to get the two active
sensor IDs (0 and 2), then 0xff when those are seen.
# iotools io_write8 0x66 0x80; iotools io_write8 0x62 5; iotools io_read8 0x62
0x00
# iotools io_write8 0x66 0x80; iotools io_write8 0x62 5; iotools io_read8 0x62
0x02
# iotools io_write8 0x66 0x80; iotools io_write8 0x62 5; iotools io_read8 0x62
0xff
# iotools io_write8 0x66 0x80; iotools io_write8 0x62 5; iotools io_read8 0x62
0xff
#
Change-Id: I8f047a517357617f18ad59d21fa13409bc81821b
Signed-off-by: Bill Richardson <wfrichar@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/180224
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | common/acpi.c | 5 | ||||
-rw-r--r-- | common/thermal.c | 23 | ||||
-rw-r--r-- | include/dptf.h | 6 | ||||
-rw-r--r-- | include/ec_commands.h | 8 |
4 files changed, 37 insertions, 5 deletions
diff --git a/common/acpi.c b/common/acpi.c index 68c281b6e6..69cf3bc837 100644 --- a/common/acpi.c +++ b/common/acpi.c @@ -71,6 +71,11 @@ int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr) result = dptf_get_fan_duty_target(); break; #endif +#ifdef CONFIG_TEMP_SENSOR + case EC_ACPI_MEM_TEMP_ID: + result = dptf_query_next_sensor_event(); + break; +#endif default: CPRINTF("[%T ACPI read 0x%02x (ignored)]\n", acpi_addr); break; diff --git a/common/thermal.c b/common/thermal.c index 6464ef7161..7113564f82 100644 --- a/common/thermal.c +++ b/common/thermal.c @@ -7,6 +7,7 @@ * implementation from the original version that shipped on Link. */ +#include "atomic.h" #include "chipset.h" #include "common.h" #include "console.h" @@ -45,8 +46,21 @@ static void dptf_init(void) } DECLARE_HOOK(HOOK_INIT, dptf_init, HOOK_PRIO_DEFAULT); +/* Keep track of which triggered sensor thresholds the AP has seen */ +static uint32_t dptf_seen; +int dptf_query_next_sensor_event(void) +{ + int id; + for (id = 0; id < TEMP_SENSOR_COUNT; id++) + if (dptf_seen & (1 << id)) { /* atomic? */ + atomic_clear(&dptf_seen, (1 << id)); + return id; + } + + return -1; +} /* Return true if any threshold transition occurs. */ static int dpft_check_temp_threshold(int sensor_id, int temp) @@ -68,11 +82,13 @@ static int dpft_check_temp_threshold(int sensor_id, int temp) if (cond_went_true(&dptf_threshold[sensor_id][i].over)) { CPRINTF("[%T DPTF over threshold [%d][%d]\n", sensor_id, i); + atomic_or(&dptf_seen, (1 << sensor_id)); tripped = 1; } if (cond_went_false(&dptf_threshold[sensor_id][i].over)) { CPRINTF("[%T DPTF under threshold [%d][%d]\n", sensor_id, i); + atomic_or(&dptf_seen, (1 << sensor_id)); tripped = 1; } } @@ -80,7 +96,6 @@ static int dpft_check_temp_threshold(int sensor_id, int temp) return tripped; } - void dptf_set_temp_threshold(int sensor_id, int temp, int idx, int enable) { CPRINTF("[%T DPTF sensor %d, threshold %d C, index %d, %sabled]\n", @@ -89,15 +104,12 @@ void dptf_set_temp_threshold(int sensor_id, int temp, int idx, int enable) if (enable) { dptf_threshold[sensor_id][idx].temp = temp; cond_init(&dptf_threshold[sensor_id][idx].over, 0); + atomic_clear(&dptf_seen, (1 << sensor_id)); } else { dptf_threshold[sensor_id][idx].temp = -1; } } - - - - /*****************************************************************************/ /* EC-specific thermal controls */ @@ -350,6 +362,7 @@ static int command_dptftemp(int argc, char **argv) ccprintf(" %s\n", temp_sensors[id].name); } + ccprintf("AP seen mask: 0x%08x\n", dptf_seen); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(dptftemp, command_dptftemp, diff --git a/include/dptf.h b/include/dptf.h index 31c9c09bca..f611acb361 100644 --- a/include/dptf.h +++ b/include/dptf.h @@ -24,4 +24,10 @@ void dptf_set_temp_threshold(int sensor_id, /* zero-based sensor index */ int idx, /* which threshold (0 or 1) */ int enable); /* true = on, false = off */ +/* + * Return the ID of a temp sensor that has crossed its threshold since the last + time we asked. -1 means none. + */ +int dptf_query_next_sensor_event(void); + #endif /* __CROS_EC_DPTF_H */ diff --git a/include/ec_commands.h b/include/ec_commands.h index 7b3fb170d1..f526accd00 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -1877,6 +1877,14 @@ struct ec_params_reboot_ec { * register determines which sensor is affected by the THRESHOLD and COMMIT * registers. The THRESHOLD register uses the same EC_TEMP_SENSOR_OFFSET scheme * as the memory-mapped sensors. The COMMIT register applies those settings. + * + * The spec does not mandate any way to read back the threshold settings + * themselves, but when a threshold is crossed the AP needs a way to determine + * which sensor(s) are responsible. Each reading of the ID register clears and + * returns one sensor ID that has crossed one of its threshold (in either + * direction) since the last read. A value of 0xFF means "no new thresholds + * have tripped". Setting or enabling the thresholds for a sensor will clear + * the unread event count for that sensor. */ #define EC_ACPI_MEM_TEMP_ID 0x05 #define EC_ACPI_MEM_TEMP_THRESHOLD 0x06 |