Support for vt8237r/s stage2 for v3, untested due to other issues. Also nuke a 
PCI ID that isn't actually part of the vt8237 at all. WIP.

Signed-off-by: Corey Osgood <corey.osgood@gmail.com>

Index: southbridge/via/vt8237/lpc.c
===================================================================
--- southbridge/via/vt8237/lpc.c	(revision 0)
+++ southbridge/via/vt8237/lpc.c	(revision 0)
@@ -0,0 +1,470 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Corey Osgood <corey.osgood@gmail.com>
+ * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * 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
+ */
+
+/* Inspiration from other VIA SB code. */
+
+#include <types.h>
+#include <io.h>
+#include <lib.h>
+#include <console.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <arch/x86/lapic.h>
+#include <mc146818rtc.h>
+#include <keyboard.h>
+#include <legacy.h>
+#include <statictree.h>
+#include <config.h>
+#include "vt8237.h"
+
+#define ALL		(0xff << 24)
+#define NONE		(0)
+#define DISABLED	(1 << 16)
+#define ENABLED		(0 << 16)
+#define TRIGGER_EDGE	(0 << 15)
+#define TRIGGER_LEVEL	(1 << 15)
+#define POLARITY_HIGH	(0 << 13)
+#define POLARITY_LOW	(1 << 13)
+#define PHYSICAL_DEST	(0 << 11)
+#define LOGICAL_DEST	(1 << 11)
+#define ExtINT		(7 << 8)
+#define NMI		(4 << 8)
+#define SMI		(2 << 8)
+#define INT		(1 << 8)
+
+static struct ioapicreg {
+	u32 reg;
+	u32 value_low;
+	u32 value_high;
+} ioapic_table[] = {
+	/* IO-APIC virtual wire mode configuration. */
+	/* mask, trigger, polarity, destination, delivery, vector */
+	{0, ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST |
+		    ExtINT, NONE},
+	{1,  DISABLED, NONE},
+	{2,  DISABLED, NONE},
+	{3,  DISABLED, NONE},
+	{4,  DISABLED, NONE},
+	{5,  DISABLED, NONE},
+	{6,  DISABLED, NONE},
+	{7,  DISABLED, NONE},
+	{8,  DISABLED, NONE},
+	{9,  DISABLED, NONE},
+	{10, DISABLED, NONE},
+	{11, DISABLED, NONE},
+	{12, DISABLED, NONE},
+	{13, DISABLED, NONE},
+	{14, DISABLED, NONE},
+	{15, DISABLED, NONE},
+	{16, DISABLED, NONE},
+	{17, DISABLED, NONE},
+	{18, DISABLED, NONE},
+	{19, DISABLED, NONE},
+	{20, DISABLED, NONE},
+	{21, DISABLED, NONE},
+	{22, DISABLED, NONE},
+	{23, DISABLED, NONE},
+};
+
+static void setup_ioapic(struct device *dev)
+{
+	struct southbridge_via_vt8237_lpc_config *sb =
+		(struct southbridge_via_vt8237_lpc_config *)dev->device_configuration;
+
+	u32 value_low, value_high, val;
+	volatile u32 *l;
+	int i;
+
+	/* All delivered to CPU0. */
+	ioapic_table[0].value_high = (lapicid()) << (56 - 32);
+	l = (void *)sb->apic_base;
+
+	/* Set APIC to FSB message bus. */
+	l[0] = 0x3;
+	val = l[4];
+	l[4] = (val & 0xFFFFFE) | 1;
+
+	/* Set APIC ADDR - this will be VT8237_APIC_ID. */
+	l[0] = 0;
+	val = l[4];
+	l[4] = (val & 0xF0FFFF) | (sb->apic_id << 24);
+
+	for (i = 0; i < ARRAY_SIZE(ioapic_table); i++) {
+		l[0] = (ioapic_table[i].reg * 2) + 0x10;
+		l[4] = ioapic_table[i].value_low;
+		value_low = l[4];
+		l[0] = (ioapic_table[i].reg * 2) + 0x11;
+		l[4] = ioapic_table[i].value_high;
+		value_high = l[4];
+
+		if ((i == 0) && (value_low == 0xffffffff)) {
+			printk(BIOS_WARNING, "IO APIC not responding.\n");
+			return;
+		}
+	}
+}
+
+/** Set up PCI IRQ routing, route everything through APIC. */
+static void pci_routing_fixup(struct device *dev)
+{
+	/* PCI PNP Interrupt Routing INTE/F - disable */
+	pci_write_config8(dev, 0x44, 0x00);
+
+	/* PCI PNP Interrupt Routing INTG/H - disable */
+	pci_write_config8(dev, 0x45, 0x00);
+
+	/* Route INTE-INTH through registers above, no map to INTA-INTD. */
+	pci_write_config8(dev, 0x46, 0x10);
+
+	/* PCI Interrupt Polarity */
+	pci_write_config8(dev, 0x54, 0x00);
+
+	/* PCI INTA# Routing */
+	pci_write_config8(dev, 0x55, 0x00);
+
+	/* PCI INTB#/C# Routing */
+	pci_write_config8(dev, 0x56, 0x00);
+
+	/* PCI INTD# Routing */
+	pci_write_config8(dev, 0x57, 0x00);
+}
+
+/**
+ * Set up the power management capabilities directly into ACPI mode.
+ * This avoids having to handle any System Management Interrupts (SMIs).
+ */
+static void setup_pm(struct device *dev)
+{
+	struct southbridge_via_vt8237_lpc_config *sb =
+		(struct southbridge_via_vt8237_lpc_config *)dev->device_configuration;
+
+	/* Debounce LID and PWRBTN# Inputs for 16ms. */
+	pci_write_config8(dev, 0x80, 0x20);
+
+	/* Set ACPI base address to I/O sb->acpi_io_base. */
+	pci_write_config16(dev, 0x88, sb->acpi_io_base | 0x1);
+
+	/* Set ACPI to 9, must set IRQ 9 override to level! Set PSON gating. */
+	pci_write_config8(dev, 0x82, 0x40 | sb->acpi_irq);
+
+	/* Primary interupt channel, define wake events 0=IRQ0 15=IRQ15 1=en. */
+	pci_write_config16(dev, 0x84, 0x30b2);
+
+	/* SMI output level to low, 7.5us throttle clock */
+	pci_write_config8(dev, 0x8d, 0x18);
+
+	/* GP Timer Control 1s */
+	pci_write_config8(dev, 0x93, 0x88);
+
+	/*
+	 * 7 = SMBus clock from RTC 32.768KHz
+	 * 5 = Internal PLL reset from susp
+	 * 2 = GPO2 is GPIO
+	 */
+	pci_write_config8(dev, 0x94, 0xa4);
+
+	/*
+	 * 7 = stp to sust delay 1msec
+	 * 6 = SUSST# Deasserted Before PWRGD for STD
+	 * 4 = PWRGOOD reset on VT8237A/S
+	 * 3 = GPO26/GPO27 is GPO 
+	 * 2 = Disable Alert on Lan
+	 */
+	pci_write_config8(dev, 0x95, 0xcc);
+
+	/* Disable GP3 timer. */
+	pci_write_config8(dev, 0x98, 0);
+
+	/* Enable ACPI accessm RTC signal gated with PSON. */
+	pci_write_config8(dev, 0x81, 0x84);
+
+	/* Clear status events. */
+	outw(0xffff, sb->acpi_io_base + 0x00);
+	outw(0xffff, sb->acpi_io_base + 0x20);
+	outw(0xffff, sb->acpi_io_base + 0x28);
+	outl(0xffffffff, sb->acpi_io_base + 0x30);
+
+	/* Disable SCI on GPIO. */
+	outw(0x0, sb->acpi_io_base + 0x22);
+
+	/* Disable SMI on GPIO. */
+	outw(0x0, sb->acpi_io_base + 0x24);
+
+	/* Disable all global enable SMIs. */
+	outw(0x0, sb->acpi_io_base + 0x2a);
+
+	/* All SMI off, both IDE buses ON, PSON rising edge. */
+	outw(0x0, sb->acpi_io_base + 0x2c);
+
+	/* Primary activity SMI disable. */
+	outl(0x0, sb->acpi_io_base + 0x34);
+
+	/* GP timer reload on none. */
+	outl(0x0, sb->acpi_io_base + 0x38);
+
+	/* Disable extended IO traps. */
+	outb(0x0, sb->acpi_io_base + 0x42);
+
+	/* SCI is generated for RTC/pwrBtn/slpBtn. */
+	outw(0x001, sb->acpi_io_base + 0x04);
+}
+
+static void vt8237_common_init(struct device *dev)
+{
+	u8 enables, byte;
+
+	/* Enable addr/data stepping. */
+	byte = pci_read_config8(dev, PCI_COMMAND);
+	byte |= PCI_COMMAND_WAIT;
+	pci_write_config8(dev, PCI_COMMAND, byte);
+
+	/* Enable the internal I/O decode. */
+	enables = pci_read_config8(dev, 0x6C);
+	enables |= 0x80;
+	pci_write_config8(dev, 0x6C, enables);
+
+	/*
+	 * ROM decode
+	 * bit range
+	 *   7 000E0000h-000EFFFFh
+	 *   6 FFF00000h-FFF7FFFFh
+	 *   5 FFE80000h-FFEFFFFFh
+	 *   4 FFE00000h-FFE7FFFFh
+	 *   3 FFD80000h-FFDFFFFFh
+	 *   2 FFD00000h-FFD7FFFFh
+	 *   1 FFC80000h-FFCFFFFFh
+	 *   0 FFC00000h-FFC7FFFFh
+	 * So 0x7f here sets ROM decode to FFC00000-FFFFFFFF or 4Mbyte.
+	 */
+	pci_write_config8(dev, 0x41, 0x7f);
+
+	/*
+	 * Set bit 6 of 0x40 (I/O recovery time).
+	 * IMPORTANT FIX - EISA = ECLR reg at 0x4d0! Decoding must be on so
+	 * that PCI interrupts can be properly marked as level triggered.
+	 */
+	enables = pci_read_config8(dev, 0x40);
+	enables |= 0x44;
+	pci_write_config8(dev, 0x40, enables);
+
+	/* Line buffer control */
+	enables = pci_read_config8(dev, 0x42);
+	enables |= 0xf8;
+	pci_write_config8(dev, 0x42, enables);
+
+	/* Delay transaction control */
+	pci_write_config8(dev, 0x43, 0xb);
+
+	/* I/O recovery time, default IDE routing */
+	pci_write_config8(dev, 0x4c, 0x44);
+
+	/* ROM memory cycles go to LPC. */
+	pci_write_config8(dev, 0x59, 0x80);
+
+	/*
+	 * Bit | Meaning
+	 * -------------
+	 *   3 | Bypass APIC De-Assert Message (1=Enable)
+	 *   1 | possibly "INTE#, INTF#, INTG#, INTH# as PCI"
+	 *     | bit 1=1 works for Aaron at VIA, bit 1=0 works for jakllsch
+	 *   0 | Dynamic Clock Gating Main Switch (1=Enable)
+	 */
+	pci_write_config8(dev, 0x5b, 0xb);
+
+	/* Set 0x58 to 0x43 APIC and RTC. */
+	pci_write_config8(dev, 0x58, 0x43);
+
+	/* Enable serial IRQ, 6PCI clocks. */
+	pci_write_config8(dev, 0x52, 0x9);
+
+	/* Power management setup */
+	setup_pm(dev);
+
+	/* Enable the RTC. */
+	enables = pci_read_config8(dev, 0x51);
+	enables |= (1 << 3);
+	pci_write_config8(dev, 0x51, enables);
+
+	/* Start the RTC. */
+	rtc_init(0);
+}
+
+static void vt8237_read_resources(struct device *dev)
+{
+	struct southbridge_via_vt8237_lpc_config *sb =
+		(struct southbridge_via_vt8237_lpc_config *)dev->device_configuration;
+
+	struct resource *res;
+
+	pci_dev_read_resources(dev);
+	/* Fixed APIC resource */
+	res = new_resource(dev, 0x44);
+	/* Possible breakage */
+	res->base = sb->apic_base;
+	res->size = 256;
+	res->limit = res->base + res->size - 1;
+	res->align = 8;
+	res->gran = 8;
+	res->flags = IORESOURCE_MEM | IORESOURCE_FIXED |
+		     IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+}
+
+/**
+ * The VT8237 is not a PCI bridge and has no resources of its own (other
+ * than standard PC I/O addresses), however it does control the ISA bus
+ * and so we need to manually call enable childrens resources on that bus.
+ */
+static void vt8237_enable_resources(struct device *dev)
+{
+	pci_dev_enable_resources(dev);
+	enable_childrens_resources(dev);
+}
+
+static void init_keyboard(struct device *dev)
+{
+	struct southbridge_via_vt8237_lpc_config *sb =
+		(struct southbridge_via_vt8237_lpc_config *)dev->device_configuration;
+
+	u8 regval;
+
+	if (sb->enable_keyboard)
+	{
+		/* Enable PS/2 mouse, Keyboard, and KBC Config */
+		regval = pci_read_config8(dev, 0x51);
+		regval |= (1 << 2)|(1 << 1)|1;
+		pci_write_config8(dev, 0x51, regval);
+
+		init_pc_keyboard(0x60, 0x64, 0);
+	}
+}
+
+static void southbridge_init_common(struct device *dev)
+{
+	vt8237_common_init(dev);
+	pci_routing_fixup(dev);
+	setup_ioapic(dev);
+	setup_i8259();
+	init_keyboard(dev);
+}
+
+static void vt8237r_init(struct device *dev)
+{
+	struct southbridge_via_vt8237_lpc_config *sb =
+		(struct southbridge_via_vt8237_lpc_config *)dev->device_configuration;
+
+	u8 enables;
+
+	/*
+	 * Enable SATA LED, disable special CPU Frequency Change -
+	 * GPIO28 GPIO22 GPIO29 GPIO23 are GPIOs.
+	 */
+	pci_write_config8(dev, 0xe5, 0x9);
+
+	/* REQ5 as PCI request input - should be together with INTE-INTH. */
+	pci_write_config8(dev, 0xe4, 0x4);
+
+	/* Set bit 3 of 0x4f (use INIT# as CPU reset). */
+	enables = pci_read_config8(dev, 0x4f);
+	enables |= 0x08;
+	pci_write_config8(dev, 0x4f, enables);
+
+	/*
+	 * Set Read Pass Write Control Enable
+	 * (force A2 from APIC FSB to low).
+	 */
+	pci_write_config8(dev, 0x48, 0x8c);
+
+	southbridge_init_common(dev);
+
+	/* FIXME: Intel needs more bit set for C2/C3. */
+
+	/*
+	 * Allow SLP# signal to assert LDTSTOP_L.
+	 * Will work for C3 and for FID/VID change.
+	 */
+	outb(0x1, sb->acpi_io_base + 0x11);
+}
+
+static void vt8237s_init(struct device *dev)
+{
+	struct southbridge_via_vt8237_lpc_config *sb =
+		(struct southbridge_via_vt8237_lpc_config *)dev->device_configuration;
+
+	u32 tmp;
+
+	/* Put SPI base VT8237S_SPI_MEM_BASE. */
+	tmp = pci_read_config32(dev, 0xbc);
+	pci_write_config32(dev, 0xbc, (sb->spi_mem_base >> 8) | (tmp & 0xFF000000));
+
+	/* Enable SATA LED, VR timer = 100us, VR timer should be fixed. */
+	pci_write_config8(dev, 0xe5, 0x69);
+
+	/*
+	 * REQ5 as PCI request input - should be together with INTE-INTH. 
+	 * Fast VR timer disable - need for LDTSTOP_L signal.
+	 */
+	pci_write_config8(dev, 0xe4, 0xa5);
+
+	/* Reduce further the STPCLK/LDTSTP signal to 5us. */
+	pci_write_config8(dev, 0xec, 0x4);
+
+	/* Host Bus Power Management Control, maybe not needed */
+	pci_write_config8(dev, 0x8c, 0x5);
+
+	/* Enable HPET at hpet_addr (from dts), does not work correctly on R. */
+	pci_write_config32(dev, 0x68, (sb->hpet_addr | 0x80));
+
+	southbridge_init_common(dev);
+
+	/* FIXME: Intel needs more bit set for C2/C3. */
+
+	/*
+	 * Allow SLP# signal to assert LDTSTOP_L.
+	 * Will work for C3 and for FID/VID change. FIXME FIXME, pre rev A2.
+	 */
+	
+	outb(0xff, sb->acpi_io_base + 0x50);
+}
+
+struct device_operations vt8237r_lpc = {
+	.id = {.type = DEVICE_ID_PCI,
+		{.pci = {.vendor = PCI_VENDOR_ID_VIA,
+				.device = PCI_DEVICE_ID_VIA_VT8237R_LPC}}},
+	.constructor			= default_device_constructor,
+	.phase2_fixup			= vt8237_enable,
+	.phase3_scan			= scan_static_bus,
+	.phase4_read_resources		= vt8237_read_resources,
+	.phase4_set_resources		= pci_dev_set_resources,
+	.phase5_enable_resources	= vt8237_enable_resources,
+	.phase6_init			= vt8237r_init,
+};
+
+struct device_operations vt8237s_lpc = {
+	.id = {.type = DEVICE_ID_PCI,
+		{.pci = {.vendor = PCI_VENDOR_ID_VIA,
+				.device = PCI_DEVICE_ID_VIA_VT8237S_LPC}}},
+	.constructor			= default_device_constructor,
+	.phase2_fixup			= vt8237_enable,
+	.phase3_scan			= scan_static_bus,
+	.phase4_read_resources		= vt8237_read_resources,
+	.phase4_set_resources		= pci_dev_set_resources,
+	.phase5_enable_resources	= vt8237_enable_resources,
+	.phase6_init			= vt8237s_init,
+};
Index: southbridge/via/vt8237/sata.dts
===================================================================
--- southbridge/via/vt8237/sata.dts	(revision 0)
+++ southbridge/via/vt8237/sata.dts	(revision 0)
@@ -0,0 +1,28 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Corey Osgood <corey.osgood@gmail.com>
+ *
+ * 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
+ */
+
+{
+	device_operations = "vt8237r_sata";
+	/* configuration variables go here */
+};
+
+{
+	device_operations = "vt8237s_sata";
+};
Index: southbridge/via/vt8237/ide.c
===================================================================
--- southbridge/via/vt8237/ide.c	(revision 0)
+++ southbridge/via/vt8237/ide.c	(revision 0)
@@ -0,0 +1,105 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * 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
+ */
+
+/* Based on other VIA SB code. */
+#include <types.h>
+#include <console.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <statictree.h>
+#include "vt8237.h"
+
+/**
+ * No native mode. Interrupts from unconnected HDDs might occur if
+ * IRQ14/15 is used for PCI. Therefore no native mode support.
+ */
+static void ide_init(struct device *dev)
+{
+	struct southbridge_via_vt8237_ide_config *sb =
+	    (struct southbridge_via_vt8237_ide_config *)dev->device_configuration;
+
+	u8 enables;
+	u32 cablesel;
+
+	printk(BIOS_INFO, "%s IDE interface %s\n", "Primary",
+		    sb->ide0_enable ? "enabled" : "disabled");
+	printk(BIOS_INFO, "%s IDE interface %s\n", "Secondary",
+		    sb->ide1_enable ? "enabled" : "disabled");
+	enables = pci_read_config8(dev, IDE_CS) & ~0x3;
+	enables |= (sb->ide0_enable << 1) | sb->ide1_enable;
+	pci_write_config8(dev, IDE_CS, enables);
+	enables = pci_read_config8(dev, IDE_CS);
+	printk(BIOS_DEBUG, "Enables in reg 0x40 read back as 0x%x\n", enables);
+
+	/* Enable only compatibility mode. */
+	enables = pci_read_config8(dev, IDE_CONF_II);
+	enables &= ~0xc0;
+	pci_write_config8(dev, IDE_CONF_II, enables);
+	enables = pci_read_config8(dev, IDE_CONF_II);
+	printk(BIOS_DEBUG, "Enables in reg 0x42 read back as 0x%x\n", enables);
+
+	/* Enable prefetch buffers. */
+	enables = pci_read_config8(dev, IDE_CONF_I);
+	enables |= 0xf0;
+	pci_write_config8(dev, IDE_CONF_I, enables);
+
+	/* Flush FIFOs at half. */
+	enables = pci_read_config8(dev, IDE_CONF_FIFO);
+	enables &= 0xf0;
+	enables |= (1 << 2) | (1 << 0);
+	pci_write_config8(dev, IDE_CONF_FIFO, enables);
+
+	/* PIO read prefetch counter, Bus Master IDE Status Reg. Read Retry. */
+	enables = pci_read_config8(dev, IDE_MISC_I);
+	enables &= 0xe2;
+	enables |= (1 << 4) | (1 << 3);
+	pci_write_config8(dev, IDE_MISC_I, enables);
+
+	/* Use memory read multiple, Memory-Write-and-Invalidate. */
+	enables = pci_read_config8(dev, IDE_MISC_II);
+	enables |= (1 << 2) | (1 << 3);
+	pci_write_config8(dev, IDE_MISC_II, enables);
+
+	/* Force interrupts to use compat mode. */
+	pci_write_config8(dev, PCI_INTERRUPT_PIN, 0x0);
+	pci_write_config8(dev, PCI_INTERRUPT_LINE, 0xff);
+
+	/* Cable guy... */
+	cablesel = pci_read_config32(dev, IDE_UDMA);
+	cablesel &= ~((1 << 28) | (1 << 20) | (1 << 12) | (1 << 4));
+	cablesel |= (sb->ide0_80pin_cable << 28) |
+		    (sb->ide0_80pin_cable << 20) |
+		    (sb->ide1_80pin_cable << 12) |
+		    (sb->ide1_80pin_cable << 4);
+	pci_write_config32(dev, IDE_UDMA, cablesel);
+}
+
+struct device_operations vt8237_ide = {
+	.id = {.type = DEVICE_ID_PCI,
+		{.pci = {.vendor = PCI_VENDOR_ID_VIA,
+				.device = PCI_DEVICE_ID_VIA_VT8237_PATA}}},
+	.constructor			= default_device_constructor,
+	.phase2_fixup			= vt8237_enable,
+	.phase3_scan			= 0,
+	//.phase4_enable_disable		= vt8237_enable,
+	//.phase4_read_resources		= pci_dev_read_resources,
+	//.phase4_set_resources		= pci_dev_set_resources,
+	//.phase5_enable_resources	= pci_dev_enable_resources,
+	.phase6_init			= ide_init,
+};
Index: southbridge/via/vt8237/vt8237.h
===================================================================
--- southbridge/via/vt8237/vt8237.h	(revision 961)
+++ southbridge/via/vt8237/vt8237.h	(working copy)
@@ -22,16 +22,6 @@
 
 #include <types.h>
 
-/* Static resources for the VT8237R southbridge */
-
-#define VT8237R_APIC_ID			0x2
-#define VT8237R_ACPI_IO_BASE		0x500
-/* 0x0 disabled, 0x2 reserved, 0xf = IRQ15 */
-#define VT8237R_ACPI_IRQ		0x9
-#define VT8237S_SPI_MEM_BASE		0xfed02000ULL
-#define VT8237R_HPET_ADDR		0xfed00000ULL
-#define VT8237R_APIC_BASE		0xfec00000ULL
-
 /* IDE */
 #define IDE_CS				0x40
 #define IDE_CONF_I			0x41
@@ -41,10 +31,12 @@
 #define IDE_MISC_II			0x45
 #define IDE_UDMA			0x50
 
+#define SATA_MISC_CTRL 0x45
+
 /* SMBus */
-#define VT8237R_POWER_WELL		0x94
-#define VT8237R_SMBUS_IO_BASE_REG	0xd0
-#define VT8237R_SMBUS_HOST_CONF		0xd2
+#define VT8237_POWER_WELL		0x94
+#define VT8237_SMBUS_IO_BASE_REG	0xd0
+#define VT8237_SMBUS_HOST_CONF		0xd2
 
 #define SMBHSTSTAT			0x0
 #define SMBSLVSTAT			0x1
@@ -86,5 +78,6 @@
 
 void enable_smbus(u16);
 u8 smbus_read_byte(u16, u8, u16);
+void vt8237_enable(struct device *);
 
 #endif
Index: southbridge/via/vt8237/stage1.c
===================================================================
--- southbridge/via/vt8237/stage1.c	(revision 961)
+++ southbridge/via/vt8237/stage1.c	(working copy)
@@ -170,14 +170,14 @@
 	/* 7 = SMBus Clock from RTC 32.768KHz
 	 * 5 = Internal PLL reset from susp
 	 */
-	pci_conf1_write_config8(dev, VT8237R_POWER_WELL, 0xa0);
+	pci_conf1_write_config8(dev, VT8237_POWER_WELL, 0xa0);
 
 	/* Enable SMBus. */
-	pci_conf1_write_config16(dev, VT8237R_SMBUS_IO_BASE_REG,
+	pci_conf1_write_config16(dev, VT8237_SMBUS_IO_BASE_REG,
 			   smbus_io_base | 0x1);
 
 	/* SMBus Host Configuration, enable. */
-	pci_conf1_write_config8(dev, VT8237R_SMBUS_HOST_CONF, 0x01);
+	pci_conf1_write_config8(dev, VT8237_SMBUS_HOST_CONF, 0x01);
 
 	/* Make it work for I/O. */
 	pci_conf1_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
Index: southbridge/via/vt8237/lpc.dts
===================================================================
--- southbridge/via/vt8237/lpc.dts	(revision 0)
+++ southbridge/via/vt8237/lpc.dts	(revision 0)
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Corey Osgood <corey.osgood@gmail.com>
+ *
+ * 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
+ */
+
+{
+	device_operations = "vt8237r_lpc";
+	enable_keyboard = "1";
+	acpi_io_base = "0x500";
+	acpi_irq = "0x9";
+	apic_id = "0x2";
+	apic_base = "0xfec00000ULL";	
+
+	/* These are unused by vt8237r, but necessary to use
+	 * the same driver for vt8237s */
+	spi_mem_base = "0";
+	hpet_addr = "0";
+};
+
+{
+	device_operations = "vt8237s_lpc";
+	enable_keyboard = "1";
+	acpi_io_base = "0x500";
+	acpi_irq = "0x9";
+	apic_id = "0x2";
+	apic_base = "0xfec00000ULL";	
+	spi_mem_base = "0xfed02000ULL";
+	hpet_addr = "0xfed00000ULL";
+};
Index: southbridge/via/vt8237/sata.c
===================================================================
--- southbridge/via/vt8237/sata.c	(revision 0)
+++ southbridge/via/vt8237/sata.c	(revision 0)
@@ -0,0 +1,123 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007, 2008 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * 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.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "vt8237.h"
+
+/* TODO: use phase2_fixup to disable SATA */
+static void sata_i_init(struct device *dev)
+{
+	u8 reg;
+
+	printk(BIOS_DEBUG, "Configuring VIA SATA controller\n");
+
+	/* Class IDE Disk */
+	reg = pci_read_config8(dev, SATA_MISC_CTRL);
+	reg &= 0x7f;		/* Sub Class Write Protect off */
+	pci_write_config8(dev, SATA_MISC_CTRL, reg);
+
+	/* Change the device class to SATA from RAID. */
+	pci_write_config8(dev, PCI_CLASS_DEVICE, 0x1);
+	reg |= 0x80;		/* Sub Class Write Protect on */
+	pci_write_config8(dev, SATA_MISC_CTRL, reg);
+}
+
+/* VT8237R is SATA, VT8237S is SATAII */
+static void sata_ii_init(struct device *dev)
+{
+	u8 reg;
+
+	sata_i_init(dev);
+
+	/*
+	 * Analog black magic, you may or may not need to adjust 0x60-0x6f,
+	 * depends on PCB.
+	 */
+
+	/*
+	 * Analog PHY - gen1
+	 * CDR bandwidth [6:5] = 3
+	 * Squelch Window Select [4:3] = 1
+	 * CDR Charge Pump [2:0] = 1
+	 */
+
+	/* TODO: Move to DTS */
+
+	pci_write_config8(dev, 0x64, 0x49);
+
+	/* Adjust driver current source value to 9. */
+	reg = pci_read_config8(dev, 0x65);
+	reg &= 0xf0;
+	reg |= 0x9;
+	pci_write_config8(dev, 0x65, reg);
+
+	/* Set all manual termination 50ohm bits [2:0] and enable [4]. */
+	reg = pci_read_config8(dev, 0x6a);
+	reg |= 0xf;
+	pci_write_config8(dev, 0x6a, reg);
+
+	/*
+	 * Analog PHY - gen2
+	 * CDR bandwidth [5:4] = 2
+	 * Pre / De-emphasis Level [7:6] controls bits [3:2], rest in 0x6e
+	 * CDR Charge Pump [2:0] = 1
+	 */
+
+	reg = pci_read_config8(dev, 0x6f);
+	reg &= 0x08;
+	reg |= 0x61;
+	pci_write_config8(dev, 0x6f, reg);
+
+	/* Check if staggered spinup is supported. */
+	reg = pci_read_config8(dev, 0x83);
+	if ((reg & 0x8) == 0) {
+		/* Start OOB sequence on both drives. */
+		reg |= 0x30;
+		pci_write_config8(dev, 0x83, reg);
+	}
+}
+
+struct device_operations vt8237r_sata = {
+	.id = {.type = DEVICE_ID_PCI,
+		{.pci = {.vendor = PCI_VENDOR_ID_VIA,
+				.device = PCI_DEVICE_ID_VIA_VT8237R_SATA}}},
+	.constructor			= default_device_constructor,
+	.phase3_scan			= 0,
+	//.phase4_enable_disable		= vt8237_enable,
+	//.phase4_read_resources		= pci_dev_read_resources,
+	//.phase4_set_resources		= pci_dev_set_resources,
+	//.phase5_enable_resources	= pci_dev_enable_resources,
+	.phase6_init			= sata_i_init,
+};
+
+struct device_operations vt8237s_sata = {
+	.id = {.type = DEVICE_ID_PCI,
+		{.pci = {.vendor = PCI_VENDOR_ID_VIA,
+				.device = PCI_DEVICE_ID_VIA_VT8237S_SATA}}},
+	.constructor			= default_device_constructor,
+	.phase2_fixup			= 0,
+	.phase3_scan			= 0,
+	//.phase4_enable_disable		= vt8237_enable,
+	//.phase4_read_resources		= pci_dev_read_resources,
+	//.phase4_set_resources		= pci_dev_set_resources,
+	//.phase5_enable_resources	= pci_dev_enable_resources,
+	.phase6_init			= sata_ii_init,
+};
Index: southbridge/via/vt8237/ide.dts
===================================================================
--- southbridge/via/vt8237/ide.dts	(revision 0)
+++ southbridge/via/vt8237/ide.dts	(revision 0)
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Corey Osgood <corey.osgood@gmail.com>
+ *
+ * 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
+ */
+
+{
+	device_operations = "vt8237_ide";
+	ide0_enable = "1";
+	ide1_enable = "1";
+	ide0_80pin_cable = "0";
+	ide1_80pin_cable = "0";
+};
Index: southbridge/via/vt8237/Makefile
===================================================================
--- southbridge/via/vt8237/Makefile	(revision 961)
+++ southbridge/via/vt8237/Makefile	(working copy)
@@ -20,6 +20,9 @@
 
 ifeq ($(CONFIG_SOUTHBRIDGE_VIA_VT8237),y)
 
-STAGE2_CHIPSET_SRC += 
+STAGE2_CHIPSET_SRC += $(src)/southbridge/via/vt8237/vt8237.c \
+			$(src)/southbridge/via/vt8237/lpc.c \
+			$(src)/southbridge/via/vt8237/ide.c \
+			$(src)/southbridge/via/vt8237/sata.c
 
 endif
Index: southbridge/via/vt8237/vt8237.c
===================================================================
--- southbridge/via/vt8237/vt8237.c	(revision 0)
+++ southbridge/via/vt8237/vt8237.c	(revision 0)
@@ -0,0 +1,84 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Corey Osgood <corey.osgood@gmail.com>
+ *
+ * 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 <types.h>
+#include <console.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <statictree.h>
+#include <config.h>
+#include "vt8237.h"
+
+/*
+ * Datasheet: http://www.via.com.tw/en/downloads/datasheets/chipsets/
+ *		VT8237R_SouthBridge_Revision2.06_Lead-Free.zip
+ */
+
+void vt8237_enable(struct device *dev)
+{
+	struct device *lpc_dev;
+	u16 sb_fn_ctrl;
+
+	const u8 func = dev->path.pci.devfn & 0x7;
+	const u8 device = dev->path.pci.devfn >> 3;
+	const int d16_index[6] = {12, 13, 10, 8, 9, 7};
+	
+
+	printk(BIOS_DEBUG, "Enabling/Disabling device 0x%x function 0x%x.\n",
+							device, func);
+
+	if(dev->id.pci.vendor != PCI_VENDOR_ID_VIA)
+		return;
+	
+	lpc_dev = dev_find_slot(0, PCI_BDF(0, 17, 0));
+	sb_fn_ctrl = pci_read_config8(lpc_dev, 0x50) << 8;
+	sb_fn_ctrl |= pci_read_config8(lpc_dev, 0x51);
+
+	if (device == 16)
+	{
+		/* If any port is enabled, the first port needs to be enabled */
+		if (dev->enabled)
+		{
+			sb_fn_ctrl &= ~(1 << d16_index[0]);
+			sb_fn_ctrl &= ~(1 << d16_index[func]);
+		}
+		else
+		{
+			sb_fn_ctrl |= (1 << d16_index[func]);
+		}
+	}
+	else if (device == 17)
+	{
+		if (func == 5)
+		{
+			sb_fn_ctrl &= ~(dev->enabled << 14);
+			sb_fn_ctrl |= (!dev->enabled << 14); 
+		}
+		else if (func == 6)
+		{
+			sb_fn_ctrl &= ~(dev->enabled << 15);
+			sb_fn_ctrl |= (!dev->enabled << 15);
+		}
+	}
+			
+	pci_write_config8(dev, 0x50, (sb_fn_ctrl >> 8) & 0xff);
+	pci_write_config8(dev, 0x51, sb_fn_ctrl & 0xff);
+
+	/* TODO: If SATA is disabled, move IDE to fn0 to conform PCI specs. */
+}
Index: include/device/pci_ids.h
===================================================================
--- include/device/pci_ids.h	(revision 961)
+++ include/device/pci_ids.h	(working copy)
@@ -272,7 +280,5 @@
 #define PCI_DEVICE_ID_VIA_VT8237R_SATA		0x3149
 #define PCI_DEVICE_ID_VIA_VT8237S_SATA		0x5372
 #define PCI_DEVICE_ID_VIA_VT8237_UHCI		0x3038
-#define PCI_DEVICE_ID_VIA_VT8237_VLINK		0x287e
 
-
 #endif /* DEVICE_PCI_IDS_H */

