diff --git a/configs/config.protectli_vp46xx b/configs/config.protectli_vp46xx index 1d1283633d5..0fca3e7af64 100644 --- a/configs/config.protectli_vp46xx +++ b/configs/config.protectli_vp46xx @@ -1,4 +1,4 @@ -CONFIG_LOCALVERSION="v1.2.1-rc4" +CONFIG_LOCALVERSION="v1.2.1-rc5" CONFIG_OPTION_BACKEND_NONE=y CONFIG_VENDOR_PROTECTLI=y CONFIG_ONBOARD_VGA_IS_PRIMARY=y diff --git a/configs/config.protectli_vp46xx_no_emmc b/configs/config.protectli_vp46xx_no_emmc index e7595f50c64..d3895822ff4 100644 --- a/configs/config.protectli_vp46xx_no_emmc +++ b/configs/config.protectli_vp46xx_no_emmc @@ -1,4 +1,4 @@ -CONFIG_LOCALVERSION="v1.2.1-rc4" +CONFIG_LOCALVERSION="v1.2.1-rc5" CONFIG_OPTION_BACKEND_NONE=y CONFIG_VENDOR_PROTECTLI=y CONFIG_ONBOARD_VGA_IS_PRIMARY=y diff --git a/src/mainboard/protectli/vault_cml/bootblock.c b/src/mainboard/protectli/vault_cml/bootblock.c index 82c46f985f3..02cc3ae4344 100644 --- a/src/mainboard/protectli/vault_cml/bootblock.c +++ b/src/mainboard/protectli/vault_cml/bootblock.c @@ -1,14 +1,24 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include #include #include +#include #include #include "gpio.h" #define UART_DEV PNP_DEV(0x2e, IT8784E_SP1) #define GPIO_DEV PNP_DEV(0x2e, IT8784E_GPIO) +static void ite_set_gpio_iobase(u16 iobase) +{ + pnp_enter_conf_state(GPIO_DEV); + pnp_set_logical_device(GPIO_DEV); + pnp_set_iobase(GPIO_DEV, PNP_IDX_IO1, iobase); + pnp_exit_conf_state(GPIO_DEV); +} + void bootblock_mainboard_early_init(void) { /* CLKIN freq 24MHz, Ext CLKIN for Watchdog, Internal VCC_OK */ @@ -25,6 +35,8 @@ void bootblock_mainboard_early_init(void) ite_delay_pwrgd3(GPIO_DEV); ite_kill_watchdog(GPIO_DEV); ite_enable_serial(UART_DEV, CONFIG_TTYS0_BASE); + ite_gpio_setup(GPIO_DEV, 80, ITE_GPIO_INPUT, ITE_GPIO_SIMPLE_IO_MODE, ITE_GPIO_PULLUP_ENABLE); + ite_set_gpio_iobase(0xa00); } void bootblock_mainboard_init(void) diff --git a/src/mainboard/protectli/vault_cml/devicetree.cb b/src/mainboard/protectli/vault_cml/devicetree.cb index 1e3290ab0b1..48a8aad3b40 100644 --- a/src/mainboard/protectli/vault_cml/devicetree.cb +++ b/src/mainboard/protectli/vault_cml/devicetree.cb @@ -238,7 +238,9 @@ chip soc/intel/cannonlake end device pnp 2e.5 off end # Keyboard device pnp 2e.6 off end # Mouse - device pnp 2e.7 off end # GPIO + device pnp 2e.7 on + io 0x62 = 0xa00 + end # GPIO device pnp 2e.a off end # CIR end chip drivers/pc80/tpm diff --git a/src/superio/ite/Makefile.inc b/src/superio/ite/Makefile.inc index f9dd2640cbf..f9569bf6b3f 100644 --- a/src/superio/ite/Makefile.inc +++ b/src/superio/ite/Makefile.inc @@ -4,9 +4,16 @@ bootblock-$(CONFIG_SUPERIO_ITE_COMMON_PRE_RAM) += common/early_serial.c romstage-$(CONFIG_SUPERIO_ITE_COMMON_PRE_RAM) += common/early_serial.c +bootblock-$(CONFIG_SUPERIO_ITE_COMMON_GPIO_PRE_RAM) += common/gpio.c +romstage-$(CONFIG_SUPERIO_ITE_COMMON_GPIO_PRE_RAM) += common/gpio.c + ## include generic ite environment controller driver ramstage-$(CONFIG_SUPERIO_ITE_ENV_CTRL) += common/env_ctrl.c +## include generic ite driver to smm to control S3-relevant functions +smm-$(CONFIG_SUPERIO_ITE_COMMON_PRE_RAM) += common/early_serial.c +smm-$(CONFIG_SUPERIO_ITE_COMMON_GPIO_PRE_RAM) += common/gpio.c + subdirs-y += it8528e subdirs-y += it8613e subdirs-y += it8623e diff --git a/src/superio/ite/common/Kconfig b/src/superio/ite/common/Kconfig index 36c1496db03..d7c48e4561e 100644 --- a/src/superio/ite/common/Kconfig +++ b/src/superio/ite/common/Kconfig @@ -5,6 +5,33 @@ config SUPERIO_ITE_COMMON_PRE_RAM bool +config SUPERIO_ITE_COMMON_GPIO_PRE_RAM + bool + help + Enable generic pre-ram driver for configuring ITE SIO GPIOs. + It applies only to ITE SIOs not ITE ECs using LDN 7 (typically) + to configure GPIO Simple I/O mode. + +if SUPERIO_ITE_COMMON_GPIO_PRE_RAM + +config SUPERIO_ITE_COMMON_NUM_GPIO_SETS + int + help + The maximum number of GPIO sets supported by ITE SIO chip. + Each SIO chip must set this config option to a proper values + if it intends to enable SUPERIO_ITE_COMMON_GPIO_PRE_RAM. + +config SUPERIO_ITE_COMMON_GPIO_LED_FREQ_5BIT + bool + default n + help + Selected ITE SIOs control the GPIO LED frequency using 5 bits + instead of two. The LED register layout is also different for + these chips. Select this if the SIO GP LED Frequency control + field has 5 bits and support duty cycle as well. + +endif + # Generic ITE environment controller driver config SUPERIO_ITE_ENV_CTRL bool diff --git a/src/superio/ite/common/gpio.c b/src/superio/ite/common/gpio.c new file mode 100644 index 00000000000..11c02ba1c83 --- /dev/null +++ b/src/superio/ite/common/gpio.c @@ -0,0 +1,191 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include + +#include "ite.h" +#include "ite_gpio.h" + +/* Catch ITE SIOs that enable the driver but do not configure the number of sets */ +#if CONFIG_SUPERIO_ITE_COMMON_NUM_GPIO_SETS == 0 +#error "Maximum number of ITE SIO GPIO sets not provided" +#endif + +#if CONFIG_SUPERIO_ITE_COMMON_NUM_GPIO_SETS > 10 +#error "ITE SIO GPIO drivers only support up to 10 GPIO sets" +#endif + +/* GPIO Polarity Select: 1: Inverting, 0: Non-inverting */ +#define ITE_GPIO_REG_POLARITY(x) \ + (((x) > 8) ? (0xd1 + ((x) - 9) * 5) \ + : (0xb0 + ((x) - 1)) \ + ) + +/* GPIO Internal Pull-up: 1: Enable, 0: Disable */ +#define ITE_GPIO_REG_PULLUP(x) \ + (((x) > 8) ? (0xd4 + ((x) - 9) * 5) \ + : (0xb8 + ((x) - 1)) \ + ) + +/* GPIO Function Select: 1: Simple I/O, 0: Alternate function */ +#define ITE_GPIO_REG_FN_SELECT(x) \ + (((x) > 8) ? (0xd3 + ((x) - 9) * 5) \ + : (0xc0 + ((x) - 1)) \ + ) + +/* GPIO Mode: 0: input mode, 1: output mode */ +#define ITE_GPIO_REG_OUTPUT(x) \ + (((x) > 8) ? (0xd2 + ((x) - 9) * 5) \ + : (0xc8 + ((x) - 1)) \ + ) + +/* GPIO LED pin mapping register */ +#define ITE_GPIO_REG_LED_PINMAP(x) (0xf8 + ((x) & 1) * 2) +#define ITE_GPIO_LED_PIN_LOC(set, pin) ((((set) & 7) << 3) | ((pin) & 7)) +#define ITE_GPIO_LED_PIN_LOC_MASK 0x3f +/* GPIO LED control register */ +#define ITE_GPIO_REG_LED_CONTROL(x) (0xf9 + ((x) & 1) * 2) +#define ITE_GPIO_LED_OUTPUT_LOW (1 << 0) +#define ITE_GPIO_LED_PINMAP_CLEAR (1 << 4) +#define ITE_GPIO_LED_SHORT_LOW_PULSE \ + (CONFIG(SUPERIO_ITE_COMMON_GPIO_LED_FREQ_5BIT) ? (1 << 5) \ + : (1 << 3) \ + ) +#define ITE_GPIO_LED_FREQ_SEL(x) \ + (CONFIG(SUPERIO_ITE_COMMON_GPIO_LED_FREQ_5BIT) \ + ? ((((x) & 0x18) << 3) | (((x) & 0x7) << 1)) \ + : (((x) & 0x3) << 1) \ + ) +#define ITE_GPIO_LED_FREQ_SEL_MASK \ + (CONFIG(SUPERIO_ITE_COMMON_GPIO_LED_FREQ_5BIT) ? 0xce : 0x06) + +static bool ite_has_gpio_fn_select_reg(u8 set) +{ + /* IT8718F has all registers for all sets. */ + if (CONFIG(SUPERIO_ITE_IT8718F)) + return true; + + /* Typically ITE GPIO sets 6 to 8 don't have enable and polarity registers. */ + if (set < 6 || set > 8) + return true; + + return false; +} + +static bool ite_has_gpio_polarity_reg(u8 set) +{ + /* IT8718F has all registers for all sets. */ + if (CONFIG(SUPERIO_ITE_IT8718F)) + return true; + + /* IT8720F/IT8721F has polarity register for all GPIO sets */ + if (CONFIG(SUPERIO_ITE_IT8720F) || CONFIG(SUPERIO_ITE_IT8721F)) + return true; + + /* Typically ITE GPIO sets 6 to 8 don't have enable and polarity registers. */ + if (set < 6 || set > 8) + return true; + + return false; +} + +static bool ite_has_gpio_pullup_reg(u8 set) +{ + /* IT8718F/IT8720F does not have pull-up register for set 2 */ + if ((CONFIG(SUPERIO_ITE_IT8718F) || CONFIG(SUPERIO_ITE_IT8720F)) && (set == 2)) + return false; + + /* IT8783E/F does not have pull-up register for set 6 */ + if (CONFIG(SUPERIO_ITE_IT8783EF) && (set == 6)) + return false; + + /* + * ITE GPIO Sets 7 and 8 don't have a pullup register. + * See IT8786/IT8625 datasheet section 8.10.10. + * Also applies to IT8728F. + */ + if (set != 7 && set != 8) + return true; + + return false; +} + +/* + * Configures a single GPIO given its number as gpio_num, direction ("in_out" + * parameter) and properties, such as polarity and pull ("gpio_ctrl" + * parameter). The "enable" parameter can configure the GPIO in Simple I/O + * mode when set or Alternate function mode when clear. Some chips may also + * not support configuring all properties for a particular GPIO. It is left to + * the implementer to check if GPIO settings are valid for given gpio_num. + */ +void ite_gpio_setup(pnp_devfn_t gpiodev, u8 gpio_num, enum ite_gpio_direction in_out, + enum ite_gpio_mode enable, u8 gpio_ctrl) +{ + u8 set = (gpio_num / 10); + u8 pin = (gpio_num % 10); + + /* Number of configurable sets is chip dependent, 8 pins each */ + if (gpio_num < 10 || set > CONFIG_SUPERIO_ITE_COMMON_NUM_GPIO_SETS || pin > 7) + return; + + pnp_enter_conf_state(gpiodev); + pnp_set_logical_device(gpiodev); + + if (ite_has_gpio_fn_select_reg(set)) + pnp_unset_and_set_config(gpiodev, ITE_GPIO_REG_FN_SELECT(set), + 1 << pin, (enable & 1) << pin); + + if (ite_has_gpio_polarity_reg(set)) + pnp_unset_and_set_config(gpiodev, ITE_GPIO_REG_POLARITY(set), + 1 << pin, + (gpio_ctrl & ITE_GPIO_POL_INVERT) ? 1 << pin : 0); + + + pnp_unset_and_set_config(gpiodev, ITE_GPIO_REG_OUTPUT(set), 1 << pin, (in_out & 1) << pin); + + if (ite_has_gpio_pullup_reg(set)) + pnp_unset_and_set_config(gpiodev, ITE_GPIO_REG_PULLUP(set), 1 << pin, + (gpio_ctrl & ITE_GPIO_PULLUP_ENABLE) ? 1 << pin : 0); + + pnp_exit_conf_state(gpiodev); +} + +void ite_gpio_setup_led(pnp_devfn_t gpiodev, u8 gpio_num, + enum ite_gpio_led led_no, + enum ite_led_frequency freq, + u8 led_ctrl) +{ + u8 set = (gpio_num / 10); + u8 pin = (gpio_num % 10); + u8 reg = 0; + + /* Number of configurable sets is chip dependent, 8 pins each */ + if (gpio_num < 10 || set > CONFIG_SUPERIO_ITE_COMMON_NUM_GPIO_SETS || pin > 7) + return; + + /* LED is available only for GPIO sets 1-5 */ + if (set > 5) + return; + + pnp_enter_conf_state(gpiodev); + pnp_set_logical_device(gpiodev); + + /* Pinmap clear bit is only available when frequency is controlled with 5 bits */ + if (CONFIG(SUPERIO_ITE_COMMON_GPIO_LED_FREQ_5BIT) && (led_ctrl & ITE_LED_PINMAP_CLEAR)) + reg |= ITE_GPIO_LED_PINMAP_CLEAR; + + if (led_ctrl & ITE_LED_OUTPUT_LOW) + reg |= ITE_GPIO_LED_OUTPUT_LOW; + + if (led_ctrl & ITE_LED_SHORT_LOW_PULSE) + reg |= ITE_GPIO_LED_SHORT_LOW_PULSE; + + reg |= ITE_GPIO_LED_FREQ_SEL(freq); + pnp_write_config(gpiodev, ITE_GPIO_REG_LED_CONTROL(led_no), reg); + + reg = ITE_GPIO_LED_PIN_LOC(set, pin); + pnp_write_config(gpiodev, ITE_GPIO_REG_LED_PINMAP(led_no), reg); + + pnp_exit_conf_state(gpiodev); +} diff --git a/src/superio/ite/common/ite_gpio.h b/src/superio/ite/common/ite_gpio.h new file mode 100644 index 00000000000..ca1b209953f --- /dev/null +++ b/src/superio/ite/common/ite_gpio.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef SUPERIO_ITE_COMMON_GPIO_PRE_RAM_H +#define SUPERIO_ITE_COMMON_GPIO_PRE_RAM_H + +#include +#include + +#define ITE_GPIO_REG_SELECT(x) (0x25 + (x)) + +enum ite_gpio_control { + ITE_GPIO_CONTROL_DEFAULT = 0, + ITE_GPIO_POL_INVERT = (1 << 0), + ITE_GPIO_PULLUP_ENABLE = (1 << 1), +}; + +enum ite_gpio_direction { + ITE_GPIO_INPUT, + ITE_GPIO_OUTPUT +}; + +enum ite_gpio_mode { + ITE_GPIO_ALT_FN_MODE, + ITE_GPIO_SIMPLE_IO_MODE +}; + +/* There are two GP LED blink register sets */ +enum ite_gpio_led { + ITE_GPIO_LED_1, + ITE_GPIO_LED_2 +}; + +enum ite_led_control { + ITE_LED_CONTROL_DEFAULT = 0, + ITE_LED_SHORT_LOW_PULSE = (1 << 0), + ITE_LED_OUTPUT_LOW = (1 << 1), + /* + * Only for ITE SIOs with 5-bit frequency selection. + * When enabled, the LED pin mapping register is cleared when PANSWH# is low for over 4s. + */ + ITE_LED_PINMAP_CLEAR = (1 << 2), +}; + +enum ite_led_frequency { + /* Most ITE SIOs have 2-bit frequency selection */ + ITE_LED_FREQ_4HZ = 0, + ITE_LED_FREQ_1HZ = 1, + ITE_LED_FREQ_0P25HZ = 2, + ITE_LED_FREQ_0P125HZ = 3, + /* ITE SIOs with 5-bit frequency selection: IT8625, IT8613 */ + ITE_LED_FREQ_4HZ_DUTY_50 = 0, + ITE_LED_FREQ_1HZ_DUTY_50 = 1, + ITE_LED_FREQ_0P25HZ_DUTY_50 = 2, + ITE_LED_FREQ_2HZ_DUTY_50 = 3, + ITE_LED_FREQ_0P25HZ_DUTY_25 = 4, + ITE_LED_FREQ_0P25HZ_DUTY_75 = 5, + ITE_LED_FREQ_0P125HZ_DUTY_25 = 6, + ITE_LED_FREQ_0P125HZ_DUTY_75 = 7, + ITE_LED_FREQ_0P4HZ_DUTY_20 = 8, + ITE_LED_FREQ_0P5HZ_DUTY_50 = 16, + ITE_LED_FREQ_0P125HZ_DUTY_50 = 24, +}; + +void ite_gpio_setup(pnp_devfn_t gpiodev, u8 gpio_num, + enum ite_gpio_direction output, + enum ite_gpio_mode enable, + u8 gpio_ctrl); + +void ite_gpio_setup_led(pnp_devfn_t gpiodev, u8 gpio_num, + enum ite_gpio_led led_no, + enum ite_led_frequency freq, + u8 led_ctrl); + + +#endif /* SUPERIO_ITE_COMMON_PRE_RAM_H */ diff --git a/src/superio/ite/it8784e/Kconfig b/src/superio/ite/it8784e/Kconfig index 66dd6c93621..ba19459cf5a 100644 --- a/src/superio/ite/it8784e/Kconfig +++ b/src/superio/ite/it8784e/Kconfig @@ -3,8 +3,16 @@ config SUPERIO_ITE_IT8784E bool select SUPERIO_ITE_COMMON_PRE_RAM + select SUPERIO_ITE_COMMON_GPIO_PRE_RAM select SUPERIO_ITE_ENV_CTRL select SUPERIO_ITE_ENV_CTRL_PWM_FREQ2 select SUPERIO_ITE_ENV_CTRL_8BIT_PWM select SUPERIO_ITE_ENV_CTRL_7BIT_SLOPE_REG select SUPERIO_ITE_ENV_CTRL_EXT_ANY_TMPIN + +if SUPERIO_ITE_IT8784E + +config SUPERIO_ITE_COMMON_NUM_GPIO_SETS + default 10 + +endif