summaryrefslogtreecommitdiff
path: root/src/southbridge/via/vt8235/vt8235.c
diff options
context:
space:
mode:
authorRonald G. Minnich <rminnich@gmail.com>2004-10-06 17:33:54 +0000
committerRonald G. Minnich <rminnich@gmail.com>2004-10-06 17:33:54 +0000
commit02fa3b2743b3f37381b6af4ee4362422b9011c8b (patch)
treec3bcc53e5ee909406558c116ac331bf05c5b561f /src/southbridge/via/vt8235/vt8235.c
parent4fa89208a16e1e2052fff315c76f8f3f07459571 (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.c346
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: