eric patch
[coreboot.git] / src / southbridge / intel / pxhd / pxhd_bridge.c
blobbceca29db94226ae4f1061dcedd6a13a158f43e9
1 /*
2 * (C) 2003-2004 Linux Networx
3 */
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>
11 #include <delay.h>
12 #include "pxhd.h"
14 static void pxhd_enable(device_t dev)
16 device_t bridge;
17 uint16_t value;
18 if ((dev->path.u.pci.devfn & 1) == 0) {
19 /* Can we enable/disable the bridges? */
20 return;
22 bridge = dev_find_slot(dev->bus->secondary, dev->path.u.pci.devfn & ~1);
23 if (!bridge) {
24 printk_err("Cannot find bridge for ioapic: %s\n",
25 dev_path(dev));
26 return;
28 value = pci_read_config16(bridge, 0x40);
29 value &= ~(1 << 13);
30 if (!dev->enabled) {
31 value |= (1 << 13);
33 pci_write_config16(bridge, 0x40, value);
37 #define NMI_OFF 0
39 static unsigned int pxhd_scan_bridge(device_t dev, unsigned int max)
41 int bus_100Mhz = 0;
43 dev->link[0].dev = dev;
44 dev->links = 1;
46 get_option(&bus_100Mhz, "pxhd_bus_speed_100");
47 if(bus_100Mhz) {
48 uint16_t word;
50 printk_debug("setting pxhd bus to 100 Mhz\n");
51 /* set to pcix 100 mhz */
52 word = pci_read_config16(dev, 0x40);
53 word &= ~(3 << 14);
54 word |= (1 << 14);
55 word &= ~(3 << 9);
56 word |= (2 << 9);
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)
66 uint32_t dword;
67 uint16_t word;
68 uint8_t byte;
69 int nmi_option;
71 /* Bridge control ISA enable */
72 pci_write_config8(dev, 0x3e, 0x07);
74 #if 0
76 /* Enable memory write and invalidate ??? */
77 byte = pci_read_config8(dev, 0x04);
78 byte |= 0x10;
79 pci_write_config8(dev, 0x04, byte);
81 /* Set drive strength */
82 word = pci_read_config16(dev, 0xe0);
83 word = 0x0404;
84 pci_write_config16(dev, 0xe0, word);
85 word = pci_read_config16(dev, 0xe4);
86 word = 0x0404;
87 pci_write_config16(dev, 0xe4, word);
89 /* Set impedance */
90 word = pci_read_config16(dev, 0xe8);
91 word = 0x0404;
92 pci_write_config16(dev, 0xe8, word);
94 /* Set discard unrequested prefetch data */
95 word = pci_read_config16(dev, 0x4c);
96 word |= 1;
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);
108 dword |= (1<<8);
109 pci_write_config32(dev, 0x04, dword);
111 /* system and error parity enable */
112 dword = pci_read_config32(dev, 0x3c);
113 dword |= (3<<16);
114 pci_write_config32(dev, 0x3c, dword);
116 /* NMI enable */
117 nmi_option = NMI_OFF;
118 get_option(&nmi_option, "nmi");
119 if(nmi_option) {
120 dword = pci_read_config32(dev, 0x44);
121 dword |= (1<<0);
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);
129 dword |= (1<<1);
130 pci_write_config32(dev, 0xc4, dword);
131 dword = pci_read_config32(dev, 0xc8);
132 dword |= (1<<1);
133 pci_write_config32(dev, 0xc8, dword);
136 return;
137 #endif
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,
144 .init = pcix_init,
145 .scan_bus = pxhd_scan_bridge,
146 .reset_bus = pci_bus_reset,
147 .ops_pci = 0,
150 static struct pci_driver pcix_driver __pci_driver = {
151 .ops = &pcix_ops,
152 .vendor = PCI_VENDOR_ID_INTEL,
153 .device = 0x0329,
156 static struct pci_driver pcix_driver2 __pci_driver = {
157 .ops = &pcix_ops,
158 .vendor = PCI_VENDOR_ID_INTEL,
159 .device = 0x032a,
162 #define ALL (0xff << 24)
163 #define NONE (0)
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)
173 #define NMI (4 << 8)
174 #define SMI (2 << 8)
175 #define INT (1 << 8)
176 /* IO-APIC virtual wire mode configuration */
177 /* mask, trigger, polarity, destination, delivery, vector */
179 static void setup_ioapic(device_t dev)
181 int i;
182 unsigned long value_low, value_high;
183 unsigned long ioapic_base;
184 volatile unsigned long *l;
185 unsigned interrupts;
187 ioapic_base = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
188 l = (unsigned long *) ioapic_base;
190 /* Enable front side bus delivery */
191 l[0] = 0x03;
192 l[4] = 1;
194 l[0] = 0x01;
195 interrupts = (l[04] >> 16) & 0xff;
196 for (i = 0; i < interrupts; i++) {
197 l[0] = (i * 2) + 0x10;
198 l[4] = DISABLED;
199 value_low = l[4];
200 l[0] = (i * 2) + 0x11;
201 l[4] = NONE; /* Should this be an address? */
202 value_high = l[4];
203 if (value_low == 0xffffffff) {
204 printk_warning("IO APIC not responding.\n");
205 return;
210 static void ioapic_init(device_t dev)
212 uint32_t value;
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);
218 setup_ioapic(dev);
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,
235 .init = ioapic_init,
236 .scan_bus = 0,
237 .enable = pxhd_enable,
238 .ops_pci = &intel_ops_pci,
241 static struct pci_driver ioapic_driver __pci_driver = {
242 .ops = &ioapic_ops,
243 .vendor = PCI_VENDOR_ID_INTEL,
244 .device = 0x0326,
248 static struct pci_driver ioapic2_driver __pci_driver = {
249 .ops = &ioapic_ops,
250 .vendor = PCI_VENDOR_ID_INTEL,
251 .device = 0x0327,
255 struct chip_operations southbridge_intel_pxhd_ops = {
256 CHIP_NAME("PXHD")
257 .enable_dev = pxhd_enable,