From 17b478b29cf15f3a96d441d5de773bfd9859b4c2 Mon Sep 17 00:00:00 2001 From: Xincheng Zhang Date: Sat, 5 Sep 2026 10:56:34 +0800 Subject: [PATCH 1/2] PCI: dwc: Allow drivers to skip MEM outbound iATU setup Some DWC-based controllers do not require outbound iATU windows for MEM transactions. For those platforms, programming outbound iATU windows for host bridge MEM ranges is unnecessary and may constrain the available MEM aperture. The DWC PCIe RP Controller Databook v6.00a, section 3.12.2, describes the default outbound no-match behavior as pass-through. Section 3.12.5.6, "No Address Match Result", says the address is not translated and programmable TLP header fields come from the application transmit interface. This no-match path cannot translate between different parent-bus and PCI addresses, so require skipped MEM ranges to be identity-mapped. Add dw_pcie_rp->bypass_ob_mem_iatu so drivers can skip generic MEM iATU setup while using the common DWC host init path. Existing drivers keep the current behavior because the flag defaults to false. The I/O iATU setup does not use the MEM resource iterator, and the iterator may be uninitialized when MEM setup is skipped. Avoid using it in the I/O iATU error path. Signed-off-by: Xincheng Zhang Signed-off-by: Manivannan Sadhasivam Link: https://patch.msgid.link/20260905025635.211390-2-zhangxincheng@ultrarisc.com --- .../pci/controller/dwc/pcie-designware-host.c | 17 +++++++++++++++-- drivers/pci/controller/dwc/pcie-designware.h | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index f5a38e6fd8d7..b06797b4e31d 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -918,6 +918,20 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp) atu.parent_bus_addr = entry->res->start - pci->parent_bus_offset; atu.pci_addr = entry->res->start - entry->offset; + if (pp->bypass_ob_mem_iatu) { + /* + * The no-match pass-through path preserves the correct + * PCI address only for identity-mapped MEM ranges. + */ + if (atu.parent_bus_addr != atu.pci_addr) { + dev_err(pci->dev, + "Cannot bypass outbound iATU for non-identity MEM range %pr\n", + entry->res); + return -EINVAL; + } + continue; + } + /* Adjust iATU size if MSG TLP region was allocated before */ if (pp->msg_res && pp->msg_res->parent == entry->res) res_size = resource_size(entry->res) - @@ -964,8 +978,7 @@ static int dw_pcie_iatu_setup(struct dw_pcie_rp *pp) ret = dw_pcie_prog_outbound_atu(pci, &atu); if (ret) { - dev_err(pci->dev, "Failed to set IO range %pr\n", - entry->res); + dev_err(pci->dev, "Failed to set IO range\n"); return ret; } ob_iatu_index++; diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 0735ae940924..d89badcca268 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -469,6 +469,7 @@ struct dw_pcie_rp { struct pci_config_window *cfg; bool ecam_enabled; bool native_ecam; + bool bypass_ob_mem_iatu; bool skip_l23_ready; bool skip_pwrctrl_off; }; From 8da2b970ed4c8188ef464cee060707f2370e015c Mon Sep 17 00:00:00 2001 From: Xincheng Zhang Date: Sat, 5 Sep 2026 10:56:35 +0800 Subject: [PATCH 2/2] PCI: ultrarisc: Skip MEM outbound iATU setup on DP1000 DP1000 has 16 outbound iATU windows and each window can map up to 4GB. One window is used for CFG accesses, one for I/O space and one for the 32-bit MEM aperture, leaving only 13 windows for the 64-bit MEM aperture. This limits the 64-bit MEM aperture that can be described with outbound iATU windows. DP1000 routes MEM transactions without using outbound iATU windows, so skip generic DWC MEM outbound iATU setup to allow a larger 64-bit MEM aperture. DP1000 does not use ECAM for this controller. Config space accesses keep using the normal DWC config access path and CFG outbound iATU programming. I/O space is also unchanged and still uses an outbound iATU window. The new flag only skips generic MEM-window programming. The DP1000 integration has SoC wrapper address decode for the PCIe MEM apertures described by the "ranges" property. CPU physical accesses to those MEM apertures are routed directly as PCIe MEM transactions with the corresponding PCIe bus address, without consuming outbound iATU windows. Set 'dw_pcie_rp->bypass_ob_mem_iatu' for this controller. Signed-off-by: Xincheng Zhang Signed-off-by: Manivannan Sadhasivam Link: https://patch.msgid.link/20260905025635.211390-3-zhangxincheng@ultrarisc.com --- drivers/pci/controller/dwc/pcie-ultrarisc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/pci/controller/dwc/pcie-ultrarisc.c b/drivers/pci/controller/dwc/pcie-ultrarisc.c index 51e89180490d..0d4989a0f3af 100644 --- a/drivers/pci/controller/dwc/pcie-ultrarisc.c +++ b/drivers/pci/controller/dwc/pcie-ultrarisc.c @@ -154,6 +154,12 @@ static int ultrarisc_pcie_probe(struct platform_device *pdev) pp = &pci->pp; + /* + * DP1000 routes MEM transactions without outbound iATU windows, which + * avoids the 16-window/4GB-per-window aperture limit. + */ + pp->bypass_ob_mem_iatu = true; + platform_set_drvdata(pdev, ultra); ret = ultrarisc_pcie_init_clks(ultra);