Arthur Heymans (arthur@aheymans.xyz) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18305
-gerrit
commit cdd7d79a4de7651578925b311059d7b91deebe16 Author: Arthur Heymans arthur@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@aheymans.xyz --- src/northbridge/intel/i945/Kconfig | 1 + src/northbridge/intel/i945/raminit.c | 594 ++++++----------------------------- src/northbridge/intel/i945/raminit.h | 6 +- 3 files changed, 104 insertions(+), 497 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 cc227cc..7f03612 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); @@ -1729,8 +1348,8 @@ static void sdram_set_timing_and_control(struct sys_info *sysinfo) /* CL 3, 4, 5 */ 3, 4, 5, /* FSB533, DDR667/533/400 */ 4, 5, 6, /* FSB667, DDR667/533/400 */ - 5, 6, 7, /* FSB800, DDR400/533 */ - 6, 7, 8, /* FSB800, DDR667 */ + 4, 5, 6, /* FSB800, DDR400/533 */ + 5, 6, 7, /* FSB800, DDR667 */ 5, 6, 7, /* FSB1066, DDR400 */ 7, 8, 9, /* FSB1066, DDR533/DDR667 */ }; @@ -3062,7 +2681,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");
@@ -3080,20 +2699,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 */ + select_dram_timings(&sysinfo);
/* Determine smallest refresh period */ sdram_detect_smallest_refresh(&sysinfo); @@ -3101,15 +2711,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;