[coreboot-gerrit] New patch to review for coreboot: sio/ite/common: Add generic environment-controller driver

Nico Huber (nico.h@gmx.de) gerrit at coreboot.org
Tue Nov 8 12:53:24 CET 2016


Nico Huber (nico.h at gmx.de) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17284

-gerrit

commit 1ed5f126e20409fecdbfaa34d2378fd542a0d59d
Author: Nico Huber <nico.huber at secunet.com>
Date:   Thu Sep 29 12:33:01 2016 +0200

    sio/ite/common: Add generic environment-controller driver
    
    The environment-controller entity is shared by many ITE super-i/o chips.
    There are some differences between the chips, though. To cover that, the
    super-i/o chip should select Kconfig options of this driver accordingly.
    
    The current implementation isn't exhaustive: It covers only those parts
    that are connected on boards I could test, plus those that are currently
    used by the IT8772F. The latter could be ported to use this driver if
    somebody minds to test it.
    
    Change-Id: I7a40f677f667d103ce1d09a3e468915729067803
    Signed-off-by: Nico Huber <nico.huber at secunet.com>
---
 src/superio/ite/Makefile.inc           |   3 +
 src/superio/ite/common/Kconfig         |  18 +++
 src/superio/ite/common/env_ctrl.c      | 250 +++++++++++++++++++++++++++++++++
 src/superio/ite/common/env_ctrl.h      | 135 ++++++++++++++++++
 src/superio/ite/common/env_ctrl_chip.h | 100 +++++++++++++
 5 files changed, 506 insertions(+)

diff --git a/src/superio/ite/Makefile.inc b/src/superio/ite/Makefile.inc
index eb073d4..487beb1 100644
--- a/src/superio/ite/Makefile.inc
+++ b/src/superio/ite/Makefile.inc
@@ -16,6 +16,9 @@
 ## include generic ite pre-ram stage driver
 romstage-$(CONFIG_SUPERIO_ITE_COMMON_ROMSTAGE) += common/early_serial.c
 
+## include generic ite environment controller driver
+ramstage-$(CONFIG_SUPERIO_ITE_ENV_CTRL) += common/env_ctrl.c
+
 subdirs-y += it8671f
 subdirs-y += it8712f
 subdirs-y += it8716f
diff --git a/src/superio/ite/common/Kconfig b/src/superio/ite/common/Kconfig
index 165944b..fe4b58f 100644
--- a/src/superio/ite/common/Kconfig
+++ b/src/superio/ite/common/Kconfig
@@ -3,6 +3,7 @@
 ##
 ## Copyright (C) 2009 Ronald G. Minnich
 ## Copyright (C) 2014 Edward O'Callaghan <eocallaghan at alterapraxis.com>
+## Copyright (C) 2016 secunet Security Networks AG
 ##
 ## 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
@@ -18,3 +19,20 @@
 # romstage.
 config SUPERIO_ITE_COMMON_ROMSTAGE
 	bool
+
+# Generic ITE environment controller driver
+config SUPERIO_ITE_ENV_CTRL
+	bool
+
+if SUPERIO_ITE_ENV_CTRL
+
+config SUPERIO_ITE_ENV_CTRL_FAN16_CONFIG
+	bool
+
+config SUPERIO_ITE_ENV_CTRL_8BIT_PWM
+	bool
+
+config SUPERIO_ITE_ENV_CTRL_PWM_FREQ2
+	bool
+
+endif
diff --git a/src/superio/ite/common/env_ctrl.c b/src/superio/ite/common/env_ctrl.c
new file mode 100644
index 0000000..4ce6ccc
--- /dev/null
+++ b/src/superio/ite/common/env_ctrl.c
@@ -0,0 +1,250 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ * Copyright (C) 2016 secunet Security Networks AG
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <arch/io.h>
+#include <console/console.h>
+#include <delay.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;
+	int retries = 10;
+
+	/* Wait up to 10ms for non-busy state. */
+	while (retries > 0) {
+		reg = ite_ec_read(base, ITE_EC_EXTEMP_STATUS);
+
+		if ((reg & ITE_EC_EXTEMP_STATUS_HOST_BUSY) == 0x0)
+			break;
+
+		retries--;
+
+		mdelay(1);
+	}
+
+	if (retries == 0 && (reg & ITE_EC_EXTEMP_STATUS_HOST_BUSY) == 0x1) {
+		/*
+		 * 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);
+	}
+}
+
+/*
+ * Setup External Temperature to read via PECI into TMPINx register
+ */
+static void enable_peci(const u16 base, const u8 tmpin)
+{
+	if (tmpin == 0 || tmpin > ITE_EC_TMPIN_CNT)
+		return;
+
+	/* Enable PECI interface */
+	ite_ec_write(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);
+
+	/* External Temperature reported in TMPINx register */
+	ite_ec_write(base, ITE_EC_ADC_TEMP_CHANNEL_ENABLE,
+			   (tmpin & 3) << 6);
+}
+
+/*
+ * Set up External Temperature to read via thermal diode/resistor
+ * into TMPINx register
+ */
+static void enable_tmpin(const u16 base, const int tmpin,
+			 const enum ite_ec_thermal_mode mode)
+{
+	u8 reg;
+
+	reg = ite_ec_read(base, ITE_EC_ADC_TEMP_CHANNEL_ENABLE);
+
+	switch (mode) {
+	case THERMAL_DIODE:
+		reg |= ITE_EC_ADC_TEMP_DIODE_MODE(tmpin);
+		break;
+	case THERMAL_RESISTOR:
+		reg |= ITE_EC_ADC_TEMP_RESISTOR_MODE(tmpin);
+		break;
+	default:
+		printk(BIOS_WARNING,
+		       "Unsupported thermal mode 0x%x on TMPIN%d\n",
+		       mode, tmpin);
+		return;
+	}
+
+	ite_ec_write(base, ITE_EC_ADC_TEMP_CHANNEL_ENABLE, reg);
+
+	/* Enable the startup of monitoring operation */
+	reg = ite_ec_read(base, ITE_EC_CONFIGURATION);
+	reg |= ITE_EC_CONFIGURATION_START;
+	ite_ec_write(base, ITE_EC_CONFIGURATION, reg);
+}
+
+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)
+{
+	u8 pwm_ctrl;
+	u8 pwm_start = 0;
+	u8 pwm_auto = 0;
+
+	if (mode == FAN_SMART_SOFTWARE) {
+		pwm_ctrl = ITE_EC_FAN_CTL_PWM_MODE_SOFTWARE;
+
+		/* 50% duty cycle by default */
+		const u8 duty = conf->pwm_start ? conf->pwm_start : 50;
+		if (IS_ENABLED(CONFIG_SUPERIO_ITE_ENV_CTRL_8BIT_PWM))
+			pwm_start = ITE_EC_FAN_CTL_PWM_DUTY(duty);
+		else
+			pwm_ctrl |= ITE_EC_FAN_CTL_PWM_DUTY(duty);
+	} else {
+		pwm_ctrl = ITE_EC_FAN_CTL_PWM_MODE_AUTOMATIC;
+		pwm_ctrl |= ITE_EC_FAN_CTL_TEMPIN(conf->tmpin);
+
+		pwm_start = ITE_EC_FAN_CTL_PWM_START_DUTY(conf->pwm_start);
+		pwm_start |= ITE_EC_FAN_CTL_PWM_SLOPE_BIT6(conf->slope);
+
+		pwm_auto = ITE_EC_FAN_CTL_PWM_SLOPE_LOWER(conf->slope);
+
+		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);
+		/* 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));
+	}
+
+	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);
+}
+
+static void enable_fan(const u16 base, const u8 fan,
+		       const struct ite_ec_fan_config *const conf)
+{
+	u8 reg;
+
+	if (conf->mode == FAN_IGNORE)
+		return;
+
+	/* FAN_CTL2 might have its own frequency setting */
+	if (IS_ENABLED(CONFIG_SUPERIO_ITE_ENV_CTRL_PWM_FREQ2) && fan == 2) {
+		reg = ite_ec_read(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);
+	}
+
+	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);
+		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);
+	}
+
+	if (IS_ENABLED(SUPERIO_ITE_ENV_CTRL_FAN16_CONFIG)
+	    && conf->mode >= FAN_MODE_ON) {
+		reg = ite_ec_read(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);
+	}
+
+	reg = ite_ec_read(base, ITE_EC_FAN_MAIN_CTL);
+	if (conf->mode >= FAN_MODE_ON)
+		reg |= ITE_EC_FAN_MAIN_CTL_TAC_EN(fan);
+	else
+		reg &= ~ITE_EC_FAN_MAIN_CTL_TAC_EN(fan);
+	if (conf->mode >= FAN_SMART_SOFTWARE)
+		reg |= ITE_EC_FAN_MAIN_CTL_SMART(fan);
+	else
+		reg &= ~ITE_EC_FAN_MAIN_CTL_SMART(fan);
+	ite_ec_write(base, ITE_EC_FAN_MAIN_CTL, reg);
+}
+
+void ite_ec_init(const u16 base, const struct ite_ec_config *const conf)
+{
+	size_t i;
+
+	/* Configure 23.43kHz PWM active high output */
+	u8 fan_ctl = ite_ec_read(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);
+
+	/* Enable PECI if configured */
+	enable_peci(base, conf->peci_tmpin);
+
+	/* Enable HWM if configured */
+	for (i = 0; i < ITE_EC_TMPIN_CNT; ++i)
+		enable_tmpin(base, i + 1, conf->tmpin_mode[i]);
+
+	/* Enable reading of voltage pins */
+	ite_ec_write(base, ITE_EC_ADC_VOLTAGE_CHANNEL_ENABLE, conf->vin_mask);
+
+	/* Enable FANx if configured */
+	for (i = 0; i < ITE_EC_FAN_CNT; ++i)
+		enable_fan(base, i + 1, &conf->fan[i]);
+
+	/*
+	 * System may get wrong temperature data when SIO is in
+	 * busy state. Therefore, check the status and terminate
+	 * processes if needed.
+	 */
+	if (conf->peci_tmpin != 0)
+		extemp_force_idle_status(base);
+}
diff --git a/src/superio/ite/common/env_ctrl.h b/src/superio/ite/common/env_ctrl.h
new file mode 100644
index 0000000..fa13116
--- /dev/null
+++ b/src/superio/ite/common/env_ctrl.h
@@ -0,0 +1,135 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ * Copyright (C) 2016 secunet Security Networks AG
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 SUPERIO_ITE_ENV_CTRL_H
+#define SUPERIO_ITE_ENV_CTRL_H
+
+#include "env_ctrl_chip.h"
+
+#if IS_ENABLED(CONFIG_SUPERIO_ITE_ENV_CTRL_8BIT_PWM)
+#define ITE_EC_FAN_MAX_PWM			0xff
+#define ITE_EC_FAN_PWM_DEFAULT_CLOCK		ITE_EC_FAN_PWM_CLOCK_6MHZ
+#else
+#define ITE_EC_FAN_MAX_PWM			0x7f
+#define ITE_EC_FAN_PWM_DEFAULT_CLOCK		ITE_EC_FAN_PWM_CLOCK_3MHZ
+#endif
+
+#define ITE_EC_CONFIGURATION			0x00
+#define   ITE_EC_CONFIGURATION_START		(1 << 0)
+
+#define ITE_EC_INTERFACE_SELECT			0x0a
+#define   ITE_EC_INTERFACE_PSEUDO_EOC		(1 << 7)
+#define   ITE_EC_INTERFACE_SMB_ENABLE		(1 << 6)
+#define   ITE_EC_INTERFACE_SEL_DISABLE		(0 << 4)
+#define   ITE_EC_INTERFACE_SEL_SST_SLAVE	(1 << 4)
+#define   ITE_EC_INTERFACE_SEL_PECI		(2 << 4)
+#define   ITE_EC_INTERFACE_SEL_SST_HOST		(3 << 4)
+#define   ITE_EC_INTERFACE_CLOCK_32MHZ		(0 << 3)
+#define   ITE_EC_INTERFACE_CLOCK_24MHZ		(1 << 3)
+#define   ITE_EC_INTERFACE_SPEED_TOLERANCE	(1 << 2)
+#define   ITE_EC_INTERFACE_PECI_AWFCS		(1 << 0)
+
+#define ITE_EC_FAN_PWM_SMOOTHING_FREQ		0x0b
+#define   ITE_EC_FAN_PWM_SMOOTHING_MASK		(3 << 6)
+#define   ITE_EC_FAN_PWM_SMOOTHING_1KHZ		(0 << 6)
+#define   ITE_EC_FAN_PWM_SMOOTHING_256HZ	(1 << 6)
+#define   ITE_EC_FAN_PWM_SMOOTHING_64HZ		(2 << 6)
+#define   ITE_EC_FAN_PWM_SMOOTHING_16HZ		(3 << 6)
+
+#define ITE_EC_FAN_TAC_COUNTER_ENABLE		0x0c
+#define   ITE_EC_FAN_TAC_16BIT_ENABLE(x)	(1 << ((x)-1))
+#define ITE_EC_FAN_TAC_LIMIT(x)			(0x10 + ((x)-1))
+#define ITE_EC_FAN_TAC_EXT_LIMIT(x)		(0x1b + ((x)-1))
+
+#define ITE_EC_FAN_MAIN_CTL			0x13
+#define   ITE_EC_FAN_MAIN_CTL_TAC_EN(x)		(1 << ((x)+3))
+#define   ITE_EC_FAN_MAIN_CTL_COLL_FULL_SPEED	(1 << 3)
+#define   ITE_EC_FAN_MAIN_CTL_SMART(x)		(1 << ((x)-1))
+#define ITE_EC_FAN_CTL_MODE			0x14
+#define   ITE_EC_FAN_CTL_POLARITY_HIGH		(1 << 7)
+#define   ITE_EC_FAN_PWM_CLOCK_MASK		(7 << 4)
+#define   ITE_EC_FAN_PWM_CLOCK_48MHZ		(0 << 4)
+#define   ITE_EC_FAN_PWM_CLOCK_24MHZ		(1 << 4)
+#define   ITE_EC_FAN_PWM_CLOCK_12MHZ		(2 << 4)
+#define   ITE_EC_FAN_PWM_CLOCK_8MHZ		(3 << 4)
+#define   ITE_EC_FAN_PWM_CLOCK_6MHZ		(4 << 4)
+#define   ITE_EC_FAN_PWM_CLOCK_3MHZ		(5 << 4)
+#define   ITE_EC_FAN_PWM_CLOCK_1_5MHZ		(6 << 4)
+#define   ITE_EC_FAN_PWM_CLOCK_51KHZ		(7 << 4)
+#define   ITE_EC_FAN_PWM_MIN_DUTY_20		(1 << 3)
+#define   ITE_EC_FAN_CTL_ON(x)			(1 << ((x)-1))
+#define ITE_EC_FAN_CTL_PWM_CONTROL(x)		(0x15 + ((x)-1))
+#define   ITE_EC_FAN_CTL_PWM_MODE_SOFTWARE	(0 << 7)
+#define   ITE_EC_FAN_CTL_PWM_MODE_AUTOMATIC	(1 << 7)
+#define   ITE_EC_FAN_CTL_PWM_DUTY_MASK		(ITE_EC_FAN_MAX_PWM << 0)
+#define   ITE_EC_FAN_CTL_PWM_DUTY(p)		\
+	  ({ 					\
+		const unsigned int _p = p;			\
+		(_p >= 100)					\
+			? ITE_EC_FAN_MAX_PWM			\
+			: (_p * ITE_EC_FAN_MAX_PWM) / 100;	\
+	  })
+#define   ITE_EC_FAN_CTL_TEMPIN_MASK		(3 << 0)
+#define   ITE_EC_FAN_CTL_TEMPIN(x)		(((x)-1) & 3)
+
+#define ITE_EC_ADC_VOLTAGE_CHANNEL_ENABLE	0x50
+#define ITE_EC_ADC_TEMP_CHANNEL_ENABLE		0x51
+#define   ITE_EC_ADC_TEMP_EXT_REPORTS_TO(x)	(((x) & 3) << 6)
+#define   ITE_EC_ADC_TEMP_RESISTOR_MODE(x)	(1 << ((x)+2))
+#define   ITE_EC_ADC_TEMP_DIODE_MODE(x)		(1 << ((x)-1))
+#define ITE_EC_ADC_TEMP_EXTRA_CHANNEL_ENABLE	0x55
+
+#define ITE_EC_FAN_CTL_TEMP_LIMIT_OFF(x)	(0x60 + ((x)-1) * 8)
+#define ITE_EC_FAN_CTL_TEMP_LIMIT_START(x)	(0x61 + ((x)-1) * 8)
+#define ITE_EC_FAN_CTL_TEMP_LIMIT_FULL(x)	(0x62 + ((x)-1) * 8)
+#define ITE_EC_FAN_CTL_PWM_START(x)		(0x63 + ((x)-1) * 8)
+#define   ITE_EC_FAN_CTL_PWM_SLOPE_BIT6(s)	(((s) & 0x40) << 1)
+#define   ITE_EC_FAN_CTL_PWM_START_DUTY(p)	ITE_EC_FAN_CTL_PWM_DUTY(p)
+#define ITE_EC_FAN_CTL_PWM_AUTO(x)		(0x64 + ((x)-1) * 8)
+#define   ITE_EC_FAN_CTL_AUTO_SMOOTHING_EN	(1 << 7)
+#define   ITE_EC_FAN_CTL_PWM_SLOPE_LOWER(s)	((s) & 0x3f)
+#define ITE_EC_FAN_CTL_DELTA_TEMP(x)		(0x65 + ((x)-1) * 8)
+#define   ITE_EC_FAN_CTL_DELTA_TEMP_INTRVL(c)	((c) & 0x1f)
+
+#define ITE_EC_EXTEMP_STATUS			0x88
+#define   ITE_EC_EXTEMP_STATUS_HOST_BUSY	(1 << 0)
+#define ITE_EC_EXTEMP_ADDRESS			0x89
+#define ITE_EC_EXTEMP_WRITE_LENGTH		0x8a
+#define ITE_EC_EXTEMP_READ_LENGTH		0x8b
+#define ITE_EC_EXTEMP_COMMAND			0x8c
+#define ITE_EC_EXTEMP_WRITE_DATA_2		0x8d
+#define ITE_EC_EXTEMP_CONTROL			0x8e
+#define   ITE_EC_EXTEMP_CTRL_AUTO_32HZ		(0 << 6)
+#define   ITE_EC_EXTEMP_CTRL_AUTO_16HZ		(1 << 6)
+#define   ITE_EC_EXTEMP_CTRL_AUTO_8HZ		(2 << 6)
+#define   ITE_EC_EXTEMP_CTRL_AUTO_4HZ		(3 << 6)
+#define   ITE_EC_EXTEMP_CTRL_AUTO_START		(1 << 5)
+#define   ITE_EC_EXTEMP_CTRL_AUTO_ABORT		(1 << 4)
+#define   ITE_EC_EXTEMP_CTRL_AUTO_TWO_DOMAIN	(1 << 3)
+#define   ITE_EC_EXTEMP_CTRL_CONTENTION		(1 << 2)
+#define   ITE_EC_EXTEMP_CTRL_SST_IDLE_HIGH	(1 << 1)
+#define   ITE_EC_EXTEMP_CTRL_START		(1 << 0)
+
+/* Standard PECI GetTemp */
+#define PECI_CLIENT_ADDRESS			0x30
+#define PECI_GETTEMP_COMMAND			0x01
+#define PECI_GETTEMP_WRITE_LENGTH		0x01
+#define PECI_GETTEMP_READ_LENGTH		0x02
+
+void ite_ec_init(u16 base, const struct ite_ec_config *conf);
+
+#endif /* SUPERIO_ITE_ENV_CTRL_H */
diff --git a/src/superio/ite/common/env_ctrl_chip.h b/src/superio/ite/common/env_ctrl_chip.h
new file mode 100644
index 0000000..f01c574
--- /dev/null
+++ b/src/superio/ite/common/env_ctrl_chip.h
@@ -0,0 +1,100 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
+ * Copyright (C) 2016 secunet Security Networks AG
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 SUPERIO_ITE_ENV_CTRL_CHIP_H
+#define SUPERIO_ITE_ENV_CTRL_CHIP_H
+
+#define ITE_EC_TMPIN_CNT	3
+#define ITE_EC_FAN_CNT		3
+
+/* Supported thermal mode on TMPINx */
+enum ite_ec_thermal_mode {
+	THERMAL_MODE_DISABLED = 0,
+	THERMAL_DIODE,
+	THERMAL_RESISTOR,
+};
+
+/* Bit mask for voltage pins VINx */
+enum ite_ec_voltage_pin {
+	VIN0 = 0x01,
+	VIN1 = 0x02,
+	VIN2 = 0x04,
+	VIN3 = 0x08,
+	VIN4 = 0x10,
+	VIN5 = 0x20,
+	VIN6 = 0x40,
+	VIN7 = 0x80,
+	VIN_ALL = 0xff
+};
+
+enum ite_ec_fan_mode {
+	FAN_IGNORE = 0,
+	FAN_MODE_ON,
+	FAN_MODE_OFF,
+	FAN_SMART_SOFTWARE,
+	FAN_SMART_AUTOMATIC,
+};
+
+struct ite_ec_fan_smartconfig {
+	u8 tmpin;	/* select TMPINx (1, 2 or 3)		*/
+	u8 tmp_off;	/* turn fan off below (°C)		*/
+	u8 tmp_start;	/* turn fan on above (°C)		*/
+	u8 tmp_full;	/* 100% duty cycle above (°C)		*/
+	u8 tmp_delta;	/* adapt fan speed when temperature
+			   changed by at least `tmp_delta`°C	*/
+	u8 smoothing;	/* enable smoothing			*/
+	u8 pwm_start;	/* start at this duty cycle (%)		*/
+	u8 slope;	/* increase duty cycle by `slope`%/°C	*/
+};
+
+struct ite_ec_fan_config {
+	enum ite_ec_fan_mode mode;
+	struct ite_ec_fan_smartconfig smart;
+};
+
+struct ite_ec_config {
+	/*
+	 * Enable external temperature sensor to use PECI GetTemp()
+	 * command and store in register TMPIN 1, 2, or 3.
+	 */
+	u8 peci_tmpin;
+
+	/*
+	 * Enable thermal mode on TMPINx.
+	 */
+	enum ite_ec_thermal_mode tmpin_mode[ITE_EC_TMPIN_CNT];
+
+	/*
+	 * Enable reading of voltage pins VINx.
+	 */
+	enum ite_ec_voltage_pin vin_mask;
+
+	/*
+	 * Enable a FAN in given mode.
+	 */
+	struct ite_ec_fan_config fan[ITE_EC_FAN_CNT];
+};
+
+/* Some shorthands for device trees */
+#define TMPIN1	ec.tmpin_mode[0]
+#define TMPIN2	ec.tmpin_mode[1]
+#define TMPIN3	ec.tmpin_mode[2]
+#define FAN1	ec.fan[0]
+#define FAN2	ec.fan[1]
+#define FAN3	ec.fan[2]
+
+#endif /* SUPERIO_ITE_ENV_CTRL_CHIP_H */



More information about the coreboot-gerrit mailing list