// SPDX-License-Identifier: GPL-2.0 /* * PLDA PCIe XpressRich host controller driver * * Copyright (C) 2023 Microchip Co. Ltd * * Author: Daire McNamara */ #include #include "pcie-plda.h" void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index, phys_addr_t axi_addr, phys_addr_t pci_addr, size_t size) { u32 atr_sz = ilog2(size) - 1; u32 val; if (index == 0) val = PCIE_CONFIG_INTERFACE; else val = PCIE_TX_RX_INTERFACE; writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) + ATR0_AXI4_SLV0_TRSL_PARAM); val = lower_32_bits(axi_addr) | (atr_sz << ATR_SIZE_SHIFT) | ATR_IMPL_ENABLE; writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) + ATR0_AXI4_SLV0_SRCADDR_PARAM); val = upper_32_bits(axi_addr); writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) + ATR0_AXI4_SLV0_SRC_ADDR); val = lower_32_bits(pci_addr); writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) + ATR0_AXI4_SLV0_TRSL_ADDR_LSB); val = upper_32_bits(pci_addr); writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) + ATR0_AXI4_SLV0_TRSL_ADDR_UDW); val = readl(bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM); val |= (ATR0_PCIE_ATR_SIZE << ATR0_PCIE_ATR_SIZE_SHIFT); writel(val, bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM); writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR); } EXPORT_SYMBOL_GPL(plda_pcie_setup_window); int plda_pcie_setup_iomems(struct platform_device *pdev, struct plda_pcie_rp *port) { void __iomem *bridge_base_addr = port->bridge_addr; struct pci_host_bridge *bridge = platform_get_drvdata(pdev); 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, pci_addr, resource_size(entry->res)); index++; } } return 0; } EXPORT_SYMBOL_GPL(plda_pcie_setup_iomems);