Linux PCI subsystem development
 help / color / mirror / Atom feed
* [PATCH v2 00/16] PCI: dwc: Cache PCIe capability offset and simplify drivers
@ 2026-05-30 15:30 Hans Zhang
  2026-05-30 15:30 ` [PATCH v2 01/16] PCI: dwc: Add pcie_cap field and helper in designware header Hans Zhang
                   ` (15 more replies)
  0 siblings, 16 replies; 27+ messages in thread
From: Hans Zhang @ 2026-05-30 15:30 UTC (permalink / raw)
  To: bhelgaas, lpieralisi, kwilczynski, mani, s-vadapalli, a-garg7
  Cc: robh, linux-pci, linux-kernel, Hans Zhang

Hi,

The DWC PCIe core and its many platform drivers repeatedly call
dw_pcie_find_capability(pci, PCI_CAP_ID_EXP) to obtain the offset of the
PCI Express Capability structure. This is wasteful and makes the code
verbose. Some drivers even search for the offset in suspend/resume paths.

Add a cached pcie_cap field in struct dw_pcie and a helper
dw_pcie_get_pcie_cap() to initialize it once at the point when the
hardware is ready. Then replace all explicit capability searches with
the cached value across the entire dwc subtree.

**Safety analysis: DBI access timing**
The PCIe Capability offset is read from DBI configuration space. DBI
registers are only accessible after the controller's clocks, resets, and
power are enabled. The following call graph demonstrates that all
dw_pcie_find_capability() replacements occur only after hardware is ready:

- For Root Complex mode:
  dw_pcie_host_init()
    ...
    if (pp->ops->init)
      pp->ops->init   [enables clocks/resets]
    dw_pcie_get_pcie_cap()   [caches offset]
    ...
    dw_pcie_link_up
      pci->ops->link_up
    ...
    dw_pcie_start_link
      pci->ops->start_link
    ...
    pci_host_probe
    if (pp->ops->post_init)
      pp->ops->post_init
    ...

- For Endpoint mode:
  dw_pcie_ep_init()
    ep->ops->pre_init()    [enables clocks/resets]
    dw_pcie_get_pcie_cap()   [caches offset]
    dw_pcie_ep_init_non_sticky_registers() etc.

- Some platform drivers (e.g., layerscape-ep, tegra194) need the offset
  before calling dw_pcie_ep_init() / dw_pcie_host_init(). They already
  enable hardware themselves and explicitly call dw_pcie_get_pcie_cap()
  before the core caches it. This is safe and ensures the cached value is
  available for all later users.

Thus, no DBI access occurs before hardware is operational.

Changes in v2:
- Move dw_pcie_get_pcie_cap() from the beginning of dw_pcie_host_init()
  and dw_pcie_ep_init() to after the hardware initialization callbacks
  (host_init/pre_init). This can prevent the reading of DBI when the clock
  is turned off or when the hardware is not ready.
- Convert all platform drivers to use the cached offset via
  dw_pcie_get_pcie_cap() or directly pci->pcie_cap where safe.
- Fix type mismatches (u16 -> u8).
- Properly split per-driver modifications.

v1:
https://patchwork.kernel.org/project/linux-pci/cover/20260509135152.2241235-1-18255117159@163.com/

---
**Why splitting into per-driver patches**  
To facilitate review and potential bisection, each platform driver is
modified in its own patch. The core changes are in patches 1-2, and
follow-up patches convert individual glue drivers. If maintainers prefer
to squash them, please let me know and I will merge in v3.

This splitting patch of each controller was carried out solely for
the convenience of code review.
---

Hans Zhang (16):
  PCI: dwc: Add pcie_cap field and helper in designware header
  PCI: dwc: Use cached PCIe capability offset in core
  PCI: dwc: imx6: Use cached PCIe capability offset
  PCI: dwc: layerscape-ep: Use cached PCIe capability offset
  PCI: dwc: meson: Use cached PCIe capability offset
  PCI: dwc: rockchip: Use cached PCIe capability offset
  PCI: dwc: eswin: Use cached PCIe capability offset
  PCI: dwc: fu740: Use cached PCIe capability offset
  PCI: dwc: intel-gw: Use cached PCIe capability offset
  PCI: dwc: qcom-ep: Use cached PCIe capability offset
  PCI: dwc: qcom: Use cached PCIe capability offset
  PCI: dwc: sophgo: Use cached PCIe capability offset
  PCI: dwc: spacemit-k1: Use cached PCIe capability offset
  PCI: dwc: spear13xx: Use cached PCIe capability offset
  PCI: dwc: tegra194: Use cached PCIe capability offset
  PCI: dwc: ultrarisc: Use cached PCIe capability offset

 drivers/pci/controller/dwc/pci-imx6.c         |  6 +++---
 .../pci/controller/dwc/pci-layerscape-ep.c    |  9 +++-----
 drivers/pci/controller/dwc/pci-meson.c        |  4 ++--
 .../pci/controller/dwc/pcie-designware-ep.c   |  4 +++-
 .../pci/controller/dwc/pcie-designware-host.c |  2 ++
 drivers/pci/controller/dwc/pcie-designware.c  | 16 ++++++--------
 drivers/pci/controller/dwc/pcie-designware.h  | 17 +++++++++++++++
 drivers/pci/controller/dwc/pcie-dw-rockchip.c |  2 +-
 drivers/pci/controller/dwc/pcie-eswin.c       |  3 +--
 drivers/pci/controller/dwc/pcie-fu740.c       |  2 +-
 drivers/pci/controller/dwc/pcie-intel-gw.c    |  2 +-
 drivers/pci/controller/dwc/pcie-qcom-ep.c     | 11 ++++------
 drivers/pci/controller/dwc/pcie-qcom.c        | 21 ++++++++-----------
 drivers/pci/controller/dwc/pcie-sophgo.c      |  5 +++--
 drivers/pci/controller/dwc/pcie-spacemit-k1.c |  2 +-
 drivers/pci/controller/dwc/pcie-spear13xx.c   |  2 +-
 drivers/pci/controller/dwc/pcie-tegra194.c    |  6 ++----
 drivers/pci/controller/dwc/pcie-ultrarisc.c   |  2 +-
 18 files changed, 61 insertions(+), 55 deletions(-)


base-commit: 3a97877d13e1a29c50ab15ed0a0aba87b75061dd
-- 
2.34.1


^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2026-06-01 17:11 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-30 15:30 [PATCH v2 00/16] PCI: dwc: Cache PCIe capability offset and simplify drivers Hans Zhang
2026-05-30 15:30 ` [PATCH v2 01/16] PCI: dwc: Add pcie_cap field and helper in designware header Hans Zhang
2026-05-30 15:30 ` [PATCH v2 02/16] PCI: dwc: Use cached PCIe capability offset in core Hans Zhang
2026-05-30 16:11   ` sashiko-bot
2026-05-30 15:30 ` [PATCH v2 03/16] PCI: dwc: imx6: Use cached PCIe capability offset Hans Zhang
2026-05-30 15:30 ` [PATCH v2 04/16] PCI: dwc: layerscape-ep: " Hans Zhang
2026-05-30 16:04   ` sashiko-bot
2026-05-30 15:30 ` [PATCH v2 05/16] PCI: dwc: meson: " Hans Zhang
2026-05-30 15:30 ` [PATCH v2 06/16] PCI: dwc: rockchip: " Hans Zhang
2026-05-30 16:01   ` sashiko-bot
2026-06-01 17:11   ` Sebastian Reichel
2026-05-30 15:30 ` [PATCH v2 07/16] PCI: dwc: eswin: " Hans Zhang
2026-05-30 15:30 ` [PATCH v2 08/16] PCI: dwc: fu740: " Hans Zhang
2026-05-30 15:30 ` [PATCH v2 09/16] PCI: dwc: intel-gw: " Hans Zhang
2026-05-30 16:04   ` sashiko-bot
2026-05-30 15:30 ` [PATCH v2 10/16] PCI: dwc: qcom-ep: " Hans Zhang
2026-05-30 16:08   ` sashiko-bot
2026-05-30 15:30 ` [PATCH v2 11/16] PCI: dwc: qcom: " Hans Zhang
2026-05-30 16:06   ` sashiko-bot
2026-05-30 15:30 ` [PATCH v2 12/16] PCI: dwc: sophgo: " Hans Zhang
2026-05-30 16:25   ` sashiko-bot
2026-05-30 15:30 ` [PATCH v2 13/16] PCI: dwc: spacemit-k1: " Hans Zhang
2026-05-30 15:30 ` [PATCH v2 14/16] PCI: dwc: spear13xx: " Hans Zhang
2026-05-30 16:06   ` sashiko-bot
2026-05-30 15:31 ` [PATCH v2 15/16] PCI: dwc: tegra194: " Hans Zhang
2026-05-30 16:06   ` sashiko-bot
2026-05-30 15:31 ` [PATCH v2 16/16] PCI: dwc: ultrarisc: " Hans Zhang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox