From d3fdf5e6f3243484328d3d954a1924b355ff9c21 Mon Sep 17 00:00:00 2001 From: Bill Richardson Date: Thu, 12 Dec 2013 11:03:17 -0800 Subject: Add stubs for DPTF thermal thresholds This adds three new registers to the ACPI->EC interface, which will allow the AP to set/clear two DPTF thermal threshold points for each temp sensor. The registers are EC_ACPI_MEM_TEMP_ID 0x05 EC_ACPI_MEM_TEMP_THRESHOLD 0x06 EC_ACPI_MEM_TEMP_COMMIT 0x07 It doesn't actually do anything yet, but the AP can now write those values. BUG=chrome-os-partner:23970 BRANCH=none TEST=manual On the host: dptf() { [ "$#" -eq "2" ] || return; iotools io_write8 0x66 0x81 iotools io_write8 0x62 $1 iotools io_write8 0x62 $2 } Now watch the EC console while running on the host: dptf 5 1 dptf 6 80 dptf 7 2 dptf 7 3 The EC should say DPTF sensor 1, threshold 7 C, index 0, enabled DPTF sensor 1, threshold 7 C, index 1, enabled Change-Id: I71fa57e3ca7c7b5bb8892e63212bf294b44dece5 Signed-off-by: Bill Richardson Reviewed-on: https://chromium-review.googlesource.com/179778 Reviewed-by: Duncan Laurie Reviewed-by: Randall Spangler --- common/acpi.c | 42 +++++++++++++++++++++++++----------------- common/thermal.c | 13 +++++++++++++ include/dptf.h | 8 +++++++- include/ec_commands.h | 39 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 82 insertions(+), 20 deletions(-) diff --git a/common/acpi.c b/common/acpi.c index 942dd21dd2..68c281b6e6 100644 --- a/common/acpi.c +++ b/common/acpi.c @@ -20,6 +20,11 @@ static uint8_t acpi_addr; /* First byte of data after ACPI command */ static int acpi_data_count; /* Number of data writes after command */ static uint8_t acpi_mem_test; /* Test byte in ACPI memory space */ +#ifdef CONFIG_TEMP_SENSOR +static int dptf_temp_sensor_id; /* last sensor ID written */ +static int dptf_temp_threshold; /* last threshold written */ +#endif + /* This handles AP writes to the EC via the ACPI I/O port. There are only a few * ACPI commands (EC_CMD_ACPI_*), but they are all handled here. */ @@ -27,8 +32,7 @@ int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr) { int data = 0; int retval = 0; - - CPRINTF("[HEY: %T %s(%d, 0x%x)]\n", is_cmd, value); + int result = 0xff; /* value for bogus read */ /* Read command/data; this clears the FRMH status bit. */ if (is_cmd) { @@ -47,8 +51,6 @@ int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr) /* Process complete commands */ if (acpi_cmd == EC_CMD_ACPI_READ && acpi_data_count == 1) { /* ACPI read cmd + addr */ - int result = 0xff; /* value for bogus read */ - switch (acpi_addr) { case EC_ACPI_MEM_VERSION: result = EC_ACPI_MEM_VERSION_CURRENT; @@ -61,29 +63,20 @@ int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr) break; #ifdef CONFIG_PWM_KBLIGHT case EC_ACPI_MEM_KEYBOARD_BACKLIGHT: - /* - * TODO(crosbug.com/p/23774): not very satisfying that - * LPC knows directly about the keyboard backlight, but - * for now this is good enough and less code than - * defining a new API for ACPI commands. If we start - * adding more commands, or need to support LPC on more - * than just LM4, fix this. - */ result = pwm_get_duty(PWM_CH_KBLIGHT); break; #endif #ifdef CONFIG_FANS case EC_ACPI_MEM_FAN_DUTY: - /** TODO(crosbug.com/p/23774): Fix this too */ result = dptf_get_fan_duty_target(); break; #endif default: + CPRINTF("[%T ACPI read 0x%02x (ignored)]\n", acpi_addr); break; } /* Send the result byte */ - CPRINTF("[%T ACPI read 0x%02x = 0x%02x]\n", acpi_addr, result); *resultptr = result; retval = 1; @@ -91,7 +84,6 @@ int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr) /* ACPI write cmd + addr + data */ switch (acpi_addr) { case EC_ACPI_MEM_TEST: - CPRINTF("[%T ACPI mem test 0x%02x]\n", data); acpi_mem_test = data; break; #ifdef CONFIG_PWM_KBLIGHT @@ -107,12 +99,28 @@ int acpi_ap_to_ec(int is_cmd, uint8_t value, uint8_t *resultptr) #endif #ifdef CONFIG_FANS case EC_ACPI_MEM_FAN_DUTY: - /** TODO(crosbug.com/p/23774): Fix this too */ dptf_set_fan_duty_target(data); break; +#endif +#ifdef CONFIG_TEMP_SENSOR + case EC_ACPI_MEM_TEMP_ID: + dptf_temp_sensor_id = data; + break; + case EC_ACPI_MEM_TEMP_THRESHOLD: + dptf_temp_threshold = data + EC_TEMP_SENSOR_OFFSET; + break; + case EC_ACPI_MEM_TEMP_COMMIT: + { + int idx = data & EC_ACPI_MEM_TEMP_COMMIT_SELECT_MASK; + int enable = data & EC_ACPI_MEM_TEMP_COMMIT_ENABLE_MASK; + dptf_set_temp_threshold(dptf_temp_sensor_id, + dptf_temp_threshold, + idx, enable); + break; + } #endif default: - CPRINTF("[%T ACPI write 0x%02x = 0x%02x]\n", + CPRINTF("[%T ACPI write 0x%02x = 0x%02x (ignored)]\n", acpi_addr, data); break; } diff --git a/common/thermal.c b/common/thermal.c index 97c12412e0..873a8a1981 100644 --- a/common/thermal.c +++ b/common/thermal.c @@ -23,6 +23,19 @@ #define CPUTS(outstr) cputs(CC_THERMAL, outstr) #define CPRINTF(format, args...) cprintf(CC_THERMAL, format, ## args) +/*****************************************************************************/ +/* DPTF temperature thresholds */ + +void dptf_set_temp_threshold(int sensor_id, int temp, int idx, int enable) +{ + /* TODO(crosbug.com/p/23970) */ + CPRINTF("[%T DPTF sensor %d, threshold %d C, index %d, %sabled]\n", + sensor_id, K_TO_C(temp), idx, enable ? "en" : "dis"); +} + +/*****************************************************************************/ +/* EC-specific thermal controls */ + test_mockable_static void smi_sensor_failure_warning(void) { CPRINTF("[%T can't read any temp sensors!]\n"); diff --git a/include/dptf.h b/include/dptf.h index 48be860f2d..4213426255 100644 --- a/include/dptf.h +++ b/include/dptf.h @@ -11,7 +11,13 @@ /* 0-100% sets fixed duty cycle, out of range means let the EC drive */ void dptf_set_fan_duty_target(int pct); -/* 0-100% if in duty mode. -1 if not */ +/* 0-100% if in duty mode. -1 if not */ int dptf_get_fan_duty_target(void); +/* Each temp sensor can have up to two thresholds */ +void dptf_set_temp_threshold(int sensor_id, /* zero-based sensor index */ + int temp, /* in degrees K */ + int idx, /* which threshold (0 or 1) */ + int enable); /* true = on, false = off */ + #endif /* __CROS_EC_DPTF_H */ diff --git a/include/ec_commands.h b/include/ec_commands.h index b97ef7dc48..7b3fb170d1 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -1855,6 +1855,7 @@ struct ec_params_reboot_ec { #define EC_CMD_ACPI_QUERY_EVENT 0x84 /* Valid addresses in ACPI memory space, for read/write commands */ + /* Memory space version; set to EC_ACPI_MEM_VERSION_CURRENT */ #define EC_ACPI_MEM_VERSION 0x00 /* @@ -1864,10 +1865,44 @@ struct ec_params_reboot_ec { #define EC_ACPI_MEM_TEST 0x01 /* Test compliment; writes here are ignored. */ #define EC_ACPI_MEM_TEST_COMPLIMENT 0x02 + /* Keyboard backlight brightness percent (0 - 100) */ #define EC_ACPI_MEM_KEYBOARD_BACKLIGHT 0x03 -/* Target Fan Duty (0-100, 0xff for auto/none) */ -#define EC_ACPI_MEM_FAN_DUTY 0x04 +/* DPTF Target Fan Duty (0-100, 0xff for auto/none) */ +#define EC_ACPI_MEM_FAN_DUTY 0x04 + +/* + * DPTF temp thresholds. Any of the EC's temp sensors can have up to two + * independent thresholds attached to them. The current value of the ID + * 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. + */ +#define EC_ACPI_MEM_TEMP_ID 0x05 +#define EC_ACPI_MEM_TEMP_THRESHOLD 0x06 +#define EC_ACPI_MEM_TEMP_COMMIT 0x07 +/* + * Here are the bits for the COMMIT register: + * bit 0 selects the threshold index for the chosen sensor (0/1) + * bit 1 enables/disables the selected threshold (0 = off, 1 = on) + * Each write to the commit register affects one threshold. + */ +#define EC_ACPI_MEM_TEMP_COMMIT_SELECT_MASK (1 << 0) +#define EC_ACPI_MEM_TEMP_COMMIT_ENABLE_MASK (1 << 1) +/* + * Example: + * + * Set the thresholds for sensor 2 to 50 C and 60 C: + * write 2 to [0x05] -- select temp sensor 2 + * write 0x7b to [0x06] -- C_TO_K(50) - EC_TEMP_SENSOR_OFFSET + * write 0x2 to [0x07] -- enable threshold 0 with this value + * write 0x85 to [0x06] -- C_TO_K(60) - EC_TEMP_SENSOR_OFFSET + * write 0x3 to [0x07] -- enable threshold 1 with this value + * + * Disable the 60 C threshold, leaving the 50 C threshold unchanged: + * write 2 to [0x05] -- select temp sensor 2 + * write 0x1 to [0x07] -- disable threshold 1 + */ /* Current version of ACPI memory address space */ #define EC_ACPI_MEM_VERSION_CURRENT 1 -- cgit v1.2.1