superio/ite: Add special fan vectors

A number of ITE SIOs support "special fan control vectors", which
effectively allow non-linear fan speed control. This is for example used
by the vendor firmware of the "HP Pro 3500 Series".

The special vector registers won't be written to until the mb's
devicetree configures `FAN_VECX.tmp_start != 0`.

Change-Id: I93df2b5652fc3fde775b6161fa5bebc4a34d5e94
Signed-off-by: Joel Linn <jl@conductive.de>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/81426
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
This commit is contained in:
Joel Linn 2024-03-26 18:33:38 +01:00 committed by Nico Huber
parent fb51661be1
commit 9905d1f8a8
6 changed files with 95 additions and 0 deletions

View File

@ -54,4 +54,15 @@ config SUPERIO_ITE_ENV_CTRL_NO_FULLSPEED_SETTING
Fan controller does not support running at full speed when limit
temperature is reached.
config SUPERIO_ITE_ENV_CTRL_FAN_VECTOR
bool
help
Special fan control that will assist the smart control
config SUPERIO_ITE_ENV_CTRL_FAN_VECTOR_RANGED
bool
depends on SUPERIO_ITE_ENV_CTRL_FAN_VECTOR
help
Range and negative slope support
endif

View File

@ -253,6 +253,49 @@ static void enable_fan(const u16 base, const u8 fan,
}
}
static void enable_fan_vector(const u16 base, const u8 fan_vector,
const struct ite_ec_fan_vector_config *const conf)
{
u8 reg;
u8 start = conf->tmp_start;
if (!start) {
/* When tmp_start is not configured we would set the
* register to it's default of 0xFF here, which would
* effectively disable the vector functionality of the
* SuperIO altogether since that temperature will never
* be reached. We can therefore return here and don't
* need to set any other registers.
*/
return;
}
pnp_write_hwm5_index(base, ITE_EC_FAN_VEC_CTL_LIMIT_START(fan_vector), start);
const s8 slope = conf->slope;
const bool slope_neg = slope < 0;
if (slope <= -128)
reg = 127;
else if (slope_neg)
reg = -slope;
else
reg = slope;
reg |= ITE_EC_FAN_VEC_CTL_SLOPE_TMPIN0(conf->tmpin);
pnp_write_hwm5_index(base, ITE_EC_FAN_VEC_CTL_SLOPE(fan_vector), reg);
reg = ITE_EC_FAN_VEC_CTL_DELTA_TEMP_INTRVL(conf->tmp_delta);
reg |= ITE_EC_FAN_VEC_CTL_DELTA_FANOUT(conf->fanout);
reg |= ITE_EC_FAN_VEC_CTL_DELTA_TMPIN1(conf->tmpin);
pnp_write_hwm5_index(base, ITE_EC_FAN_VEC_CTL_DELTA(fan_vector), reg);
if (CONFIG(SUPERIO_ITE_ENV_CTRL_FAN_VECTOR_RANGED)) {
reg = conf->tmp_range & 0x7f;
reg |= ITE_EC_FAN_VEC_CTL_RANGE_SLOPESIGN(slope_neg);
pnp_write_hwm5_index(base, ITE_EC_FAN_VEC_CTL_RANGE(fan_vector), reg);
} else if (slope_neg) {
printk(BIOS_WARNING, "Unsupported negative slope on fan vector control\n");
}
}
static void enable_beeps(const u16 base, const struct ite_ec_config *const conf)
{
u8 reg = 0;
@ -313,6 +356,12 @@ void ite_ec_init(const u16 base, const struct ite_ec_config *const conf)
for (i = 0; i < ITE_EC_FAN_CNT; ++i)
enable_fan(base, i + 1, &conf->fan[i]);
if (CONFIG(SUPERIO_ITE_ENV_CTRL_FAN_VECTOR)) {
/* Enable Special FAN Vector X if configured */
for (i = 0; i < ITE_EC_FAN_VECTOR_CNT; ++i)
enable_fan_vector(base, i, &conf->fan_vector[i]);
}
/* Enable beeps if configured */
enable_beeps(base, conf);

View File

@ -199,6 +199,17 @@ static const u8 ITE_EC_TEMP_ADJUST[] = { 0x56, 0x57, 0x59 };
#define ITE_EC_FAN_CTL_TARGET_ZONE(x) (0x66 + ((x)-1) * 8)
#define ITE_EC_FAN_CTL_TARGET_ZONE_MASK 0x0f
#define ITE_EC_FAN_VEC_CTL_LIMIT_START(x) (0x90 + (x) * 4)
#define ITE_EC_FAN_VEC_CTL_SLOPE(x) (0x91 + (x) * 4)
#define ITE_EC_FAN_VEC_CTL_DELTA(x) (0x92 + (x) * 4)
#define ITE_EC_FAN_VEC_CTL_RANGE(x) (0x93 + (x) * 4)
#define ITE_EC_FAN_VEC_CTL_SLOPE_TMPIN0(x) (((x) & 0x1) << 7)
#define ITE_EC_FAN_VEC_CTL_DELTA_TMPIN1(x) (((x) & 0x2) << 6)
#define ITE_EC_FAN_VEC_CTL_DELTA_TEMP_INTRVL(c) ITE_EC_FAN_CTL_DELTA_TEMP_INTRVL(c)
#define ITE_EC_FAN_VEC_CTL_DELTA_FANOUT(x) (((x) & 0x3) << 5)
#define ITE_EC_FAN_VEC_CTL_RANGE_SLOPESIGN(x) (((x) & 0x1) << 7)
#define ITE_EC_EXTEMP_STATUS 0x88
#define ITE_EC_EXTEMP_STATUS_HOST_BUSY (1 << 0)
#define ITE_EC_EXTEMP_ADDRESS 0x89

View File

@ -11,6 +11,8 @@
#define ITE_EC_FAN_CNT 3
#endif
#define ITE_EC_FAN_VECTOR_CNT 2 /* A, B */
/* Supported thermal mode on TMPINx */
enum ite_ec_thermal_mode {
THERMAL_MODE_DISABLED = 0,
@ -69,6 +71,17 @@ struct ite_ec_fan_config {
struct ite_ec_fan_smartconfig smart;
};
/* Special fan control modes that will assist smart control */
struct ite_ec_fan_vector_config {
u8 tmpin; /* select TMPINx (1, 2 or 3) */
u8 fanout; /* select FANx (1, 2 or 3) */
u8 tmp_start;
u8 tmp_delta;
u8 tmp_range; /* restrict the range of the vector function,
0x00 to disable */
s8 slope;
};
struct ite_ec_config {
/*
* Enable reading of voltage pins VINx.
@ -85,6 +98,11 @@ struct ite_ec_config {
*/
struct ite_ec_fan_config fan[ITE_EC_FAN_CNT];
/*
* Enable special FAN vector control.
*/
struct ite_ec_fan_vector_config fan_vector[ITE_EC_FAN_VECTOR_CNT];
bool tmpin_beep;
bool fan_beep;
bool vin_beep;
@ -111,4 +129,7 @@ struct ite_ec_config {
#define FAN4 ec.fan[3]
#define FAN5 ec.fan[4]
#define FAN_VECA ec.fan_vector[0]
#define FAN_VECB ec.fan_vector[1]
#endif /* SUPERIO_ITE_ENV_CTRL_CHIP_H */

View File

@ -10,3 +10,4 @@ config SUPERIO_ITE_IT8728F
select SUPERIO_ITE_ENV_CTRL_5FANS
select SUPERIO_ITE_ENV_CTRL_7BIT_SLOPE_REG
select SUPERIO_ITE_ENV_CTRL_EXT_ANY_TMPIN
select SUPERIO_ITE_ENV_CTRL_FAN_VECTOR

View File

@ -7,5 +7,7 @@ config SUPERIO_ITE_IT8772F
select SUPERIO_ITE_ENV_CTRL_7BIT_SLOPE_REG
select SUPERIO_ITE_ENV_CTRL_8BIT_PWM
select SUPERIO_ITE_ENV_CTRL_EXT_ANY_TMPIN
select SUPERIO_ITE_ENV_CTRL_FAN_VECTOR
select SUPERIO_ITE_ENV_CTRL_FAN_VECTOR_RANGED
select SUPERIO_ITE_ENV_CTRL_NO_FULLSPEED_SETTING
select SUPERIO_ITE_ENV_CTRL_PWM_FREQ2