summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/mainboard/via/epia-n/irq_links.asl571
-rw-r--r--src/mainboard/via/epia-n/mptable.c115
-rw-r--r--src/mainboard/via/epia-n/pata_methods.asl132
-rw-r--r--src/mainboard/via/epia-n/pci_init.asl30
-rw-r--r--src/mainboard/via/epia-n/sb_physical.asl548
-rw-r--r--src/northbridge/via/cn400/vlink.c246
-rw-r--r--src/southbridge/via/vt8237r/vt8237r_nic.c62
-rw-r--r--src/southbridge/via/vt8237r/vt8237r_usb.c166
8 files changed, 1870 insertions, 0 deletions
diff --git a/src/mainboard/via/epia-n/irq_links.asl b/src/mainboard/via/epia-n/irq_links.asl
new file mode 100644
index 0000000000..fc93e760b5
--- /dev/null
+++ b/src/mainboard/via/epia-n/irq_links.asl
@@ -0,0 +1,571 @@
+/*
+ * Minimalist ACPI DSDT table for EPIA-N / NL
+ * Basic description of PCI Interrupt Assignments.
+ * This is expected to be included into _SB.PCI0 namespace
+ * (C) Copyright 2009 Jon Harrison <jon.harrison@blueyonder.co.uk>
+ *
+ */
+
+ /* PCI PnP Routing Links */
+
+ /* Define how interrupt Link A is plumbed in */
+ Device (LNKA)
+ {
+ Name (_HID, EisaId ("PNP0C0F"))
+ Name (_UID, 0x01)
+ /* Status - always return ready */
+ Method (_STA, 0, NotSerialized)
+ {
+ /* See If Coreboot has allocated INTA# */
+ And (PIRA, 0xF0, Local0)
+ If (LEqual (Local0, 0x00))
+ {
+ Return (0x09)
+ }
+ Else
+ {
+ Return (0x0B)
+ }
+ }
+
+ Method (_PRS, 0, NotSerialized)
+ {
+ Name (BUFA, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared, )
+ {3,4,6,7,10,11,12}
+ })
+ Return (BUFA)
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (BUFA, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared, _Y07)
+ {}
+ })
+ /* Read the Binary Encoded Field and Map this */
+ /* onto the bitwise _INT field in the IRQ descriptor */
+ /* See ACPI Spec for detail of _IRQ Descriptor */
+ CreateByteField (BUFA, \_SB.PCI0.LNKA._CRS._Y07._INT, IRA1)
+ CreateByteField (BUFA, 0x02, IRA2)
+ Store (0x00, Local3)
+ Store (0x00, Local4)
+ And (PIRA, 0xF0, Local1)
+ ShiftRight (Local1, 0x04, Local1)
+ If (LNotEqual (Local1, 0x00))
+ {
+ If (LGreater (Local1, 0x07))
+ {
+ Subtract (Local1, 0x08, Local2)
+ ShiftLeft (One, Local2, Local4)
+ }
+ Else
+ {
+ If (LGreater (Local1, 0x00))
+ {
+ ShiftLeft (One, Local1, Local3)
+ }
+ }
+
+ Store (Local3, IRA1)
+ Store (Local4, IRA2)
+ }
+ Return (BUFA)
+ }
+
+ /* Set Resources - dummy function to keep Linux ACPI happy
+ * Linux is more than happy not to tinker with irq
+ * assignments as long as the CRS and STA functions
+ * return good values
+ */
+ Method (_SRS, 1, NotSerialized) {}
+ /* Disable - Set PnP Routing Reg to 0 */
+ Method (_DIS, 0, NotSerialized )
+ {
+ And (PIRA, 0x0F, PIRA)
+ }
+ } // End of LNKA
+
+ Device (LNKB)
+ {
+ Name (_HID, EisaId ("PNP0C0F"))
+ Name (_UID, 0x02)
+ Method (_STA, 0, NotSerialized)
+ {
+ /* See If Coreboot has allocated INTB# */
+ And (PIBC, 0x0F, Local0)
+ If (LEqual (Local0, 0x00))
+ {
+ Return (0x09)
+ }
+ Else
+ {
+ Return (0x0B)
+ }
+ }
+
+ Method (_PRS, 0, NotSerialized)
+ {
+ Name (BUFB, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared, )
+ {3,4,6,7,10,11,12}
+ })
+ Return (BUFB)
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (BUFB, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared, _Y08)
+ {}
+ })
+ /* Read the Binary Encoded Field and Map this */
+ /* onto the bitwise _INT field in the IRQ descriptor */
+ /* See ACPI Spec for detail of _IRQ Descriptor */
+ CreateByteField (BUFB, \_SB.PCI0.LNKB._CRS._Y08._INT, IRB1)
+ CreateByteField (BUFB, 0x02, IRB2)
+ Store (0x00, Local3)
+ Store (0x00, Local4)
+ And (PIBC, 0x0F, Local1)
+ If (LNotEqual (Local1, 0x00))
+ {
+ If (LGreater (Local1, 0x07))
+ {
+ Subtract (Local1, 0x08, Local2)
+ ShiftLeft (One, Local2, Local4)
+ }
+ Else
+ {
+ If (LGreater (Local1, 0x00))
+ {
+ ShiftLeft (One, Local1, Local3)
+ }
+ }
+
+ Store (Local3, IRB1)
+ Store (Local4, IRB2)
+ }
+ Return (BUFB)
+ }
+
+ /* Set Resources - dummy function to keep Linux ACPI happy
+ * Linux is more than happy not to tinker with irq
+ * assignments as long as the CRS and STA functions
+ * return good values
+ */
+ Method (_SRS, 1, NotSerialized) {}
+ /* Disable - Set PnP Routing Reg to 0 */
+ Method (_DIS, 0, NotSerialized )
+ {
+ And (PIBC, 0xF0, PIBC)
+ }
+
+ } // End of LNKB
+
+ Device (LNKC)
+ {
+ Name (_HID, EisaId ("PNP0C0F"))
+ Name (_UID, 0x03)
+ Method (_STA, 0, NotSerialized)
+ {
+ /* See If Coreboot has allocated INTC# */
+ And (PIBC, 0xF0, Local0)
+ If (LEqual (Local0, 0x00))
+ {
+ Return (0x09)
+ }
+ Else
+ {
+ Return (0x0B)
+ }
+ }
+
+ Method (_PRS, 0, NotSerialized)
+ {
+ Name (BUFC, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared, )
+ {3,4,6,7,10,11,12}
+ })
+ Return (BUFC)
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (BUFC, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared, _Y09)
+ {}
+ })
+ /* Read the Binary Encoded Field and Map this */
+ /* onto the bitwise _INT field in the IRQ descriptor */
+ /* See ACPI Spec for detail of _IRQ Descriptor */
+ CreateByteField (BUFC, \_SB.PCI0.LNKC._CRS._Y09._INT, IRC1)
+ CreateByteField (BUFC, 0x02, IRC2)
+ Store (0x00, Local3)
+ Store (0x00, Local4)
+ And (PIBC, 0xF0, Local1)
+ ShiftRight (Local1, 0x04, Local1)
+ If (LNotEqual (Local1, 0x00))
+ {
+ If (LGreater (Local1, 0x07))
+ {
+ Subtract (Local1, 0x08, Local2)
+ ShiftLeft (One, Local2, Local4)
+ }
+ Else
+ {
+ If (LGreater (Local1, 0x00))
+ {
+ ShiftLeft (One, Local1, Local3)
+ }
+ }
+
+ Store (Local3, IRC1)
+ Store (Local4, IRC2)
+ }
+ Return (BUFC)
+ }
+
+ /* Set Resources - dummy function to keep Linux ACPI happy
+ * Linux is more than happy not to tinker with irq
+ * assignments as long as the CRS and STA functions
+ * return good values
+ */
+ Method (_SRS, 1, NotSerialized) {}
+ /* Disable - Set PnP Routing Reg to 0 */
+ Method (_DIS, 0, NotSerialized )
+ {
+ And (PIBC, 0x0F, PIBC)
+ }
+
+} // End of LNKC
+
+Device (LNKD)
+{
+ Name (_HID, EisaId ("PNP0C0F"))
+ Name (_UID, 0x04)
+ Method (_STA, 0, NotSerialized)
+ {
+ /* See If Coreboot has allocated INTD# */
+ And (PIRD, 0xF0, Local0)
+ If (LEqual (Local0, 0x00))
+ {
+ Return (0x09)
+ }
+ Else
+ {
+ Return (0x0B)
+ }
+ }
+
+ Method (_PRS, 0, NotSerialized)
+ {
+ Name (BUFD, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared, )
+ {3,4,6,7,10,11,12}
+ })
+ Return (BUFD)
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (BUFD, ResourceTemplate ()
+ {
+ IRQ (Level, ActiveLow, Shared, _Y0A)
+ {}
+ })
+ /* Read the Binary Encoded Field and Map this */
+ /* onto the bitwise _INT field in the IRQ descriptor */
+ /* See ACPI Spec for detail of _IRQ Descriptor */
+ CreateByteField (BUFD, \_SB.PCI0.LNKD._CRS._Y0A._INT, IRD1)
+ CreateByteField (BUFD, 0x02, IRD2)
+ Store (0x00, Local3)
+ Store (0x00, Local4)
+ And (PIRD, 0xF0, Local1)
+ ShiftRight (Local1, 0x04, Local1)
+ If (LNotEqual (Local1, 0x00))
+ {
+ If (LGreater (Local1, 0x07))
+ {
+ Subtract (Local1, 0x08, Local2)
+ ShiftLeft (One, Local2, Local4)
+ }
+ Else
+ {
+ If (LGreater (Local1, 0x00))
+ {
+ ShiftLeft (One, Local1, Local3)
+ }
+ }
+
+ Store (Local3, IRD1)
+ Store (Local4, IRD2)
+ }
+ Return (BUFD)
+ }
+
+ /* Set Resources - dummy function to keep Linux ACPI happy
+ * Linux is more than happy not to tinker with irq
+ * assignments as long as the CRS and STA functions
+ * return good values
+ */
+ Method (_SRS, 1, NotSerialized) {}
+ /* Disable - Set PnP Routing Reg to 0 */
+ Method (_DIS, 0, NotSerialized )
+ {
+ And (PIRD, 0x0F, PIRD)
+ }
+
+} // End of LNKD
+
+
+/* APIC IRQ Links */
+
+Device (ATAI)
+{
+ Name (_HID, EisaId ("PNP0C0F"))
+ Name (_UID, 0x05)
+ Method (_STA, 0, NotSerialized)
+ {
+ /* ATFL == 0x02 if SATA Enabled */
+ If (LNotEqual (ATFL, 0x02))
+ {
+ /* Double Check By Reading SATA VID */
+ /* Otherwise Compatibility Mode */
+ If (LNotEqual (\_SB.PCI0.SATA.VID, 0x1106))
+ {
+ Return (0x09)
+ }
+ Else
+ {
+ Return (0x0B)
+ }
+ }
+ Else
+ {
+ /* Serial ATA Enabled Check if PATA is in */
+ /* Compatibility Mode */
+ If (LEqual (\_SB.PCI0.PATA.ENAT, 0x0A))
+ {
+ Return (0x09)
+ }
+ Else
+ {
+ Return (0x0B)
+ }
+ }
+ }
+
+ Method (_PRS, 0, NotSerialized)
+ {
+ Name (ATAN, ResourceTemplate ()
+ {
+ Interrupt (ResourceConsumer, Level, ActiveLow, Shared, ,, )
+ {
+ 0x00000014,
+ }
+ })
+ Return (ATAN)
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (ATAB, ResourceTemplate ()
+ {
+ Interrupt (ResourceConsumer, Level, ActiveLow, Shared, ,, _Y10)
+ {
+ 0x00000000,
+ }
+ })
+ CreateByteField (ATAB, \_SB.PCI0.ATAI._CRS._Y10._INT, IRAI)
+ Store (0x14, IRAI)
+ Return (ATAB)
+
+ }
+
+ /* Set Resources - dummy function to keep Linux ACPI happy
+ * Linux is more than happy not to tinker with irq
+ * assignments as long as the CRS and STA functions
+ * return good values
+ */
+ Method (_SRS, 1, NotSerialized) {}
+ /* Disable - dummy function to keep Linux ACPI happy */
+ Method (_DIS, 0, NotSerialized ) {}
+
+} // End of ATA Interface Link
+
+
+Device (USBI)
+{
+ Name (_HID, EisaId ("PNP0C0F"))
+ Name (_UID, 0x0A)
+ Method (_STA, 0, NotSerialized)
+ {
+ /* Check that at least one of the USB */
+ /* functions is enabled */
+ And (IDEB, 0x37, Local0)
+ If (LEqual (Local0, 0x37))
+ {
+ Return (0x09)
+ }
+ Else
+ {
+ Return (0x0B)
+ }
+ }
+
+ Method (_PRS, 0, NotSerialized)
+ {
+ Name (USBB, ResourceTemplate ()
+ {
+ Interrupt (ResourceConsumer, Level, ActiveLow, Shared, ,, )
+ {
+ 0x00000015,
+ }
+ })
+
+ Return(USBB)
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (USBB, ResourceTemplate ()
+ {
+ Interrupt (ResourceConsumer, Level, ActiveLow, Shared, ,, _Y12)
+ {
+ 0x00000000,
+ }
+ })
+ CreateByteField (USBB, \_SB.PCI0.USBI._CRS._Y12._INT, IRBI)
+ Store (0x15, IRBI)
+ Return (USBB)
+ }
+
+
+ /* Set Resources - dummy function to keep Linux ACPI happy
+ * Linux is more than happy not to tinker with irq
+ * assignments as long as the CRS and STA functions
+ * return good values
+ */
+ Method (_SRS, 1, NotSerialized) {}
+ /* Disable - dummy function to keep Linux ACPI happy */
+ Method (_DIS, 0, NotSerialized ) {}
+}
+
+Device (VT8I)
+{
+ Name (_HID, EisaId ("PNP0C0F"))
+ Name (_UID, 0x0B)
+ Method (_STA, 0, NotSerialized)
+ {
+ /* Check Whether Sound and/or Modem are Activated */
+ If (LEqual (EAMC, 0x03))
+ {
+ Return (0x09)
+ }
+ Else
+ {
+ Return (0x0B)
+ }
+ }
+
+ Method (_PRS, 0, NotSerialized)
+ {
+ Name (A97C, ResourceTemplate ()
+ {
+ Interrupt (ResourceConsumer, Level, ActiveLow, Shared, ,, )
+ {
+ 0x00000016,
+ }
+ })
+ Return (A97C)
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (A97B, ResourceTemplate ()
+ {
+ Interrupt (ResourceConsumer, Level, ActiveLow, Shared, ,, _Y14)
+ {
+ 0x00000000,
+ }
+ })
+ CreateByteField (A97B, \_SB.PCI0.VT8I._CRS._Y14._INT, IRCI)
+ Store (0x16, IRCI)
+ Return (A97B)
+ }
+
+ /* Set Resources - dummy function to keep Linux ACPI happy
+ * Linux is more than happy not to tinker with irq
+ * assignments as long as the CRS and STA functions
+ * return good values
+ */
+ Method (_SRS, 1, NotSerialized) {}
+ /* Disable - dummy function to keep Linux ACPI happy */
+ Method (_DIS, 0, NotSerialized ) {}
+
+}
+
+
+Device (NICI)
+{
+ Name (_HID, EisaId ("PNP0C0F"))
+ Name (_UID, 0x0C)
+ Method (_STA, 0, NotSerialized)
+ {
+ /* Check if LAN Function is Enabled */
+ /* Note that LAN Enable Polarity is different */
+ /* from other functions in VT8237R !? */
+ If (LEqual (ELAN, 0x00))
+ {
+ Return (0x09)
+ }
+ Else
+ {
+ Return (0x0B)
+ }
+ }
+
+ Method (_PRS, 0, NotSerialized)
+ {
+ Name (NICB, ResourceTemplate ()
+ {
+ Interrupt (ResourceConsumer, Level, ActiveLow, Shared, ,, )
+ {
+ 0x00000017,
+ }
+ })
+ Return (NICB)
+ }
+
+ Method (_CRS, 0, NotSerialized)
+ {
+ Name (NICD, ResourceTemplate ()
+ {
+ Interrupt (ResourceConsumer, Level, ActiveLow, Shared, ,, _Y16)
+ {
+ 0x00000000,
+ }
+ })
+ CreateByteField (NICD, \_SB.PCI0.NICI._CRS._Y16._INT, IRDI)
+ Store (0x17, IRDI)
+ Return (NICD)
+ }
+
+ /* Set Resources - dummy function to keep Linux ACPI happy
+ * Linux is more than happy not to tinker with irq
+ * assignments as long as the CRS and STA functions
+ * return good values
+ */
+ Method (_SRS, 1, NotSerialized) {}
+ /* Disable - dummy function to keep Linux ACPI happy */
+ Method (_DIS, 0, NotSerialized ) {}
+
+
+}
diff --git a/src/mainboard/via/epia-n/mptable.c b/src/mainboard/via/epia-n/mptable.c
new file mode 100644
index 0000000000..e0d5f8f456
--- /dev/null
+++ b/src/mainboard/via/epia-n/mptable.c
@@ -0,0 +1,115 @@
+/* generated by MPTable, version 2.0.15*/
+/* as modified by RGM for coreboot */
+#include <console/console.h>
+#include <arch/smp/mpspec.h>
+#include <device/pci.h>
+#include <string.h>
+#include <stdint.h>
+
+void *smp_write_config_table(void *v)
+{
+ static const char sig[4] = "PCMP";
+ static const char oem[8] = "LNXI ";
+ static const char productid[12] = "P4DPE ";
+ struct mp_config_table *mc;
+
+ mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
+ memset(mc, 0, sizeof(*mc));
+
+ memcpy(mc->mpc_signature, sig, sizeof(sig));
+ mc->mpc_length = sizeof(*mc); /* initially just the header */
+ mc->mpc_spec = 0x04;
+ mc->mpc_checksum = 0; /* not yet computed */
+ memcpy(mc->mpc_oem, oem, sizeof(oem));
+ memcpy(mc->mpc_productid, productid, sizeof(productid));
+ mc->mpc_oemptr = 0;
+ mc->mpc_oemsize = 0;
+ mc->mpc_entry_count = 0; /* No entries yet... */
+ mc->mpc_lapic = LAPIC_ADDR;
+ mc->mpe_length = 0;
+ mc->mpe_checksum = 0;
+ mc->reserved = 0;
+
+ smp_write_processors(mc);
+
+
+/*Bus: Bus ID Type*/
+ smp_write_bus(mc, 0, "PCI ");
+ smp_write_bus(mc, 1, "PCI ");
+ smp_write_bus(mc, 2, "ISA ");
+/*I/O APICs: APIC ID Version State Address*/
+ smp_write_ioapic(mc, 2, 0x20, 0xfec00000);
+ {
+ device_t dev;
+ struct resource *res;
+ dev = dev_find_slot(1, PCI_DEVFN(0x1e,0));
+ if (dev) {
+ res = find_resource(dev, PCI_BASE_ADDRESS_0);
+ if (res) {
+ smp_write_ioapic(mc, 3, 0x20, res->base);
+ }
+ }
+ dev = dev_find_slot(1, PCI_DEVFN(0x1c,0));
+ if (dev) {
+ res = find_resource(dev, PCI_BASE_ADDRESS_0);
+ if (res) {
+ smp_write_ioapic(mc, 4, 0x20, res->base);
+ }
+ }
+ dev = dev_find_slot(4, PCI_DEVFN(0x1e,0));
+ if (dev) {
+ res = find_resource(dev, PCI_BASE_ADDRESS_0);
+ if (res) {
+ smp_write_ioapic(mc, 5, 0x20, res->base);
+ }
+ }
+ dev = dev_find_slot(4, PCI_DEVFN(0x1c,0));
+ if (dev) {
+ res = find_resource(dev, PCI_BASE_ADDRESS_0);
+ if (res) {
+ smp_write_ioapic(mc, 8, 0x20, res->base);
+ }
+ }
+ }
+/*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#
+*/ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x40, 0x2, 0x15);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x40, 0x2, 0x15);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x41, 0x2, 0x15);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x41, 0x2, 0x15);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x42, 0x2, 0x15);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x46, 0x2, 0x16);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x1, 0x0, 0x2, 0x10);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x48, 0x2, 0x17);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x3d, 0x2, 0x14);
+ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x2, 0x0, 0x2, 0x0);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x2, 0x1, 0x2, 0x1);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x2, 0x0, 0x2, 0x2);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x2, 0x3, 0x2, 0x3);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x2, 0x4, 0x2, 0x4);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x2, 0x5, 0x2, 0x5);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x2, 0x6, 0x2, 0x6);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x2, 0x7, 0x2, 0x7);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x2, 0x8, 0x2, 0x8);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x2, 0x9, 0x2, 0x9);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x2, 0xd, 0x2, 0xd);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x2, 0xe, 0x2, 0xe);
+ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x2, 0xf, 0x2, 0xf);
+/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/
+ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x0, 0x0, MP_APIC_ALL, 0x0);
+ smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x0, 0x0, MP_APIC_ALL, 0x1);
+ /* There is no extension information... */
+
+ /* Compute the checksums */
+ mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
+ mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
+ printk_debug("Wrote the mp table end at: %p - %p\n",
+ mc, smp_next_mpe_entry(mc));
+ return smp_next_mpe_entry(mc);
+}
+
+unsigned long write_smp_table(unsigned long addr)
+{
+ void *v;
+ v = smp_write_floating_table(addr);
+ return (unsigned long)smp_write_config_table(v);
+}
diff --git a/src/mainboard/via/epia-n/pata_methods.asl b/src/mainboard/via/epia-n/pata_methods.asl
new file mode 100644
index 0000000000..68d505868e
--- /dev/null
+++ b/src/mainboard/via/epia-n/pata_methods.asl
@@ -0,0 +1,132 @@
+/*
+ * Minimalist ACPI DSDT table for EPIA-N / NL
+ * Basic description of some hardware resources to allow
+ * interrupt assignments to be done. This is expected to be included
+ * into the PATA Device definition in ab_physical.asl
+ * (C) Copyright 2009 Jon Harrison <jon.harrison@blueyonder.co.uk>
+ *
+ */
+
+Name (TIM0, Package (0x07)
+{
+ Package (0x05)
+ {
+ 0x78, 0xB4, 0xF0, 0x017F, 0x0258
+ },
+
+ Package (0x05)
+ {
+ 0x20, 0x22, 0x33, 0x47, 0x5D
+ },
+
+ Package (0x05)
+ {
+ 0x04, 0x03, 0x02, 0x01, 0x00
+ },
+
+ Package (0x04)
+ {
+ 0x02, 0x01, 0x00, 0x00
+ },
+
+ Package (0x07)
+ {
+ 0x78, 0x50, 0x3C, 0x2D, 0x1E, 0x14, 0x0F
+ },
+
+ Package (0x0F)
+ {
+ 0x06, 0x05, 0x04, 0x04, 0x03, 0x03, 0x02, 0x02,
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,0x00
+ },
+
+ Package (0x07)
+ {
+ 0x0E, 0x08, 0x06, 0x04, 0x02, 0x01, 0x00
+ }
+})
+
+
+/* This method sets up the PATA Timing Control*/
+/* Note that a lot of this is done in the */
+/* Coreboot VT8237R Init code, but this is */
+/* already getting very cluttered with board */
+/* specific code. Using ACPI will allow this */
+/* to be de-cluttered a bit (so long as we're */
+/* running a ACPI Capable OS !!!) */
+
+Method (PMEX, 0, Serialized)
+{
+ If (REGF)
+ {
+ /* Check if these regs are still at defaults */
+ /* Board specific timing improvement if not */
+ /* Already changed */
+ If (LEqual (PMPT, 0xA8))
+ {
+ Store (0x5D, PMPT)
+ }
+
+ If (LEqual (PSPT, 0xA8))
+ {
+ Store (0x5D, PSPT)
+ }
+
+ If (LEqual (SMPT, 0xA8))
+ {
+ Store (0x5D, SMPT)
+ }
+
+ If (LEqual (SSPT, 0xA8))
+ {
+ Store (0x5D, SSPT)
+ }
+
+ }
+}
+
+/* This Method Provides the method that is used to */
+/* Reset ATA Drives to POST reset condition */
+Method (GTF, 4, Serialized)
+{
+ Store (Buffer (0x07)
+ {
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xEF
+ }, Local1)
+ Store (Buffer (0x07)
+ {
+ 0x03, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xEF
+ }, Local2)
+ CreateByteField (Local1, 0x01, MODE)
+ CreateByteField (Local2, 0x01, UMOD)
+ CreateByteField (Local1, 0x05, PCHA)
+ CreateByteField (Local2, 0x05, UCHA)
+ And (Arg0, 0x03, Local3)
+ If (LEqual (And (Local3, 0x01), 0x01))
+ {
+ Store (0xB0, PCHA)
+ Store (0xB0, UCHA)
+ }
+
+ If (Arg1)
+ {
+ Store (DerefOf (Index (DerefOf (Index (TIM0, 0x05)), Arg2)),
+ UMOD)
+ Or (UMOD, 0x40, UMOD)
+ }
+ Else
+ {
+ Store (Match (DerefOf (Index (TIM0, 0x01)), MEQ, Arg3, MTR,
+ 0x00, 0x00), Local0)
+ Or (0x20, DerefOf (Index (DerefOf (Index (TIM0, 0x03)), Local0
+ )), UMOD)
+ }
+
+ Store (Match (DerefOf (Index (TIM0, 0x01)), MEQ, Arg3, MTR,
+ 0x00, 0x00), Local0)
+ Or (0x08, DerefOf (Index (DerefOf (Index (TIM0, 0x02)), Local0
+ )), MODE)
+ Concatenate (Local1, Local2, Local6)
+ Return (Local6)
+}
+
diff --git a/src/mainboard/via/epia-n/pci_init.asl b/src/mainboard/via/epia-n/pci_init.asl
new file mode 100644
index 0000000000..3169a03d50
--- /dev/null
+++ b/src/mainboard/via/epia-n/pci_init.asl
@@ -0,0 +1,30 @@
+/*
+ * Minimalist ACPI DSDT table for EPIA-N / NL
+ * Basic description of PCI Interrupt Assignments.
+ * This is expected to be included into _SB.PCI0 namespace
+ * (C) Copyright 2009 Jon Harrison <jon.harrison@blueyonder.co.uk>
+ *
+ */
+
+/* This file provides a PCI Bus Initialisation Method that sets
+ * some flags for use in the interrupt link assignment
+ */
+
+Method (\_SB.PCI0._INI, 0, NotSerialized)
+{
+
+ /* Checking for ATA Interface Enabled */
+ Store (0x00, ATFL)
+ If (LEqual (EIDE, 0x01))
+ {
+ Store (0x02, ATFL)
+ }
+ Else
+ {
+ If (LNotEqual (\_SB.PCI0.PATA.VID, 0x1106))
+ {
+ Store (0x01, ATFL)
+ }
+ }
+
+}
diff --git a/src/mainboard/via/epia-n/sb_physical.asl b/src/mainboard/via/epia-n/sb_physical.asl
new file mode 100644
index 0000000000..c59feb64f0
--- /dev/null
+++ b/src/mainboard/via/epia-n/sb_physical.asl
@@ -0,0 +1,548 @@
+/*
+ * Minimalist ACPI DSDT table for EPIA-N / NL
+ * Basic description of some hardware resources to allow
+ * interrupt assignments to be done. This is expected to be included
+ * into _SB.PCI0 namespace
+ * (C) Copyright 2009 Jon Harrison <jon.harrison@blueyonder.co.uk>
+ *
+ */
+
+
+/* Basic description of the VT8237R LPC Interface
+ * PCI Configuration Space
+ */
+
+Device (VT8R)
+{
+ Name (_ADR, 0x00110000)
+ OperationRegion (USBC, PCI_Config, 0x50, 0x02)
+ Scope (\)
+ {
+ Field (\_SB.PCI0.VT8R.USBC, ByteAcc, NoLock, Preserve)
+ {
+ IDEB, 8
+ }
+ }
+
+ OperationRegion (VTSB, PCI_Config, 0x00, 0xE8)
+ Scope (\)
+ {
+ Field (\_SB.PCI0.VT8R.VTSB, ByteAcc, NoLock, Preserve)
+ {
+ Offset (0x02),
+ DEID, 16,
+ Offset (0x2C),
+ ID2C, 8,
+ ID2D, 8,
+ ID2E, 8,
+ ID2F, 8,
+ Offset (0x44),
+ PIRE, 4,
+ PIRF, 4,
+ PIRG, 4,
+ PIRH, 4,
+ POLE, 1,
+ POLF, 1,
+ POLG, 1,
+ POLH, 1,
+ ENR8, 1,
+ Offset (0x50),
+ ESB4, 1,
+ ESB3, 1,
+ ESB2, 1,
+ EIDE, 1,
+ EUSB, 1,
+ ESB1, 1,
+ EAMC, 2,
+ EKBC, 1,
+ KBCC, 1,
+ EPS2, 1,
+ ERTC, 1,
+ ELAN, 1,
+ , 2,
+ USBD, 1,
+ SIRQ, 8,
+ Offset (0x55),
+ PIRA, 8,
+ PIBC, 8,
+ PIRD, 8,
+ Offset (0x75),
+ BSAT, 1,
+ Offset (0x94),
+ PWC1, 2,
+ GPO1, 1,
+ GPO2, 1,
+ GPO3, 1,
+ PLLD, 1
+ }
+ }
+}
+
+/* Basic Description of Serial ATA Interface */
+Device (SATA)
+{
+ Name (_ADR, 0x000F0000)
+ Method (_STA, 0, NotSerialized)
+ {
+ If (LNotEqual (\_SB.PCI0.SATA.VID, 0x1106))
+ {
+ Return (0x00)
+ }
+ Else
+ {
+ If (LEqual (\_SB.PCI0.SATA.CMDR, 0x00))
+ {
+ Return (0x0D)
+ }
+ Else
+ {
+ Return (0x0F)
+ }
+ }
+ }
+
+ OperationRegion (SAPR, PCI_Config, 0x00, 0xC2)
+ Field (SAPR, ByteAcc, NoLock, Preserve)
+ {
+ VID, 16,
+ Offset (0x04),
+ CMDR, 3,
+ Offset (0x3C),
+ IDEI, 8,
+ Offset (0x49),
+ , 6,
+ EPHY, 1
+ }
+}
+
+/* Basic Description of Parallel ATA Interface */
+/* An some initialisation of the interface */
+Device (PATA)
+{
+ Name (_ADR, 0x000F0001)
+ Name (REGF, 0x01)
+ Method (_STA, 0, NotSerialized)
+ {
+ If (LNotEqual (\_SB.PCI0.PATA.VID, 0x1106))
+ {
+ Return (0x00)
+ }
+ Else
+ {
+ PMEX ()
+ /* Check if the Interface is Enabled */
+ If (LEqual (\_SB.PCI0.PATA.CMDR, 0x00))
+ {
+ Return (0x0D)
+ }
+ Else
+ {
+ Return (0x0F)
+ }
+ }
+ }
+
+ /* ACPI Spec says to check that regions are accessible */
+ /* before trying to access them */
+ Method (_REG, 2, NotSerialized)
+ {
+ /* Arg0 = Operating Region (0x02 == PCI_Config) */
+ If (LEqual (Arg0, 0x02))
+ {
+ /* Arg1 = Handler Connection Mode (0x01 == Connect) */
+ Store (Arg1, REGF)
+ }
+ }
+
+ Include("pata_methods.asl")
+
+
+ OperationRegion (PAPR, PCI_Config, 0x00, 0xC2)
+ Field (PAPR, ByteAcc, NoLock, Preserve)
+ {
+ VID, 16,
+ Offset (0x04),
+ CMDR, 3,
+ Offset (0x09),
+ ENAT, 4,
+ Offset (0x3C),
+ IDEI, 8,
+ Offset (0x40),
+ ESCH, 1,
+ EPCH, 1,
+ Offset (0x48),
+ SSPT, 8,
+ SMPT, 8,
+ PSPT, 8,
+ PMPT, 8,
+ Offset (0x50),
+ SSUT, 4,
+ SSCT, 1,
+ SSUE, 3,
+ SMUT, 4,
+ SMCT, 1,
+ SMUE, 3,
+ PSUT, 4,
+ PSCT, 1,
+ PSUE, 3,
+ PMUT, 4,
+ PMCT, 1,
+ PMUE, 3
+ }
+
+
+ Device (CHN0)
+ {
+ Name (_ADR, 0x00)
+ Method (_STA, 0, NotSerialized)
+ {
+ If (LNotEqual (\_SB.PCI0.PATA.EPCH, 0x01))
+ {
+ Return (0x00)
+ }
+ Else
+ {
+ Return (0x0F)
+ }
+ }
+
+ Device (DRV0)
+ {
+ Name (_ADR, 0x00)
+ Method (_GTF, 0, NotSerialized)
+ {
+ Return (GTF (0x00, PMUE, PMUT, PMPT))
+ }
+ }
+
+ Device (DRV1)
+ {
+ Name (_ADR, 0x01)
+ Method (_GTF, 0, NotSerialized)
+ {
+ Return (GTF (0x01, PSUE, PSUT, PSPT))
+ }
+ }
+ }
+
+ Device (CHN1)
+ {
+ Name (_ADR, 0x01)
+ Method (_STA, 0, NotSerialized)
+ {
+ If (LNotEqual (ATFL, 0x02))
+ {
+ If (LEqual (\_SB.PCI0.SATA.EPHY, 0x01))
+ {
+ Return (0x00)
+ }
+ Else
+ {
+ If (LNotEqual (\_SB.PCI0.PATA.ESCH, 0x01))
+ {
+ Return (0x00)
+ }
+ Else
+ {
+ Return (0x0F)
+ }
+ }
+ }
+ Else
+ {
+ If (LEqual (ATFL, 0x02))
+ {
+ If (LNotEqual (\_SB.PCI0.PATA.ESCH, 0x01))
+ {
+ Return (0x00)
+ }
+ Else
+ {
+ Return (0x0F)
+ }
+ }
+ Else
+ {
+ Return(0x00)
+ }
+ }
+ }
+
+ Device (DRV0)
+ {
+ Name (_ADR, 0x00)
+ Method (_GTF, 0, NotSerialized)
+ {
+ Return (GTF (0x02, SMUE, SMUT, SMPT))
+ }
+ }
+
+ Device (DRV1)
+ {
+ Name (_ADR, 0x01)
+ Method (_GTF, 0, NotSerialized)
+ {
+ Return (GTF (0x03, SSUE, SSUT, SSPT))
+ }
+ }
+ }
+} // End of PATA Device
+
+
+/* Implement Basic USB Presence detect and */
+/* Power Management Event mask */
+Device (USB0)
+{
+ Name (_ADR, 0x00100000)
+ Name (_PRW, Package (0x02)
+ {
+ 0x0E,
+ 0x03
+ })
+
+ OperationRegion (U2F0, PCI_Config, 0x00, 0xC2)
+ Field (U2F0, ByteAcc, NoLock, Preserve)
+ {
+ VID, 16,
+ Offset (0x04),
+ CMDR, 3,
+ Offset (0x3C),
+ U0IR, 4,
+ Offset (0x84),
+ ECDX, 2
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ If (LNotEqual (\_SB.PCI0.USB0.VID, 0x1106))
+ {
+ Return (0x00)
+ }
+ Else
+ {
+ If (LEqual (\_SB.PCI0.USB0.CMDR, 0x00))
+ {
+ Return (0x0D)
+ }
+ Else
+ {
+ Return (0x0F)
+ }
+ }
+ }
+}
+
+Device (USB1)
+{
+ Name (_ADR, 0x00100001)
+ Name (_PRW, Package (0x02)
+ {
+ 0x0E,
+ 0x03
+ })
+
+ OperationRegion (U2F1, PCI_Config, 0x00, 0xC2)
+ Field (U2F1, ByteAcc, NoLock, Preserve)
+ {
+ VID, 16,
+ Offset (0x04),
+ CMDR, 3,
+ Offset (0x3C),
+ U1IR, 4,
+ Offset (0x84),
+ ECDX, 2
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ If (LNotEqual (\_SB.PCI0.USB1.VID, 0x1106))
+ {
+ Return (0x00)
+ }
+ Else
+ {
+ If (LEqual (\_SB.PCI0.USB1.CMDR, 0x00))
+ {
+ Return (0x0D)
+ }
+ Else
+ {
+ Return (0x0F)
+ }
+ }
+ }
+}
+
+Device (USB2)
+{
+ Name (_ADR, 0x00100002)
+ Name (_PRW, Package (0x02)
+ {
+ 0x0E,
+ 0x03
+ })
+
+ OperationRegion (U2F2, PCI_Config, 0x00, 0xC2)
+ Field (U2F2, ByteAcc, NoLock, Preserve)
+ {
+ VID, 16,
+ Offset (0x04),
+ CMDR, 3,
+ Offset (0x3C),
+ U2IR, 4,
+ Offset (0x84),
+ ECDX, 2
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ If (LNotEqual (\_SB.PCI0.USB2.VID, 0x1106))
+ {
+ Return (0x00)
+ }
+ Else
+ {
+ If (LEqual (\_SB.PCI0.USB2.CMDR, 0x00))
+ {
+ Return (0x0D)
+ }
+ Else
+ {
+ Return (0x0F)
+ }
+ }
+ }
+}
+
+Device (USB3)
+{
+ Name (_ADR, 0x00100003)
+ Name (_PRW, Package (0x02)
+ {
+ 0x0E,
+ 0x03
+ })
+
+ OperationRegion (U2F3, PCI_Config, 0x00, 0xC2)
+ Field (U2F3, ByteAcc, NoLock, Preserve)
+ {
+ VID, 16,
+ Offset (0x04),
+ CMDR, 3,
+ Offset (0x3C),
+ U3IR, 4,
+ Offset (0x84),
+ ECDX, 2
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ If (LNotEqual (\_SB.PCI0.USB3.VID, 0x1106))
+ {
+ Return (0x00)
+ }
+ Else
+ {
+ If (LEqual (\_SB.PCI0.USB3.CMDR, 0x00))
+ {
+ Return (0x0D)
+ }
+ Else
+ {
+ Return (0x0F)
+ }
+ }
+ }
+}
+
+Device (USB4)
+{
+ Name (_ADR, 0x00100004)
+ Name (_PRW, Package (0x02)
+ {
+ 0x0E,
+ 0x03
+ })
+
+ OperationRegion (U2F4, PCI_Config, 0x00, 0xC2)
+ Field (U2F4, ByteAcc, NoLock, Preserve)
+ {
+ VID, 16,
+ Offset (0x04),
+ CMDR, 3,
+ Offset (0x3C),
+ U4IR, 4,
+ Offset (0x84),
+ ECDX, 2
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ If (LNotEqual (\_SB.PCI0.USB4.VID, 0x1106))
+ {
+ Return (0x00)
+ }
+ Else
+ {
+ If (LEqual (\_SB.PCI0.USB4.CMDR, 0x00))
+ {
+ Return (0x0D)
+ }
+ Else
+ {
+ Return (0x0F)
+ }
+ }
+ }
+}
+
+/* Basic Definition of Ethernet Interface */
+Device (NIC0)
+{
+ Name (_ADR, 0x00120000)
+ Name (_PRW, Package (0x02)
+ {
+ 0x03,
+ 0x05
+ })
+
+ OperationRegion (NIC0, PCI_Config, 0x00, 0xC2)
+ Field (NIC0, ByteAcc, NoLock, Preserve)
+ {
+ VID, 16,
+ Offset (0x04),
+ CMDR, 3,
+ Offset (0x3C),
+ NIIR, 4,
+ }
+
+ Method (_STA, 0, NotSerialized)
+ {
+ If (LNotEqual (\_SB.PCI0.NIC0.VID, 0x1106))
+ {
+ Return (0x00)
+ }
+ Else
+ {
+ If (LEqual (\_SB.PCI0.NIC0.CMDR, 0x00))
+ {
+ Return (0x0D)
+ }
+ Else
+ {
+ Return (0x0F)
+ }
+ }
+ }
+}
+
+/* Very Basic Definition of Sound Controller */
+Device (AC97)
+{
+ Name (_ADR, 0x00110005)
+ Name (_PRW, Package (0x02)
+ {
+ 0x0D,
+ 0x05
+ })
+}
diff --git a/src/northbridge/via/cn400/vlink.c b/src/northbridge/via/cn400/vlink.c
new file mode 100644
index 0000000000..1542af71fe
--- /dev/null
+++ b/src/northbridge/via/cn400/vlink.c
@@ -0,0 +1,246 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 Jon Harrison <bothlyn@blueyonder.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <console/console.h>
+#include <arch/io.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "chip.h"
+#include "northbridge.h"
+#include "cn400.h"
+
+static void noop_1k(u32 knops)
+{
+ u32 i;
+
+ for (i = 0; i < 1024 * knops; i++) {
+ __asm__ volatile ("nop\n\t");
+ }
+
+ return;
+}
+
+/* Vlink Performance Improvements */
+static void vlink_init(device_t dev)
+{
+ u8 reg, reg8;
+ int i, j;
+
+ printk_spew("Entering CN400 %s\n", __func__);
+
+ /* Disconnect the VLink Before Changing Settings */
+ reg = pci_read_config8(dev, 0x47);
+ reg |= 0x04;
+ pci_write_config8(dev, 0x47, reg);
+
+ /* Wait for anything pending to flush */
+ noop_1k(20);
+
+ /* Setup Vlink Mode 1 */
+ pci_write_config8(dev, 0x4F, 0x01);
+ pci_write_config8(dev, 0x48, 0x13);
+
+ /* PCI Buffer Control */
+ pci_write_config8(dev, 0x70, 0x82);
+
+ /* CPU to PCI Flow Control */
+ pci_write_config8(dev, 0x71, 0xc8);
+ pci_write_config8(dev, 0x72, 0xee);
+
+ /* PCI Master Control */
+ pci_write_config8(dev, 0x73, 0x01);
+ pci_write_config8(dev, 0x74, 0x20);
+
+ /* PCI Arbitration 1 */
+ pci_write_config8(dev, 0x75, 0x0f);
+
+ /* PCI Arbitration 2 */
+ pci_write_config8(dev, 0x76, 0x50);
+ pci_write_config8(dev, 0x77, 0x6e);
+ pci_write_config8(dev, 0x7F, 0x10);
+
+ pci_write_config8(dev, 0x94, 0x20);
+ pci_write_config8(dev, 0x95, 0x0f);
+
+ /* V-Link CKG Control 1 */
+ pci_write_config8(dev, 0xB0, 0x01);
+
+ /* V-Link NB Compensation Control */
+ pci_write_config8(dev, 0xB5, 0x46);
+ pci_write_config8(dev, 0xB6, 0x68);
+ reg = pci_read_config8(dev, 0xB4);
+ reg |= 0x01;
+ pci_write_config8(dev, 0xB4, reg);
+
+ /* V-Link NB Receive Strobe Delay */
+ pci_write_config8(dev, 0xB7, 0x02);
+
+ /* V-Link SB Compensation Control */
+ pci_write_config8(dev, 0xB9, 0x84);
+ reg = pci_read_config8(dev, 0xB8);
+ reg |= 0x01;
+ pci_write_config8(dev, 0xB8, reg);
+
+ pci_write_config8(dev, 0xBA, 0x6a);
+ pci_write_config8(dev, 0xBB, 0x01);
+
+#ifdef DEBUG_CN400
+ /* Reconnect the VLink Before Continuing*/
+ reg = pci_read_config8(dev, 0x47);
+ reg &= ~0x04;
+ pci_write_config8(dev, 0x47, reg);
+
+ printk_spew("%s PCI Header Regs::\n", dev_path(dev));
+
+ for (i = 0 ; i < 16; i++)
+ {
+ printk_spew("%02X: ", i*16);
+ for (j = 0; j < 16; j++)
+ {
+ reg8 = pci_read_config8(dev, j+(i*16));
+ printk_spew("%02X ", reg8);
+ }
+ printk_spew("\n");
+ }
+#endif
+}
+
+static const struct device_operations vlink_operations = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = vlink_init,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver vlink_driver __pci_driver = {
+ .ops = &vlink_operations,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_CN400_VLINK,
+};
+
+static void c3_host_init(device_t dev)
+{
+ u8 reg8;
+ int i, j;
+
+ printk_spew("Entering CN400 %s\n", __func__);
+
+ printk_spew("%s PCI Header Regs::\n", dev_path(dev));
+
+ for (i = 0 ; i < 16; i++)
+ {
+ printk_spew("%02X: ", i*16);
+ for (j = 0; j < 16; j++)
+ {
+ reg8 = pci_read_config8(dev, j+(i*16));
+ printk_spew("%02X ", reg8);
+ }
+ printk_spew("\n");
+ }
+
+}
+
+static const struct device_operations c3_host_operations = {
+ .read_resources = cn400_noop,
+ .set_resources = cn400_noop,
+ .enable_resources = cn400_noop,
+ .init = c3_host_init,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver c3_host_driver __pci_driver = {
+ .ops = &c3_host_operations,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_CN400_HOST,
+};
+
+
+static void c3_err_init(device_t dev)
+{
+ u8 reg8;
+ int i, j;
+
+ printk_spew("Entering CN400 %s\n", __func__);
+
+ printk_spew("%s PCI Header Regs::\n", dev_path(dev));
+
+ for (i = 0 ; i < 16; i++)
+ {
+ printk_spew("%02X: ", i*16);
+ for (j = 0; j < 16; j++)
+ {
+ reg8 = pci_read_config8(dev, j+(i*16));
+ printk_spew("%02X ", reg8);
+ }
+ printk_spew("\n");
+ }
+
+}
+
+static const struct device_operations c3_err_operations = {
+ .read_resources = cn400_noop,
+ .set_resources = cn400_noop,
+ .enable_resources = cn400_noop,
+ .init = c3_err_init,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver c3_err_driver __pci_driver = {
+ .ops = &c3_err_operations,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_CN400_ERR,
+};
+
+static void cn400_pm_init(device_t dev)
+{
+ u8 reg8;
+ int i, j;
+
+ printk_spew("Entering CN400 %s\n", __func__);
+
+ printk_spew("%s PCI Header Regs::\n", dev_path(dev));
+
+ for (i = 0 ; i < 16; i++)
+ {
+ printk_spew("%02X: ", i*16);
+ for (j = 0; j < 16; j++)
+ {
+ reg8 = pci_read_config8(dev, j+(i*16));
+ printk_spew("%02X ", reg8);
+ }
+ printk_spew("\n");
+ }
+
+}
+
+static const struct device_operations cn400_pm_operations = {
+ .read_resources = cn400_noop,
+ .set_resources = cn400_noop,
+ .enable_resources = cn400_noop,
+ .init = cn400_pm_init,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver cn400_pm_driver __pci_driver = {
+ .ops = &c3_err_operations,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_CN400_PM,
+};
diff --git a/src/southbridge/via/vt8237r/vt8237r_nic.c b/src/southbridge/via/vt8237r/vt8237r_nic.c
new file mode 100644
index 0000000000..9f618087cb
--- /dev/null
+++ b/src/southbridge/via/vt8237r/vt8237r_nic.c
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz>
+ * Copyright (C) 2009 Jon Harrison <bothlyn@blueyonder.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License v2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "vt8237r.h"
+
+
+static void vt8237_eth_read_resources(struct device *dev)
+{
+#ifdef CONFIG_EPIA_VT8237R_INIT
+ struct resource *res;
+
+ /* Fix the I/O Resources of the USB2.0 Interface */
+ res = new_resource(dev, PCI_BASE_ADDRESS_0);
+ res->base = 0xF6001000ULL;
+ res->size = 256;
+ res->align = 12;
+ res->gran = 8;
+ res->limit = res->base + res->size - 1;
+ res->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+ IORESOURCE_ASSIGNED;
+#else
+ pci_dev_read_resources(dev);
+#endif
+ return;
+}
+
+
+static const struct device_operations vt8237_eth_ops = {
+ .read_resources = vt8237_eth_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver vt8237r_driver_eth __pci_driver = {
+ .ops = &vt8237_eth_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_8233_7,
+};
diff --git a/src/southbridge/via/vt8237r/vt8237r_usb.c b/src/southbridge/via/vt8237r/vt8237r_usb.c
new file mode 100644
index 0000000000..bc4c34f8f9
--- /dev/null
+++ b/src/southbridge/via/vt8237r/vt8237r_usb.c
@@ -0,0 +1,166 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz>
+ * Copyright (C) 2009 Jon Harrison <bothlyn@blueyonder.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License v2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "vt8237r.h"
+
+#ifdef CONFIG_EPIA_VT8237R_INIT
+u32 usb_io_addr[4] = {0xcc00, 0xd000, 0xd400, 0xd800};
+#endif
+
+static void usb_i_init(struct device *dev)
+{
+
+#ifdef CONFIG_EPIA_VT8237R_INIT
+ u8 reg8;
+
+ printk_debug("Entering %s\n", __func__);
+
+ printk_spew("%s Read %02X from PCI Command Reg\n", dev_path(dev), reg8);
+
+ reg8 = pci_read_config8(dev, 0x04);
+
+ reg8 = reg8 | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
+ pci_write_config8(dev, 0x04, reg8);
+
+ printk_spew("%s Wrote %02X to PCI Command Reg\n", dev_path(dev), reg8);
+
+ /* Set Cache Line Size and Latency Timer */
+ pci_write_config8(dev, 0x0c, 0x08);
+ pci_write_config8(dev, 0x0d, 0x20);
+
+ /* Enable Sub Device ID Back Door and set Generic */
+ reg8 = pci_read_config8(dev, 0x42);
+ reg8 |= 0x10;
+ pci_write_config8(dev, 0x42, reg8);
+ pci_write_config16(dev, 0x2e, 0xAA07);
+ reg8 &= ~0x10;
+ pci_write_config8(dev, 0x42, reg8);
+
+
+ pci_write_config8(dev, 0x41, 0x12);
+
+ pci_write_config8(dev, 0x49, 0x0B);
+
+ /* Clear PCI Status */
+ pci_write_config16(dev, 0x06, 0x7A10);
+#endif
+ return;
+}
+
+static void vt8237_usb_i_read_resources(struct device *dev)
+{
+#ifdef CONFIG_EPIA_VT8237R_INIT
+ struct resource *res;
+ u8 function = (u8) dev->path.pci.devfn & 0x7;
+
+ printk_spew("VT8237R Fixing USB 1.1 fn %d I/O resource = 0x%04X\n", function, usb_io_addr[function]);
+
+ /* Fix the I/O Resources of the USB1.1 Interfaces */
+ /* Auto PCI probe seems to size the resources */
+ /* Incorrectly */
+ res = new_resource(dev, PCI_BASE_ADDRESS_4);
+ res->base = usb_io_addr[function];
+ res->size = 256;
+ res->limit = 0xffffUL;
+ res->align = 10;
+ res->gran = 8;
+ res->flags = IORESOURCE_IO | IORESOURCE_FIXED |
+ IORESOURCE_ASSIGNED;
+#else
+ pci_dev_read_resources(dev);
+#endif
+ return;
+}
+
+static void usb_ii_init(struct device *dev)
+{
+#ifdef CONFIG_EPIA_VT8237R_INIT
+ u8 reg8;
+
+ printk_debug("Entering %s\n", __func__);
+
+ /* Set memory Write and Invalidate */
+ reg8 = pci_read_config8(dev, 0x04);
+ reg8 |= 0x10;
+ pci_write_config8(dev, 0x04, reg8);
+
+ /* Set Cache line Size and Latency Timer */
+ pci_write_config8(dev, 0x0c, 0x08);
+ pci_write_config8(dev, 0x0d, 0x20);
+
+ /* Clear PCI Status */
+ pci_write_config16(dev, 0x06, 0x7A10);
+#endif
+
+}
+
+static void vt8237_usb_ii_read_resources(struct device *dev)
+{
+#ifdef CONFIG_EPIA_VT8237R_INIT
+ struct resource *res;
+
+ /* Fix the I/O Resources of the USB2.0 Interface */
+ res = new_resource(dev, PCI_BASE_ADDRESS_0);
+ res->base = 0xF6000000ULL;
+ res->size = 256;
+ res->align = 12;
+ res->gran = 8;
+ res->limit = res->base + res->size - 1;
+ res->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+ IORESOURCE_ASSIGNED;
+#else
+ pci_dev_read_resources(dev);
+#endif
+ return;
+}
+
+static const struct device_operations usb_i_ops = {
+ .read_resources = vt8237_usb_i_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_i_init,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static const struct device_operations usb_ii_ops = {
+ .read_resources = vt8237_usb_ii_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = usb_ii_init,
+ .enable = 0,
+ .ops_pci = 0,
+};
+
+static const struct pci_driver vt8237r_driver_usbii __pci_driver = {
+ .ops = &usb_ii_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_VT8237R_EHCI,
+};
+
+static const struct pci_driver vt8237r_driver_usbi __pci_driver = {
+ .ops = &usb_i_ops,
+ .vendor = PCI_VENDOR_ID_VIA,
+ .device = PCI_DEVICE_ID_VIA_VT8237R_UHCI,
+};