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>
7 #include <pc80/mc146818rtc.h>
8 #include <arch/ioapic.h>
11 /* The epia-m is really short on interrupts available, so PCI interupts A & D are ganged togther and so are B & C.
12 This is how the Award bios sets it up too.
13 epia can be more generous as it does not need to reserve interrupts for cardbus devices, but if changed then
14 make sure that ACPI dsdt is changed to suit.
21 IRQ 5 = available for PCI interrupts
22 IRQ 6 = floppy or availbale for PCI if floppy controller disabled
23 IRQ 7 = LPT or available if LPT port disabled
25 IRQ 9 = available for PCI interrupts
26 IRQ 10 = cardbus slot or available for PCI if no cardbus (ie epia)
27 IRQ 11 = cardbus slot or available for PCI if no cardbus (ie epia)
28 IRQ 12 = PS2 mouse (hardwired to 12)
29 IRQ 13 = legacy FPU interrupt
30 IRQ 14 = IDE controller 1
31 IRQ 15 = IDE controller 2
34 static const unsigned char pciIrqs[4] = { 5 , 9 , 9, 5 };
36 static const unsigned char usbPins[4] = { 'A','B','C','D'};
37 static const unsigned char enetPins[4] = { 'A','B','C','D'};
38 static const unsigned char slotPins[4] = { 'B','C','D','A'};
39 static const unsigned char firewirePins[4] = { 'B','C','D','A'};
40 static const unsigned char vt8235Pins[4] = { 'A','B','C','D'};
41 static const unsigned char vgaPins[4] = { 'A','B','C','D'};
42 static const unsigned char cbPins[4] = { 'A','B','C','D'};
43 static const unsigned char riserPins[4] = { 'A','B','C','D'};
46 static unsigned char *pin_to_irq(const unsigned char *pin)
48 static unsigned char Irqs[4];
50 for (i = 0 ; i < 4 ; i++)
51 Irqs[i] = pciIrqs[ pin[i] - 'A' ];
56 static void pci_routing_fixup(struct device *dev)
58 printk(BIOS_INFO, "%s: dev is %p\n", __func__, dev);
60 /* set up PCI IRQ routing */
61 pci_write_config8(dev, 0x55, pciIrqs[0] << 4);
62 pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) );
63 pci_write_config8(dev, 0x57, pciIrqs[3] << 4);
66 // firewire built into southbridge
67 printk(BIOS_INFO, "setting firewire\n");
68 pci_assign_irqs(0, 0x0d, pin_to_irq(firewirePins));
70 // Standard usb components
71 printk(BIOS_INFO, "setting usb\n");
72 pci_assign_irqs(0, 0x10, pin_to_irq(usbPins));
74 // VT8235 + sound hardware
75 printk(BIOS_INFO, "setting vt8235\n");
76 pci_assign_irqs(0, 0x11, pin_to_irq(vt8235Pins));
78 // Ethernet built into southbridge
79 printk(BIOS_INFO, "setting ethernet\n");
80 pci_assign_irqs(0, 0x12, pin_to_irq(enetPins));
83 printk(BIOS_INFO, "setting vga\n");
84 pci_assign_irqs(1, 0x00, pin_to_irq(vgaPins));
87 printk(BIOS_INFO, "setting pci slot\n");
88 pci_assign_irqs(0, 0x14, pin_to_irq(slotPins));
91 printk(BIOS_INFO, "setting cardbus slot\n");
92 pci_assign_irqs(0, 0x0a, pin_to_irq(cbPins));
94 // Via 2 slot riser card 2nd slot
95 printk(BIOS_INFO, "setting riser slot\n");
96 pci_assign_irqs(0, 0x13, pin_to_irq(riserPins));
98 printk(BIOS_SPEW, "%s: DONE\n", __func__);
102 * Set up the power management capabilities directly into ACPI mode. This
103 * avoids having to handle any System Management Interrupts (SMI's) which I
104 * can't figure out how to do !!!!
107 static void setup_pm(device_t dev)
110 pci_write_config8(dev, 0x80, 0x20);
112 // Set ACPI base address to IO 0x400
113 pci_write_config16(dev, 0x88, 0x0401);
116 pci_write_config8(dev, 0x82, 0x45);
118 // primary interupt channel
119 pci_write_config16(dev, 0x84, 0x30f2);
121 // throttle / stop clock control
122 pci_write_config8(dev, 0x8d, 0x18);
124 pci_write_config8(dev, 0x93, 0x88);
125 pci_write_config8(dev, 0x94, 0xb0);
126 pci_write_config8(dev, 0x95, 0xc0);
127 pci_write_config8(dev, 0x98, 0);
128 pci_write_config8(dev, 0x99, 0xea);
129 pci_write_config8(dev, 0xe4, 0x14);
130 pci_write_config8(dev, 0xe5, 0x08);
133 // Enable ACPI access (and setup like award)
134 pci_write_config8(dev, 0x81, 0x84);
139 outl(0xffffffff, 0x430);
147 outl(0xffff7fff, 0x448);
151 static void vt8235_init(struct device *dev)
153 unsigned char enables;
155 printk(BIOS_DEBUG, "vt8235 init\n");
157 // enable the internal I/O decode
158 enables = pci_read_config8(dev, 0x6C);
160 pci_write_config8(dev, 0x6C, enables);
162 // Map 4MB of FLASH into the address space
163 pci_write_config8(dev, 0x41, 0x7f);
165 // Set bit 6 of 0x40, because Award does it (IO recovery time)
166 // IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI
167 // interrupts can be properly marked as level triggered.
168 enables = pci_read_config8(dev, 0x40);
170 pci_write_config8(dev, 0x40, enables);
172 // Set 0x42 to 0xf0 to match Award bios
173 enables = pci_read_config8(dev, 0x42);
175 pci_write_config8(dev, 0x42, enables);
177 /* Set 0x58 to 0x03 to match Award */
178 pci_write_config8(dev, 0x58, 0x03);
180 /* Set bit 3 of 0x4f to match award (use INIT# as cpu reset) */
181 enables = pci_read_config8(dev, 0x4f);
183 pci_write_config8(dev, 0x4f, enables);
185 // Set bit 3 of 0x4a, to match award (dummy pci request)
186 enables = pci_read_config8(dev, 0x4a);
188 pci_write_config8(dev, 0x4a, enables);
190 // Set bit 3 of 0x4f to match award (use INIT# as cpu reset)
191 enables = pci_read_config8(dev, 0x4f);
193 pci_write_config8(dev, 0x4f, enables);
195 // Set 0x58 to 0x03 to match Award
196 pci_write_config8(dev, 0x58, 0x03);
199 /* enable serial irq */
200 pci_write_config8(dev, 0x52, 0x9);
203 pci_write_config8(dev, 0x53, 0x00);
205 // Power management setup
208 /* set up isa bus -- i/o recovery time, rom write enable, extend-ale */
209 pci_write_config8(dev, 0x40, 0x54);
215 /* total kludge to get lxb to call our childrens set/enable functions - these are not called unless this
216 device has a resource to set - so set a dummy one */
217 static void vt8235_read_resources(device_t dev)
219 struct resource *res;
221 pci_dev_read_resources(dev);
223 res = new_resource(dev, 1);
225 res->size = 0x1000UL;
226 res->limit = 0xffffUL;
227 res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
229 res = new_resource(dev, 3); /* IOAPIC */
230 res->base = IO_APIC_ADDR;
231 res->size = 0x00001000;
232 res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
235 static void vt8235_set_resources(device_t dev)
237 //struct resource *resource;
238 //resource = find_resource(dev,1);
239 //resource->flags |= IORESOURCE_STORED;
240 pci_dev_set_resources(dev);
243 static void southbridge_init(struct device *dev)
246 pci_routing_fixup(dev);
249 static struct device_operations vt8235_lpc_ops = {
250 .read_resources = vt8235_read_resources,
251 .set_resources = vt8235_set_resources,
252 .enable_resources = pci_dev_enable_resources,
253 .init = southbridge_init,
254 .scan_bus = scan_static_bus,
257 static const struct pci_driver lpc_driver __pci_driver = {
258 .ops = &vt8235_lpc_ops,
259 .vendor = PCI_VENDOR_ID_VIA,
260 .device = PCI_DEVICE_ID_VIA_8235,