pci_auto: Downgrade prefetch if necessary
authorPatrick Rudolph <patrick.rudolph@9elements.com>
Wed, 26 Feb 2025 13:56:42 +0000 (14:56 +0100)
committerTom Rini <trini@konsulko.com>
Wed, 12 Mar 2025 16:23:59 +0000 (10:23 -0600)
Legacy PCI devices, like qemu's Bochs VGA device, are allowed to have
prefetchable 32-bit BARs, while PCIe devices are not allowed to have
32-bit prefetchable BARs. Typically prefetchable BARs are 64-bit and
typically the prefetch MMIO window is also 64-bit and placed above
4GiB, as it's the case on qemu sbsa-ref.

Currently the U-Boot code assumes that prefetchable BARs are
64-bit BARs and always tries to assign them into the prefetch
MMIO window.

When a 32-bit BAR is marked as prefetch, but the prefetch area is
not within the first 4GiB of the address space, then downgrade the
BAR and place it in the non-prefetch MMIO window.

For prefetch BARs there's no downside on being placed in non prefetch
MMIO areas, besides the possible slower performance when a driver tries
to map it Write-Combine.

TEST: Fixes pci_auto on QEMU sbsa-ref fails to autoconfigure BAR0.

Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
drivers/pci/pci_auto.c

index 90f8188..e68e31a 100644 (file)
@@ -107,7 +107,8 @@ static void dm_pciauto_setup_device(struct udevice *dev,
                        }
 
                        if (prefetch &&
-                           (bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH))
+                           (bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH) &&
+                           (found_mem64 || prefetch->bus_lower < 0x100000000ULL))
                                bar_res = prefetch;
                        else
                                bar_res = mem;