Support up to 24 thermal sensors

And tidy reporting fan/thermal via memmap.

BUG=chrome-os-partner:11628
TEST=manual
  ectool pwmgetfanrpm -> should report fan speed
  ectool temps N ->
    should work for N=0-9
    reports error for N=15-23
    reports invalid sensor ID for N<0 or N>23

Change-Id: I484f81399f5e9dae9c759401091cc6f5acc733ff
Signed-off-by: Randall Spangler <rspangler@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/28032
Reviewed-by: Bill Richardson <wfrichar@chromium.org>
This commit is contained in:
Randall Spangler
2012-07-20 11:05:07 -07:00
committed by Gerrit
parent bff14cac0b
commit 360d91573a
6 changed files with 109 additions and 60 deletions

View File

@@ -662,7 +662,11 @@ static int lpc_init(void)
return EC_SUCCESS;
}
DECLARE_HOOK(HOOK_INIT, lpc_init, HOOK_PRIO_DEFAULT);
/*
* Set prio to higher than default so other inits can initialize their
* memmap data.
*/
DECLARE_HOOK(HOOK_INIT, lpc_init, HOOK_PRIO_DEFAULT - 1);
static int lpc_resume(void)

View File

@@ -530,7 +530,7 @@ static int power_button_init(void)
return EC_SUCCESS;
}
DECLARE_HOOK(HOOK_INIT, power_button_init, HOOK_PRIO_DEFAULT + 1);
DECLARE_HOOK(HOOK_INIT, power_button_init, HOOK_PRIO_DEFAULT);
void power_button_interrupt(enum gpio_signal signal)

View File

@@ -125,41 +125,36 @@ int pwm_set_keyboard_backlight(int percent)
return EC_SUCCESS;
}
static void update_mapped_memory(void)
/**
* Return non-zero if fan is enabled but stalled
*/
static int fan_is_stalled(void)
{
int i, r;
uint16_t *mapped = (uint16_t *)host_get_memmap(EC_MEMMAP_FAN);
/* Must be enabled with non-zero target to stall */
if (!pwm_get_fan_enabled() || pwm_get_fan_target_rpm() == 0)
return 0;
for (i = 0; i < 4; ++i)
mapped[i] = 0xffff;
r = pwm_get_fan_rpm();
/* Write fan speed. Or 0xFFFE for fan stalled. */
if (r)
mapped[0] = r;
else
mapped[0] = 0xfffe;
}
static void check_fan_failure(void)
{
if (pwm_get_fan_target_rpm() != 0 && pwm_get_fan_enabled() &&
((LM4_FAN_FANSTS >> (2 * FAN_CH_CPU)) & 0x03) == 0) {
/*
* Fan enabled but stalled. Issues warning. As we have thermal
* shutdown protection, issuing warning here should be enough.
*/
host_set_single_event(EC_HOST_EVENT_THERMAL);
cputs(CC_PWM, "[Fan stalled!]\n");
}
/* Check for stall condition */
return (((LM4_FAN_FANSTS >> (2 * FAN_CH_CPU)) & 0x03) == 0) ? 1 : 0;
}
void pwm_task(void)
{
uint16_t *mapped = (uint16_t *)host_get_memmap(EC_MEMMAP_FAN);
while (1) {
check_fan_failure();
update_mapped_memory();
if (fan_is_stalled()) {
mapped[0] = EC_FAN_SPEED_STALLED;
/*
* Issue warning. As we have thermal shutdown
* protection, issuing warning here should be enough.
*/
host_set_single_event(EC_HOST_EVENT_THERMAL);
cprintf(CC_PWM, "[%T Fan stalled!]\n");
} else
mapped[0] = pwm_get_fan_rpm();
/* Update about once a second */
usleep(1000000);
}
}
@@ -299,7 +294,9 @@ static int pwm_init(void)
{
volatile uint32_t scratch __attribute__((unused));
const struct pwm_state *prev;
uint16_t *mapped;
int version, size;
int i;
/* Enable the fan module and delay a few clocks */
LM4_SYSTEM_RCGCFAN = 1;
@@ -359,6 +356,11 @@ static int pwm_init(void)
pwm_enable_keyboard_backlight(1);
}
/* Initialize memory-mapped data */
mapped = (uint16_t *)host_get_memmap(EC_MEMMAP_FAN);
for (i = 0; i < EC_FAN_SPEED_ENTRIES; i++)
mapped[i] = EC_FAN_SPEED_NOT_PRESENT;
return EC_SUCCESS;
}
DECLARE_HOOK(HOOK_INIT, pwm_init, HOOK_PRIO_DEFAULT);

View File

@@ -76,20 +76,29 @@ static void poll_fast_sensors(void)
static void update_mapped_memory(void)
{
int i, t;
uint8_t *mapped = host_get_memmap(EC_MEMMAP_TEMP_SENSOR);
uint8_t *mptr = host_get_memmap(EC_MEMMAP_TEMP_SENSOR);
memset(mapped, 0xff, 16);
for (i = 0; i < TEMP_SENSOR_COUNT; i++, mptr++) {
/*
* Switch to second range if first one is full, or stop if
* second range is also full.
*/
if (i == EC_TEMP_SENSOR_ENTRIES)
mptr = host_get_memmap(EC_MEMMAP_TEMP_SENSOR_B);
else if (i >= EC_TEMP_SENSOR_ENTRIES +
EC_TEMP_SENSOR_B_ENTRIES)
break;
for (i = 0; i < TEMP_SENSOR_COUNT && i < 16; ++i) {
if (!temp_sensor_powered(i)) {
mapped[i] = 0xfd;
*mptr = EC_TEMP_SENSOR_NOT_POWERED;
continue;
}
t = temp_sensor_read(i);
if (t != -1)
mapped[i] = t - EC_TEMP_SENSOR_OFFSET;
if (t == -1)
*mptr = EC_TEMP_SENSOR_ERROR;
else
mapped[i] = 0xfe;
*mptr = t - EC_TEMP_SENSOR_OFFSET;
}
}
@@ -98,8 +107,14 @@ void temp_sensor_task(void)
{
int i;
/* Switch data is now present */
*host_get_memmap(EC_MEMMAP_THERMAL_VERSION) = 1;
/* Initialize memory-mapped data */
memset(host_get_memmap(EC_MEMMAP_TEMP_SENSOR),
EC_TEMP_SENSOR_NOT_PRESENT, EC_TEMP_SENSOR_ENTRIES);
memset(host_get_memmap(EC_MEMMAP_TEMP_SENSOR_B),
EC_TEMP_SENSOR_NOT_PRESENT, EC_TEMP_SENSOR_B_ENTRIES);
/* Temp sensor data is present, with B range supported. */
*host_get_memmap(EC_MEMMAP_THERMAL_VERSION) = 2;
while (1) {
for (i = 0; i < 4; ++i) {

View File

@@ -65,8 +65,9 @@
#define EC_MEMMAP_TEXT_MAX 8 /* Size of a string in the memory map */
/* The offset address of each type of data in mapped memory. */
#define EC_MEMMAP_TEMP_SENSOR 0x00
#define EC_MEMMAP_FAN 0x10
#define EC_MEMMAP_TEMP_SENSOR 0x00 /* Temp sensors */
#define EC_MEMMAP_FAN 0x10 /* Fan speeds */
#define EC_MEMMAP_TEMP_SENSOR_B 0x18 /* Temp sensors (second set) */
#define EC_MEMMAP_ID 0x20 /* 'E' 'C' */
#define EC_MEMMAP_ID_VERSION 0x22 /* Version of data in 0x20 - 0x2f */
#define EC_MEMMAP_THERMAL_VERSION 0x23 /* Version of data in 0x00 - 0x1f */
@@ -89,6 +90,27 @@
#define EC_MEMMAP_BATT_SERIAL 0x70 /* Battery Serial Number String */
#define EC_MEMMAP_BATT_TYPE 0x78 /* Battery Type String */
/* Number of temp sensors at EC_MEMMAP_TEMP_SENSOR */
#define EC_TEMP_SENSOR_ENTRIES 16
/*
* Number of temp sensors at EC_MEMMAP_TEMP_SENSOR_B.
*
* Valid only if EC_MEMMAP_THERMAL_VERSION returns >= 2.
*/
#define EC_TEMP_SENSOR_B_ENTRIES 8
#define EC_TEMP_SENSOR_NOT_PRESENT 0xff
#define EC_TEMP_SENSOR_ERROR 0xfe
#define EC_TEMP_SENSOR_NOT_POWERED 0xfd
/*
* The offset of temperature value stored in mapped memory. This allows
* reporting a temperature range of 200K to 454K = -73C to 181C.
*/
#define EC_TEMP_SENSOR_OFFSET 200
#define EC_FAN_SPEED_ENTRIES 4 /* Number of fans at EC_MEMMAP_FAN */
#define EC_FAN_SPEED_NOT_PRESENT 0xffff /* Entry not present */
#define EC_FAN_SPEED_STALLED 0xfffe /* Fan stalled */
/* Battery bit flags at EC_MEMMAP_BATT_FLAG. */
#define EC_BATT_FLAG_AC_PRESENT 0x01
#define EC_BATT_FLAG_BATT_PRESENT 0x02
@@ -115,12 +137,6 @@
#define EC_WIRELESS_SWITCH_WLAN 0x01
#define EC_WIRELESS_SWITCH_BLUETOOTH 0x02
/*
* The offset of temperature value stored in mapped memory. This allows
* reporting a temperature range of 200K to 454K = -73C to 181C.
*/
#define EC_TEMP_SENSOR_OFFSET 200
/*
* This header file is used in coreboot both in C and ACPI code. The ACPI code
* is pre-processed to handle constants but the ASL compiler is unable to

View File

@@ -684,25 +684,34 @@ int cmd_temperature(int argc, char *argv[])
return -1;
}
/* Currently we only store up to 16 temperature sensor data in
* mapped memory. */
if (id >= 16) {
printf("Sensor with ID greater than 16 unsupported.\n");
if (id < 0 ||
id >= EC_TEMP_SENSOR_ENTRIES + EC_TEMP_SENSOR_B_ENTRIES) {
printf("Sensor ID invalid.\n");
return -1;
}
printf("Reading temperature...");
rv = read_mapped_mem8(EC_MEMMAP_TEMP_SENSOR + id);
if (rv == 0xff) {
if (id < EC_TEMP_SENSOR_ENTRIES)
rv = read_mapped_mem8(EC_MEMMAP_TEMP_SENSOR + id);
else if (read_mapped_mem8(EC_MEMMAP_THERMAL_VERSION) >= 2)
rv = read_mapped_mem8(EC_MEMMAP_TEMP_SENSOR_B +
id - EC_TEMP_SENSOR_ENTRIES);
else {
/* Sensor in second bank, but second bank isn't supported */
rv = EC_TEMP_SENSOR_NOT_PRESENT;
}
switch (rv) {
case EC_TEMP_SENSOR_NOT_PRESENT:
printf("Sensor not present\n");
return -1;
} else if (rv == 0xfe) {
case EC_TEMP_SENSOR_ERROR:
printf("Error\n");
return -1;
} else if (rv == 0xfd) {
case EC_TEMP_SENSOR_NOT_POWERED:
printf("Sensor disabled/unpowered\n");
return -1;
} else {
default:
printf("%d\n", rv + EC_TEMP_SENSOR_OFFSET);
return 0;
}
@@ -840,13 +849,16 @@ int cmd_pwm_get_fan_rpm(int argc, char *argv[])
int rv;
rv = read_mapped_mem16(EC_MEMMAP_FAN);
if (rv == 0xffff)
switch (rv) {
case EC_FAN_SPEED_NOT_PRESENT:
return -1;
if (rv == 0xfffe)
case EC_FAN_SPEED_STALLED:
printf("Fan stalled!\n");
else
break;
default:
printf("Current fan RPM: %d\n", rv);
break;
}
return 0;
}