2 * Driver for PLX Technology PCI9000-series host bridge.
4 * Copyright (C) 1997, 1998, 1999, 2000 FutureTV Labs Ltd
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
14 #include <linux/kernel.h>
15 #include <linux/pci.h>
16 #include <linux/init.h>
17 #include <linux/sched.h>
19 #include <asm/hardware.h>
21 #include <asm/ptrace.h>
23 #include <asm/mach/pci.h>
26 * Since the following functions are all very similar, the common parts
27 * are pulled out into these macros.
30 #define PLX_CLEAR_CONFIG \
31 __raw_writel(0, PLX_BASE + 0xac); \
32 local_irq_restore(flags); }
34 #define PLX_SET_CONFIG \
35 { unsigned long flags; \
36 local_irq_save(flags); \
37 __raw_writel((1<<31 | (dev->bus->number << 16) \
38 | (dev->devfn << 8) | (where & ~3) \
39 | ((dev->bus->number == 0)?0:1)), PLX_BASE + 0xac); \
41 #define PLX_CONFIG_WRITE(size) \
43 __raw_write##size(value, PCIO_BASE + (where & 3)); \
44 if (__raw_readw(PLX_BASE + 0x6) & 0x2000) \
45 __raw_writew(0x2000, PLX_BASE + 0x6); \
47 return PCIBIOS_SUCCESSFUL;
49 #define PLX_CONFIG_READ(size) \
51 *value = __raw_read##size(PCIO_BASE + (where & 3)); \
52 if (__raw_readw(PLX_BASE + 0x6) & 0x2000) { \
53 __raw_writew(0x2000, PLX_BASE + 0x6); \
54 *value = 0xffffffffUL; \
57 return PCIBIOS_SUCCESSFUL;
59 /* Configuration space access routines */
62 plx90x0_read_config_byte (struct pci_dev *dev,
69 plx90x0_read_config_word (struct pci_dev *dev,
70 int where, u16 *value)
76 plx90x0_read_config_dword (struct pci_dev *dev,
77 int where, u32 *value)
83 plx90x0_write_config_byte (struct pci_dev *dev,
90 plx90x0_write_config_word (struct pci_dev *dev,
97 plx90x0_write_config_dword (struct pci_dev *dev,
104 plx_syserr_handler(int irq, void *handle, struct pt_regs *regs)
106 printk("PLX90x0: machine check %04x (pc=%08lx)\n",
107 readw(PLX_BASE + 6), regs->ARM_pc);
108 __raw_writew(0xf000, PLX_BASE + 6);
111 static struct pci_ops
114 plx90x0_read_config_byte,
115 plx90x0_read_config_word,
116 plx90x0_read_config_dword,
117 plx90x0_write_config_byte,
118 plx90x0_write_config_word,
119 plx90x0_write_config_dword,
123 * Initialise the PCI system.
127 plx90x0_init(struct arm_sysdata *sysdata)
129 static const unsigned long int base = PLX_BASE;
131 unsigned long bar = (unsigned long)virt_to_bus((void *)PAGE_OFFSET);
133 /* Have a sniff around and see which PLX device is present. */
134 unsigned long id = __raw_readl(base + 0xf0);
137 /* This check was a good idea, but can fail. The PLX9060 puts no
138 default value in these registers unless NB# is asserted (which it
139 isn't on these cards). */
140 if ((id & 0xffff) != PCI_VENDOR_ID_PLX)
141 return; /* Nothing found */
144 /* Found one - now work out what it is. */
146 case 0: /* PCI_DEVICE_ID_PLX_9060 */
149 case PCI_DEVICE_ID_PLX_9060ES:
152 case PCI_DEVICE_ID_PLX_9060SD:
153 what = "PCI9060SD"; /* uhuhh.. */
155 case PCI_DEVICE_ID_PLX_9080:
159 printk("PCI: Unknown PLX device %04lx found -- ignored.\n",
164 printk("PCI: PLX Technology %s host bridge found.\n", what);
166 /* Now set it up for both master and slave accesses. */
167 __raw_writel(0xffff0147, base + 0x4);
168 __raw_writeb(32, base + 0xd);
169 __raw_writel(0x8 | bar, base + 0x18);
170 __raw_writel(0xf8000008, base + 0x80);
171 __raw_writel(0x40000001, base + 0x84);
172 __raw_writel(0, base + 0x88);
173 __raw_writel(0, base + 0x8c);
174 __raw_writel(0x11, base + 0x94);
175 __raw_writel(0xC3 + (4 << 28)
176 + (8 << 11) + (1 << 10)
177 + (1 << 24), base + 0x98);
178 __raw_writel(0xC0000000, base + 0x9c);
179 __raw_writel(PLX_MEM_START, base + 0xa0);
180 __raw_writel(PLX_IO_START, base + 0xa4);
181 __raw_writel(0x3, base + 0xa8);
182 __raw_writel(0, base + 0xac);
183 __raw_writel(0x10001, base + 0xe8);
184 __raw_writel(0x8000767e, base + 0xec);
186 request_irq(IRQ_SYSERR, plx_syserr_handler, 0,
187 "system error", NULL);
189 pci_scan_bus(0, &plx90x0_ops, sysdata);