1*39bd5f82SMinda Chen // SPDX-License-Identifier: GPL-2.0 2*39bd5f82SMinda Chen /* 3*39bd5f82SMinda Chen * PLDA PCIe XpressRich host controller driver 4*39bd5f82SMinda Chen * 5*39bd5f82SMinda Chen * Copyright (C) 2023 Microchip Co. Ltd 6*39bd5f82SMinda Chen * 7*39bd5f82SMinda Chen * Author: Daire McNamara <daire.mcnamara@microchip.com> 8*39bd5f82SMinda Chen */ 9*39bd5f82SMinda Chen 10*39bd5f82SMinda Chen #include <linux/pci-ecam.h> 11*39bd5f82SMinda Chen 12*39bd5f82SMinda Chen #include "pcie-plda.h" 13*39bd5f82SMinda Chen 14*39bd5f82SMinda Chen void plda_pcie_setup_window(void __iomem *bridge_base_addr, u32 index, 15*39bd5f82SMinda Chen phys_addr_t axi_addr, phys_addr_t pci_addr, 16*39bd5f82SMinda Chen size_t size) 17*39bd5f82SMinda Chen { 18*39bd5f82SMinda Chen u32 atr_sz = ilog2(size) - 1; 19*39bd5f82SMinda Chen u32 val; 20*39bd5f82SMinda Chen 21*39bd5f82SMinda Chen if (index == 0) 22*39bd5f82SMinda Chen val = PCIE_CONFIG_INTERFACE; 23*39bd5f82SMinda Chen else 24*39bd5f82SMinda Chen val = PCIE_TX_RX_INTERFACE; 25*39bd5f82SMinda Chen 26*39bd5f82SMinda Chen writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) + 27*39bd5f82SMinda Chen ATR0_AXI4_SLV0_TRSL_PARAM); 28*39bd5f82SMinda Chen 29*39bd5f82SMinda Chen val = lower_32_bits(axi_addr) | (atr_sz << ATR_SIZE_SHIFT) | 30*39bd5f82SMinda Chen ATR_IMPL_ENABLE; 31*39bd5f82SMinda Chen writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) + 32*39bd5f82SMinda Chen ATR0_AXI4_SLV0_SRCADDR_PARAM); 33*39bd5f82SMinda Chen 34*39bd5f82SMinda Chen val = upper_32_bits(axi_addr); 35*39bd5f82SMinda Chen writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) + 36*39bd5f82SMinda Chen ATR0_AXI4_SLV0_SRC_ADDR); 37*39bd5f82SMinda Chen 38*39bd5f82SMinda Chen val = lower_32_bits(pci_addr); 39*39bd5f82SMinda Chen writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) + 40*39bd5f82SMinda Chen ATR0_AXI4_SLV0_TRSL_ADDR_LSB); 41*39bd5f82SMinda Chen 42*39bd5f82SMinda Chen val = upper_32_bits(pci_addr); 43*39bd5f82SMinda Chen writel(val, bridge_base_addr + (index * ATR_ENTRY_SIZE) + 44*39bd5f82SMinda Chen ATR0_AXI4_SLV0_TRSL_ADDR_UDW); 45*39bd5f82SMinda Chen 46*39bd5f82SMinda Chen val = readl(bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM); 47*39bd5f82SMinda Chen val |= (ATR0_PCIE_ATR_SIZE << ATR0_PCIE_ATR_SIZE_SHIFT); 48*39bd5f82SMinda Chen writel(val, bridge_base_addr + ATR0_PCIE_WIN0_SRCADDR_PARAM); 49*39bd5f82SMinda Chen writel(0, bridge_base_addr + ATR0_PCIE_WIN0_SRC_ADDR); 50*39bd5f82SMinda Chen } 51*39bd5f82SMinda Chen EXPORT_SYMBOL_GPL(plda_pcie_setup_window); 52*39bd5f82SMinda Chen 53*39bd5f82SMinda Chen int plda_pcie_setup_iomems(struct platform_device *pdev, 54*39bd5f82SMinda Chen struct plda_pcie_rp *port) 55*39bd5f82SMinda Chen { 56*39bd5f82SMinda Chen void __iomem *bridge_base_addr = port->bridge_addr; 57*39bd5f82SMinda Chen struct pci_host_bridge *bridge = platform_get_drvdata(pdev); 58*39bd5f82SMinda Chen struct resource_entry *entry; 59*39bd5f82SMinda Chen u64 pci_addr; 60*39bd5f82SMinda Chen u32 index = 1; 61*39bd5f82SMinda Chen 62*39bd5f82SMinda Chen resource_list_for_each_entry(entry, &bridge->windows) { 63*39bd5f82SMinda Chen if (resource_type(entry->res) == IORESOURCE_MEM) { 64*39bd5f82SMinda Chen pci_addr = entry->res->start - entry->offset; 65*39bd5f82SMinda Chen plda_pcie_setup_window(bridge_base_addr, index, 66*39bd5f82SMinda Chen entry->res->start, pci_addr, 67*39bd5f82SMinda Chen resource_size(entry->res)); 68*39bd5f82SMinda Chen index++; 69*39bd5f82SMinda Chen } 70*39bd5f82SMinda Chen } 71*39bd5f82SMinda Chen 72*39bd5f82SMinda Chen return 0; 73*39bd5f82SMinda Chen } 74*39bd5f82SMinda Chen EXPORT_SYMBOL_GPL(plda_pcie_setup_iomems); 75