Keith Hui has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/82632?usp=email )
Change subject: sio/nuvoton: Implement a common ramstage ACPI LDN helper ......................................................................
sio/nuvoton: Implement a common ramstage ACPI LDN helper
With few exceptions, Nuvoton super I/O chips have the same configuration registers.
This patch provides a helper function for configuring the ACPI logical device on Nuvoton SIOs, covering system power state after power loss and switching PS/2 port roles between keyboard and mouse, both controllable using nvram options.
This patch covers nct5572d, nct6776, nct6779d, nct6791d. Change all to use this common code, and add HAVE_POWER_STATE_AFTER_FAILURE Kconfig to all that don't have it already.
It extends these features to Nuvoton SIOs that currently lack them, with additional improvements:
1. Enable waking up the system from PS/2 keyboard and/or mouse. 2. Establish a known state for "user-defined" power state after power loss: off. This value is not used by coreboot.
Inclusion of these helpers are controlled by existing Kconfigs: HAVE_SHARED_PS2_PORT for PS/2 port roles swap, to be set by mainboards. HAVE_POWER_STATE_AFTER_FAILURE for power state after failure.
The nvram options have to be added individually to mainboards.
TEST=Both features boot tested on asus/p8z77-m which uses sio/nuvoton/nct6779d.
Change-Id: Ibaddcaa2d77c5b06ddfbb6dbaac00df5e72dd4bd Signed-off-by: Keith Hui buurin@gmail.com --- M src/superio/nuvoton/Makefile.mk A src/superio/nuvoton/common/common.c A src/superio/nuvoton/common/common.h M src/superio/nuvoton/nct5572d/superio.c M src/superio/nuvoton/nct6776/Kconfig M src/superio/nuvoton/nct6776/superio.c M src/superio/nuvoton/nct6779d/Kconfig M src/superio/nuvoton/nct6779d/superio.c M src/superio/nuvoton/nct6791d/Kconfig M src/superio/nuvoton/nct6791d/superio.c 10 files changed, 110 insertions(+), 14 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/32/82632/1
diff --git a/src/superio/nuvoton/Makefile.mk b/src/superio/nuvoton/Makefile.mk index 570102a..b4645e7 100644 --- a/src/superio/nuvoton/Makefile.mk +++ b/src/superio/nuvoton/Makefile.mk @@ -3,6 +3,8 @@ ## include generic nuvoton pre-ram stage driver bootblock-$(CONFIG_SUPERIO_NUVOTON_COMMON_PRE_RAM) += common/early_serial.c romstage-$(CONFIG_SUPERIO_NUVOTON_COMMON_PRE_RAM) += common/early_serial.c +## include generic nuvoton helper +ramstage-y += common/common.c
subdirs-$(CONFIG_SUPERIO_NUVOTON_WPCM450) += wpcm450 subdirs-$(CONFIG_SUPERIO_NUVOTON_NCT5104D) += nct5104d diff --git a/src/superio/nuvoton/common/common.c b/src/superio/nuvoton/common/common.c new file mode 100644 index 0000000..ca1d0b4 --- /dev/null +++ b/src/superio/nuvoton/common/common.c @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * Configuration routines common to Nuvoton NCT67xx SIO chips. + * Also covers 5572. + * + * Do not use for NCT6687D; some registers are in different places. + */ + +#include <stdint.h> +#include <console/console.h> +#include <device/device.h> +#include <device/pnp.h> +#include <option.h> +#include "common.h" + +#define POWER_LOSS_CONTROL_SHIFT 5 +#define POWER_LOSS_CONTROL_MASK (3 << POWER_LOSS_CONTROL_SHIFT) + +/* CR 0xe6 */ +#define ENMDAT_UP (1 << 7) +#define CASEOPEN0_CLEAR (1 << 5) +#define POWER_LOSS_LAST_STATE (1 << 4) /* 1=off */ +#define PWROK_TRIG (1 << 0) /* We keep this low */ +/* CR 0xe0 */ +#define KB_WAKEUP_PSOUT (1 << 6) +#define MS_WAKEUP_PSOUT (1 << 5) +#define KBD_MS_SWAP (1 << 2) +#define MSXKEY (1 << 1) +#define KBXKEY (1 << 0) +/* CR 0xe4 */ +#define EN_3VSBSW (1 << 4) /* Power RAM in S3; required for S3 suspend */ +#define KB_WAKEUP_ANYKEY (1 << 3) /* Keyboard wakeup: any key */ + +void nct677x_configure_acpi_ldn(struct device *dev) +{ + uint8_t byte; + + pnp_enter_conf_mode(dev); + pnp_set_logical_device(dev); + + /* Set power state after power fail */ + /* Important: Make sure the definitions in mainboard/Kconfig around + * MAINBOARD_POWER_FAILURE_STATE and your board's cmos.layout match. + * And if MAINBOARD_POWER_FAILURE_STATE deviates from the chip's + * expectation (ie. 0=off, 1=on, 2=keep), this code must be adapted. + */ + if (CONFIG(HAVE_POWER_STATE_AFTER_FAILURE)) { + unsigned int power_status = get_uint_option("power_on_after_fail", + CONFIG_MAINBOARD_POWER_FAILURE_STATE) & 3; + /* TODO: Show proper message for "keep". */ + printk(BIOS_INFO, "set power %s after power fail\n", + power_status ? "on" : "off"); + byte = (power_status << POWER_LOSS_CONTROL_SHIFT); + } else + byte = 0; + + byte |= (KB_WAKEUP_ANYKEY | EN_3VSBSW); + + pnp_unset_and_set_config(dev, 0xe4, POWER_LOSS_CONTROL_MASK, byte); + + /* Allow PS/2 mouse wake up + * Clear case open pin 0 status. + * Set user-defined power state to "off" just in case. + */ + pnp_unset_and_set_config(dev, 0xe6, PWROK_TRIG, + ENMDAT_UP | CASEOPEN0_CLEAR | POWER_LOSS_LAST_STATE); + + /* Keyboard wakeup: any key (TODO: Check if KB_WAKEUP_PSOUT is needed) + * Mouse wakeup: any button or movement + */ + byte = (KBXKEY | MSXKEY); + + /* Swap keyboard and mouse port roles if requested by nvram option */ + if (CONFIG(HAVE_SHARED_PS2_PORT) && get_uint_option("swap_keyboard_and_mouse", 0)) + byte |= KBD_MS_SWAP; + + pnp_unset_and_set_config(dev, 0xe0, KBD_MS_SWAP, byte); + + pnp_exit_conf_mode(dev); +} diff --git a/src/superio/nuvoton/common/common.h b/src/superio/nuvoton/common/common.h new file mode 100644 index 0000000..648173e --- /dev/null +++ b/src/superio/nuvoton/common/common.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef SUPERIO_NUVOTON_COMMON_H +#define SUPERIO_NUVOTON_COMMON_H + +#include <device/pnp_type.h> + +void nct677x_configure_acpi_ldn(struct device *dev); + +#endif /* SUPERIO_NUVOTON_COMMON_H */ diff --git a/src/superio/nuvoton/nct5572d/superio.c b/src/superio/nuvoton/nct5572d/superio.c index 34fa016..000d1d3 100644 --- a/src/superio/nuvoton/nct5572d/superio.c +++ b/src/superio/nuvoton/nct5572d/superio.c @@ -45,20 +45,7 @@ } break; case NCT5572D_ACPI: - /* Set power state after power fail */ - power_status = get_uint_option("power_on_after_fail", - CONFIG_MAINBOARD_POWER_FAILURE_STATE); - pnp_enter_conf_mode(dev); - pnp_set_logical_device(dev); - byte = pnp_read_config(dev, 0xe4); - byte &= ~0x60; - if (power_status == MAINBOARD_POWER_ON) - byte |= (0x1 << 5); - else if (power_status == MAINBOARD_POWER_KEEP) - byte |= (0x2 << 5); - pnp_write_config(dev, 0xe4, byte); - pnp_exit_conf_mode(dev); - printk(BIOS_INFO, "set power %s after power fail\n", power_status ? "on" : "off"); + nct677x_configure_acpi_ldn(dev); break; } } diff --git a/src/superio/nuvoton/nct6776/Kconfig b/src/superio/nuvoton/nct6776/Kconfig index 9f5e084..7a4478a 100644 --- a/src/superio/nuvoton/nct6776/Kconfig +++ b/src/superio/nuvoton/nct6776/Kconfig @@ -3,3 +3,5 @@ config SUPERIO_NUVOTON_NCT6776 bool select SUPERIO_NUVOTON_COMMON_PRE_RAM + select HAVE_POWER_STATE_AFTER_FAILURE + select HAVE_POWER_STATE_PREVIOUS_AFTER_FAILURE diff --git a/src/superio/nuvoton/nct6776/superio.c b/src/superio/nuvoton/nct6776/superio.c index d98e303..09f5cd5 100644 --- a/src/superio/nuvoton/nct6776/superio.c +++ b/src/superio/nuvoton/nct6776/superio.c @@ -19,6 +19,9 @@ case NCT6776_KBC: pc_keyboard_init(NO_AUX_DEVICE); break; + case NCT6776_ACPI: + nct677x_configure_acpi_ldn(dev); + break; } }
diff --git a/src/superio/nuvoton/nct6779d/Kconfig b/src/superio/nuvoton/nct6779d/Kconfig index ce2af16..f60cf1c 100644 --- a/src/superio/nuvoton/nct6779d/Kconfig +++ b/src/superio/nuvoton/nct6779d/Kconfig @@ -3,3 +3,5 @@ config SUPERIO_NUVOTON_NCT6779D bool select SUPERIO_NUVOTON_COMMON_PRE_RAM + select HAVE_POWER_STATE_AFTER_FAILURE + select HAVE_POWER_STATE_PREVIOUS_AFTER_FAILURE diff --git a/src/superio/nuvoton/nct6779d/superio.c b/src/superio/nuvoton/nct6779d/superio.c index 1360476..41f9203 100644 --- a/src/superio/nuvoton/nct6779d/superio.c +++ b/src/superio/nuvoton/nct6779d/superio.c @@ -4,6 +4,7 @@ #include <device/pnp.h> #include <pc80/keyboard.h> #include <superio/conf_mode.h> +#include <superio/nuvoton/common/common.h>
#include "nct6779d.h"
@@ -17,6 +18,9 @@ case NCT6779D_KBC: pc_keyboard_init(NO_AUX_DEVICE); break; + case NCT6779D_ACPI: + nct677x_configure_acpi_ldn(dev); + break; } }
diff --git a/src/superio/nuvoton/nct6791d/Kconfig b/src/superio/nuvoton/nct6791d/Kconfig index a536491..f7d8a33 100644 --- a/src/superio/nuvoton/nct6791d/Kconfig +++ b/src/superio/nuvoton/nct6791d/Kconfig @@ -3,3 +3,5 @@ config SUPERIO_NUVOTON_NCT6791D bool select SUPERIO_NUVOTON_COMMON_PRE_RAM + select HAVE_POWER_STATE_AFTER_FAILURE + select HAVE_POWER_STATE_PREVIOUS_AFTER_FAILURE diff --git a/src/superio/nuvoton/nct6791d/superio.c b/src/superio/nuvoton/nct6791d/superio.c index 91a3908..cc55d7f 100644 --- a/src/superio/nuvoton/nct6791d/superio.c +++ b/src/superio/nuvoton/nct6791d/superio.c @@ -17,6 +17,9 @@ case NCT6791D_KBC: pc_keyboard_init(NO_AUX_DEVICE); break; + case NCT6791D_ACPI: + nct677x_configure_acpi_ldn(dev); + break; } }