diff options
| -rw-r--r-- | drivers/pci/controller/dwc/pcie-designware-host.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 06c02fcc76c8..fad0cbedefbc 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -367,10 +367,20 @@ int dw_pcie_msi_host_init(struct dw_pcie_rp *pp) * order not to miss MSI TLPs from those devices the MSI target * address has to be within the lowest 4GB. * - * Note until there is a better alternative found the reservation is - * done by allocating from the artificially limited DMA-coherent - * memory. + * Per DWC databook r6.21a, section 3.10.2.3, the incoming MWr TLP + * targeting the MSI_CTRL_ADDR is terminated by the iMSI-RX and never + * appears on the AXI bus. So MSI_CTRL_ADDR address doesn't need to be + * mapped and can be any memory that doesn't get allocated for the BAR + * memory. Since most of the platforms provide 32-bit address for + * 'config' region, try cfg0_base as the first option for the MSI target + * address if it's a 32-bit address. Otherwise, try 32-bit and 64-bit + * coherent memory allocation one by one. */ + if (!(pp->cfg0_base & GENMASK_ULL(63, 32))) { + pp->msi_data = pp->cfg0_base; + return 0; + } + ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); if (!ret) msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &pp->msi_data, |
