Felix Held has submitted this change. ( https://review.coreboot.org/c/coreboot/+/35858 )
Change subject: superio/hwm5_conf: factor out HWM access from ITE env_ctrl ......................................................................
superio/hwm5_conf: factor out HWM access from ITE env_ctrl
Nuvoton and Winbond use the same off-by-5 indirect address space to access their hardware monitor/environment controller in the SIO chip, so move this to a common location and replace the inb/outb calls with the corresponding inline functions from device/pnp.h
Change-Id: I20606313d0cc9cf74be7dca30bc4550059125fe1 Signed-off-by: Felix Held felix-coreboot@felixheld.de Reviewed-on: https://review.coreboot.org/c/coreboot/+/35858 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: HAOUAS Elyes ehaouas@noos.fr --- A src/include/superio/hwm5_conf.h M src/superio/ite/common/env_ctrl.c 2 files changed, 109 insertions(+), 71 deletions(-)
Approvals: build bot (Jenkins): Verified HAOUAS Elyes: Looks good to me, approved
diff --git a/src/include/superio/hwm5_conf.h b/src/include/superio/hwm5_conf.h new file mode 100644 index 0000000..bfec0fd --- /dev/null +++ b/src/include/superio/hwm5_conf.h @@ -0,0 +1,58 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef DEVICE_PNP_HWM5_CONF_H +#define DEVICE_PNP_HWM5_CONF_H + +#include <device/pnp.h> + +/* The address/data register pair for the indirect/indexed IO space of the + * hardware monitor (HWM) that does temperature and voltage sensing and fan + * control in ITE, Nuvoton and Winbond super IO chips aren't at offset 0 and 1 + * of the corresponding IO address region, but at offset 5 and 6. */ + +/* + * u8 pnp_read_hwm5_index(u16 port, u8 reg) + * Description: + * This routine reads indexed I/O registers. The reg byte is written + * to the index register at I/O address = port + 5. The result is then + * read from the data register at I/O address = port + 6. + * + * Parameters: + * @param[in] u16 base = The I/O address of the port index register. + * @param[in] u8 reg = The offset within the indexed space. + * @param[out] u8 result = The value read back from the data register. + */ +static inline u8 pnp_read_hwm5_index(u16 base, u8 reg) +{ + return pnp_read_index(base + 5, reg); +} + +/* + * void pnp_write_hwm5_index(u16 port, u8 reg, u8 value) + * Description: + * This routine writes indexed I/O registers. The reg byte is written + * to the index register at I/O address = port + 5. The value byte is then + * written to the data register at I/O address = port + 6. + * + * Parameters: + * @param[in] u16 base = The address of the port index register. + * @param[in] u8 reg = The offset within the indexed space. + * @param[in] u8 value = The value to be written to the data register. + */ +static inline void pnp_write_hwm5_index(u16 base, u8 reg, u8 value) +{ + pnp_write_index(base + 5, reg, value); +} + +#endif /* DEVICE_PNP_HWM5_CONF_H */ diff --git a/src/superio/ite/common/env_ctrl.c b/src/superio/ite/common/env_ctrl.c index 1b93036..2f2942b 100644 --- a/src/superio/ite/common/env_ctrl.c +++ b/src/superio/ite/common/env_ctrl.c @@ -21,22 +21,11 @@ #include <arch/io.h> #include <console/console.h> #include <delay.h> +#include <superio/hwm5_conf.h>
#include "env_ctrl.h" #include "env_ctrl_chip.h"
-static inline u8 ite_ec_read(const u16 base, const u8 addr) -{ - outb(addr, base + 5); - return inb(base + 6); -} - -static inline void ite_ec_write(const u16 base, const u8 addr, const u8 value) -{ - outb(addr, base + 5); - outb(value, base + 6); -} - static void extemp_force_idle_status(const u16 base) { u8 reg; @@ -44,7 +33,7 @@
/* Wait up to 10ms for non-busy state. */ while (retries > 0) { - reg = ite_ec_read(base, ITE_EC_EXTEMP_STATUS); + reg = pnp_read_hwm5_index(base, ITE_EC_EXTEMP_STATUS);
if ((reg & ITE_EC_EXTEMP_STATUS_HOST_BUSY) == 0x0) break; @@ -59,9 +48,8 @@ * SIO is busy due to unfinished peci transaction. * Re-configure Register 0x8E to terminate processes. */ - ite_ec_write(base, ITE_EC_EXTEMP_CONTROL, - ITE_EC_EXTEMP_CTRL_AUTO_4HZ | - ITE_EC_EXTEMP_CTRL_AUTO_START); + pnp_write_hwm5_index(base, ITE_EC_EXTEMP_CONTROL, + ITE_EC_EXTEMP_CTRL_AUTO_4HZ | ITE_EC_EXTEMP_CTRL_AUTO_START); } }
@@ -71,22 +59,16 @@ static void enable_peci(const u16 base) { /* Enable PECI interface */ - ite_ec_write(base, ITE_EC_INTERFACE_SELECT, - ITE_EC_INTERFACE_SEL_PECI | - ITE_EC_INTERFACE_SPEED_TOLERANCE); + pnp_write_hwm5_index(base, ITE_EC_INTERFACE_SELECT, + ITE_EC_INTERFACE_SEL_PECI | ITE_EC_INTERFACE_SPEED_TOLERANCE);
/* Setup External Temperature using PECI GetTemp */ - ite_ec_write(base, ITE_EC_EXTEMP_ADDRESS, - PECI_CLIENT_ADDRESS); - ite_ec_write(base, ITE_EC_EXTEMP_COMMAND, - PECI_GETTEMP_COMMAND); - ite_ec_write(base, ITE_EC_EXTEMP_WRITE_LENGTH, - PECI_GETTEMP_WRITE_LENGTH); - ite_ec_write(base, ITE_EC_EXTEMP_READ_LENGTH, - PECI_GETTEMP_READ_LENGTH); - ite_ec_write(base, ITE_EC_EXTEMP_CONTROL, - ITE_EC_EXTEMP_CTRL_AUTO_4HZ | - ITE_EC_EXTEMP_CTRL_AUTO_START); + pnp_write_hwm5_index(base, ITE_EC_EXTEMP_ADDRESS, PECI_CLIENT_ADDRESS); + pnp_write_hwm5_index(base, ITE_EC_EXTEMP_COMMAND, PECI_GETTEMP_COMMAND); + pnp_write_hwm5_index(base, ITE_EC_EXTEMP_WRITE_LENGTH, PECI_GETTEMP_WRITE_LENGTH); + pnp_write_hwm5_index(base, ITE_EC_EXTEMP_READ_LENGTH, PECI_GETTEMP_READ_LENGTH); + pnp_write_hwm5_index(base, ITE_EC_EXTEMP_CONTROL, + ITE_EC_EXTEMP_CTRL_AUTO_4HZ | ITE_EC_EXTEMP_CTRL_AUTO_START); }
/* @@ -98,7 +80,7 @@ { u8 reg;
- reg = ite_ec_read(base, ITE_EC_ADC_TEMP_CHANNEL_ENABLE); + reg = pnp_read_hwm5_index(base, ITE_EC_ADC_TEMP_CHANNEL_ENABLE);
switch (conf->mode) { case THERMAL_PECI: @@ -122,26 +104,25 @@ return; }
- ite_ec_write(base, ITE_EC_ADC_TEMP_CHANNEL_ENABLE, reg); + pnp_write_hwm5_index(base, ITE_EC_ADC_TEMP_CHANNEL_ENABLE, reg);
/* Set temperature offsets */ if (conf->mode != THERMAL_RESISTOR) { - reg = ite_ec_read(base, ITE_EC_BEEP_ENABLE); + reg = pnp_read_hwm5_index(base, ITE_EC_BEEP_ENABLE); reg |= ITE_EC_TEMP_ADJUST_WRITE_ENABLE; - ite_ec_write(base, ITE_EC_BEEP_ENABLE, reg); - ite_ec_write(base, ITE_EC_TEMP_ADJUST[tmpin-1], conf->offset); + pnp_write_hwm5_index(base, ITE_EC_BEEP_ENABLE, reg); + pnp_write_hwm5_index(base, ITE_EC_TEMP_ADJUST[tmpin-1], conf->offset); }
/* Set temperature limits */ u8 max = conf->max; - ite_ec_write(base, ITE_EC_HIGH_TEMP_LIMIT(tmpin), - max ? max : 127); - ite_ec_write(base, ITE_EC_LOW_TEMP_LIMIT(tmpin), conf->min); + pnp_write_hwm5_index(base, ITE_EC_HIGH_TEMP_LIMIT(tmpin), max ? max : 127); + pnp_write_hwm5_index(base, ITE_EC_LOW_TEMP_LIMIT(tmpin), conf->min);
/* Enable the startup of monitoring operation */ - reg = ite_ec_read(base, ITE_EC_CONFIGURATION); + reg = pnp_read_hwm5_index(base, ITE_EC_CONFIGURATION); reg |= ITE_EC_CONFIGURATION_START; - ite_ec_write(base, ITE_EC_CONFIGURATION, reg); + pnp_write_hwm5_index(base, ITE_EC_CONFIGURATION, reg); }
static void fan_smartconfig(const u16 base, const u8 fan, @@ -177,20 +158,19 @@ if (conf->smoothing) pwm_auto |= ITE_EC_FAN_CTL_AUTO_SMOOTHING_EN;
- ite_ec_write(base, ITE_EC_FAN_CTL_TEMP_LIMIT_OFF(fan), - conf->tmp_off); - ite_ec_write(base, ITE_EC_FAN_CTL_TEMP_LIMIT_START(fan), - conf->tmp_start); + pnp_write_hwm5_index(base, ITE_EC_FAN_CTL_TEMP_LIMIT_OFF(fan), conf->tmp_off); + pnp_write_hwm5_index(base, ITE_EC_FAN_CTL_TEMP_LIMIT_START(fan), + conf->tmp_start); /* Full speed above 127°C by default */ - ite_ec_write(base, ITE_EC_FAN_CTL_TEMP_LIMIT_FULL(fan), - conf->tmp_full ? conf->tmp_full : 127); - ite_ec_write(base, ITE_EC_FAN_CTL_DELTA_TEMP(fan), - ITE_EC_FAN_CTL_DELTA_TEMP_INTRVL(conf->tmp_delta)); + pnp_write_hwm5_index(base, ITE_EC_FAN_CTL_TEMP_LIMIT_FULL(fan), + conf->tmp_full ? conf->tmp_full : 127); + pnp_write_hwm5_index(base, ITE_EC_FAN_CTL_DELTA_TEMP(fan), + ITE_EC_FAN_CTL_DELTA_TEMP_INTRVL(conf->tmp_delta)); }
- ite_ec_write(base, ITE_EC_FAN_CTL_PWM_CONTROL(fan), pwm_ctrl); - ite_ec_write(base, ITE_EC_FAN_CTL_PWM_START(fan), pwm_start); - ite_ec_write(base, ITE_EC_FAN_CTL_PWM_AUTO(fan), pwm_auto); + pnp_write_hwm5_index(base, ITE_EC_FAN_CTL_PWM_CONTROL(fan), pwm_ctrl); + pnp_write_hwm5_index(base, ITE_EC_FAN_CTL_PWM_START(fan), pwm_start); + pnp_write_hwm5_index(base, ITE_EC_FAN_CTL_PWM_AUTO(fan), pwm_auto); }
static void enable_fan(const u16 base, const u8 fan, @@ -205,39 +185,39 @@
/* FAN_CTL2 might have its own frequency setting */ if (CONFIG(SUPERIO_ITE_ENV_CTRL_PWM_FREQ2) && fan == 2) { - reg = ite_ec_read(base, ITE_EC_ADC_TEMP_EXTRA_CHANNEL_ENABLE); + reg = pnp_read_hwm5_index(base, ITE_EC_ADC_TEMP_EXTRA_CHANNEL_ENABLE); reg &= ~ITE_EC_FAN_PWM_CLOCK_MASK; reg |= ITE_EC_FAN_PWM_DEFAULT_CLOCK; - ite_ec_write(base, ITE_EC_ADC_TEMP_EXTRA_CHANNEL_ENABLE, reg); + pnp_write_hwm5_index(base, ITE_EC_ADC_TEMP_EXTRA_CHANNEL_ENABLE, reg); }
if (conf->mode >= FAN_SMART_SOFTWARE) { fan_smartconfig(base, fan, conf->mode, &conf->smart); } else { - reg = ite_ec_read(base, ITE_EC_FAN_CTL_MODE); + reg = pnp_read_hwm5_index(base, ITE_EC_FAN_CTL_MODE); if (conf->mode == FAN_MODE_ON) reg |= ITE_EC_FAN_CTL_ON(fan); else reg &= ~ITE_EC_FAN_CTL_ON(fan); - ite_ec_write(base, ITE_EC_FAN_CTL_MODE, reg); + pnp_write_hwm5_index(base, ITE_EC_FAN_CTL_MODE, reg); }
if (CONFIG(SUPERIO_ITE_ENV_CTRL_FAN16_CONFIG) && conf->mode >= FAN_MODE_ON) { - reg = ite_ec_read(base, ITE_EC_FAN_TAC_COUNTER_ENABLE); + reg = pnp_read_hwm5_index(base, ITE_EC_FAN_TAC_COUNTER_ENABLE); reg |= ITE_EC_FAN_TAC_16BIT_ENABLE(fan); - ite_ec_write(base, ITE_EC_FAN_TAC_COUNTER_ENABLE, reg); + pnp_write_hwm5_index(base, ITE_EC_FAN_TAC_COUNTER_ENABLE, reg); }
if (CONFIG(SUPERIO_ITE_ENV_CTRL_5FANS) && fan > 3) { - reg = ite_ec_read(base, ITE_EC_FAN_SEC_CTL); + reg = pnp_read_hwm5_index(base, ITE_EC_FAN_SEC_CTL); if (conf->mode >= FAN_MODE_ON) reg |= ITE_EC_FAN_SEC_CTL_TAC_EN(fan); else reg &= ~ITE_EC_FAN_SEC_CTL_TAC_EN(fan); - ite_ec_write(base, ITE_EC_FAN_SEC_CTL, reg); + pnp_write_hwm5_index(base, ITE_EC_FAN_SEC_CTL, reg); } else { - reg = ite_ec_read(base, ITE_EC_FAN_MAIN_CTL); + reg = pnp_read_hwm5_index(base, ITE_EC_FAN_MAIN_CTL); if (conf->mode >= FAN_MODE_ON) reg |= ITE_EC_FAN_MAIN_CTL_TAC_EN(fan); else @@ -250,7 +230,7 @@ else reg &= ~ITE_EC_FAN_MAIN_CTL_SMART(fan); } - ite_ec_write(base, ITE_EC_FAN_MAIN_CTL, reg); + pnp_write_hwm5_index(base, ITE_EC_FAN_MAIN_CTL, reg); } }
@@ -261,20 +241,20 @@
if (conf->tmpin_beep) { reg |= ITE_EC_BEEP_ON_TMP_LIMIT; - ite_ec_write(base, ITE_EC_BEEP_FREQ_DIV_OF_TMPIN, freq); + pnp_write_hwm5_index(base, ITE_EC_BEEP_FREQ_DIV_OF_TMPIN, freq); } if (conf->fan_beep) { reg |= ITE_EC_BEEP_ON_FAN_LIMIT; - ite_ec_write(base, ITE_EC_BEEP_FREQ_DIV_OF_FAN, freq); + pnp_write_hwm5_index(base, ITE_EC_BEEP_FREQ_DIV_OF_FAN, freq); } if (conf->vin_beep) { reg |= ITE_EC_BEEP_ON_VIN_LIMIT; - ite_ec_write(base, ITE_EC_BEEP_FREQ_DIV_OF_VIN, freq); + pnp_write_hwm5_index(base, ITE_EC_BEEP_FREQ_DIV_OF_VIN, freq); }
if (reg) { - reg |= ite_ec_read(base, ITE_EC_BEEP_ENABLE); - ite_ec_write(base, ITE_EC_BEEP_ENABLE, reg); + reg |= pnp_read_hwm5_index(base, ITE_EC_BEEP_ENABLE); + pnp_write_hwm5_index(base, ITE_EC_BEEP_ENABLE, reg); } }
@@ -283,11 +263,11 @@ size_t i;
/* Configure 23.43kHz PWM active high output */ - u8 fan_ctl = ite_ec_read(base, ITE_EC_FAN_CTL_MODE); + u8 fan_ctl = pnp_read_hwm5_index(base, ITE_EC_FAN_CTL_MODE); fan_ctl &= ~ITE_EC_FAN_PWM_CLOCK_MASK; fan_ctl |= ITE_EC_FAN_PWM_DEFAULT_CLOCK; fan_ctl |= ITE_EC_FAN_CTL_POLARITY_HIGH; - ite_ec_write(base, ITE_EC_FAN_CTL_MODE, fan_ctl); + pnp_write_hwm5_index(base, ITE_EC_FAN_CTL_MODE, fan_ctl);
/* Enable HWM if configured */ for (i = 0; i < ITE_EC_TMPIN_CNT; ++i) @@ -295,13 +275,13 @@
/* Enable External Sensor SMBus Host if configured */ if (conf->smbus_en) { - ite_ec_write(base, ITE_EC_INTERFACE_SELECT, - ite_ec_read(base, ITE_EC_INTERFACE_SELECT) | + pnp_write_hwm5_index(base, ITE_EC_INTERFACE_SELECT, + pnp_read_hwm5_index(base, ITE_EC_INTERFACE_SELECT) | ITE_EC_INTERFACE_SMB_ENABLE); }
/* Enable reading of voltage pins */ - ite_ec_write(base, ITE_EC_ADC_VOLTAGE_CHANNEL_ENABLE, conf->vin_mask); + pnp_write_hwm5_index(base, ITE_EC_ADC_VOLTAGE_CHANNEL_ENABLE, conf->vin_mask);
/* Enable FANx if configured */ for (i = 0; i < ITE_EC_FAN_CNT; ++i)