From f49e5048b6445524c23fc63fccc280e13c33c1d2 Mon Sep 17 00:00:00 2001 From: Daire McNamara Date: Fri, 11 Oct 2024 15:00:41 +0100 Subject: [PATCH] PCI: microchip: Fix outbound address translation tables On Microchip PolarFire SoC (MPFS) the PCIe Root Port can be behind one of three general-purpose Fabric Interface Controller (FIC) buses that encapsulate an AXI-M interface. That FIC is responsible for managing the translations of the upper 32-bits of the AXI-M address. On MPFS, the Root Port driver needs to take account of that outbound address translation done by the parent FIC bus before setting up its own outbound address translation tables. In all cases on MPFS, the remaining outbound address translation tables are 32-bit only. Limit the outbound address translation tables to 32-bit only. Fixes: 6f15a9c9f941 ("PCI: microchip: Add Microchip Polarfire PCIe controller driver") Signed-off-by: Daire McNamara Acked-by: Conor Dooley Reviewed-by: Ilpo Jarvinen Link: https://lore.kernel.org/r/20241011140043.1250030-2-daire.mcnamara@microchip.com [esmil: forward ported to 6.14] Signed-off-by: Emil Renner Berthing --- .../pci/controller/plda/pcie-microchip-host.c | 28 +++++++++++++++++-- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/pci/controller/plda/pcie-microchip-host.c b/drivers/pci/controller/plda/pcie-microchip-host.c index c92e71c1d599..437a232ae893 100644 --- a/drivers/pci/controller/plda/pcie-microchip-host.c +++ b/drivers/pci/controller/plda/pcie-microchip-host.c @@ -26,6 +26,7 @@ #include "pcie-plda.h" #define MC_MAX_NUM_INBOUND_WINDOWS 8 +#define MC_OUTBOUND_TRANS_TBL_MASK GENMASK(31, 0) #define MPFS_NC_BOUNCE_ADDR 0x80000000 /* PCIe Bridge Phy and Controller Phy offsets */ @@ -699,6 +700,27 @@ static int mc_pcie_setup_inbound_ranges(struct platform_device *pdev, return 0; } +static int mc_pcie_setup_iomems(struct pci_host_bridge *bridge, + struct plda_pcie_rp *port) +{ + void __iomem *bridge_base_addr = port->bridge_addr; + struct resource_entry *entry; + u64 pci_addr; + u32 index = 1; + + resource_list_for_each_entry(entry, &bridge->windows) { + if (resource_type(entry->res) == IORESOURCE_MEM) { + pci_addr = entry->res->start - entry->offset; + plda_pcie_setup_window(bridge_base_addr, index, + entry->res->start & MC_OUTBOUND_TRANS_TBL_MASK, + pci_addr, resource_size(entry->res)); + index++; + } + } + + return 0; +} + static int mc_platform_init(struct pci_config_window *cfg) { struct device *dev = cfg->parent; @@ -707,15 +729,15 @@ static int mc_platform_init(struct pci_config_window *cfg) int ret; /* Configure address translation table 0 for PCIe config space */ - plda_pcie_setup_window(port->bridge_base_addr, 0, cfg->res.start, - cfg->res.start, + plda_pcie_setup_window(port->bridge_base_addr, 0, + cfg->res.start & MC_OUTBOUND_TRANS_TBL_MASK, 0, resource_size(&cfg->res)); /* Need some fixups in config space */ mc_pcie_enable_msi(port, cfg->win); /* Configure non-config space outbound ranges */ - ret = plda_pcie_setup_iomems(bridge, &port->plda); + ret = mc_pcie_setup_iomems(bridge, &port->plda); if (ret) return ret; -- 2.43.0