2 #include <console/console.h>
3 #include <device/device.h>
4 #include <device/pci.h>
5 #include <device/pci_ops.h>
6 #include <device/pci_ids.h>
8 #include <pc80/mc146818rtc.h>
14 * Taken some liberties - changed irq structures to pins numbers so that it is
15 * easier to change PCI irq assignments without having to change each PCI
16 * function individually
18 * pciIrqs contains the irqs assigned for PCI pins A-D
20 * Setting will depend on motherboard as irqs can be quite scarce e.g on
21 * EPIA-MII, 16 bit CF card wants a dedicated IRQ. A 16 bit card in pcmcia
22 * socket may want another - for now only claim 3 interupts for PCI, leaving at
23 * least one spare for CF. On EPIA-M one could allocated all four irqs to
24 * different numbers since there are no cardbus devices
27 static const unsigned char pciIrqs[4] = { 11 , 5, 10 , 12 };
29 static const unsigned char usbPins[4] = { 'A','B','C','D'};
30 static const unsigned char enetPins[4] = { 'A','B','C','D'};
31 static const unsigned char slotPins[4] = { 'B','C','D','A'};
32 static const unsigned char firewirePins[4] = { 'B','C','D','A'};
33 static const unsigned char vt8235Pins[4] = { 'A','B','C','D'};
34 static const unsigned char vgaPins[4] = { 'A','B','C','D'};
35 static const unsigned char cbPins[4] = { 'A','B','C','D'};
36 static const unsigned char riserPins[4] = { 'A','B','C','D'};
39 Our IDSEL mappings are as follows
40 PCI slot is AD31 (device 15) (00:14.0)
41 Southbridge is AD28 (device 12) (00:11.0)
44 static unsigned char *pin_to_irq(const unsigned char *pin)
46 static unsigned char Irqs[4];
48 for (i = 0 ; i < 4 ; i++)
49 Irqs[i] = pciIrqs[ pin[i] - 'A' ];
54 static void pci_routing_fixup(struct device *dev)
56 printk_info("%s: dev is %p\n", __FUNCTION__, dev);
58 /* initialize PCI interupts - these assignments depend
59 on the PCB routing of PINTA-D
66 pci_write_config8(dev, 0x55, pciIrqs[0] << 4);
67 pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) );
68 pci_write_config8(dev, 0x57, pciIrqs[3] << 4);
71 // firewire built into southbridge
72 printk_info("setting firewire\n");
73 pci_assign_irqs(0, 0x0d, pin_to_irq(firewirePins));
75 // Standard usb components
76 printk_info("setting usb\n");
77 pci_assign_irqs(0, 0x10, pin_to_irq(usbPins));
79 // VT8235 + sound hardware
80 printk_info("setting vt8235\n");
81 pci_assign_irqs(0, 0x11, pin_to_irq(vt8235Pins));
83 // Ethernet built into southbridge
84 printk_info("setting ethernet\n");
85 pci_assign_irqs(0, 0x12, pin_to_irq(enetPins));
88 printk_info("setting vga\n");
89 pci_assign_irqs(1, 0x00, pin_to_irq(vgaPins));
92 printk_info("setting pci slot\n");
93 pci_assign_irqs(0, 0x14, pin_to_irq(slotPins));
96 printk_info("setting cardbus slot\n");
97 pci_assign_irqs(0, 0x0a, pin_to_irq(cbPins));
99 // Via 2 slot riser card 2nd slot
100 printk_info("setting riser slot\n");
101 pci_assign_irqs(0, 0x13, pin_to_irq(riserPins));
103 printk_spew("%s: DONE\n", __FUNCTION__);
107 * Set up the power management capabilities directly into ACPI mode. This
108 * avoids having to handle any System Management Interrupts (SMI's) which I
109 * can't figure out how to do !!!!
112 void setup_pm(device_t dev)
116 pci_write_config8(dev, 0x80, 0x20);
118 // Set ACPI base address to IO 0x4000
119 pci_write_config16(dev, 0x88, 0x0401);
122 pci_write_config8(dev, 0x82, 0x45);
124 // primary interupt channel
125 pci_write_config16(dev, 0x84, 0x30f2);
127 // throttle / stop clock control
128 pci_write_config8(dev, 0x8d, 0x18);
130 pci_write_config8(dev, 0x93, 0x88);
131 pci_write_config8(dev, 0x94, 0xb0);
132 pci_write_config8(dev, 0x95, 0xc0);
133 pci_write_config8(dev, 0x98, 0);
134 pci_write_config8(dev, 0x99, 0xea);
135 pci_write_config8(dev, 0xe4, 0x14);
136 pci_write_config8(dev, 0xe5, 0x08);
139 // Enable ACPI access (and setup like award)
140 pci_write_config8(dev, 0x81, 0x84);
145 outl(0xffffffff, 0x430);
153 outl(0xffff7fff, 0x448);
157 static void vt8235_init(struct device *dev)
159 unsigned char enables;
161 printk_debug("vt8235 init\n");
163 // enable the internal I/O decode
164 enables = pci_read_config8(dev, 0x6C);
166 pci_write_config8(dev, 0x6C, enables);
168 // Map 4MB of FLASH into the address space
169 pci_write_config8(dev, 0x41, 0x7f);
171 // Set bit 6 of 0x40, because Award does it (IO recovery time)
172 // IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI
173 // interrupts can be properly marked as level triggered.
174 enables = pci_read_config8(dev, 0x40);
176 pci_write_config8(dev, 0x40, enables);
178 // Set 0x42 to 0xf0 to match Award bios
179 enables = pci_read_config8(dev, 0x42);
181 pci_write_config8(dev, 0x42, enables);
183 /* Set 0x58 to 0x03 to match Award */
184 pci_write_config8(dev, 0x58, 0x03);
186 /* Set bit 3 of 0x4f to match award (use INIT# as cpu reset) */
187 enables = pci_read_config8(dev, 0x4f);
189 pci_write_config8(dev, 0x4f, enables);
191 // Set bit 3 of 0x4a, to match award (dummy pci request)
192 enables = pci_read_config8(dev, 0x4a);
194 pci_write_config8(dev, 0x4a, enables);
196 // Set bit 3 of 0x4f to match award (use INIT# as cpu reset)
197 enables = pci_read_config8(dev, 0x4f);
199 pci_write_config8(dev, 0x4f, enables);
201 // Set 0x58 to 0x03 to match Award
202 pci_write_config8(dev, 0x58, 0x03);
204 // enable the ethernet/RTC
206 enables = pci_read_config8(dev, 0x51);
208 pci_write_config8(dev, 0x51, enables);
211 /* enable serial irq */
212 pci_write_config8(dev, 0x52, 0x9);
215 pci_write_config8(dev, 0x53, 0x00);
217 // Power management setup
220 /* set up isa bus -- i/o recovery time, rom write enable, extend-ale */
221 pci_write_config8(dev, 0x40, 0x54);
227 static void southbridge_init(struct device *dev)
230 pci_routing_fixup(dev);
233 static struct device_operations vt8235_lpc_ops = {
234 .read_resources = pci_dev_read_resources,
235 .set_resources = pci_dev_set_resources,
236 .enable_resources = pci_dev_enable_resources,
237 .init = &southbridge_init,
238 .scan_bus = scan_static_bus,
241 static struct pci_driver lpc_driver __pci_driver = {
242 .ops = &vt8235_lpc_ops,
243 .vendor = PCI_VENDOR_ID_VIA,
244 .device = PCI_DEVICE_ID_VIA_8235,