From 279406cd14d9764b54084f8deba8cadc81093589 Mon Sep 17 00:00:00 2001 From: Sean Rhodes Date: Wed, 28 Jan 2026 11:16:01 +0000 Subject: [PATCH] mb/starlabs/starfighter: Add NVMe port power sequence Implement Fatcat-style 3-stage M.2 NVMe slot sequencing (PWREN, PERST#, CLKREQ#) for StarFighter and apply it to all NVMe-capable ports (both Gen3 and Gen4). This addresses intermittent NVMe detection problems on cold/warm boot and improves PCIe link speed negotiation by ensuring the device is held in reset with clocks gated until slot power is enabled and coreboot is about to initialize devices. Sequence per NVMe port: 1) pre-mem: disable CLKREQ#, assert PERST#, PWREN=0 2) BS_PRE_DEVICE exit: PWREN=1, enable CLKREQ# native, keep PERST# asserted 3) BS_DEV_INIT_CHIPS entry: deassert PERST# Also update the variant gpio_table defaults so PWREN stays off and CLKREQ# stays disconnected until the sequencing code enables them. Signed-off-by: Sean Rhodes Change-Id: Ic34e9e755e167e301348fbe7c75649401300f53b Reviewed-on: https://review.coreboot.org/c/coreboot/+/90974 Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/starlabs/starfighter/Kconfig | 1 + .../starlabs/starfighter/mainboard.c | 9 +-- .../starlabs/starfighter/variants/mtl/gpio.c | 65 +++++++++++++++--- .../starlabs/starfighter/variants/rpl/gpio.c | 67 ++++++++++++++++--- 4 files changed, 120 insertions(+), 22 deletions(-) diff --git a/src/mainboard/starlabs/starfighter/Kconfig b/src/mainboard/starlabs/starfighter/Kconfig index 07a810ec63..b7795cc6aa 100644 --- a/src/mainboard/starlabs/starfighter/Kconfig +++ b/src/mainboard/starlabs/starfighter/Kconfig @@ -32,6 +32,7 @@ config BOARD_STARLABS_STARFIGHTER_SERIES select SYSTEM_TYPE_LAPTOP select TPM_MEASURED_BOOT select VALIDATE_INTEL_DESCRIPTOR + select STARLABS_NVME_POWER_SEQUENCE config BOARD_STARLABS_STARFIGHTER_RPL select BOARD_STARLABS_STARFIGHTER_SERIES diff --git a/src/mainboard/starlabs/starfighter/mainboard.c b/src/mainboard/starlabs/starfighter/mainboard.c index cd46529c0f..e0b6ffae49 100644 --- a/src/mainboard/starlabs/starfighter/mainboard.c +++ b/src/mainboard/starlabs/starfighter/mainboard.c @@ -1,10 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include -static void init_mainboard(void *chip_info) +static void starlabs_configure_gpios(void *unused) { const struct pad_config *pads; size_t num; @@ -13,6 +14,6 @@ static void init_mainboard(void *chip_info) gpio_configure_pads(pads, num); } -struct chip_operations mainboard_ops = { - .init = init_mainboard, -}; +BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, starlabs_configure_gpios, NULL); + +struct chip_operations mainboard_ops = {}; diff --git a/src/mainboard/starlabs/starfighter/variants/mtl/gpio.c b/src/mainboard/starlabs/starfighter/variants/mtl/gpio.c index 63d8218f80..32e7a5f6bc 100644 --- a/src/mainboard/starlabs/starfighter/variants/mtl/gpio.c +++ b/src/mainboard/starlabs/starfighter/variants/mtl/gpio.c @@ -1,8 +1,42 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_H07, 1, DEEP), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D20, NONE, PLTRST, NF1), + PAD_CFG_GPO(GPP_A20, 0, PLTRST), + PAD_CFG_GPO(GPP_D22, 1, DEEP), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C10, NONE, PLTRST, NF1), + PAD_CFG_GPO(GPP_H00, 0, PLTRST), + PAD_CFG_GPO(GPP_B19, 1, DEEP), + PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D21, NONE, PLTRST, NF2), + PAD_CFG_GPO(GPP_H02, 0, PLTRST), +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_A20, 1, PLTRST), + PAD_CFG_GPO(GPP_H00, 1, PLTRST), + PAD_CFG_GPO(GPP_H02, 1, PLTRST), +}; + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ +/* clang-format off */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H08, NONE, DEEP, NF1), /* RXD */ @@ -17,7 +51,18 @@ const struct pad_config early_gpio_table[] = { PAD_CFG_GPI_LOCK(GPP_B06, NONE, LOCK_CONFIG), PAD_CFG_GPI_LOCK(GPP_B07, NONE, LOCK_CONFIG), PAD_CFG_GPI_LOCK(GPP_B08, NONE, LOCK_CONFIG), + + PAD_CFG_GPI(GPP_D20, NONE, PLTRST), /* Clock Request 8 */ + PAD_CFG_GPO(GPP_A20, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_H07, 0, DEEP), /* Enable (PWREN off) */ + PAD_CFG_GPI(GPP_C10, NONE, PLTRST), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H00, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D22, 0, DEEP), /* Enable (PWREN off) */ + PAD_CFG_GPI(GPP_D21, NONE, PLTRST), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_H02, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_B19, 0, DEEP), /* WiFi disabled */ }; +/* clang-format on */ const struct pad_config *variant_early_gpio_table(size_t *num) { @@ -26,6 +71,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num) } /* Pad configuration in ramstage. */ +/* clang-format off */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_V00, NONE, DEEP, NF1), /* Battery Low */ @@ -50,19 +96,19 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC(GPP_B00, NONE, DEEP, LEVEL, INVERT), /* Interrupt */ /* SSD (CPU)*/ - PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D20, NONE, PLTRST, NF1), /* Clock Request 8 */ - PAD_CFG_GPO(GPP_A20, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_H07, 1, DEEP), /* Enable */ + PAD_NC(GPP_D20, NONE), /* Clock Request 8 */ + PAD_CFG_GPO(GPP_A20, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_H07, 0, DEEP), /* Enable (PWREN off) */ /* SSD (PCH) */ - PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_C10, NONE, PLTRST, NF1), /* Clock Request 1 */ - PAD_CFG_GPO(GPP_H00, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D22, 1, DEEP), /* Enable */ + PAD_NC(GPP_C10, NONE), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H00, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D22, 0, DEEP), /* Enable (PWREN off) */ /* Wireless */ - PAD_CFG_NF_IOSTANDBY_IGNORE(GPP_D21, NONE, PLTRST, NF2), /* Clock Request 5 */ - PAD_CFG_GPO(GPP_H02, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_B19, 1, DEEP), /* WiFi RF Kill */ + PAD_NC(GPP_D21, NONE), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_H02, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_B19, 0, DEEP), /* WiFi disabled */ PAD_CFG_GPO(GPP_B18, 1, DEEP), /* Bluetooth RF Kill */ /* Display */ @@ -252,6 +298,7 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_D19, NONE), PAD_NC(GPP_D23, NONE), }; +/* clang-format on */ const struct pad_config *variant_gpio_table(size_t *num) { diff --git a/src/mainboard/starlabs/starfighter/variants/rpl/gpio.c b/src/mainboard/starlabs/starfighter/variants/rpl/gpio.c index d58121e83a..d1b7f60df6 100644 --- a/src/mainboard/starlabs/starfighter/variants/rpl/gpio.c +++ b/src/mainboard/starlabs/starfighter/variants/rpl/gpio.c @@ -1,8 +1,44 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include +#include + +#if ENV_RAMSTAGE +/* clang-format off */ +static const struct pad_config nvme_pads[] = { + PAD_CFG_GPO(GPP_D14, 1, DEEP), + PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_F20, 0, PLTRST), + PAD_CFG_GPO(GPP_D16, 1, PLTRST), + PAD_CFG_NF(GPP_H19, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_H0, 0, PLTRST), + PAD_CFG_GPO(GPP_E3, 1, DEEP), + PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), + PAD_CFG_GPO(GPP_H2, 0, PLTRST), +}; + +static const struct pad_config post_nvme_pads[] = { + PAD_CFG_GPO(GPP_F20, 1, PLTRST), + PAD_CFG_GPO(GPP_H0, 1, PLTRST), + PAD_CFG_GPO(GPP_H2, 1, PLTRST), +}; +/* clang-format on */ + +const struct pad_config *variant_nvme_power_sequence_pads(size_t *num) +{ + *num = ARRAY_SIZE(nvme_pads); + return nvme_pads; +} + +const struct pad_config *variant_nvme_power_sequence_post_pads(size_t *num) +{ + *num = ARRAY_SIZE(post_nvme_pads); + return post_nvme_pads; +} +#endif /* Early pad configuration in bootblock */ +/* clang-format off */ const struct pad_config early_gpio_table[] = { /* Debug Connector */ PAD_CFG_NF(GPP_H10, NONE, DEEP, NF2), /* RXD */ @@ -13,7 +49,18 @@ const struct pad_config early_gpio_table[] = { PAD_CFG_GPI_LOCK(GPP_F13, NONE, LOCK_CONFIG), PAD_CFG_GPI_LOCK(GPP_F14, NONE, LOCK_CONFIG), PAD_CFG_GPI_LOCK(GPP_F15, NONE, LOCK_CONFIG), + + PAD_CFG_GPI(GPP_D6, NONE, DEEP), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_F20, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D14, 0, DEEP), /* Enable (PWREN off) */ + PAD_CFG_GPI(GPP_H19, NONE, DEEP), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D16, 0, PLTRST), /* Enable (PWREN off) */ + PAD_CFG_GPI(GPP_D7, NONE, DEEP), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ }; +/* clang-format on */ const struct pad_config *variant_early_gpio_table(size_t *num) { @@ -22,6 +69,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num) } /* Pad configuration in ramstage. */ +/* clang-format off */ const struct pad_config gpio_table[] = { /* General Purpose I/O Deep */ PAD_CFG_NF(GPD0, NONE, DEEP, NF1), /* Battery Low */ @@ -46,19 +94,19 @@ const struct pad_config gpio_table[] = { PAD_CFG_GPI_APIC_LOW(GPP_D11, NONE, PLTRST), /* Interrupt */ /* SSD */ - PAD_CFG_NF(GPP_D6, NONE, DEEP, NF1), /* Clock Request 5 */ - PAD_CFG_GPO(GPP_F20, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D14, 1, DEEP), /* Enable */ + PAD_NC(GPP_D6, NONE), /* Clock Request 5 */ + PAD_CFG_GPO(GPP_F20, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D14, 0, DEEP), /* Enable (PWREN off) */ /* SSD 2 */ - PAD_CFG_NF(GPP_H19, NONE, DEEP, NF1), /* Clock Request 2 */ - PAD_CFG_GPO(GPP_H0, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_D16, 1, PLTRST), /* Enable */ + PAD_NC(GPP_H19, NONE), /* Clock Request 2 */ + PAD_CFG_GPO(GPP_H0, 0, PLTRST), /* Reset (PERST# asserted) */ + PAD_CFG_GPO(GPP_D16, 0, PLTRST), /* Enable (PWREN off) */ /* Wireless */ - PAD_CFG_NF(GPP_D7, NONE, DEEP, NF1), /* Clock Request 1 */ - PAD_CFG_GPO(GPP_H2, 1, PLTRST), /* Reset */ - PAD_CFG_GPO(GPP_E3, 1, DEEP), /* WiFi RF Kill */ + PAD_NC(GPP_D7, NONE), /* Clock Request 1 */ + PAD_CFG_GPO(GPP_H2, 0, PLTRST), /* Reset asserted */ + PAD_CFG_GPO(GPP_E3, 0, DEEP), /* WiFi disabled */ PAD_CFG_GPO(GPP_A13, 1, DEEP), /* Bluetooth RF Kill */ /* Display */ @@ -265,6 +313,7 @@ const struct pad_config gpio_table[] = { PAD_NC(GPP_R6, NONE), PAD_NC(GPP_R7, NONE), }; +/* clang-format on */ const struct pad_config *variant_gpio_table(size_t *num) {