summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEd Swierk <eswierk@arastra.com>2008-03-16 23:34:10 +0000
committerStefan Reinauer <stepan@openbios.org>2008-03-16 23:34:10 +0000
commitaaea11b749ccd481a37424c38625873c231f850d (patch)
treedee6e79b648a2916002d20b1f31af6bf32ad1524
parent62eee3ff4fc544ede21d72fcb5a1859b3f571dc8 (diff)
downloadcoreboot-aaea11b749ccd481a37424c38625873c231f850d.tar.xz
Here is an updated patch addressing most of Uwe's and Peter's
comments. Ripping out the ehci/uhci_init() code doesn't seem to have done any harm, and I got rid of a bunch of unused junk in i3100_smbus.h I left the *_set_subsystem() arguments unsigned, as that's how the function is declared in include/device/pci.h. Signed-off-by: Ed Swierk <eswierk@arastra.com> Acked-by: Stefan Reinauer <stepan@coresystems.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3157 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
-rw-r--r--src/southbridge/intel/i3100/Config.lb28
-rw-r--r--src/southbridge/intel/i3100/chip.h49
-rw-r--r--src/southbridge/intel/i3100/i3100.c69
-rw-r--r--src/southbridge/intel/i3100/i3100.h27
-rw-r--r--src/southbridge/intel/i3100/i3100_early_lpc.c32
-rw-r--r--src/southbridge/intel/i3100/i3100_early_smbus.c47
-rw-r--r--src/southbridge/intel/i3100/i3100_ehci.c62
-rw-r--r--src/southbridge/intel/i3100/i3100_lpc.c311
-rw-r--r--src/southbridge/intel/i3100/i3100_pci.c46
-rw-r--r--src/southbridge/intel/i3100/i3100_reset.c26
-rw-r--r--src/southbridge/intel/i3100/i3100_sata.c89
-rw-r--r--src/southbridge/intel/i3100/i3100_smbus.c74
-rw-r--r--src/southbridge/intel/i3100/i3100_smbus.h113
-rw-r--r--src/southbridge/intel/i3100/i3100_uhci.c62
14 files changed, 1035 insertions, 0 deletions
diff --git a/src/southbridge/intel/i3100/Config.lb b/src/southbridge/intel/i3100/Config.lb
new file mode 100644
index 0000000000..7b6b4aed31
--- /dev/null
+++ b/src/southbridge/intel/i3100/Config.lb
@@ -0,0 +1,28 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2008 Arastra, Inc.
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License version 2 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
+##
+
+config chip.h
+driver i3100.o
+driver i3100_uhci.o
+driver i3100_lpc.o
+driver i3100_sata.o
+driver i3100_ehci.o
+driver i3100_smbus.o
+driver i3100_pci.o
+object i3100_reset.o
diff --git a/src/southbridge/intel/i3100/chip.h b/src/southbridge/intel/i3100/chip.h
new file mode 100644
index 0000000000..f35e4a8b0e
--- /dev/null
+++ b/src/southbridge/intel/i3100/chip.h
@@ -0,0 +1,49 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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
+ *
+ */
+
+struct southbridge_intel_i3100_config
+{
+#define I3100_GPIO_USE_MASK 0x03
+#define I3100_GPIO_USE_DEFAULT 0x00
+#define I3100_GPIO_USE_AS_NATIVE 0x01
+#define I3100_GPIO_USE_AS_GPIO 0x02
+
+#define I3100_GPIO_SEL_MASK 0x0c
+#define I3100_GPIO_SEL_DEFAULT 0x00
+#define I3100_GPIO_SEL_OUTPUT 0x04
+#define I3100_GPIO_SEL_INPUT 0x08
+
+#define I3100_GPIO_LVL_MASK 0x30
+#define I3100_GPIO_LVL_DEFAULT 0x00
+#define I3100_GPIO_LVL_LOW 0x10
+#define I3100_GPIO_LVL_HIGH 0x20
+#define I3100_GPIO_LVL_BLINK 0x30
+
+#define I3100_GPIO_INV_MASK 0xc0
+#define I3100_GPIO_INV_DEFAULT 0x00
+#define I3100_GPIO_INV_OFF 0x40
+#define I3100_GPIO_INV_ON 0x80
+
+ /* GPIO use select */
+ u8 gpio[64];
+ u32 pirq_a_d;
+ u32 pirq_e_h;
+};
+extern struct chip_operations southbridge_intel_i3100_ops;
diff --git a/src/southbridge/intel/i3100/i3100.c b/src/southbridge/intel/i3100/i3100.c
new file mode 100644
index 0000000000..046bcaeb08
--- /dev/null
+++ b/src/southbridge/intel/i3100/i3100.c
@@ -0,0 +1,69 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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
+ *
+ */
+
+/* This code is based on src/southbridge/intel/esb6300/esb6300.c */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include "i3100.h"
+
+void i3100_enable(device_t dev)
+{
+ device_t lpc_dev;
+ u32 index = 0;
+ u16 reg_old, reg;
+
+ /* See if we are behind the i3100 PCI bridge */
+ lpc_dev = dev_find_slot(dev->bus->secondary, PCI_DEVFN(0x1f, 0));
+ if ((dev->path.u.pci.devfn & 0xf8) == 0xf8) {
+ index = dev->path.u.pci.devfn & 7;
+ }
+ else if ((dev->path.u.pci.devfn & 0xf8) == 0xe8) {
+ index = (dev->path.u.pci.devfn & 7) + 8;
+ }
+ if ((!lpc_dev) || (index >= 16) || ((1 << index) & 0x3091)) {
+ return;
+ }
+ if ((lpc_dev->vendor != PCI_VENDOR_ID_INTEL) ||
+ (lpc_dev->device != PCI_DEVICE_ID_INTEL_3100_LPC)) {
+ u32 id;
+ id = pci_read_config32(lpc_dev, PCI_VENDOR_ID);
+ if (id != (PCI_VENDOR_ID_INTEL |
+ (PCI_DEVICE_ID_INTEL_3100_LPC << 16))) {
+ return;
+ }
+ }
+
+ reg = reg_old = pci_read_config16(lpc_dev, 0xf2);
+ reg &= ~(1 << index);
+ if (!dev->enabled) {
+ reg |= (1 << index);
+ }
+ if (reg != reg_old) {
+ pci_write_config16(lpc_dev, 0xf2, reg);
+ }
+}
+
+struct chip_operations southbridge_intel_i3100_ops = {
+ CHIP_NAME("Intel 3100 Southbridge")
+ .enable_dev = i3100_enable,
+};
diff --git a/src/southbridge/intel/i3100/i3100.h b/src/southbridge/intel/i3100/i3100.h
new file mode 100644
index 0000000000..18c8b33f1a
--- /dev/null
+++ b/src/southbridge/intel/i3100/i3100.h
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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
+ *
+ */
+
+#ifndef SOUTHBRIDGE_INTEL_I3100_I3100_H
+#define SOUTHBRIDGE_INTEL_I3100_I3100_H
+#include "chip.h"
+
+void i3100_enable(device_t dev);
+
+#endif
diff --git a/src/southbridge/intel/i3100/i3100_early_lpc.c b/src/southbridge/intel/i3100/i3100_early_lpc.c
new file mode 100644
index 0000000000..2fdb3dfa09
--- /dev/null
+++ b/src/southbridge/intel/i3100/i3100_early_lpc.c
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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
+ *
+ */
+
+static void i3100_enable_superio(void)
+{
+ device_t dev;
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_3100_LPC), 0);
+ if (dev == PCI_DEV_INVALID) {
+ die("LPC bridge not found\r\n");
+ }
+
+ /* Enable decoding of I/O locations for SuperIO devices */
+ pci_write_config16(dev, 0x82, 0x340f);
+}
diff --git a/src/southbridge/intel/i3100/i3100_early_smbus.c b/src/southbridge/intel/i3100/i3100_early_smbus.c
new file mode 100644
index 0000000000..3e31864c22
--- /dev/null
+++ b/src/southbridge/intel/i3100/i3100_early_smbus.c
@@ -0,0 +1,47 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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 "i3100_smbus.h"
+
+#define SMBUS_IO_BASE 0x0f00
+
+static void enable_smbus(void)
+{
+ device_t dev;
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_3100_SMB), 0);
+ if (dev == PCI_DEV_INVALID) {
+ die("SMBus controller not found\r\n");
+ }
+ print_spew("SMBus controller enabled\r\n");
+ pci_write_config32(dev, 0x20, SMBUS_IO_BASE | 1);
+ pci_write_config8(dev, 0x40, 1);
+ pci_write_config8(dev, 0x4, 1);
+ /* SMBALERT_DIS */
+ outb(4, SMBUS_IO_BASE + SMBSLVCMD);
+
+ /* Disable interrupt generation */
+ outb(0, SMBUS_IO_BASE + SMBHSTCTL);
+}
+
+static int smbus_read_byte(u32 device, u32 address)
+{
+ return do_smbus_read_byte(SMBUS_IO_BASE, device, address);
+}
diff --git a/src/southbridge/intel/i3100/i3100_ehci.c b/src/southbridge/intel/i3100/i3100_ehci.c
new file mode 100644
index 0000000000..fc36791dc6
--- /dev/null
+++ b/src/southbridge/intel/i3100/i3100_ehci.c
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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 <device/pci_ops.h>
+#include "i3100.h"
+
+static void ehci_init(struct device *dev)
+{
+}
+
+static void ehci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ u8 access_cntl;
+ access_cntl = pci_read_config8(dev, 0x80);
+ /* Enable writes to protected registers */
+ pci_write_config8(dev, 0x80, access_cntl | 1);
+ /* Write the subsystem vendor and device id */
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+ /* Restore protection */
+ pci_write_config8(dev, 0x80, access_cntl);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = &ehci_set_subsystem,
+};
+static struct device_operations ehci_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = ehci_init,
+ .scan_bus = 0,
+ .enable = i3100_enable,
+ .ops_pci = &lops_pci,
+};
+
+static struct pci_driver ehci_driver __pci_driver = {
+ .ops = &ehci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_EHCI,
+};
diff --git a/src/southbridge/intel/i3100/i3100_lpc.c b/src/southbridge/intel/i3100/i3100_lpc.c
new file mode 100644
index 0000000000..8914ed73de
--- /dev/null
+++ b/src/southbridge/intel/i3100/i3100_lpc.c
@@ -0,0 +1,311 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Linux Networx
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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
+ *
+ */
+
+/* This code is based on src/southbridge/intel/esb6300/esb6300_lpc.c */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/mc146818rtc.h>
+#include <pc80/isa-dma.h>
+#include <arch/io.h>
+#include "i3100.h"
+
+#define ACPI_BAR 0x40
+#define GPIO_BAR 0x48
+#define RCBA 0xf0
+
+#define NMI_OFF 0
+#define MAINBOARD_POWER_OFF 0
+#define MAINBOARD_POWER_ON 1
+
+#ifndef MAINBOARD_POWER_ON_AFTER_FAIL
+#define MAINBOARD_POWER_ON_AFTER_FAIL MAINBOARD_POWER_ON
+#endif
+
+#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 void setup_ioapic(device_t dev)
+{
+ int i;
+ u32 value_low, value_high;
+ u32 ioapic_base = 0xfec00000;
+ volatile u32 *l;
+ u32 interrupts;
+ struct resource *res;
+
+ /* Enable IO APIC */
+ res = find_resource(dev, RCBA);
+ if (!res) {
+ return;
+ }
+ *((u8 *)(res->base + 0x31ff)) |= (1 << 0);
+
+ l = (u32 *) ioapic_base;
+
+ l[0] = 0x01;
+ interrupts = (l[04] >> 16) & 0xff;
+ for (i = 0; i < interrupts; i++) {
+ l[0] = (i * 2) + 0x10;
+ l[4] = DISABLED;
+ value_low = l[4];
+ l[0] = (i * 2) + 0x11;
+ l[4] = NONE; /* Should this be an address? */
+ value_high = l[4];
+ if (value_low == 0xffffffff) {
+ printk_warning("%d IO APIC not responding.\n",
+ dev_path(dev));
+ return;
+ }
+ }
+
+ /* Put the APIC in virtual wire mode */
+ l[0] = 0x10;
+ l[4] = ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT;
+}
+
+#define SERIRQ_CNTL 0x64
+static void i3100_enable_serial_irqs(device_t dev)
+{
+ /* set packet length and toggle silent mode bit */
+ pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(1 << 6)|((21 - 17) << 2)|(0 << 0));
+ pci_write_config8(dev, SERIRQ_CNTL, (1 << 7)|(0 << 6)|((21 - 17) << 2)|(0 << 0));
+}
+
+typedef struct southbridge_intel_i3100_config config_t;
+
+static void set_i3100_gpio_use_sel(
+ device_t dev, struct resource *res, config_t *config)
+{
+ u32 gpio_use_sel, gpio_use_sel2;
+
+ gpio_use_sel = 0x1b0ce7c3;
+ gpio_use_sel2 = 0x00000107;
+ outl(gpio_use_sel, res->base + 0x00);
+ outl(gpio_use_sel2, res->base + 0x30);
+}
+
+static void set_i3100_gpio_direction(
+ device_t dev, struct resource *res, config_t *config)
+{
+ u32 gpio_io_sel, gpio_io_sel2;
+
+ gpio_io_sel = 0xed00ffff;
+ gpio_io_sel2 = 0x00000307;
+ outl(gpio_io_sel, res->base + 0x04);
+ outl(gpio_io_sel2, res->base + 0x34);
+}
+
+static void set_i3100_gpio_level(
+ device_t dev, struct resource *res, config_t *config)
+{
+ u32 gpio_lvl, gpio_lvl2;
+ u32 gpio_blink;
+
+ gpio_lvl = 0x00030000;
+ gpio_blink = 0x00000000;
+ gpio_lvl2 = 0x00000300;
+ outl(gpio_lvl, res->base + 0x0c);
+ outl(gpio_blink, res->base + 0x18);
+ outl(gpio_lvl2, res->base + 0x38);
+}
+
+static void set_i3100_gpio_inv(
+ device_t dev, struct resource *res, config_t *config)
+{
+ u32 gpio_inv;
+
+ gpio_inv = 0x00006000;
+ outl(gpio_inv, res->base + 0x2c);
+}
+
+static void i3100_pirq_init(device_t dev)
+{
+ config_t *config;
+
+ /* Get the chip configuration */
+ config = dev->chip_info;
+
+ if(config->pirq_a_d) {
+ pci_write_config32(dev, 0x60, config->pirq_a_d);
+ }
+ if(config->pirq_e_h) {
+ pci_write_config32(dev, 0x68, config->pirq_e_h);
+ }
+}
+
+
+static void i3100_gpio_init(device_t dev)
+{
+ struct resource *res;
+ config_t *config;
+
+ /* Skip if I don't have any configuration */
+ if (!dev->chip_info) {
+ return;
+ }
+ /* The programmer is responsible for ensuring
+ * a valid gpio configuration.
+ */
+
+ /* Get the chip configuration */
+ config = dev->chip_info;
+ /* Find the GPIO bar */
+ res = find_resource(dev, GPIO_BAR);
+ if (!res) {
+ return;
+ }
+
+ /* Set the use selects */
+ set_i3100_gpio_use_sel(dev, res, config);
+
+ /* Set the IO direction */
+ set_i3100_gpio_direction(dev, res, config);
+
+ /* Setup the input inverters */
+ set_i3100_gpio_inv(dev, res, config);
+
+ /* Set the value on the GPIO output pins */
+ set_i3100_gpio_level(dev, res, config);
+
+}
+
+
+static void lpc_init(struct device *dev)
+{
+ u8 byte;
+ int pwr_on = MAINBOARD_POWER_ON_AFTER_FAIL;
+
+ setup_ioapic(dev);
+
+ /* Decode 0xffc00000 - 0xffffffff to fwh idsel 0 */
+ pci_write_config32(dev, 0xd0, 0x00000000);
+
+ i3100_enable_serial_irqs(dev);
+
+ get_option(&pwr_on, "power_on_after_fail");
+ byte = pci_read_config8(dev, 0xa4);
+ byte &= 0xfe;
+ if (!pwr_on) {
+ byte |= 1;
+ }
+ pci_write_config8(dev, 0xa4, byte);
+ printk_info("set power %s after power fail\n", pwr_on ? "on" : "off");
+
+ /* Set up the PIRQ */
+ i3100_pirq_init(dev);
+
+ /* Set the state of the gpio lines */
+ i3100_gpio_init(dev);
+
+ /* Initialize the real time clock */
+ rtc_init(0);
+
+ /* Initialize isa dma */
+ isa_dma_init();
+}
+
+static void i3100_lpc_read_resources(device_t dev)
+{
+ struct resource *res;
+
+ /* Get the normal pci resources of this device */
+ pci_dev_read_resources(dev);
+
+ /* Add the ACPI BAR */
+ res = pci_get_resource(dev, ACPI_BAR);
+
+ /* Add the GPIO BAR */
+ res = pci_get_resource(dev, GPIO_BAR);
+
+ /* Add an extra subtractive resource for both memory and I/O */
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+
+ res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+
+ /* Add resource for RCBA */
+ res = new_resource(dev, RCBA);
+ res->size = 0x4000;
+ res->limit = 0xffffc000;
+ res->align = 14;
+ res->gran = 14;
+ res->flags = IORESOURCE_MEM;
+}
+
+static void i3100_lpc_enable_resources(device_t dev)
+{
+ u8 acpi_cntl, gpio_cntl;
+
+ /* Enable the normal pci resources */
+ pci_dev_enable_resources(dev);
+
+ /* Enable the ACPI bar */
+ acpi_cntl = pci_read_config8(dev, 0x44);
+ acpi_cntl |= (1 << 4);
+ pci_write_config8(dev, 0x44, acpi_cntl);
+
+ /* Enable the GPIO bar */
+ gpio_cntl = pci_read_config8(dev, 0x4c);
+ gpio_cntl |= (1 << 4);
+ pci_write_config8(dev, 0x4c, gpio_cntl);
+
+ /* Enable the RCBA */
+ pci_write_config32(dev, RCBA, pci_read_config32(dev, RCBA) | (1 << 0));
+
+ enable_childrens_resources(dev);
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = 0,
+};
+
+static struct device_operations lpc_ops = {
+ .read_resources = i3100_lpc_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = i3100_lpc_enable_resources,
+ .init = lpc_init,
+ .scan_bus = scan_static_bus,
+ .enable = i3100_enable,
+ .ops_pci = &lops_pci,
+};
+
+static struct pci_driver lpc_driver __pci_driver = {
+ .ops = &lpc_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_LPC,
+};
diff --git a/src/southbridge/intel/i3100/i3100_pci.c b/src/southbridge/intel/i3100/i3100_pci.c
new file mode 100644
index 0000000000..991d1d8ed0
--- /dev/null
+++ b/src/southbridge/intel/i3100/i3100_pci.c
@@ -0,0 +1,46 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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 <device/pci_ops.h>
+#include "i3100.h"
+
+static void pci_init(struct device *dev)
+{
+}
+
+static struct device_operations pci_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .init = pci_init,
+ .scan_bus = pci_scan_bridge,
+ .ops_pci = 0,
+};
+
+static struct pci_driver pci_driver __pci_driver = {
+ .ops = &pci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_PCI,
+};
+
diff --git a/src/southbridge/intel/i3100/i3100_reset.c b/src/southbridge/intel/i3100/i3100_reset.c
new file mode 100644
index 0000000000..3ac52decb6
--- /dev/null
+++ b/src/southbridge/intel/i3100/i3100_reset.c
@@ -0,0 +1,26 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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 <arch/io.h>
+
+void hard_reset(void)
+{
+ outb(0x06, 0xcf9);
+}
diff --git a/src/southbridge/intel/i3100/i3100_sata.c b/src/southbridge/intel/i3100/i3100_sata.c
new file mode 100644
index 0000000000..43fea3942f
--- /dev/null
+++ b/src/southbridge/intel/i3100/i3100_sata.c
@@ -0,0 +1,89 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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
+ *
+ */
+
+/* This code is based on src/southbridge/intel/esb6300/esb6300_sata.c */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include "i3100.h"
+
+static void sata_init(struct device *dev)
+{
+ /* Enable SATA devices */
+
+ printk_debug("SATA init\n");
+ /* SATA configuration */
+ pci_write_config8(dev, 0x04, 0x07);
+ pci_write_config8(dev, 0x09, 0x8f);
+
+ /* Set timings */
+ pci_write_config16(dev, 0x40, 0x0a307);
+ pci_write_config16(dev, 0x42, 0x0a307);
+
+ /* Sync DMA */
+ pci_write_config16(dev, 0x48, 0x000f);
+ pci_write_config16(dev, 0x4a, 0x1111);
+
+ /* Fast ATA */
+ pci_write_config16(dev, 0x54, 0x1000);
+
+ /* Select IDE mode */
+ pci_write_config8(dev, 0x90, 0x00);
+
+ /* Enable ports 0-3 */
+ pci_write_config8(dev, 0x92, 0x0f);
+
+ printk_debug("SATA Enabled\n");
+}
+
+static void sata_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = sata_set_subsystem,
+};
+
+static struct device_operations sata_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = sata_init,
+ .scan_bus = 0,
+ .ops_pci = &lops_pci,
+};
+
+static struct pci_driver sata_driver __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_SATA,
+};
+
+static struct pci_driver sata_driver_nr __pci_driver = {
+ .ops = &sata_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_SATA_R,
+};
+
diff --git a/src/southbridge/intel/i3100/i3100_smbus.c b/src/southbridge/intel/i3100/i3100_smbus.c
new file mode 100644
index 0000000000..552fcbff96
--- /dev/null
+++ b/src/southbridge/intel/i3100/i3100_smbus.c
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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 <device/device.h>
+#include <device/path.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/smbus.h>
+#include <arch/io.h>
+#include "i3100.h"
+#include "i3100_smbus.h"
+
+static int lsmbus_read_byte(device_t dev, u8 address)
+{
+ u16 device;
+ struct resource *res;
+ struct bus *pbus;
+
+ device = dev->path.u.i2c.device;
+ pbus = get_pbus_smbus(dev);
+ res = find_resource(pbus->dev, 0x20);
+
+ return do_smbus_read_byte(res->base, device, address);
+}
+
+static struct smbus_bus_operations lops_smbus_bus = {
+ .read_byte = lsmbus_read_byte,
+};
+
+static void smbus_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = &smbus_set_subsystem,
+};
+
+static struct device_operations smbus_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = 0,
+ .scan_bus = scan_static_bus,
+ .enable = i3100_enable,
+ .ops_pci = &lops_pci,
+ .ops_smbus_bus = &lops_smbus_bus,
+};
+
+static struct pci_driver smbus_driver __pci_driver = {
+ .ops = &smbus_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_SMB,
+};
+
diff --git a/src/southbridge/intel/i3100/i3100_smbus.h b/src/southbridge/intel/i3100/i3100_smbus.h
new file mode 100644
index 0000000000..b285fbaa93
--- /dev/null
+++ b/src/southbridge/intel/i3100/i3100_smbus.h
@@ -0,0 +1,113 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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
+ *
+ */
+
+/* This code is based on src/southbridge/intel/esb6300/esb6300_smbus.h */
+
+#include <device/smbus_def.h>
+
+#define SMBHSTSTAT 0x0
+#define SMBHSTCTL 0x2
+#define SMBHSTCMD 0x3
+#define SMBXMITADD 0x4
+#define SMBHSTDAT0 0x5
+#define SMBHSTDAT1 0x6
+#define SMBBLKDAT 0x7
+#define SMBTRNSADD 0x9
+#define SMBSLVDATA 0xa
+#define SMLINK_PIN_CTL 0xe
+#define SMBUS_PIN_CTL 0xf
+#define SMBSLVCMD 0x11
+
+#define SMBUS_TIMEOUT (100*1000*10)
+
+static void smbus_delay(void)
+{
+ outb(0x80, 0x80);
+}
+
+static int smbus_wait_until_ready(u32 smbus_io_base)
+{
+ u32 loops = SMBUS_TIMEOUT;
+ u8 byte;
+ do {
+ smbus_delay();
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_io_base + SMBHSTSTAT);
+ } while (byte & 1);
+ return loops ? 0 : -1;
+}
+
+static int smbus_wait_until_done(u32 smbus_io_base)
+{
+ u32 loops = SMBUS_TIMEOUT;
+ u8 byte;
+ do {
+ smbus_delay();
+ if (--loops == 0)
+ break;
+ byte = inb(smbus_io_base + SMBHSTSTAT);
+ } while ((byte & 1) || (byte & ~((1 << 6)|(1 << 0))) == 0);
+ return loops ? 0 : -1;
+}
+
+static int do_smbus_read_byte(u32 smbus_io_base, u16 device, u8 address)
+{
+ u8 global_status_register;
+ u8 byte;
+
+ if (smbus_wait_until_ready(smbus_io_base) < 0) {
+ return SMBUS_WAIT_UNTIL_READY_TIMEOUT;
+ }
+ /* setup transaction */
+ /* disable interrupts */
+ outb(inb(smbus_io_base + SMBHSTCTL) & (~1), smbus_io_base + SMBHSTCTL);
+ /* set the device I'm talking too */
+ outb(((device & 0x7f) << 1) | 1, smbus_io_base + SMBXMITADD);
+ /* set the command/address... */
+ outb(address & 0xFF, smbus_io_base + SMBHSTCMD);
+ /* set up for a byte data read */
+ outb((inb(smbus_io_base + SMBHSTCTL) & 0xE3) | (0x2 << 2), smbus_io_base + SMBHSTCTL);
+ /* clear any lingering errors, so the transaction will run */
+ outb(inb(smbus_io_base + SMBHSTSTAT), smbus_io_base + SMBHSTSTAT);
+
+ /* clear the data byte...*/
+ outb(0, smbus_io_base + SMBHSTDAT0);
+
+ /* start the command */
+ outb((inb(smbus_io_base + SMBHSTCTL) | 0x40), smbus_io_base + SMBHSTCTL);
+
+ /* poll for transaction completion */
+ if (smbus_wait_until_done(smbus_io_base) < 0) {
+ return SMBUS_WAIT_UNTIL_DONE_TIMEOUT;
+ }
+
+ global_status_register = inb(smbus_io_base + SMBHSTSTAT);
+
+ /* Ignore the In Use Status... */
+ global_status_register &= ~(3 << 5);
+
+ /* read results of transaction */
+ byte = inb(smbus_io_base + SMBHSTDAT0);
+ if (global_status_register != (1 << 1)) {
+ return SMBUS_ERROR;
+ }
+ return byte;
+}
diff --git a/src/southbridge/intel/i3100/i3100_uhci.c b/src/southbridge/intel/i3100/i3100_uhci.c
new file mode 100644
index 0000000000..642d7e8448
--- /dev/null
+++ b/src/southbridge/intel/i3100/i3100_uhci.c
@@ -0,0 +1,62 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2008 Arastra, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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 <device/pci_ops.h>
+#include "i3100.h"
+
+static void uhci_init(struct device *dev)
+{
+}
+
+static void uhci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
+{
+ pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ ((device & 0xffff) << 16) | (vendor & 0xffff));
+}
+
+static struct pci_operations lops_pci = {
+ .set_subsystem = &uhci_set_subsystem,
+};
+
+static struct device_operations uhci_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = uhci_init,
+ .scan_bus = 0,
+ .enable = i3100_enable,
+ .ops_pci = &lops_pci,
+};
+
+static struct pci_driver uhci_driver __pci_driver = {
+ .ops = &uhci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_USB,
+};
+
+static struct pci_driver usb2_driver __pci_driver = {
+ .ops = &uhci_ops,
+ .vendor = PCI_VENDOR_ID_INTEL,
+ .device = PCI_DEVICE_ID_INTEL_3100_USB2,
+};