[coreboot] r715 - coreboot-v3/northbridge/amd/k8

svn at coreboot.org svn at coreboot.org
Sun Aug 3 21:36:53 CEST 2008


Author: rminnich
Date: 2008-08-03 21:36:53 +0200 (Sun, 03 Aug 2008)
New Revision: 715

Modified:
   coreboot-v3/northbridge/amd/k8/raminit.c
Log:
This mostly compiles. 

Also, per Uwe, remove the \r\n for \n

Signed-off-by: Ronald G. Minnich <rminnich at gmail.com>

Acked-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006 at gmx.net>


Modified: coreboot-v3/northbridge/amd/k8/raminit.c
===================================================================
--- coreboot-v3/northbridge/amd/k8/raminit.c	2008-08-02 20:56:11 UTC (rev 714)
+++ coreboot-v3/northbridge/amd/k8/raminit.c	2008-08-03 19:36:53 UTC (rev 715)
@@ -52,7 +52,7 @@
 		struct device *dev;
 		unsigned where;
 		unsigned long reg;
-		printk(BIOS_DEBUG, "%08x <- %08x\r\n", register_values[i], register_values[i+2]);
+		printk(BIOS_DEBUG, "%08x <- %08x\n", register_values[i], register_values[i+2]);
 		dev = register_values[i] & ~0xfff;
 		where = register_values[i] & 0xfff;
 		reg = pci_read_config32(dev, where);
@@ -61,7 +61,7 @@
 		pci_write_config32(dev, where, reg);
 	}
 */
-	printk(BIOS_DEBUG, "done.\r\n");
+	printk(BIOS_DEBUG, "done.\n");
 }
 
 static int controller_present(const struct mem_controller *ctrl)
@@ -543,7 +543,7 @@
 	int max;
 
         if (!controller_present(ctrl)) {
-                printk(BIOS_DEBUG, "No memory controller present\r\n");
+                printk(BIOS_DEBUG, "No memory controller present\n");
                 return;
         }
 	printk(BIOS_SPEW, "setting up CPU 0x%x northbridge registers ", ctrl->node_id);
@@ -552,7 +552,7 @@
 		struct device *dev;
 		unsigned where;
 		unsigned long reg;
-                printk(BIOS_DEBUG, "%08x <- %08x\r\n", register_values[i], register_values[i+2]);
+                printk(BIOS_DEBUG, "%08x <- %08x\n", register_values[i], register_values[i+2]);
 		dev = (register_values[i] & ~0xfff) - PCI_BDF(0, 0x18, 0) + ctrl->f0;
 		where = register_values[i] & 0xfff;
 		reg = pci_read_config32(dev, where);
@@ -560,7 +560,7 @@
 		reg |= register_values[i+2];
 		pci_write_config32(dev, where, reg);
 	}
-	printk(BIOS_SPEW, "done.\r\n");
+	printk(BIOS_SPEW, "done.\n");
 }
 
 
@@ -695,7 +695,7 @@
 	goto out;
 
  val_err:
-	die("Bad SPD value\r\n");
+	die("Bad SPD value\n");
 	/* If an hw_error occurs report that I have no memory */
 hw_err:
 	sz.side1 = 0;
@@ -857,7 +857,7 @@
 
 	limit_reg = 0x44 + index;
 	base_reg = 0x40 + index;
-	for(device = PCI_DEV(0, 0x18, 1); device <= PCI_DEV(0, 0x1f, 1); device += PCI_DEV(0, 1, 0)) {
+	for(device = PCI_BDF(0, 0x18, 1); device <= PCI_BDF(0, 0x1f, 1); device += PCI_BDF(0, 1, 0)) {
 		pci_write_config32(device, limit_reg, limit);
 		pci_write_config32(device, base_reg, base);
 	}
@@ -871,12 +871,10 @@
 	}
 
 	/* Report the amount of memory. */
-	print_spew("RAM: 0x");
-	print_spew_hex32(tom_k);
-	print_spew(" KB\r\n");
+	printk(BIOS_SPEW, "RAM: 0x%x KB\n", tom_k);
 
 	/* Now set top of memory */
-	msr_t msr;
+	struct msr msr;
 	if(tom_k > (4*1024*1024)) {
 		msr.lo = (tom_k & 0x003fffff) << 10;
 		msr.hi = (tom_k & 0xffc00000) >> 22;
@@ -988,7 +986,7 @@
 		if(is_dual_channel(ctrl)) {
                 /* Also we run out of address mask bits if we try and interleave 8 4GB dimms */
 	                if ((bits == 3) && (common_size == (1 << (32 - 3)))) {
-//     		                printk(BIOS_DEBUG, "8 4GB chip selects cannot be interleaved\r\n");
+//     		                printk(BIOS_DEBUG, "8 4GB chip selects cannot be interleaved\n");
 	                        return 0;
                 	}  
 			csbase_inc <<=1;
@@ -998,7 +996,7 @@
 		csbase_inc = 1 << csbase_low_d0_shift[common_cs_mode];
 		if(is_dual_channel(ctrl)) {
 	                if( (bits==3) && (common_cs_mode > 8)) {
-//        	                printk(BIOS_DEBUG, "8 cs_mode>8 chip selects cannot be interleaved\r\n");
+//        	                printk(BIOS_DEBUG, "8 cs_mode>8 chip selects cannot be interleaved\n");
         	                return 0;
 			}
 			csbase_inc <<=1;
@@ -1124,7 +1122,7 @@
 	if (read_option(CMOS_VSTART_interleave_chip_selects, CMOS_VLEN_interleave_chip_selects, 1) != 0) {
 		tom_k = interleave_chip_selects(ctrl);
 	} else {
-		printk(BIOS_DEBUG, "Interleaving disabled\r\n");
+		printk(BIOS_DEBUG, "Interleaving disabled\n");
 		tom_k = 0;
 	}
 	if (!tom_k) {
@@ -1195,9 +1193,9 @@
 	}
 	pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
 	if (is_registered(ctrl)) {
-		printk(BIOS_DEBUG, "Registered\r\n");
+		printk(BIOS_DEBUG, "Registered\n");
 	} else {
-		printk(BIOS_DEBUG, "Unbuffered\r\n");
+		printk(BIOS_DEBUG, "Unbuffered\n");
 	}
 	return dimm_mask;
 }
@@ -1291,7 +1289,7 @@
 			}
 		}
 	}
-	printk(BIOS_SPEW, "Enabling dual channel memory\r\n");
+	printk(BIOS_SPEW, "Enabling dual channel memory\n");
 	u32 dcl;
 	dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
 	dcl &= ~DCL_32ByteEn;
@@ -1321,7 +1319,7 @@
 {
 	static const struct mem_param speed[] = {
 		{
-			.name	    = "100Mhz\r\n",
+			.name	    = "100Mhz\n",
 			.cycle_time = 0xa0,
 			.divisor    = (10 <<1),
 			.tRC	    = 0x46,
@@ -1335,7 +1333,7 @@
 			.rdpreamble = { ((9 << 1) + 0), ((9 << 1) + 0), ((9 << 1) + 0), ((9 << 1) + 0) }
 		},
 		{
-			.name	    = "133Mhz\r\n",
+			.name	    = "133Mhz\n",
 			.cycle_time = 0x75,
 			.divisor    = (7<<1)+1,
 			.tRC	    = 0x41,
@@ -1349,7 +1347,7 @@
 			.rdpreamble = { ((8 << 1) + 0), ((7 << 1) + 0), ((7 << 1) + 1), ((7 << 1) + 0) }
 		},
 		{
-			.name	    = "166Mhz\r\n",
+			.name	    = "166Mhz\n",
 			.cycle_time = 0x60,
 			.divisor    = (6<<1),
 			.tRC	    = 0x3C,
@@ -1363,7 +1361,7 @@
 			.rdpreamble = { ((7 << 1) + 1), ((6 << 1) + 0), ((6 << 1) + 1), ((6 << 1) + 0) }
 		},
 		{
-			.name	    = "200Mhz\r\n",
+			.name	    = "200Mhz\n",
 			.cycle_time = 0x50,
 			.divisor    = (5<<1),
 			.tRC	    = 0x37,
@@ -1389,7 +1387,7 @@
 	if (!param->cycle_time) {
 		die("min_cycle_time to low");
 	}
-	print_spew(param->name);
+	printk(BIOS_SPEW, param->name);
 #ifdef DRAM_MIN_CYCLE_TIME
 	printk(BIOS_DEBUG, param->name);
 #endif
@@ -1914,7 +1912,7 @@
 
 	clocks = param->dtl_trwt[lat][mtype];
 	if ((clocks < DTH_TRWT_MIN) || (clocks > DTH_TRWT_MAX)) {
-		die("Unknown Trwt\r\n");
+		die("Unknown Trwt\n");
 	}
 	
 	dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
@@ -2082,14 +2080,14 @@
 	const struct mem_param *param;
 	long dimm_mask;
 	if (!controller_present(ctrl)) {
-		printk(BIOS_DEBUG, "No memory controller present\r\n");
+		printk(BIOS_DEBUG, "No memory controller present\n");
 		return;
 	}
 	hw_enable_ecc(ctrl);
 	activate_spd_rom(ctrl);
 	dimm_mask = spd_detect_dimms(ctrl);
 	if (!(dimm_mask & ((1 << DIMM_SOCKETS) - 1))) {
-		printk(BIOS_DEBUG, "No memory for this cpu\r\n");
+		printk(BIOS_DEBUG, "No memory for this cpu\n");
 		return;
 	}
 	dimm_mask = spd_enable_2channels(ctrl, dimm_mask);        
@@ -2113,7 +2111,7 @@
 	return;
  hw_spd_err:
 	/* Unrecoverable error reading SPD data */
-	print_err("SPD error - reset\r\n");
+	print_err("SPD error - reset\n");
 	hard_reset();
 	return;
 }
@@ -2235,7 +2233,7 @@
 
 	/* Error if I don't have memory */
 	if (memory_end_k(ctrl, controllers) == 0) {
-		die("No memory\r\n");
+		die("No memory\n");
 	}
 
 	/* Before enabling memory start the memory clocks */
@@ -2276,7 +2274,7 @@
 		dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
 		if (dcl & DCL_DimmEccEn) {
 			u32 mnc;
-			print_spew("ECC enabled\r\n");
+			printk(BIOS_SPEW, "ECC enabled\n");
 			mnc = pci_read_config32(ctrl[i].f3, MCA_NB_CONFIG);
 			mnc |= MNC_ECC_EN;
 			if (dcl & DCL_128BitEn) {
@@ -2315,7 +2313,7 @@
 			}
 		} while(((dcl & DCL_DramInit) != 0) && (loops < TIMEOUT_LOOPS));
 		if (loops >= TIMEOUT_LOOPS) {
-			printk(BIOS_DEBUG, " failed\r\n");
+			printk(BIOS_DEBUG, " failed\n");
 			continue;
 		}
 
@@ -2328,7 +2326,7 @@
 			} while(((dcl & DCL_MemClrStatus) == 0) || ((dcl & DCL_DramEnable) == 0) );
 		}
 
-		printk(BIOS_DEBUG, " done\r\n");
+		printk(BIOS_DEBUG, " done\n");
 	}
 
 #if HW_MEM_HOLE_SIZEK != 0
@@ -2361,10 +2359,10 @@
         for(i=0;i<controllers; i++) {
                 ctrl = &ctrl_a[i];
                 ctrl->node_id = i;
-                ctrl->f0 = PCI_DEV(0, 0x18+i, 0);
-                ctrl->f1 = PCI_DEV(0, 0x18+i, 1);
-                ctrl->f2 = PCI_DEV(0, 0x18+i, 2);
-                ctrl->f3 = PCI_DEV(0, 0x18+i, 3);
+                ctrl->f0 = PCI_BDF(0, 0x18+i, 0);
+                ctrl->f1 = PCI_BDF(0, 0x18+i, 1);
+                ctrl->f2 = PCI_BDF(0, 0x18+i, 2);
+                ctrl->f3 = PCI_BDF(0, 0x18+i, 3);
 
                 if(spd_addr == (void *)0) continue;
 
@@ -2374,2383 +2372,3 @@
                 }
         }
 }
-#endif
-
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2002 Linux Networx
- * (Written by Eric Biederman <ebiederman at lnxi.com> for Linux Networx)
- * Copyright (C) 2004 YingHai Lu
- * Copyright (C) 2007 Ronald G. Minnich <rminnich at 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; version 2 of the License.
- *
- * 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 should be done by Eric
-	2004.11 yhlu add 4 rank DIMM support
-	2004.12 yhlu add D0 support
-	2005.02 yhlu add E0 memory hole support
-*/
-/* not yet 
-#if K8_REV_F_SUPPORT == 1
-        #include "raminit_f.c"
-#else
- */
-
-#include <mem.h>
-#include <cache.h>
-#include <mtrr.h>
-#include "raminit.h"
-#include "k8.h"
-#include "sysconf.h"
-
-#ifndef QRANK_DIMM_SUPPORT
-#define QRANK_DIMM_SUPPORT 0
-#endif
-
-static void hard_reset(void);
-
-static void setup_resource_map(const unsigned int *register_values, int max)
-{
-	int i;
-	printk(BIOS_DEBUG, "setting up resource map....");
-	for(i = 0; i < max; i += 3) {
-		struct device *dev;
-		unsigned where;
-		unsigned long reg;
-		printk(BIOS_DEBUG, "%08x <- %08x\r\n", register_values[i], register_values[i+2]);
-		dev = register_values[i] & ~0xfff;
-		where = register_values[i] & 0xfff;
-		reg = pci_read_config32(dev, where);
-		reg &= register_values[i+1];
-		reg |= register_values[i+2];
-		pci_write_config32(dev, where, reg);
-	}
-	printk(BIOS_DEBUG, "done.\r\n");
-}
-
-static int controller_present(const struct mem_controller *ctrl)
-{
-        return pci_read_config32(ctrl->f0, 0) == 0x11001022;
-}
-
-static void sdram_set_registers(const struct mem_controller *ctrl)
-{
-	static const unsigned int register_values[] = {
-
-	/* Careful set limit registers before base registers which contain the enables */
-	/* DRAM Limit i Registers
-	 * F1:0x44 i = 0
-	 * F1:0x4C i = 1
-	 * F1:0x54 i = 2
-	 * F1:0x5C i = 3
-	 * F1:0x64 i = 4
-	 * F1:0x6C i = 5
-	 * F1:0x74 i = 6
-	 * F1:0x7C i = 7
-	 * [ 2: 0] Destination Node ID
-	 *	   000 = Node 0
-	 *	   001 = Node 1
-	 *	   010 = Node 2
-	 *	   011 = Node 3
-	 *	   100 = Node 4
-	 *	   101 = Node 5
-	 *	   110 = Node 6
-	 *	   111 = Node 7
-	 * [ 7: 3] Reserved
-	 * [10: 8] Interleave select
-	 *	   specifies the values of A[14:12] to use with interleave enable.
-	 * [15:11] Reserved
-	 * [31:16] DRAM Limit Address i Bits 39-24
-	 *	   This field defines the upper address bits of a 40 bit  address
-	 *	   that define the end of the DRAM region.
-	 */
-	PCI_ADDR(0, 0x18, 1, 0x44), 0x0000f8f8, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x4C), 0x0000f8f8, 0x00000001,
-	PCI_ADDR(0, 0x18, 1, 0x54), 0x0000f8f8, 0x00000002,
-	PCI_ADDR(0, 0x18, 1, 0x5C), 0x0000f8f8, 0x00000003,
-	PCI_ADDR(0, 0x18, 1, 0x64), 0x0000f8f8, 0x00000004,
-	PCI_ADDR(0, 0x18, 1, 0x6C), 0x0000f8f8, 0x00000005,
-	PCI_ADDR(0, 0x18, 1, 0x74), 0x0000f8f8, 0x00000006,
-	PCI_ADDR(0, 0x18, 1, 0x7C), 0x0000f8f8, 0x00000007,
-	/* DRAM Base i Registers
-	 * F1:0x40 i = 0
-	 * F1:0x48 i = 1
-	 * F1:0x50 i = 2
-	 * F1:0x58 i = 3
-	 * F1:0x60 i = 4
-	 * F1:0x68 i = 5
-	 * F1:0x70 i = 6
-	 * F1:0x78 i = 7
-	 * [ 0: 0] Read Enable
-	 *	   0 = Reads Disabled
-	 *	   1 = Reads Enabled
-	 * [ 1: 1] Write Enable
-	 *	   0 = Writes Disabled
-	 *	   1 = Writes Enabled
-	 * [ 7: 2] Reserved
-	 * [10: 8] Interleave Enable
-	 *	   000 = No interleave
-	 *	   001 = Interleave on A[12] (2 nodes)
-	 *	   010 = reserved
-	 *	   011 = Interleave on A[12] and A[14] (4 nodes)
-	 *	   100 = reserved
-	 *	   101 = reserved
-	 *	   110 = reserved
-	 *	   111 = Interleve on A[12] and A[13] and A[14] (8 nodes)
-	 * [15:11] Reserved
-	 * [13:16] DRAM Base Address i Bits 39-24
-	 *	   This field defines the upper address bits of a 40-bit address
-	 *	   that define the start of the DRAM region.
-	 */
-	PCI_ADDR(0, 0x18, 1, 0x40), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x48), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x50), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x58), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x60), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x68), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x70), 0x0000f8fc, 0x00000000,
-	PCI_ADDR(0, 0x18, 1, 0x78), 0x0000f8fc, 0x00000000,
-
-	/* DRAM CS Base Address i Registers
-	 * F2:0x40 i = 0
-	 * F2:0x44 i = 1
-	 * F2:0x48 i = 2
-	 * F2:0x4C i = 3
-	 * F2:0x50 i = 4
-	 * F2:0x54 i = 5
-	 * F2:0x58 i = 6
-	 * F2:0x5C i = 7
-	 * [ 0: 0] Chip-Select Bank Enable
-	 *	   0 = Bank Disabled
-	 *	   1 = Bank Enabled
-	 * [ 8: 1] Reserved
-	 * [15: 9] Base Address (19-13)
-	 *	   An optimization used when all DIMM are the same size...
-	 * [20:16] Reserved
-	 * [31:21] Base Address (35-25)
-	 *	   This field defines the top 11 addresses bit of a 40-bit
-	 *	   address that define the memory address space.  These
-	 *	   bits decode 32-MByte blocks of memory.
-	 */
-	PCI_ADDR(0, 0x18, 2, 0x40), 0x001f01fe, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x44), 0x001f01fe, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x48), 0x001f01fe, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x4C), 0x001f01fe, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x50), 0x001f01fe, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x54), 0x001f01fe, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x58), 0x001f01fe, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x5C), 0x001f01fe, 0x00000000,
-	/* DRAM CS Mask Address i Registers
-	 * F2:0x60 i = 0
-	 * F2:0x64 i = 1
-	 * F2:0x68 i = 2
-	 * F2:0x6C i = 3
-	 * F2:0x70 i = 4
-	 * F2:0x74 i = 5
-	 * F2:0x78 i = 6
-	 * F2:0x7C i = 7
-	 * Select bits to exclude from comparison with the DRAM Base address register.
-	 * [ 8: 0] Reserved
-	 * [15: 9] Address Mask (19-13)
-	 *	   Address to be excluded from the optimized case
-	 * [20:16] Reserved
-	 * [29:21] Address Mask (33-25)
-	 *	   The bits with an address mask of 1 are excluded from address comparison
-	 * [31:30] Reserved
-	 * 
-	 */
-	PCI_ADDR(0, 0x18, 2, 0x60), 0xC01f01ff, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x64), 0xC01f01ff, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x68), 0xC01f01ff, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x6C), 0xC01f01ff, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x70), 0xC01f01ff, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x74), 0xC01f01ff, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x78), 0xC01f01ff, 0x00000000,
-	PCI_ADDR(0, 0x18, 2, 0x7C), 0xC01f01ff, 0x00000000,
-	/* DRAM Bank Address Mapping Register
-	 * F2:0x80
-	 * Specify the memory module size
-	 * [ 2: 0] CS1/0 
-	 * [ 6: 4] CS3/2
-	 * [10: 8] CS5/4
-	 * [14:12] CS7/6
-	 *	   000 = 32Mbyte  (Rows = 12 & Col =  8)
-	 *	   001 = 64Mbyte  (Rows = 12 & Col =  9)
-	 *	   010 = 128Mbyte (Rows = 13 & Col =  9)|(Rows = 12 & Col = 10)
-	 *	   011 = 256Mbyte (Rows = 13 & Col = 10)|(Rows = 12 & Col = 11)
-	 *	   100 = 512Mbyte (Rows = 13 & Col = 11)|(Rows = 14 & Col = 10)
-	 *	   101 = 1Gbyte	  (Rows = 14 & Col = 11)|(Rows = 13 & Col = 12)
-	 *	   110 = 2Gbyte	  (Rows = 14 & Col = 12)
-	 *	   111 = reserved 
-	 * [ 3: 3] Reserved
-	 * [ 7: 7] Reserved
-	 * [11:11] Reserved
-	 * [31:15]
-	 */
-	PCI_ADDR(0, 0x18, 2, 0x80), 0xffff8888, 0x00000000,
-	/* DRAM Timing Low Register
-	 * F2:0x88
-	 * [ 2: 0] Tcl (Cas# Latency, Cas# to read-data-valid)
-	 *	   000 = reserved
-	 *	   001 = CL 2
-	 *	   010 = CL 3
-	 *	   011 = reserved
-	 *	   100 = reserved
-	 *	   101 = CL 2.5
-	 *	   110 = reserved
-	 *	   111 = reserved
-	 * [ 3: 3] Reserved
-	 * [ 7: 4] Trc (Row Cycle Time, Ras#-active to Ras#-active/bank auto refresh)
-	 *	   0000 =  7 bus clocks
-	 *	   0001 =  8 bus clocks
-	 *	   ...
-	 *	   1110 = 21 bus clocks
-	 *	   1111 = 22 bus clocks
-	 * [11: 8] Trfc (Row refresh Cycle time, Auto-refresh-active to RAS#-active or RAS#auto-refresh)
-	 *	   0000 = 9 bus clocks
-	 *	   0010 = 10 bus clocks
-	 *	   ....
-	 *	   1110 = 23 bus clocks
-	 *	   1111 = 24 bus clocks
-	 * [14:12] Trcd (Ras#-active to Case#-read/write Delay)
-	 *	   000 = reserved
-	 *	   001 = reserved
-	 *	   010 = 2 bus clocks
-	 *	   011 = 3 bus clocks
-	 *	   100 = 4 bus clocks
-	 *	   101 = 5 bus clocks
-	 *	   110 = 6 bus clocks
-	 *	   111 = reserved
-	 * [15:15] Reserved
-	 * [18:16] Trrd (Ras# to Ras# Delay)
-	 *	   000 = reserved
-	 *	   001 = reserved
-	 *	   010 = 2 bus clocks
-	 *	   011 = 3 bus clocks
-	 *	   100 = 4 bus clocks
-	 *	   101 = reserved
-	 *	   110 = reserved
-	 *	   111 = reserved
-	 * [19:19] Reserved
-	 * [23:20] Tras (Minmum Ras# Active Time)
-	 *	   0000 to 0100 = reserved
-	 *	   0101 = 5 bus clocks
-	 *	   ...
-	 *	   1111 = 15 bus clocks
-	 * [26:24] Trp (Row Precharge Time)
-	 *	   000 = reserved
-	 *	   001 = reserved
-	 *	   010 = 2 bus clocks
-	 *	   011 = 3 bus clocks
-	 *	   100 = 4 bus clocks
-	 *	   101 = 5 bus clocks
-	 *	   110 = 6 bus clocks
-	 *	   111 = reserved
-	 * [27:27] Reserved
-	 * [28:28] Twr (Write Recovery Time)
-	 *	   0 = 2 bus clocks
-	 *	   1 = 3 bus clocks
-	 * [31:29] Reserved
-	 */
-	PCI_ADDR(0, 0x18, 2, 0x88), 0xe8088008, 0x02522001 /* 0x03623125 */ ,
-	/* DRAM Timing High Register
-	 * F2:0x8C
-	 * [ 0: 0] Twtr (Write to Read Delay)
-	 *	   0 = 1 bus Clocks
-	 *	   1 = 2 bus Clocks
-	 * [ 3: 1] Reserved
-	 * [ 6: 4] Trwt (Read to Write Delay)
-	 *	   000 = 1 bus clocks
-	 *	   001 = 2 bus clocks
-	 *	   010 = 3 bus clocks
-	 *	   011 = 4 bus clocks
-	 *	   100 = 5 bus clocks
-	 *	   101 = 6 bus clocks
-	 *	   110 = reserved
-	 *	   111 = reserved
-	 * [ 7: 7] Reserved
-	 * [12: 8] Tref (Refresh Rate)
-	 *	   00000 = 100Mhz 4K rows
-	 *	   00001 = 133Mhz 4K rows
-	 *	   00010 = 166Mhz 4K rows
-	 *	   00011 = 200Mhz 4K rows
-	 *	   01000 = 100Mhz 8K/16K rows
-	 *	   01001 = 133Mhz 8K/16K rows
-	 *	   01010 = 166Mhz 8K/16K rows
-	 *	   01011 = 200Mhz 8K/16K rows
-	 * [19:13] Reserved
-	 * [22:20] Twcl (Write CAS Latency)
-	 *	   000 = 1 Mem clock after CAS# (Unbuffered Dimms)
-	 *	   001 = 2 Mem clocks after CAS# (Registered Dimms)
-	 * [31:23] Reserved
-	 */
-	PCI_ADDR(0, 0x18, 2, 0x8c), 0xff8fe08e, (0 << 20)|(0 << 8)|(0 << 4)|(0 << 0),
-	/* DRAM Config Low Register
-	 * F2:0x90
-	 * [ 0: 0] DLL Disable
-	 *	   0 = Enabled
-	 *	   1 = Disabled
-	 * [ 1: 1] D_DRV
-	 *	   0 = Normal Drive
-	 *	   1 = Weak Drive
-	 * [ 2: 2] QFC_EN
-	 *	   0 = Disabled
-	 *	   1 = Enabled
-	 * [ 3: 3] Disable DQS Hystersis  (FIXME handle this one carefully)
-	 *	   0 = Enable DQS input filter 
-	 *	   1 = Disable DQS input filtering 
-	 * [ 7: 4] Reserved
-	 * [ 8: 8] DRAM_Init
-	 *	   0 = Initialization done or not yet started.
-	 *	   1 = Initiate DRAM intialization sequence
-	 * [ 9: 9] SO-Dimm Enable
-	 *	   0 = Do nothing
-	 *	   1 = SO-Dimms present
-	 * [10:10] DramEnable
-	 *	   0 = DRAM not enabled
-	 *	   1 = DRAM initialized and enabled
-	 * [11:11] Memory Clear Status
-	 *	   0 = Memory Clear function has not completed
-	 *	   1 = Memory Clear function has completed
-	 * [12:12] Exit Self-Refresh
-	 *	   0 = Exit from self-refresh done or not yet started
-	 *	   1 = DRAM exiting from self refresh
-	 * [13:13] Self-Refresh Status
-	 *	   0 = Normal Operation
-	 *	   1 = Self-refresh mode active
-	 * [15:14] Read/Write Queue Bypass Count
-	 *	   00 = 2
-	 *	   01 = 4
-	 *	   10 = 8
-	 *	   11 = 16
-	 * [16:16] 128-bit/64-Bit
-	 *	   0 = 64bit Interface to DRAM
-	 *	   1 = 128bit Interface to DRAM
-	 * [17:17] DIMM ECC Enable
-	 *	   0 = Some DIMMs do not have ECC
-	 *	   1 = ALL DIMMS have ECC bits
-	 * [18:18] UnBuffered DIMMs
-	 *	   0 = Buffered DIMMS
-	 *	   1 = Unbuffered DIMMS
-	 * [19:19] Enable 32-Byte Granularity
-	 *	   0 = Optimize for 64byte bursts
-	 *	   1 = Optimize for 32byte bursts
-	 * [20:20] DIMM 0 is x4
-	 * [21:21] DIMM 1 is x4
-	 * [22:22] DIMM 2 is x4
-	 * [23:23] DIMM 3 is x4
-	 *	   0 = DIMM is not x4
-	 *	   1 = x4 DIMM present
-	 * [24:24] Disable DRAM Receivers
-	 *	   0 = Receivers enabled
-	 *	   1 = Receivers disabled
-	 * [27:25] Bypass Max
-	 *	   000 = Arbiters chois is always respected
-	 *	   001 = Oldest entry in DCQ can be bypassed 1 time
-	 *	   010 = Oldest entry in DCQ can be bypassed 2 times
-	 *	   011 = Oldest entry in DCQ can be bypassed 3 times
-	 *	   100 = Oldest entry in DCQ can be bypassed 4 times
-	 *	   101 = Oldest entry in DCQ can be bypassed 5 times
-	 *	   110 = Oldest entry in DCQ can be bypassed 6 times
-	 *	   111 = Oldest entry in DCQ can be bypassed 7 times
-	 * [31:28] Reserved
-	 */
-	PCI_ADDR(0, 0x18, 2, 0x90), 0xf0000000, 
-	(4 << 25)|(0 << 24)| 
-	(0 << 23)|(0 << 22)|(0 << 21)|(0 << 20)| 
-	(1 << 19)|(0 << 18)|(1 << 17)|(0 << 16)| 
-	(2 << 14)|(0 << 13)|(0 << 12)| 
-	(0 << 11)|(0 << 10)|(0 << 9)|(0 << 8)| 
-	(0 << 3) |(0 << 1) |(0 << 0),
-	/* DRAM Config High Register
-	 * F2:0x94
-	 * [ 0: 3] Maximum Asynchronous Latency
-	 *	   0000 = 0 ns
-	 *	   ...
-	 *	   1111 = 15 ns
-	 * [ 7: 4] Reserved
-	 * [11: 8] Read Preamble
-	 *	   0000 = 2.0 ns
-	 *	   0001 = 2.5 ns
-	 *	   0010 = 3.0 ns
-	 *	   0011 = 3.5 ns
-	 *	   0100 = 4.0 ns
-	 *	   0101 = 4.5 ns
-	 *	   0110 = 5.0 ns
-	 *	   0111 = 5.5 ns
-	 *	   1000 = 6.0 ns
-	 *	   1001 = 6.5 ns
-	 *	   1010 = 7.0 ns
-	 *	   1011 = 7.5 ns
-	 *	   1100 = 8.0 ns
-	 *	   1101 = 8.5 ns
-	 *	   1110 = 9.0 ns
-	 *	   1111 = 9.5 ns
-	 * [15:12] Reserved
-	 * [18:16] Idle Cycle Limit
-	 *	   000 = 0 cycles
-	 *	   001 = 4 cycles
-	 *	   010 = 8 cycles
-	 *	   011 = 16 cycles
-	 *	   100 = 32 cycles
-	 *	   101 = 64 cycles
-	 *	   110 = 128 cycles
-	 *	   111 = 256 cycles
-	 * [19:19] Dynamic Idle Cycle Center Enable
-	 *	   0 = Use Idle Cycle Limit
-	 *	   1 = Generate a dynamic Idle cycle limit
-	 * [22:20] DRAM MEMCLK Frequency
-	 *	   000 = 100Mhz
-	 *	   001 = reserved
-	 *	   010 = 133Mhz
-	 *	   011 = reserved
-	 *	   100 = reserved
-	 *	   101 = 166Mhz
-	 *	   110 = reserved
-	 *	   111 = reserved
-	 * [24:23] Reserved
-	 * [25:25] Memory Clock Ratio Valid (FIXME carefully enable memclk)
-	 *	   0 = Disable MemClks
-	 *	   1 = Enable MemClks
-	 * [26:26] Memory Clock 0 Enable
-	 *	   0 = Disabled
-	 *	   1 = Enabled
-	 * [27:27] Memory Clock 1 Enable
-	 *	   0 = Disabled
-	 *	   1 = Enabled
-	 * [28:28] Memory Clock 2 Enable
-	 *	   0 = Disabled
-	 *	   1 = Enabled
-	 * [29:29] Memory Clock 3 Enable
-	 *	   0 = Disabled
-	 *	   1 = Enabled
-	 * [31:30] Reserved
-	 */
-	PCI_ADDR(0, 0x18, 2, 0x94), 0xc180f0f0,
-	(0 << 29)|(0 << 28)|(0 << 27)|(0 << 26)|(0 << 25)|
-	(0 << 20)|(0 << 19)|(DCH_IDLE_LIMIT_16 << 16)|(0 << 8)|(0 << 0),
-	/* DRAM Delay Line Register
-	 * F2:0x98
-	 * Adjust the skew of the input DQS strobe relative to DATA
-	 * [15: 0] Reserved
-	 * [23:16] Delay Line Adjust
-	 *	   Adjusts the DLL derived PDL delay by one or more delay stages
-	 *	   in either the faster or slower direction.
-	 * [24:24} Adjust Slower
-	 *	   0 = Do Nothing
-	 *	   1 = Adj is used to increase the PDL delay
-	 * [25:25] Adjust Faster
-	 *	   0 = Do Nothing
-	 *	   1 = Adj is used to decrease the PDL delay
-	 * [31:26] Reserved
-	 */
-	PCI_ADDR(0, 0x18, 2, 0x98), 0xfc00ffff, 0x00000000,
-	/* MCA NB Status Low reg */
-	PCI_ADDR(0, 0x18, 3, 0x48), 0x00f00000, 0x00000000,
-	/* MCA NB Status high reg */
-	PCI_ADDR(0, 0x18, 3, 0x4c), 0x01801e8c, 0x00000000,
-	/* MCA NB address Low reg */
-	PCI_ADDR(0, 0x18, 3, 0x50), 0x00000007, 0x00000000,
-	/* MCA NB address high reg */
-	PCI_ADDR(0, 0x18, 3, 0x54), 0xffffff00, 0x00000000,
-	/* DRAM Scrub Control Register
-	 * F3:0x58
-	 * [ 4: 0] DRAM Scrube Rate
-	 * [ 7: 5] reserved
-	 * [12: 8] L2 Scrub Rate
-	 * [15:13] reserved
-	 * [20:16] Dcache Scrub
-	 * [31:21] reserved
-	 *	   Scrub Rates
-	 *	   00000 = Do not scrub
-	 *	   00001 =  40.00 ns
-	 *	   00010 =  80.00 ns
-	 *	   00011 = 160.00 ns
-	 *	   00100 = 320.00 ns
-	 *	   00101 = 640.00 ns
-	 *	   00110 =   1.28 us
-	 *	   00111 =   2.56 us
-	 *	   01000 =   5.12 us
-	 *	   01001 =  10.20 us
-	 *	   01011 =  41.00 us
-	 *	   01100 =  81.90 us
-	 *	   01101 = 163.80 us
-	 *	   01110 = 327.70 us
-	 *	   01111 = 655.40 us
-	 *	   10000 =   1.31 ms
-	 *	   10001 =   2.62 ms
-	 *	   10010 =   5.24 ms
-	 *	   10011 =  10.49 ms
-	 *	   10100 =  20.97 ms
-	 *	   10101 =  42.00 ms
-	 *	   10110 =  84.00 ms
-	 *	   All Others = Reserved
-	 */
-	PCI_ADDR(0, 0x18, 3, 0x58), 0xffe0e0e0, 0x00000000,
-	/* DRAM Scrub Address Low Register
-	 * F3:0x5C
-	 * [ 0: 0] DRAM Scrubber Redirect Enable
-	 *	   0 = Do nothing
-	 *	   1 = Scrubber Corrects errors found in normal operation
-	 * [ 5: 1] Reserved
-	 * [31: 6] DRAM Scrub Address 31-6
-	 */
-	PCI_ADDR(0, 0x18, 3, 0x5C), 0x0000003e, 0x00000000,
-	/* DRAM Scrub Address High Register
-	 * F3:0x60
-	 * [ 7: 0] DRAM Scrubb Address 39-32
-	 * [31: 8] Reserved
-	 */
-	PCI_ADDR(0, 0x18, 3, 0x60), 0xffffff00, 0x00000000,
-	};
-	int i;
-	int max;
-
-        if (!controller_present(ctrl)) {
-                printk(BIOS_DEBUG, "No memory controller present\r\n");
-                return;
-        }
-	printk(BIOS_SPEW, "setting up CPU 0x%x northbridge registers ", ctrl->node_id);
-	max = sizeof(register_values)/sizeof(register_values[0]);
-/*
-	for(i = 0; i < max; i += 3) {
-		struct device *dev;
-		unsigned where;
-		unsigned long reg;
-                printk(BIOS_DEBUG, "%08x <- %08x\r\n", register_values[i], register_values[i+2]);
-		dev = (register_values[i] & ~0xfff) - PCI_DEV(0, 0x18, 0) + ctrl->f0;
-		where = register_values[i] & 0xfff;
-		reg = pci_read_config32(dev, where);
-		reg &= register_values[i+1];
-		reg |= register_values[i+2];
-		pci_write_config32(dev, where, reg);
-	}
-*/
-	printk(BIOS_SPEW, "done.\r\n");
-}
-
-
-static void hw_enable_ecc(const struct mem_controller *ctrl)
-{
-	u32 dcl, nbcap;
-	nbcap = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
-	dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
-	dcl &= ~DCL_DimmEccEn;
-	if (nbcap & NBCAP_ECC) {
-		dcl |= DCL_DimmEccEn;
-	}
-	if (read_option(CMOS_VSTART_ECC_memory, CMOS_VLEN_ECC_memory, 1) == 0) {
-		dcl &= ~DCL_DimmEccEn;
-	}
-	pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
-	
-}
-
-static int is_dual_channel(const struct mem_controller *ctrl)
-{
-	u32 dcl;
-	dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
-	return dcl & DCL_128BitEn;
-}
-
-static int is_opteron(const struct mem_controller *ctrl)
-{
-	/* Test to see if I am an Opteron.  
-	 * FIXME Socket 939 based Athlon64 have dual channel capability,
-	 * too, so we need a better test for Opterons
-	 */
-#warning "FIXME: Implement a better test for Opterons"
-	u32 nbcap;
-	nbcap = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
-	return !!(nbcap & NBCAP_128Bit);
-}
-
-static int is_registered(const struct mem_controller *ctrl)
-{
-	/* Test to see if we are dealing with registered SDRAM.
-	 * If we are not registered we are unbuffered.
-	 * This function must be called after spd_handle_unbuffered_dimms.
-	 */
-	u32 dcl;
-	dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
-	return !(dcl & DCL_UnBufDimm);
-}
-
-struct dimm_size {
-	unsigned long side1;
-	unsigned long side2;
-	unsigned long rows;
-	unsigned long col;
-#if QRANK_DIMM_SUPPORT == 1
-	unsigned long rank;
-#endif
-};
-
-static struct dimm_size spd_get_dimm_size(unsigned device)
-{
-	/* Calculate the log base 2 size of a DIMM in bits */
-	struct dimm_size sz;
-	int value, low;
-	sz.side1 = 0;
-	sz.side2 = 0;
-	sz.rows = 0;
-	sz.col = 0;
-#if QRANK_DIMM_SUPPORT == 1
-	sz.rank = 0;
-#endif
-
-	/* Note it might be easier to use byte 31 here, it has the DIMM size as
-	 * a multiple of 4MB.  The way we do it now we can size both
-	 * sides of an assymetric dimm.
-	 */
-	value = spd_read_byte(device, 3);	/* rows */
-	if (value < 0) goto hw_err;
-	if ((value & 0xf) == 0) goto val_err;
-	sz.side1 += value & 0xf;
-	sz.rows = value & 0xf;
-
-	value = spd_read_byte(device, 4);	/* columns */
-	if (value < 0) goto hw_err;
-	if ((value & 0xf) == 0) goto val_err;
-	sz.side1 += value & 0xf;
-	sz.col = value & 0xf;
-
-	value = spd_read_byte(device, 17);	/* banks */
-	if (value < 0) goto hw_err;
-	if ((value & 0xff) == 0) goto val_err;
-	sz.side1 += log2(value & 0xff);
-
-	/* Get the module data width and convert it to a power of two */
-	value = spd_read_byte(device, 7);	/* (high byte) */
-	if (value < 0) goto hw_err;
-	value &= 0xff;
-	value <<= 8;
-	
-	low = spd_read_byte(device, 6);	/* (low byte) */
-	if (low < 0) goto hw_err;
-	value = value | (low & 0xff);
-	if ((value != 72) && (value != 64)) goto val_err;
-	sz.side1 += log2(value);
-
-	/* side 2 */
-	value = spd_read_byte(device, 5);	/* number of physical banks */
-	if (value < 0) goto hw_err;
-	if (value == 1) goto out;
-	if ((value != 2) && (value != 4 )) {
-		goto val_err;
-	}
-#if QRANK_DIMM_SUPPORT == 1
-	sz.rank = value;
-#endif
-
-	/* Start with the symmetrical case */
-	sz.side2 = sz.side1;
-
-	value = spd_read_byte(device, 3);	/* rows */
-	if (value < 0) goto hw_err;
-	if ((value & 0xf0) == 0) goto out;	/* If symmetrical we are done */
-	sz.side2 -= (value & 0x0f);		/* Subtract out rows on side 1 */
-	sz.side2 += ((value >> 4) & 0x0f);	/* Add in rows on side 2 */
-
-	value = spd_read_byte(device, 4);	/* columns */
-	if (value < 0) goto hw_err;
-	if ((value & 0xff) == 0) goto val_err;
-	sz.side2 -= (value & 0x0f);		/* Subtract out columns on side 1 */
-	sz.side2 += ((value >> 4) & 0x0f);	/* Add in columsn on side 2 */
-
-	goto out;
-
- val_err:
-	die("Bad SPD value\r\n");
-	/* If an hw_error occurs report that I have no memory */
-hw_err:
-	sz.side1 = 0;
-	sz.side2 = 0;
-	sz.rows = 0;
-	sz.col = 0;
-#if QRANK_DIMM_SUPPORT == 1
-	sz.rank = 0;
-#endif
- out:
-	return sz;
-}
-
-
-static void set_dimm_size(const struct mem_controller *ctrl, struct dimm_size sz, unsigned index)
-{
-	u32 base0, base1;
-	u32 dch;
-
-	if (sz.side1 != sz.side2) {
-		sz.side2 = 0;
-	}
-	
-	/* For each base register.
-	 * Place the dimm size in 32 MB quantities in the bits 31 - 21.
-	 * The initialize dimm size is in bits.
-	 * Set the base enable bit0.
-	 */
-	
-	base0 = base1 = 0;
-
-	/* Make certain side1 of the dimm is at least 32MB */
-	if (sz.side1 >= (25 +3)) {
-		base0 = (1 << ((sz.side1 - (25 + 3)) + 21)) | 1;
-	}
-	
-	/* Make certain side2 of the dimm is at least 32MB */
-	if (sz.side2 >= (25 + 3)) {
-		base1 = (1 << ((sz.side2 - (25 + 3)) + 21)) | 1;
-	}
-
-	/* Double the size if we are using dual channel memory */
-	if (is_dual_channel(ctrl)) {
-		base0 = (base0 << 1) | (base0 & 1);
-		base1 = (base1 << 1) | (base1 & 1);
-	}
-
-	/* Clear the reserved bits */
-	base0 &= ~0x001ffffe;
-	base1 &= ~0x001ffffe;
-
-	/* Set the appropriate DIMM base address register */
-	pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+0)<<2), base0);
-	pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+1)<<2), base1);
-#if QRANK_DIMM_SUPPORT == 1
-	if(sz.rank == 4) {
-		pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+4)<<2), base0);
-		pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+5)<<2), base1);
-	}
-#endif
-
-	/* Enable the memory clocks for this DIMM */
-	if (base0) {
-		dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
-		dch |= DCH_MEMCLK_EN0 << index;
-#if QRANK_DIMM_SUPPORT == 1
-		if(sz.rank == 4) {
-			dch |= DCH_MEMCLK_EN0 << (index + 2);
-		}
-#endif
-		pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
-	}
-}
-
-static void set_dimm_map(const struct mem_controller *ctrl, struct dimm_size sz, unsigned index)
-{
-	static const unsigned cs_map_aa[] = {
-		/* (row=12, col=8)(14, 12) ---> (0, 0) (2, 4) */
-		0, 1, 3, 6, 0,
-		0, 2, 4, 7, 9,
-		0, 0, 5, 8,10,
-	};
-
-	u32 map;
-	u32 dch;
-
-	map = pci_read_config32(ctrl->f2, DRAM_BANK_ADDR_MAP);
-	map &= ~(0xf << (index * 4));
-#if QRANK_DIMM_SUPPORT == 1
-        if(sz.rank == 4) {
-                map &= ~(0xf << ( (index + 2) * 4));
-        }
-#endif
-
-
-	/* Make certain side1 of the dimm is at least 32MB */
-	if (sz.side1 >= (25 +3)) {
-		if(is_cpu_pre_d0()) {
-			map |= (sz.side1 - (25 + 3)) << (index *4);
-#if QRANK_DIMM_SUPPORT == 1
-	                if(sz.rank == 4) {
-         	              map |= (sz.side1 - (25 + 3)) << ( (index + 2) * 4);
-               		}
-#endif
-		}
-		else {
-			map |= cs_map_aa[(sz.rows - 12) * 5 + (sz.col - 8) ] << (index*4);
-#if QRANK_DIMM_SUPPORT == 1
-		        if(sz.rank == 4) {
-                	       map |=  cs_map_aa[(sz.rows - 12) * 5 + (sz.col - 8) ] << ( (index + 2) * 4);
-               		}
-#endif
-		}
-	}
-
-	pci_write_config32(ctrl->f2, DRAM_BANK_ADDR_MAP, map);
-	
-}
-
-static long spd_set_ram_size(const struct mem_controller *ctrl, long dimm_mask)
-{
-	int i;
-	
-	for(i = 0; i < DIMM_SOCKETS; i++) {
-		struct dimm_size sz;
-		if (!(dimm_mask & (1 << i))) {
-			continue;
-		}
-		sz = spd_get_dimm_size(ctrl->channel0[i]);
-		if (sz.side1 == 0) {
-			return -1; /* Report SPD error */
-		}
-		set_dimm_size(ctrl, sz, i);
-		set_dimm_map (ctrl, sz, i);
-	}
-	return dimm_mask;
-}
-
-static void route_dram_accesses(const struct mem_controller *ctrl,
-	unsigned long base_k, unsigned long limit_k)
-{
-	/* Route the addresses to the controller node */
-	unsigned node_id;
-	unsigned limit;
-	unsigned base;
-	unsigned index;
-	unsigned limit_reg, base_reg;
-	struct device *device;
-
-	node_id = ctrl->node_id;
-	index = (node_id << 3);
-	limit = (limit_k << 2);
-	limit &= 0xffff0000;
-	limit -= 0x00010000;
-	limit |= ( 0 << 8) | (node_id << 0);
-	base = (base_k << 2);
-	base &= 0xffff0000;
-	base |= (0 << 8) | (1<<1) | (1<<0);
-
-	limit_reg = 0x44 + index;
-	base_reg = 0x40 + index;
-	for(device = PCI_DEV(0, 0x18, 1); device <= PCI_DEV(0, 0x1f, 1); device += PCI_DEV(0, 1, 0)) {
-		pci_write_config32(device, limit_reg, limit);
-		pci_write_config32(device, base_reg, base);
-	}
-}
-
-static void set_top_mem(unsigned tom_k, unsigned hole_startk)
-{
-	/* Error if I don't have memory */
-	if (!tom_k) {
-		die("No memory?");
-	}
-
-	/* Report the amount of memory. */
-	print_spew("RAM: 0x");
-	print_spew_hex32(tom_k);
-	print_spew(" KB\r\n");
-
-	/* Now set top of memory */
-	msr_t msr;
-	if(tom_k > (4*1024*1024)) {
-		msr.lo = (tom_k & 0x003fffff) << 10;
-		msr.hi = (tom_k & 0xffc00000) >> 22;
-		wrmsr(TOP_MEM2, msr);
-	}
-
-	/* Leave a 64M hole between TOP_MEM and TOP_MEM2
-	 * so I can see my rom chip and other I/O devices.
-	 */
-	if (tom_k >= 0x003f0000) {
-#if HW_MEM_HOLE_SIZEK != 0
-                if(hole_startk != 0) {
-                        tom_k = hole_startk;
-                } else
-#endif
-                tom_k = 0x3f0000;
-	}
-	msr.lo = (tom_k & 0x003fffff) << 10;
-	msr.hi = (tom_k & 0xffc00000) >> 22;
-	wrmsr(TOP_MEM, msr);
-}
-
-static unsigned long interleave_chip_selects(const struct mem_controller *ctrl)
-{
-	/* 35 - 25 */
-	static const u8 csbase_low_shift[] = { 
-	/* 32MB */	(13 - 4),
-	/* 64MB */	(14 - 4),
-	/* 128MB */	(14 - 4), 
-	/* 256MB */	(15 - 4),
-	/* 512MB */	(15 - 4),
-	/* 1GB */	(16 - 4),
-	/* 2GB */	(16 - 4), 
-	};
-
-        static const u8 csbase_low_d0_shift[] = {
-        /* 32MB */      (13 - 4),
-        /* 64MB */      (14 - 4),
-        /* 128MB */     (14 - 4),
-	/* 128MB */     (15 - 4),
-        /* 256MB */     (15 - 4),
-        /* 512MB */     (15 - 4),
-        /* 256MB */     (16 - 4),
-        /* 512MB */     (16 - 4),
-        /* 1GB */       (16 - 4),
-	/* 1GB */       (17 - 4),
-        /* 2GB */       (17 - 4),
-        };
-
-	/* cs_base_high is not changed */
-
-	u32 csbase_inc;
-	int chip_selects, index;
-	int bits;
-	unsigned common_size;
-	unsigned common_cs_mode;
-	u32 csbase, csmask;
-
-	/* See if all of the memory chip selects are the same size
-	 * and if so count them.
-	 */
-	chip_selects = 0;
-	common_size = 0;
-	common_cs_mode = 0;
-	for(index = 0; index < 8; index++) {
-		unsigned size;
-		unsigned cs_mode;
-		u32 value;
-		
-		value = pci_read_config32(ctrl->f2, DRAM_CSBASE + (index << 2));
-		
-		/* Is it enabled? */
-		if (!(value & 1)) {
-			continue;
-		}
-		chip_selects++;
-		size = value >> 21;
-		if (common_size == 0) {
-			common_size = size;
-		}
-		/* The size differed fail */
-		if (common_size != size) {
-			return 0;
-		}
-
-		value = pci_read_config32(ctrl->f2, DRAM_BANK_ADDR_MAP);
-                cs_mode =( value >> ((index>>1)*4)) & 0xf;
-                if(cs_mode == 0 ) continue;
-                if(common_cs_mode == 0) {
-                	common_cs_mode = cs_mode;
-                }
-                /* The size differed fail */
-                if(common_cs_mode != cs_mode) {
-                        return 0;
-                }
-	}
-
-	/* Chip selects can only be interleaved when there is
-	 * more than one and their is a power of two of them.
-	 */
-	bits = log2(chip_selects);
-	if (((1 << bits) != chip_selects) || (bits < 1) || (bits > 3)) {
-		return 0;
-	}
-
-	/* Find the bits of csbase that we need to interleave on */
-	if(is_cpu_pre_d0()){
-		csbase_inc = 1 << csbase_low_shift[common_cs_mode];
-		if(is_dual_channel(ctrl)) {
-                /* Also we run out of address mask bits if we try and interleave 8 4GB dimms */
-	                if ((bits == 3) && (common_size == (1 << (32 - 3)))) {
-//     		                printk(BIOS_DEBUG, "8 4GB chip selects cannot be interleaved\r\n");
-	                        return 0;
-                	}  
-			csbase_inc <<=1;
-		}
-	}
-	else {
-		csbase_inc = 1 << csbase_low_d0_shift[common_cs_mode];
-		if(is_dual_channel(ctrl)) {
-	                if( (bits==3) && (common_cs_mode > 8)) {
-//        	                printk(BIOS_DEBUG, "8 cs_mode>8 chip selects cannot be interleaved\r\n");
-        	                return 0;
-			}
-			csbase_inc <<=1;
-                }   
-	}
-
-	/* Compute the initial values for csbase and csbask. 
-	 * In csbase just set the enable bit and the base to zero.
-	 * In csmask set the mask bits for the size and page level interleave.
-	 */
-	csbase = 0 | 1;
-	csmask = (((common_size  << bits) - 1) << 21);
-	csmask |= 0xfe00 & ~((csbase_inc << bits) - csbase_inc);
-	for(index = 0; index < 8; index++) {
-		u32 value;
-
-		value = pci_read_config32(ctrl->f2, DRAM_CSBASE + (index << 2));
-		/* Is it enabled? */
-		if (!(value & 1)) {
-			continue;
-		}
-		pci_write_config32(ctrl->f2, DRAM_CSBASE + (index << 2), csbase);
-		pci_write_config32(ctrl->f2, DRAM_CSMASK + (index << 2), csmask);
-		csbase += csbase_inc;
-	}
-	
-	printk(BIOS_SPEW, "Interleaved\n");
-
-	/* Return the memory size in K */
-	return common_size << (15 + bits);
-}
-
-static unsigned long order_chip_selects(const struct mem_controller *ctrl)
-{
-	unsigned long tom;
-
-	/* Remember which registers we have used in the high 8 bits of tom */
-	tom = 0;
-	for(;;) {
-		/* Find the largest remaining canidate */
-		unsigned index, canidate;
-		u32 csbase, csmask;
-		unsigned size;
-		csbase = 0;
-		canidate = 0;
-		for(index = 0; index < 8; index++) {
-			u32 value;
-			value = pci_read_config32(ctrl->f2, DRAM_CSBASE + (index << 2));
-
-			/* Is it enabled? */
-			if (!(value & 1)) {
-				continue;
-			}
-			
-			/* Is it greater? */
-			if (value <= csbase) {
-				continue;
-			}
-			
-			/* Has it already been selected */
-			if (tom & (1 << (index + 24))) {
-				continue;
-			}
-			/* I have a new canidate */
-			csbase = value;
-			canidate = index;
-		}
-		/* See if I have found a new canidate */
-		if (csbase == 0) {
-			break;
-		}
-
-		/* Remember the dimm size */
-		size = csbase >> 21;
-
-		/* Remember I have used this register */
-		tom |= (1 << (canidate + 24));
-
-		/* Recompute the cs base register value */
-		csbase = (tom << 21) | 1;
-
-		/* Increment the top of memory */
-		tom += size;
-
-		/* Compute the memory mask */
-		csmask = ((size -1) << 21);
-		csmask |= 0xfe00;		/* For now don't optimize */
-
-		/* Write the new base register */
-		pci_write_config32(ctrl->f2, DRAM_CSBASE + (canidate << 2), csbase);
-		/* Write the new mask register */
-		pci_write_config32(ctrl->f2, DRAM_CSMASK + (canidate << 2), csmask);
-		
-	}
-	/* Return the memory size in K */
-	return (tom & ~0xff000000) << 15;
-}
-
-unsigned long memory_end_k(const struct mem_controller *ctrl, int max_node_id)
-{
-	unsigned node_id;
-	unsigned end_k;
-	/* Find the last memory address used */
-	end_k = 0;
-	for(node_id = 0; node_id < max_node_id; node_id++) {
-		u32 limit, base;
-		unsigned index;
-		index = node_id << 3;
-		base = pci_read_config32(ctrl->f1, 0x40 + index);
-		/* Only look at the limit if the base is enabled */
-		if ((base & 3) == 3) {
-			limit = pci_read_config32(ctrl->f1, 0x44 + index);
-			end_k = ((limit + 0x00010000) & 0xffff0000) >> 2;
-		}
-	}
-	return end_k;
-}
-
-static void order_dimms(const struct mem_controller *ctrl)
-{
-	unsigned long tom_k, base_k;
-
-	if (read_option(CMOS_VSTART_interleave_chip_selects, CMOS_VLEN_interleave_chip_selects, 1) != 0) {
-		tom_k = interleave_chip_selects(ctrl);
-	} else {
-		printk(BIOS_DEBUG, "Interleaving disabled\r\n");
-		tom_k = 0;
-	}
-	if (!tom_k) {
-		tom_k = order_chip_selects(ctrl);
-	}
-	/* Compute the memory base address */
-	base_k = memory_end_k(ctrl, ctrl->node_id);
-	tom_k += base_k;
-	route_dram_accesses(ctrl, base_k, tom_k);
-	set_top_mem(tom_k, 0);
-}
-
-static long disable_dimm(const struct mem_controller *ctrl, unsigned index, long dimm_mask)
-{
-	printk(BIOS_DEBUG, "disabling dimm 0x%x\n", index); 
-	pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+0)<<2), 0);
-	pci_write_config32(ctrl->f2, DRAM_CSBASE + (((index << 1)+1)<<2), 0);
-	dimm_mask &= ~(1 << index);
-	return dimm_mask;
-}
-
-static long spd_handle_unbuffered_dimms(const struct mem_controller *ctrl, long dimm_mask)
-{
-	int i;
-	int registered;
-	int unbuffered;
-	int has_dualch = is_opteron(ctrl);
-	u32 dcl;
-	unbuffered = 0;
-	registered = 0;
-	for(i = 0; (i < DIMM_SOCKETS); i++) {
-		int value;
-		if (!(dimm_mask & (1 << i))) {
-			continue;
-		}
-		value = spd_read_byte(ctrl->channel0[i], 21);
-		if (value < 0) {
-			return -1;
-		}
-		/* Registered dimm ? */
-		if (value & (1 << 1)) {
-			registered = 1;
-		} 
-		/* Otherwise it must be an unbuffered dimm */
-		else {
-			unbuffered = 1;
-		}
-	}
-	if (unbuffered && registered) {
-		die("Mixed buffered and registered dimms not supported");
-	}
-
-	dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
-	dcl &= ~DCL_UnBufDimm;
-	if (unbuffered) {
-		if ((has_dualch) && (!is_cpu_pre_d0())) {
-			dcl |= DCL_UnBufDimm; /* set DCL_DualDIMMen too? */
-			
-			/* set DCL_En2T if you have non-equal DDR mem types! */
-			
-			if ((cpuid_eax(1) & 0x30) == 0x30) {
-				/* CS[7:4] is copy of CS[3:0], should be set for 939 socket */
-				dcl |= DCL_UpperCSMap;
-			}
-		} else {
-			dcl |= DCL_UnBufDimm;
-		}
-	}
-	pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
-	if (is_registered(ctrl)) {
-		printk(BIOS_DEBUG, "Registered\r\n");
-	} else {
-		printk(BIOS_DEBUG, "Unbuffered\r\n");
-	}
-	return dimm_mask;
-}
-
-static unsigned int spd_detect_dimms(const struct mem_controller *ctrl)
-{
-	unsigned dimm_mask;
-	int i;
-	dimm_mask = 0;
-	for(i = 0; i < DIMM_SOCKETS; i++) {
-		int byte;
-		unsigned device;
-		device = ctrl->channel0[i];
-		if (device) {
-			byte = spd_read_byte(ctrl->channel0[i], 2);  /* Type */
-			if (byte == 7) {
-				dimm_mask |= (1 << i);
-			}
-		}
-		device = ctrl->channel1[i];
-		if (device) {
-			byte = spd_read_byte(ctrl->channel1[i], 2);
-			if (byte == 7) {
-				dimm_mask |= (1 << (i + DIMM_SOCKETS));
-			}
-		}
-	}
-	return dimm_mask;
-}
-
-static long spd_enable_2channels(const struct mem_controller *ctrl, long dimm_mask)
-{
-	int i;
-	u32 nbcap;
-	/* SPD addresses to verify are identical */
-	static const u8 addresses[] = {
-		2,	/* Type should be DDR SDRAM */
-		3,	/* *Row addresses */
-		4,	/* *Column addresses */
-		5,	/* *Physical Banks */
-		6,	/* *Module Data Width low */
-		7,	/* *Module Data Width high */
-		9,	/* *Cycle time at highest CAS Latency CL=X */
-		11,	/* *SDRAM Type */
-		13,	/* *SDRAM Width */
-		17,	/* *Logical Banks */
-		18,	/* *Supported CAS Latencies */
-		21,	/* *SDRAM Module Attributes */
-		23,	/* *Cycle time at CAS Latnecy (CLX - 0.5) */
-		26,	/* *Cycle time at CAS Latnecy (CLX - 1.0) */
-		27,	/* *tRP Row precharge time */
-		28,	/* *Minimum Row Active to Row Active Delay (tRRD) */
-		29,	/* *tRCD RAS to CAS */
-		30,	/* *tRAS Activate to Precharge */
-		41,	/* *Minimum Active to Active/Auto Refresh Time(Trc) */
-		42,	/* *Minimum Auto Refresh Command Time(Trfc) */
-	};
-	/* If the dimms are not in pairs do not do dual channels */
-	if ((dimm_mask & ((1 << DIMM_SOCKETS) - 1)) !=
-		((dimm_mask >> DIMM_SOCKETS) & ((1 << DIMM_SOCKETS) - 1))) { 
-		goto single_channel;
-	}
-	/* If the cpu is not capable of doing dual channels don't do dual channels */
-	nbcap = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
-	if (!(nbcap & NBCAP_128Bit)) {
-		goto single_channel;
-	}
-	for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
-		unsigned device0, device1;
-		int value0, value1;
-		int j;
-		/* If I don't have a dimm skip this one */
-		if (!(dimm_mask & (1 << i))) {
-			continue;
-		}
-		device0 = ctrl->channel0[i];
-		device1 = ctrl->channel1[i];
-		for(j = 0; j < sizeof(addresses)/sizeof(addresses[0]); j++) {
-			unsigned addr;
-			addr = addresses[j];
-			value0 = spd_read_byte(device0, addr);
-			if (value0 < 0) {
-				return -1;
-			}
-			value1 = spd_read_byte(device1, addr);
-			if (value1 < 0) {
-				return -1;
-			}
-			if (value0 != value1) {
-				goto single_channel;
-			}
-		}
-	}
-	printk(BIOS_SPEW, "Enabling dual channel memory\r\n");
-	u32 dcl;
-	dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
-	dcl &= ~DCL_32ByteEn;
-	dcl |= DCL_128BitEn;
-	pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
-	return dimm_mask;
- single_channel:
-	dimm_mask &= ~((1 << (DIMM_SOCKETS *2)) - (1 << DIMM_SOCKETS));
-	return dimm_mask;
-}
-
-struct mem_param {
-	u8 cycle_time;
-	u8 divisor; /* In 1/2 ns increments */
-	u8 tRC;
-	u8 tRFC;
-	u32 dch_memclk;
-	u16 dch_tref4k, dch_tref8k;
-	u8	 dtl_twr;
-	u8	 dtl_twtr;
-	u8  dtl_trwt[3][3]; /* first index is CAS_LAT 2/2.5/3 and 128/registered64/64 */
- 	u8	 rdpreamble[4]; /* 0 is for registered, 1 for 1-2 DIMMS, 2 and 3 for 3 or 4 unreg dimm slots */
-	char name[9];
-};
-
-static const struct mem_param *get_mem_param(unsigned min_cycle_time)
-{
-	static const struct mem_param speed[] = {
-		{
-			.name	    = "100Mhz\r\n",
-			.cycle_time = 0xa0,
-			.divisor    = (10 <<1),
-			.tRC	    = 0x46,
-			.tRFC	    = 0x50,
-			.dch_memclk = DCH_MEMCLK_100MHZ << DCH_MEMCLK_SHIFT,
-			.dch_tref4k = DTH_TREF_100MHZ_4K,
-			.dch_tref8k = DTH_TREF_100MHZ_8K,
-			.dtl_twr    = 2,
-			.dtl_twtr   = 1,
-			.dtl_trwt   = { { 2, 2, 3 }, { 3, 3, 4 }, { 3, 3, 4 }},
-			.rdpreamble = { ((9 << 1) + 0), ((9 << 1) + 0), ((9 << 1) + 0), ((9 << 1) + 0) }
-		},
-		{
-			.name	    = "133Mhz\r\n",
-			.cycle_time = 0x75,
-			.divisor    = (7<<1)+1,
-			.tRC	    = 0x41,
-			.tRFC	    = 0x4B,
-			.dch_memclk = DCH_MEMCLK_133MHZ << DCH_MEMCLK_SHIFT,
-			.dch_tref4k = DTH_TREF_133MHZ_4K,
-			.dch_tref8k = DTH_TREF_133MHZ_8K,
-			.dtl_twr    = 2,
-			.dtl_twtr   = 1,
-			.dtl_trwt   = { { 2, 2, 3 }, { 3, 3, 4 }, { 3, 3, 4 }},
-			.rdpreamble = { ((8 << 1) + 0), ((7 << 1) + 0), ((7 << 1) + 1), ((7 << 1) + 0) }
-		},
-		{
-			.name	    = "166Mhz\r\n",
-			.cycle_time = 0x60,
-			.divisor    = (6<<1),
-			.tRC	    = 0x3C,
-			.tRFC	    = 0x48,
-			.dch_memclk = DCH_MEMCLK_166MHZ << DCH_MEMCLK_SHIFT,
-			.dch_tref4k = DTH_TREF_166MHZ_4K,
-			.dch_tref8k = DTH_TREF_166MHZ_8K,
-			.dtl_twr    = 3,
-			.dtl_twtr   = 1,
-			.dtl_trwt   = { { 3, 2, 3 }, { 3, 3, 4 }, { 4, 3, 4 }},
-			.rdpreamble = { ((7 << 1) + 1), ((6 << 1) + 0), ((6 << 1) + 1), ((6 << 1) + 0) }
-		},
-		{
-			.name	    = "200Mhz\r\n",
-			.cycle_time = 0x50,
-			.divisor    = (5<<1),
-			.tRC	    = 0x37,
-			.tRFC	    = 0x46,
-			.dch_memclk = DCH_MEMCLK_200MHZ << DCH_MEMCLK_SHIFT,
-			.dch_tref4k = DTH_TREF_200MHZ_4K,
-			.dch_tref8k = DTH_TREF_200MHZ_8K,
-			.dtl_twr    = 3,
-			.dtl_twtr   = 2,
-			.dtl_trwt   = { { 0, 2, 3 }, { 3, 3, 4 }, { 3, 3, 4 }},
-			.rdpreamble = { ((7 << 1) + 0), ((5 << 1) + 0), ((5 << 1) + 1), ((5 << 1) + 1) }
-		},
-		{
-			.cycle_time = 0x00,
-		},
-	};
-	const struct mem_param *param;
-	for(param = &speed[0]; param->cycle_time ; param++) {
-		if (min_cycle_time > (param+1)->cycle_time) {
-			break;
-		}
-	}
-	if (!param->cycle_time) {
-		die("min_cycle_time to low");
-	}
-	print_spew(param->name);
-#ifdef DRAM_MIN_CYCLE_TIME
-	printk(BIOS_DEBUG, param->name);
-#endif
-	return param;
-}
-
-struct spd_set_memclk_result {
-	const struct mem_param *param;
-	long dimm_mask;
-};
-static struct spd_set_memclk_result spd_set_memclk(const struct mem_controller *ctrl, long dimm_mask)
-{
-	/* Compute the minimum cycle time for these dimms */
-	struct spd_set_memclk_result result;
-	unsigned min_cycle_time, min_latency, bios_cycle_time;
-	int i;
-	u32 value;
-
-	static const u8 latency_indicies[] = { 26, 23, 9 };
-	static const unsigned char min_cycle_times[] = {
-		[NBCAP_MEMCLK_200MHZ] = 0x50, /* 5ns */
-		[NBCAP_MEMCLK_166MHZ] = 0x60, /* 6ns */
-		[NBCAP_MEMCLK_133MHZ] = 0x75, /* 7.5ns */
-		[NBCAP_MEMCLK_100MHZ] = 0xa0, /* 10ns */
-	};
-
-	value = pci_read_config32(ctrl->f3, NORTHBRIDGE_CAP);
-
-	min_cycle_time = min_cycle_times[(value >> NBCAP_MEMCLK_SHIFT) & NBCAP_MEMCLK_MASK];
-	bios_cycle_time = min_cycle_times[
-		read_option(CMOS_VSTART_max_mem_clock, CMOS_VLEN_max_mem_clock, 0)];
-	if (bios_cycle_time > min_cycle_time) {
-		min_cycle_time = bios_cycle_time;
-	}
-	min_latency = 2;
-
-	/* Compute the least latency with the fastest clock supported
-	 * by both the memory controller and the dimms.
-	 */
-	for(i = 0; i < DIMM_SOCKETS; i++) {
-		int new_cycle_time, new_latency;
-		int index;
-		int latencies;
-		int latency;
-
-		if (!(dimm_mask & (1 << i))) {
-			continue;
-		}
-
-		/* First find the supported CAS latencies
-		 * Byte 18 for DDR SDRAM is interpreted:
-		 * bit 0 == CAS Latency = 1.0
-		 * bit 1 == CAS Latency = 1.5
-		 * bit 2 == CAS Latency = 2.0
-		 * bit 3 == CAS Latency = 2.5
-		 * bit 4 == CAS Latency = 3.0
-		 * bit 5 == CAS Latency = 3.5
-		 * bit 6 == TBD
-		 * bit 7 == TBD
-		 */
-		new_cycle_time = 0xa0;
-		new_latency = 5;
-
-		latencies = spd_read_byte(ctrl->channel0[i], 18);
-		if (latencies <= 0) continue;
-
-		/* Compute the lowest cas latency supported */
-		latency = log2(latencies) -2;
-
-		/* Loop through and find a fast clock with a low latency */
-		for(index = 0; index < 3; index++, latency++) {
-			int value;
-			if ((latency < 2) || (latency > 4) ||
-				(!(latencies & (1 << latency)))) {
-				continue;
-			}
-			value = spd_read_byte(ctrl->channel0[i], latency_indicies[index]);
-			if (value < 0) {
-				goto hw_error;
-			}
-
-			/* Only increase the latency if we decreas the clock */
-			if ((value >= min_cycle_time) && (value < new_cycle_time)) {
-				new_cycle_time = value;
-				new_latency = latency;
-			}
-		}
-		if (new_latency > 4){
-			continue;
-		}
-		/* Does min_latency need to be increased? */
-		if (new_cycle_time > min_cycle_time) {
-			min_cycle_time = new_cycle_time;
-		}
-		/* Does min_cycle_time need to be increased? */
-		if (new_latency > min_latency) {
-			min_latency = new_latency;
-		}
-	}
-	/* Make a second pass through the dimms and disable
-	 * any that cannot support the selected memclk and cas latency.
-	 */
-	
-	for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
-		int latencies;
-		int latency;
-		int index;
-		int value;
-		if (!(dimm_mask & (1 << i))) {
-			continue;
-		}
-		latencies = spd_read_byte(ctrl->channel0[i], 18);
-		if (latencies < 0) goto hw_error;
-		if (latencies == 0) {
-			goto dimm_err;
-		}
-
-		/* Compute the lowest cas latency supported */
-		latency = log2(latencies) -2;
-
-		/* Walk through searching for the selected latency */
-		for(index = 0; index < 3; index++, latency++) {
-			if (!(latencies & (1 << latency))) {
-				continue;
-			}
-			if (latency == min_latency)
-				break;
-		}
-		/* If I can't find the latency or my index is bad error */
-		if ((latency != min_latency) || (index >= 3)) {
-			goto dimm_err;
-		}
-		
-		/* Read the min_cycle_time for this latency */
-		value = spd_read_byte(ctrl->channel0[i], latency_indicies[index]);
-		if (value < 0) goto hw_error;
-		
-		/* All is good if the selected clock speed 
-		 * is what I need or slower.
-		 */
-		if (value <= min_cycle_time) {
-			continue;
-		}
-		/* Otherwise I have an error, disable the dimm */
-	dimm_err:
-		dimm_mask = disable_dimm(ctrl, i, dimm_mask);
-	}
-#if 0
-//down speed for full load 4 rank support
-#if QRANK_DIMM_SUPPORT
-	if(dimm_mask == (3|(3<<DIMM_SOCKETS)) ) {
-		int ranks = 4;
-	        for(i = 0; (i < 4) && (ctrl->channel0[i]); i++) {
-			int val;
-                	if (!(dimm_mask & (1 << i))) {
-                        	continue;
-	                }
-        	        val = spd_read_byte(ctrl->channel0[i], 5);
-			if(val!=ranks) {
-				ranks = val;
-				break;
-			}
-		}
-		if(ranks==4) {
-			if(min_cycle_time <= 0x50 ) {
-				min_cycle_time = 0x60;
-			}
-		}
-		
-	}
-#endif
-#endif
-	/* Now that I know the minimum cycle time lookup the memory parameters */
-	result.param = get_mem_param(min_cycle_time);
-
-	/* Update DRAM Config High with our selected memory speed */
-	value = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
-	value &= ~(DCH_MEMCLK_MASK << DCH_MEMCLK_SHIFT);
-#if 0
-	/* Improves DQS centering by correcting for case when core speed multiplier and MEMCLK speed 
-	 * result in odd clock divisor, by selecting the next lowest memory speed, required only at DDR400 
-	 * and higher speeds with certain DIMM loadings ---- cheating???*/
-	if(!is_cpu_pre_e0()) {
-		if(min_cycle_time==0x50) {
-			value |= 1<<31;
-		}
-	}
-#endif
-
-	value |= result.param->dch_memclk;
-	pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, value);
-
-	static const unsigned latencies[] = { DTL_CL_2, DTL_CL_2_5, DTL_CL_3 };
-	/* Update DRAM Timing Low with our selected cas latency */
-	value = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	value &= ~(DTL_TCL_MASK << DTL_TCL_SHIFT);
-	value |= latencies[min_latency - 2] << DTL_TCL_SHIFT;
-	pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, value);
-	
-	result.dimm_mask = dimm_mask;
-	return result;
- hw_error:
-	result.param = (const struct mem_param *)0;
-	result.dimm_mask = -1;
-	return result;
-}
-
-
-static int update_dimm_Trc(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	unsigned clocks, old_clocks;
-	u32 dtl;
-	int value;
-	value = spd_read_byte(ctrl->channel0[i], 41);
-	if (value < 0) return -1;
-	if ((value == 0) || (value == 0xff)) {
-		value = param->tRC;
-	}
-	clocks = ((value << 1) + param->divisor - 1)/param->divisor;
-	if (clocks < DTL_TRC_MIN) {
-		clocks = DTL_TRC_MIN;
-	}
-	if (clocks > DTL_TRC_MAX) {
-		return 0;
-	}
-
-	dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	old_clocks = ((dtl >> DTL_TRC_SHIFT) & DTL_TRC_MASK) + DTL_TRC_BASE;
-	if (old_clocks > clocks) {
-		clocks = old_clocks;
-	}
-	dtl &= ~(DTL_TRC_MASK << DTL_TRC_SHIFT);
-	dtl |=	((clocks - DTL_TRC_BASE) << DTL_TRC_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
-	return 1;
-}
-
-static int update_dimm_Trfc(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	unsigned clocks, old_clocks;
-	u32 dtl;
-	int value;
-	value = spd_read_byte(ctrl->channel0[i], 42);
-	if (value < 0) return -1;
-	if ((value == 0) || (value == 0xff)) {
-		value = param->tRFC;
-	}
-	clocks = ((value << 1) + param->divisor - 1)/param->divisor;
-	if (clocks < DTL_TRFC_MIN) {
-		clocks = DTL_TRFC_MIN;
-	}
-	if (clocks > DTL_TRFC_MAX) {
-		return 0;
-	}
-	dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	old_clocks = ((dtl >> DTL_TRFC_SHIFT) & DTL_TRFC_MASK) + DTL_TRFC_BASE;
-	if (old_clocks > clocks) {
-		clocks = old_clocks;
-	}
-	dtl &= ~(DTL_TRFC_MASK << DTL_TRFC_SHIFT);
-	dtl |= ((clocks - DTL_TRFC_BASE) << DTL_TRFC_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
-	return 1;
-}
-
-
-static int update_dimm_Trcd(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	unsigned clocks, old_clocks;
-	u32 dtl;
-	int value;
-	value = spd_read_byte(ctrl->channel0[i], 29);
-	if (value < 0) return -1;
-	clocks = (value + (param->divisor << 1) -1)/(param->divisor << 1);
-	if (clocks < DTL_TRCD_MIN) {
-		clocks = DTL_TRCD_MIN;
-	}
-	if (clocks > DTL_TRCD_MAX) {
-		return 0;
-	}
-	dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	old_clocks = ((dtl >> DTL_TRCD_SHIFT) & DTL_TRCD_MASK) + DTL_TRCD_BASE;
-	if (old_clocks > clocks) {
-		clocks = old_clocks;
-	}
-	dtl &= ~(DTL_TRCD_MASK << DTL_TRCD_SHIFT);
-	dtl |= ((clocks - DTL_TRCD_BASE) << DTL_TRCD_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
-	return 1;
-}
-
-static int update_dimm_Trrd(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	unsigned clocks, old_clocks;
-	u32 dtl;
-	int value;
-	value = spd_read_byte(ctrl->channel0[i], 28);
-	if (value < 0) return -1;
-	clocks = (value + (param->divisor << 1) -1)/(param->divisor << 1);
-	if (clocks < DTL_TRRD_MIN) {
-		clocks = DTL_TRRD_MIN;
-	}
-	if (clocks > DTL_TRRD_MAX) {
-		return 0;
-	}
-	dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	old_clocks = ((dtl >> DTL_TRRD_SHIFT) & DTL_TRRD_MASK) + DTL_TRRD_BASE;
-	if (old_clocks > clocks) {
-		clocks = old_clocks;
-	}
-	dtl &= ~(DTL_TRRD_MASK << DTL_TRRD_SHIFT);
-	dtl |= ((clocks - DTL_TRRD_BASE) << DTL_TRRD_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
-	return 1;
-}
-
-static int update_dimm_Tras(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	unsigned clocks, old_clocks;
-	u32 dtl;
-	int value;
-	value = spd_read_byte(ctrl->channel0[i], 30);
-	if (value < 0) return -1;
-	clocks = ((value << 1) + param->divisor - 1)/param->divisor;
-	if (clocks < DTL_TRAS_MIN) {
-		clocks = DTL_TRAS_MIN;
-	}
-	if (clocks > DTL_TRAS_MAX) {
-		return 0;
-	}
-	dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	old_clocks = ((dtl >> DTL_TRAS_SHIFT) & DTL_TRAS_MASK) + DTL_TRAS_BASE;
-	if (old_clocks > clocks) {
-		clocks = old_clocks;
-	}
-	dtl &= ~(DTL_TRAS_MASK << DTL_TRAS_SHIFT);
-	dtl |= ((clocks - DTL_TRAS_BASE) << DTL_TRAS_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
-	return 1;
-}
-
-static int update_dimm_Trp(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	unsigned clocks, old_clocks;
-	u32 dtl;
-	int value;
-	value = spd_read_byte(ctrl->channel0[i], 27);
-	if (value < 0) return -1;
-	clocks = (value + (param->divisor << 1) - 1)/(param->divisor << 1);
-	if (clocks < DTL_TRP_MIN) {
-		clocks = DTL_TRP_MIN;
-	}
-	if (clocks > DTL_TRP_MAX) {
-		return 0;
-	}
-	dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	old_clocks = ((dtl >> DTL_TRP_SHIFT) & DTL_TRP_MASK) + DTL_TRP_BASE;
-	if (old_clocks > clocks) {
-		clocks = old_clocks;
-	}
-	dtl &= ~(DTL_TRP_MASK << DTL_TRP_SHIFT);
-	dtl |= ((clocks - DTL_TRP_BASE) << DTL_TRP_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
-	return 1;
-}
-
-static void set_Twr(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	u32 dtl;
-	dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	dtl &= ~(DTL_TWR_MASK << DTL_TWR_SHIFT);
-	dtl |= (param->dtl_twr - DTL_TWR_BASE) << DTL_TWR_SHIFT;
-	pci_write_config32(ctrl->f2, DRAM_TIMING_LOW, dtl);
-}
-
-
-static void init_Tref(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	u32 dth;
-	dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
-	dth &= ~(DTH_TREF_MASK << DTH_TREF_SHIFT);
-	dth |= (param->dch_tref4k << DTH_TREF_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
-}
-
-static int update_dimm_Tref(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	u32 dth;
-	int value;
-	unsigned tref, old_tref;
-	value = spd_read_byte(ctrl->channel0[i], 3);
-	if (value < 0) return -1;
-	value &= 0xf;
-
-	tref = param->dch_tref8k;
-	if (value == 12) {
-		tref = param->dch_tref4k;
-	}
-
-	dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
-	old_tref = (dth >> DTH_TREF_SHIFT) & DTH_TREF_MASK;
-	if ((value == 12) && (old_tref == param->dch_tref4k)) {
-		tref = param->dch_tref4k;
-	} else {
-		tref = param->dch_tref8k;
-	}
-	dth &= ~(DTH_TREF_MASK << DTH_TREF_SHIFT);
-	dth |= (tref << DTH_TREF_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
-	return 1;
-}
-
-
-static int update_dimm_x4(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	u32 dcl;
-	int value;
-#if QRANK_DIMM_SUPPORT == 1
-	int rank;
-#endif
-	int dimm;
-	value = spd_read_byte(ctrl->channel0[i], 13);
-	if (value < 0) {
-		return -1;
-	}
-
-#if QRANK_DIMM_SUPPORT == 1
-	rank = spd_read_byte(ctrl->channel0[i], 5);       /* number of physical banks */
-	if (rank < 0) {
-		return -1;	
-	}
-#endif
-
-	dimm = 1<<(DCL_x4DIMM_SHIFT+i);
-#if QRANK_DIMM_SUPPORT == 1
-	if(rank==4) {
-		dimm |= 1<<(DCL_x4DIMM_SHIFT+i+2);
-	}
-#endif
-	dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
-	dcl &= ~dimm;
-	if (value == 4) {
-		dcl |= dimm;
-	}
-	pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
-	return 1;
-}
-
-static int update_dimm_ecc(const struct mem_controller *ctrl, const struct mem_param *param, int i)
-{
-	u32 dcl;
-	int value;
-	value = spd_read_byte(ctrl->channel0[i], 11);
-	if (value < 0) {
-		return -1;
-	}
-	if (value != 2) {
-		dcl = pci_read_config32(ctrl->f2, DRAM_CONFIG_LOW);
-		dcl &= ~DCL_DimmEccEn;
-		pci_write_config32(ctrl->f2, DRAM_CONFIG_LOW, dcl);
-	}
-	return 1;
-}
-
-static int count_dimms(const struct mem_controller *ctrl)
-{
-	int dimms;
-	unsigned index;
-	dimms = 0;
-	for(index = 0; index < 8; index += 2) {
-		u32 csbase;
-		csbase = pci_read_config32(ctrl->f2, (DRAM_CSBASE + (index << 2)));
-		if (csbase & 1) {
-			dimms += 1;
-		}
-	}
-	return dimms;
-}
-
-static void set_Twtr(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	u32 dth;
-
-	dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
-	dth &= ~(DTH_TWTR_MASK << DTH_TWTR_SHIFT);
-	dth |= ((param->dtl_twtr - DTH_TWTR_BASE) << DTH_TWTR_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
-}
-
-static void set_Trwt(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	u32 dth, dtl;
-	unsigned latency;
-	unsigned clocks;
-	int lat, mtype;
-
-	clocks = 0;
-	dtl = pci_read_config32(ctrl->f2, DRAM_TIMING_LOW);
-	latency = (dtl >> DTL_TCL_SHIFT) & DTL_TCL_MASK;
-
-	if (is_opteron(ctrl)) {
-		mtype = 0; /* dual channel */
-	} else if (is_registered(ctrl)) {
-		mtype = 1; /* registered 64bit interface */
-	} else {
-		mtype = 2; /* unbuffered 64bit interface */
-	}
-
-	switch (latency) {
-		case DTL_CL_2:
-			lat = 0;
-			break;
-		case DTL_CL_2_5:
-			lat = 1;
-			break;
-		case DTL_CL_3:
-			lat = 2;
-			break;
-		default:
-			die("Unknown LAT for Trwt");
-	}
-
-	clocks = param->dtl_trwt[lat][mtype];
-	if ((clocks < DTH_TRWT_MIN) || (clocks > DTH_TRWT_MAX)) {
-		die("Unknown Trwt\r\n");
-	}
-	
-	dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
-	dth &= ~(DTH_TRWT_MASK << DTH_TRWT_SHIFT);
-	dth |= ((clocks - DTH_TRWT_BASE) << DTH_TRWT_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
-	return;
-}
-
-static void set_Twcl(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	/* Memory Clocks after CAS# */
-	u32 dth;
-	unsigned clocks;
-	if (is_registered(ctrl)) {
-		clocks = 2;
-	} else {
-		clocks = 1;
-	}
-	dth = pci_read_config32(ctrl->f2, DRAM_TIMING_HIGH);
-	dth &= ~(DTH_TWCL_MASK << DTH_TWCL_SHIFT);
-	dth |= ((clocks - DTH_TWCL_BASE) << DTH_TWCL_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_TIMING_HIGH, dth);
-}
-
-
-static void set_read_preamble(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	u32 dch;
-	unsigned rdpreamble;
-	int slots, i;
-
-	slots = 0;
-
-	for(i = 0; i < 4; i++) {
-		if (ctrl->channel0[i]) {
-			slots += 1;
-		}
-	}
-
-	/* map to index to param.rdpreamble array */
-	if (is_registered(ctrl)) {
-		i = 0;
-	} else if (slots < 3) {
-		i = 1;
-	} else if (slots == 3) {
-		i = 2;
-	} else if (slots == 4) {
-		i = 3;
-	} else {
-		die("Unknown rdpreamble for this nr of slots");
-	}
-
-	dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
-	dch &= ~(DCH_RDPREAMBLE_MASK << DCH_RDPREAMBLE_SHIFT);
-	rdpreamble = param->rdpreamble[i];
-
-	if ((rdpreamble < DCH_RDPREAMBLE_MIN) || (rdpreamble > DCH_RDPREAMBLE_MAX)) {
-		die("Unknown rdpreamble");
-	}
-
-	dch |= (rdpreamble - DCH_RDPREAMBLE_BASE) << DCH_RDPREAMBLE_SHIFT;
-	pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
-}
-
-static void set_max_async_latency(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	u32 dch;
-	unsigned async_lat;
-	int dimms;
-
-	dimms = count_dimms(ctrl);
-
-	dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
-	dch &= ~(DCH_ASYNC_LAT_MASK << DCH_ASYNC_LAT_SHIFT);
-	async_lat = 0;
-	if (is_registered(ctrl)) {
-		if (dimms == 4) {
-			/* 9ns */
-			async_lat = 9;
-		} 
-		else {
-			/* 8ns */
-			async_lat = 8;
-		}
-	}
-	else {
-		if (dimms > 3) {
-			die("Too many unbuffered dimms");
-		}
-		else if (dimms == 3) {
-			/* 7ns */
-			async_lat = 7;
-		}
-		else {
-			/* 6ns */
-			async_lat = 6;
-		}
-	}
-	dch |= ((async_lat - DCH_ASYNC_LAT_BASE) << DCH_ASYNC_LAT_SHIFT);
-	pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
-}
-
-static void set_idle_cycle_limit(const struct mem_controller *ctrl, const struct mem_param *param)
-{
-	u32 dch;
-	/* AMD says to Hardcode this */
-	dch = pci_read_config32(ctrl->f2, DRAM_CONFIG_HIGH);
-	dch &= ~(DCH_IDLE_LIMIT_MASK << DCH_IDLE_LIMIT_SHIFT);
-	dch |= DCH_IDLE_LIMIT_16 << DCH_IDLE_LIMIT_SHIFT;
-	dch |= DCH_DYN_IDLE_CTR_EN;
-	pci_write_config32(ctrl->f2, DRAM_CONFIG_HIGH, dch);
-}
-
-static long spd_set_dram_timing(const struct mem_controller *ctrl, const struct mem_param *param, long dimm_mask)
-{
-	int i;
-	
-	init_Tref(ctrl, param);
-	for(i = 0; i < DIMM_SOCKETS; i++) {
-		int rc;
-		if (!(dimm_mask & (1 << i))) {
-			continue;
-		}
-		/* DRAM Timing Low Register */
-		if ((rc = update_dimm_Trc (ctrl, param, i)) <= 0) goto dimm_err;
-		if ((rc = update_dimm_Trfc(ctrl, param, i)) <= 0) goto dimm_err;
-		if ((rc = update_dimm_Trcd(ctrl, param, i)) <= 0) goto dimm_err;
-		if ((rc = update_dimm_Trrd(ctrl, param, i)) <= 0) goto dimm_err;
-		if ((rc = update_dimm_Tras(ctrl, param, i)) <= 0) goto dimm_err;
-		if ((rc = update_dimm_Trp (ctrl, param, i)) <= 0) goto dimm_err;
-
-		/* DRAM Timing High Register */
-		if ((rc = update_dimm_Tref(ctrl, param, i)) <= 0) goto dimm_err;
-	
-
-		/* DRAM Config Low */
-		if ((rc = update_dimm_x4 (ctrl, param, i)) <= 0) goto dimm_err;
-		if ((rc = update_dimm_ecc(ctrl, param, i)) <= 0) goto dimm_err;
-		continue;
-	dimm_err:
-		if (rc < 0) {
-			return -1;
-		}
-		dimm_mask = disable_dimm(ctrl, i, dimm_mask);
-	}
-	/* DRAM Timing Low Register */
-	set_Twr(ctrl, param);
-
-	/* DRAM Timing High Register */
-	set_Twtr(ctrl, param);
-	set_Trwt(ctrl, param);
-	set_Twcl(ctrl, param);
-
-	/* DRAM Config High */
-	set_read_preamble(ctrl, param);
-	set_max_async_latency(ctrl, param);
-	set_idle_cycle_limit(ctrl, param);
-	return dimm_mask;
-}
-
-static void sdram_set_spd_registers(const struct mem_controller *ctrl, struct sys_info *sysinfo) 
-{
-	struct spd_set_memclk_result result;
-	const struct mem_param *param;
-	long dimm_mask;
-	if (!controller_present(ctrl)) {
-		printk(BIOS_DEBUG, "No memory controller present\r\n");
-		return;
-	}
-	hw_enable_ecc(ctrl);
-	activate_spd_rom(ctrl);
-	dimm_mask = spd_detect_dimms(ctrl);
-	if (!(dimm_mask & ((1 << DIMM_SOCKETS) - 1))) {
-		printk(BIOS_DEBUG, "No memory for this cpu\r\n");
-		return;
-	}
-	dimm_mask = spd_enable_2channels(ctrl, dimm_mask);        
-	if (dimm_mask < 0) 
-		goto hw_spd_err;
-	dimm_mask = spd_set_ram_size(ctrl , dimm_mask);           
-	if (dimm_mask < 0) 
-		goto hw_spd_err;
-	dimm_mask = spd_handle_unbuffered_dimms(ctrl, dimm_mask); 
-	if (dimm_mask < 0) 
-		goto hw_spd_err;
-	result = spd_set_memclk(ctrl, dimm_mask);
-	param     = result.param;
-	dimm_mask = result.dimm_mask;
-	if (dimm_mask < 0) 
-		goto hw_spd_err;
-	dimm_mask = spd_set_dram_timing(ctrl, param , dimm_mask);
-	if (dimm_mask < 0)
-		goto hw_spd_err;
-	order_dimms(ctrl);
-	return;
- hw_spd_err:
-	/* Unrecoverable error reading SPD data */
-	print_err("SPD error - reset\r\n");
-	hard_reset();
-	return;
-}
-
-#if HW_MEM_HOLE_SIZEK != 0
-static u32 hoist_memory(int controllers, const struct mem_controller *ctrl,unsigned hole_startk, int i)
-{
-        int ii;
-        u32 carry_over;
-        struct device *dev;
-        u32 base, limit;
-        u32 basek;
-        u32 hoist;
-        int j;
-
-        carry_over = (4*1024*1024) - hole_startk;
-
-        for(ii=controllers - 1;ii>i;ii--) {
-                base  = pci_read_config32(ctrl[0].f1, 0x40 + (ii << 3));
-                if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
-                        continue;
-                }
-		limit = pci_read_config32(ctrl[0].f1, 0x44 + (ii << 3));
-                for(j = 0; j < controllers; j++) {
-                        pci_write_config32(ctrl[j].f1, 0x44 + (ii << 3), limit + (carry_over << 2));
-                        pci_write_config32(ctrl[j].f1, 0x40 + (ii << 3), base + (carry_over << 2));
-                }
-        }
-        limit = pci_read_config32(ctrl[0].f1, 0x44 + (i << 3));
-        for(j = 0; j < controllers; j++) {
-                pci_write_config32(ctrl[j].f1, 0x44 + (i << 3), limit + (carry_over << 2));
-        }
-        dev = ctrl[i].f1;
-        base  = pci_read_config32(dev, 0x40 + (i << 3));
-        basek  = (base & 0xffff0000) >> 2;
-        if(basek == hole_startk) {
-                //don't need set memhole here, because hole off set will be 0, overflow
-                //so need to change base reg instead, new basek will be 4*1024*1024
-                base &= 0x0000ffff;
-                base |= (4*1024*1024)<<2;
-                for(j = 0; j < controllers; j++) {
-                        pci_write_config32(ctrl[j].f1, 0x40 + (i<<3), base);
-                }
-        }
-	else {
-        	hoist = /* hole start address */
-                	((hole_startk << 10) & 0xff000000) +
-	                /* hole address to memory controller address */
-        	        (((basek + carry_over) >> 6) & 0x0000ff00) +
-                	/* enable */
-	                1;
-	        pci_write_config32(dev, 0xf0, hoist);
-	}
-
-        return carry_over;
-}
-
-static void set_hw_mem_hole(int controllers, const struct mem_controller *ctrl)
-{
-
-        u32 hole_startk;
-        int i;
-
-        hole_startk = 4*1024*1024 - HW_MEM_HOLE_SIZEK;
-
-#if HW_MEM_HOLE_SIZE_AUTO_INC == 1 
-	/* We need to double check if hole_startk is valid.
-	 * If it is equal to the dram base address in K (base_k), 
-	 * we need to decrease it.
-	 */
-        u32 basek_pri;
-        for(i=0; i<controllers; i++) {
-                        u32 base;
-                        unsigned base_k;
-                        base  = pci_read_config32(ctrl[0].f1, 0x40 + (i << 3));
-                        if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
-                                continue;
-                        }
-                        base_k = (base & 0xffff0000) >> 2;
-                        if(base_k == hole_startk) {
-				/* decrease memory hole startk to make sure it is
-				 * in the middle of the previous node 
-				 */
-                                hole_startk -= (base_k - basek_pri)>>1; 
-                                break; /* only one hole */
-                        }
-                        basek_pri = base_k;
-        }
-
-#endif
-        /* Find node number that needs the memory hole configured */
-        for(i=0; i<controllers; i++) {
-                        u32 base, limit;
-                        unsigned base_k, limit_k;
-                        base  = pci_read_config32(ctrl[0].f1, 0x40 + (i << 3));
-                        if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
-                                continue;
-                        }
-                        limit = pci_read_config32(ctrl[0].f1, 0x44 + (i << 3));
-                        base_k = (base & 0xffff0000) >> 2;
-                        limit_k = ((limit + 0x00010000) & 0xffff0000) >> 2;
-			if ((base_k <= hole_startk) && (limit_k > hole_startk)) {
-                                unsigned end_k;
-                                hoist_memory(controllers, ctrl, hole_startk, i);
-                                end_k = memory_end_k(ctrl, controllers);
-                                set_top_mem(end_k, hole_startk);
-                                break; /* only one hole */
-                        }
-        }
-
-}
-
-#endif
-
-#define TIMEOUT_LOOPS 300000
-static void sdram_enable(int controllers, const struct mem_controller *ctrl, struct sys_info *sysinfo)
-{
-	int i;
-
-	/* Error if I don't have memory */
-	if (memory_end_k(ctrl, controllers) == 0) {
-		die("No memory\r\n");
-	}
-
-	/* Before enabling memory start the memory clocks */
-	for(i = 0; i < controllers; i++) {
-		u32 dch;
-		if (!controller_present(ctrl + i))
-			continue;
-		dch = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_HIGH);
-		if (dch & (DCH_MEMCLK_EN0|DCH_MEMCLK_EN1|DCH_MEMCLK_EN2|DCH_MEMCLK_EN3)) {
-			dch |= DCH_MEMCLK_VALID;
-			pci_write_config32(ctrl[i].f2, DRAM_CONFIG_HIGH, dch);
-		}
-		else {
-			/* Disable dram receivers */
-			u32 dcl;
-			dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
-			dcl |= DCL_DisInRcvrs;
-			pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
-		}
-	}
-
-	/* And if necessary toggle the the reset on the dimms by hand */
-	memreset(controllers, ctrl);
-
-	/* We need to wait a mimmium of 20 MEMCLKS to enable the  InitDram */
-
-	for(i = 0; i < controllers; i++) {
-		u32 dcl, dch;
-		if (!controller_present(ctrl + i))
-			continue;
-		/* Skip everything if I don't have any memory on this controller */
-		dch = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_HIGH);
-		if (!(dch & DCH_MEMCLK_VALID)) {
-			continue;
-		}
-
-		/* Toggle DisDqsHys to get it working */
-		dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
-		if (dcl & DCL_DimmEccEn) {
-			u32 mnc;
-			print_spew("ECC enabled\r\n");
-			mnc = pci_read_config32(ctrl[i].f3, MCA_NB_CONFIG);
-			mnc |= MNC_ECC_EN;
-			if (dcl & DCL_128BitEn) {
-				mnc |= MNC_CHIPKILL_EN;
-			}
-			pci_write_config32(ctrl[i].f3, MCA_NB_CONFIG, mnc);
-		}
-		dcl |= DCL_DisDqsHys;
-		pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
-		dcl &= ~DCL_DisDqsHys;
-		dcl &= ~DCL_DLL_Disable;
-		dcl &= ~DCL_D_DRV;
-		dcl &= ~DCL_QFC_EN;
-		dcl |= DCL_DramInit;
-		pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
-
-	}
-	for(i = 0; i < controllers; i++) {
-		u32 dcl, dch;
-		if (!controller_present(ctrl + i))
-			continue;
-		/* Skip everything if I don't have any memory on this controller */
-		dch = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_HIGH);
-		if (!(dch & DCH_MEMCLK_VALID)) {
-			continue;
-		}
-
-		printk(BIOS_DEBUG, "Initializing memory: ");
-
-		int loops = 0;
-		do {
-			dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
-			loops += 1;
-			if ((loops & 1023) == 0) {
-				printk(BIOS_DEBUG, ".");
-			}
-		} while(((dcl & DCL_DramInit) != 0) && (loops < TIMEOUT_LOOPS));
-		if (loops >= TIMEOUT_LOOPS) {
-			printk(BIOS_DEBUG, " failed\r\n");
-			continue;
-		}
-
-		if (!is_cpu_pre_c0()) {
-			/* Wait until it is safe to touch memory */
-			dcl &= ~(DCL_MemClrStatus | DCL_DramEnable);
-			pci_write_config32(ctrl[i].f2, DRAM_CONFIG_LOW, dcl);
-			do {
-				dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
-			} while(((dcl & DCL_MemClrStatus) == 0) || ((dcl & DCL_DramEnable) == 0) );
-		}
-
-		printk(BIOS_DEBUG, " done\r\n");
-	}
-
-#if HW_MEM_HOLE_SIZEK != 0
-         // init hw mem hole here
-        /* DramHoleValid bit only can be set after MemClrStatus is set by Hardware */
-	if(!is_cpu_pre_e0())
-	        set_hw_mem_hole(controllers, ctrl);
-#endif
-
-	//FIXME add enable node interleaving here -- yhlu
-	/*needed?
-		1. check how many nodes we have , if not all has ram installed get out
-		2. check cs_base lo is 0, node 0 f2 0x40,,,,, if any one is not using lo is CS_BASE, get out
-		3. check if other node is the same as node 0 about f2 0x40,,,,, otherwise get out
-		4. if all ready enable node_interleaving in f1 0x40..... of every node
-		5. for node interleaving we need to set mem hole to every node ( need recalcute hole offset in f0 for every node)
-	*/
-
-}
-
-static void set_sysinfo_in_ram(unsigned val)
-{
-}
-
-static void fill_mem_ctrl(int controllers, struct mem_controller *ctrl_a, const u16 *spd_addr)
-{
-        int i;
-        int j;
-        struct mem_controller *ctrl;
-        for(i=0;i<controllers; i++) {
-                ctrl = &ctrl_a[i];
-                ctrl->node_id = i;
-                ctrl->f0 = PCI_DEV(0, 0x18+i, 0);
-                ctrl->f1 = PCI_DEV(0, 0x18+i, 1);
-                ctrl->f2 = PCI_DEV(0, 0x18+i, 2);
-                ctrl->f3 = PCI_DEV(0, 0x18+i, 3);
-
-                if(spd_addr == (void *)0) continue;
-
-                for(j=0;j<DIMM_SOCKETS;j++) {
-                        ctrl->channel0[j] = spd_addr[(i*2+0)*DIMM_SOCKETS + j];
-                        ctrl->channel1[j] = spd_addr[(i*2+1)*DIMM_SOCKETS + j];
-                }
-        }
-}
-#endif
-





More information about the coreboot mailing list