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>
13 /* The epia-m is really short on interrupts available, so PCI interupts A & D are ganged togther and so are B & C.
14 This is how the Award bios sets it up too.
15 epia can be more generous as it does not need to reserve interrupts for cardbus devices, but if changed then
16 make sure that ACPI dsdt is changed to suit.
23 IRQ 5 = available for PCI interrupts
24 IRQ 6 = floppy or availbale for PCI if floppy controller disabled
25 IRQ 7 = LPT or available if LPT port disabled
27 IRQ 9 = available for PCI interrupts
28 IRQ 10 = cardbus slot or available for PCI if no cardbus (ie epia)
29 IRQ 11 = cardbus slot or available for PCI if no cardbus (ie epia)
30 IRQ 12 = PS2 mouse (hardwired to 12)
31 IRQ 13 = legacy FPU interrupt
32 IRQ 14 = IDE controller 1
33 IRQ 15 = IDE controller 2
36 static const unsigned char pciIrqs[4] = { 5 , 9 , 9, 5 };
38 static const unsigned char usbPins[4] = { 'A','B','C','D'};
39 static const unsigned char enetPins[4] = { 'A','B','C','D'};
40 static const unsigned char slotPins[4] = { 'B','C','D','A'};
41 static const unsigned char firewirePins[4] = { 'B','C','D','A'};
42 static const unsigned char vt8235Pins[4] = { 'A','B','C','D'};
43 static const unsigned char vgaPins[4] = { 'A','B','C','D'};
44 static const unsigned char cbPins[4] = { 'A','B','C','D'};
45 static const unsigned char riserPins[4] = { 'A','B','C','D'};
48 static unsigned char *pin_to_irq(const unsigned char *pin)
50 static unsigned char Irqs[4];
52 for (i = 0 ; i < 4 ; i++)
53 Irqs[i] = pciIrqs[ pin[i] - 'A' ];
58 static void pci_routing_fixup(struct device *dev)
60 printk_info("%s: dev is %p\n", __FUNCTION__, dev);
62 /* set up PCI IRQ routing */
63 pci_write_config8(dev, 0x55, pciIrqs[0] << 4);
64 pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) );
65 pci_write_config8(dev, 0x57, pciIrqs[3] << 4);
68 // firewire built into southbridge
69 printk_info("setting firewire\n");
70 pci_assign_irqs(0, 0x0d, pin_to_irq(firewirePins));
72 // Standard usb components
73 printk_info("setting usb\n");
74 pci_assign_irqs(0, 0x10, pin_to_irq(usbPins));
76 // VT8235 + sound hardware
77 printk_info("setting vt8235\n");
78 pci_assign_irqs(0, 0x11, pin_to_irq(vt8235Pins));
80 // Ethernet built into southbridge
81 printk_info("setting ethernet\n");
82 pci_assign_irqs(0, 0x12, pin_to_irq(enetPins));
85 printk_info("setting vga\n");
86 pci_assign_irqs(1, 0x00, pin_to_irq(vgaPins));
89 printk_info("setting pci slot\n");
90 pci_assign_irqs(0, 0x14, pin_to_irq(slotPins));
93 printk_info("setting cardbus slot\n");
94 pci_assign_irqs(0, 0x0a, pin_to_irq(cbPins));
96 // Via 2 slot riser card 2nd slot
97 printk_info("setting riser slot\n");
98 pci_assign_irqs(0, 0x13, pin_to_irq(riserPins));
100 printk_spew("%s: DONE\n", __FUNCTION__);
104 * Set up the power management capabilities directly into ACPI mode. This
105 * avoids having to handle any System Management Interrupts (SMI's) which I
106 * can't figure out how to do !!!!
109 void setup_pm(device_t dev)
113 pci_write_config8(dev, 0x80, 0x20);
115 // Set ACPI base address to IO 0x4000
116 pci_write_config16(dev, 0x88, 0x0401);
119 pci_write_config8(dev, 0x82, 0x45);
121 // primary interupt channel
122 pci_write_config16(dev, 0x84, 0x30f2);
124 // throttle / stop clock control
125 pci_write_config8(dev, 0x8d, 0x18);
127 pci_write_config8(dev, 0x93, 0x88);
128 pci_write_config8(dev, 0x94, 0xb0);
129 pci_write_config8(dev, 0x95, 0xc0);
130 pci_write_config8(dev, 0x98, 0);
131 pci_write_config8(dev, 0x99, 0xea);
132 pci_write_config8(dev, 0xe4, 0x14);
133 pci_write_config8(dev, 0xe5, 0x08);
136 // Enable ACPI access (and setup like award)
137 pci_write_config8(dev, 0x81, 0x84);
142 outl(0xffffffff, 0x430);
150 outl(0xffff7fff, 0x448);
154 static void vt8235_init(struct device *dev)
156 unsigned char enables;
158 printk_debug("vt8235 init\n");
160 // enable the internal I/O decode
161 enables = pci_read_config8(dev, 0x6C);
163 pci_write_config8(dev, 0x6C, enables);
165 // Map 4MB of FLASH into the address space
166 pci_write_config8(dev, 0x41, 0x7f);
168 // Set bit 6 of 0x40, because Award does it (IO recovery time)
169 // IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI
170 // interrupts can be properly marked as level triggered.
171 enables = pci_read_config8(dev, 0x40);
173 pci_write_config8(dev, 0x40, enables);
175 // Set 0x42 to 0xf0 to match Award bios
176 enables = pci_read_config8(dev, 0x42);
178 pci_write_config8(dev, 0x42, enables);
180 /* Set 0x58 to 0x03 to match Award */
181 pci_write_config8(dev, 0x58, 0x03);
183 /* Set bit 3 of 0x4f to match award (use INIT# as cpu reset) */
184 enables = pci_read_config8(dev, 0x4f);
186 pci_write_config8(dev, 0x4f, enables);
188 // Set bit 3 of 0x4a, to match award (dummy pci request)
189 enables = pci_read_config8(dev, 0x4a);
191 pci_write_config8(dev, 0x4a, enables);
193 // Set bit 3 of 0x4f to match award (use INIT# as cpu reset)
194 enables = pci_read_config8(dev, 0x4f);
196 pci_write_config8(dev, 0x4f, enables);
198 // Set 0x58 to 0x03 to match Award
199 pci_write_config8(dev, 0x58, 0x03);
202 /* enable serial irq */
203 pci_write_config8(dev, 0x52, 0x9);
206 pci_write_config8(dev, 0x53, 0x00);
208 // Power management setup
211 /* set up isa bus -- i/o recovery time, rom write enable, extend-ale */
212 pci_write_config8(dev, 0x40, 0x54);
218 /* total kludge to get lxb to call our childrens set/enable functions - these are not called unless this
219 device has a resource to set - so set a dummy one */
220 void vt8235_read_resources(device_t dev)
223 struct resource *resource;
224 pci_dev_read_resources(dev);
225 resource = new_resource(dev, 1);
226 resource->flags |= IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IO | IORESOURCE_STORED;
228 resource->base = 0x2e;
231 void vt8235_set_resources(device_t dev)
233 struct resource *resource;
234 //resource = find_resource(dev,1);
235 //resource->flags |= IORESOURCE_STORED;
236 pci_dev_set_resources(dev);
239 void vt8235_enable_resources(device_t dev)
241 /* vt8235 is not a pci bridge and has no resources of its own (other than standard PC i/o addresses)
242 however it does control the isa bus and so we need to manually call enable childrens resources on that bus */
243 pci_dev_enable_resources(dev);
244 enable_childrens_resources(dev);
248 static void southbridge_init(struct device *dev)
251 pci_routing_fixup(dev);
254 static struct device_operations vt8235_lpc_ops = {
255 .read_resources = vt8235_read_resources,
256 .set_resources = vt8235_set_resources,
257 .enable_resources = vt8235_enable_resources,
258 .init = &southbridge_init,
259 .scan_bus = scan_static_bus,
262 static struct pci_driver lpc_driver __pci_driver = {
263 .ops = &vt8235_lpc_ops,
264 .vendor = PCI_VENDOR_ID_VIA,
265 .device = PCI_DEVICE_ID_VIA_8235,