soc/qualcomm/common: Implement asynchronous PCIe initialization
Introduce SOC_QUALCOMM_PCIE_ASYNCHRONOUS_INIT to allow the PCIe link training to proceed without blocking the boot flow. Refactor qcom_setup_pcie_host into two logical phases: 1. Initiate: Power on endpoints and trigger LTSSM (Romstage). 2. Verify: Wait for link-up status (Ramstage). When the async Kconfig is enabled, the initiation happens in romstage, but the blocking 'wait_link_up' call is deferred to ramstage. This allows other SoC and mainboard initializations to run in between the hardware link training, reducing overall boot time. BUG=b:449871690 TEST=Verified PCIe link still enumerates correctly on Bluey with asynchronous init enabled. Change-Id: Idf368731325b5efcf4db0d1912a8c75417ef11ab Signed-off-by: Subrata Banik <subratabanik@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/91723 Reviewed-by: Kapil Porwal <kapilporwal@google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
8a90e46346
commit
f1baed6f79
2 changed files with 65 additions and 2 deletions
|
|
@ -61,4 +61,14 @@ config SOC_QUALCOMM_DEBUG_TSENS
|
|||
When enabled, a call to monitor TSENS will dump the sensor data on
|
||||
the debug console.
|
||||
|
||||
config SOC_QUALCOMM_PCIE_ASYNCHRONOUS_INIT
|
||||
bool
|
||||
default n
|
||||
help
|
||||
When enabled, qcom_setup_pcie_host will initiate the PCIe
|
||||
hardware power-up sequence but will not block the boot flow
|
||||
to wait for the link-up status. This can reduce overall
|
||||
boot time, but requires late-stage drivers to verify link
|
||||
readiness before access.
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -178,6 +178,9 @@ static enum cb_err qcom_pcie_dw_link_up(struct qcom_pcie_cntlr_t *pcie)
|
|||
/* enable link training */
|
||||
setbits32(pcie->cntlr_cfg->parf + PCIE_PARF_LTSSM, LTSSM_EN);
|
||||
|
||||
if (CONFIG(SOC_QUALCOMM_PCIE_ASYNCHRONOUS_INIT))
|
||||
return CB_SUCCESS;
|
||||
|
||||
/* Check that link was established */
|
||||
if (wait_link_up(pcie)) {
|
||||
printk(BIOS_INFO, "PCIe link is up\n");
|
||||
|
|
@ -562,8 +565,7 @@ void qcom_pci_domain_read_resources(struct device *dev)
|
|||
res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
|
||||
}
|
||||
|
||||
/* PCI domain ops enable callback */
|
||||
void qcom_setup_pcie_host(struct device *dev)
|
||||
static enum cb_err pcie_initiate_link(void)
|
||||
{
|
||||
gcom_pcie_get_config(&qcom_pcie_cfg);
|
||||
|
||||
|
|
@ -576,6 +578,57 @@ void qcom_setup_pcie_host(struct device *dev)
|
|||
qcom_pcie_configure_gpios(qcom_pcie_cfg.cntlr_cfg);
|
||||
|
||||
if (!qcom_dw_pcie_enable(&qcom_pcie_cfg))
|
||||
return CB_SUCCESS;
|
||||
else
|
||||
return CB_ERR;
|
||||
}
|
||||
|
||||
static enum cb_err pcie_verify_link_status(void)
|
||||
{
|
||||
gcom_pcie_get_config(&qcom_pcie_cfg);
|
||||
|
||||
if (is_pcie_link_up(&qcom_pcie_cfg)) {
|
||||
printk(BIOS_INFO, "PCIe Link is already up\n");
|
||||
return CB_SUCCESS;
|
||||
}
|
||||
|
||||
/* Check that link was established */
|
||||
if (wait_link_up(&qcom_pcie_cfg)) {
|
||||
printk(BIOS_INFO, "PCIe link is up\n");
|
||||
return CB_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
* Link can be established in Gen 1 as it failed to establish in Gen2.
|
||||
* So allow some time to do it.
|
||||
*/
|
||||
udelay(100);
|
||||
|
||||
return is_pcie_link_up(&qcom_pcie_cfg) ? CB_SUCCESS : CB_ERR;
|
||||
}
|
||||
|
||||
/* PCI domain ops enable callback */
|
||||
void qcom_setup_pcie_host(struct device *dev)
|
||||
{
|
||||
/* STAGE 1: Initiate Hardware (Sync or Async)
|
||||
* In Romstage (or if Async is disabled), we always start the hardware.
|
||||
*/
|
||||
if (ENV_SEPARATE_ROMSTAGE || !CONFIG(SOC_QUALCOMM_PCIE_ASYNCHRONOUS_INIT)) {
|
||||
if (pcie_initiate_link() != CB_SUCCESS) {
|
||||
printk(BIOS_EMERG, "Failed to enable PCIe\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Async in Romstage */
|
||||
if (ENV_SEPARATE_ROMSTAGE)
|
||||
return;
|
||||
}
|
||||
|
||||
/* STAGE 2: Late Check (Async only)
|
||||
* If we are in Ramstage and Async is enabled, the hardware was already
|
||||
* kicked off in Romstage. Now we just verify the result.
|
||||
*/
|
||||
if (pcie_verify_link_status() == CB_SUCCESS)
|
||||
printk(BIOS_NOTICE, "PCIe enumerated succussfully..\n");
|
||||
else
|
||||
printk(BIOS_EMERG, "Failed to enable PCIe\n");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue