summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/fizz/board.c78
-rw-r--r--board/fizz/board.h3
-rw-r--r--board/samus/board.c30
-rw-r--r--common/fan.c4
-rw-r--r--common/thermal.c10
-rw-r--r--driver/temp_sensor/tmp432.c62
-rw-r--r--driver/temp_sensor/tmp432.h1
-rw-r--r--include/ec_commands.h16
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 */
};