2 * (C) 2003-2004 Linux Networx
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <device/pci.h>
7 #include <device/pci_ids.h>
8 #include <device/pci_ops.h>
9 #include <device/pcix.h>
10 #include <pc80/mc146818rtc.h>
14 static void pxhd_enable(device_t dev)
18 if ((dev->path.pci.devfn & 1) == 0) {
19 /* Can we enable/disable the bridges? */
22 bridge = dev_find_slot(dev->bus->secondary, dev->path.pci.devfn & ~1);
24 printk_err("Cannot find bridge for ioapic: %s\n",
28 value = pci_read_config16(bridge, 0x40);
33 pci_write_config16(bridge, 0x40, value);
39 static unsigned int pxhd_scan_bridge(device_t dev, unsigned int max)
43 dev->link[0].dev = dev;
46 get_option(&bus_100Mhz, "pxhd_bus_speed_100");
50 printk_debug("setting pxhd bus to 100 Mhz\n");
51 /* set to pcix 100 mhz */
52 word = pci_read_config16(dev, 0x40);
57 pci_write_config16(dev, 0x40, word);
59 /* reset the bus to make the new frequencies effective */
60 pci_bus_reset(&dev->link[0]);
62 return pcix_scan_bridge(dev, max);
64 static void pcix_init(device_t dev)
71 /* Bridge control ISA enable */
72 pci_write_config8(dev, 0x3e, 0x07);
76 /* Enable memory write and invalidate ??? */
77 byte = pci_read_config8(dev, 0x04);
79 pci_write_config8(dev, 0x04, byte);
81 /* Set drive strength */
82 word = pci_read_config16(dev, 0xe0);
84 pci_write_config16(dev, 0xe0, word);
85 word = pci_read_config16(dev, 0xe4);
87 pci_write_config16(dev, 0xe4, word);
90 word = pci_read_config16(dev, 0xe8);
92 pci_write_config16(dev, 0xe8, word);
94 /* Set discard unrequested prefetch data */
95 word = pci_read_config16(dev, 0x4c);
97 pci_write_config16(dev, 0x4c, word);
99 /* Set split transaction limits */
100 word = pci_read_config16(dev, 0xa8);
101 pci_write_config16(dev, 0xaa, word);
102 word = pci_read_config16(dev, 0xac);
103 pci_write_config16(dev, 0xae, word);
105 /* Set up error reporting, enable all */
106 /* system error enable */
107 dword = pci_read_config32(dev, 0x04);
109 pci_write_config32(dev, 0x04, dword);
111 /* system and error parity enable */
112 dword = pci_read_config32(dev, 0x3c);
114 pci_write_config32(dev, 0x3c, dword);
117 nmi_option = NMI_OFF;
118 get_option(&nmi_option, "nmi");
120 dword = pci_read_config32(dev, 0x44);
122 pci_write_config32(dev, 0x44, dword);
125 /* Set up CRC flood enable */
126 dword = pci_read_config32(dev, 0xc0);
127 if(dword) { /* do device A only */
128 dword = pci_read_config32(dev, 0xc4);
130 pci_write_config32(dev, 0xc4, dword);
131 dword = pci_read_config32(dev, 0xc8);
133 pci_write_config32(dev, 0xc8, dword);
140 static struct device_operations pcix_ops = {
141 .read_resources = pci_bus_read_resources,
142 .set_resources = pci_dev_set_resources,
143 .enable_resources = pci_bus_enable_resources,
145 .scan_bus = pxhd_scan_bridge,
146 .reset_bus = pci_bus_reset,
150 static const struct pci_driver pcix_driver __pci_driver = {
152 .vendor = PCI_VENDOR_ID_INTEL,
156 static const struct pci_driver pcix_driver2 __pci_driver = {
158 .vendor = PCI_VENDOR_ID_INTEL,
162 #define ALL (0xff << 24)
164 #define DISABLED (1 << 16)
165 #define ENABLED (0 << 16)
166 #define TRIGGER_EDGE (0 << 15)
167 #define TRIGGER_LEVEL (1 << 15)
168 #define POLARITY_HIGH (0 << 13)
169 #define POLARITY_LOW (1 << 13)
170 #define PHYSICAL_DEST (0 << 11)
171 #define LOGICAL_DEST (1 << 11)
172 #define ExtINT (7 << 8)
176 /* IO-APIC virtual wire mode configuration */
177 /* mask, trigger, polarity, destination, delivery, vector */
179 static void setup_ioapic(device_t dev)
182 unsigned long value_low, value_high;
183 unsigned long ioapic_base;
184 volatile unsigned long *l;
187 ioapic_base = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
188 l = (unsigned long *) ioapic_base;
190 /* Enable front side bus delivery */
195 interrupts = (l[04] >> 16) & 0xff;
196 for (i = 0; i < interrupts; i++) {
197 l[0] = (i * 2) + 0x10;
200 l[0] = (i * 2) + 0x11;
201 l[4] = NONE; /* Should this be an address? */
203 if (value_low == 0xffffffff) {
204 printk_warning("IO APIC not responding.\n");
210 static void ioapic_init(device_t dev)
213 /* Enable bus mastering so IOAPICs work */
214 value = pci_read_config16(dev, PCI_COMMAND);
215 value |= PCI_COMMAND_MASTER;
216 pci_write_config16(dev, PCI_COMMAND, value);
221 static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device)
223 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
224 ((device & 0xffff) << 16) | (vendor & 0xffff));
227 static struct pci_operations intel_ops_pci = {
228 .set_subsystem = intel_set_subsystem,
231 static struct device_operations ioapic_ops = {
232 .read_resources = pci_dev_read_resources,
233 .set_resources = pci_dev_set_resources,
234 .enable_resources = pci_dev_enable_resources,
237 .enable = pxhd_enable,
238 .ops_pci = &intel_ops_pci,
241 static const struct pci_driver ioapic_driver __pci_driver = {
243 .vendor = PCI_VENDOR_ID_INTEL,
248 static const struct pci_driver ioapic2_driver __pci_driver = {
250 .vendor = PCI_VENDOR_ID_INTEL,
255 struct chip_operations southbridge_intel_pxhd_ops = {
256 CHIP_NAME("Intel PXHD Southbridge")
257 .enable_dev = pxhd_enable,