1 /* 1 /* 2 * This file is subject to the terms and condi 2 * This file is subject to the terms and conditions of the GNU General Public 3 * License. See the file "COPYING" in the mai 3 * License. See the file "COPYING" in the main directory of this archive 4 * for more details. 4 * for more details. 5 * 5 * 6 * Copyright (C) 2003 Christoph Hellwig (hch@l 6 * Copyright (C) 2003 Christoph Hellwig (hch@lst.de) 7 * Copyright (C) 1999, 2000, 04 Ralf Baechle ( 7 * Copyright (C) 1999, 2000, 04 Ralf Baechle (ralf@linux-mips.org) 8 * Copyright (C) 1999, 2000 Silicon Graphics, 8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 9 */ 9 */ >> 10 #include <linux/kernel.h> >> 11 #include <linux/export.h> >> 12 #include <linux/pci.h> >> 13 #include <linux/smp.h> >> 14 #include <linux/dma-direct.h> >> 15 #include <asm/sn/arch.h> >> 16 #include <asm/pci/bridge.h> >> 17 #include <asm/paccess.h> >> 18 #include <asm/sn/intr.h> >> 19 #include <asm/sn/sn0/hub.h> >> 20 >> 21 /* >> 22 * Max #PCI busses we can handle; ie, max #PCI bridges. >> 23 */ >> 24 #define MAX_PCI_BUSSES 40 >> 25 >> 26 /* >> 27 * XXX: No kmalloc available when we do our crosstalk scan, >> 28 * we should try to move it later in the boot process. >> 29 */ >> 30 static struct bridge_controller bridges[MAX_PCI_BUSSES]; 10 31 11 #include <linux/io.h> !! 32 extern struct pci_ops bridge_pci_ops; 12 33 13 #include <asm/sn/addrs.h> !! 34 int bridge_probe(nasid_t nasid, int widget_id, int masterwid) 14 #include <asm/sn/types.h> !! 35 { 15 #include <asm/sn/klconfig.h> !! 36 unsigned long offset = NODE_OFFSET(nasid); 16 #include <asm/sn/agent.h> !! 37 struct bridge_controller *bc; 17 #include <asm/sn/ioc3.h> !! 38 static int num_bridges = 0; 18 #include <asm/pci/bridge.h> !! 39 int slot; >> 40 >> 41 pci_set_flags(PCI_PROBE_ONLY); >> 42 >> 43 printk("a bridge\n"); >> 44 >> 45 /* XXX: kludge alert.. */ >> 46 if (!num_bridges) >> 47 ioport_resource.end = ~0UL; >> 48 >> 49 bc = &bridges[num_bridges]; >> 50 >> 51 bc->pc.pci_ops = &bridge_pci_ops; >> 52 bc->pc.mem_resource = &bc->mem; >> 53 bc->pc.io_resource = &bc->io; >> 54 >> 55 bc->pc.index = num_bridges; >> 56 >> 57 bc->mem.name = "Bridge PCI MEM"; >> 58 bc->pc.mem_offset = offset; >> 59 bc->mem.start = 0; >> 60 bc->mem.end = ~0UL; >> 61 bc->mem.flags = IORESOURCE_MEM; >> 62 >> 63 bc->io.name = "Bridge IO MEM"; >> 64 bc->pc.io_offset = offset; >> 65 bc->io.start = 0UL; >> 66 bc->io.end = ~0UL; >> 67 bc->io.flags = IORESOURCE_IO; >> 68 >> 69 bc->widget_id = widget_id; >> 70 bc->nasid = nasid; >> 71 >> 72 bc->baddr = (u64)masterwid << 60 | PCI64_ATTR_BAR; >> 73 >> 74 /* >> 75 * point to this bridge >> 76 */ >> 77 bc->base = (struct bridge_regs *)RAW_NODE_SWIN_BASE(nasid, widget_id); >> 78 >> 79 /* >> 80 * Clear all pending interrupts. >> 81 */ >> 82 bridge_write(bc, b_int_rst_stat, BRIDGE_IRR_ALL_CLR); >> 83 >> 84 /* >> 85 * Until otherwise set up, assume all interrupts are from slot 0 >> 86 */ >> 87 bridge_write(bc, b_int_device, 0x0); >> 88 >> 89 /* >> 90 * swap pio's to pci mem and io space (big windows) >> 91 */ >> 92 bridge_set(bc, b_wid_control, BRIDGE_CTRL_IO_SWAP | >> 93 BRIDGE_CTRL_MEM_SWAP); >> 94 #ifdef CONFIG_PAGE_SIZE_4KB >> 95 bridge_clr(bc, b_wid_control, BRIDGE_CTRL_PAGE_SIZE); >> 96 #else /* 16kB or larger */ >> 97 bridge_set(bc, b_wid_control, BRIDGE_CTRL_PAGE_SIZE); >> 98 #endif >> 99 >> 100 /* >> 101 * Hmm... IRIX sets additional bits in the address which >> 102 * are documented as reserved in the bridge docs. >> 103 */ >> 104 bridge_write(bc, b_wid_int_upper, 0x8000 | (masterwid << 16)); >> 105 bridge_write(bc, b_wid_int_lower, 0x01800090); /* PI_INT_PEND_MOD off*/ >> 106 bridge_write(bc, b_dir_map, (masterwid << 20)); /* DMA */ >> 107 bridge_write(bc, b_int_enable, 0); >> 108 >> 109 for (slot = 0; slot < 8; slot ++) { >> 110 bridge_set(bc, b_device[slot].reg, BRIDGE_DEV_SWAP_DIR); >> 111 bc->pci_int[slot] = -1; >> 112 } >> 113 bridge_read(bc, b_wid_tflush); /* wait until Bridge PIO complete */ >> 114 >> 115 register_pci_controller(&bc->pc); >> 116 >> 117 num_bridges++; >> 118 >> 119 return 0; >> 120 } >> 121 >> 122 /* >> 123 * All observed requests have pin == 1. We could have a global here, that >> 124 * gets incremented and returned every time - unfortunately, pci_map_irq >> 125 * may be called on the same device over and over, and need to return the >> 126 * same value. On O2000, pin can be 0 or 1, and PCI slots can be [0..7]. >> 127 * >> 128 * A given PCI device, in general, should be able to intr any of the cpus >> 129 * on any one of the hubs connected to its xbow. >> 130 */ >> 131 int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) >> 132 { >> 133 return 0; >> 134 } >> 135 >> 136 static inline struct pci_dev *bridge_root_dev(struct pci_dev *dev) >> 137 { >> 138 while (dev->bus->parent) { >> 139 /* Move up the chain of bridges. */ >> 140 dev = dev->bus->self; >> 141 } >> 142 >> 143 return dev; >> 144 } >> 145 >> 146 /* Do platform specific device initialization at pci_enable_device() time */ >> 147 int pcibios_plat_dev_init(struct pci_dev *dev) >> 148 { >> 149 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus); >> 150 struct pci_dev *rdev = bridge_root_dev(dev); >> 151 int slot = PCI_SLOT(rdev->devfn); >> 152 int irq; >> 153 >> 154 irq = bc->pci_int[slot]; >> 155 if (irq == -1) { >> 156 irq = request_bridge_irq(bc, slot); >> 157 if (irq < 0) >> 158 return irq; >> 159 >> 160 bc->pci_int[slot] = irq; >> 161 } >> 162 dev->irq = irq; >> 163 >> 164 return 0; >> 165 } >> 166 >> 167 dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr) >> 168 { >> 169 struct pci_dev *pdev = to_pci_dev(dev); >> 170 struct bridge_controller *bc = BRIDGE_CONTROLLER(pdev->bus); >> 171 >> 172 return bc->baddr + paddr; >> 173 } >> 174 >> 175 phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dma_addr) >> 176 { >> 177 return dma_addr & ~(0xffUL << 56); >> 178 } >> 179 >> 180 /* >> 181 * Device might live on a subordinate PCI bus. XXX Walk up the chain of buses >> 182 * to find the slot number in sense of the bridge device register. >> 183 * XXX This also means multiple devices might rely on conflicting bridge >> 184 * settings. >> 185 */ >> 186 >> 187 static inline void pci_disable_swapping(struct pci_dev *dev) >> 188 { >> 189 struct bridge_controller *bc = BRIDGE_CONTROLLER(dev->bus); >> 190 struct bridge_regs *bridge = bc->base; >> 191 int slot = PCI_SLOT(dev->devfn); >> 192 >> 193 /* Turn off byte swapping */ >> 194 bridge->b_device[slot].reg &= ~BRIDGE_DEV_SWAP_DIR; >> 195 bridge->b_widget.w_tflush; /* Flush */ >> 196 } >> 197 >> 198 static void pci_fixup_ioc3(struct pci_dev *d) >> 199 { >> 200 pci_disable_swapping(d); >> 201 } 19 202 20 #ifdef CONFIG_NUMA 203 #ifdef CONFIG_NUMA 21 int pcibus_to_node(struct pci_bus *bus) 204 int pcibus_to_node(struct pci_bus *bus) 22 { 205 { 23 struct bridge_controller *bc = BRIDGE_ 206 struct bridge_controller *bc = BRIDGE_CONTROLLER(bus); 24 207 25 return bc->nasid; 208 return bc->nasid; 26 } 209 } 27 EXPORT_SYMBOL(pcibus_to_node); 210 EXPORT_SYMBOL(pcibus_to_node); 28 #endif /* CONFIG_NUMA */ 211 #endif /* CONFIG_NUMA */ 29 212 30 static void ip29_fixup_phy(struct pci_dev *dev !! 213 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SGI, PCI_DEVICE_ID_SGI_IOC3, 31 { !! 214 pci_fixup_ioc3); 32 int nasid = pcibus_to_node(dev->bus); << 33 u32 sid; << 34 << 35 if (nasid != 1) << 36 return; /* only needed on seco << 37 << 38 /* enable ethernet PHY on IP29 systemb << 39 pci_read_config_dword(dev, PCI_SUBSYST << 40 if (sid == (PCI_VENDOR_ID_SGI | (IOC3_ << 41 REMOTE_HUB_S(nasid, MD_LED0, 0 << 42 } << 43 << 44 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SGI, PCI << 45 ip29_fixup_phy); << 46 215
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.