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 <sean@starlabs.systems>
Change-Id: Ic34e9e755e167e301348fbe7c75649401300f53b
Reviewed-on: https://review.coreboot.org/c/coreboot/+/90974
Reviewed-by: Matt DeVillier <matt.devillier@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
0306eb0723
commit
279406cd14
4 changed files with 120 additions and 22 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <bootstate.h>
|
||||
#include <device/device.h>
|
||||
#include <soc/ramstage.h>
|
||||
#include <variants.h>
|
||||
|
||||
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 = {};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,42 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <variants.h>
|
||||
#include <common/nvme_seq.h>
|
||||
|
||||
#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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,8 +1,44 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#include <variants.h>
|
||||
#include <common/nvme_seq.h>
|
||||
|
||||
#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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue