summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-host.c16
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,