Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

PCI: dwc: Use cfg0_base as iMSI-RX target address to support 32-bit MSI devices

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

authored by

Shawn Lin and committed by
Manivannan Sadhasivam
68ac85fb 8719c64e

+13 -3
+13 -3
drivers/pci/controller/dwc/pcie-designware-host.c
··· 367 367 * order not to miss MSI TLPs from those devices the MSI target 368 368 * address has to be within the lowest 4GB. 369 369 * 370 - * Note until there is a better alternative found the reservation is 371 - * done by allocating from the artificially limited DMA-coherent 372 - * memory. 370 + * Per DWC databook r6.21a, section 3.10.2.3, the incoming MWr TLP 371 + * targeting the MSI_CTRL_ADDR is terminated by the iMSI-RX and never 372 + * appears on the AXI bus. So MSI_CTRL_ADDR address doesn't need to be 373 + * mapped and can be any memory that doesn't get allocated for the BAR 374 + * memory. Since most of the platforms provide 32-bit address for 375 + * 'config' region, try cfg0_base as the first option for the MSI target 376 + * address if it's a 32-bit address. Otherwise, try 32-bit and 64-bit 377 + * coherent memory allocation one by one. 373 378 */ 379 + if (!(pp->cfg0_base & GENMASK_ULL(63, 32))) { 380 + pp->msi_data = pp->cfg0_base; 381 + return 0; 382 + } 383 + 374 384 ret = dma_set_coherent_mask(dev, DMA_BIT_MASK(32)); 375 385 if (!ret) 376 386 msi_vaddr = dmam_alloc_coherent(dev, sizeof(u64), &pp->msi_data,