[coreboot-gerrit] Patch set updated for coreboot: [WIP] nb/i945/raminit: Use common ddr2 decode functions

Arthur Heymans (arthur@aheymans.xyz) gerrit at coreboot.org
Sun Feb 12 23:42:32 CET 2017


Arthur Heymans (arthur at aheymans.xyz) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18305

-gerrit

commit 54e24d03e1595bab742b7e3b70cad298cfaef0a3
Author: Arthur Heymans <arthur at aheymans.xyz>
Date:   Mon Feb 6 22:40:14 2017 +0100

    [WIP] nb/i945/raminit: Use common ddr2 decode functions
    
    This simplifies computing dram timings a lot.
    
    This removes computation of rank size based on columns, rows,
    banks,... and uses the information in SPD byte 31.
    
    TODO: mclk for 1067MHz FSB
    
    Change-Id: I97c93939d11807752797785dd88c70b43a236ee3
    Signed-off-by: Arthur Heymans <arthur at aheymans.xyz>
---
 src/northbridge/intel/i945/Kconfig   |   1 +
 src/northbridge/intel/i945/raminit.c | 590 ++++++-----------------------------
 src/northbridge/intel/i945/raminit.h |   6 +-
 3 files changed, 102 insertions(+), 495 deletions(-)

diff --git a/src/northbridge/intel/i945/Kconfig b/src/northbridge/intel/i945/Kconfig
index 18e90b6..955b91c 100644
--- a/src/northbridge/intel/i945/Kconfig
+++ b/src/northbridge/intel/i945/Kconfig
@@ -26,6 +26,7 @@ config NORTHBRIDGE_SPECIFIC_OPTIONS # dummy
 	select INTEL_GMA_ACPI
 	select INTEL_GMA_SSC_ALTERNATE_REF
 	select RELOCATABLE_RAMSTAGE
+	select SPD_DDR2
 
 config NORTHBRIDGE_INTEL_SUBTYPE_I945GC
 	def_bool n
diff --git a/src/northbridge/intel/i945/raminit.c b/src/northbridge/intel/i945/raminit.c
index 1f79cf6..6c2e337 100644
--- a/src/northbridge/intel/i945/raminit.c
+++ b/src/northbridge/intel/i945/raminit.c
@@ -28,6 +28,7 @@
 #include "i945.h"
 #include "chip.h"
 #include <cbmem.h>
+#include <device/dram/ddr2.h>
 
 /* Debugging macros. */
 #if CONFIG_DEBUG_RAM_SETUP
@@ -315,8 +316,7 @@ static void sdram_detect_errors(struct sys_info *sysinfo)
 static void sdram_get_dram_configuration(struct sys_info *sysinfo)
 {
 	u32 dimm_mask = 0;
-	int i;
-
+	dimm_attr dimm;
 	/**
 	 * i945 supports two DIMMs, in two configurations:
 	 *
@@ -357,9 +357,11 @@ static void sdram_get_dram_configuration(struct sys_info *sysinfo)
 	 *
 	 */
 
-	for (i = 0; i<(2 * DIMM_SOCKETS); i++) {
+	int i, j, spd_size;
+	spd_raw_data raw_spd;
+
+	for (i = 0; i < (2 * DIMM_SOCKETS); i++) {
 		int device = get_dimm_spd_address(sysinfo, i);
-		u8 reg8;
 
 		/* Initialize the socket information with a sane value */
 		sysinfo->dimm[i] = SYSINFO_DIMM_NOT_POPULATED;
@@ -368,31 +370,37 @@ static void sdram_get_dram_configuration(struct sys_info *sysinfo)
 		if (!sdram_capabilities_dual_channel() && (i >> 1))
 			continue;
 
-		printk(BIOS_DEBUG, "DDR II Channel %d Socket %d: ", (i >> 1), (i & 1));
+		spd_size = spd_decode_spd_size_ddr2(spd_read_byte(device, 0));
+
+		for (j = 0; j < spd_size; j++)
+			raw_spd[j] = spd_read_byte(device, j);
 
-		if (spd_read_byte(device, SPD_MEMORY_TYPE) != SPD_MEMORY_TYPE_SDRAM_DDR2) {
-			printk(BIOS_DEBUG, "N/A\n");
+		if (spd_decode_ddr2(&dimm, raw_spd) == SPD_STATUS_INVALID)
 			continue;
-		}
+		dram_print_spd_ddr2(&dimm);
 
-		reg8 = spd_read_byte(device, SPD_DIMM_CONFIG_TYPE);
-		if (reg8 == ERROR_SCHEME_ECC)
+		sysinfo->dimm_decoded[i] = dimm;
+
+		if (sysinfo->dimm_decoded[i].flags.is_ecc)
 			die("Error: ECC memory not supported by this chipset\n");
 
-		reg8 = spd_read_byte(device, SPD_MODULE_ATTRIBUTES);
-		if (reg8 & MODULE_BUFFERED)
-			die("Error: Buffered memory not supported by this chipset\n");
-		if (reg8 & MODULE_REGISTERED)
+		switch (sysinfo->dimm_decoded[i].dimm_type) {
+		case SPD_RDIMM:
+		case SPD_72B_SO_RDIMM:
+		case SPD_MINI_RDIMM:
 			die("Error: Registered memory not supported by this chipset\n");
+		default: break;
+		}
 
-		switch (spd_read_byte(device, SPD_PRIMARY_SDRAM_WIDTH)) {
+		printk(BIOS_DEBUG, "DDR II Channel %d Socket %d: ", (i >> 1), (i & 1));
+		switch (sysinfo->dimm_decoded[i].width) {
 		case 0x08:
-			switch (spd_read_byte(device, SPD_NUM_DIMM_BANKS) & 0x0f) {
-			case 1:
+			switch (sysinfo->dimm_decoded[i].ranks) {
+			case 2:
 				printk(BIOS_DEBUG, "x8DDS\n");
 				sysinfo->dimm[i] = SYSINFO_DIMM_X8DDS;
 				break;
-			case 0:
+			case 1:
 				printk(BIOS_DEBUG, "x8DS\n");
 				sysinfo->dimm[i] = SYSINFO_DIMM_X8DS;
 				break;
@@ -401,12 +409,12 @@ static void sdram_get_dram_configuration(struct sys_info *sysinfo)
 			}
 			break;
 		case 0x10:
-			switch (spd_read_byte(device, SPD_NUM_DIMM_BANKS) & 0x0f) {
-			case 1:
+			switch (sysinfo->dimm_decoded[i].ranks) {
+			case 2:
 				printk(BIOS_DEBUG, "x16DS\n");
 				sysinfo->dimm[i] = SYSINFO_DIMM_X16DS;
 				break;
-			case 0:
+			case 1:
 				printk(BIOS_DEBUG, "x16SS\n");
 				sysinfo->dimm[i] = SYSINFO_DIMM_X16SS;
 				break;
@@ -417,15 +425,14 @@ static void sdram_get_dram_configuration(struct sys_info *sysinfo)
 		default:
 			die("Unsupported DDR-II memory width.\n");
 		}
-
 		dimm_mask |= (1 << i);
 	}
-
 	if (!dimm_mask) {
 		die("No memory installed.\n");
 	}
 
 	if (!(dimm_mask & ((1 << DIMM_SOCKETS) - 1))) {
+		/* Possible does not boot in this case */
 		printk(BIOS_INFO, "Channel 0 has no memory populated.\n");
 	}
 }
@@ -438,7 +445,6 @@ static void sdram_get_dram_configuration(struct sys_info *sysinfo)
 static void sdram_verify_package_type(struct sys_info * sysinfo)
 {
 	int i;
-
 	/* Assume no stacked DIMMs are available until we find one */
 	sysinfo->package = 0;
 	for (i = 0; i < 2*DIMM_SOCKETS; i++) {
@@ -446,365 +452,83 @@ static void sdram_verify_package_type(struct sys_info * sysinfo)
 			continue;
 
 		/* Is the current DIMM a stacked DIMM? */
-		if (spd_read_byte(get_dimm_spd_address(sysinfo, i), SPD_NUM_DIMM_BANKS) & (1 << 4))
+		if (sysinfo->dimm_decoded[i].flags.stacked)
 			sysinfo->package = 1;
 	}
 }
 
-static u8 sdram_possible_cas_latencies(struct sys_info * sysinfo)
+static void select_cas_dramfreq(struct sys_info * sysinfo)
 {
+	dimm_attr dimm[2 * DIMM_SOCKETS];
+	u8 selected_cas;
 	int i;
-	u8 cas_mask;
-
-	/* Setup CAS mask with all supported CAS Latencies */
-	cas_mask = SPD_CAS_LATENCY_DDR2_3 |
-		   SPD_CAS_LATENCY_DDR2_4 |
-		   SPD_CAS_LATENCY_DDR2_5;
-
-	for (i = 0; i < 2*DIMM_SOCKETS; i++) {
-		if (sysinfo->dimm[i] != SYSINFO_DIMM_NOT_POPULATED)
-			cas_mask &= spd_read_byte(get_dimm_spd_address(sysinfo, i),
-						  SPD_ACCEPTABLE_CAS_LATENCIES);
-	}
-
-	if (!cas_mask) {
-		die("No DDR-II modules with accepted CAS latencies found.\n");
-	}
+	u8 cas_mask = SPD_CAS_LATENCY_DDR2_3 | SPD_CAS_LATENCY_DDR2_4
+		| SPD_CAS_LATENCY_DDR2_5;
+	u32 min_tCLK = TCK_200MHZ, common_tCLK;
 
-	return cas_mask;
-}
-
-static void sdram_detect_cas_latency_and_ram_speed(struct sys_info * sysinfo, u8 cas_mask)
-{
-	int i, j, idx;
-	int lowest_common_cas = 0;
-	int max_ram_speed = 0;
-
-	const u8 ddr2_speeds_table[] = {
-		0x50, 0x60,	/* DDR2 400: tCLK = 5.0ns  tAC = 0.6ns  */
-		0x3d, 0x50,	/* DDR2 533: tCLK = 3.75ns tAC = 0.5ns  */
-		0x30, 0x45,	/* DDR2 667: tCLK = 3.0ns  tAC = 0.45ns */
-	};
-
-	const u8 spd_lookup_table[] = {
-		SPD_MIN_CYCLE_TIME_AT_CAS_MAX,	SPD_ACCESS_TIME_FROM_CLOCK,
-		SPD_SDRAM_CYCLE_TIME_2ND,	SPD_ACCESS_TIME_FROM_CLOCK_2ND,
-		SPD_SDRAM_CYCLE_TIME_3RD,	SPD_ACCESS_TIME_FROM_CLOCK_3RD
-	};
+	for (i = 0; i < 2 * DIMM_SOCKETS; i++)
+		dimm[i] = sysinfo->dimm_decoded[i];
 
 	switch (sdram_capabilities_max_supported_memory_frequency()) {
-	case 400: max_ram_speed = 0; break;
-	case 533: max_ram_speed = 1; break;
-	case 667: max_ram_speed = 2; break;
+	case 400: min_tCLK = TCK_200MHZ; break;
+	case 533: min_tCLK = TCK_266MHZ; break;
+	case 667: min_tCLK = TCK_333MHZ; break;
 	}
 
-	sysinfo->memory_frequency = 0;
-	sysinfo->cas = 0;
-
-	if (cas_mask & SPD_CAS_LATENCY_DDR2_3) {
-		lowest_common_cas = 3;
-	} else if (cas_mask & SPD_CAS_LATENCY_DDR2_4) {
-		lowest_common_cas = 4;
-	} else if (cas_mask & SPD_CAS_LATENCY_DDR2_5) {
-		lowest_common_cas = 5;
-	}
-	PRINTK_DEBUG("lowest common cas = %d\n", lowest_common_cas);
-
-	for (j = max_ram_speed; j>=0; j--) {
-		int freq_cas_mask = cas_mask;
-
-		PRINTK_DEBUG("Probing Speed %d\n", j);
-		for (i = 0; i < 2*DIMM_SOCKETS; i++) {
-			int device = get_dimm_spd_address(sysinfo, i);
-			int current_cas_mask;
-
-			PRINTK_DEBUG("  DIMM: %d\n", i);
-			if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED) {
-				continue;
-			}
-
-			current_cas_mask = spd_read_byte(device, SPD_ACCEPTABLE_CAS_LATENCIES);
-
-			while (current_cas_mask) {
-				int highest_supported_cas = 0, current_cas = 0;
-				PRINTK_DEBUG("    Current CAS mask: %04x; ", current_cas_mask);
-				if (current_cas_mask & SPD_CAS_LATENCY_DDR2_5) {
-					highest_supported_cas = 5;
-				} else if (current_cas_mask & SPD_CAS_LATENCY_DDR2_4) {
-					highest_supported_cas = 4;
-				} else if (current_cas_mask & SPD_CAS_LATENCY_DDR2_3) {
-					highest_supported_cas = 3;
-				} else {
-					die("Invalid max. CAS.\n");
-				}
-				if (current_cas_mask & SPD_CAS_LATENCY_DDR2_3) {
-					current_cas = 3;
-				} else if (current_cas_mask & SPD_CAS_LATENCY_DDR2_4) {
-					current_cas = 4;
-				} else if (current_cas_mask & SPD_CAS_LATENCY_DDR2_5) {
-					current_cas = 5;
-				} else {
-					die("Invalid CAS.\n");
-				}
-
-				idx = highest_supported_cas - current_cas;
-				PRINTK_DEBUG("idx=%d, ", idx);
-				PRINTK_DEBUG("tCLK=%x, ", spd_read_byte(device, spd_lookup_table[2*idx]));
-				PRINTK_DEBUG("tAC=%x", spd_read_byte(device, spd_lookup_table[(2*idx)+1]));
-
-				if (spd_read_byte(device, spd_lookup_table[2*idx]) <= ddr2_speeds_table[2*j] &&
-						spd_read_byte(device, spd_lookup_table[(2*idx)+1]) <= ddr2_speeds_table[(2*j)+1]) {
-					PRINTK_DEBUG(":    OK\n");
-					break;
-				}
-
-				PRINTK_DEBUG(":    Not fast enough!\n");
-
-				current_cas_mask &= ~(1 << (current_cas));
-			}
-
-			freq_cas_mask &= current_cas_mask;
-			if (!current_cas_mask) {
-				PRINTK_DEBUG("    No valid CAS for this speed on DIMM %d\n", i);
-				break;
-			}
-		}
-		PRINTK_DEBUG("  freq_cas_mask for speed %d: %04x\n", j, freq_cas_mask);
-		if (freq_cas_mask) {
-			switch (j) {
-			case 0: sysinfo->memory_frequency = 400; break;
-			case 1: sysinfo->memory_frequency = 533; break;
-			case 2: sysinfo->memory_frequency = 667; break;
-			}
-			if (freq_cas_mask & SPD_CAS_LATENCY_DDR2_3) {
-				sysinfo->cas = 3;
-			} else if (freq_cas_mask & SPD_CAS_LATENCY_DDR2_4) {
-				sysinfo->cas = 4;
-			} else if (freq_cas_mask & SPD_CAS_LATENCY_DDR2_5) {
-				sysinfo->cas = 5;
-			}
-			break;
-		}
-	}
-
-	if (sysinfo->memory_frequency && sysinfo->cas) {
-		printk(BIOS_DEBUG, "Memory will be driven at %dMHz with CAS=%d clocks\n",
-				sysinfo->memory_frequency, sysinfo->cas);
-	} else {
+	common_tCLK = get_common_freq_cas(cas_mask, dimm, 2 * DIMM_SOCKETS,
+				&selected_cas);
+	if (common_tCLK == 0)
 		die("Could not find common memory frequency and CAS\n");
-	}
-}
+	common_tCLK = MAX(common_tCLK, min_tCLK);
 
-static void sdram_detect_smallest_tRAS(struct sys_info * sysinfo)
-{
-	int i;
-	int tRAS_time;
-	int tRAS_cycles;
-	int freq_multiplier = 0;
+	sysinfo->cas = selected_cas;
+	sysinfo->tclk = common_tCLK;
 
-	switch (sysinfo->memory_frequency) {
-	case 400: freq_multiplier = 0x14; break; /* 5ns */
-	case 533: freq_multiplier = 0x0f; break; /* 3.75ns */
-	case 667: freq_multiplier = 0x0c; break; /* 3ns */
+	switch (sysinfo->tclk) {
+	case TCK_200MHZ: sysinfo->memory_frequency = 400; break;
+	case TCK_266MHZ: sysinfo->memory_frequency = 533; break;
+	case TCK_333MHZ: sysinfo->memory_frequency = 667; break;
 	}
-
-	tRAS_cycles = 4; /* 4 clocks minimum */
-	tRAS_time = tRAS_cycles * freq_multiplier;
-
-	for (i = 0; i < 2*DIMM_SOCKETS; i++) {
-		u8 reg8;
-
-		if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
-			continue;
-
-		reg8 = spd_read_byte(get_dimm_spd_address(sysinfo, i), SPD_MIN_ACTIVE_TO_PRECHARGE_DELAY);
-		if (!reg8) {
-			die("Invalid tRAS value.\n");
-		}
-
-		while ((tRAS_time >> 2) < reg8) {
-			tRAS_time += freq_multiplier;
-			tRAS_cycles++;
-		}
-	}
-	if (tRAS_cycles > 0x18) {
-		die("DDR-II Module does not support this frequency (tRAS error)\n");
-	}
-
-	printk(BIOS_DEBUG, "tRAS = %d cycles\n", tRAS_cycles);
-	sysinfo->tras = tRAS_cycles;
+	printk(BIOS_DEBUG, "Memory will be driven at %dMHz with CAS=%d clocks\n",
+		sysinfo->memory_frequency, sysinfo->cas);
 }
 
-static void sdram_detect_smallest_tRP(struct sys_info * sysinfo)
+static void select_dram_timings(struct sys_info * sysinfo)
 {
 	int i;
-	int tRP_time;
-	int tRP_cycles;
-	int freq_multiplier = 0;
-
-	switch (sysinfo->memory_frequency) {
-	case 400: freq_multiplier = 0x14; break; /* 5ns */
-	case 533: freq_multiplier = 0x0f; break; /* 3.75ns */
-	case 667: freq_multiplier = 0x0c; break; /* 3ns */
-	}
-
-	tRP_cycles = 2; /* 2 clocks minimum */
-	tRP_time = tRP_cycles * freq_multiplier;
+	int tCLK = sysinfo->tclk;
+	int tRAS_cycles, tRP_cycles, tRCD_cycles, tWR_cycles, tRFC_cycles;
 
 	for (i = 0; i < 2*DIMM_SOCKETS; i++) {
-		u8 reg8;
-
 		if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
 			continue;
 
-		reg8 = spd_read_byte(get_dimm_spd_address(sysinfo, i), SPD_MIN_ROW_PRECHARGE_TIME);
-		if (!reg8) {
-			die("Invalid tRP value.\n");
-		}
+		tRAS_cycles = DIV_ROUND_UP(sysinfo->dimm_decoded[i].tRAS, tCLK);
+		if (tRAS_cycles > sysinfo->tras)
+			sysinfo->tras = tRAS_cycles;
 
-		while (tRP_time < reg8) {
-			tRP_time += freq_multiplier;
-			tRP_cycles++;
-		}
-	}
+		tRP_cycles = DIV_ROUND_UP(sysinfo->dimm_decoded[i].tRP, tCLK);
+		if (tRP_cycles > sysinfo->trp)
+			sysinfo->trp = tRP_cycles;
 
-	if (tRP_cycles > 6) {
-		die("DDR-II Module does not support this frequency (tRP error)\n");
-	}
+		tRCD_cycles = DIV_ROUND_UP(sysinfo->dimm_decoded[i].tRCD, tCLK);
+		if (tRCD_cycles > sysinfo->trcd)
+			sysinfo->trcd = tRCD_cycles;
 
-	printk(BIOS_DEBUG, "tRP = %d cycles\n", tRP_cycles);
-	sysinfo->trp = tRP_cycles;
-}
+		tWR_cycles = DIV_ROUND_UP(sysinfo->dimm_decoded[i].tWR, tCLK);
+		if (tWR_cycles > sysinfo->twr)
+			sysinfo->twr = tWR_cycles;
 
-static void sdram_detect_smallest_tRCD(struct sys_info * sysinfo)
-{
-	int i;
-	int tRCD_time;
-	int tRCD_cycles;
-	int freq_multiplier = 0;
+		tRFC_cycles = DIV_ROUND_UP(sysinfo->dimm_decoded[i].tRFC, tCLK);
+		if (tRFC_cycles > sysinfo->trfc)
+			sysinfo->trfc = tRFC_cycles;
 
-	switch (sysinfo->memory_frequency) {
-	case 400: freq_multiplier = 0x14; break; /* 5ns */
-	case 533: freq_multiplier = 0x0f; break; /* 3.75ns */
-	case 667: freq_multiplier = 0x0c; break; /* 3ns */
 	}
-
-	tRCD_cycles = 2; /* 2 clocks minimum */
-	tRCD_time = tRCD_cycles * freq_multiplier;
-
-	for (i = 0; i < 2*DIMM_SOCKETS; i++) {
-		u8 reg8;
-
-		if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
-			continue;
-
-		reg8 = spd_read_byte(get_dimm_spd_address(sysinfo, i), SPD_MIN_RAS_TO_CAS_DELAY);
-		if (!reg8) {
-			die("Invalid tRCD value.\n");
-		}
-
-		while (tRCD_time < reg8) {
-			tRCD_time += freq_multiplier;
-			tRCD_cycles++;
-		}
-	}
-	if (tRCD_cycles > 6) {
-		die("DDR-II Module does not support this frequency (tRCD error)\n");
-	}
-
-	printk(BIOS_DEBUG, "tRCD = %d cycles\n", tRCD_cycles);
-	sysinfo->trcd = tRCD_cycles;
-}
-
-static void sdram_detect_smallest_tWR(struct sys_info * sysinfo)
-{
-	int i;
-	int tWR_time;
-	int tWR_cycles;
-	int freq_multiplier = 0;
-
-	switch (sysinfo->memory_frequency) {
-	case 400: freq_multiplier = 0x14; break; /* 5ns */
-	case 533: freq_multiplier = 0x0f; break; /* 3.75ns */
-	case 667: freq_multiplier = 0x0c; break; /* 3ns */
-	}
-
-	tWR_cycles = 2; /* 2 clocks minimum */
-	tWR_time = tWR_cycles * freq_multiplier;
-
-	for (i = 0; i < 2*DIMM_SOCKETS; i++) {
-		u8 reg8;
-
-		if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
-			continue;
-
-		reg8 = spd_read_byte(get_dimm_spd_address(sysinfo, i), SPD_WRITE_RECOVERY_TIME);
-		if (!reg8) {
-			die("Invalid tWR value.\n");
-		}
-
-		while (tWR_time < reg8) {
-			tWR_time += freq_multiplier;
-			tWR_cycles++;
-		}
-	}
-	if (tWR_cycles > 5) {
-		die("DDR-II Module does not support this frequency (tWR error)\n");
-	}
-
-	printk(BIOS_DEBUG, "tWR = %d cycles\n", tWR_cycles);
-	sysinfo->twr = tWR_cycles;
-}
-
-static void sdram_detect_smallest_tRFC(struct sys_info * sysinfo)
-{
-	int i, index = 0;
-
-	const u8 tRFC_cycles[] = {
-	     /* 75 105 127.5 */
-		15, 21, 26,	/* DDR2-400 */
-		20, 28, 34,	/* DDR2-533 */
-		25, 35, 43 	/* DDR2-667 */
-	};
-
-	for (i = 0; i < 2*DIMM_SOCKETS; i++) {
-		u8 reg8;
-
-		if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
-			continue;
-
-		reg8 = sysinfo->banksize[i*2];
-		switch (reg8) {
-		case 0x04: reg8 = 0; break;
-		case 0x08: reg8 = 1; break;
-		case 0x10: reg8 = 2; break;
-		case 0x20: reg8 = 3; break;
-		}
-
-		if (sysinfo->dimm[i] == SYSINFO_DIMM_X16DS || sysinfo->dimm[i] == SYSINFO_DIMM_X16SS)
-			reg8++;
-
-		if (reg8 > 3) {
-			/* Can this happen? Go back to 127.5ns just to be sure
-			 * we don't run out of the array. This may be wrong
-			 */
-			printk(BIOS_DEBUG, "DIMM %d is 1Gb x16.. Please report.\n", i);
-			reg8 = 3;
-		}
-
-		if (reg8 > index)
-			index = reg8;
-
-	}
-	index--;
-	switch (sysinfo->memory_frequency) {
-	case 667: index += 3; /* Fallthrough */
-	case 533: index += 3; /* Fallthrough */
-	case 400: break;
-	}
-
-	sysinfo->trfc = tRFC_cycles[index];
-	printk(BIOS_DEBUG, "tRFC = %d cycles\n", tRFC_cycles[index]);
+	printk(BIOS_DEBUG, "tRAS = %d cycles\n", sysinfo->tras);
+	printk(BIOS_DEBUG, "tRP  = %d cycles\n", sysinfo->trp);
+	printk(BIOS_DEBUG, "tRCD = %d cycles\n", sysinfo->trcd);
+	printk(BIOS_DEBUG, "tWR  = %d cycles\n", sysinfo->twr);
+	printk(BIOS_DEBUG, "tRFC = %d cycles\n", sysinfo->trfc);
 }
 
 static void sdram_detect_smallest_refresh(struct sys_info * sysinfo)
@@ -819,23 +543,20 @@ static void sdram_detect_smallest_refresh(struct sys_info * sysinfo)
 		if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
 			continue;
 
-		refresh = spd_read_byte(get_dimm_spd_address(sysinfo, i),
-					SPD_REFRESH) & ~(1 << 7);
-
-		/* 15.6us */
-		if (!refresh)
-			continue;
+		refresh = sysinfo->dimm_decoded[i].tRR;
 
 		/* Refresh is slower than 15.6us, use 15.6us */
-		if (refresh > 2)
+		/* tRR is decoded in units of 1/256us */
+		if (refresh >= 15625 * 256)
 			continue;
 
-		if (refresh == 2) {
+		if (refresh == 15625 * 256 / 2) {
 			sysinfo->refresh = 1;
 			break;
 		}
 
-		die("DDR-II module has unsupported refresh value\n");
+		if (refresh == 15625 * 256 / 4)
+			die("DDR-II module has unsupported refresh value\n");
 	}
 	printk(BIOS_DEBUG, "Refresh: %s\n", sysinfo->refresh?"7.8us":"15.6us");
 }
@@ -848,8 +569,7 @@ static void sdram_verify_burst_length(struct sys_info * sysinfo)
 		if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
 			continue;
 
-		if (!(spd_read_byte(get_dimm_spd_address(sysinfo, i),
-				    SPD_SUPPORTED_BURST_LENGTHS) & SPD_BURST_LENGTH_8))
+		if (!sysinfo->dimm_decoded[i].flags.bl8)
 			die("Only DDR-II RAM with burst length 8 is supported by this chipset.\n");
 	}
 }
@@ -1376,121 +1096,26 @@ static void sdram_enable_system_memory_io(struct sys_info *sysinfo)
 	}
 }
 
-struct dimm_size {
-	unsigned long side1;
-	unsigned long side2;
-};
-
-static struct dimm_size sdram_get_dimm_size(struct sys_info *sysinfo, u16 dimmno)
-{
-	/* Calculate the log base 2 size of a DIMM in bits */
-	struct dimm_size sz;
-	int value, low, rows, columns, device;
-
-	device = get_dimm_spd_address(sysinfo, dimmno);
-	sz.side1 = 0;
-	sz.side2 = 0;
-
-	rows = spd_read_byte(device, SPD_NUM_ROWS);	/* rows */
-	if (rows < 0) goto hw_err;
-	if ((rows & 0xf) == 0) goto val_err;
-	sz.side1 += rows & 0xf;
-
-	columns = spd_read_byte(device, SPD_NUM_COLUMNS);	/* columns */
-	if (columns < 0) goto hw_err;
-	if ((columns & 0xf) == 0) goto val_err;
-	sz.side1 += columns & 0xf;
-
-	value = spd_read_byte(device, SPD_NUM_BANKS_PER_SDRAM);	/* 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, SPD_MODULE_DATA_WIDTH_MSB);	/* (high byte) */
-	if (value < 0) goto hw_err;
-	value &= 0xff;
-	value <<= 8;
-
-	low = spd_read_byte(device, SPD_MODULE_DATA_WIDTH_LSB);	/* (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, SPD_NUM_DIMM_BANKS);	/* number of physical banks */
-
-	if (value < 0) goto hw_err;
-	value &= 7;
-	value++;
-	if (value == 1) goto out;
-	if (value != 2) goto val_err;
-
-	/* Start with the symmetrical case */
-	sz.side2 = sz.side1;
-
-	if ((rows & 0xf0) == 0) goto out;	/* If symmetrical we are done */
-
-	/* Don't die here, I have not come across any of these to test what
-	 * actually happens.
-	 */
-	printk(BIOS_ERR, "Asymmetric DIMMs are not supported by this chipset\n");
-
-	sz.side2 -= (rows & 0x0f);		/* Subtract out rows on side 1 */
-	sz.side2 += ((rows >> 4) & 0x0f);	/* Add in rows on side 2 */
-
-	sz.side2 -= (columns & 0x0f);		/* Subtract out columns on side 1 */
-	sz.side2 += ((columns >> 4) & 0x0f);	/* Add in columns on side 2 */
-
-	goto out;
-
- val_err:
-	die("Bad SPD value\n");
- hw_err:
-	/* If a hardware error occurs the spd ROM probably does not exist.
-	 * In this case report that there is no memory
-	 */
-	sz.side1 = 0;
-	sz.side2 = 0;
-out:
-	return sz;
-}
-
 static void sdram_detect_dimm_size(struct sys_info * sysinfo)
 {
 	int i;
 
 	for (i = 0; i < 2 * DIMM_SOCKETS; i++) {
-		struct dimm_size sz;
-
 		sysinfo->banksize[i * 2] = 0;
 		sysinfo->banksize[(i * 2) + 1] = 0;
 
 		if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
 			continue;
-
-		sz = sdram_get_dimm_size(sysinfo, i);
-
-		sysinfo->banks[i] = spd_read_byte(get_dimm_spd_address(sysinfo, i),
-						  SPD_NUM_BANKS_PER_SDRAM);	/* banks */
-
-		if (sz.side1 < 30)
+		if (sysinfo->dimm_decoded[i].ranksize_mb < 128)
 			die("DDR-II rank size smaller than 128MB is not supported.\n");
 
-		sysinfo->banksize[i * 2] = 1 << (sz.side1 - 28);
-
+		sysinfo->banksize[i * 2] = sysinfo->dimm_decoded[i].ranksize_mb / 32;
 		printk(BIOS_DEBUG, "DIMM %d side 0 = %d MB\n", i, sysinfo->banksize[i * 2] * 32 );
 
-		if (!sz.side2)
+		if (sysinfo->dimm_decoded[i].ranks)
 			continue;
 
-		/* If there is a second side, it has to have at least 128M, too */
-		if (sz.side2 < 30)
-			die("DDR-II rank size smaller than 128MB is not supported.\n");
-
-		sysinfo->banksize[(i * 2) + 1] = 1 << (sz.side2 - 28);
-
+		sysinfo->banksize[(i * 2) + 1] = sysinfo->dimm_decoded[i].ranksize_mb / 32;
 		printk(BIOS_DEBUG, "DIMM %d side 1 = %d MB\n", i, sysinfo->banksize[(i * 2) + 1] * 32);
 	}
 }
@@ -1564,25 +1189,19 @@ static int sdram_program_row_boundaries(struct sys_info *sysinfo)
 
 static int sdram_set_row_attributes(struct sys_info *sysinfo)
 {
-	int i, value;
+	int i;
 	u16 dra0 = 0, dra1 = 0, dra = 0;
 
 	printk(BIOS_DEBUG, "Setting row attributes...\n");
 	for (i = 0; i < 2 * DIMM_SOCKETS; i++) {
-		u16 device;
 		u8 columnsrows;
 
 		if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED) {
 			continue;
 		}
 
-		device = get_dimm_spd_address(sysinfo, i);
-
-		value = spd_read_byte(device, SPD_NUM_ROWS);	/* rows */
-		columnsrows = (value & 0x0f);
-
-		value = spd_read_byte(device, SPD_NUM_COLUMNS);	/* columns */
-		columnsrows |= (value & 0xf) << 4;
+		columnsrows = (sysinfo->dimm_decoded[i].row_bits & 0x0f)
+			| (sysinfo->dimm_decoded[i].col_bits & 0xf) << 4;
 
 		switch (columnsrows) {
 		case 0x9d: dra = 2; break;
@@ -1630,7 +1249,7 @@ static void sdram_set_bank_architecture(struct sys_info *sysinfo)
 		if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
 			continue;
 
-		if (sysinfo->banks[i] != 8)
+		if (sysinfo->dimm_decoded[i].banks != 8)
 			continue;
 
 		printk(BIOS_SPEW, "DIMM%d has 8 banks.\n", i);
@@ -3033,7 +2652,7 @@ static void sdram_setup_processor_side(void)
 void sdram_initialize(int boot_path, const u8 *spd_addresses)
 {
 	struct sys_info sysinfo;
-	u8 reg8, cas_mask;
+	u8 reg8;
 
 	printk(BIOS_DEBUG, "Setting up RAM controller.\n");
 
@@ -3051,20 +2670,11 @@ void sdram_initialize(int boot_path, const u8 *spd_addresses)
 	/* Check whether we have stacked DIMMs */
 	sdram_verify_package_type(&sysinfo);
 
-	/* Determine common CAS */
-	cas_mask = sdram_possible_cas_latencies(&sysinfo);
+	/* Select common CAS latency and dram frequency */
+	select_cas_dramfreq(&sysinfo);
 
-	/* Choose Common Frequency */
-	sdram_detect_cas_latency_and_ram_speed(&sysinfo, cas_mask);
-
-	/* Determine smallest common tRAS */
-	sdram_detect_smallest_tRAS(&sysinfo);
-
-	/* Determine tRP */
-	sdram_detect_smallest_tRP(&sysinfo);
-
-	/* Determine tRCD */
-	sdram_detect_smallest_tRCD(&sysinfo);
+	/* Select nRAS, nRP, nRCD, nWR, tRFC */
+	select_dram_timings(&sysinfo);
 
 	/* Determine smallest refresh period */
 	sdram_detect_smallest_refresh(&sysinfo);
@@ -3072,15 +2682,9 @@ void sdram_initialize(int boot_path, const u8 *spd_addresses)
 	/* Verify all DIMMs support burst length 8 */
 	sdram_verify_burst_length(&sysinfo);
 
-	/* determine tWR */
-	sdram_detect_smallest_tWR(&sysinfo);
-
 	/* Determine DIMM size parameters (rows, columns banks) */
 	sdram_detect_dimm_size(&sysinfo);
 
-	/* determine tRFC */
-	sdram_detect_smallest_tRFC(&sysinfo);
-
 	/* Program PLL settings */
 	sdram_program_pll_settings(&sysinfo);
 
diff --git a/src/northbridge/intel/i945/raminit.h b/src/northbridge/intel/i945/raminit.h
index 0554900..0d5ed67 100644
--- a/src/northbridge/intel/i945/raminit.h
+++ b/src/northbridge/intel/i945/raminit.h
@@ -23,9 +23,12 @@
 /* Burst length is always 8 */
 #define BURSTLENGTH	 8
 
+#include <device/dram/ddr2.h>
+
 struct sys_info {
 	u16 memory_frequency;	/* 400, 533 or 667 */
 	u16 fsb_frequency;	/* 945GM: 400, 533 or 667 / 945GC: 533, 800, or 1066 */
+	u32 tclk;
 
 	u8 trp;			/* calculated by sdram_detect_smallest_tRP() */
 	u8 trcd;		/* calculated by sdram_detect_smallest_tRCD() */
@@ -50,14 +53,13 @@ struct sys_info {
 #define SYSINFO_PACKAGE_PLANAR		0x00
 #define SYSINFO_PACKAGE_STACKED		0x01
 	u8 dimm[2 * DIMM_SOCKETS];
+	dimm_attr dimm_decoded[2 * DIMM_SOCKETS];
 #define SYSINFO_DIMM_X16DS		0x00
 #define SYSINFO_DIMM_X8DS		0x01
 #define SYSINFO_DIMM_X16SS		0x02
 #define SYSINFO_DIMM_X8DDS		0x03
 #define SYSINFO_DIMM_NOT_POPULATED	0x04
 
-	u8 banks[2 * DIMM_SOCKETS];
-
 	u8 banksize[2 * 2 * DIMM_SOCKETS];
 	const u8 *spd_addresses;
 



More information about the coreboot-gerrit mailing list