15ff5392b2a60db7f17f2284a96563f79cabfa97
[coreboot.git] / src / southbridge / via / vt8235 / vt8235_lpc.c
1 #include <arch/io.h>
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
8 #include <pc80/mc146818rtc.h>
9
10 #include "chip.h"
11
12 /* The epia-m is really short on interrupts available, so PCI interupts A & D are ganged togther and so are B & C.
13    This is how the Award bios sets it up too.
14    epia can be more generous as it does not need to reserve interrupts for cardbus devices, but if changed then
15    make sure that ACPI dsdt is changed to suit.
16
17         IRQ 0 = timer
18         IRQ 1 = keyboard
19         IRQ 2 = cascade
20         IRQ 3 = COM 2
21         IRQ 4 = COM 1
22         IRQ 5 = available for PCI interrupts
23         IRQ 6 = floppy or availbale for PCI if floppy controller disabled
24         IRQ 7 = LPT or available if LPT port disabled
25         IRQ 8 = rtc
26         IRQ 9 = available for PCI interrupts
27         IRQ 10 = cardbus slot or available for PCI if no cardbus (ie epia)
28         IRQ 11 = cardbus slot or available for PCI if no cardbus (ie epia)
29         IRQ 12 = PS2 mouse (hardwired to 12)
30         IRQ 13 = legacy FPU interrupt
31         IRQ 14 = IDE controller 1
32         IRQ 15 = IDE controller 2
33
34 */
35 static const unsigned char pciIrqs[4] = { 5 , 9 , 9, 5 };
36
37 static const unsigned char usbPins[4] =      { 'A','B','C','D'};
38 static const unsigned char enetPins[4] =     { 'A','B','C','D'};
39 static const unsigned char slotPins[4] =     { 'B','C','D','A'};
40 static const unsigned char firewirePins[4] = { 'B','C','D','A'};
41 static const unsigned char vt8235Pins[4] =   { 'A','B','C','D'};
42 static const unsigned char vgaPins[4] =      { 'A','B','C','D'};
43 static const unsigned char cbPins[4] =       { 'A','B','C','D'};
44 static const unsigned char riserPins[4] =    { 'A','B','C','D'};
45
46
47 static unsigned char *pin_to_irq(const unsigned char *pin)
48 {
49         static unsigned char Irqs[4];
50         int i;
51         for (i = 0 ; i < 4 ; i++)
52                 Irqs[i] = pciIrqs[ pin[i] - 'A' ];
53
54         return Irqs;
55 }
56
57 static void pci_routing_fixup(struct device *dev)
58 {
59         printk(BIOS_INFO, "%s: dev is %p\n", __func__, dev);
60
61         /* set up PCI IRQ routing */
62         pci_write_config8(dev, 0x55, pciIrqs[0] << 4);
63         pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) );
64         pci_write_config8(dev, 0x57, pciIrqs[3] << 4);
65
66
67         // firewire built into southbridge
68         printk(BIOS_INFO, "setting firewire\n");
69         pci_assign_irqs(0, 0x0d, pin_to_irq(firewirePins));
70
71         // Standard usb components
72         printk(BIOS_INFO, "setting usb\n");
73         pci_assign_irqs(0, 0x10, pin_to_irq(usbPins));
74
75         // VT8235 + sound hardware
76         printk(BIOS_INFO, "setting vt8235\n");
77         pci_assign_irqs(0, 0x11, pin_to_irq(vt8235Pins));
78
79         // Ethernet built into southbridge
80         printk(BIOS_INFO, "setting ethernet\n");
81         pci_assign_irqs(0, 0x12, pin_to_irq(enetPins));
82
83         // VGA
84         printk(BIOS_INFO, "setting vga\n");
85         pci_assign_irqs(1, 0x00, pin_to_irq(vgaPins));
86
87         // PCI slot
88         printk(BIOS_INFO, "setting pci slot\n");
89         pci_assign_irqs(0, 0x14, pin_to_irq(slotPins));
90
91         // Cardbus slot
92         printk(BIOS_INFO, "setting cardbus slot\n");
93         pci_assign_irqs(0, 0x0a, pin_to_irq(cbPins));
94
95         // Via 2 slot riser card 2nd slot
96         printk(BIOS_INFO, "setting riser slot\n");
97         pci_assign_irqs(0, 0x13, pin_to_irq(riserPins));
98
99         printk(BIOS_SPEW, "%s: DONE\n", __func__);
100 }
101
102 /*
103  * Set up the power management capabilities directly into ACPI mode.  This
104  * avoids having to handle any System Management Interrupts (SMI's) which I
105  * can't figure out how to do !!!!
106  */
107
108 static void setup_pm(device_t dev)
109 {
110         // Set gen config 0
111         pci_write_config8(dev, 0x80, 0x20);
112
113         // Set ACPI base address to IO 0x400
114         pci_write_config16(dev, 0x88, 0x0401);
115
116         // set ACPI irq to 5
117         pci_write_config8(dev, 0x82, 0x45);
118
119         // primary interupt channel
120         pci_write_config16(dev, 0x84, 0x30f2);
121
122         // throttle / stop clock control
123         pci_write_config8(dev, 0x8d, 0x18);
124
125         pci_write_config8(dev, 0x93, 0x88);
126         pci_write_config8(dev, 0x94, 0xb0);
127         pci_write_config8(dev, 0x95, 0xc0);
128         pci_write_config8(dev, 0x98, 0);
129         pci_write_config8(dev, 0x99, 0xea);
130         pci_write_config8(dev, 0xe4, 0x14);
131         pci_write_config8(dev, 0xe5, 0x08);
132
133
134         // Enable ACPI access (and setup like award)
135         pci_write_config8(dev, 0x81, 0x84);
136
137         outw(0xffff, 0x400);
138         outw(0xffff, 0x420);
139         outw(0xffff, 0x428);
140         outl(0xffffffff, 0x430);
141
142         outw(0x0, 0x424);
143         outw(0x0, 0x42a);
144         outw(0x1, 0x42c);
145         outl(0x0, 0x434);
146         outl(0x01, 0x438);
147         outb(0x0, 0x442);
148         outl(0xffff7fff, 0x448);
149         outw(0x001, 0x404);
150 }
151
152 static void vt8235_init(struct device *dev)
153 {
154         unsigned char enables;
155
156         printk(BIOS_DEBUG, "vt8235 init\n");
157
158         // enable the internal I/O decode
159         enables = pci_read_config8(dev, 0x6C);
160         enables |= 0x80;
161         pci_write_config8(dev, 0x6C, enables);
162
163         // Map 4MB of FLASH into the address space
164         pci_write_config8(dev, 0x41, 0x7f);
165
166         // Set bit 6 of 0x40, because Award does it (IO recovery time)
167         // IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI
168         // interrupts can be properly marked as level triggered.
169         enables = pci_read_config8(dev, 0x40);
170         enables |= 0x45;
171         pci_write_config8(dev, 0x40, enables);
172
173         // Set 0x42 to 0xf0 to match Award bios
174         enables = pci_read_config8(dev, 0x42);
175         enables |= 0xf0;
176         pci_write_config8(dev, 0x42, enables);
177
178         /* Set 0x58 to 0x03 to match Award */
179         pci_write_config8(dev, 0x58, 0x03);
180
181         /* Set bit 3 of 0x4f to match award (use INIT# as cpu reset) */
182         enables = pci_read_config8(dev, 0x4f);
183         enables |= 0x08;
184         pci_write_config8(dev, 0x4f, enables);
185
186         // Set bit 3 of 0x4a, to match award (dummy pci request)
187         enables = pci_read_config8(dev, 0x4a);
188         enables |= 0x08;
189         pci_write_config8(dev, 0x4a, enables);
190
191         // Set bit 3 of 0x4f to match award (use INIT# as cpu reset)
192         enables = pci_read_config8(dev, 0x4f);
193         enables |= 0x08;
194         pci_write_config8(dev, 0x4f, enables);
195
196         // Set 0x58 to 0x03 to match Award
197         pci_write_config8(dev, 0x58, 0x03);
198
199
200         /* enable serial irq */
201         pci_write_config8(dev, 0x52, 0x9);
202
203         /* dma */
204         pci_write_config8(dev, 0x53, 0x00);
205
206         // Power management setup
207         setup_pm(dev);
208
209         /* set up isa bus -- i/o recovery time, rom write enable, extend-ale */
210         pci_write_config8(dev, 0x40, 0x54);
211
212         // Start the rtc
213         rtc_init(0);
214 }
215
216 /* total kludge to get lxb to call our childrens set/enable functions - these are not called unless this
217    device has a resource to set - so set a dummy one */
218 static void vt8235_read_resources(device_t dev)
219 {
220         struct resource *res;
221
222         pci_dev_read_resources(dev);
223
224         res = new_resource(dev, 1);
225         res->base = 0x0UL;
226         res->size = 0x1000UL;
227         res->limit = 0xffffUL;
228         res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
229
230         res = new_resource(dev, 3); /* IOAPIC */
231         res->base = 0xfec00000;
232         res->size = 0x00001000;
233         res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
234 }
235
236 static void vt8235_set_resources(device_t dev)
237 {
238         //struct resource *resource;
239         //resource = find_resource(dev,1);
240         //resource->flags |= IORESOURCE_STORED;
241         pci_dev_set_resources(dev);
242 }
243
244 static void southbridge_init(struct device *dev)
245 {
246         vt8235_init(dev);
247         pci_routing_fixup(dev);
248 }
249
250 static struct device_operations vt8235_lpc_ops = {
251         .read_resources   = vt8235_read_resources,
252         .set_resources    = vt8235_set_resources,
253         .enable_resources = pci_dev_enable_resources,
254         .init             = southbridge_init,
255         .scan_bus         = scan_static_bus,
256 };
257
258 static const struct pci_driver lpc_driver __pci_driver = {
259         .ops    = &vt8235_lpc_ops,
260         .vendor = PCI_VENDOR_ID_VIA,
261         .device = PCI_DEVICE_ID_VIA_8235,
262 };