Skip to content

Commit

Permalink
MIPS: SGI-IP27: use generic PCI driver
Browse files Browse the repository at this point in the history
Converted bridge code to a platform driver using the PCI generic driver
framework and use adding platform devices during xtalk scan. This allows
easier sharing bridge driver for other SGI platforms like IP30 (Octane) and
IP35 (Origin 3k, Fuel, Tezro).

Signed-off-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
[paul.burton@mips.com:
  - Leave __phys_to_dma(), __dma_to_phys() & pcibus_to_node() in
    arch/mips/pci/pci-ip27.c since the motivation for moving them
    disappeared when the driver stopped being moved to drivers/pci.]
Signed-off-by: Paul Burton <paul.burton@mips.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: James Hogan <jhogan@kernel.org>
Cc: linux-mips@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
  • Loading branch information
Thomas Bogendoerfer authored and Paul Burton committed May 9, 2019
1 parent 8041edb commit a57140e
Show file tree
Hide file tree
Showing 10 changed files with 288 additions and 275 deletions.
5 changes: 5 additions & 0 deletions arch/mips/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,8 @@ config SGI_IP27
select HAVE_PCI
select IRQ_MIPS_CPU
select NR_CPUS_DEFAULT_64
select PCI_DRIVERS_GENERIC
select PCI_XTALK_BRIDGE
select SYS_HAS_CPU_R10000
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
Expand Down Expand Up @@ -1249,6 +1251,9 @@ config IRQ_GT641XX
config PCI_GT64XXX_PCI0
bool

config PCI_XTALK_BRIDGE
bool

config NO_EXCEPT_FILL
bool

Expand Down
11 changes: 1 addition & 10 deletions arch/mips/include/asm/mach-ip27/topology.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,9 @@
#include <asm/mmzone.h>

struct cpuinfo_ip27 {
// cpuid_t p_cpuid; /* PROM assigned cpuid */
cnodeid_t p_nodeid; /* my node ID in compact-id-space */
nasid_t p_nasid; /* my node ID in numa-as-id-space */
unsigned char p_slice; /* Physical position on node board */
#if 0
unsigned long loops_per_sec;
unsigned long ipi_count;
unsigned long irq_attempt[NR_IRQS];
unsigned long smp_local_irq_count;
unsigned long prof_multiplier;
unsigned long prof_counter;
#endif
};

extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS];
Expand All @@ -30,7 +21,7 @@ extern struct cpuinfo_ip27 sn_cpu_info[NR_CPUS];
struct pci_bus;
extern int pcibus_to_node(struct pci_bus *);

#define cpumask_of_pcibus(bus) (cpu_online_mask)
#define cpumask_of_pcibus(bus) (cpumask_of_node(pcibus_to_node(bus)))

extern unsigned char __node_distances[MAX_COMPACT_NODES][MAX_COMPACT_NODES];

Expand Down
11 changes: 3 additions & 8 deletions arch/mips/include/asm/pci/bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -801,15 +801,12 @@ struct bridge_err_cmdword {
#define PCI64_ATTR_RMF_SHFT 48

struct bridge_controller {
struct pci_controller pc;
struct resource mem;
struct resource io;
struct resource busn;
struct bridge_regs *base;
nasid_t nasid;
unsigned int widget_id;
u64 baddr;
unsigned long baddr;
unsigned long intr_addr;
unsigned int pci_int[8];
nasid_t nasid;
};

#define BRIDGE_CONTROLLER(bus) \
Expand All @@ -824,6 +821,4 @@ struct bridge_controller {

extern int request_bridge_irq(struct bridge_controller *bc, int pin);

extern struct pci_ops bridge_pci_ops;

#endif /* _ASM_PCI_BRIDGE_H */
9 changes: 0 additions & 9 deletions arch/mips/include/asm/xtalk/xtalk.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,6 @@ typedef struct xtalk_piomap_s *xtalk_piomap_t;
#define XIO_PORT(x) ((xwidgetnum_t)(((x)&XIO_PORT_BITS) >> XIO_PORT_SHIFT))
#define XIO_PACK(p, o) ((((uint64_t)(p))<<XIO_PORT_SHIFT) | ((o)&XIO_ADDR_BITS))

#ifdef CONFIG_PCI
extern int bridge_probe(nasid_t nasid, int widget, int masterwid);
#else
static inline int bridge_probe(nasid_t nasid, int widget, int masterwid)
{
return 0;
}
#endif

#endif /* !__ASSEMBLY__ */

#endif /* _ASM_XTALK_XTALK_H */
3 changes: 2 additions & 1 deletion arch/mips/pci/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ obj-$(CONFIG_PCI_AR2315) += pci-ar2315.o
obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o
obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o
obj-$(CONFIG_MIPS_PCI_VIRTIO) += pci-virtio-guest.o
obj-$(CONFIG_PCI_XTALK_BRIDGE) += pci-xtalk-bridge.o
#
# These are still pretty much in the old state, watch, go blind.
#
Expand All @@ -39,7 +40,7 @@ obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o pci-malta.o
obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o
obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o
obj-$(CONFIG_PMC_MSP7120_FPGA) += fixup-pmcmsp.o ops-pmcmsp.o
obj-$(CONFIG_SGI_IP27) += ops-bridge.o pci-ip27.o
obj-$(CONFIG_SGI_IP27) += pci-ip27.o
obj-$(CONFIG_SGI_IP32) += fixup-ip32.o ops-mace.o pci-ip32.o
obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o
obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o
Expand Down
181 changes: 0 additions & 181 deletions arch/mips/pci/pci-ip27.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,162 +7,7 @@
* Copyright (C) 1999, 2000, 04 Ralf Baechle (ralf@linux-mips.org)
* Copyright (C) 1999, 2000 Silicon Graphics, Inc.
*/
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/pci.h>
#include <linux/smp.h>
#include <linux/dma-direct.h>
#include <asm/sn/arch.h>
#include <asm/pci/bridge.h>
#include <asm/paccess.h>
#include <asm/sn/intr.h>
#include <asm/sn/sn0/hub.h>

/*
* Max #PCI busses we can handle; ie, max #PCI bridges.
*/
#define MAX_PCI_BUSSES 40

/*
* XXX: No kmalloc available when we do our crosstalk scan,
* we should try to move it later in the boot process.
*/
static struct bridge_controller bridges[MAX_PCI_BUSSES];

extern struct pci_ops bridge_pci_ops;

int bridge_probe(nasid_t nasid, int widget_id, int masterwid)
{
unsigned long offset = NODE_OFFSET(nasid);
struct bridge_controller *bc;
static int num_bridges = 0;
int slot;

pci_set_flags(PCI_PROBE_ONLY);

printk("a bridge\n");

/* XXX: kludge alert.. */
if (!num_bridges)
ioport_resource.end = ~0UL;

bc = &bridges[num_bridges];

bc->pc.pci_ops = &bridge_pci_ops;
bc->pc.mem_resource = &bc->mem;
bc->pc.io_resource = &bc->io;

bc->pc.index = num_bridges;

bc->mem.name = "Bridge PCI MEM";
bc->pc.mem_offset = offset;
bc->mem.start = 0;
bc->mem.end = ~0UL;
bc->mem.flags = IORESOURCE_MEM;

bc->io.name = "Bridge IO MEM";
bc->pc.io_offset = offset;
bc->io.start = 0UL;
bc->io.end = ~0UL;
bc->io.flags = IORESOURCE_IO;

bc->widget_id = widget_id;
bc->nasid = nasid;

bc->baddr = (u64)masterwid << 60 | PCI64_ATTR_BAR;

/*
* point to this bridge
*/
bc->base = (struct bridge_regs *)RAW_NODE_SWIN_BASE(nasid, widget_id);

/*
* Clear all pending interrupts.
*/
bridge_write(bc, b_int_rst_stat, BRIDGE_IRR_ALL_CLR);

/*
* Until otherwise set up, assume all interrupts are from slot 0
*/
bridge_write(bc, b_int_device, 0x0);

/*
* swap pio's to pci mem and io space (big windows)
*/
bridge_set(bc, b_wid_control, BRIDGE_CTRL_IO_SWAP |
BRIDGE_CTRL_MEM_SWAP);
#ifdef CONFIG_PAGE_SIZE_4KB
bridge_clr(bc, b_wid_control, BRIDGE_CTRL_PAGE_SIZE);
#else /* 16kB or larger */
bridge_set(bc, b_wid_control, BRIDGE_CTRL_PAGE_SIZE);
#endif

/*
* Hmm... IRIX sets additional bits in the address which
* are documented as reserved in the bridge docs.
*/
bridge_write(bc, b_wid_int_upper, 0x8000 | (masterwid << 16));
bridge_write(bc, b_wid_int_lower, 0x01800090); /* PI_INT_PEND_MOD off*/
bridge_write(bc, b_dir_map, (masterwid << 20)); /* DMA */
bridge_write(bc, b_int_enable, 0);

for (slot = 0; slot < 8; slot ++) {
bridge_set(bc, b_device[slot].reg, BRIDGE_DEV_SWAP_DIR);
bc->pci_int[slot] = -1;
}
bridge_read(bc, b_wid_tflush); /* wait until Bridge PIO complete */

register_pci_controller(&bc->pc);

num_bridges++;

return 0;
}

/*
* All observed requests have pin == 1. We could have a global here, that
* gets incremented and returned every time - unfortunately, pci_map_irq
* may be called on the same device over and over, and need to return the
* same value. On O2000, pin can be 0 or 1, and PCI slots can be [0..7].
*
* A given PCI device, in general, should be able to intr any of the cpus
* on any one of the hubs connected to its xbow.
*/
int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
return 0;
}

static inline struct pci_dev *bridge_root_dev(struct pci_dev *dev)
{
while (dev->bus->parent) {
/* Move up the chain of bridges. */
dev = dev->bus->self;
}

return dev;
}

/* Do platform specific device initialization at pci_enable_device() time */
int pcibios_plat_dev_init(struct pci_dev *dev)
{
struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
struct pci_dev *rdev = bridge_root_dev(dev);
int slot = PCI_SLOT(rdev->devfn);
int irq;

irq = bc->pci_int[slot];
if (irq == -1) {
irq = request_bridge_irq(bc, slot);
if (irq < 0)
return irq;

bc->pci_int[slot] = irq;
}
dev->irq = irq;

return 0;
}

dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
{
Expand All @@ -177,29 +22,6 @@ phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr)
return dma_addr & ~(0xffUL << 56);
}

/*
* Device might live on a subordinate PCI bus. XXX Walk up the chain of buses
* to find the slot number in sense of the bridge device register.
* XXX This also means multiple devices might rely on conflicting bridge
* settings.
*/

static inline void pci_disable_swapping(struct pci_dev *dev)
{
struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus);
struct bridge_regs *bridge = bc->base;
int slot = PCI_SLOT(dev->devfn);

/* Turn off byte swapping */
bridge->b_device[slot].reg &= ~BRIDGE_DEV_SWAP_DIR;
bridge->b_widget.w_tflush; /* Flush */
}

static void pci_fixup_ioc3(struct pci_dev *d)
{
pci_disable_swapping(d);
}

#ifdef CONFIG_NUMA
int pcibus_to_node(struct pci_bus *bus)
{
Expand All @@ -209,6 +31,3 @@ int pcibus_to_node(struct pci_bus *bus)
}
EXPORT_SYMBOL(pcibus_to_node);
#endif /* CONFIG_NUMA */

DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3,
pci_fixup_ioc3);
Loading

0 comments on commit a57140e

Please sign in to comment.