18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Port for PPC64 David Engebretsen, IBM Corp.
48c2ecf20Sopenharmony_ci * Contains common pci routines for ppc64 platform, pSeries and iSeries brands.
58c2ecf20Sopenharmony_ci *
68c2ecf20Sopenharmony_ci * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM
78c2ecf20Sopenharmony_ci *   Rework, based on alpha PCI code.
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#undef DEBUG
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_ci#include <linux/kernel.h>
138c2ecf20Sopenharmony_ci#include <linux/pci.h>
148c2ecf20Sopenharmony_ci#include <linux/string.h>
158c2ecf20Sopenharmony_ci#include <linux/init.h>
168c2ecf20Sopenharmony_ci#include <linux/export.h>
178c2ecf20Sopenharmony_ci#include <linux/mm.h>
188c2ecf20Sopenharmony_ci#include <linux/list.h>
198c2ecf20Sopenharmony_ci#include <linux/syscalls.h>
208c2ecf20Sopenharmony_ci#include <linux/irq.h>
218c2ecf20Sopenharmony_ci#include <linux/vmalloc.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci#include <asm/processor.h>
248c2ecf20Sopenharmony_ci#include <asm/io.h>
258c2ecf20Sopenharmony_ci#include <asm/prom.h>
268c2ecf20Sopenharmony_ci#include <asm/pci-bridge.h>
278c2ecf20Sopenharmony_ci#include <asm/byteorder.h>
288c2ecf20Sopenharmony_ci#include <asm/machdep.h>
298c2ecf20Sopenharmony_ci#include <asm/ppc-pci.h>
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci/* pci_io_base -- the base address from which io bars are offsets.
328c2ecf20Sopenharmony_ci * This is the lowest I/O base address (so bar values are always positive),
338c2ecf20Sopenharmony_ci * and it *must* be the start of ISA space if an ISA bus exists because
348c2ecf20Sopenharmony_ci * ISA drivers use hard coded offsets.  If no ISA bus exists nothing
358c2ecf20Sopenharmony_ci * is mapped on the first 64K of IO space
368c2ecf20Sopenharmony_ci */
378c2ecf20Sopenharmony_ciunsigned long pci_io_base;
388c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pci_io_base);
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_cistatic int __init pcibios_init(void)
418c2ecf20Sopenharmony_ci{
428c2ecf20Sopenharmony_ci	struct pci_controller *hose, *tmp;
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	printk(KERN_INFO "PCI: Probing PCI hardware\n");
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	/* For now, override phys_mem_access_prot. If we need it,g
478c2ecf20Sopenharmony_ci	 * later, we may move that initialization to each ppc_md
488c2ecf20Sopenharmony_ci	 */
498c2ecf20Sopenharmony_ci	ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot;
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	/* On ppc64, we always enable PCI domains and we keep domain 0
528c2ecf20Sopenharmony_ci	 * backward compatible in /proc for video cards
538c2ecf20Sopenharmony_ci	 */
548c2ecf20Sopenharmony_ci	pci_add_flags(PCI_ENABLE_PROC_DOMAINS | PCI_COMPAT_DOMAIN_0);
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci	/* Scan all of the recorded PCI controllers.  */
578c2ecf20Sopenharmony_ci	list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
588c2ecf20Sopenharmony_ci		pcibios_scan_phb(hose);
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci	/* Call common code to handle resource allocation */
618c2ecf20Sopenharmony_ci	pcibios_resource_survey();
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci	/* Add devices. */
648c2ecf20Sopenharmony_ci	list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
658c2ecf20Sopenharmony_ci		pci_bus_add_devices(hose->bus);
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	/* Call machine dependent fixup */
688c2ecf20Sopenharmony_ci	if (ppc_md.pcibios_fixup)
698c2ecf20Sopenharmony_ci		ppc_md.pcibios_fixup();
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	return 0;
748c2ecf20Sopenharmony_ci}
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_cisubsys_initcall(pcibios_init);
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ciint pcibios_unmap_io_space(struct pci_bus *bus)
798c2ecf20Sopenharmony_ci{
808c2ecf20Sopenharmony_ci	struct pci_controller *hose;
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	WARN_ON(bus == NULL);
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	/* If this is not a PHB, we only flush the hash table over
858c2ecf20Sopenharmony_ci	 * the area mapped by this bridge. We don't play with the PTE
868c2ecf20Sopenharmony_ci	 * mappings since we might have to deal with sub-page alignments
878c2ecf20Sopenharmony_ci	 * so flushing the hash table is the only sane way to make sure
888c2ecf20Sopenharmony_ci	 * that no hash entries are covering that removed bridge area
898c2ecf20Sopenharmony_ci	 * while still allowing other busses overlapping those pages
908c2ecf20Sopenharmony_ci	 *
918c2ecf20Sopenharmony_ci	 * Note: If we ever support P2P hotplug on Book3E, we'll have
928c2ecf20Sopenharmony_ci	 * to do an appropriate TLB flush here too
938c2ecf20Sopenharmony_ci	 */
948c2ecf20Sopenharmony_ci	if (bus->self) {
958c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_BOOK3S_64
968c2ecf20Sopenharmony_ci		struct resource *res = bus->resource[0];
978c2ecf20Sopenharmony_ci#endif
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci		pr_debug("IO unmapping for PCI-PCI bridge %s\n",
1008c2ecf20Sopenharmony_ci			 pci_name(bus->self));
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC_BOOK3S_64
1038c2ecf20Sopenharmony_ci		__flush_hash_table_range(res->start + _IO_BASE,
1048c2ecf20Sopenharmony_ci					 res->end + _IO_BASE + 1);
1058c2ecf20Sopenharmony_ci#endif
1068c2ecf20Sopenharmony_ci		return 0;
1078c2ecf20Sopenharmony_ci	}
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	/* Get the host bridge */
1108c2ecf20Sopenharmony_ci	hose = pci_bus_to_host(bus);
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci	pr_debug("IO unmapping for PHB %pOF\n", hose->dn);
1138c2ecf20Sopenharmony_ci	pr_debug("  alloc=0x%p\n", hose->io_base_alloc);
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	iounmap(hose->io_base_alloc);
1168c2ecf20Sopenharmony_ci	return 0;
1178c2ecf20Sopenharmony_ci}
1188c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(pcibios_unmap_io_space);
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_civoid __iomem *ioremap_phb(phys_addr_t paddr, unsigned long size)
1218c2ecf20Sopenharmony_ci{
1228c2ecf20Sopenharmony_ci	struct vm_struct *area;
1238c2ecf20Sopenharmony_ci	unsigned long addr;
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci	WARN_ON_ONCE(paddr & ~PAGE_MASK);
1268c2ecf20Sopenharmony_ci	WARN_ON_ONCE(size & ~PAGE_MASK);
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci	/*
1298c2ecf20Sopenharmony_ci	 * Let's allocate some IO space for that guy. We don't pass VM_IOREMAP
1308c2ecf20Sopenharmony_ci	 * because we don't care about alignment tricks that the core does in
1318c2ecf20Sopenharmony_ci	 * that case.  Maybe we should due to stupid card with incomplete
1328c2ecf20Sopenharmony_ci	 * address decoding but I'd rather not deal with those outside of the
1338c2ecf20Sopenharmony_ci	 * reserved 64K legacy region.
1348c2ecf20Sopenharmony_ci	 */
1358c2ecf20Sopenharmony_ci	area = __get_vm_area_caller(size, 0, PHB_IO_BASE, PHB_IO_END,
1368c2ecf20Sopenharmony_ci				    __builtin_return_address(0));
1378c2ecf20Sopenharmony_ci	if (!area)
1388c2ecf20Sopenharmony_ci		return NULL;
1398c2ecf20Sopenharmony_ci
1408c2ecf20Sopenharmony_ci	addr = (unsigned long)area->addr;
1418c2ecf20Sopenharmony_ci	if (ioremap_page_range(addr, addr + size, paddr,
1428c2ecf20Sopenharmony_ci			pgprot_noncached(PAGE_KERNEL))) {
1438c2ecf20Sopenharmony_ci		unmap_kernel_range(addr, size);
1448c2ecf20Sopenharmony_ci		return NULL;
1458c2ecf20Sopenharmony_ci	}
1468c2ecf20Sopenharmony_ci
1478c2ecf20Sopenharmony_ci	return (void __iomem *)addr;
1488c2ecf20Sopenharmony_ci}
1498c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(ioremap_phb);
1508c2ecf20Sopenharmony_ci
1518c2ecf20Sopenharmony_cistatic int pcibios_map_phb_io_space(struct pci_controller *hose)
1528c2ecf20Sopenharmony_ci{
1538c2ecf20Sopenharmony_ci	unsigned long phys_page;
1548c2ecf20Sopenharmony_ci	unsigned long size_page;
1558c2ecf20Sopenharmony_ci	unsigned long io_virt_offset;
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci	phys_page = ALIGN_DOWN(hose->io_base_phys, PAGE_SIZE);
1588c2ecf20Sopenharmony_ci	size_page = ALIGN(hose->pci_io_size, PAGE_SIZE);
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci	/* Make sure IO area address is clear */
1618c2ecf20Sopenharmony_ci	hose->io_base_alloc = NULL;
1628c2ecf20Sopenharmony_ci
1638c2ecf20Sopenharmony_ci	/* If there's no IO to map on that bus, get away too */
1648c2ecf20Sopenharmony_ci	if (hose->pci_io_size == 0 || hose->io_base_phys == 0)
1658c2ecf20Sopenharmony_ci		return 0;
1668c2ecf20Sopenharmony_ci
1678c2ecf20Sopenharmony_ci	/* Let's allocate some IO space for that guy. We don't pass
1688c2ecf20Sopenharmony_ci	 * VM_IOREMAP because we don't care about alignment tricks that
1698c2ecf20Sopenharmony_ci	 * the core does in that case. Maybe we should due to stupid card
1708c2ecf20Sopenharmony_ci	 * with incomplete address decoding but I'd rather not deal with
1718c2ecf20Sopenharmony_ci	 * those outside of the reserved 64K legacy region.
1728c2ecf20Sopenharmony_ci	 */
1738c2ecf20Sopenharmony_ci	hose->io_base_alloc = ioremap_phb(phys_page, size_page);
1748c2ecf20Sopenharmony_ci	if (!hose->io_base_alloc)
1758c2ecf20Sopenharmony_ci		return -ENOMEM;
1768c2ecf20Sopenharmony_ci	hose->io_base_virt = hose->io_base_alloc +
1778c2ecf20Sopenharmony_ci				hose->io_base_phys - phys_page;
1788c2ecf20Sopenharmony_ci
1798c2ecf20Sopenharmony_ci	pr_debug("IO mapping for PHB %pOF\n", hose->dn);
1808c2ecf20Sopenharmony_ci	pr_debug("  phys=0x%016llx, virt=0x%p (alloc=0x%p)\n",
1818c2ecf20Sopenharmony_ci		 hose->io_base_phys, hose->io_base_virt, hose->io_base_alloc);
1828c2ecf20Sopenharmony_ci	pr_debug("  size=0x%016llx (alloc=0x%016lx)\n",
1838c2ecf20Sopenharmony_ci		 hose->pci_io_size, size_page);
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci	/* Fixup hose IO resource */
1868c2ecf20Sopenharmony_ci	io_virt_offset = pcibios_io_space_offset(hose);
1878c2ecf20Sopenharmony_ci	hose->io_resource.start += io_virt_offset;
1888c2ecf20Sopenharmony_ci	hose->io_resource.end += io_virt_offset;
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	pr_debug("  hose->io_resource=%pR\n", &hose->io_resource);
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci	return 0;
1938c2ecf20Sopenharmony_ci}
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ciint pcibios_map_io_space(struct pci_bus *bus)
1968c2ecf20Sopenharmony_ci{
1978c2ecf20Sopenharmony_ci	WARN_ON(bus == NULL);
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ci	/* If this not a PHB, nothing to do, page tables still exist and
2008c2ecf20Sopenharmony_ci	 * thus HPTEs will be faulted in when needed
2018c2ecf20Sopenharmony_ci	 */
2028c2ecf20Sopenharmony_ci	if (bus->self) {
2038c2ecf20Sopenharmony_ci		pr_debug("IO mapping for PCI-PCI bridge %s\n",
2048c2ecf20Sopenharmony_ci			 pci_name(bus->self));
2058c2ecf20Sopenharmony_ci		pr_debug("  virt=0x%016llx...0x%016llx\n",
2068c2ecf20Sopenharmony_ci			 bus->resource[0]->start + _IO_BASE,
2078c2ecf20Sopenharmony_ci			 bus->resource[0]->end + _IO_BASE);
2088c2ecf20Sopenharmony_ci		return 0;
2098c2ecf20Sopenharmony_ci	}
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci	return pcibios_map_phb_io_space(pci_bus_to_host(bus));
2128c2ecf20Sopenharmony_ci}
2138c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(pcibios_map_io_space);
2148c2ecf20Sopenharmony_ci
2158c2ecf20Sopenharmony_civoid pcibios_setup_phb_io_space(struct pci_controller *hose)
2168c2ecf20Sopenharmony_ci{
2178c2ecf20Sopenharmony_ci	pcibios_map_phb_io_space(hose);
2188c2ecf20Sopenharmony_ci}
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci#define IOBASE_BRIDGE_NUMBER	0
2218c2ecf20Sopenharmony_ci#define IOBASE_MEMORY		1
2228c2ecf20Sopenharmony_ci#define IOBASE_IO		2
2238c2ecf20Sopenharmony_ci#define IOBASE_ISA_IO		3
2248c2ecf20Sopenharmony_ci#define IOBASE_ISA_MEM		4
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_ciSYSCALL_DEFINE3(pciconfig_iobase, long, which, unsigned long, in_bus,
2278c2ecf20Sopenharmony_ci			  unsigned long, in_devfn)
2288c2ecf20Sopenharmony_ci{
2298c2ecf20Sopenharmony_ci	struct pci_controller* hose;
2308c2ecf20Sopenharmony_ci	struct pci_bus *tmp_bus, *bus = NULL;
2318c2ecf20Sopenharmony_ci	struct device_node *hose_node;
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci	/* Argh ! Please forgive me for that hack, but that's the
2348c2ecf20Sopenharmony_ci	 * simplest way to get existing XFree to not lockup on some
2358c2ecf20Sopenharmony_ci	 * G5 machines... So when something asks for bus 0 io base
2368c2ecf20Sopenharmony_ci	 * (bus 0 is HT root), we return the AGP one instead.
2378c2ecf20Sopenharmony_ci	 */
2388c2ecf20Sopenharmony_ci	if (in_bus == 0 && of_machine_is_compatible("MacRISC4")) {
2398c2ecf20Sopenharmony_ci		struct device_node *agp;
2408c2ecf20Sopenharmony_ci
2418c2ecf20Sopenharmony_ci		agp = of_find_compatible_node(NULL, NULL, "u3-agp");
2428c2ecf20Sopenharmony_ci		if (agp)
2438c2ecf20Sopenharmony_ci			in_bus = 0xf0;
2448c2ecf20Sopenharmony_ci		of_node_put(agp);
2458c2ecf20Sopenharmony_ci	}
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci	/* That syscall isn't quite compatible with PCI domains, but it's
2488c2ecf20Sopenharmony_ci	 * used on pre-domains setup. We return the first match
2498c2ecf20Sopenharmony_ci	 */
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci	list_for_each_entry(tmp_bus, &pci_root_buses, node) {
2528c2ecf20Sopenharmony_ci		if (in_bus >= tmp_bus->number &&
2538c2ecf20Sopenharmony_ci		    in_bus <= tmp_bus->busn_res.end) {
2548c2ecf20Sopenharmony_ci			bus = tmp_bus;
2558c2ecf20Sopenharmony_ci			break;
2568c2ecf20Sopenharmony_ci		}
2578c2ecf20Sopenharmony_ci	}
2588c2ecf20Sopenharmony_ci	if (bus == NULL || bus->dev.of_node == NULL)
2598c2ecf20Sopenharmony_ci		return -ENODEV;
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_ci	hose_node = bus->dev.of_node;
2628c2ecf20Sopenharmony_ci	hose = PCI_DN(hose_node)->phb;
2638c2ecf20Sopenharmony_ci
2648c2ecf20Sopenharmony_ci	switch (which) {
2658c2ecf20Sopenharmony_ci	case IOBASE_BRIDGE_NUMBER:
2668c2ecf20Sopenharmony_ci		return (long)hose->first_busno;
2678c2ecf20Sopenharmony_ci	case IOBASE_MEMORY:
2688c2ecf20Sopenharmony_ci		return (long)hose->mem_offset[0];
2698c2ecf20Sopenharmony_ci	case IOBASE_IO:
2708c2ecf20Sopenharmony_ci		return (long)hose->io_base_phys;
2718c2ecf20Sopenharmony_ci	case IOBASE_ISA_IO:
2728c2ecf20Sopenharmony_ci		return (long)isa_io_base;
2738c2ecf20Sopenharmony_ci	case IOBASE_ISA_MEM:
2748c2ecf20Sopenharmony_ci		return -EINVAL;
2758c2ecf20Sopenharmony_ci	}
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci	return -EOPNOTSUPP;
2788c2ecf20Sopenharmony_ci}
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_ci#ifdef CONFIG_NUMA
2818c2ecf20Sopenharmony_ciint pcibus_to_node(struct pci_bus *bus)
2828c2ecf20Sopenharmony_ci{
2838c2ecf20Sopenharmony_ci	struct pci_controller *phb = pci_bus_to_host(bus);
2848c2ecf20Sopenharmony_ci	return phb->node;
2858c2ecf20Sopenharmony_ci}
2868c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pcibus_to_node);
2878c2ecf20Sopenharmony_ci#endif
288