coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
env_ctrl.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <console/console.h>
4 #include <delay.h>
5 #include <stddef.h>
6 #include <superio/hwm5_conf.h>
7 
8 #include "env_ctrl.h"
9 #include "env_ctrl_chip.h"
10 
11 static void extemp_force_idle_status(const u16 base)
12 {
13  u8 reg;
14  int retries = 10;
15 
16  /* Wait up to 10ms for non-busy state. */
17  while (retries > 0) {
19 
20  if ((reg & ITE_EC_EXTEMP_STATUS_HOST_BUSY) == 0x0)
21  break;
22 
23  retries--;
24 
25  mdelay(1);
26  }
27 
28  if (retries == 0 && (reg & ITE_EC_EXTEMP_STATUS_HOST_BUSY) == 0x1) {
29  /*
30  * SIO is busy due to unfinished peci transaction.
31  * Re-configure Register 0x8E to terminate processes.
32  */
35  }
36 }
37 
38 /*
39  * Setup PECI interface
40  */
41 static void enable_peci(const u16 base)
42 {
43  /* Enable PECI interface */
46 
47  /* Setup External Temperature using PECI GetTemp */
54 }
55 
56 /*
57  * Set up External Temperature to read via PECI or thermal diode/resistor
58  * into TMPINx register
59  */
60 static void enable_tmpin(const u16 base, const u8 tmpin,
61  const struct ite_ec_thermal_config *const conf)
62 {
63  u8 reg;
64  u8 reg_extra;
65 
68 
69  switch (conf->mode) {
70  case THERMAL_PECI:
71  /* Some chips can set any TMPIN as the target for PECI readings
72  while others can only read to TMPIN3. In the latter case a
73  different register is used for enabling it. */
74  if (CONFIG(SUPERIO_ITE_ENV_CTRL_EXT_ANY_TMPIN)) {
75  /* IT8721F is an exception, it cannot use TMPIN2 for PECI. */
76  if (CONFIG(SUPERIO_ITE_IT8721F) && tmpin == 2) {
78  "PECI to TMPIN2 not supported on IT8721F\n");
79  return;
80  }
83  "PECI specified for multiple TMPIN\n");
84  return;
85  }
86  reg |= ITE_EC_ADC_TEMP_EXT_REPORTS_TO(tmpin);
87  } else if (tmpin == 3) {
90  reg_extra);
91  } else {
92  printk(BIOS_WARNING, "PECI to TMPIN%d not supported on this Super I/O",
93  tmpin);
94  return;
95  }
97 
98  break;
99  case THERMAL_DIODE:
100  reg |= ITE_EC_ADC_TEMP_DIODE_MODE(tmpin);
101  break;
102  case THERMAL_RESISTOR:
103  reg |= ITE_EC_ADC_TEMP_RESISTOR_MODE(tmpin);
104  break;
105  default:
106  printk(BIOS_WARNING, "Unsupported thermal mode 0x%x on TMPIN%d\n",
107  conf->mode, tmpin);
108  return;
109  }
110 
112 
113  /* Set temperature offsets */
114  if (conf->mode != THERMAL_RESISTOR) {
119  }
120 
121  /* Set temperature limits */
122  u8 max = conf->max;
123  pnp_write_hwm5_index(base, ITE_EC_HIGH_TEMP_LIMIT(tmpin), max ? max : 127);
125 
126  /* Enable the startup of monitoring operation */
130 }
131 
132 static void fan_smartconfig(const u16 base, const u8 fan,
133  const enum ite_ec_fan_mode mode,
134  const struct ite_ec_fan_smartconfig *const conf)
135 {
136  u8 pwm_ctrl;
137  u8 pwm_start = 0;
138  u8 pwm_auto = 0;
139  u8 delta_temp;
140 
141  if (mode == FAN_SMART_SOFTWARE) {
143 
144  /* 50% duty cycle by default */
145  const u8 duty = conf->pwm_start ? conf->pwm_start : 50;
146  if (CONFIG(SUPERIO_ITE_ENV_CTRL_8BIT_PWM))
147  pwm_start = ITE_EC_FAN_CTL_PWM_DUTY(duty);
148  else
149  pwm_ctrl |= ITE_EC_FAN_CTL_PWM_DUTY(duty);
150  } else {
152  pwm_ctrl |= ITE_EC_FAN_CTL_TEMPIN(conf->tmpin);
153 
154  if (conf->clsd_loop) {
155  pwm_ctrl |= ITE_EC_FAN_PWM_CLSD_LOOP;
156  pwm_start = ITE_EC_FAN_CTL_PWM_START_RPM(conf->rpm_start);
157  pwm_auto = ITE_EC_FAN_CTL_PWM_SLOPE_LOWER(conf->slope);
158  } else {
159  pwm_start = ITE_EC_FAN_CTL_PWM_START_DUTY(conf->pwm_start);
160 
161  if (CONFIG(SUPERIO_ITE_ENV_CTRL_7BIT_SLOPE_REG)) {
162  pwm_auto = conf->slope & 0x7f;
163  } else {
164  pwm_start |= ITE_EC_FAN_CTL_PWM_SLOPE_BIT6(conf->slope);
165  pwm_auto = ITE_EC_FAN_CTL_PWM_SLOPE_LOWER(conf->slope);
166  }
167  }
168 
169  if (conf->smoothing)
171 
174  conf->tmp_start);
175  /* Full speed above 127°C by default */
177  conf->tmp_full ? conf->tmp_full : 127);
178 
179  delta_temp = ITE_EC_FAN_CTL_DELTA_TEMP_INTRVL(conf->tmp_delta);
180  delta_temp |= ITE_EC_FAN_CTL_FULL_AT_THRML_LMT(conf->full_lmt);
182  delta_temp);
183  }
184 
188 }
189 
190 static void enable_fan(const u16 base, const u8 fan,
191  const struct ite_ec_fan_config *const conf)
192 {
193  u8 reg;
194 
195  if (conf->mode == FAN_IGNORE ||
196  (CONFIG(SUPERIO_ITE_ENV_CTRL_NO_ONOFF) &&
197  conf->mode <= FAN_MODE_OFF))
198  return;
199 
200  /* FAN_CTL2 might have its own frequency setting */
201  if (CONFIG(SUPERIO_ITE_ENV_CTRL_PWM_FREQ2) && fan == 2) {
206  }
207 
208  if (conf->mode >= FAN_SMART_SOFTWARE) {
209  fan_smartconfig(base, fan, conf->mode, &conf->smart);
210  } else {
212  if (conf->mode == FAN_MODE_ON)
213  reg |= ITE_EC_FAN_CTL_ON(fan);
214  else
215  reg &= ~ITE_EC_FAN_CTL_ON(fan);
217  }
218 
219  if (CONFIG(SUPERIO_ITE_ENV_CTRL_FAN16_CONFIG) && conf->mode >= FAN_MODE_ON) {
221  reg |= ITE_EC_FAN_TAC_16BIT_ENABLE(fan);
223  }
224 
225  if (CONFIG(SUPERIO_ITE_ENV_CTRL_5FANS) && fan > 3) {
227  if (conf->mode >= FAN_MODE_ON)
228  reg |= ITE_EC_FAN_SEC_CTL_TAC_EN(fan);
229  else
230  reg &= ~ITE_EC_FAN_SEC_CTL_TAC_EN(fan);
232  } else {
234  if (conf->mode >= FAN_MODE_ON)
235  reg |= ITE_EC_FAN_MAIN_CTL_TAC_EN(fan);
236  else
237  reg &= ~ITE_EC_FAN_MAIN_CTL_TAC_EN(fan);
238 
239  /* Some ITEs have SmartGuardian always enabled */
240  if (!CONFIG(SUPERIO_ITE_ENV_CTRL_NO_ONOFF)) {
241  if (conf->mode >= FAN_SMART_SOFTWARE)
242  reg |= ITE_EC_FAN_MAIN_CTL_SMART(fan);
243  else
244  reg &= ~ITE_EC_FAN_MAIN_CTL_SMART(fan);
245  }
247  }
248 }
249 
250 static void enable_beeps(const u16 base, const struct ite_ec_config *const conf)
251 {
252  u8 reg = 0;
254 
255  if (conf->tmpin_beep) {
258  }
259  if (conf->fan_beep) {
262  }
263  if (conf->vin_beep) {
266  }
267 
268  if (reg) {
271  }
272 }
273 
274 void ite_ec_init(const u16 base, const struct ite_ec_config *const conf)
275 {
276  size_t i;
277 
278  /* Configure 23.43kHz PWM active high output */
280  fan_ctl &= ~ITE_EC_FAN_PWM_CLOCK_MASK;
281  fan_ctl |= ITE_EC_FAN_PWM_DEFAULT_CLOCK;
282  fan_ctl |= ITE_EC_FAN_CTL_POLARITY_HIGH;
284 
285  /* Enable HWM if configured */
286  for (i = 0; i < ITE_EC_TMPIN_CNT; ++i)
287  enable_tmpin(base, i + 1, &conf->tmpin[i]);
288 
289  /* Enable External Sensor SMBus Host if configured */
290  if (conf->smbus_en) {
294  }
295 
296  /* Set SST/PECI Host Controller Clock to either 24 MHz or internal 32 MHz */
297  if (conf->smbus_24mhz) {
301  }
302 
303  /* Enable reading of voltage pins */
305 
306  /* Enable FANx if configured */
307  for (i = 0; i < ITE_EC_FAN_CNT; ++i)
308  enable_fan(base, i + 1, &conf->fan[i]);
309 
310  /* Enable beeps if configured */
311  enable_beeps(base, conf);
312 
313  /*
314  * System may get wrong temperature data when SIO is in
315  * busy state. Therefore, check the status and terminate
316  * processes if needed.
317  */
318  for (i = 0; i < ITE_EC_TMPIN_CNT; ++i)
319  if (conf->tmpin[i].mode == THERMAL_PECI)
321 }
#define printk(level,...)
Definition: stdlib.h:16
void mdelay(unsigned int msecs)
Definition: delay.c:2
@ FAN_IGNORE
Definition: chip.h:33
@ CONFIG
Definition: dsi_common.h:201
static void fan_smartconfig(const u16 base, const u8 fan, const enum ite_ec_fan_mode mode, const struct ite_ec_fan_smartconfig *const conf)
Definition: env_ctrl.c:132
static void extemp_force_idle_status(const u16 base)
Definition: env_ctrl.c:11
static void enable_fan(const u16 base, const u8 fan, const struct ite_ec_fan_config *const conf)
Definition: env_ctrl.c:190
static void enable_peci(const u16 base)
Definition: env_ctrl.c:41
static void enable_tmpin(const u16 base, const u8 tmpin, const struct ite_ec_thermal_config *const conf)
Definition: env_ctrl.c:60
static void enable_beeps(const u16 base, const struct ite_ec_config *const conf)
Definition: env_ctrl.c:250
void ite_ec_init(const u16 base, const struct ite_ec_config *const conf)
Definition: env_ctrl.c:274
#define ITE_EC_FAN_CTL_PWM_MODE_AUTOMATIC
Definition: env_ctrl.h:105
#define ITE_EC_FAN_CTL_MODE
Definition: env_ctrl.h:75
#define ITE_EC_BEEP_ENABLE
Definition: env_ctrl.h:137
#define ITE_EC_FAN_CTL_POLARITY_HIGH
Definition: env_ctrl.h:76
#define PECI_GETTEMP_READ_LENGTH
Definition: env_ctrl.h:225
#define ITE_EC_FAN_MAIN_CTL
Definition: env_ctrl.h:71
#define ITE_EC_EXTEMP_CTRL_AUTO_4HZ
Definition: env_ctrl.h:213
#define ITE_EC_EXTEMP_READ_LENGTH
Definition: env_ctrl.h:206
#define ITE_EC_BEEP_ON_VIN_LIMIT
Definition: env_ctrl.h:148
#define ITE_EC_FAN_CTL_PWM_AUTO(x)
Definition: env_ctrl.h:176
#define ITE_EC_BEEP_FREQ_DIV_OF_TMPIN
Definition: env_ctrl.h:152
#define ITE_EC_ADC_TEMP_EXTRA_TMPIN3_EXT
Definition: env_ctrl.h:132
#define ITE_EC_TEMP_ADJUST_WRITE_ENABLE
Definition: env_ctrl.h:138
#define ITE_EC_FAN_SEC_CTL
Definition: env_ctrl.h:49
#define ITE_EC_FAN_CTL_PWM_START_RPM(p)
Definition: env_ctrl.h:190
#define ITE_EC_EXTEMP_STATUS_HOST_BUSY
Definition: env_ctrl.h:203
#define ITE_EC_INTERFACE_SPEED_TOLERANCE
Definition: env_ctrl.h:28
#define ITE_EC_BEEP_ON_TMP_LIMIT
Definition: env_ctrl.h:147
#define ITE_EC_FAN_CTL_DELTA_TEMP(x)
Definition: env_ctrl.h:181
#define ITE_EC_BEEP_ON_FAN_LIMIT
Definition: env_ctrl.h:149
#define ITE_EC_FAN_CTL_ON(x)
Definition: env_ctrl.h:87
#define ITE_EC_FAN_CTL_PWM_DUTY(p)
Definition: env_ctrl.h:107
#define ITE_EC_FAN_PWM_DEFAULT_CLOCK
Definition: env_ctrl.h:13
#define ITE_EC_EXTEMP_COMMAND
Definition: env_ctrl.h:207
#define ITE_EC_INTERFACE_SMB_ENABLE
Definition: env_ctrl.h:21
#define PECI_GETTEMP_WRITE_LENGTH
Definition: env_ctrl.h:224
#define ITE_EC_FAN_TAC_COUNTER_ENABLE
Definition: env_ctrl.h:46
#define ITE_EC_ADC_TEMP_DIODE_MODE(x)
Definition: env_ctrl.h:130
#define ITE_EC_BEEP_FREQ_DIV_OF_FAN
Definition: env_ctrl.h:150
#define ITE_EC_ADC_TEMP_EXT_REPORTS_TO(x)
Definition: env_ctrl.h:128
#define ITE_EC_FAN_CTL_TEMP_LIMIT_START(x)
Definition: env_ctrl.h:161
#define ITE_EC_BEEP_FREQ_DIV_OF_VIN
Definition: env_ctrl.h:151
#define ITE_EC_ADC_TEMP_RESISTOR_MODE(x)
Definition: env_ctrl.h:129
#define PECI_GETTEMP_COMMAND
Definition: env_ctrl.h:223
#define ITE_EC_FAN_PWM_CLOCK_MASK
Definition: env_ctrl.h:77
#define ITE_EC_ADC_VOLTAGE_CHANNEL_ENABLE
Definition: env_ctrl.h:125
#define ITE_EC_FAN_CTL_DELTA_TEMP_INTRVL(c)
Definition: env_ctrl.h:197
#define ITE_EC_FAN_SEC_CTL_TAC_EN(x)
Definition: env_ctrl.h:50
#define ITE_EC_FAN_CTL_TEMPIN(x)
Definition: env_ctrl.h:101
#define ITE_EC_CONFIGURATION
Definition: env_ctrl.h:16
#define ITE_EC_FAN_MAIN_CTL_SMART(x)
Definition: env_ctrl.h:74
#define ITE_EC_LOW_TEMP_LIMIT(x)
Definition: env_ctrl.h:123
#define ITE_EC_FAN_PWM_CLSD_LOOP
Definition: env_ctrl.h:94
#define ITE_EC_EXTEMP_ADDRESS
Definition: env_ctrl.h:204
#define ITE_EC_FAN_CTL_PWM_SLOPE_LOWER(s)
Definition: env_ctrl.h:194
#define ITE_EC_BEEP_TONE_DIVISOR(x)
Definition: env_ctrl.h:153
#define PECI_CLIENT_ADDRESS
Definition: env_ctrl.h:222
static const u8 ITE_EC_TEMP_ADJUST[]
Definition: env_ctrl.h:135
#define ITE_EC_FAN_CTL_PWM_SLOPE_BIT6(s)
Definition: env_ctrl.h:188
#define ITE_EC_FAN_CTL_PWM_MODE_SOFTWARE
Definition: env_ctrl.h:104
#define ITE_EC_INTERFACE_SELECT
Definition: env_ctrl.h:19
#define ITE_EC_INTERFACE_CLOCK_24MHZ
Definition: env_ctrl.h:27
#define ITE_EC_FAN_MAIN_CTL_TAC_EN(x)
Definition: env_ctrl.h:72
#define ITE_EC_FAN_CTL_PWM_START_DUTY(p)
Definition: env_ctrl.h:189
#define ITE_EC_ADC_TEMP_CHANNEL_ENABLE
Definition: env_ctrl.h:126
#define ITE_EC_HIGH_TEMP_LIMIT(x)
Definition: env_ctrl.h:122
#define ITE_EC_FAN_CTL_AUTO_SMOOTHING_EN
Definition: env_ctrl.h:193
#define ITE_EC_FAN_TAC_16BIT_ENABLE(x)
Definition: env_ctrl.h:47
#define ITE_EC_FAN_CTL_PWM_START(x)
Definition: env_ctrl.h:171
#define ITE_EC_EXTEMP_WRITE_LENGTH
Definition: env_ctrl.h:205
#define ITE_EC_FAN_CTL_PWM_CONTROL(x)
Definition: env_ctrl.h:89
#define ITE_EC_EXTEMP_CTRL_AUTO_START
Definition: env_ctrl.h:214
#define ITE_EC_INTERFACE_SEL_PECI
Definition: env_ctrl.h:24
#define ITE_EC_CONFIGURATION_START
Definition: env_ctrl.h:17
#define ITE_EC_FAN_CTL_TEMP_LIMIT_FULL(x)
Definition: env_ctrl.h:166
#define ITE_EC_ADC_TEMP_EXT_REPORTS_TO_MASK
Definition: env_ctrl.h:127
#define ITE_EC_FAN_CTL_TEMP_LIMIT_OFF(x)
Definition: env_ctrl.h:156
#define ITE_EC_ADC_TEMP_EXTRA_CHANNEL_ENABLE
Definition: env_ctrl.h:131
#define ITE_EC_BEEP_FREQ_DIVISOR(x)
Definition: env_ctrl.h:154
#define ITE_EC_EXTEMP_CONTROL
Definition: env_ctrl.h:209
#define ITE_EC_EXTEMP_STATUS
Definition: env_ctrl.h:202
#define ITE_EC_FAN_CTL_FULL_AT_THRML_LMT(x)
Definition: env_ctrl.h:198
ite_ec_fan_mode
Definition: env_ctrl_chip.h:44
@ FAN_SMART_SOFTWARE
Definition: env_ctrl_chip.h:48
@ FAN_MODE_ON
Definition: env_ctrl_chip.h:46
@ FAN_MODE_OFF
Definition: env_ctrl_chip.h:47
#define ITE_EC_FAN_CNT
Definition: env_ctrl_chip.h:11
#define ITE_EC_TMPIN_CNT
Definition: env_ctrl_chip.h:6
@ THERMAL_RESISTOR
Definition: env_ctrl_chip.h:18
@ THERMAL_PECI
Definition: env_ctrl_chip.h:19
@ THERMAL_DIODE
Definition: env_ctrl_chip.h:17
static u8 pnp_read_hwm5_index(u16 base, u8 reg)
Definition: hwm5_conf.h:26
static void pnp_write_hwm5_index(u16 base, u8 reg, u8 value)
Definition: hwm5_conf.h:43
#define BIOS_WARNING
BIOS_WARNING - Bad configuration.
Definition: loglevel.h:86
uintptr_t base
Definition: uart.c:17
uint16_t u16
Definition: stdint.h:48
uint8_t u8
Definition: stdint.h:45
Definition: dw_i2c.c:39
struct ite_ec_thermal_config tmpin[ITE_EC_TMPIN_CNT]
Definition: env_ctrl_chip.h:81
enum ite_ec_voltage_pin vin_mask
Definition: env_ctrl_chip.h:76
struct ite_ec_fan_config fan[ITE_EC_FAN_CNT]
Definition: env_ctrl_chip.h:86
struct ite_ec_fan_smartconfig smart
Definition: env_ctrl_chip.h:69
enum ite_ec_fan_mode mode
Definition: env_ctrl_chip.h:68
enum ite_ec_thermal_mode mode
Definition: env_ctrl_chip.h:23