mb/google/fatcat: Add x1 slot power sequence and support AICs with PRSNT2#
Address x1 slot enumeration issues for certain add in cards (AICs)
during boot. This change implements proper power sequencing and adds
support for AICs that use PRSNT2# signaling instead of ClkReq#. The
x1 slot power rail (X1_PCIE_SLOT_PWR_EN via GPP_A8) is pull-high by
design, with GPP_A08 PAD defaulting to GPI configuration. This enables
slot power during early boot phases. PERST# (GPP_D19) is logically
ANDed with PLTRST#, ensuring PLTRST# de-assertion occurs only after x1
slot power stabilization, maintaining proper PCIe timing automatically.
For scenarios requiring power-off at boot, the following sequence
ensures compliance with PCIe link training timing requirements:
Step 1 (romstage): ClkReq PAD off; PERST# asserted; power off
Step 2 (ramstage at BS_PRE_DEVICE exit): Power on; ClkReq PAD on (if
used)
Step 3 (ramstage at BS_DEV_INIT_CHIPS entry): PERST# de-asserted
The CBI fw_config SD field has been redefined to accommodate different
AIC types:
- SD_BAYHUB: For AICs supporting ClkReq# signaling
- SD_GENSYS: For AICs using only PRSNT2# signaling
BUG=None
TEST=Boot Fatcat board with AIC cards configured via CBI fw_config SD
field (SD_BAYHUB or SD_GENSYS). Confirm PCIe device enumeration
appears correctly in boot log. For instance:
[SPEW ] do_pci_scan_bridge for PCI: 00:00:1c.0
[DEBUG] PCI: pci_scan_bus for segment group 00 bus ae
[DEBUG] PCI: 00:ae:00.0 [1217/9860] enabled
The device should be seen from lspci command, such as:
ae:00.0 Class 0805: Device 1217:9860 (rev 01)
Signed-off-by: Cliff Huang <cliff.huang@intel.com>
Change-Id: I94a7ee2ecd8d3fd83006297ef68f97ff49e47595
Reviewed-on: https://review.coreboot.org/c/coreboot/+/90000
Reviewed-by: Pranava Y N <pranavayn@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
9702010123
commit
59593b5b5c
6 changed files with 103 additions and 11 deletions
|
|
@ -62,6 +62,18 @@ static void mainboard_early(void *unused)
|
|||
|
||||
BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_EXIT, mainboard_early, NULL);
|
||||
|
||||
void __weak fw_config_post_gpio_configure(void)
|
||||
{
|
||||
/* default implementation does nothing */
|
||||
}
|
||||
|
||||
static void mainboard_pre_dev_init_chips(void *unused)
|
||||
{
|
||||
fw_config_post_gpio_configure();
|
||||
}
|
||||
|
||||
BOOT_STATE_INIT_ENTRY(BS_DEV_INIT_CHIPS, BS_ON_ENTRY, mainboard_pre_dev_init_chips, NULL);
|
||||
|
||||
void __weak baseboard_devtree_update(void)
|
||||
{
|
||||
/* Override dev tree settings per baseboard */
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ const struct pad_config *variant_early_gpio_table(size_t *num);
|
|||
const struct pad_config *variant_romstage_gpio_table(size_t *num);
|
||||
void fw_config_configure_pre_mem_gpio(void);
|
||||
void fw_config_gpio_padbased_override(struct pad_config *padbased_table);
|
||||
void fw_config_post_gpio_configure(void);
|
||||
|
||||
const struct mb_cfg *variant_memory_params(void);
|
||||
void variant_get_spd_info(struct mem_spd *spd_info);
|
||||
|
|
|
|||
|
|
@ -168,20 +168,70 @@ static const struct pad_config audio_disable_pads[] = {
|
|||
PAD_NC(GPP_D17, NONE),
|
||||
};
|
||||
|
||||
/*
|
||||
* NOTE: The PCIe slot power PADs are pulled high by default on Fatcat. Since
|
||||
* these PADs default to GPI configuration, slot power is enabled during early
|
||||
* boot. Also, PERST# PADs are logically ANDed with PLTRST#. This ensures that
|
||||
* PLTRST# de-assertion at the slot occurs after PCIe slot power stabilization,
|
||||
* maintaining proper PCIe power-on sequences.
|
||||
*
|
||||
* If slot power must be disabled at boot, PERST# de-assertion must occur after
|
||||
* power restoration and satisfy PCIe link training timing requirements.
|
||||
* Additionally, the slot power PADs are recommended to be reworked to pull low
|
||||
* to avoid a power glitch. The suggested power sequence is:
|
||||
*
|
||||
* Step 1 (romstage): ClkReq PAD off; PERST# asserted; power off
|
||||
* Step 2 (ramstage at BS_PRE_DEVICE exit): Power on; ClkReq PAD on (if used)
|
||||
* Step 3 (ramstage at BS_DEV_INIT_CHIPS entry): PERST# de-asserted
|
||||
*/
|
||||
|
||||
/* x1 slot power sequence: 1. no clkreq; PERST=asserted; power=off */
|
||||
static const struct pad_config pre_mem_x1slot_pads[] = {
|
||||
/* GPP_C11: CLKREQ2_X1_GEN4_DT_CEM_SLOT_N */
|
||||
PAD_CFG_GPI(GPP_C11, NONE, DEEP),
|
||||
/* GPP_D19: X1_DT_PCIE_RST_N */
|
||||
PAD_CFG_GPO(GPP_D19, 0, PLTRST),
|
||||
/* GPP_A08: X1_PCIE_SLOT_PWR_EN */
|
||||
PAD_CFG_GPO(GPP_A08, 0, PLTRST),
|
||||
};
|
||||
|
||||
/* x1 slot CBI + x1 slot power sequence: 2. power=on */
|
||||
static const struct pad_config x1slot_pads[] = {
|
||||
/* GPP_A08: X1_PCIE_SLOT_PWR_EN */
|
||||
PAD_CFG_GPO(GPP_A08, 1, PLTRST),
|
||||
/* GPP_D19: X1_DT_PCIE_RST_N */
|
||||
PAD_CFG_GPO(GPP_D19, 1, PLTRST),
|
||||
PAD_CFG_GPO(GPP_D19, 0, PLTRST),
|
||||
/* GPP_B25: X1_SLOT_WAKE_N */
|
||||
PAD_CFG_GPI_SCI_LOW(GPP_B25, NONE, DEEP, LEVEL),
|
||||
};
|
||||
|
||||
/*
|
||||
* x1 slot power sequence: 3. PERST# = de-assert;
|
||||
*/
|
||||
static const struct pad_config post_x1slot_pads[] = {
|
||||
/* GPP_D19: X1_DT_PCIE_RST_N */
|
||||
PAD_CFG_GPO(GPP_D19, 1, PLTRST),
|
||||
};
|
||||
|
||||
static const struct pad_config x1slot_clkreq_pads[] = {
|
||||
/* x1 slot power sequence: 3a. Clkreq = enable for AIC with clkreq support */
|
||||
/* GPP_C11: CLKREQ2_X1_GEN4_DT_CEM_SLOT_N */
|
||||
PAD_CFG_NF(GPP_C11, NONE, DEEP, NF1),
|
||||
};
|
||||
|
||||
static const struct pad_config x1slot_prsnt_pads[] = {
|
||||
/* x1 slot power sequence: 3b. clkreq = GPI or NC for AIC using PRSNT2# */
|
||||
/* GPP_C11: for PRSNT2_X1_GEN4_DT_CEM_SLOT_N */
|
||||
PAD_CFG_GPI(GPP_C11, NONE, DEEP),
|
||||
};
|
||||
|
||||
static const struct pad_config x1slot_disable_pads[] = {
|
||||
/* GPP_A08: X1_PCIE_SLOT_PWR_EN */
|
||||
PAD_CFG_GPO(GPP_A08, 0, PLTRST),
|
||||
PAD_CFG_GPO(GPP_A08, 1, PLTRST),
|
||||
/* GPP_D19: X1_DT_PCIE_RST_N */
|
||||
PAD_NC(GPP_D19, NONE),
|
||||
/* GPP_C11: CLKREQ2_X1_GEN4_DT_CEM_SLOT_N */
|
||||
PAD_NC(GPP_C11, NONE),
|
||||
/* GPP_B25: X1_SLOT_WAKE_N */
|
||||
PAD_NC(GPP_B25, NONE)
|
||||
};
|
||||
|
|
@ -579,6 +629,9 @@ void fw_config_configure_pre_mem_gpio(void)
|
|||
GPIO_CONFIGURE_PADS(pre_mem_gen5_ssd_pwr_pads);
|
||||
}
|
||||
|
||||
if (!fw_config_probe(FW_CONFIG(SD, SD_NONE)))
|
||||
GPIO_CONFIGURE_PADS(pre_mem_x1slot_pads);
|
||||
|
||||
/*
|
||||
* NOTE: We place WWAN sequence 2 here. According to the WWAN FIBOCOM
|
||||
* FM350-GL datasheet, the minimum time requirement (Tpr: time between 3.3V
|
||||
|
|
@ -661,10 +714,15 @@ void fw_config_gpio_padbased_override(struct pad_config *padbased_table)
|
|||
GPIO_PADBASED_OVERRIDE(padbased_table, wwan_disable_pads);
|
||||
}
|
||||
|
||||
if (fw_config_probe(FW_CONFIG(SD, SD_NONE)))
|
||||
GPIO_PADBASED_OVERRIDE(padbased_table, x1slot_disable_pads);
|
||||
else
|
||||
if (fw_config_probe(FW_CONFIG(SD, SD_GENSYS))) {
|
||||
GPIO_PADBASED_OVERRIDE(padbased_table, x1slot_pads);
|
||||
GPIO_PADBASED_OVERRIDE(padbased_table, x1slot_prsnt_pads);
|
||||
} else if (fw_config_probe(FW_CONFIG(SD, SD_BAYHUB))) {
|
||||
GPIO_PADBASED_OVERRIDE(padbased_table, x1slot_pads);
|
||||
GPIO_PADBASED_OVERRIDE(padbased_table, x1slot_clkreq_pads);
|
||||
} else {
|
||||
GPIO_PADBASED_OVERRIDE(padbased_table, x1slot_disable_pads);
|
||||
}
|
||||
|
||||
if (fw_config_probe(FW_CONFIG(TOUCHPAD, TOUCHPAD_LPSS_I2C))) {
|
||||
GPIO_PADBASED_OVERRIDE(padbased_table, touchpad_lpss_i2c_enable_pads);
|
||||
|
|
@ -727,3 +785,9 @@ void fw_config_gpio_padbased_override(struct pad_config *padbased_table)
|
|||
GPIO_PADBASED_OVERRIDE(padbased_table, fp_disable_pads);
|
||||
}
|
||||
}
|
||||
|
||||
void fw_config_post_gpio_configure(void)
|
||||
{
|
||||
if (!fw_config_probe(FW_CONFIG(SD, SD_NONE)))
|
||||
GPIO_CONFIGURE_PADS(post_x1slot_pads);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ static const struct pad_config gpio_table[] = {
|
|||
/* GPP_A06: ESPI_RST_EC_R_N */
|
||||
/* GPP_A06 : GPP_A06 ==> ESPI_RST_HDR configured on reset, do not touch */
|
||||
|
||||
/* GPP_A08: X1_PCIE_SLOT_PWR_EN */
|
||||
/* NOTE: x1 slot power will be updated according to SD fw_config */
|
||||
/* GPP_A09: M.2_WWAN_FCP_OFF_N */
|
||||
PAD_CFG_GPO(GPP_A09, 1, PLTRST),
|
||||
/* GPP_A10: M.2_WWAN_DISABLE_N */
|
||||
|
|
@ -81,7 +83,8 @@ static const struct pad_config gpio_table[] = {
|
|||
PAD_CFG_GPO(GPP_B21, 0, DEEP),
|
||||
/* GPP_B24: ESPI_ALERT0_EC_R_N */
|
||||
PAD_NC(GPP_B24, NONE),
|
||||
|
||||
/* GPP_B25: X1_SLOT_WAKE_N */
|
||||
/* NOTE: x1 slot wake will be overridden according to SD fw_config */
|
||||
/* GPP_C00: GPP_C0_SMBCLK */
|
||||
PAD_CFG_NF(GPP_C00, NONE, DEEP, NF1),
|
||||
/* GPP_C01: GPP_C1_SMBDATA */
|
||||
|
|
@ -101,7 +104,7 @@ static const struct pad_config gpio_table[] = {
|
|||
/* GPP_C10: CLKREQ1_X4_GEN5_M2_SSD_N */
|
||||
PAD_CFG_NF(GPP_C10, NONE, DEEP, NF1),
|
||||
/* GPP_C11: CLKREQ2_X1_GEN4_DT_CEM_SLOT_N */
|
||||
PAD_CFG_NF(GPP_C11, NONE, DEEP, NF1),
|
||||
/* NOTE: x1 slot clkreq will be overridden according to SD fw_config */
|
||||
/* GPP_C12: CLKREQ3_X1_GEN1_GBE_LAN_N */
|
||||
PAD_CFG_NF(GPP_C12, NONE, DEEP, NF1),
|
||||
/* GPP_C13: CLKREQ4_X1_GEN4_M2_WLAN_N */
|
||||
|
|
@ -159,6 +162,8 @@ static const struct pad_config gpio_table[] = {
|
|||
PAD_CFG_NF(GPP_D17, NONE, DEEP, NF1),
|
||||
/* GPP_D18: CLKREQ6_X4_GEN4_M2_SSD_N */
|
||||
PAD_CFG_NF(GPP_D18, NONE, DEEP, NF1),
|
||||
/* GPP_D19: X1_DT_PCIE_RST_N */
|
||||
/* NOTE: X1 PERST will follow power sequence according to SD fw_config */
|
||||
/* GPP_D20: CSE_EARLY_SW */
|
||||
PAD_CFG_GPI_SCI_HIGH(GPP_D20, NONE, DEEP, LEVEL),
|
||||
/* GPP_D21: NC */
|
||||
|
|
@ -363,8 +368,6 @@ static const struct pad_config early_gpio_table[] = {
|
|||
|
||||
/* Pad configuration in romstage */
|
||||
static const struct pad_config romstage_gpio_table[] = {
|
||||
/* GPP_A08: X1_PCIE_SLOT_PWR_EN */
|
||||
PAD_CFG_GPO(GPP_A08, 0, PLTRST),
|
||||
/* GPP_C00: GPP_C0_SMBCLK */
|
||||
PAD_CFG_NF(GPP_C00, NONE, DEEP, NF1),
|
||||
/* GPP_C01: GPP_C1_SMBDATA */
|
||||
|
|
|
|||
|
|
@ -36,8 +36,8 @@ fw_config
|
|||
end
|
||||
field SD 13 14
|
||||
option SD_NONE 0
|
||||
option SD_GENSYS 1
|
||||
option SD_BAYHUB 2
|
||||
option SD_GENSYS 1 # use pin B17 as PRSNT2#
|
||||
option SD_BAYHUB 2 # use pin B17 as ClkReq#
|
||||
end
|
||||
field STORAGE 15 16
|
||||
option STORAGE_UNKNOWN 0
|
||||
|
|
@ -602,6 +602,10 @@ chip soc/intel/pantherlake
|
|||
register "pcie_rp[PCIE_RP(3)]" = "{
|
||||
.clk_src = 2,
|
||||
.clk_req = 2,
|
||||
/*
|
||||
* NOTE: The clock usage flag is changed to
|
||||
* PCIE_RP_CLK_REQ_UNUSED in variant.c when PRSNT#2 is used.
|
||||
*/
|
||||
.flags = PCIE_RP_CLK_REQ_DETECT | PCIE_RP_LTR | PCIE_RP_AER,
|
||||
}"
|
||||
chip soc/intel/common/block/pcie/rtd3
|
||||
|
|
|
|||
|
|
@ -75,6 +75,14 @@ void variant_update_soc_chip_config(struct soc_intel_pantherlake_config *config)
|
|||
*/
|
||||
config->thc_mode[0] = THC_HID_I2C_MODE;
|
||||
}
|
||||
|
||||
/* x1 Slot */
|
||||
if (fw_config_probe(FW_CONFIG(SD, SD_GENSYS))) {
|
||||
uint8_t flags = config->pcie_rp[PCIE_RP(3)].flags;
|
||||
flags &= ~(PCIE_RP_CLK_REQ_DETECT | PCIE_RP_CLK_REQ_UNUSED);
|
||||
flags |= PCIE_RP_CLK_SRC_UNUSED;
|
||||
config->pcie_rp[PCIE_RP(3)].flags = flags;
|
||||
}
|
||||
}
|
||||
|
||||
void variant_update_soc_memory_init_params(FSPM_UPD *memupd)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue