mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
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 <zhangxincheng@ultrarisc.com> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com> Link: https://patch.msgid.link/20260905025635.211390-2-zhangxincheng@ultrarisc.com
This commit is contained in:
parent
cee9395acd
commit
17b478b29c
|
|
@ -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++;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user