Commit 12962267 authored by Chris Metcalf's avatar Chris Metcalf

arch/tile: tilegx PCI root complex support

This change implements PCIe root complex support for tilegx using
the kernel support layer for accessing the TRIO hardware shim.

Reviewed-by: Bjorn Helgaas <bhelgaas@google.com> [changes in 07487f3]
Signed-off-by: default avatarChris Metcalf <cmetcalf@tilera.com>
parent bce5bbbb
...@@ -356,6 +356,9 @@ config PCI ...@@ -356,6 +356,9 @@ config PCI
default y default y
select PCI_DOMAINS select PCI_DOMAINS
select GENERIC_PCI_IOMAP select GENERIC_PCI_IOMAP
select TILE_GXIO_TRIO if TILEGX
select ARCH_SUPPORTS_MSI if TILEGX
select PCI_MSI if TILEGX
---help--- ---help---
Enable PCI root complex support, so PCIe endpoint devices can Enable PCI root complex support, so PCIe endpoint devices can
be attached to the Tile chip. Many, but not all, PCI devices be attached to the Tile chip. Many, but not all, PCI devices
......
...@@ -16,8 +16,11 @@ ...@@ -16,8 +16,11 @@
#define _ASM_TILE_PCI_H #define _ASM_TILE_PCI_H
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/numa.h>
#include <asm-generic/pci_iomap.h> #include <asm-generic/pci_iomap.h>
#ifndef __tilegx__
/* /*
* Structure of a PCI controller (host bridge) * Structure of a PCI controller (host bridge)
*/ */
...@@ -40,6 +43,91 @@ struct pci_controller { ...@@ -40,6 +43,91 @@ struct pci_controller {
struct resource mem_resources[3]; struct resource mem_resources[3];
}; };
/*
* This flag tells if the platform is TILEmpower that needs
* special configuration for the PLX switch chip.
*/
extern int tile_plx_gen1;
static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
#define TILE_NUM_PCIE 2
#else
#include <asm/page.h>
#include <gxio/trio.h>
/**
* We reserve the hugepage-size address range at the top of the 64-bit address
* space to serve as the PCI window, emulating the BAR0 space of an endpoint
* device. This window is used by the chip-to-chip applications running on
* the RC node. The reason for carving out this window is that Mem-Maps that
* back up this window will not overlap with those that map the real physical
* memory.
*/
#define PCIE_HOST_BAR0_SIZE HPAGE_SIZE
#define PCIE_HOST_BAR0_START HPAGE_MASK
/**
* The first PAGE_SIZE of the above "BAR" window is mapped to the
* gxpci_host_regs structure.
*/
#define PCIE_HOST_REGS_SIZE PAGE_SIZE
/*
* This is the PCI address where the Mem-Map interrupt regions start.
* We use the 2nd to the last huge page of the 64-bit address space.
* The last huge page is used for the rootcomplex "bar", for C2C purpose.
*/
#define MEM_MAP_INTR_REGIONS_BASE (HPAGE_MASK - HPAGE_SIZE)
/*
* Each Mem-Map interrupt region occupies 4KB.
*/
#define MEM_MAP_INTR_REGION_SIZE (1<< TRIO_MAP_MEM_LIM__ADDR_SHIFT)
/*
* Structure of a PCI controller (host bridge) on Gx.
*/
struct pci_controller {
/* Pointer back to the TRIO that this PCIe port is connected to. */
gxio_trio_context_t *trio;
int mac; /* PCIe mac index on the TRIO shim */
int trio_index; /* Index of TRIO shim that contains the MAC. */
int pio_mem_index; /* PIO region index for memory access */
/*
* Mem-Map regions for all the memory controllers so that Linux can
* map all of its physical memory space to the PCI bus.
*/
int mem_maps[MAX_NUMNODES];
int index; /* PCI domain number */
struct pci_bus *root_bus;
int last_busno;
struct pci_ops *ops;
/* Table that maps the INTx numbers to Linux irq numbers. */
int irq_intx_table[4];
struct resource mem_space;
/* Address ranges that are routed to this controller/bridge. */
struct resource mem_resources[3];
};
extern struct pci_controller pci_controllers[TILEGX_NUM_TRIO * TILEGX_TRIO_PCIES];
extern gxio_trio_context_t trio_contexts[TILEGX_NUM_TRIO];
extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
#endif /* __tilegx__ */
/* /*
* The hypervisor maps the entirety of CPA-space as bus addresses, so * The hypervisor maps the entirety of CPA-space as bus addresses, so
* bus addresses are physical addresses. The networking and block * bus addresses are physical addresses. The networking and block
...@@ -50,12 +138,8 @@ struct pci_controller { ...@@ -50,12 +138,8 @@ struct pci_controller {
int __init tile_pci_init(void); int __init tile_pci_init(void);
int __init pcibios_init(void); int __init pcibios_init(void);
static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
void __devinit pcibios_fixup_bus(struct pci_bus *bus); void __devinit pcibios_fixup_bus(struct pci_bus *bus);
#define TILE_NUM_PCIE 2
#define pci_domain_nr(bus) (((struct pci_controller *)(bus)->sysdata)->index) #define pci_domain_nr(bus) (((struct pci_controller *)(bus)->sysdata)->index)
/* /*
...@@ -79,12 +163,6 @@ static inline int pcibios_assign_all_busses(void) ...@@ -79,12 +163,6 @@ static inline int pcibios_assign_all_busses(void)
#define PCIBIOS_MIN_MEM 0 #define PCIBIOS_MIN_MEM 0
#define PCIBIOS_MIN_IO 0 #define PCIBIOS_MIN_IO 0
/*
* This flag tells if the platform is TILEmpower that needs
* special configuration for the PLX switch chip.
*/
extern int tile_plx_gen1;
/* Use any cpu for PCI. */ /* Use any cpu for PCI. */
#define cpumask_of_pcibus(bus) cpu_online_mask #define cpumask_of_pcibus(bus) cpu_online_mask
......
...@@ -14,4 +14,8 @@ obj-$(CONFIG_SMP) += smpboot.o smp.o tlb.o ...@@ -14,4 +14,8 @@ obj-$(CONFIG_SMP) += smpboot.o smp.o tlb.o
obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel_$(BITS).o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel_$(BITS).o
ifdef CONFIG_TILEGX
obj-$(CONFIG_PCI) += pci_gx.o
else
obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_PCI) += pci.o
endif
This diff is collapsed.
...@@ -1344,6 +1344,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -1344,6 +1344,7 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
#if !defined (__tilegx__)
/* /*
* Initialize the PCI structures. This is done before memory * Initialize the PCI structures. This is done before memory
* setup so that we know whether or not a pci_reserve region * setup so that we know whether or not a pci_reserve region
...@@ -1351,6 +1352,7 @@ void __init setup_arch(char **cmdline_p) ...@@ -1351,6 +1352,7 @@ void __init setup_arch(char **cmdline_p)
*/ */
if (tile_pci_init() == 0) if (tile_pci_init() == 0)
pci_reserve_mb = 0; pci_reserve_mb = 0;
#endif
/* PCI systems reserve a region just below 4GB for mapping iomem. */ /* PCI systems reserve a region just below 4GB for mapping iomem. */
pci_reserve_end_pfn = (1 << (32 - PAGE_SHIFT)); pci_reserve_end_pfn = (1 << (32 - PAGE_SHIFT));
...@@ -1379,6 +1381,10 @@ void __init setup_arch(char **cmdline_p) ...@@ -1379,6 +1381,10 @@ void __init setup_arch(char **cmdline_p)
setup_cpu(1); setup_cpu(1);
setup_clock(); setup_clock();
load_hv_initrd(); load_hv_initrd();
#if defined(CONFIG_PCI) && defined (__tilegx__)
tile_pci_init();
#endif
} }
......
...@@ -575,13 +575,6 @@ void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size, ...@@ -575,13 +575,6 @@ void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
} }
EXPORT_SYMBOL(ioremap_prot); EXPORT_SYMBOL(ioremap_prot);
/* Map a PCI MMIO bus address into VA space. */
void __iomem *ioremap(resource_size_t phys_addr, unsigned long size)
{
panic("ioremap for PCI MMIO is not supported");
}
EXPORT_SYMBOL(ioremap);
/* Unmap an MMIO VA mapping. */ /* Unmap an MMIO VA mapping. */
void iounmap(volatile void __iomem *addr_in) void iounmap(volatile void __iomem *addr_in)
{ {
......
...@@ -2143,9 +2143,9 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB, ...@@ -2143,9 +2143,9 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82865_HB,
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB, DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82875_HB,
quirk_unhide_mch_dev6); quirk_unhide_mch_dev6);
#ifdef CONFIG_TILE #ifdef CONFIG_TILEPRO
/* /*
* The Tilera TILEmpower platform needs to set the link speed * The Tilera TILEmpower tilepro platform needs to set the link speed
* to 2.5GT(Giga-Transfers)/s (Gen 1). The default link speed * to 2.5GT(Giga-Transfers)/s (Gen 1). The default link speed
* setting is 5GT/s (Gen 2). 0x98 is the Link Control2 PCIe * setting is 5GT/s (Gen 2). 0x98 is the Link Control2 PCIe
* capability register of the PEX8624 PCIe switch. The switch * capability register of the PEX8624 PCIe switch. The switch
...@@ -2160,7 +2160,7 @@ static void __devinit quirk_tile_plx_gen1(struct pci_dev *dev) ...@@ -2160,7 +2160,7 @@ static void __devinit quirk_tile_plx_gen1(struct pci_dev *dev)
} }
} }
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8624, quirk_tile_plx_gen1); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8624, quirk_tile_plx_gen1);
#endif /* CONFIG_TILE */ #endif /* CONFIG_TILEPRO */
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
/* Some chipsets do not support MSI. We cannot easily rely on setting /* Some chipsets do not support MSI. We cannot easily rely on setting
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment