Sean Rhodes has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/62702 )
Change subject: ec/starlabs/merlin: Add support for Nuvoton EC's ......................................................................
ec/starlabs/merlin: Add support for Nuvoton EC's
Signed-off-by: Sean Rhodes sean@starlabs.systems Change-Id: Ib66baf1e88f5d548ce955dffa00c9b88255b2f95 --- M src/ec/starlabs/merlin/Kconfig M src/ec/starlabs/merlin/Makefile.inc A src/ec/starlabs/merlin/nuvoton.c A src/ec/starlabs/merlin/nuvoton.h 4 files changed, 402 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/02/62702/1
diff --git a/src/ec/starlabs/merlin/Kconfig b/src/ec/starlabs/merlin/Kconfig index 93101b7..f413b0b 100644 --- a/src/ec/starlabs/merlin/Kconfig +++ b/src/ec/starlabs/merlin/Kconfig @@ -1,5 +1,11 @@ ## SPDX-License-Identifier: GPL-2.0-only
+config EC_STARLABS_NUVOTON + bool + select EC_ACPI + help + Interface to Nuvoton embedded controller principally in Star Labs notebooks. + config EC_STARLABS_ITE bool select EC_ACPI diff --git a/src/ec/starlabs/merlin/Makefile.inc b/src/ec/starlabs/merlin/Makefile.inc index 3445ef3..6e7b1d2 100644 --- a/src/ec/starlabs/merlin/Makefile.inc +++ b/src/ec/starlabs/merlin/Makefile.inc @@ -26,3 +26,12 @@ endif endif endif + +if ($(CONFIG_EC_STARLABS_NUVOTON),y) + +EC_VARIANT_DIR := $(call strip_quotes, $(CONFIG_EC_VARIANT_DIR)) +CPPFLAGS_common += -I$(src)/ec/starlabs/merlin/variants/$(EC_VARIANT_DIR) + +all-y += nuvoton.c + +endif diff --git a/src/ec/starlabs/merlin/nuvoton.c b/src/ec/starlabs/merlin/nuvoton.c new file mode 100644 index 0000000..ef317a9 --- /dev/null +++ b/src/ec/starlabs/merlin/nuvoton.c @@ -0,0 +1,301 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/console.h> +#include <device/device.h> +#include <device/pnp.h> +#include <ec/acpi/ec.h> +#include <option.h> +#include <pc80/keyboard.h> + +#include "ite.h" +#include "ecdefs.h" + +uint16_t it_get_version(void) +{ + return (ec_read(ECRAM_MAJOR_VERSION) << 8) | ec_read(ECRAM_MINOR_VERSION); +} + +static uint8_t get_ec_value_from_option(const char *name, + unsigned int fallback, + const uint8_t *lut, + size_t lut_size) +{ + unsigned int index = get_uint_option(name, fallback); + if (index >= lut_size) + index = fallback; + return lut[index]; +} + +static uint16_t ite_get_chip_id(unsigned int port) +{ + return (pnp_read_index(port, ITE_CHIPID1) << 8) | + pnp_read_index(port, ITE_CHIPID2); +} + +static void merlin_init(struct device *dev) +{ + if (!dev->enabled) + return; + + /* + * The address/data IO port pair for the ite EC are configurable + * through the EC domain and are fixed by the EC's firmware blob. If + * the value(s) passed through the "dev" structure don't match the + * expected values then output severe warnings. + */ + if (dev->path.pnp.port != ITE_FIXED_ADDR) { + printk(BIOS_ERR, "ITE: Incorrect ports defined in devicetree.cb.\n"); + printk(BIOS_ERR, "ITE: Serious operational issues will arise.\n"); + return; + } + + const uint16_t chip_id = ite_get_chip_id(dev->path.pnp.port); + + if (chip_id != ITE_CHIPID_VAL) { + printk(BIOS_ERR, "ITE: Expected chip ID 0x%04x, but got 0x%04x instead.\n", + ITE_CHIPID_VAL, chip_id); + return; + } + + pc_keyboard_init(NO_AUX_DEVICE); + + /* + * Restore settings from CMOS into EC RAM: + * + * kbl_timeout + * fn_ctrl_swap + * max_charge + * fan_mode + * fn_lock_state + * trackpad_state + * kbl_brightness + * kbl_state + */ + + /* + * Keyboard Backlight Timeout + * + * Setting: kbl_timeout + * + * Values: 30 Seconds, 1 Minute, 3 Minutes, 5 Minutes, Never + * Default: 30 Seconds + * + */ + const uint8_t kbl_timeout[] = { + SEC_30, + MIN_1, + MIN_3, + MIN_5, + NEVER + }; + + ec_write(ECRAM_KBL_TIMEOUT, + get_ec_value_from_option("kbl_timeout", + 0, + kbl_timeout, + ARRAY_SIZE(kbl_timeout))); + + /* + * Fn Ctrl Reverse + * + * Setting: fn_ctrl_swap + * + * Values: Enabled, Disabled + * Default: Disabled + * + */ + const uint8_t fn_ctrl_swap[] = { + FN_CTRL, + CTRL_FN + }; + + ec_write(ECRAM_FN_CTRL_REVERSE, + get_ec_value_from_option("fn_ctrl_swap", + 1, + fn_ctrl_swap, + ARRAY_SIZE(fn_ctrl_swap))); + + /* + * Maximum Charge Level + * + * Setting: max_charge + * + * Values: 60%, 80%, 100% + * Default: 100% + * + */ + const uint8_t max_charge[] = { + CHARGE_100, + CHARGE_80, + CHARGE_60 + }; + + if (CONFIG(EC_STARLABS_MAX_CHARGE)) + ec_write(ECRAM_MAX_CHARGE, + get_ec_value_from_option("max_charge", + 0, + max_charge, + ARRAY_SIZE(max_charge))); + + /* + * Fan Mode + * + * Setting: fan_mode + * + * Values: Quiet, Normal, Aggressive + * Default: Normal + * + */ + const uint8_t fan_mode[] = { + FAN_NORMAL, + FAN_AGGRESSIVE, + FAN_QUIET + }; + + if (CONFIG(EC_STARLABS_FAN)) + ec_write(ECRAM_FAN_MODE, + get_ec_value_from_option("fan_mode", + 0, + fan_mode, + ARRAY_SIZE(fan_mode))); + + /* + * Function Lock + * + * Setting: fn_lock_state + * + * Values: Locked, Unlocked + * Default: Locked + * + */ + const uint8_t fn_lock_state[] = { + UNLOCKED, + LOCKED + }; + + ec_write(ECRAM_FN_LOCK_STATE, + get_ec_value_from_option("fn_lock_state", + 1, + fn_lock_state, + ARRAY_SIZE(fn_lock_state))); + + /* + * Trackpad State + * + * Setting: trackpad_state + * + * Values: Enabled, Disabled + * Default: Enabled + * + */ + const uint8_t trackpad_state[] = { + TRACKPAD_ENABLED, + TRACKPAD_DISABLED + }; + + ec_write(ECRAM_TRACKPAD_STATE, + get_ec_value_from_option("trackpad_state", + 0, + trackpad_state, + ARRAY_SIZE(trackpad_state))); + + /* + * Keyboard Backlight Brightness + * + * Setting: kbl_brightness + * + * Values: Off, Low, High / Off, On + * Default: Low + * + */ + const uint8_t kbl_brightness[] = { + KBL_ON, + KBL_OFF, + KBL_LOW, + KBL_HIGH + }; + + if (CONFIG(EC_STARLABS_KBL_LEVELS)) + ec_write(ECRAM_KBL_BRIGHTNESS, + get_ec_value_from_option("kbl_brightness", + 2, + kbl_brightness, + ARRAY_SIZE(kbl_brightness))); + else + ec_write(ECRAM_KBL_BRIGHTNESS, + get_ec_value_from_option("kbl_brightness", + 0, + kbl_brightness, + ARRAY_SIZE(kbl_brightness))); + + /* + * Keyboard Backlight State + * + * Setting: kbl_state + * + * Values: Off, On + * Default: On + * + */ + const uint8_t kbl_state[] = { + KBL_DISABLED, + KBL_ENABLED + }; + + ec_write(ECRAM_KBL_STATE, + get_ec_value_from_option("kbl_state", + 1, + kbl_state, + ARRAY_SIZE(kbl_state))); +} + +static struct device_operations ops = { + .init = merlin_init, + .read_resources = noop_read_resources, + .set_resources = noop_set_resources, +}; + +static struct pnp_info pnp_dev_info[] = { + /* Serial Port 1 (UART1) */ + { NULL, ITE_SP1, PNP_IO0 | PNP_IRQ0, 0x0ff8, }, + /* Serial Port 2 (UART2) */ + { NULL, ITE_SP2, PNP_IO0 | PNP_IRQ0, 0x0ff8, }, + /* System Wake-Up Control (SWUC) */ + { NULL, ITE_SWUC, PNP_IO0 | PNP_IRQ0, 0xfff0, }, + /* KBC / Mouse Interface */ + { NULL, ITE_SWUC, PNP_IRQ0, }, + /* KBC / Keyboard Interface */ + { NULL, ITE_KBCK, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, }, + /* Consumer IR (CIR) */ + { NULL, ITE_IR, PNP_IO0 | PNP_IRQ0, 0xfff8, }, + /* Shared Memory / Flash Interface (SMFI) */ + { NULL, ITE_SMFI, PNP_IO0 | PNP_IRQ0, 0xfff0, }, + /* RTC-like Timer (RCTC) */ + { NULL, ITE_RTCT, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IO3 | PNP_IRQ0, + 0xfffe, 0xfffe, 0xfffe, 0xfffe, }, + /* Power Management I/F Channel 1 (PMC1) */ + { NULL, ITE_PMC1, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, }, + /* Power Management I/F Channel 2 (PMC2) */ + { NULL, ITE_PMC2, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IRQ0, 0x07fc, + 0x07fc, 0xfff0, }, + /* Serial Peripheral Interface (SSPI) */ + { NULL, ITE_SSPI, PNP_IO0 | PNP_IRQ0, 0xfff8, }, + /* Platform Environment Control Interface (PECI) */ + { NULL, ITE_PECI, PNP_IRQ0, 0xfff8, }, + /* Power Management I/F Channel 3 (PMC3) */ + { NULL, ITE_PMC3, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, }, + /* Power Management I/F Channel 4 (PMC4) */ + { NULL, ITE_PMC4, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, }, + /* Power Management I/F Channel 5 (PMC5) */ + { NULL, ITE_PMC5, PNP_IO0 | PNP_IO1 | PNP_IRQ0, 0x07ff, 0x07ff, }, +}; + +static void enable_dev(struct device *dev) +{ + pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info); +} + +struct chip_operations ec_starlabs_merlin_ops = { + CHIP_NAME("ITE EC") + .enable_dev = enable_dev +}; diff --git a/src/ec/starlabs/merlin/nuvoton.h b/src/ec/starlabs/merlin/nuvoton.h new file mode 100644 index 0000000..8f8bb99 --- /dev/null +++ b/src/ec/starlabs/merlin/nuvoton.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* + * EC communication interface for ITE Embedded Controller. + */ + +#ifndef _EC_STARLABS_ITE_H +#define _EC_STARLABS_ITE_H + +/* + * Define the expected value of the PNP base address that is fixed through + * the BADRSEL register controlled within the EC domain by the EC Firmware. + */ +#define ITE_FIXED_ADDR 0x4e + +/* Logical device number (LDN) assignments. */ +#define ITE_SP1 0x01 /* Serial Port 1 (UART) */ +#define ITE_SP2 0x02 /* Serial Port 2 (UART) */ +#define ITE_SWUC 0x04 /* System Wake-Up Control (SWUC) */ +#define ITE_KBCM 0x05 /* KBC / Mouse Interface */ +#define ITE_KBCK 0x06 /* KBC / Keyboard Interface */ +#define ITE_IR 0x0a /* Consumer IR (CIR) */ +#define ITE_SMFI 0x0f /* Shared Memory / Flash Interface (SMFI) */ +#define ITE_RTCT 0x10 /* RTC-like Timer (RCTC) */ +#define ITE_PMC1 0x11 /* Power Management I/F Channel 1 (PMC1) */ +#define ITE_PMC2 0x12 /* Power Management I/F Channel 2 (PMC2) */ +#define ITE_SSPI 0x13 /* Serial Peripheral Interface (SSPI) */ +#define ITE_PECI 0x14 /* Platform Environment Control Interface (PECI) */ +#define ITE_PMC3 0x17 /* Power Management I/F Channel 3 (PMC3) */ +#define ITE_PMC4 0x18 /* Power Management I/F Channel 4 (PMC4) */ +#define ITE_PMC5 0x19 /* Power Management I/F Channel 5 (PMC5) */ + +/* Host domain registers. */ +#define ITE_CHIPID1 0x20 /* Device ID register 1 */ +#define ITE_CHIPID2 0x21 /* Device ID register 2 */ + +/* EC RAM common offsets */ +#define ECRAM_MAJOR_VERSION 0x00 +#define ECRAM_MINOR_VERSION 0x01 + +/* + * CMOS Settings + */ + +/* Keyboard Backlight Timeout */ +#define SEC_30 0x00 +#define MIN_1 0x01 +#define MIN_3 0x02 +#define MIN_5 0x03 +#define NEVER 0x04 + +/* Fn Ctrl Swap */ +#define FN_CTRL 0x00 +#define CTRL_FN 0x01 + +/* Max Charge Setting */ +#define CHARGE_100 0x00 +#define CHARGE_80 0xbb +#define CHARGE_60 0xaa + +/* Fan Mode Setting */ +#define FAN_NORMAL 0x00 +#define FAN_AGGRESSIVE 0xbb +#define FAN_QUIET 0xaa + +/* Fn Lock State */ +#define UNLOCKED 0x00 +#define LOCKED 0x01 + +/* Trackpad State */ +#define TRACKPAD_ENABLED 0x00 +#define TRACKPAD_DISABLED 0x22 + +/* Keyboard Brightness Levels */ +#define KBL_ON 0xdd +#define KBL_OFF 0xcc +#define KBL_LOW 0xbb +#define KBL_HIGH 0xaa + +/* Keyboard Backlight State */ +#define KBL_DISABLED 0x00 +#define KBL_ENABLED 0xdd + +uint16_t it_get_version(void); + +#endif