diff options
author | Ronald G. Minnich <rminnich@gmail.com> | 2004-10-06 17:33:54 +0000 |
---|---|---|
committer | Ronald G. Minnich <rminnich@gmail.com> | 2004-10-06 17:33:54 +0000 |
commit | 02fa3b2743b3f37381b6af4ee4362422b9011c8b (patch) | |
tree | c3bcc53e5ee909406558c116ac331bf05c5b561f /src/southbridge/via/vt8235/vt8235.c | |
parent | 4fa89208a16e1e2052fff315c76f8f3f07459571 (diff) |
epia-m support
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1655 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/southbridge/via/vt8235/vt8235.c')
-rw-r--r-- | src/southbridge/via/vt8235/vt8235.c | 346 |
1 files changed, 227 insertions, 119 deletions
diff --git a/src/southbridge/via/vt8235/vt8235.c b/src/southbridge/via/vt8235/vt8235.c index ca5ab32ac3..fc4c6a6186 100644 --- a/src/southbridge/via/vt8235/vt8235.c +++ b/src/southbridge/via/vt8235/vt8235.c @@ -9,6 +9,8 @@ #include "vt8235.h" #include "chip.h" +void rtc_init(int i); + void pc_keyboard_init(void); void hard_reset(void) @@ -23,67 +25,78 @@ static void usb_on(int enable) /* Base 8235 controller */ device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 0); /* USB controller 1 */ - device_t dev2 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, 0); + device_t dev1 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, 0); /* USB controller 2 */ - device_t dev3 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, dev2); - - /* enable USB1 */ - if(dev2) { - if (enable) { - pci_write_config8(dev2, 0x3c, 0x05); - pci_write_config8(dev2, 0x04, 0x07); - } else { - pci_write_config8(dev2, 0x3c, 0x00); - pci_write_config8(dev2, 0x04, 0x00); + device_t dev2 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_2, dev1); + /* USB controller 2 */ + device_t dev3 = dev_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_82C586_2, dev2); + + if(enable){ + if(dev0) { + regval = pci_read_config8(dev0, 0x50); + regval &= ~(0x36); + pci_write_config8(dev0, 0x50, regval); } - } - - if(dev0) { - regval = pci_read_config8(dev0, 0x50); - if (enable) - regval &= ~(0x10); - else - regval |= 0x10; - pci_write_config8(dev0, 0x50, regval); - } - - /* enable USB2 */ - if(dev3) { - if (enable) { - pci_write_config8(dev3, 0x3c, 0x05); - pci_write_config8(dev3, 0x04, 0x07); - } else { - pci_write_config8(dev3, 0x3c, 0x00); - pci_write_config8(dev3, 0x04, 0x00); + + /* enable USB1 */ + if(dev1) { + pci_write_config8(dev1, 0x04, 0x07); + } + + /* enable USB2 */ + if(dev2) { + pci_write_config8(dev2, 0x04, 0x07); + } + + /* enable USB3 */ + if(dev3) { + pci_write_config8(dev3, 0x04, 0x07); + } + + }else{ + if(dev0) { + regval = pci_read_config8(dev0, 0x50); + regval |= 0x36; + pci_write_config8(dev0, 0x50, regval); + } + + /* disable USB1 */ + if(dev1) { + pci_write_config8(dev1, 0x3c, 0x00); + pci_write_config8(dev1, 0x04, 0x00); + } + + /* disable USB2 */ + if(dev2) { + pci_write_config8(dev2, 0x3c, 0x00); + pci_write_config8(dev2, 0x04, 0x00); + } + + /* disable USB3 */ + if(dev3) { + pci_write_config8(dev3, 0x3c, 0x00); + pci_write_config8(dev3, 0x04, 0x00); } - } - - if(dev0) { - regval = pci_read_config8(dev0, 0x50); - if (enable) - regval &= ~(0x20); - else - regval |= 0x20; - pci_write_config8(dev0, 0x50, regval); } } static void keyboard_on(void) { unsigned char regval; - + /* Base 8235 controller */ - device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, 0); - - /* kevinh/Ispiri - update entire function to use - new pci_write_config8 */ + device_t dev0 = dev_find_device(PCI_VENDOR_ID_VIA, \ + PCI_DEVICE_ID_VIA_8235, 0); if (dev0) { regval = pci_read_config8(dev0, 0x51); - regval |= 0x0f; +// regval |= 0x0f; + /* !!!FIX let's try this */ + regval |= 0x1d; pci_write_config8(dev0, 0x51, regval); } - init_pc_keyboard(0x60, 0x64, 0); + pc_keyboard_init(); } static void nvram_on(void) @@ -152,16 +165,43 @@ static void vt8235_pci_enable(struct southbridge_via_vt8235_config *conf) */ void pci_assign_irqs(unsigned bus, unsigned slot, const unsigned char pIntAtoD[4]); +/* taken some liberties - changed irq structures to pins numbers so that it is easier to + * change PCI irq assignments without having to change each PCI function individually + */ -static const unsigned char southbridgeIrqs[4] = { 11, 5, 10, 12 }; -static const unsigned char enetIrqs[4] = { 11, 5, 10, 12 }; -static const unsigned char slotIrqs[4] = { 5, 10, 12, 11 }; - +/* pciIrqs contains the irqs assigned for PCI pins A-D */ +/* setting will depend on motherboard as irqs can be quite scarce */ +/* e.g on EPIA-MII, 16 bit CF card wants a dedicated IRQ. A 16 bit card in pcmcia socket */ +/* may want another - for now only claim 3 interupts for PCI, leaving at least one spare */ +/* for CF. */ +/* On EPIA-M one could allocated all four irqs to different numbers since there are no cardbus */ +/* devices */ + + +static const unsigned char pciIrqs[4] = { 5 , 9 , 9, 10 }; + +static const unsigned char usbPins[4] = { 'A','B','C','D'}; +static const unsigned char enetPins[4] = { 'A','B','C','D'}; +static const unsigned char slotPins[4] = { 'B','C','D','A'}; +static const unsigned char firewirePins[4] = { 'B','C','D','A'}; +static const unsigned char vt8235Pins[4] = { 'A','B','C','D'}; +static const unsigned char vgaPins[4] = { 'A','B','C','D'}; +static const unsigned char cbPins[4] = { 'A','B','C','D'}; +static const unsigned char riserPins[4] = { 'A','B','C','D'}; /* Our IDSEL mappings are as follows PCI slot is AD31 (device 15) (00:14.0) Southbridge is AD28 (device 12) (00:11.0) */ +static unsigned char *pin_to_irq(const unsigned char *pin) +{ + static unsigned char Irqs[4]; + int i; + for (i = 0 ; i < 4 ; i++) + Irqs[i] = pciIrqs[ pin[i] - 'A' ]; + + return Irqs; +} static void pci_routing_fixup(void) { device_t dev; @@ -177,23 +217,47 @@ static void pci_routing_fixup(void) PINTC = IRQ10 PINTD = IRQ12 */ - pci_write_config8(dev, 0x55, 0xb0); - pci_write_config8(dev, 0x56, 0xa5); - pci_write_config8(dev, 0x57, 0xc0); + pci_write_config8(dev, 0x55, pciIrqs[0] << 4); + pci_write_config8(dev, 0x56, pciIrqs[1] | (pciIrqs[2] << 4) ); + pci_write_config8(dev, 0x57, pciIrqs[3] << 4); + } - // Standard southbridge components - printk_info("setting southbridge\n"); - pci_assign_irqs(0, 0x11, southbridgeIrqs); + + + // firewire built into southbridge + printk_info("setting firewire\n"); + pci_assign_irqs(0, 0x0d, pin_to_irq(firewirePins) ); + + // Standard usb components + printk_info("setting usb\n"); + pci_assign_irqs(0, 0x10, pin_to_irq(usbPins) ); + + // VT8235 + sound hardware + printk_info("setting vt8235\n"); + pci_assign_irqs(0, 0x11, pin_to_irq(vt8235Pins) ); // Ethernet built into southbridge printk_info("setting ethernet\n"); - pci_assign_irqs(0, 0x12, enetIrqs); + pci_assign_irqs(0, 0x12, pin_to_irq(enetPins) ); + + // VGA + printk_info("setting vga\n"); + pci_assign_irqs(1, 0x00, pin_to_irq(vgaPins) ); // PCI slot printk_info("setting pci slot\n"); - pci_assign_irqs(0, 0x14, slotIrqs); - printk_info("%s: DONE\n", __FUNCTION__); + pci_assign_irqs(0, 0x14, pin_to_irq(slotPins) ); + + // Cardbus slot + printk_info("setting cardbus slot\n"); + pci_assign_irqs(0, 0x0a, pin_to_irq(cbPins) ); + + // Via 2 slot riser card 2nd slot + printk_info("setting riser slot\n"); + pci_assign_irqs(0, 0x13, pin_to_irq(riserPins) ); + + } @@ -213,13 +277,76 @@ dump_south(void) } } +void set_led(void) +{ + + // set power led to steady now that lxbios has virtually done its job + device_t dev0; + dev0 = dev_find_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,0); + + pci_write_config8(dev0,0x94,0xb0); + +} + +/* set up the power management capabilities directly into ACPI mode */ +/* this avoids having to handle any System Management Interrupts (SMI's) which I can't */ +/* figure out how to do !!!! */ + +void setup_pm(device_t dev0) +{ + + // Set gen config 0 + pci_write_config8(dev0,0x80,0x20); + + // Set ACPI base address to IO 0x4000 + pci_write_config16(dev0, 0x88, 0x0401); + + // set ACPI irq to 5 + pci_write_config8(dev0,0x82,0x55); + + // primary interupt channel + pci_write_config16(dev0,0x84,0x30f2); + + // throttle / stop clock control + pci_write_config8(dev0,0x8d,0x18); + + pci_write_config8(dev0,0x93,0x88); + //pci_write_config8(dev0,0x94,0xb0); + pci_write_config8(dev0,0x95,0xc0); + pci_write_config8(dev0,0x98,0); + pci_write_config8(dev0,0x99,0xea); + pci_write_config8(dev0,0xe4,0x14); + pci_write_config8(dev0,0xe5,0x08); + + + // Enable ACPI access (and setup like award) + pci_write_config8(dev0, 0x81, 0x84); + + outw(0xffff,0x400); + outw(0xffff,0x420); + outw(0xffff,0x428); + outl(0xffffffff,0x430); + + outw(0x0,0x424); + outw(0x0,0x42a); + outw(0x1,0x42c); + outl(0x0,0x434); + outl(0x01,0x438); + outb(0x0,0x442); + outl(0xffff7fff,0x448); + outw(0x001,0x404); + + +} + static void vt8235_init(struct southbridge_via_vt8235_config *conf) { unsigned char enables; device_t dev0; device_t dev1; - device_t devpwr; - + //device_t devpwr; + //int i; + // to do: use the pcibios_find function here, instead of // hard coding the devfn. // done - kevinh/Ispiri @@ -243,6 +370,7 @@ static void vt8235_init(struct southbridge_via_vt8235_config *conf) // IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI // interrupts can be properly marked as level triggered. enables = pci_read_config8(dev0, 0x40); + enables |= 0x45; pci_write_config8(dev0, 0x40, enables); // Set 0x42 to 0xf0 to match Award bios @@ -250,6 +378,17 @@ static void vt8235_init(struct southbridge_via_vt8235_config *conf) enables |= 0xf0; pci_write_config8(dev0, 0x42, enables); + + /* Set 0x58 to 0x03 to match Award */ + pci_write_config8(dev0, 0x58, 0x03); + + /* Set bit 3 of 0x4f to match award (use INIT# as cpu reset) */ + enables = pci_read_config8(dev0, 0x4f); + enables |= 0x08; + pci_write_config8(dev0, 0x4f, enables); + + + // Set bit 3 of 0x4a, to match award (dummy pci request) enables = pci_read_config8(dev0, 0x4a); enables |= 0x08; @@ -271,68 +410,24 @@ static void vt8235_init(struct southbridge_via_vt8235_config *conf) } - // enable com1 and com2. - if (conf->enable_com_ports) { - enables = pci_read_config8(dev0, 0x6e); - - /* 0x80 is enable com port b, 0x10 is to make it com2, 0x8 - * is enable com port a as com1 kevinh/Ispiri - Old code - * thought 0x01 would make it com1, that was wrong enables = - * 0x80 | 0x10 | 0x8 ; pci_write_config8(dev0, 0x6e, - * enables); // note: this is also a redo of some port of - * assembly, but we want everything up. - */ - - /* set com1 to 115 kbaud not clear how to do this yet. - * forget it; done in assembly. - */ + /* enable serial irq */ + pci_write_config8(dev0,0x52,0x9); + + /* dma */ + pci_write_config8(dev0, 0x53, 0x00); + + /* Use compatability mode - per award bios */ + pci_write_config32(dev1, 0x10, 0x0); + pci_write_config32(dev1, 0x14, 0x0); + pci_write_config32(dev1, 0x18, 0x0); + pci_write_config32(dev1, 0x1c, 0x0); + - } - // enable IDE, since Linux won't do it. - // First do some more things to devfn (17,0) - // note: this should already be cleared, according to the book. - enables = pci_read_config8(dev0, 0x50); - printk_debug("IDE enable in reg. 50 is 0x%x\n", enables); - enables &= ~8; // need manifest constant here! - printk_debug("set IDE reg. 50 to 0x%x\n", enables); - pci_write_config8(dev0, 0x50, enables); - - // set default interrupt values (IDE) - enables = pci_read_config8(dev0, 0x4c); - printk_debug("IRQs in reg. 4c are 0x%x\n", enables & 0xf); - // clear out whatever was there. - enables &= ~0xf; - enables |= 4; - printk_debug("setting reg. 4c to 0x%x\n", enables); - pci_write_config8(dev0, 0x4c, enables); - - // set up the serial port interrupts. - // com2 to 3, com1 to 4 - pci_write_config8(dev0, 0x46, 0x04); - pci_write_config8(dev0, 0x47, 0x03); - pci_write_config8(dev0, 0x6e, 0x98); - // // Power management setup - // - // Set ACPI base address to IO 0x4000 - //pci_write_config32(devpwr, 0x48, 0x4001); - - // Enable ACPI access (and setup like award) - //pci_write_config8(devpwr, 0x41, 0x84); - - // Set hardware monitor base address to IO 0x6000 - //pci_write_config32(devpwr, 0x70, 0x6001); - - // Enable hardware monitor (and setup like award) - //pci_write_config8(devpwr, 0x74, 0x01); - - // set IO base address to 0x5000 - //pci_write_config32(devpwr, 0x90, 0x5001); - - // Enable SMBus - //pci_write_config8(devpwr, 0xd2, 0x01); + setup_pm(dev0); // + // // IDE setup // if (! conf->enable_native_ide) { @@ -422,6 +517,8 @@ static void vt8235_init(struct southbridge_via_vt8235_config *conf) // Start the rtc rtc_init(0); + + } static void southbridge_init(struct chip *chip, enum chip_pass pass) @@ -436,12 +533,23 @@ static void southbridge_init(struct chip *chip, enum chip_pass pass) break; case CONF_PASS_POST_PCI: + /* initialise the PIC - particularly so that VGA bios init code + doesn't get nasty unknown interupt vectors when it tries to establish + its interrupts. */ + setup_i8259(); vt8235_init(conf); pci_routing_fixup(); + usb_on(1); + keyboard_on(); + vga_fixup(); + + + break; case CONF_PASS_PRE_BOOT: dump_south(); + set_led(); break; default: |