- Update abuild.sh so it will rebuild successfull builds
[coreboot.git] / src / southbridge / via / vt8235 / vt8235.c
1
2 #include <arch/io.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 <console/console.h>
8 #include "vt8235.h"
9 #include "chip.h"
10
11 void rtc_init(int i);
12
13 void pc_keyboard_init(void);
14
15 void hard_reset(void) 
16 {
17         printk_err("NO HARD RESET ON VT8235! FIX ME!\n");
18 }
19
20 static void usb_on(int enable)
21 {
22         unsigned char regval;
23
24         /* Base 8235 controller */
25         device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 0);
26         /* USB controller 1 */
27         device_t dev1 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, 0);
28         /* USB controller 2 */
29         device_t dev2 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, dev1);
30         /* USB controller 2 */
31         device_t dev3 = dev_find_device(PCI_VENDOR_ID_VIA, 
32         PCI_DEVICE_ID_VIA_82C586_2, dev2);
33         
34         if(enable){
35                 if(dev0) {
36                         regval = pci_read_config8(dev0, 0x50);
37                         regval &= ~(0x36);
38                         pci_write_config8(dev0, 0x50, regval);
39                 }
40
41                 /* enable USB1 */
42                 if(dev1) {
43                         pci_write_config8(dev1, 0x04, 0x07);
44                 }
45
46                 /* enable USB2 */
47                 if(dev2) {
48                         pci_write_config8(dev2, 0x04, 0x07);
49                 }
50
51                 /* enable USB3 */
52                 if(dev3) {
53                         pci_write_config8(dev3, 0x04, 0x07);
54                 }
55
56         }else{
57                 if(dev0) {
58                         regval = pci_read_config8(dev0, 0x50);
59                         regval |= 0x36;    
60                         pci_write_config8(dev0, 0x50, regval);
61                 }
62
63                 /* disable USB1 */
64                 if(dev1) {
65                         pci_write_config8(dev1, 0x3c, 0x00);
66                         pci_write_config8(dev1, 0x04, 0x00);
67                 }
68
69                 /* disable USB2 */
70                 if(dev2) {
71                         pci_write_config8(dev2, 0x3c, 0x00);
72                         pci_write_config8(dev2, 0x04, 0x00);
73                 }
74
75                 /* disable USB3 */
76                 if(dev3) {
77                         pci_write_config8(dev3, 0x3c, 0x00);
78                         pci_write_config8(dev3, 0x04, 0x00);
79                 }
80         }
81 }
82
83 static void keyboard_on(void)
84 {
85         unsigned char regval;
86
87         /* Base 8235 controller */
88         device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, \
89                                                 PCI_DEVICE_ID_VIA_8235, 0);
90
91         if (dev0) {
92                 regval = pci_read_config8(dev0, 0x51);
93 //              regval |= 0x0f; 
94                 /* !!!FIX let's try this */
95                 regval |= 0x1d; 
96                 pci_write_config8(dev0, 0x51, regval);
97         }
98         pc_keyboard_init();
99 }
100
101 static void nvram_on(void)
102 {
103         /*
104          * the VIA 8235 South has a very different nvram setup than the 
105          * piix4e ...
106          * turn on ProMedia nvram.
107          * TO DO: use the PciWriteByte function here.
108          */
109         
110         /*
111          * kevinh/Ispiri - I don't think this is the correct address/value
112          * intel_conf_writeb(0x80008841, 0xFF);
113          */
114 }
115
116
117 /*
118  * Enable the ethernet device and turn off stepping (because it is integrated 
119  * inside the southbridge)
120  */
121 static void ethernet_fixup()
122 {
123         device_t        edev;
124         uint8_t         byte;
125
126         printk_info("Ethernet fixup\n");
127
128         edev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_7, 0);
129         if (edev) {
130                 printk_debug("Configuring VIA LAN\n");
131                 
132                 /* We don't need stepping - though the device supports it */
133                 byte = pci_read_config8(edev, PCI_COMMAND);
134                 byte &= ~PCI_COMMAND_WAIT;
135                 pci_write_config8(edev, PCI_COMMAND, byte);
136         } else {
137                 printk_debug("VIA LAN not found\n");
138         }
139 }
140
141
142 /* we need to do things in this function so that PCI scan will find 
143  * them.  One problem here is that we can't use ANY of the new device 
144  * stuff. This work here precedes all that.      
145  * Fundamental problem with linuxbios V2 architecture.
146  * You can't do pci control in the C code without having done a PCI scan.
147  * But in some cases you need to to pci control in the c code before doing
148  * a PCI scan. But you can't use arch/romcc_io.h (the code you need) because
149  * that has functions with the same name but different type signatures
150  * (e.g. device_t). This needs to get fixed. We need low-level pci scans
151  * in the C code. 
152  */
153 static void vt8235_pci_enable(struct southbridge_via_vt8235_config *conf) 
154 {
155         /*
156           unsigned long busdevfn = 0x8000;
157           if (conf->enable_ide) {
158           printk_debug("%s: enabling IDE function\n", __FUNCTION__);
159           }
160         */
161 }
162
163 /* PIRQ init
164  */
165 void pci_assign_irqs(unsigned bus, unsigned slot, const unsigned char pIntAtoD[4]);
166
167 /* taken some liberties - changed irq structures to pins numbers so that it is easier to
168  * change PCI irq assignments without having to change each PCI function individually
169  */
170
171 /* pciIrqs contains the irqs assigned for PCI pins A-D */
172 /* setting will depend on motherboard as irqs can be quite scarce */
173 /* e.g on EPIA-MII, 16 bit CF card wants a dedicated IRQ. A 16 bit card in pcmcia socket */
174 /* may want another - for now only claim 3 interupts for PCI, leaving at least one spare */
175 /* for CF.  */
176 /* On EPIA-M one could allocated all four irqs to different numbers since there are no cardbus */
177 /* devices */
178
179
180 static const unsigned char pciIrqs[4] = { 5 , 9 , 9, 10 };
181
182 static const unsigned char usbPins[4] =      { 'A','B','C','D'};
183 static const unsigned char enetPins[4] =     { 'A','B','C','D'};
184 static const unsigned char slotPins[4] =     { 'B','C','D','A'};
185 static const unsigned char firewirePins[4] = { 'B','C','D','A'};
186 static const unsigned char vt8235Pins[4] =   { 'A','B','C','D'};
187 static const unsigned char vgaPins[4] =      { 'A','B','C','D'};
188 static const unsigned char cbPins[4] =       { 'A','B','C','D'};
189 static const unsigned char riserPins[4] =    { 'A','B','C','D'};
190 /*
191         Our IDSEL mappings are as follows
192         PCI slot is AD31          (device 15) (00:14.0)
193         Southbridge is AD28       (device 12) (00:11.0)
194 */
195 static unsigned char *pin_to_irq(const unsigned char *pin)
196 {
197         static unsigned char Irqs[4];
198         int i;
199         for (i = 0 ; i < 4 ; i++)
200                 Irqs[i] = pciIrqs[ pin[i] - 'A' ];
201
202         return Irqs;
203 }
204 static void pci_routing_fixup(void)
205 {
206         device_t dev;
207
208         dev = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 0);
209         printk_info("%s: dev is %p\n", __FUNCTION__, dev);
210         if (dev) {
211                 /* initialize PCI interupts - these assignments depend
212                    on the PCB routing of PINTA-D 
213
214                    PINTA = IRQ11
215                    PINTB = IRQ5
216                    PINTC = IRQ10
217                    PINTD = IRQ12
218                 */
219                 pci_write_config8(dev, 0x55, pciIrqs[0] << 4);
220                 pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) );
221                 pci_write_config8(dev, 0x57, pciIrqs[3] << 4);
222
223         }
224
225
226
227         // firewire built into southbridge
228         printk_info("setting firewire\n");
229         pci_assign_irqs(0, 0x0d, pin_to_irq(firewirePins) );
230
231         // Standard usb components
232         printk_info("setting usb\n");
233         pci_assign_irqs(0, 0x10, pin_to_irq(usbPins) );
234
235         // VT8235 + sound hardware
236         printk_info("setting vt8235\n");
237         pci_assign_irqs(0, 0x11, pin_to_irq(vt8235Pins) );
238
239         // Ethernet built into southbridge
240         printk_info("setting ethernet\n");
241         pci_assign_irqs(0, 0x12, pin_to_irq(enetPins) );
242
243         // VGA
244         printk_info("setting vga\n");
245         pci_assign_irqs(1, 0x00, pin_to_irq(vgaPins) );
246
247         // PCI slot
248         printk_info("setting pci slot\n");
249         pci_assign_irqs(0, 0x14, pin_to_irq(slotPins) );
250
251         // Cardbus slot 
252         printk_info("setting cardbus slot\n");
253         pci_assign_irqs(0, 0x0a, pin_to_irq(cbPins) );
254
255         // Via 2 slot riser card 2nd slot
256         printk_info("setting riser slot\n");
257         pci_assign_irqs(0, 0x13, pin_to_irq(riserPins) );
258
259
260 }
261
262
263 void
264 dump_south(void)
265 {
266         device_t dev0;
267         dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 0);
268         int i,j;
269         
270         for(i = 0; i < 256; i += 16) {
271                 printk_debug("0x%x: ", i);
272                 for(j = 0; j < 16; j++) {
273                         printk_debug("%02x ", pci_read_config8(dev0, i+j));
274                 }
275                 printk_debug("\n");
276         }
277 }
278
279 void set_led(void)
280 {
281
282         // set power led to steady now that lxbios has virtually done its job
283         device_t dev0;
284         dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,0);
285
286         pci_write_config8(dev0,0x94,0xb0);
287
288 }
289
290 /* set up the power management capabilities directly into ACPI mode */
291 /* this avoids having to handle any System Management Interrupts (SMI's) which I can't */
292 /* figure out how to do !!!! */ 
293
294 void setup_pm(device_t dev0)
295 {
296
297         // Set gen config 0
298         pci_write_config8(dev0,0x80,0x20);
299
300         // Set ACPI base address to IO 0x4000
301         pci_write_config16(dev0, 0x88, 0x0401);
302         
303         // set ACPI irq to 5
304         pci_write_config8(dev0,0x82,0x55);
305
306         // primary interupt channel
307         pci_write_config16(dev0,0x84,0x30f2);
308
309         // throttle / stop clock control
310         pci_write_config8(dev0,0x8d,0x18);
311
312         pci_write_config8(dev0,0x93,0x88);
313         //pci_write_config8(dev0,0x94,0xb0);
314         pci_write_config8(dev0,0x95,0xc0);
315         pci_write_config8(dev0,0x98,0);
316         pci_write_config8(dev0,0x99,0xea);
317         pci_write_config8(dev0,0xe4,0x14);
318         pci_write_config8(dev0,0xe5,0x08);
319
320
321         // Enable ACPI access (and setup like award)
322         pci_write_config8(dev0, 0x81, 0x84);
323
324         outw(0xffff,0x400);
325         outw(0xffff,0x420);
326         outw(0xffff,0x428);
327         outl(0xffffffff,0x430);
328         
329         outw(0x0,0x424);
330         outw(0x0,0x42a);
331         outw(0x1,0x42c);
332         outl(0x0,0x434);
333         outl(0x01,0x438);
334         outb(0x0,0x442);
335         outl(0xffff7fff,0x448);
336         outw(0x001,0x404);
337
338
339 }
340
341 static void vt8235_init(struct southbridge_via_vt8235_config *conf)
342 {
343         unsigned char enables;
344         device_t dev0;
345         device_t dev1;
346         //device_t devpwr;
347         //int i;
348
349         // to do: use the pcibios_find function here, instead of 
350         // hard coding the devfn. 
351         // done - kevinh/Ispiri
352         printk_debug("vt8235 init\n");
353         /* Base 8235 controller */
354         dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 0);
355         /* IDE controller */
356         dev1 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1, 0);
357         /* Power management controller */
358         //devpwr = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235_4, 0);
359
360         // enable the internal I/O decode
361         enables = pci_read_config8(dev0, 0x6C);
362         enables |= 0x80;
363         pci_write_config8(dev0, 0x6C, enables);
364         
365         // Map 4MB of FLASH into the address space
366         pci_write_config8(dev0, 0x41, 0x7f);
367         
368         // Set bit 6 of 0x40, because Award does it (IO recovery time)
369         // IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI 
370         // interrupts can be properly marked as level triggered.
371         enables = pci_read_config8(dev0, 0x40);
372         enables |= 0x45;
373         pci_write_config8(dev0, 0x40, enables);
374         
375         // Set 0x42 to 0xf0 to match Award bios
376         enables = pci_read_config8(dev0, 0x42);
377         enables |= 0xf0;
378         pci_write_config8(dev0, 0x42, enables);
379         
380
381         /* Set 0x58 to 0x03 to match Award */
382         pci_write_config8(dev0, 0x58, 0x03);
383
384         /* Set bit 3 of 0x4f to match award (use INIT# as cpu reset) */
385         enables = pci_read_config8(dev0, 0x4f);
386         enables |= 0x08;
387         pci_write_config8(dev0, 0x4f, enables);
388
389
390
391         // Set bit 3 of 0x4a, to match award (dummy pci request)
392         enables = pci_read_config8(dev0, 0x4a);
393         enables |= 0x08;
394         pci_write_config8(dev0, 0x4a, enables);
395         
396         // Set bit 3 of 0x4f to match award (use INIT# as cpu reset)
397         enables = pci_read_config8(dev0, 0x4f);
398         enables |= 0x08;
399         pci_write_config8(dev0, 0x4f, enables);
400         
401         // Set 0x58 to 0x03 to match Award
402         pci_write_config8(dev0, 0x58, 0x03);
403         
404         // enable the ethernet/RTC
405         if(dev0) {
406                 enables = pci_read_config8(dev0, 0x51);
407                 enables |= 0x18; 
408                 pci_write_config8(dev0, 0x51, enables);
409         }
410         
411         
412         /* enable serial irq */
413         pci_write_config8(dev0,0x52,0x9);
414
415         /* dma */
416         pci_write_config8(dev0, 0x53, 0x00);
417
418         /* Use compatability mode - per award bios */
419         pci_write_config32(dev1, 0x10, 0x0);
420         pci_write_config32(dev1, 0x14, 0x0);
421         pci_write_config32(dev1, 0x18, 0x0);
422         pci_write_config32(dev1, 0x1c, 0x0);
423
424
425         // Power management setup
426         setup_pm(dev0);
427         
428         //
429         //
430         // IDE setup
431         //
432         if (! conf->enable_native_ide) {
433                 // Run the IDE controller in 'compatiblity mode - i.e. don't use PCI
434                 // interrupts.  Using PCI ints confuses linux for some reason.
435                 
436                 printk_info("%s: enabling compatibility IDE addresses\n", __FUNCTION__);
437                 enables = pci_read_config8(dev1, 0x42);
438                 printk_debug("enables in reg 0x42 0x%x\n", enables);
439                 enables &= ~0xc0;               // compatability mode
440                 pci_write_config8(dev1, 0x42, enables);
441                 enables = pci_read_config8(dev1, 0x42);
442                 printk_debug("enables in reg 0x42 read back as 0x%x\n", enables);
443         }
444         
445         enables = pci_read_config8(dev1, 0x40);
446         printk_debug("enables in reg 0x40 0x%x\n", enables);
447         enables |= 3;
448         pci_write_config8(dev1, 0x40, enables);
449         enables = pci_read_config8(dev1, 0x40);
450         printk_debug("enables in reg 0x40 read back as 0x%x\n", enables);
451         
452         // Enable prefetch buffers
453         enables = pci_read_config8(dev1, 0x41);
454         enables |= 0xf0;
455         pci_write_config8(dev1, 0x41, enables);
456         
457         // Lower thresholds (cause award does it)
458         enables = pci_read_config8(dev1, 0x43);
459         enables &= ~0x0f;
460         enables |=  0x05;
461         pci_write_config8(dev1, 0x43, enables);
462         
463         // PIO read prefetch counter (cause award does it)
464         pci_write_config8(dev1, 0x44, 0x18);
465         
466         // Use memory read multiple
467         pci_write_config8(dev1, 0x45, 0x1c);
468         
469         // address decoding. 
470         // we want "flexible", i.e. 1f0-1f7 etc. or native PCI
471         // kevinh@ispiri.com - the standard linux drivers seem ass slow when 
472         // used in native mode - I've changed back to classic
473         enables = pci_read_config8(dev1, 0x9);
474         printk_debug("enables in reg 0x9 0x%x\n", enables);
475         // by the book, set the low-order nibble to 0xa. 
476         if (conf->enable_native_ide) {
477                 enables &= ~0xf;
478                 // cf/cg silicon needs an 'f' here. 
479                 enables |= 0xf;
480         } else {
481                 enables &= ~0x5;
482         }
483         
484         pci_write_config8(dev1, 0x9, enables);
485         enables = pci_read_config8(dev1, 0x9);
486         printk_debug("enables in reg 0x9 read back as 0x%x\n", enables);
487         
488         // standard bios sets master bit. 
489         enables = pci_read_config8(dev1, 0x4);
490         printk_debug("command in reg 0x4 0x%x\n", enables);
491         enables |= 7;
492         
493         // No need for stepping - kevinh@ispiri.com
494         enables &= ~0x80;
495         
496         pci_write_config8(dev1, 0x4, enables);
497         enables = pci_read_config8(dev1, 0x4);
498         printk_debug("command in reg 0x4 reads back as 0x%x\n", enables);
499         
500         if (! conf->enable_native_ide) {
501                 // Use compatability mode - per award bios
502                 pci_write_config32(dev1, 0x10, 0x0);
503                 pci_write_config32(dev1, 0x14, 0x0);
504                 pci_write_config32(dev1, 0x18, 0x0);
505                 pci_write_config32(dev1, 0x1c, 0x0);
506                 
507                 // Force interrupts to use compat mode - just like Award bios
508                 pci_write_config8(dev1, 0x3d, 00);
509                 pci_write_config8(dev1, 0x3c, 0xff);
510         }
511         
512         
513         /* set up isa bus -- i/o recovery time, rom write enable, extend-ale */
514         pci_write_config8(dev0, 0x40, 0x54);
515         ethernet_fixup();
516         
517         // Start the rtc
518         rtc_init(0);
519
520
521 }
522
523 static void southbridge_init(struct chip *chip, enum chip_pass pass)
524 {
525
526         struct southbridge_via_vt8235_config *conf = 
527                 (struct southbridge_via_vt8235_config *)chip->chip_info;
528
529         switch (pass) {
530         case CONF_PASS_PRE_PCI:
531                 vt8235_pci_enable(conf);
532                 break;
533                 
534         case CONF_PASS_POST_PCI:
535                 /* initialise the PIC - particularly so that VGA bios init code 
536                    doesn't get nasty unknown interupt vectors when it tries to establish 
537                    its interrupts. */
538                 setup_i8259();
539                 vt8235_init(conf);
540                 pci_routing_fixup();
541                 usb_on(1);
542                 keyboard_on();
543                 vga_fixup();
544
545
546
547                 break;
548
549         case CONF_PASS_PRE_BOOT:
550                 dump_south();
551                 set_led();
552                 break;
553                 
554         default:
555                 /* nothing yet */
556                 break;
557         }
558 }
559
560 struct chip_operations southbridge_via_vt8235_control = {
561         CHIP_NAME("VIA vt8235")
562         .enable    = southbridge_init,
563 };