From 1f56aa1d73eb5c840a8f6e3bd413f09c9042541b Mon Sep 17 00:00:00 2001 From: Manikanta Maddireddy Date: Mon, 25 Nov 2024 23:46:04 +0530 Subject: [PATCH] PCI: tegra264: Add IO BAR support PCI supports IO BAR with 32-bit address, however XAL HW module provide a way to use 64-bit MMIO address as a CPU address and a 32-bit PCI address for IO BAR. Program 64-bit MMIO address in XAL registers, when sending the TLP over the bus, XAL truncates it to 32-bit address. Bug 4883004 Signed-off-by: Manikanta Maddireddy Change-Id: Idf2fdfa9d345ae7d0630d4ab9b1074422a9f68f4 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/3256977 Reviewed-by: Ankit Patel (SW-TEGRA) Tested-by: Ankit Patel (SW-TEGRA) Reviewed-by: Bibek Basu Reviewed-by: mobile promotions Tested-by: mobile promotions GVS: buildbot_gerritrpt --- .../controller/private-soc/pcie-tegra264.c | 32 +++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/drivers/pci/controller/private-soc/pcie-tegra264.c b/drivers/pci/controller/private-soc/pcie-tegra264.c index f4292cf1..552d7ad2 100644 --- a/drivers/pci/controller/private-soc/pcie-tegra264.c +++ b/drivers/pci/controller/private-soc/pcie-tegra264.c @@ -34,6 +34,10 @@ extern int of_get_pci_domain_nr(struct device_node *node); #define PCIE_LINK_UP_TIMEOUT 1000000 /* 1 s */ /* XAL registers */ +#define XAL_RC_IO_BASE_HI 0xc +#define XAL_RC_IO_BASE_LO 0x10 +#define XAL_RC_IO_LIMIT_HI 0x14 +#define XAL_RC_IO_LIMIT_LO 0x18 #define XAL_RC_MEM_32BIT_BASE_HI 0x1c #define XAL_RC_MEM_32BIT_BASE_LO 0x20 #define XAL_RC_MEM_32BIT_LIMIT_HI 0x24 @@ -70,6 +74,8 @@ struct tegra264_pcie { u64 prefetch_mem_limit; u64 mem_base; u64 mem_limit; + u64 io_base; + u64 io_limit; u32 ctl_id; struct tegra_bpmp *bpmp; bool link_state; @@ -137,6 +143,12 @@ static void tegra264_pcie_init(struct tegra264_pcie *pcie) u32 val; /* Program XAL */ + writel(upper_32_bits(pcie->io_base), pcie->xal_base + XAL_RC_IO_BASE_HI); + writel(lower_32_bits(pcie->io_base), pcie->xal_base + XAL_RC_IO_BASE_LO); + + writel(upper_32_bits(pcie->io_limit), pcie->xal_base + XAL_RC_IO_LIMIT_HI); + writel(lower_32_bits(pcie->io_limit), pcie->xal_base + XAL_RC_IO_LIMIT_LO); + writel(upper_32_bits(pcie->mem_base), pcie->xal_base + XAL_RC_MEM_32BIT_BASE_HI); writel(lower_32_bits(pcie->mem_base), pcie->xal_base + XAL_RC_MEM_32BIT_BASE_LO); @@ -234,15 +246,17 @@ static int tegra264_pcie_probe(struct platform_device *pdev) resource_list_for_each_entry(entry, &bridge->windows) { struct resource *res = entry->res; - if (resource_type(res) != IORESOURCE_MEM) - continue; - - if (res->flags & IORESOURCE_PREFETCH) { - pcie->prefetch_mem_base = res->start; - pcie->prefetch_mem_limit = res->end; - } else { - pcie->mem_base = res->start; - pcie->mem_limit = res->end; + if (resource_type(res) == IORESOURCE_IO) { + pcie->io_base = pci_pio_to_address(res->start); + pcie->io_limit = pcie->io_base + resource_size(res) - 1U; + } else if (resource_type(res) == IORESOURCE_MEM) { + if (res->flags & IORESOURCE_PREFETCH) { + pcie->prefetch_mem_base = res->start; + pcie->prefetch_mem_limit = res->end; + } else { + pcie->mem_base = res->start; + pcie->mem_limit = res->end; + } } }