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>
18 #include <asm/hardware.h>
20 #include <asm/ptrace.h>
22 #include <asm/mach/pci.h>
25 * Since the following functions are all very similar, the common parts
26 * are pulled out into these macros.
29 #define PLX_CLEAR_CONFIG \
30 __raw_writel(0, PLX_BASE + 0xac); \
31 local_irq_restore(flags); }
33 #define PLX_SET_CONFIG \
34 { unsigned long flags; \
35 local_irq_save(flags); \
36 __raw_writel((1<<31 | (bus->number << 16) \
37 | (devfn << 8) | (where & ~3) \
38 | ((bus->number == 0)?0:1)), PLX_BASE + 0xac); \
40 #define PLX_CONFIG_WRITE(size) \
42 __raw_write##size(value, PCIO_BASE + (where & 3)); \
43 if (__raw_readw(PLX_BASE + 0x6) & 0x2000) \
44 __raw_writew(0x2000, PLX_BASE + 0x6); \
46 return PCIBIOS_SUCCESSFUL;
48 #define PLX_CONFIG_READ(size) \
50 *value = __raw_read##size(PCIO_BASE + (where & 3)); \
51 if (__raw_readw(PLX_BASE + 0x6) & 0x2000) { \
52 __raw_writew(0x2000, PLX_BASE + 0x6); \
53 *value = 0xffffffffUL; \
56 return PCIBIOS_SUCCESSFUL;
58 /* Configuration space access routines */
61 plx90x0_read_config (struct pci_bus *bus, unsigned int devfn, int where,
62 int where, int size, u32 *value)
75 return PCIBIOS_SUCCESSFUL;
79 plx90x0_write_config (struct pci_bus *bus, unsigned int devfn, int where,
80 int where, int size, u32 value)
93 return PCIBIOS_SUCCESSFUL;
96 static struct pci_ops plx90x0_ops =
98 .read = plx90x0_read_config,
99 .write = plx90x0_write_config,
103 plx_syserr_handler(int irq, void *handle, struct pt_regs *regs)
105 printk("PLX90x0: machine check %04x (pc=%08lx)\n",
106 readw(PLX_BASE + 6), regs->ARM_pc);
107 __raw_writew(0xf000, PLX_BASE + 6);
111 * Initialise the PCI system.
115 plx90x0_init(struct arm_sysdata *sysdata)
117 static const unsigned long int base = PLX_BASE;
119 unsigned long bar = (unsigned long)virt_to_bus((void *)PAGE_OFFSET);
121 /* Have a sniff around and see which PLX device is present. */
122 unsigned long id = __raw_readl(base + 0xf0);
125 /* This check was a good idea, but can fail. The PLX9060 puts no
126 default value in these registers unless NB# is asserted (which it
127 isn't on these cards). */
128 if ((id & 0xffff) != PCI_VENDOR_ID_PLX)
129 return; /* Nothing found */
132 /* Found one - now work out what it is. */
134 case 0: /* PCI_DEVICE_ID_PLX_9060 */
137 case PCI_DEVICE_ID_PLX_9060ES:
140 case PCI_DEVICE_ID_PLX_9060SD:
141 what = "PCI9060SD"; /* uhuhh.. */
143 case PCI_DEVICE_ID_PLX_9080:
147 printk("PCI: Unknown PLX device %04lx found -- ignored.\n",
152 printk("PCI: PLX Technology %s host bridge found.\n", what);
154 /* Now set it up for both master and slave accesses. */
155 __raw_writel(0xffff0147, base + 0x4);
156 __raw_writeb(32, base + 0xd);
157 __raw_writel(0x8 | bar, base + 0x18);
158 __raw_writel(0xf8000008, base + 0x80);
159 __raw_writel(0x40000001, base + 0x84);
160 __raw_writel(0, base + 0x88);
161 __raw_writel(0, base + 0x8c);
162 __raw_writel(0x11, base + 0x94);
163 __raw_writel(0xC3 + (4 << 28)
164 + (8 << 11) + (1 << 10)
165 + (1 << 24), base + 0x98);
166 __raw_writel(0xC0000000, base + 0x9c);
167 __raw_writel(PLX_MEM_START, base + 0xa0);
168 __raw_writel(PLX_IO_START, base + 0xa4);
169 __raw_writel(0x3, base + 0xa8);
170 __raw_writel(0, base + 0xac);
171 __raw_writel(0x10001, base + 0xe8);
172 __raw_writel(0x8000767e, base + 0xec);
174 request_irq(IRQ_SYSERR, plx_syserr_handler, 0,
175 "system error", NULL);
177 pci_scan_bus(0, &plx90x0_ops, sysdata);