dw_pcie_ep_init() no longer caches the offset automatically. For qcom-ep,
hardware (clocks, PHY) is enabled only after PERST# deassert. Therefore,
we must call dw_pcie_get_pcie_cap() in qcom_pcie_perst_deassert() after
the resources are enabled, before any DBI access. This ensures the cached
offset is valid for subsequent uses in interrupt handlers and ICC updates.

Signed-off-by: Hans Zhang <[email protected]>
---
In pcie-qcom-ep, dw_pcie_find_capability() appears in:

  qcom_pcie_ep_probe()
    -> dw_pcie_ep_init()
    -> qcom_pcie_ep_enable_irq_resources()
      -> qcom_pcie_ep_global_irq_thread()
        -> qcom_pcie_ep_icc_update()
          -> dw_pcie_find_capability()
        -> qcom_pcie_ep_perst_irq_thread()
          -> qcom_pcie_perst_deassert()
            -> offset = dw_pcie_find_capability()  (called twice)
---
 drivers/pci/controller/dwc/pcie-qcom-ep.c | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c 
b/drivers/pci/controller/dwc/pcie-qcom-ep.c
index 56184e6ca6e6..16b0891f9571 100644
--- a/drivers/pci/controller/dwc/pcie-qcom-ep.c
+++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c
@@ -307,15 +307,13 @@ static void qcom_pcie_dw_write_dbi2(struct dw_pcie *pci, 
void __iomem *base,
 static void qcom_pcie_ep_icc_update(struct qcom_pcie_ep *pcie_ep)
 {
        struct dw_pcie *pci = &pcie_ep->pci;
-       u32 offset, status;
-       int speed, width;
-       int ret;
+       int speed, width, ret;
+       u32 status;
 
        if (!pcie_ep->icc_mem)
                return;
 
-       offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
-       status = readw(pci->dbi_base + offset + PCI_EXP_LNKSTA);
+       status = readw(pci->dbi_base + pci->pcie_cap + PCI_EXP_LNKSTA);
 
        speed = FIELD_GET(PCI_EXP_LNKSTA_CLS, status);
        width = FIELD_GET(PCI_EXP_LNKSTA_NLW, status);
@@ -491,14 +489,15 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci)
 
        dw_pcie_dbi_ro_wr_en(pci);
 
+       dw_pcie_get_pcie_cap(pci);
+
        /* Set the L0s Exit Latency to 2us-4us = 0x6 */
-       offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
+       offset = pci->pcie_cap;
        val = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
        FIELD_MODIFY(PCI_EXP_LNKCAP_L0SEL, &val, 0x6);
        dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, val);
 
        /* Set the L1 Exit Latency to be 32us-64 us = 0x6 */
-       offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
        val = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
        FIELD_MODIFY(PCI_EXP_LNKCAP_L1EL, &val, 0x6);
        dw_pcie_writel_dbi(pci, offset + PCI_EXP_LNKCAP, val);
-- 
2.34.1


Reply via email to