Merge with Linux 2.5.59.
[linux-2.6/linux-mips.git] / arch / ppc / platforms / k2_pci.c
blobf0b3acecb91af60a0ccba790e6bb2d1c100b5a81
1 /*
2 * arch/ppc/platforms/k2_pci.c
3 *
4 * PCI support for SBS K2
6 * Author: Matt Porter <mporter@mvista.com>
8 * 2001 (c) MontaVista, Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2.1. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
14 #include <linux/kernel.h>
15 #include <linux/init.h>
16 #include <linux/pci.h>
17 #include <linux/slab.h>
19 #include <asm/byteorder.h>
20 #include <asm/io.h>
21 #include <asm/uaccess.h>
22 #include <asm/machdep.h>
23 #include <asm/pci-bridge.h>
25 #include <syslib/cpc710.h>
27 #include "k2.h"
29 #undef DEBUG
30 #ifdef DEBUG
31 #define DBG(x...) printk(x)
32 #else
33 #define DBG(x...)
34 #endif /* DEBUG */
36 static inline int __init
37 k2_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
39 struct pci_controller *hose = pci_bus_to_hose(dev->bus->number);
41 * Check our hose index. If we are zero then we are on the
42 * local PCI hose, otherwise we are on the cPCI hose.
44 if (!hose->index)
46 static char pci_irq_table[][4] =
48 * PCI IDSEL/INTPIN->INTLINE
49 * A B C D
52 {1, 0, 0, 0}, /* Ethernet */
53 {5, 5, 5, 5}, /* PMC Site 1 */
54 {6, 6, 6, 6}, /* PMC Site 2 */
55 {0, 0, 0, 0}, /* unused */
56 {0, 0, 0, 0}, /* unused */
57 {0, 0, 0, 0}, /* PCI-ISA Bridge */
58 {0, 0, 0, 0}, /* unused */
59 {0, 0, 0, 0}, /* unused */
60 {0, 0, 0, 0}, /* unused */
61 {0, 0, 0, 0}, /* unused */
62 {0, 0, 0, 0}, /* unused */
63 {0, 0, 0, 0}, /* unused */
64 {0, 0, 0, 0}, /* unused */
65 {0, 0, 0, 0}, /* unused */
66 {15, 0, 0, 0}, /* M5229 IDE */
68 const long min_idsel = 3, max_idsel = 17, irqs_per_slot = 4;
69 return PCI_IRQ_TABLE_LOOKUP;
71 else
73 static char pci_irq_table[][4] =
75 * PCI IDSEL/INTPIN->INTLINE
76 * A B C D
79 {10, 11, 12, 9}, /* cPCI slot 8 */
80 {11, 12, 9, 10}, /* cPCI slot 7 */
81 {12, 9, 10, 11}, /* cPCI slot 6 */
82 {9, 10, 11, 12}, /* cPCI slot 5 */
83 {10, 11, 12, 9}, /* cPCI slot 4 */
84 {11, 12, 9, 10}, /* cPCI slot 3 */
85 {12, 9, 10, 11}, /* cPCI slot 2 */
87 const long min_idsel = 15, max_idsel = 21, irqs_per_slot = 4;
88 return PCI_IRQ_TABLE_LOOKUP;
92 void k2_pcibios_fixup(void)
94 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
95 struct pci_dev *ide_dev;
98 * Enable DMA support on hdc
100 ide_dev = pci_find_device(PCI_VENDOR_ID_AL,
101 PCI_DEVICE_ID_AL_M5229,
102 NULL);
104 if (ide_dev) {
106 unsigned long ide_dma_base;
108 ide_dma_base = pci_resource_start(ide_dev, 4);
109 outb(0x00, ide_dma_base+0x2);
110 outb(0x20, ide_dma_base+0xa);
112 #endif
115 void k2_pcibios_fixup_resources(struct pci_dev *dev)
117 int i;
119 if ((dev->vendor == PCI_VENDOR_ID_IBM) &&
120 (dev->device == PCI_DEVICE_ID_IBM_CPC710_PCI64))
122 DBG("Fixup CPC710 resources\n");
123 for (i=0; i<DEVICE_COUNT_RESOURCE; i++)
125 dev->resource[i].start = 0;
126 dev->resource[i].end = 0;
131 void k2_setup_hoses(void)
133 struct pci_controller *hose_a, *hose_b;
136 * Reconfigure CPC710 memory map so
137 * we have some more PCI memory space.
140 /* Set FPHB mode */
141 __raw_writel(0x808000e0, PGCHP); /* Set FPHB mode */
143 /* PCI32 mappings */
144 __raw_writel(0x00000000, K2_PCI32_BAR+PIBAR); /* PCI I/O base */
145 __raw_writel(0x00000000, K2_PCI32_BAR+PMBAR); /* PCI Mem base */
146 __raw_writel(0xf0000000, K2_PCI32_BAR+MSIZE); /* 256MB */
147 __raw_writel(0xfff00000, K2_PCI32_BAR+IOSIZE); /* 1MB */
148 __raw_writel(0xc0000000, K2_PCI32_BAR+SMBAR); /* Base@0xc0000000 */
149 __raw_writel(0x80000000, K2_PCI32_BAR+SIBAR); /* Base@0x80000000 */
150 __raw_writel(0x000000c0, K2_PCI32_BAR+PSSIZE); /* 1GB space */
151 __raw_writel(0x000000c0, K2_PCI32_BAR+PPSIZE); /* 1GB space */
152 __raw_writel(0x00000000, K2_PCI32_BAR+BARPS); /* Base@0x00000000 */
153 __raw_writel(0x00000000, K2_PCI32_BAR+BARPP); /* Base@0x00000000 */
154 __raw_writel(0x00000080, K2_PCI32_BAR+PSBAR); /* Base@0x80 */
155 __raw_writel(0x00000000, K2_PCI32_BAR+PPBAR);
157 __raw_writel(0xc0000000, K2_PCI32_BAR+BPMDLK);
158 __raw_writel(0xd0000000, K2_PCI32_BAR+TPMDLK);
159 __raw_writel(0x80000000, K2_PCI32_BAR+BIODLK);
160 __raw_writel(0x80100000, K2_PCI32_BAR+TIODLK);
161 __raw_writel(0xe0008000, K2_PCI32_BAR+DLKCTRL);
162 __raw_writel(0xffffffff, K2_PCI32_BAR+DLKDEV);
164 /* PCI64 mappings */
165 __raw_writel(0x00100000, K2_PCI64_BAR+PIBAR); /* PCI I/O base */
166 __raw_writel(0x10000000, K2_PCI64_BAR+PMBAR); /* PCI Mem base */
167 __raw_writel(0xf0000000, K2_PCI64_BAR+MSIZE); /* 256MB */
168 __raw_writel(0xfff00000, K2_PCI64_BAR+IOSIZE); /* 1MB */
169 __raw_writel(0xd0000000, K2_PCI64_BAR+SMBAR); /* Base@0xd0000000 */
170 __raw_writel(0x80100000, K2_PCI64_BAR+SIBAR); /* Base@0x80100000 */
171 __raw_writel(0x000000c0, K2_PCI64_BAR+PSSIZE); /* 1GB space */
172 __raw_writel(0x000000c0, K2_PCI64_BAR+PPSIZE); /* 1GB space */
173 __raw_writel(0x00000000, K2_PCI64_BAR+BARPS); /* Base@0x00000000 */
174 __raw_writel(0x00000000, K2_PCI64_BAR+BARPP); /* Base@0x00000000 */
176 /* Setup PCI32 hose */
177 hose_a = pcibios_alloc_controller();
178 if (!hose_a)
179 return;
181 hose_a->first_busno = 0;
182 hose_a->last_busno = 0xff;
183 hose_a->pci_mem_offset = K2_PCI32_MEM_BASE;
185 pci_init_resource(&hose_a->io_resource,
186 K2_PCI32_LOWER_IO,
187 K2_PCI32_UPPER_IO,
188 IORESOURCE_IO,
189 "PCI32 host bridge");
191 pci_init_resource(&hose_a->mem_resources[0],
192 K2_PCI32_LOWER_MEM + K2_PCI32_MEM_BASE,
193 K2_PCI32_UPPER_MEM + K2_PCI32_MEM_BASE,
194 IORESOURCE_MEM,
195 "PCI32 host bridge");
197 hose_a->io_space.start = K2_PCI32_LOWER_IO;
198 hose_a->io_space.end = K2_PCI32_UPPER_IO;
199 hose_a->mem_space.start = K2_PCI32_LOWER_MEM;
200 hose_a->mem_space.end = K2_PCI32_UPPER_MEM;
201 hose_a->io_base_virt = (void *)K2_ISA_IO_BASE;
203 setup_indirect_pci(hose_a, K2_PCI32_CONFIG_ADDR, K2_PCI32_CONFIG_DATA);
205 /* Initialize PCI32 bus registers */
206 early_write_config_byte(hose_a,
207 hose_a->first_busno,
208 PCI_DEVFN(0, 0),
209 CPC710_BUS_NUMBER,
210 hose_a->first_busno);
212 early_write_config_byte(hose_a,
213 hose_a->first_busno,
214 PCI_DEVFN(0, 0),
215 CPC710_SUB_BUS_NUMBER,
216 hose_a->last_busno);
218 /* Enable PCI interrupt polling */
219 early_write_config_byte(hose_a,
220 hose_a->first_busno,
221 PCI_DEVFN(8, 0),
222 0x45,
223 0x80);
225 /* Route polled PCI interrupts */
226 early_write_config_byte(hose_a,
227 hose_a->first_busno,
228 PCI_DEVFN(8, 0),
229 0x48,
230 0x58);
232 early_write_config_byte(hose_a,
233 hose_a->first_busno,
234 PCI_DEVFN(8, 0),
235 0x49,
236 0x07);
238 early_write_config_byte(hose_a,
239 hose_a->first_busno,
240 PCI_DEVFN(8, 0),
241 0x4a,
242 0x31);
244 early_write_config_byte(hose_a,
245 hose_a->first_busno,
246 PCI_DEVFN(8, 0),
247 0x4b,
248 0xb9);
250 /* route secondary IDE channel interrupt to IRQ 15 */
251 early_write_config_byte(hose_a,
252 hose_a->first_busno,
253 PCI_DEVFN(8, 0),
254 0x75,
255 0x0f);
257 /* enable IDE controller IDSEL */
258 early_write_config_byte(hose_a,
259 hose_a->first_busno,
260 PCI_DEVFN(8, 0),
261 0x58,
262 0x48);
264 /* Enable IDE function */
265 early_write_config_byte(hose_a,
266 hose_a->first_busno,
267 PCI_DEVFN(17, 0),
268 0x50,
269 0x03);
271 /* Set M5229 IDE controller to native mode */
272 early_write_config_byte(hose_a,
273 hose_a->first_busno,
274 PCI_DEVFN(17, 0),
275 PCI_CLASS_PROG,
276 0xdf);
278 hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno);
280 /* Write out correct max subordinate bus number for hose A */
281 early_write_config_byte(hose_a,
282 hose_a->first_busno,
283 PCI_DEVFN(0, 0),
284 CPC710_SUB_BUS_NUMBER,
285 hose_a->last_busno);
287 /* Only setup PCI64 hose if we are in the system slot */
288 if (!(readb(K2_MISC_REG) & K2_SYS_SLOT_MASK))
290 /* Setup PCI64 hose */
291 hose_b = pcibios_alloc_controller();
292 if (!hose_b)
293 return;
295 hose_b->first_busno = hose_a->last_busno + 1;
296 hose_b->last_busno = 0xff;
298 /* Reminder: quit changing the following, it is correct. */
299 hose_b->pci_mem_offset = K2_PCI32_MEM_BASE;
301 pci_init_resource(&hose_b->io_resource,
302 K2_PCI64_LOWER_IO,
303 K2_PCI64_UPPER_IO,
304 IORESOURCE_IO,
305 "PCI64 host bridge");
307 pci_init_resource(&hose_b->mem_resources[0],
308 K2_PCI64_LOWER_MEM + K2_PCI32_MEM_BASE,
309 K2_PCI64_UPPER_MEM + K2_PCI32_MEM_BASE,
310 IORESOURCE_MEM,
311 "PCI64 host bridge");
313 hose_b->io_space.start = K2_PCI64_LOWER_IO;
314 hose_b->io_space.end = K2_PCI64_UPPER_IO;
315 hose_b->mem_space.start = K2_PCI64_LOWER_MEM;
316 hose_b->mem_space.end = K2_PCI64_UPPER_MEM;
317 hose_b->io_base_virt = (void *)K2_ISA_IO_BASE;
319 setup_indirect_pci(hose_b,
320 K2_PCI64_CONFIG_ADDR,
321 K2_PCI64_CONFIG_DATA);
323 /* Initialize PCI64 bus registers */
324 early_write_config_byte(hose_b,
326 PCI_DEVFN(0, 0),
327 CPC710_SUB_BUS_NUMBER,
328 0xff);
330 early_write_config_byte(hose_b,
332 PCI_DEVFN(0, 0),
333 CPC710_BUS_NUMBER,
334 hose_b->first_busno);
336 hose_b->last_busno = pciauto_bus_scan(hose_b,
337 hose_b->first_busno);
339 /* Write out correct max subordinate bus number for hose B */
340 early_write_config_byte(hose_b,
341 hose_b->first_busno,
342 PCI_DEVFN(0, 0),
343 CPC710_SUB_BUS_NUMBER,
344 hose_b->last_busno);
346 /* Configure PCI64 PSBAR */
347 early_write_config_dword(hose_b,
348 hose_b->first_busno,
349 PCI_DEVFN(0, 0),
350 PCI_BASE_ADDRESS_0,
351 K2_PCI64_SYS_MEM_BASE);
354 /* Configure i8259 level/edge settings */
355 outb(0x62, 0x4d0);
356 outb(0xde, 0x4d1);
358 #ifdef CONFIG_CPC710_DATA_GATHERING
360 unsigned int tmp;
361 tmp = __raw_readl(ABCNTL);
362 /* Enable data gathering on both PCI interfaces */
363 __raw_writel(tmp | 0x05000000, ABCNTL);
365 #endif
367 ppc_md.pcibios_fixup = k2_pcibios_fixup;
368 ppc_md.pcibios_fixup_resources = k2_pcibios_fixup_resources;
369 ppc_md.pci_swizzle = common_swizzle;
370 ppc_md.pci_map_irq = k2_map_irq;