diff options
author | Sean Rhodes <sean@starlabs.systems> | 2023-02-16 15:00:14 +0000 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2023-04-04 14:10:44 +0000 |
commit | 0579c609fbc61fff117f11b6692f770615be45cd (patch) | |
tree | 39899cd6c09ca72e971efd793b1cff7cb4af9e29 /src | |
parent | 5103b87a4d7b0b84a9773f9dc19a36caa7d4344f (diff) |
ec/starlabs/merlin: Add support for the ITE mirror flag
When enabled, the EC will mirror the firmware contained inside the
coreboot ROM. This allows it to be updated at the same time as
coreboot.
Enable the mirror flag if the installed EC firmware does not match
the target version or if a CMOS option, "manual_mirror_flag" is
set.
Signed-off-by: Sean Rhodes <sean@starlabs.systems>
Change-Id: I377abbb37dc4d3e535e518a73e73969b25967daa
Reviewed-on: https://review.coreboot.org/c/coreboot/+/73044
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/ec/starlabs/merlin/Kconfig | 14 | ||||
-rw-r--r-- | src/ec/starlabs/merlin/ec.h | 7 | ||||
-rw-r--r-- | src/ec/starlabs/merlin/ite.c | 63 | ||||
-rw-r--r-- | src/ec/starlabs/merlin/variants/adl/ecdefs.h | 1 | ||||
-rw-r--r-- | src/ec/starlabs/merlin/variants/apl/ecdefs.h | 1 | ||||
-rw-r--r-- | src/ec/starlabs/merlin/variants/cezanne/ecdefs.h | 1 | ||||
-rw-r--r-- | src/ec/starlabs/merlin/variants/cml/ecdefs.h | 1 | ||||
-rw-r--r-- | src/ec/starlabs/merlin/variants/glk/ecdefs.h | 1 | ||||
-rw-r--r-- | src/ec/starlabs/merlin/variants/glkr/ecdefs.h | 1 | ||||
-rw-r--r-- | src/ec/starlabs/merlin/variants/kbl/ecdefs.h | 1 | ||||
-rw-r--r-- | src/ec/starlabs/merlin/variants/merlin/ecdefs.h | 1 | ||||
-rw-r--r-- | src/ec/starlabs/merlin/variants/tgl/ecdefs.h | 1 |
12 files changed, 93 insertions, 0 deletions
diff --git a/src/ec/starlabs/merlin/Kconfig b/src/ec/starlabs/merlin/Kconfig index 6ccd21791c..5939854d1d 100644 --- a/src/ec/starlabs/merlin/Kconfig +++ b/src/ec/starlabs/merlin/Kconfig @@ -64,6 +64,20 @@ config EC_STARLABS_MAX_CHARGE help Select if the mainboard supports limiting the maximum charge of the battery. +config EC_STARLABS_MIRROR_SUPPORT + bool "Enable mirror flag support" + default n + depends on EC_STARLABS_ITE + help + Select if the EC should mirror the EC firmware contained in the coreboot ROM. + +config EC_STARLABS_MIRROR_VERSION + hex "Version of the EC firmware that should be installed." + depends on EC_STARLABS_MIRROR_SUPPORT + help + The version of the EC that should be installed. The mirror flag will be activated + if this Kconfig option is set and it does not match the current EC version. + config EC_STARLABS_MERLIN bool "Use open-source Merlin EC Firmware" default n diff --git a/src/ec/starlabs/merlin/ec.h b/src/ec/starlabs/merlin/ec.h index ca1d081f0c..2fe5ec5128 100644 --- a/src/ec/starlabs/merlin/ec.h +++ b/src/ec/starlabs/merlin/ec.h @@ -98,6 +98,13 @@ #define KBL_DISABLED 0x00 #define KBL_ENABLED 0xdd +/* Mirror Flag */ +#define MIRROR_DISABLED 0x00 +#define MIRROR_ENABLED 0xaa + +#define MIRROR_ATTEMPTS 1 + uint16_t ec_get_version(void); +void ec_mirror_flag(void); #endif diff --git a/src/ec/starlabs/merlin/ite.c b/src/ec/starlabs/merlin/ite.c index 357c67cda5..9730647276 100644 --- a/src/ec/starlabs/merlin/ite.c +++ b/src/ec/starlabs/merlin/ite.c @@ -6,6 +6,7 @@ #include <ec/acpi/ec.h> #include <option.h> #include <pc80/keyboard.h> +#include <halt.h> #include "ec.h" #include "ecdefs.h" @@ -26,6 +27,66 @@ static uint8_t get_ec_value_from_option(const char *name, return lut[index]; } +static void ec_mirror_with_count(void) +{ + unsigned int cmos_mirror_flag_counter = get_uint_option("mirror_flag_counter", UINT_MAX); + + if (cmos_mirror_flag_counter != UINT_MAX) { + printk(BIOS_DEBUG, "ITE: mirror_flag_counter = %u\n", cmos_mirror_flag_counter); + + /* Avoid boot loops by only trying a state change once */ + if (cmos_mirror_flag_counter < MIRROR_ATTEMPTS) { + cmos_mirror_flag_counter++; + set_uint_option("mirror_flag_counter", cmos_mirror_flag_counter); + printk(BIOS_DEBUG, "ITE: Mirror attempt %u/%u.\n", cmos_mirror_flag_counter, + MIRROR_ATTEMPTS); + + /* Write the EC mirror flag */ + ec_write(ECRAM_MIRROR_FLAG, MIRROR_ENABLED); + + /* Check what has been written */ + if (ec_read(ECRAM_MIRROR_FLAG) == MIRROR_ENABLED) + poweroff(); + } else { + /* + * If the mirror flags fails after 1 attempt, it will + * likely need a cold boot, or recovering. + */ + printk(BIOS_ERR, "ITE: Failed to mirror the EC in %u attempts!\n", + MIRROR_ATTEMPTS); + } + } else { + printk(BIOS_DEBUG, "ITE: Powering Off"); + /* Write the EC mirror flag */ + ec_write(ECRAM_MIRROR_FLAG, MIRROR_ENABLED); + + /* Check what has been written */ + if (ec_read(ECRAM_MIRROR_FLAG) == MIRROR_ENABLED) + poweroff(); + } +} + + +void ec_mirror_flag(void) +{ + /* + * For the mirror flag to work, the status of the EC pin must be known + * at all times, which means external power. This can be either a DC + * charger, or PD with CCG6. PD with an ANX7447 requires configuration + * from the EC, so the update will interrupt this. + * + * This means we can unconditionally apply the mirror flag to devices + * that have CCG6, present on devices with TBT, but have a manual + * flag for devices without it. + */ + if (CONFIG(EC_STARLABS_MIRROR_SUPPORT) && + (CONFIG(SOC_INTEL_COMMON_BLOCK_TCSS) || get_uint_option("mirror_flag", 0)) && + (ec_get_version() != CONFIG_EC_STARLABS_MIRROR_VERSION)) { + printk(BIOS_ERR, "ITE: System and EC ROM version mismatch.\n"); + ec_mirror_with_count(); + } +} + static uint16_t ec_get_chip_id(unsigned int port) { return (pnp_read_index(port, ITE_CHIPID1) << 8) | @@ -57,6 +118,8 @@ static void merlin_init(struct device *dev) return; } + ec_mirror_flag(); + pc_keyboard_init(NO_AUX_DEVICE); /* diff --git a/src/ec/starlabs/merlin/variants/adl/ecdefs.h b/src/ec/starlabs/merlin/variants/adl/ecdefs.h index 28f7e4b84f..f7c584c304 100644 --- a/src/ec/starlabs/merlin/variants/adl/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/adl/ecdefs.h @@ -23,5 +23,6 @@ #define ECRAM_MAX_CHARGE 0x1a #define ECRAM_FAN_MODE 0x1b #define ECRAM_FAST_CHARGE dead_code_t(uint8_t) +#define ECRAM_MIRROR_FLAG 0x05 #endif diff --git a/src/ec/starlabs/merlin/variants/apl/ecdefs.h b/src/ec/starlabs/merlin/variants/apl/ecdefs.h index fa7e79b148..5cbe14e36d 100644 --- a/src/ec/starlabs/merlin/variants/apl/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/apl/ecdefs.h @@ -23,5 +23,6 @@ #define ECRAM_MAX_CHARGE dead_code_t(uint8_t) #define ECRAM_FAN_MODE dead_code_t(uint8_t) #define ECRAM_FAST_CHARGE dead_code_t(uint8_t) +#define ECRAM_MIRROR_FLAG 0x04 #endif diff --git a/src/ec/starlabs/merlin/variants/cezanne/ecdefs.h b/src/ec/starlabs/merlin/variants/cezanne/ecdefs.h index 6942c391a3..0c522cc845 100644 --- a/src/ec/starlabs/merlin/variants/cezanne/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/cezanne/ecdefs.h @@ -23,5 +23,6 @@ #define ECRAM_KBL_BRIGHTNESS 0x36 #define ECRAM_FN_LOCK_STATE 0x70 #define ECRAM_FAST_CHARGE dead_code_t(uint8_t) +#define ECRAM_MIRROR_FLAG 0x05 #endif diff --git a/src/ec/starlabs/merlin/variants/cml/ecdefs.h b/src/ec/starlabs/merlin/variants/cml/ecdefs.h index 6a24bc4deb..0a2654bf8f 100644 --- a/src/ec/starlabs/merlin/variants/cml/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/cml/ecdefs.h @@ -23,5 +23,6 @@ #define ECRAM_KBL_BRIGHTNESS 0x19 #define ECRAM_FN_LOCK_STATE 0x2c #define ECRAM_FAST_CHARGE dead_code_t(uint8_t) +#define ECRAM_MIRROR_FLAG 0x04 #endif diff --git a/src/ec/starlabs/merlin/variants/glk/ecdefs.h b/src/ec/starlabs/merlin/variants/glk/ecdefs.h index fefdd141c9..b2e2f2f8ab 100644 --- a/src/ec/starlabs/merlin/variants/glk/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/glk/ecdefs.h @@ -23,5 +23,6 @@ #define ECRAM_MAX_CHARGE dead_code_t(uint8_t) #define ECRAM_FAN_MODE dead_code_t(uint8_t) #define ECRAM_FAST_CHARGE dead_code_t(uint8_t) +#define ECRAM_MIRROR_FLAG 0x04 #endif diff --git a/src/ec/starlabs/merlin/variants/glkr/ecdefs.h b/src/ec/starlabs/merlin/variants/glkr/ecdefs.h index 038c378fb2..ecc117c990 100644 --- a/src/ec/starlabs/merlin/variants/glkr/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/glkr/ecdefs.h @@ -23,5 +23,6 @@ #define ECRAM_MAX_CHARGE dead_code_t(uint8_t) #define ECRAM_FAN_MODE dead_code_t(uint8_t) #define ECRAM_FAST_CHARGE 0x18 +#define ECRAM_MIRROR_FLAG dead_code_t(uint8_t) #endif diff --git a/src/ec/starlabs/merlin/variants/kbl/ecdefs.h b/src/ec/starlabs/merlin/variants/kbl/ecdefs.h index 3b693173af..8f3355dd0a 100644 --- a/src/ec/starlabs/merlin/variants/kbl/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/kbl/ecdefs.h @@ -23,5 +23,6 @@ #define ECRAM_FN_CTRL_REVERSE 0x43 #define ECRAM_MAX_CHARGE dead_code_t(uint8_t) #define ECRAM_FAST_CHARGE dead_code_t(uint8_t) +#define ECRAM_MIRROR_FLAG 0x04 #endif diff --git a/src/ec/starlabs/merlin/variants/merlin/ecdefs.h b/src/ec/starlabs/merlin/variants/merlin/ecdefs.h index f02c73a27c..08f80cb1f8 100644 --- a/src/ec/starlabs/merlin/variants/merlin/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/merlin/ecdefs.h @@ -20,5 +20,6 @@ #define ECRAM_FAN_MODE 0x50 #define ECRAM_MAX_CHARGE 0x51 #define ECRAM_FAST_CHARGE 0x52 +#define ECRAM_MIRROR_FLAG 0x05 #endif diff --git a/src/ec/starlabs/merlin/variants/tgl/ecdefs.h b/src/ec/starlabs/merlin/variants/tgl/ecdefs.h index cbc7b86e10..c17b02542b 100644 --- a/src/ec/starlabs/merlin/variants/tgl/ecdefs.h +++ b/src/ec/starlabs/merlin/variants/tgl/ecdefs.h @@ -23,5 +23,6 @@ #define ECRAM_MAX_CHARGE 0x1a #define ECRAM_FAN_MODE 0x1b #define ECRAM_FAST_CHARGE dead_code_t(uint8_t) +#define ECRAM_MIRROR_FLAG 0x05 #endif |