Commit da56a1bf authored by Ajay Agarwal's avatar Ajay Agarwal Committed by Lorenzo Pieralisi

PCI: dwc: Wait for link up only if link is started

In dw_pcie_host_init() regardless of whether the link has been
started or not, the code waits for the link to come up. Even in
cases where start_link() is not defined the code ends up spinning
in a loop for 1 second. Since in some systems dw_pcie_host_init()
gets called during probe, this one second loop for each pcie
interface instance ends up extending the boot time.

Wait for the link up in only if the start_link() is defined.

Link: https://lore.kernel.org/r/20230412093425.3659088-1-ajayagarwal@google.comTested-by: default avatarWill McVicker <willmcvicker@google.com>
Signed-off-by: default avatarSajid Dalvi <sdalvi@google.com>
Signed-off-by: default avatarAjay Agarwal <ajayagarwal@google.com>
Signed-off-by: default avatarLorenzo Pieralisi <lpieralisi@kernel.org>
parent ac9a7868
...@@ -485,14 +485,19 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp) ...@@ -485,14 +485,19 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp)
if (ret) if (ret)
goto err_remove_edma; goto err_remove_edma;
if (!dw_pcie_link_up(pci)) { if (dw_pcie_link_up(pci)) {
dw_pcie_print_link_status(pci);
} else {
ret = dw_pcie_start_link(pci); ret = dw_pcie_start_link(pci);
if (ret) if (ret)
goto err_remove_edma; goto err_remove_edma;
}
/* Ignore errors, the link may come up later */ if (pci->ops && pci->ops->start_link) {
dw_pcie_wait_for_link(pci); ret = dw_pcie_wait_for_link(pci);
if (ret)
goto err_stop_link;
}
}
bridge->sysdata = pp; bridge->sysdata = pp;
......
...@@ -644,9 +644,20 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index) ...@@ -644,9 +644,20 @@ void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index)
dw_pcie_writel_atu(pci, dir, index, PCIE_ATU_REGION_CTRL2, 0); dw_pcie_writel_atu(pci, dir, index, PCIE_ATU_REGION_CTRL2, 0);
} }
int dw_pcie_wait_for_link(struct dw_pcie *pci) void dw_pcie_print_link_status(struct dw_pcie *pci)
{ {
u32 offset, val; u32 offset, val;
offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
val = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA);
dev_info(pci->dev, "PCIe Gen.%u x%u link up\n",
FIELD_GET(PCI_EXP_LNKSTA_CLS, val),
FIELD_GET(PCI_EXP_LNKSTA_NLW, val));
}
int dw_pcie_wait_for_link(struct dw_pcie *pci)
{
int retries; int retries;
/* Check if the link is up or not */ /* Check if the link is up or not */
...@@ -662,12 +673,7 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci) ...@@ -662,12 +673,7 @@ int dw_pcie_wait_for_link(struct dw_pcie *pci)
return -ETIMEDOUT; return -ETIMEDOUT;
} }
offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP); dw_pcie_print_link_status(pci);
val = dw_pcie_readw_dbi(pci, offset + PCI_EXP_LNKSTA);
dev_info(pci->dev, "PCIe Gen.%u x%u link up\n",
FIELD_GET(PCI_EXP_LNKSTA_CLS, val),
FIELD_GET(PCI_EXP_LNKSTA_NLW, val));
return 0; return 0;
} }
......
...@@ -429,6 +429,7 @@ void dw_pcie_setup(struct dw_pcie *pci); ...@@ -429,6 +429,7 @@ void dw_pcie_setup(struct dw_pcie *pci);
void dw_pcie_iatu_detect(struct dw_pcie *pci); void dw_pcie_iatu_detect(struct dw_pcie *pci);
int dw_pcie_edma_detect(struct dw_pcie *pci); int dw_pcie_edma_detect(struct dw_pcie *pci);
void dw_pcie_edma_remove(struct dw_pcie *pci); void dw_pcie_edma_remove(struct dw_pcie *pci);
void dw_pcie_print_link_status(struct dw_pcie *pci);
static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val) static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment