From cff9735e81f2c8e0dc7e1bfdc2e1a1f467a3a59c Mon Sep 17 00:00:00 2001 From: "Dustin L. Howett" Date: Sun, 22 Jan 2023 23:00:31 -0600 Subject: [PATCH] mchp/lfw: make sure we keep the EC on for long operations Over the past six months with this patch set, I've observed one troubling behavior: the power button would not always work when the machine was powered completely off (EC off) and I clicked the power button. It turns out that the power buttons control VCI_IN[01] and that the VBAT-powered control interface is configured to drive GPIO250 as VCI_OUT based on the status of those inputs. Now, GPIO250 is also known as EC_ON on hx20/30: it controls whether 3VL_EC is on. The MEC1521 manual recommends the following example of using VCI_OUT on a "mobile platform" (abbreviated): 1. A coin cell battery is installed, powering VBAT 2. The power button on VCI_IN0# is pushed causing VCI_OUT to be asserted, powering the VTR rail 3. The EC reconfigured VCI so that firmware controls the VCI_OUT pin. Now, the EC is doing this over in vci_task (hx20/hx30), which is long after LFW has started and jumped to main firmware. The problem is, restoring access to RO and RW images via properly configuring the SPI flash pins' alt mode causes us to try to read from flash on startup. Reading from flash is slightly slower, so we extend the period of time between step 2 and 3 where 3VL_EC is only driven by VCI_IN0#. When the user releases the power button during that window, 3VL_EC is cut and the EC shuts down. This patch fixes the issue by asserting firmware control of VCI_OUT as early as is safe in lfw. --- board/hx20/lfw/gpio.inc | 2 ++ board/hx30/lfw/gpio.inc | 2 ++ chip/mchp/lfw/ec_lfw.c | 10 ++++++++++ 3 files changed, 14 insertions(+) diff --git a/board/hx20/lfw/gpio.inc b/board/hx20/lfw/gpio.inc index cabf346f97..a62b0c685c 100644 --- a/board/hx20/lfw/gpio.inc +++ b/board/hx20/lfw/gpio.inc @@ -15,6 +15,8 @@ */ GPIO(QMSPI_CS0, PIN(055), GPIO_ODR_HIGH) +/* We need to take control of this away from VCI */ +GPIO(EC_ON, PIN(0250), GPIO_OUT_HIGH) /* keep +3VL_EC to power on */ /* Alternate functions GPIO definition */ diff --git a/board/hx30/lfw/gpio.inc b/board/hx30/lfw/gpio.inc index f4142d3c29..fc7440cb23 100644 --- a/board/hx30/lfw/gpio.inc +++ b/board/hx30/lfw/gpio.inc @@ -15,6 +15,8 @@ */ GPIO(QMSPI_CS0, PIN(055), GPIO_ODR_HIGH) +/* We need to take control of this away from VCI */ +GPIO(EC_ON, PIN(0250), GPIO_OUT_HIGH) /* keep +3VL_EC to power on */ /* Alternate functions GPIO definition */ diff --git a/chip/mchp/lfw/ec_lfw.c b/chip/mchp/lfw/ec_lfw.c index 8b2e429fb3..334338daa3 100644 --- a/chip/mchp/lfw/ec_lfw.c +++ b/chip/mchp/lfw/ec_lfw.c @@ -422,6 +422,16 @@ void lfw_main(void) uart_init(); system_init(); + /* + * We need to switch control of VCI_OUT (aliased as EC_ON) away from + * VCI_INx to keep the machine powered even after the user releases the + * power button. This ensures that we can stay on long enough to read + * from SPI flash. + */ + gpio_reset(GPIO_EC_ON); + MCHP_VCI_REGISTER |= MCHP_VCI_REGISTER_FW_CNTRL; + MCHP_VCI_REGISTER |= MCHP_VCI_REGISTER_FW_EXT; + spi_enable(CONFIG_SPI_FLASH_PORT, 1); uart_puts("littlefw ");