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