summaryrefslogtreecommitdiff
path: root/src/northbridge/intel/i855gme/raminit.c
diff options
context:
space:
mode:
authorJon Dufresne <jon.dufresne@gmail.com>2009-01-20 20:25:48 +0000
committerStefan Reinauer <stepan@openbios.org>2009-01-20 20:25:48 +0000
commit8c4af2b9e278d0c48cc6820ae2d1a300915425cb (patch)
tree4a25cba3f6d261f250b1c16ae4fa62a106196ddf /src/northbridge/intel/i855gme/raminit.c
parentef6cb094b83b2717fba379a2c6670c19b12c676d (diff)
downloadcoreboot-8c4af2b9e278d0c48cc6820ae2d1a300915425cb.tar.xz
This fine work by Jon Dufresne was awkwardly rotting on the mailing list for
almost three years. Let's put it somewher so people find it if they're looking for it. Someone dare sending a late announcement to the coreboot-announce list? :-) Add (preliminary) support for Intel 855GME (Mobile version of the 855) chipset to coreboot. There are some holes in the code to be filled out, but unlike the code for the 855pm this has booted a mainboard before. Signed-off-by: Jon Dufresne <jon.dufresne@gmail.com> Acked-by: Stefan Reinauer <stepan@coresystems.de> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3877 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/northbridge/intel/i855gme/raminit.c')
-rw-r--r--src/northbridge/intel/i855gme/raminit.c297
1 files changed, 297 insertions, 0 deletions
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);
+ */
+}