diff options
-rw-r--r-- | board/fizz/board.c | 78 | ||||
-rw-r--r-- | board/fizz/board.h | 3 | ||||
-rw-r--r-- | board/samus/board.c | 30 | ||||
-rw-r--r-- | common/fan.c | 4 | ||||
-rw-r--r-- | common/thermal.c | 10 | ||||
-rw-r--r-- | driver/temp_sensor/tmp432.c | 62 | ||||
-rw-r--r-- | driver/temp_sensor/tmp432.h | 1 | ||||
-rw-r--r-- | include/ec_commands.h | 16 |
8 files changed, 171 insertions, 33 deletions
diff --git a/board/fizz/board.c b/board/fizz/board.c index 940caeae37..ce0ff98920 100644 --- a/board/fizz/board.c +++ b/board/fizz/board.c @@ -149,9 +149,9 @@ BUILD_ASSERT(ARRAY_SIZE(adc_channels) == ADC_CH_COUNT); const struct fan_t fans[] = { [FAN_CH_0] = { .flags = FAN_USE_RPM_MODE, - .rpm_min = 1000, - .rpm_start = 1000, - .rpm_max = 5500, + .rpm_min = 2800, + .rpm_start = 2800, + .rpm_max = 5600, .ch = MFT_CH_0, /* Use MFT id to control fan */ .pgood_gpio = -1, .enable_gpio = GPIO_FAN_PWR_EN, @@ -271,10 +271,14 @@ BUILD_ASSERT(ARRAY_SIZE(temp_sensors) == TEMP_SENSOR_COUNT); * same order as enum temp_sensor_id. To always ignore any temp, use 0. */ struct ec_thermal_config thermal_params[] = { - /* {Twarn, Thigh, Thalt}, fan_off, fan_max */ - {{0, 0, 0}, C_TO_K(35), C_TO_K(68)}, /* TMP432_Internal */ - {{0, 0, 0}, 0, 0}, /* TMP432_Sensor_1 */ - {{0, 0, 0}, 0, 0}, /* TMP432_Sensor_2 */ + /* {Twarn, Thigh, Thalt}, <on> + * {Twarn, Thigh, X }, <off> + * fan_off, fan_max + */ + {{0, C_TO_K(87), C_TO_K(89)}, {0, C_TO_K(86), 0}, + C_TO_K(44), C_TO_K(81)},/* TMP432_Internal */ + {{0, 0, 0}, {0, 0, 0}, 0, 0}, /* TMP432_Sensor_1 */ + {{0, 0, 0}, {0, 0, 0}, 0, 0}, /* TMP432_Sensor_2 */ }; BUILD_ASSERT(ARRAY_SIZE(thermal_params) == TEMP_SENSOR_COUNT); @@ -522,3 +526,63 @@ const struct pwm_t pwm_channels[] = { [PWM_CH_FAN] = {4, PWM_CONFIG_OPEN_DRAIN, 25000}, }; BUILD_ASSERT(ARRAY_SIZE(pwm_channels) == PWM_CH_COUNT); + +struct fan_step { + int on; + int off; + int rpm; +}; + +/* Do not make the fan on/off point equal to 0 or 100 */ +const struct fan_step fan_table[] = { + {.off = 2, .rpm = 0}, + {.on = 16, .off = 2, .rpm = 2800}, + {.on = 27, .off = 18, .rpm = 3200}, + {.on = 35, .off = 29, .rpm = 3400}, + {.on = 43, .off = 37, .rpm = 4200}, + {.on = 54, .off = 45, .rpm = 4800}, + {.on = 64, .off = 56, .rpm = 5200}, + {.on = 97, .off = 83, .rpm = 5600}, +}; +#define NUM_FAN_LEVELS ARRAY_SIZE(fan_table) + +int fan_percent_to_rpm(int fan, int pct) +{ + static int current_level; + static int previous_pct; + int i; + + /* + * Compare the pct and previous pct, we have the three paths : + * 1. decreasing path. (check the off point) + * 2. increasing path. (check the on point) + * 3. invariant path. (return the current RPM) + */ + if (pct < previous_pct) { + for (i = current_level; i >= 0; i--) { + if (pct <= fan_table[i].off) + current_level = i - 1; + else + break; + } + } else if (pct > previous_pct) { + for (i = current_level + 1; i < NUM_FAN_LEVELS; i++) { + if (pct >= fan_table[i].on) + current_level = i; + else + break; + } + } + + if (current_level < 0) + current_level = 0; + + previous_pct = pct; + + if (fan_table[current_level].rpm != + fan_get_rpm_target(fans[fan].ch)) + cprintf(CC_THERMAL, "[%T Setting fan RPM to %d]\n", + fan_table[current_level].rpm); + + return fan_table[current_level].rpm; +} diff --git a/board/fizz/board.h b/board/fizz/board.h index 1e79eb97a1..6b1c27d020 100644 --- a/board/fizz/board.h +++ b/board/fizz/board.h @@ -46,6 +46,9 @@ #define WIRELESS_GPIO_WLAN_POWER GPIO_PP3300_DX_WLAN #define WIRELESS_GPIO_WWAN GPIO_PP3300_DX_LTE #define CONFIG_FANS 1 +#define CONFIG_FAN_RPM_CUSTOM +#define CONFIG_THROTTLE_AP +#define CONFIG_CHIPSET_CAN_THROTTLE #define CONFIG_PWM /* EC console commands */ diff --git a/board/samus/board.c b/board/samus/board.c index 01ad05e7a2..db49a573af 100644 --- a/board/samus/board.c +++ b/board/samus/board.c @@ -181,21 +181,21 @@ BUILD_ASSERT(ARRAY_SIZE(als) == ALS_COUNT); struct ec_thermal_config thermal_params[] = { /* {Twarn, Thigh, Thalt}, fan_off, fan_max */ {{C_TO_K(95), C_TO_K(101), C_TO_K(104)}, - C_TO_K(55), C_TO_K(90)}, /* PECI */ - {{0, 0, 0}, 0, 0}, /* EC */ - {{0, 0, 0}, C_TO_K(41), C_TO_K(55)}, /* Charger die */ - {{0, 0, 0}, 0, 0}, - {{0, 0, 0}, C_TO_K(35), C_TO_K(49)}, /* CPU die */ - {{0, 0, 0}, 0, 0}, - {{0, 0, 0}, 0, 0}, /* Left C die */ - {{0, 0, 0}, 0, 0}, - {{0, 0, 0}, 0, 0}, /* Right C die */ - {{0, 0, 0}, 0, 0}, - {{0, 0, 0}, 0, 0}, /* Right D die */ - {{0, 0, 0}, 0, 0}, - {{0, 0, 0}, C_TO_K(43), C_TO_K(54)}, /* Left D die */ - {{0, 0, 0}, 0, 0}, - {{0, 0, 0}, 0, 0}, /* Battery */ + {0, 0, 0}, C_TO_K(55), C_TO_K(90)}, /* PECI */ + {{0, 0, 0}, {0, 0, 0}, 0, 0}, /* EC */ + {{0, 0, 0}, {0, 0, 0}, C_TO_K(41), C_TO_K(55)}, /* Charger die */ + {{0, 0, 0}, {0, 0, 0}, 0, 0}, + {{0, 0, 0}, {0, 0, 0}, C_TO_K(35), C_TO_K(49)}, /* CPU die */ + {{0, 0, 0}, {0, 0, 0}, 0, 0}, + {{0, 0, 0}, {0, 0, 0}, 0, 0}, /* Left C die */ + {{0, 0, 0}, {0, 0, 0}, 0, 0}, + {{0, 0, 0}, {0, 0, 0}, 0, 0}, /* Right C die */ + {{0, 0, 0}, {0, 0, 0}, 0, 0}, + {{0, 0, 0}, {0, 0, 0}, 0, 0}, /* Right D die */ + {{0, 0, 0}, {0, 0, 0}, 0, 0}, + {{0, 0, 0}, {0, 0, 0}, C_TO_K(43), C_TO_K(54)}, /* Left D die */ + {{0, 0, 0}, {0, 0, 0}, 0, 0}, + {{0, 0, 0}, {0, 0, 0}, 0, 0}, /* Battery */ }; BUILD_ASSERT(ARRAY_SIZE(thermal_params) == TEMP_SENSOR_COUNT); diff --git a/common/fan.c b/common/fan.c index 18ea31acdb..5e2f85475f 100644 --- a/common/fan.c +++ b/common/fan.c @@ -510,7 +510,11 @@ static void pwm_fan_resume(void) { int fan; for (fan = 0; fan < CONFIG_FANS; fan++) { +#ifdef CONFIG_FAN_RPM_CUSTOM + set_thermal_control_enabled(fan, 1); +#else set_thermal_control_enabled(fan, 0); +#endif fan_set_rpm_target(fans[fan].ch, fans[fan].rpm_max); set_enabled(fan, 1); } diff --git a/common/thermal.c b/common/thermal.c index bd9ed7fbf0..7d7438f3e5 100644 --- a/common/thermal.c +++ b/common/thermal.c @@ -80,12 +80,17 @@ static void thermal_control(void) /* check all the limits */ for (j = 0; j < EC_TEMP_THRESH_COUNT; j++) { int limit = thermal_params[i].temp_host[j]; + int release = thermal_params[i].temp_host_release[j]; if (limit) { num_valid_limits[j]++; - if (t > limit) + if (t > limit) { count_over[j]++; - else if (t < limit) + } else if (release) { + if (t < release) + count_under[j]++; + } else if (t < limit) { count_under[j]++; + } } } @@ -130,7 +135,6 @@ static void thermal_control(void) cond_set_false(&cond_hot[j]); } - /* What do we do about it? (note hard-coded logic). */ if (cond_went_true(&cond_hot[EC_TEMP_THRESH_HALT])) { diff --git a/driver/temp_sensor/tmp432.c b/driver/temp_sensor/tmp432.c index f288f40ed5..0874da74b6 100644 --- a/driver/temp_sensor/tmp432.c +++ b/driver/temp_sensor/tmp432.c @@ -17,6 +17,7 @@ static int temp_val_local; static int temp_val_remote1; static int temp_val_remote2; static uint8_t is_sensor_shutdown; +static int fake_temp[TMP432_IDX_COUNT] = {-1, -1, -1}; /** * Determine whether the sensor is powered. @@ -183,18 +184,44 @@ static void temp_sensor_poll(void) if (!has_power()) return; - if (get_temp(TMP432_LOCAL, &temp_c) == EC_SUCCESS) - temp_val_local = C_TO_K(temp_c); + if (fake_temp[TMP432_IDX_LOCAL] != -1) { + temp_val_local = C_TO_K(fake_temp[TMP432_IDX_LOCAL]); + } else { + if (get_temp(TMP432_LOCAL, &temp_c) == EC_SUCCESS) + temp_val_local = C_TO_K(temp_c); + /* else: Keep previous value when it fails */ + } - if (get_temp(TMP432_REMOTE1, &temp_c) == EC_SUCCESS) - temp_val_remote1 = C_TO_K(temp_c); + if (fake_temp[TMP432_IDX_REMOTE1] != -1) { + temp_val_remote1 = C_TO_K(fake_temp[TMP432_IDX_REMOTE1]); + } else { + if (get_temp(TMP432_REMOTE1, &temp_c) == EC_SUCCESS) + temp_val_remote1 = C_TO_K(temp_c); + /* else: Keep previous value when it fails */ + } - if (get_temp(TMP432_REMOTE2, &temp_c) == EC_SUCCESS) - temp_val_remote2 = C_TO_K(temp_c); + if (fake_temp[TMP432_IDX_REMOTE2] != -1) { + temp_val_remote2 = C_TO_K(fake_temp[TMP432_IDX_REMOTE2]); + } else { + if (get_temp(TMP432_REMOTE2, &temp_c) == EC_SUCCESS) + temp_val_remote2 = C_TO_K(temp_c); + /* else: Keep previous value when it fails */ + } } DECLARE_HOOK(HOOK_SECOND, temp_sensor_poll, HOOK_PRIO_TEMP_SENSOR); #ifdef CONFIG_CMD_TEMP_SENSOR +static int tmp432_set_fake_temp(int index, int degree_c) +{ + if ((index < 0) || (index >= TMP432_IDX_COUNT)) + return EC_ERROR_INVAL; + + fake_temp[index] = degree_c; + ccprintf("New degree will be updated 1 sec later\n\n"); + + return EC_SUCCESS; +} + static void print_temps( const char *name, const int tmp432_temp_reg, @@ -226,7 +253,7 @@ static void print_temps( static int print_status(void) { - int value; + int value, i; print_temps("Local", TMP432_LOCAL, TMP432_LOCAL_THERM_LIMIT, @@ -245,6 +272,21 @@ static int print_status(void) ccprintf("\n"); + for (i = 0; i < TMP432_IDX_COUNT; ++i) { + ccprintf("fake temperature[%d]= ", i); + if (fake_temp[i] == -1) { + ccprintf("Not overridden\n"); + continue; + } + + if (tmp432_get_val(i, &value) == EC_SUCCESS) + ccprintf("%d C or %d K\n", (value - 273), value); + else + ccprintf("Access error\n"); + } + + ccprintf("\n"); + if (raw_read8(TMP432_STATUS, &value) == EC_SUCCESS) ccprintf("STATUS: %08b\n", value); @@ -321,6 +363,10 @@ static int command_tmp432(int argc, char **argv) } else if (!strcasecmp(command, "setbyte")) { ccprintf("Setting 0x%02x to 0x%02x\n", offset, data); rv = raw_write8(offset, data); + } else if (!strcasecmp(command, "fake")) { + ccprintf("Hook temperature\n"); + rv = tmp432_set_fake_temp(offset, data); + print_status(); } else return EC_ERROR_PARAM1; @@ -328,7 +374,7 @@ static int command_tmp432(int argc, char **argv) } DECLARE_CONSOLE_COMMAND(tmp432, command_tmp432, "[settemp|setbyte <offset> <value>] or [getbyte <offset>] or" - "[power <on|off>]. " + "[fake <index> <value>] or [power <on|off>]. " "Temps in Celsius.", "Print tmp432 temp sensor status or set parameters."); #endif diff --git a/driver/temp_sensor/tmp432.h b/driver/temp_sensor/tmp432.h index ea6f3286c6..2d8d2515dc 100644 --- a/driver/temp_sensor/tmp432.h +++ b/driver/temp_sensor/tmp432.h @@ -13,6 +13,7 @@ #define TMP432_IDX_LOCAL 0 #define TMP432_IDX_REMOTE1 1 #define TMP432_IDX_REMOTE2 2 +#define TMP432_IDX_COUNT 3 /* Chip-specific registers */ #define TMP432_LOCAL 0x00 diff --git a/include/ec_commands.h b/include/ec_commands.h index 373b23104b..09ebc75319 100644 --- a/include/ec_commands.h +++ b/include/ec_commands.h @@ -2680,11 +2680,27 @@ enum ec_temp_thresholds { * Thermal configuration for one temperature sensor. Temps are in degrees K. * Zero values will be silently ignored by the thermal task. * + * Set 'temp_host' value allows thermal task to trigger some event with 1 degree + * hysteresis. + * For example, + * temp_host[EC_TEMP_THRESH_HIGH] = 300 K + * temp_host_release[EC_TEMP_THRESH_HIGH] = 0 K + * EC will throttle ap when temperature >= 301 K, and release throttling when + * temperature <= 299 K. + * + * Set 'temp_host_release' value allows thermal task has a custom hysteresis. + * For example, + * temp_host[EC_TEMP_THRESH_HIGH] = 300 K + * temp_host_release[EC_TEMP_THRESH_HIGH] = 295 K + * EC will throttle ap when temperature >= 301 K, and release throttling when + * temperature <= 294 K. + * * Note that this structure is a sub-structure of * ec_params_thermal_set_threshold_v1, but maintains its alignment there. */ struct __ec_align4 ec_thermal_config { uint32_t temp_host[EC_TEMP_THRESH_COUNT]; /* levels of hotness */ + uint32_t temp_host_release[EC_TEMP_THRESH_COUNT]; /* release levels */ uint32_t temp_fan_off; /* no active cooling needed */ uint32_t temp_fan_max; /* max active cooling needed */ }; |