Tidy + compile fixup VT8235 southbridge support.
[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 "vt8235.h"
11 #include "chip.h"
12
13 /*
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
17  * 
18  * pciIrqs contains the irqs assigned for PCI pins A-D
19  * 
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
25  */
26
27 static const unsigned char pciIrqs[4] = { 11 , 5, 10 , 12 };
28
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'};
37
38 /*
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)
42 */
43
44 static unsigned char *pin_to_irq(const unsigned char *pin)
45 {
46         static unsigned char Irqs[4];
47         int i;
48         for (i = 0 ; i < 4 ; i++)
49                 Irqs[i] = pciIrqs[ pin[i] - 'A' ];
50
51         return Irqs;
52 }
53
54 static void pci_routing_fixup(struct device *dev)
55 {
56         printk_info("%s: dev is %p\n", __FUNCTION__, dev);
57         if (dev) {
58                 /* initialize PCI interupts - these assignments depend
59                    on the PCB routing of PINTA-D 
60
61                    PINTA = IRQ11
62                    PINTB = IRQ5
63                    PINTC = IRQ10
64                    PINTD = IRQ12
65                 */
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);
69         }
70
71         // firewire built into southbridge
72         printk_info("setting firewire\n");
73         pci_assign_irqs(0, 0x0d, pin_to_irq(firewirePins));
74
75         // Standard usb components
76         printk_info("setting usb\n");
77         pci_assign_irqs(0, 0x10, pin_to_irq(usbPins));
78
79         // VT8235 + sound hardware
80         printk_info("setting vt8235\n");
81         pci_assign_irqs(0, 0x11, pin_to_irq(vt8235Pins));
82
83         // Ethernet built into southbridge
84         printk_info("setting ethernet\n");
85         pci_assign_irqs(0, 0x12, pin_to_irq(enetPins));
86
87         // VGA
88         printk_info("setting vga\n");
89         pci_assign_irqs(1, 0x00, pin_to_irq(vgaPins));
90
91         // PCI slot
92         printk_info("setting pci slot\n");
93         pci_assign_irqs(0, 0x14, pin_to_irq(slotPins));
94
95         // Cardbus slot 
96         printk_info("setting cardbus slot\n");
97         pci_assign_irqs(0, 0x0a, pin_to_irq(cbPins));
98
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));
102
103         printk_spew("%s: DONE\n", __FUNCTION__);
104 }
105
106 /* 
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 !!!!
110  */ 
111
112 void setup_pm(device_t dev)
113 {
114
115         // Set gen config 0
116         pci_write_config8(dev, 0x80, 0x20);
117
118         // Set ACPI base address to IO 0x4000
119         pci_write_config16(dev, 0x88, 0x0401);
120         
121         // set ACPI irq to 5
122         pci_write_config8(dev, 0x82, 0x45);
123
124         // primary interupt channel
125         pci_write_config16(dev, 0x84, 0x30f2);
126
127         // throttle / stop clock control
128         pci_write_config8(dev, 0x8d, 0x18);
129
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);
137
138
139         // Enable ACPI access (and setup like award)
140         pci_write_config8(dev, 0x81, 0x84);
141
142         outw(0xffff, 0x400);
143         outw(0xffff, 0x420);
144         outw(0xffff, 0x428);
145         outl(0xffffffff, 0x430);
146         
147         outw(0x0, 0x424);
148         outw(0x0, 0x42a);
149         outw(0x1, 0x42c);
150         outl(0x0, 0x434);
151         outl(0x01, 0x438);
152         outb(0x0, 0x442);
153         outl(0xffff7fff, 0x448);
154         outw(0x001, 0x404);
155 }
156
157 static void vt8235_init(struct device *dev)
158 {
159         unsigned char enables;
160         
161         printk_debug("vt8235 init\n");
162
163         // enable the internal I/O decode
164         enables = pci_read_config8(dev, 0x6C);
165         enables |= 0x80;
166         pci_write_config8(dev, 0x6C, enables);
167         
168         // Map 4MB of FLASH into the address space
169         pci_write_config8(dev, 0x41, 0x7f);
170         
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);
175         enables |= 0x45;
176         pci_write_config8(dev, 0x40, enables);
177         
178         // Set 0x42 to 0xf0 to match Award bios
179         enables = pci_read_config8(dev, 0x42);
180         enables |= 0xf0;
181         pci_write_config8(dev, 0x42, enables);
182         
183         /* Set 0x58 to 0x03 to match Award */
184         pci_write_config8(dev, 0x58, 0x03);
185
186         /* Set bit 3 of 0x4f to match award (use INIT# as cpu reset) */
187         enables = pci_read_config8(dev, 0x4f);
188         enables |= 0x08;
189         pci_write_config8(dev, 0x4f, enables);
190
191         // Set bit 3 of 0x4a, to match award (dummy pci request)
192         enables = pci_read_config8(dev, 0x4a);
193         enables |= 0x08;
194         pci_write_config8(dev, 0x4a, enables);
195         
196         // Set bit 3 of 0x4f to match award (use INIT# as cpu reset)
197         enables = pci_read_config8(dev, 0x4f);
198         enables |= 0x08;
199         pci_write_config8(dev, 0x4f, enables);
200         
201         // Set 0x58 to 0x03 to match Award
202         pci_write_config8(dev, 0x58, 0x03);
203         
204         // enable the ethernet/RTC
205         if (dev) {
206                 enables = pci_read_config8(dev, 0x51);
207                 enables |= 0x18; 
208                 pci_write_config8(dev, 0x51, enables);
209         }
210         
211         /* enable serial irq */
212         pci_write_config8(dev, 0x52, 0x9);
213
214         /* dma */
215         pci_write_config8(dev, 0x53, 0x00);
216
217         // Power management setup
218         setup_pm(dev);
219         
220         /* set up isa bus -- i/o recovery time, rom write enable, extend-ale */
221         pci_write_config8(dev, 0x40, 0x54);
222         
223         // Start the rtc
224         rtc_init(0);
225 }
226
227 static void southbridge_init(struct device *dev)
228 {
229         vt8235_init(dev);
230         pci_routing_fixup(dev);
231 }
232
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,
239 };
240
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,
245 };