]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: dwc: Use cfg0_base as iMSI-RX target address to support 32-bit MSI devices
authorShawn Lin <shawn.lin@rock-chips.com>
Wed, 24 Dec 2025 01:38:52 +0000 (09:38 +0800)
committerManivannan Sadhasivam <mani@kernel.org>
Mon, 29 Dec 2025 13:59:48 +0000 (19:29 +0530)
commit f3a296405b6e ("PCI: dwc: Strengthen the MSI address allocation
logic") strengthened the iMSI-RX target address allocation logic to handle
64-bit addresses for platforms without 32-bit DMA addresses. However, it
still left 32-bit MSI capable endpoints (EPs) non-functional on such
platforms.

Per DWC databook r6.21a, sec 3.10.2.3, it states:
"The iMSI-RX is programmed with an address (MSI_CTRL_ADDR_OFF and
MSI_CTRL_UPPER_ADDR_OFF) that is used as the system MSI address. When an
inbound MWr request is passed to the AXI bridge and matches this address
as well as the conditions specified for an MSI memory write request, an
MSI interrupt is detected. When this MWr is about to be driven onto the
AXI bridge master interface1, it is dropped and never appears on the AXI
bus."

Since iMSI-RX MSI_CTRL_ADDR doesn't require actual system memory mapping,
any 32-bit address that won't be used for BAR memory allocations can be
assigned. So assign cfg0_base to the iMSI-RX target address as the first
option if it's a 32-bit address, which satisfies this requirement.
Otherwise, fallback to the existing coherent allocation.

cc: Ajay Agarwal <ajayagarwal@google.com>
cc: Will McVicker <willmcvicker@google.com>
Signed-off-by: Shawn Lin <shawn.lin@rock-chips.com>
[mani: trimmed the description to exclude testbed info and used imperative tone]
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Link: https://patch.msgid.link/1766540332-24235-1-git-send-email-shawn.lin@rock-chips.com
drivers/pci/controller/dwc/pcie-designware-host.c

index 06c02fcc76c89483da6e7fa886b788f2f04c817d..fad0cbedefbc6eca0db1d503c2b05d275436794d 100644 (file)
@@ -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,