diff options
author | Vic Yang <victoryang@google.com> | 2012-04-05 11:30:16 +0800 |
---|---|---|
committer | Vic Yang <victoryang@google.com> | 2012-04-05 11:30:16 +0800 |
commit | 94ef5f3ab3dd20ee5558df5607997985b7e2f45c (patch) | |
tree | a1b043f930015df215856a08e4cb6d249e0e4e17 /common/thermal.c | |
parent | 8ee84c5db542f3a0989c17bf5903ba4da21baf70 (diff) | |
download | chrome-ec-94ef5f3ab3dd20ee5558df5607997985b7e2f45c.tar.gz |
Increase fan speed control to 5 steps.
Factor out fan speed control for easier adjusting fan speed stepping.
Also increase number of fan speed steps from 2 to 5.
Signed-off-by: Vic Yang <victoryang@google.com>
BUG=chrome-os-partner:8466
TEST=Manual test.
Change-Id: I0ff601c0a4f2ed2a4867bdc6e550eb2827404754
Diffstat (limited to 'common/thermal.c')
-rw-r--r-- | common/thermal.c | 110 |
1 files changed, 84 insertions, 26 deletions
diff --git a/common/thermal.c b/common/thermal.c index d7fbcc76f8..f2e53c55b5 100644 --- a/common/thermal.c +++ b/common/thermal.c @@ -25,31 +25,42 @@ extern const struct temp_sensor_t temp_sensors[TEMP_SENSOR_COUNT]; /* Temperature threshold configuration. Must be in the same order as in - * enum temp_sensor_type. */ + * enum temp_sensor_type. Threshold values for overheated action first. + * Followed by fan speed stepping thresholds. */ struct thermal_config_t thermal_config[TEMP_SENSOR_TYPE_COUNT] = { /* TEMP_SENSOR_TYPE_CPU */ - {THERMAL_CONFIG_WARNING_ON_FAIL, {328, 338, 343, 348, 353}}, + {THERMAL_CONFIG_WARNING_ON_FAIL, + {343, 348, 353, 318, 323, 328, 333, 338}}, /* TEMP_SENSOR_TYPE_BOARD */ {THERMAL_CONFIG_NO_FLAG, {THERMAL_THRESHOLD_DISABLE_ALL}}, /* TEMP_SENSOR_TYPE_CASE */ - {THERMAL_CONFIG_NO_FLAG, {THERMAL_THRESHOLD_DISABLE, - THERMAL_THRESHOLD_DISABLE, 343, THERMAL_THRESHOLD_DISABLE, 358}}, + {THERMAL_CONFIG_NO_FLAG, {343, THERMAL_THRESHOLD_DISABLE, 358, + THERMAL_THRESHOLD_DISABLE_ALL}}, }; +/* Fan speed settings. */ +/* TODO: Currently temperature polling task sometimes hangs. So we should not + * turn off fan according to temperature readings. Modify this to turn off fan + * when we have reliable temperature readings. See crosbug.com/p/8479 + */ +const int fan_speed[THERMAL_FAN_STEPS + 1] = {4000, 5000, 6000, 7000, 8000, -1}; + /* Number of consecutive overheated events for each temperature sensor. */ -static int8_t ot_count[TEMP_SENSOR_COUNT][THRESHOLD_COUNT]; +static int8_t ot_count[TEMP_SENSOR_COUNT][THRESHOLD_COUNT + THERMAL_FAN_STEPS]; /* Flag that indicate if each threshold is reached. * Note that higher threshold reached does not necessarily mean lower thresholds * are reached (since we can disable any threshold.) */ -static int8_t overheated[THRESHOLD_COUNT]; +static int8_t overheated[THRESHOLD_COUNT + THERMAL_FAN_STEPS]; +static int8_t *fan_threshold_reached = overheated + THRESHOLD_COUNT; static int fan_ctrl_on = 1; int thermal_set_threshold(enum temp_sensor_type type, int threshold_id, int value) { - if (threshold_id < 0 || threshold_id >= THRESHOLD_COUNT) + if (threshold_id < 0 || + threshold_id >= THRESHOLD_COUNT + THERMAL_FAN_STEPS) return EC_ERROR_INVAL; if (value < 0) return EC_ERROR_INVAL; @@ -62,7 +73,8 @@ int thermal_set_threshold(enum temp_sensor_type type, int threshold_id, int valu int thermal_get_threshold(enum temp_sensor_type type, int threshold_id) { - if (threshold_id < 0 || threshold_id >= THRESHOLD_COUNT) + if (threshold_id < 0 || + threshold_id >= THRESHOLD_COUNT + THERMAL_FAN_STEPS) return EC_ERROR_INVAL; return thermal_config[type].thresholds[threshold_id]; @@ -106,18 +118,11 @@ static void overheated_action(void) } if (fan_ctrl_on) { - if (overheated[THRESHOLD_FAN_HI]) - pwm_set_fan_target_rpm(-1); /* Max RPM. */ - else if (overheated[THRESHOLD_FAN_LO]) - pwm_set_fan_target_rpm(6000); - else - /* TODO: Currently temperature polling task sometimes - * hangs. So we should not turn off fan according to - * temperature readings. Modify this to turn off fan - * when we have reliable temperature readings. - * See crosbug.com/p/8479 - */ - pwm_set_fan_target_rpm(4000); + int i; + for (i = THERMAL_FAN_STEPS - 1; i >= 0; --i) + if (fan_threshold_reached[i]) + break; + pwm_set_fan_target_rpm(fan_speed[i + 1]); } } @@ -158,7 +163,7 @@ static void thermal_process(void) int i, j; int cur_temp; - for (i = 0; i < THRESHOLD_COUNT; ++i) + for (i = 0; i < THRESHOLD_COUNT + THERMAL_FAN_STEPS; ++i) overheated[i] = 0; for (i = 0; i < TEMP_SENSOR_COUNT; ++i) { @@ -176,7 +181,7 @@ static void thermal_process(void) smi_sensor_failure_warning(); continue; } - for (j = 0; j < THRESHOLD_COUNT; ++j) + for (j = 0; j < THRESHOLD_COUNT + THERMAL_FAN_STEPS; ++j) update_and_check_stat(cur_temp, i, j); } @@ -200,10 +205,6 @@ static void print_thermal_config(enum temp_sensor_type type) { const struct thermal_config_t *config = thermal_config + type; uart_printf("Sensor Type %d:\n", type); - uart_printf("\tFan Low: %d K \n", - config->thresholds[THRESHOLD_FAN_LO]); - uart_printf("\tFan High: %d K \n", - config->thresholds[THRESHOLD_FAN_HI]); uart_printf("\tWarning: %d K \n", config->thresholds[THRESHOLD_WARNING]); uart_printf("\tCPU Down: %d K \n", @@ -213,6 +214,20 @@ static void print_thermal_config(enum temp_sensor_type type) } +static void print_fan_stepping(enum temp_sensor_type type) +{ + const struct thermal_config_t *config = thermal_config + type; + int i; + + uart_printf("Sensor Type %d:\n", type); + uart_printf("\tLowest speed: %d RPM\n", fan_speed[0]); + for (i = 0; i < THERMAL_FAN_STEPS; ++i) + uart_printf("\t%3d K: %d RPM\n", + config->thresholds[THRESHOLD_COUNT + i], + fan_speed[i+1]); +} + + static int command_thermal_config(int argc, char **argv) { char *e; @@ -256,6 +271,49 @@ static int command_thermal_config(int argc, char **argv) DECLARE_CONSOLE_COMMAND(thermal, command_thermal_config); +static int command_fan_config(int argc, char **argv) +{ + char *e; + int sensor_type, stepping_id, value; + + if (argc != 2 && argc != 4) { + uart_puts("Usage: thermalfan <sensor_type> [<stepping_id> <value>]\n"); + return EC_ERROR_UNKNOWN; + } + + sensor_type = strtoi(argv[1], &e, 0); + if ((e && *e) || sensor_type < 0 || + sensor_type >= TEMP_SENSOR_TYPE_COUNT) { + uart_puts("Bad sensor type ID.\n"); + return EC_ERROR_UNKNOWN; + } + + if (argc == 2) { + print_fan_stepping(sensor_type); + return EC_SUCCESS; + } + + stepping_id = strtoi(argv[2], &e, 0); + if ((e && *e) || stepping_id < 0 || stepping_id >= THERMAL_FAN_STEPS) { + uart_puts("Bad stepping ID.\n"); + return EC_ERROR_UNKNOWN; + } + + value = strtoi(argv[3], &e, 0); + if ((e && *e) || value < 0) { + uart_puts("Bad threshold value.\n"); + return EC_ERROR_UNKNOWN; + } + + thermal_config[sensor_type].thresholds[THRESHOLD_COUNT + stepping_id] = value; + uart_printf("Setting fan step %d of sensor type %d to %d K\n", + stepping_id, sensor_type, value); + + return EC_SUCCESS; +} +DECLARE_CONSOLE_COMMAND(thermalfan, command_fan_config); + + static int command_thermal_auto_fan_ctrl(int argc, char **argv) { return thermal_toggle_auto_fan_ctrl(1); |