hatch: Fix FPMCU pwr/rst gpio handling
1. No gpio control in bootblock 2. Disable power and assert reset in ramstage gpio 3. Power on and then deassert reset at the end of ramstage gpio 4. Disable power and assert reset when entering S5 On "reboot", the amount of time the power is disabled for is equivalent to the amount of time between triggering #4 and wrapping around to #3, which is about 400ms on Kohaku. Since #2 forces power off for FPMCU, S3 resume will still not work properly. Additionally, we must ensure that GPP_A12 is reconfigured as an output before going to any sleep state, since user space could have configured it to use its native3 function. See https://review.coreboot.org/c/coreboot/+/32111 for more detail. The control signals have been validated on a Kohaku in the following scenarios: 1. Cold startup 2. Issuing a "reboot" command 3. Issuing a "halt -p" and powering back on within 10 seconds 4. Issuing a "halt -p" and powering back on after 10 seconds 5. Entering and leaving S3 (does not work properly) 6. Entering and leaving S0iX BRANCH=hatch BUG=b/142751685 TEST=Verify all signals as mentioned above TEST=reboot flash_fp_mcu /opt/google/biod/fw/dartmonkey_v2.0.2417-af88cc91a.bin TEST=halt -p # power back on within 10 seconds flash_fp_mcu /opt/google/biod/fw/dartmonkey_v2.0.2417-af88cc91a.bin TEST=halt -p # power back on after 10 seconds flash_fp_mcu /opt/google/biod/fw/dartmonkey_v2.0.2417-af88cc91a.bin Change-Id: I2e3ff42715611d519677a4256bdd172ec98687f9 Signed-off-by: Craig Hesling <hesling@chromium.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/37459 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Furquan Shaikh <furquan@google.com>
This commit is contained in:
parent
344b331783
commit
fcd8c9e99e
|
@ -31,6 +31,11 @@ void __weak variant_devtree_update(void)
|
||||||
/* Override dev tree settings per board */
|
/* Override dev tree settings per board */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __weak variant_ramstage_init(void)
|
||||||
|
{
|
||||||
|
/* Default weak implementation */
|
||||||
|
}
|
||||||
|
|
||||||
static void mainboard_init(struct device *dev)
|
static void mainboard_init(struct device *dev)
|
||||||
{
|
{
|
||||||
mainboard_ec_init();
|
mainboard_ec_init();
|
||||||
|
@ -56,6 +61,8 @@ static void mainboard_chip_init(void *chip_info)
|
||||||
base_gpios,
|
base_gpios,
|
||||||
override_table,
|
override_table,
|
||||||
override_gpios);
|
override_gpios);
|
||||||
|
|
||||||
|
variant_ramstage_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct chip_operations mainboard_ops = {
|
struct chip_operations mainboard_ops = {
|
||||||
|
|
|
@ -38,7 +38,7 @@ static const struct pad_config gpio_table[] = {
|
||||||
/* A11 : PCH_SPI_FPMCU_CS_L */
|
/* A11 : PCH_SPI_FPMCU_CS_L */
|
||||||
PAD_CFG_NF(GPP_A11, NONE, DEEP, NF2),
|
PAD_CFG_NF(GPP_A11, NONE, DEEP, NF2),
|
||||||
/* A12 : FPMCU_RST_ODL */
|
/* A12 : FPMCU_RST_ODL */
|
||||||
PAD_CFG_GPO(GPP_A12, 1, DEEP),
|
PAD_CFG_GPO(GPP_A12, 0, DEEP),
|
||||||
/* A13 : SUSWARN_L */
|
/* A13 : SUSWARN_L */
|
||||||
PAD_CFG_NF(GPP_A13, NONE, DEEP, NF1),
|
PAD_CFG_NF(GPP_A13, NONE, DEEP, NF1),
|
||||||
/* A14 : ESPI_RST_L */
|
/* A14 : ESPI_RST_L */
|
||||||
|
@ -133,7 +133,7 @@ static const struct pad_config gpio_table[] = {
|
||||||
/* C10 : GPP_10 ==> GPP_C10_TP */
|
/* C10 : GPP_10 ==> GPP_C10_TP */
|
||||||
PAD_NC(GPP_C10, NONE),
|
PAD_NC(GPP_C10, NONE),
|
||||||
/* C11 : GPP_11 ==> EN_FP_RAILS */
|
/* C11 : GPP_11 ==> EN_FP_RAILS */
|
||||||
PAD_CFG_GPO(GPP_C11, 1, DEEP),
|
PAD_CFG_GPO(GPP_C11, 0, DEEP),
|
||||||
/* C12 : GPP_C12 ==> NC */
|
/* C12 : GPP_C12 ==> NC */
|
||||||
PAD_NC(GPP_C12, NONE),
|
PAD_NC(GPP_C12, NONE),
|
||||||
/* C13 : EC_PCH_INT_L */
|
/* C13 : EC_PCH_INT_L */
|
||||||
|
@ -398,8 +398,10 @@ const struct pad_config *base_gpio_table(size_t *num)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default GPIO settings before entering sleep. Configure A12: FPMCU_RST_ODL
|
* Default GPIO settings before entering non-S5 sleep states.
|
||||||
* as GPO before entering sleep.
|
* Configure A12: FPMCU_RST_ODL as GPO before entering sleep.
|
||||||
|
* This guarantees that A12's native3 function is disabled.
|
||||||
|
* See https://review.coreboot.org/c/coreboot/+/32111 .
|
||||||
*/
|
*/
|
||||||
static const struct pad_config default_sleep_gpio_table[] = {
|
static const struct pad_config default_sleep_gpio_table[] = {
|
||||||
PAD_CFG_GPO(GPP_A12, 1, DEEP), /* FPMCU_RST_ODL */
|
PAD_CFG_GPO(GPP_A12, 1, DEEP), /* FPMCU_RST_ODL */
|
||||||
|
@ -408,10 +410,11 @@ static const struct pad_config default_sleep_gpio_table[] = {
|
||||||
/*
|
/*
|
||||||
* GPIO settings before entering S5, which are same as
|
* GPIO settings before entering S5, which are same as
|
||||||
* default_sleep_gpio_table but also,
|
* default_sleep_gpio_table but also,
|
||||||
* turn off EN_PP3300_WWAN.
|
* turn off EN_PP3300_WWAN and FPMCU.
|
||||||
*/
|
*/
|
||||||
static const struct pad_config s5_sleep_gpio_table[] = {
|
static const struct pad_config s5_sleep_gpio_table[] = {
|
||||||
PAD_CFG_GPO(GPP_A12, 1, DEEP), /* FPMCU_RST_ODL */
|
PAD_CFG_GPO(GPP_A12, 0, DEEP), /* FPMCU_RST_ODL */
|
||||||
|
PAD_CFG_GPO(GPP_C11, 0, DEEP), /* PCH_FP_PWR_EN */
|
||||||
PAD_CFG_GPO(GPP_A18, 0, DEEP), /* EN_PP3300_WWAN */
|
PAD_CFG_GPO(GPP_A18, 0, DEEP), /* EN_PP3300_WWAN */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -50,4 +50,7 @@ uint32_t get_board_sku(void);
|
||||||
/* Modify devictree settings during ramstage. */
|
/* Modify devictree settings during ramstage. */
|
||||||
void variant_devtree_update(void);
|
void variant_devtree_update(void);
|
||||||
|
|
||||||
|
/* Perform variant specific initialization early on in ramstage. */
|
||||||
|
void variant_ramstage_init(void);
|
||||||
|
|
||||||
#endif /* BASEBOARD_VARIANTS_H */
|
#endif /* BASEBOARD_VARIANTS_H */
|
||||||
|
|
|
@ -17,4 +17,6 @@ SPD_SOURCES += LP_16G_2133 # 0b0001
|
||||||
|
|
||||||
romstage-y += memory.c
|
romstage-y += memory.c
|
||||||
bootblock-y += gpio.c
|
bootblock-y += gpio.c
|
||||||
|
|
||||||
ramstage-y += gpio.c
|
ramstage-y += gpio.c
|
||||||
|
ramstage-y += ramstage.c
|
||||||
|
|
|
@ -117,8 +117,6 @@ const struct pad_config *override_gpio_table(size_t *num)
|
||||||
* needed in this table.
|
* needed in this table.
|
||||||
*/
|
*/
|
||||||
static const struct pad_config early_gpio_table[] = {
|
static const struct pad_config early_gpio_table[] = {
|
||||||
/* A12 : FPMCU_RST_ODL */
|
|
||||||
PAD_CFG_GPO(GPP_A12, 0, DEEP),
|
|
||||||
/* B15 : H1_SLAVE_SPI_CS_L */
|
/* B15 : H1_SLAVE_SPI_CS_L */
|
||||||
PAD_CFG_NF(GPP_B15, NONE, DEEP, NF1),
|
PAD_CFG_NF(GPP_B15, NONE, DEEP, NF1),
|
||||||
/* B16 : H1_SLAVE_SPI_CLK */
|
/* B16 : H1_SLAVE_SPI_CLK */
|
||||||
|
@ -127,8 +125,6 @@ static const struct pad_config early_gpio_table[] = {
|
||||||
PAD_CFG_NF(GPP_B17, NONE, DEEP, NF1),
|
PAD_CFG_NF(GPP_B17, NONE, DEEP, NF1),
|
||||||
/* B18 : H1_SLAVE_SPI_MOSI_R */
|
/* B18 : H1_SLAVE_SPI_MOSI_R */
|
||||||
PAD_CFG_NF(GPP_B18, NONE, DEEP, NF1),
|
PAD_CFG_NF(GPP_B18, NONE, DEEP, NF1),
|
||||||
/* C11 : GPP_C11 ==> EN_FP_RAILS */
|
|
||||||
PAD_CFG_GPO(GPP_C11, 1, DEEP),
|
|
||||||
/* C14 : BT_DISABLE_L */
|
/* C14 : BT_DISABLE_L */
|
||||||
PAD_CFG_GPO(GPP_C14, 0, DEEP),
|
PAD_CFG_GPO(GPP_C14, 0, DEEP),
|
||||||
/* PCH_WP_OD */
|
/* PCH_WP_OD */
|
||||||
|
@ -150,14 +146,30 @@ const struct pad_config *variant_early_gpio_table(size_t *num)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GPIO settings before entering all sleep states
|
* Default GPIO settings before entering non-S5 sleep states.
|
||||||
|
* Configure A12: FPMCU_RST_ODL as GPO before entering sleep.
|
||||||
|
* This guarantees that A12's native3 function is disabled.
|
||||||
|
* See https://review.coreboot.org/c/coreboot/+/32111 .
|
||||||
*/
|
*/
|
||||||
static const struct pad_config sleep_gpio_table[] = {
|
static const struct pad_config default_sleep_gpio_table[] = {
|
||||||
PAD_CFG_GPO(GPP_A12, 1, DEEP), /* FPMCU_RST_ODL */
|
PAD_CFG_GPO(GPP_A12, 1, DEEP), /* FPMCU_RST_ODL */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPIO settings before entering S5, which are same as
|
||||||
|
* default_sleep_gpio_table but also, turn off FPMCU.
|
||||||
|
*/
|
||||||
|
static const struct pad_config s5_sleep_gpio_table[] = {
|
||||||
|
PAD_CFG_GPO(GPP_A12, 0, DEEP), /* FPMCU_RST_ODL */
|
||||||
|
PAD_CFG_GPO(GPP_C11, 0, DEEP), /* PCH_FP_PWR_EN */
|
||||||
|
};
|
||||||
|
|
||||||
const struct pad_config *variant_sleep_gpio_table(u8 slp_typ, size_t *num)
|
const struct pad_config *variant_sleep_gpio_table(u8 slp_typ, size_t *num)
|
||||||
{
|
{
|
||||||
*num = ARRAY_SIZE(sleep_gpio_table);
|
if (slp_typ == ACPI_S5) {
|
||||||
return sleep_gpio_table;
|
*num = ARRAY_SIZE(s5_sleep_gpio_table);
|
||||||
|
return s5_sleep_gpio_table;
|
||||||
|
}
|
||||||
|
*num = ARRAY_SIZE(default_sleep_gpio_table);
|
||||||
|
return default_sleep_gpio_table;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright 2019 Google LLC
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <delay.h>
|
||||||
|
#include <gpio.h>
|
||||||
|
#include <baseboard/variants.h>
|
||||||
|
#include <soc/gpio.h>
|
||||||
|
|
||||||
|
void variant_ramstage_init(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Enable power to FPMCU, wait for power rail to stabilize,
|
||||||
|
* and then deassert FPMCU reset.
|
||||||
|
* Waiting for the power rail to stabilize can take a while,
|
||||||
|
* a minimum of 400us on Kohaku.
|
||||||
|
*/
|
||||||
|
gpio_output(GPP_C11, 1);
|
||||||
|
mdelay(1);
|
||||||
|
gpio_output(GPP_A12, 1);
|
||||||
|
}
|
|
@ -154,8 +154,6 @@ const struct pad_config *override_gpio_table(size_t *num)
|
||||||
* needed in this table.
|
* needed in this table.
|
||||||
*/
|
*/
|
||||||
static const struct pad_config early_gpio_table[] = {
|
static const struct pad_config early_gpio_table[] = {
|
||||||
/* A12 : FPMCU_RST_ODL */
|
|
||||||
PAD_CFG_GPO(GPP_A12, 0, DEEP),
|
|
||||||
/* B15 : H1_SLAVE_SPI_CS_L */
|
/* B15 : H1_SLAVE_SPI_CS_L */
|
||||||
PAD_CFG_NF(GPP_B15, NONE, DEEP, NF1),
|
PAD_CFG_NF(GPP_B15, NONE, DEEP, NF1),
|
||||||
/* B16 : H1_SLAVE_SPI_CLK */
|
/* B16 : H1_SLAVE_SPI_CLK */
|
||||||
|
|
|
@ -17,4 +17,6 @@ SPD_SOURCES = LP_8G_2133 # 0b000
|
||||||
romstage-y += memory.c
|
romstage-y += memory.c
|
||||||
|
|
||||||
bootblock-y += gpio.c
|
bootblock-y += gpio.c
|
||||||
|
|
||||||
ramstage-y += gpio.c
|
ramstage-y += gpio.c
|
||||||
|
ramstage-y += ramstage.c
|
||||||
|
|
|
@ -97,8 +97,6 @@ const struct pad_config *override_gpio_table(size_t *num)
|
||||||
* needed in this table.
|
* needed in this table.
|
||||||
*/
|
*/
|
||||||
static const struct pad_config early_gpio_table[] = {
|
static const struct pad_config early_gpio_table[] = {
|
||||||
/* A12 : FPMCU_RST_ODL */
|
|
||||||
PAD_CFG_GPO(GPP_A12, 0, DEEP),
|
|
||||||
/* B15 : H1_SLAVE_SPI_CS_L */
|
/* B15 : H1_SLAVE_SPI_CS_L */
|
||||||
PAD_CFG_NF(GPP_B15, NONE, DEEP, NF1),
|
PAD_CFG_NF(GPP_B15, NONE, DEEP, NF1),
|
||||||
/* B16 : H1_SLAVE_SPI_CLK */
|
/* B16 : H1_SLAVE_SPI_CLK */
|
||||||
|
@ -136,14 +134,30 @@ const struct pad_config *variant_early_gpio_table(size_t *num)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GPIO settings before entering all sleep states
|
* Default GPIO settings before entering non-S5 sleep states.
|
||||||
|
* Configure A12: FPMCU_RST_ODL as GPO before entering sleep.
|
||||||
|
* This guarantees that A12's native3 function is disabled.
|
||||||
|
* See https://review.coreboot.org/c/coreboot/+/32111 .
|
||||||
*/
|
*/
|
||||||
static const struct pad_config sleep_gpio_table[] = {
|
static const struct pad_config default_sleep_gpio_table[] = {
|
||||||
PAD_CFG_GPO(GPP_A12, 1, DEEP), /* FPMCU_RST_ODL */
|
PAD_CFG_GPO(GPP_A12, 1, DEEP), /* FPMCU_RST_ODL */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPIO settings before entering S5, which are same as
|
||||||
|
* default_sleep_gpio_table but also, turn off FPMCU.
|
||||||
|
*/
|
||||||
|
static const struct pad_config s5_sleep_gpio_table[] = {
|
||||||
|
PAD_CFG_GPO(GPP_A12, 0, DEEP), /* FPMCU_RST_ODL */
|
||||||
|
PAD_CFG_GPO(GPP_C11, 0, DEEP), /* PCH_FP_PWR_EN */
|
||||||
|
};
|
||||||
|
|
||||||
const struct pad_config *variant_sleep_gpio_table(u8 slp_typ, size_t *num)
|
const struct pad_config *variant_sleep_gpio_table(u8 slp_typ, size_t *num)
|
||||||
{
|
{
|
||||||
*num = ARRAY_SIZE(sleep_gpio_table);
|
if (slp_typ == ACPI_S5) {
|
||||||
return sleep_gpio_table;
|
*num = ARRAY_SIZE(s5_sleep_gpio_table);
|
||||||
|
return s5_sleep_gpio_table;
|
||||||
|
}
|
||||||
|
*num = ARRAY_SIZE(default_sleep_gpio_table);
|
||||||
|
return default_sleep_gpio_table;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright 2019 Google LLC
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; version 2 of the License.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <delay.h>
|
||||||
|
#include <gpio.h>
|
||||||
|
#include <baseboard/variants.h>
|
||||||
|
#include <soc/gpio.h>
|
||||||
|
|
||||||
|
void variant_ramstage_init(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Enable power to FPMCU, wait for power rail to stabilize,
|
||||||
|
* and then deassert FPMCU reset.
|
||||||
|
* Waiting for the power rail to stabilize can take a while,
|
||||||
|
* a minimum of 400us on Kohaku.
|
||||||
|
*/
|
||||||
|
gpio_output(GPP_C11, 1);
|
||||||
|
mdelay(1);
|
||||||
|
gpio_output(GPP_A12, 1);
|
||||||
|
}
|
Loading…
Reference in New Issue