summaryrefslogtreecommitdiff
path: root/src/northbridge
diff options
context:
space:
mode:
Diffstat (limited to 'src/northbridge')
-rw-r--r--src/northbridge/intel/i855gme/Config.lb24
-rw-r--r--src/northbridge/intel/i855gme/chip.h25
-rw-r--r--src/northbridge/intel/i855gme/debug.c197
-rw-r--r--src/northbridge/intel/i855gme/northbridge.c198
-rw-r--r--src/northbridge/intel/i855gme/raminit.c297
-rw-r--r--src/northbridge/intel/i855gme/raminit.h32
-rw-r--r--src/northbridge/intel/i855gme/reset_test.c39
7 files changed, 812 insertions, 0 deletions
diff --git a/src/northbridge/intel/i855gme/Config.lb b/src/northbridge/intel/i855gme/Config.lb
new file mode 100644
index 0000000000..5a7cd14600
--- /dev/null
+++ b/src/northbridge/intel/i855gme/Config.lb
@@ -0,0 +1,24 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2006 Jon Dufresne <jon.dufresne@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
+ */
+
+config chip.h
+object northbridge.o
+#driver misc_control.o
+
diff --git a/src/northbridge/intel/i855gme/chip.h b/src/northbridge/intel/i855gme/chip.h
new file mode 100644
index 0000000000..3e1514a59c
--- /dev/null
+++ b/src/northbridge/intel/i855gme/chip.h
@@ -0,0 +1,25 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2006 Jon Dufresne <jon.dufresne@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
+ */
+
+struct northbridge_intel_i855gme_config
+{
+};
+
+extern struct chip_operations northbridge_intel_i855gme_ops;
diff --git a/src/northbridge/intel/i855gme/debug.c b/src/northbridge/intel/i855gme/debug.c
new file mode 100644
index 0000000000..46d629b01e
--- /dev/null
+++ b/src/northbridge/intel/i855gme/debug.c
@@ -0,0 +1,197 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2003 Ronald G. Minnich
+ *
+ * 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
+ */
+
+/*
+ * generic K8 debug code, used by mainboard specific auto.c
+ *
+ */
+#if 1
+/*
+static void print_debug_pci_dev(unsigned dev)
+{
+ print_debug("PCI: ");
+ print_debug_hex8((dev >> 16) & 0xff);
+ print_debug_char(':');
+ print_debug_hex8((dev >> 11) & 0x1f);
+ print_debug_char('.');
+ print_debug_hex8((dev >> 8) & 7);
+}
+*/
+
+
+static void print_debug_pci_dev(unsigned dev)
+{
+ print_debug("PCI: ");
+ print_debug_hex8((dev >> 20) & 0xff);
+ print_debug_char(':');
+ print_debug_hex8((dev >> 15) & 0x1f);
+ print_debug_char('.');
+ print_debug_hex8((dev >> 12) & 0x07);
+}
+
+static void print_pci_devices(void)
+{
+ device_t dev;
+ for(dev = PCI_DEV(0, 0, 0);
+ dev <= PCI_DEV(0, 0x1f, 0x7);
+ dev += PCI_DEV(0,0,1)) {
+ uint32_t id;
+ id = pci_read_config32(dev, PCI_VENDOR_ID);
+ if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+ (((id >> 16) & 0xffff) == 0xffff) ||
+ (((id >> 16) & 0xffff) == 0x0000)) {
+ continue;
+ }
+ print_debug_pci_dev(dev);
+ print_debug("\r\n");
+ }
+}
+
+static void dump_pci_device(unsigned dev)
+{
+ int i;
+ print_debug_pci_dev(dev);
+ print_debug("\r\n");
+
+ for(i = 0; i <= 255; i++) {
+ unsigned char val;
+ if ((i & 0x0f) == 0) {
+ print_debug_hex8(i);
+ print_debug_char(':');
+ }
+ val = pci_read_config8(dev, i);
+ print_debug_char(' ');
+ print_debug_hex8(val);
+ if ((i & 0x0f) == 0x0f) {
+ print_debug("\r\n");
+ }
+ }
+}
+
+static void dump_pci_devices(void)
+{
+ device_t dev;
+ for(dev = PCI_DEV(0, 0, 0);
+ dev <= PCI_DEV(0, 0x1f, 0x7);
+ dev += PCI_DEV(0,0,1)) {
+ uint32_t id;
+ id = pci_read_config32(dev, PCI_VENDOR_ID);
+ if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
+ (((id >> 16) & 0xffff) == 0xffff) ||
+ (((id >> 16) & 0xffff) == 0x0000)) {
+ continue;
+ }
+ dump_pci_device(dev);
+ }
+}
+
+static void dump_spd_registers(const struct mem_controller *ctrl)
+{
+ int i;
+ print_debug("\r\n");
+ for(i = 0; i < 2; i++) {
+ unsigned device;
+ device = ctrl->channel0[i];
+ if (device) {
+ int j;
+ print_debug("dimm: ");
+ print_debug_hex8(i);
+ print_debug(".0: ");
+ print_debug_hex8(device);
+ for(j = 0; j < 256; j++) {
+ int status;
+ unsigned char byte;
+ if ((j & 0xf) == 0) {
+ print_debug("\r\n");
+ print_debug_hex8(j);
+ print_debug(": ");
+ }
+ status = smbus_read_byte(device, j);
+ if (status < 0) {
+ print_debug("bad device\r\n");
+ break;
+ }
+ byte = status & 0xff;
+ print_debug_hex8(byte);
+ print_debug_char(' ');
+ }
+ print_debug("\r\n");
+ }
+#if 0
+ device = ctrl->channel1[i];
+ if (device) {
+ int j;
+ print_debug("dimm: ");
+ print_debug_hex8(i);
+ print_debug(".1: ");
+ print_debug_hex8(device);
+ for(j = 0; j < 256; j++) {
+ int status;
+ unsigned char byte;
+ if ((j & 0xf) == 0) {
+ print_debug("\r\n");
+ print_debug_hex8(j);
+ print_debug(": ");
+ }
+ status = smbus_read_byte(device, j);
+ if (status < 0) {
+ print_debug("bad device\r\n");
+ break;
+ }
+ byte = status & 0xff;
+ print_debug_hex8(byte);
+ print_debug_char(' ');
+ }
+ print_debug("\r\n");
+ }
+#endif
+ }
+}
+static void dump_smbus_registers(void)
+{
+ int i;
+ print_debug("\r\n");
+ for(i = 1; i < 0x80; i++) {
+ unsigned device;
+ device = i;
+ int j;
+ print_debug("smbus: ");
+ print_debug_hex8(device);
+ for(j = 0; j < 256; j++) {
+ int status;
+ unsigned char byte;
+ if ((j & 0xf) == 0) {
+ print_debug("\r\n");
+ print_debug_hex8(j);
+ print_debug(": ");
+ }
+ status = smbus_read_byte(device, j);
+ if (status < 0) {
+ print_debug("bad device\r\n");
+ break;
+ }
+ byte = status & 0xff;
+ print_debug_hex8(byte);
+ print_debug_char(' ');
+ }
+ print_debug("\r\n");
+ }
+}
+#endif
diff --git a/src/northbridge/intel/i855gme/northbridge.c b/src/northbridge/intel/i855gme/northbridge.c
new file mode 100644
index 0000000000..e5fecf16ee
--- /dev/null
+++ b/src/northbridge/intel/i855gme/northbridge.c
@@ -0,0 +1,198 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2003 Ronald G. Minnich
+ * Copyright (C) 2003-2004 Eric W. Biederman
+ * Copyright (C) 2006 Jon Dufresne <jon.dufresne@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
+ */
+
+#include <console/console.h>
+#include <arch/io.h>
+#include <stdint.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <stdlib.h>
+#include <string.h>
+#include <bitops.h>
+#include <cpu/x86/cache.h>
+#include "chip.h"
+
+#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM)
+
+static void pci_domain_read_resources(device_t dev)
+{
+ struct resource *resource;
+ unsigned reg;
+
+ /* Initialize the system wide io space constraints */
+ resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
+ resource->limit = 0xffffUL;
+ resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+
+ /* Initialize the system wide memory resources constraints */
+ resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
+ resource->limit = 0xffffffffULL;
+ resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+}
+
+static void ram_resource(device_t dev, unsigned long index,
+ unsigned long basek, unsigned long sizek)
+{
+ struct resource *resource;
+
+ if (!sizek) {
+ return;
+ }
+ resource = new_resource(dev, index);
+ resource->base = ((resource_t)basek) << 10;
+ resource->size = ((resource_t)sizek) << 10;
+ resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
+ IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
+}
+
+static void tolm_test(void *gp, struct device *dev, struct resource *new)
+{
+ struct resource **best_p = gp;
+ struct resource *best;
+ best = *best_p;
+ if (!best || (best->base > new->base)) {
+ best = new;
+ }
+ *best_p = best;
+}
+
+static uint32_t find_pci_tolm(struct bus *bus)
+{
+ struct resource *min;
+ uint32_t tolm;
+ min = 0;
+ search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min);
+ tolm = 0xffffffffUL;
+ if (min && tolm > min->base) {
+ tolm = min->base;
+ }
+ return tolm;
+}
+
+static void pci_domain_set_resources(device_t dev)
+{
+ device_t mc_dev;
+ uint32_t pci_tolm;
+
+ printk_debug("Entered with dev vid = %x\n", dev->vendor);
+ printk_debug("Entered with dev did = %x\n", dev->device);
+
+ pci_tolm = find_pci_tolm(&dev->link[0]);
+ mc_dev = dev->link[0].children->sibling;
+ printk_debug("MC dev vendor = %x\n", mc_dev->vendor);
+ printk_debug("MC dev device = %x\n", mc_dev->device);
+
+ if (mc_dev) {
+ /* Figure out which areas are/should be occupied by RAM.
+ * This is all computed in kilobytes and converted to/from
+ * the memory controller right at the edges.
+ * Having different variables in different units is
+ * too confusing to get right. Kilobytes are good up to
+ * 4 Terabytes of RAM...
+ */
+ uint16_t tolm_r, vga_mem;
+ unsigned long tomk, tolmk;
+ unsigned long remapbasek, remaplimitk;
+ int idx;
+
+ /* Get the value of the highest DRB. This tells the end of
+ * the physical memory. The units are ticks of 32MB
+ * i.e. 1 means 32MB.
+ */
+ tomk = (unsigned long)pci_read_config8(mc_dev, 0x43);
+ tomk = tomk * 32 * 1024;
+ /* add vga_mem detection */
+ tomk = tomk - 16 * 1024;
+ /* Compute the top of Low memory */
+ tolmk = pci_tolm >> 10;
+ if (tolmk >= tomk) {
+ /* The PCI hole does not overlap memory
+ */
+ tolmk = tomk;
+ }
+ /* Write the ram configuration registers,
+ * preserving the reserved bits.
+ */
+
+ /* Report the memory regions */
+ printk_debug("tomk = %d\n", tomk);
+ printk_debug("tolmk = %d\n", tolmk);
+
+ idx = 10;
+ /* avoid pam region */
+ ram_resource(dev, idx++, 0, 640);
+ /* ram_resource(dev, idx++, 1024, tolmk - 1024); */
+ ram_resource(dev, idx++, 768, tolmk - 768);
+
+ }
+ assign_resources(&dev->link[0]);
+}
+
+static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
+{
+ max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max);
+ return max;
+}
+
+static struct device_operations pci_domain_ops = {
+ .read_resources = pci_domain_read_resources,
+ .set_resources = pci_domain_set_resources,
+ .enable_resources = enable_childrens_resources,
+ .init = 0,
+ .scan_bus = pci_domain_scan_bus,
+};
+
+static void cpu_bus_init(device_t dev)
+{
+ initialize_cpus(&dev->link[0]);
+}
+
+static void cpu_bus_noop(device_t dev)
+{
+}
+
+static struct device_operations cpu_bus_ops = {
+ .read_resources = cpu_bus_noop,
+ .set_resources = cpu_bus_noop,
+ .enable_resources = cpu_bus_noop,
+ .init = cpu_bus_init,
+ .scan_bus = 0,
+};
+
+static void enable_dev(struct device *dev)
+{
+ struct device_path path;
+
+ /* Set the operations if it is a special bus type */
+ if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
+ dev->ops = &pci_domain_ops;
+ pci_set_method(dev);
+ }
+ else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
+ dev->ops = &cpu_bus_ops;
+ }
+}
+
+struct chip_operations northbridge_intel_i855gme_ops = {
+ CHIP_NAME("Intel 855GME Northbridge")
+ .enable_dev = enable_dev,
+};
diff --git a/src/northbridge/intel/i855gme/raminit.c b/src/northbridge/intel/i855gme/raminit.c
new file mode 100644
index 0000000000..8e928bd279
--- /dev/null
+++ b/src/northbridge/intel/i855gme/raminit.c
@@ -0,0 +1,297 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2006 Jon Dufresne <jon.dufresne@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
+ */
+
+#include <sdram_mode.h>
+
+#define dumpnorth() dump_pci_device(PCI_DEV(0, 0, 1))
+#define VG85X_MODE (SDRAM_BURST_4 | SDRAM_BURST_INTERLEAVED | SDRAM_CAS_2_5)
+
+/**
+ * Set only what I need until it works, then make it figure things out on boot
+ * assumes only one dimm is populated
+ */
+
+static void sdram_set_registers(const struct mem_controller *ctrl)
+{
+ /*
+ print_debug("Before configuration:\r\n");
+ dump_pci_devices();
+ */
+}
+
+static void spd_set_row_attributes(const struct mem_controller *ctrl)
+{
+ uint16_t dra_reg;
+
+ dra_reg = 0x7733;
+ pci_write_config16(ctrl->d0, 0x50, dra_reg);
+}
+
+static void spd_set_dram_controller_mode(const struct mem_controller *ctrl)
+{
+ uint32_t drc_reg;
+
+ /* drc_reg = 0x00009101; */
+ drc_reg = 0x00009901;
+ pci_write_config32(ctrl->d0, 0x70, drc_reg);
+}
+
+static void spd_set_dram_timing(const struct mem_controller *ctrl)
+{
+ uint32_t drt_reg;
+
+ drt_reg = 0x2a004405;
+ pci_write_config32(ctrl->d0, 0x60, drt_reg);
+}
+
+static void spd_set_dram_size(const struct mem_controller *ctrl)
+{
+ uint32_t drb_reg;
+
+ drb_reg = 0x20202010;
+ pci_write_config32(ctrl->d0, 0x40, drb_reg);
+}
+
+static void spd_set_dram_pwr_management(const struct mem_controller *ctrl)
+{
+ uint32_t pwrmg_reg;
+
+ pwrmg_reg = 0x10f10430;
+ pci_write_config32(ctrl->d0, 0x68, pwrmg_reg);
+}
+
+static void spd_set_dram_throttle_control(const struct mem_controller *ctrl)
+{
+ uint32_t dtc_reg;
+
+ dtc_reg = 0x300aa2ff;
+ pci_write_config32(ctrl->d0, 0xa0, dtc_reg);
+}
+
+void udelay(int usecs)
+{
+ int i;
+ for(i = 0; i < usecs; i++)
+ outb(i & 0xff, 0x80);
+}
+
+#define delay() udelay(200)
+
+/* if ram still doesn't work do this function */
+static void spd_set_undocumented_registers(const struct mem_controller *ctrl)
+{
+ uint16_t word;
+
+ /* 0:0.0 */
+ /*
+ pci_write_config32(PCI_DEV(0, 0, 0), 0x10, 0xe0000008);
+ pci_write_config32(PCI_DEV(0, 0, 0), 0x2c, 0x35808086);
+ pci_write_config32(PCI_DEV(0, 0, 0), 0x48, 0xfec10000);
+ pci_write_config32(PCI_DEV(0, 0, 0), 0x50, 0x00440100);
+
+ pci_write_config32(PCI_DEV(0, 0, 0), 0x58, 0x11111000);
+
+ pci_write_config16(PCI_DEV(0, 0, 0), 0x52, 0x0002);
+ */
+ pci_write_config16(PCI_DEV(0, 0, 0), 0x52, 0x0044);
+ /*
+ pci_write_config16(PCI_DEV(0, 0, 0), 0x52, 0x0000);
+ */
+ pci_write_config32(PCI_DEV(0, 0, 0), 0x58, 0x33333000);
+ pci_write_config32(PCI_DEV(0, 0, 0), 0x5c, 0x33333333);
+ /*
+ pci_write_config32(PCI_DEV(0, 0, 0), 0x60, 0x0000390a);
+ pci_write_config32(PCI_DEV(0, 0, 0), 0x74, 0x02006056);
+ pci_write_config32(PCI_DEV(0, 0, 0), 0x78, 0x00800001);
+ */
+ pci_write_config32(PCI_DEV(0, 0, 0), 0xa8, 0x00000001);
+
+ pci_write_config32(PCI_DEV(0, 0, 0), 0xbc, 0x00001020);
+ /*
+ pci_write_config32(PCI_DEV(0, 0, 0), 0xfc, 0x00000109);
+ */
+
+ /* 0:0.1 */
+ pci_write_config32(ctrl->d0, 0x74, 0x00000001);
+ pci_write_config32(ctrl->d0, 0x78, 0x001fe974);
+ pci_write_config32(ctrl->d0, 0x80, 0x00af0039);
+ pci_write_config32(ctrl->d0, 0x84, 0x0000033c);
+ pci_write_config32(ctrl->d0, 0x88, 0x00000010);
+ pci_write_config32(ctrl->d0, 0x98, 0xde5a868c);
+ pci_write_config32(ctrl->d0, 0x9c, 0x404e0046);
+ pci_write_config32(ctrl->d0, 0xa8, 0x00020e1a);
+ pci_write_config32(ctrl->d0, 0xb4, 0x0044cdac);
+ pci_write_config32(ctrl->d0, 0xb8, 0x000055d4);
+ pci_write_config32(ctrl->d0, 0xbc, 0x024acd38);
+ pci_write_config32(ctrl->d0, 0xc0, 0x00000003);
+
+ /* 0:0.3 */
+ /*
+ pci_write_config32(PCI_DEV(0, 0, 3), 0x2c, 0x35858086);
+ pci_write_config32(PCI_DEV(0, 0, 3), 0x44, 0x11110000);
+ pci_write_config32(PCI_DEV(0, 0, 3), 0x48, 0x09614a3c);
+ pci_write_config32(PCI_DEV(0, 0, 3), 0x4c, 0x4b09604a);
+ pci_write_config32(PCI_DEV(0, 0, 3), 0x50, 0x00000962);
+ pci_write_config32(PCI_DEV(0, 0, 3), 0x5c, 0x0b023331);
+ pci_write_config32(PCI_DEV(0, 0, 3), 0x6c, 0x0000402e);
+ pci_write_config32(PCI_DEV(0, 0, 3), 0x78, 0xe7c70f7f);
+ pci_write_config32(PCI_DEV(0, 0, 3), 0x7c, 0x0284007f);
+ pci_write_config32(PCI_DEV(0, 0, 3), 0x84, 0x000000ef);
+ */
+
+ /*
+ pci_write_config16(PCI_DEV(0, 0, 3), 0xc0, 0x0200);
+ pci_write_config16(PCI_DEV(0, 0, 3), 0xc0, 0x0400);
+ */
+
+ /*
+ pci_write_config32(PCI_DEV(0, 0, 3), 0xc4, 0x00000000);
+ pci_write_config32(PCI_DEV(0, 0, 3), 0xd8, 0xff00c308);
+ pci_write_config32(PCI_DEV(0, 0, 3), 0xdc, 0x00000025);
+ pci_write_config32(PCI_DEV(0, 0, 3), 0xe0, 0x001f002a);
+ pci_write_config32(PCI_DEV(0, 0, 3), 0xe4, 0x009f0098);
+ pci_write_config32(PCI_DEV(0, 0, 3), 0xec, 0x00000400);
+ pci_write_config32(PCI_DEV(0, 0, 3), 0xf0, 0xc0000000);
+ */
+}
+
+static void sdram_set_spd_registers(const struct mem_controller *ctrl)
+{
+ spd_set_row_attributes(ctrl);
+ spd_set_dram_controller_mode(ctrl);
+ spd_set_dram_timing(ctrl);
+ spd_set_dram_size(ctrl);
+ spd_set_dram_pwr_management(ctrl);
+ spd_set_dram_throttle_control(ctrl);
+ spd_set_undocumented_registers(ctrl);
+}
+
+static void ram_command(const struct mem_controller *ctrl,
+ uint8_t command,
+ uint32_t addr)
+{
+ uint32_t drc_reg;
+
+ drc_reg = pci_read_config32(ctrl->d0, 0x70);
+ drc_reg &= ~(7 << 4);
+ drc_reg |= (command << 4);
+ pci_write_config8(ctrl->d0, 0x70, drc_reg);
+ read32(addr);
+}
+
+static void ram_command_mrs(const struct mem_controller *ctrl,
+ uint8_t command,
+ uint32_t mode,
+ uint32_t addr)
+{
+ uint32_t drc_reg;
+ uint32_t adjusted_mode;
+
+ drc_reg = pci_read_config32(ctrl->d0, 0x70);
+ drc_reg &= ~(7 << 4);
+ drc_reg |= (command << 4);
+ pci_write_config8(ctrl->d0, 0x70, drc_reg);
+ /* Host address lines [13:3] map to DIMM address lines [11, 9:0] */
+ adjusted_mode = ((mode & 0x800) << (13 - 11)) | ((mode & 0x3ff) << (12 - 9));
+ print_debug("Setting mode: ");
+ print_debug_hex32(adjusted_mode + addr);
+ print_debug("\r\n");
+ read32(adjusted_mode + addr);
+}
+
+static void set_initialize_complete(const struct mem_controller *ctrl)
+{
+ uint32_t drc_reg;
+
+ drc_reg = pci_read_config32(ctrl->d0, 0x70);
+ drc_reg |= (1 << 29);
+ pci_write_config32(ctrl->d0, 0x70, drc_reg);
+}
+
+static void sdram_enable(int controllers, const struct mem_controller *ctrl)
+{
+ int i;
+ uint32_t rank1 = (1 << 30) / 2;
+ print_debug("Ram enable 1\r\n");
+ delay();
+ delay();
+
+ print_debug("Ram enable 2\r\n");
+ ram_command(ctrl, 1, 0);
+ ram_command(ctrl, 1, rank1);
+ delay();
+ delay();
+
+ print_debug("Ram enable 3\r\n");
+ ram_command(ctrl, 2, 0);
+ ram_command(ctrl, 2, rank1);
+ delay();
+ delay();
+
+ print_debug("Ram enable 4\r\n");
+ ram_command_mrs(ctrl, 4, SDRAM_EXTMODE_DLL_ENABLE, 0);
+ ram_command_mrs(ctrl, 4, SDRAM_EXTMODE_DLL_ENABLE, rank1);
+ delay();
+ delay();
+
+ print_debug("Ram enable 5\r\n");
+ ram_command_mrs(ctrl, 3, VG85X_MODE | SDRAM_MODE_DLL_RESET, 0);
+ ram_command_mrs(ctrl, 3, VG85X_MODE | SDRAM_MODE_DLL_RESET, rank1);
+
+ print_debug("Ram enable 6\r\n");
+ ram_command(ctrl, 2, 0);
+ ram_command(ctrl, 2, rank1);
+ delay();
+ delay();
+
+ print_debug("Ram enable 7\r\n");
+ for(i = 0; i < 8; i++) {
+ ram_command(ctrl, 6, 0);
+ ram_command(ctrl, 6, rank1);
+ delay();
+ delay();
+ }
+
+ print_debug("Ram enable 8\r\n");
+ ram_command_mrs(ctrl, 3, VG85X_MODE | SDRAM_MODE_NORMAL, 0);
+ ram_command_mrs(ctrl, 3, VG85X_MODE | SDRAM_MODE_NORMAL, rank1);
+
+ print_debug("Ram enable 9\r\n");
+ ram_command(ctrl, 7, 0);
+ ram_command(ctrl, 7, rank1);
+ delay();
+ delay();
+
+ print_debug("Ram enable 9\r\n");
+ set_initialize_complete(ctrl);
+
+ delay();
+ delay();
+ delay();
+
+ print_debug("After configuration:\r\n");
+ /* dump_pci_devices(); */
+
+ /*
+ print_debug("\n\n***** RAM TEST *****\r\n");
+ ram_check(0, 0xa0000);
+ ram_check(0x100000, 0x40000000);
+ */
+}
diff --git a/src/northbridge/intel/i855gme/raminit.h b/src/northbridge/intel/i855gme/raminit.h
new file mode 100644
index 0000000000..a312ee511f
--- /dev/null
+++ b/src/northbridge/intel/i855gme/raminit.h
@@ -0,0 +1,32 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2006 Jon Dufresne <jon.dufresne@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
+ */
+
+#ifndef RAMINIT_H
+#define RAMINIT_H
+
+#define DIMM_SOCKETS 2
+
+struct mem_controller {
+ device_t d0;
+ uint16_t channel0[DIMM_SOCKETS];
+};
+
+
+#endif /* RAMINIT_H */
diff --git a/src/northbridge/intel/i855gme/reset_test.c b/src/northbridge/intel/i855gme/reset_test.c
new file mode 100644
index 0000000000..b48b4a3764
--- /dev/null
+++ b/src/northbridge/intel/i855gme/reset_test.c
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2006 Jon Dufresne <jon.dufresne@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
+ */
+
+#define MCH_DRC 0x70
+#define DRC_DONE (1 << 29)
+
+ /* If I have already booted once skip a bunch of initialization */
+ /* To see if I have already booted I check to see if memory
+ * has been enabled.
+ */
+static int bios_reset_detected(void)
+{
+ uint32_t dword;
+
+ dword = pci_read_config32(PCI_DEV(0, 0, 0), MCH_DRC);
+
+ if( (dword & DRC_DONE) != 0 ) {
+ return 1;
+ }
+
+ return 0;
+}