]> git.itanic.dy.fi Git - linux-stable/commitdiff
PCI: dwc: Restrict only coherent DMA mask for MSI address allocation
authorSerge Semin <Sergey.Semin@baikalelectronics.ru>
Fri, 13 Jan 2023 17:14:07 +0000 (20:14 +0300)
committerBjorn Helgaas <bhelgaas@google.com>
Wed, 22 Feb 2023 19:46:14 +0000 (13:46 -0600)
The MSI target address must be in the lowest 4GB memory to support PCI
peripherals without 64-bit MSI support.  Since the allocation is done from
DMA coherent memory, set only the coherent DMA mask, leaving the streaming
DMA mask alone.

Thus streaming DMA operations will work with no artificial limitations. It
will be specifically useful for the eDMA-capable controllers so the
corresponding DMA engine clients would map the DMA buffers with no need for
SWIOTLB for buffers allocated above 4GB.

Add a brief comment about the reason allocating the MSI target address
below 4GB.

Link: https://lore.kernel.org/r/20230113171409.30470-26-Sergey.Semin@baikalelectronics.ru
Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
drivers/pci/controller/dwc/pcie-designware-host.c

index 3ab6ae3712c428a53ff0540c0998fbfc55d5cd06..14f27985055e6ec83c9531f59681b781c37d9060 100644 (file)
@@ -366,7 +366,17 @@ static int dw_pcie_msi_host_init(struct dw_pcie_rp *pp)
                                                    dw_chained_msi_isr, pp);
        }
 
-       ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
+       /*
+        * Even though the iMSI-RX Module supports 64-bit addresses some
+        * peripheral PCIe devices may lack 64-bit message support. In
+        * 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.
+        */
+       ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
        if (ret)
                dev_warn(dev, "Failed to set DMA mask to 32-bit. Devices with only 32-bit MSI support may not work properly\n");