summaryrefslogtreecommitdiff
path: root/src/ec/starlabs/merlin/ite.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ec/starlabs/merlin/ite.c')
-rw-r--r--src/ec/starlabs/merlin/ite.c63
1 files changed, 63 insertions, 0 deletions
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);
/*