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>
This commit is contained in:
Bill Richardson
2013-12-13 12:22:42 -08:00
committed by chrome-internal-fetch
parent c450c2b220
commit 700adf4dea
4 changed files with 37 additions and 5 deletions

View File

@@ -70,6 +70,11 @@ int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr)
case EC_ACPI_MEM_FAN_DUTY:
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);

View File

@@ -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,

View File

@@ -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 */

View File

@@ -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