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 1eb9e8c4e1e8ee0e548923826ddede6364ae0ea2 Author: Arthur Heymans arthur@aheymans.xyz Date: Mon Feb 6 22:40:14 2017 +0100
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. The result of this is that dimms with multiple asymmetric ranks are not supported anymore. These however are very rare and most likely never tested on this platform.
Change-Id: I97c93939d11807752797785dd88c70b43a236ee3 Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- src/northbridge/intel/i945/raminit.c | 614 +++++++---------------------------- src/northbridge/intel/i945/raminit.h | 16 +- 2 files changed, 121 insertions(+), 509 deletions(-)
diff --git a/src/northbridge/intel/i945/raminit.c b/src/northbridge/intel/i945/raminit.c index 68d93eb..22e1476 100644 --- a/src/northbridge/intel/i945/raminit.c +++ b/src/northbridge/intel/i945/raminit.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2017 Arthur Heymans arthur@aheymans.xyz * * 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 @@ -28,6 +29,7 @@ #include "i945.h" #include "chip.h" #include <cbmem.h> +#include <device/dram/ddr2.h>
/* Debugging macros. */ #if CONFIG_DEBUG_RAM_SETUP @@ -315,8 +317,6 @@ 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; - /** * 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,40 @@ 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)); - if (spd_read_byte(device, SPD_MEMORY_TYPE) != SPD_MEMORY_TYPE_SDRAM_DDR2) { - printk(BIOS_DEBUG, "N/A\n"); + printk(BIOS_DEBUG, "DDR II Channel %d Socket %d: N/A\n", (i >> 1), (i & 1)); continue; }
- reg8 = spd_read_byte(device, SPD_DIMM_CONFIG_TYPE); - if (reg8 == ERROR_SCHEME_ECC) - die("Error: ECC memory not supported by this chipset\n"); + spd_size = spd_decode_spd_size_ddr2(spd_read_byte(device, 0)); + if (spd_size > sizeof(raw_spd)) + continue; + + for (j = 0; j < spd_size; j++) + raw_spd[j] = spd_read_byte(device, j); + + if (spd_decode_ddr2(&sysinfo->dimm_info[i], raw_spd) + != SPD_STATUS_OK) + continue; + + if (IS_ENABLED(CONFIG_DEBUG_RAM_SETUP)) + dram_print_spd_ddr2(&sysinfo->dimm_info[i]); + + if (sysinfo->dimm_info[i].flags.is_ecc) + die("\nError: 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) - die("Error: Registered memory not supported by this chipset\n"); + if (spd_dimm_is_registered_ddr2(sysinfo->dimm_info[i].dimm_type)) + die("\nError: Registered memory not supported by this chipset\n");
- 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_info[i].width) { case 0x08: - switch (spd_read_byte(device, SPD_NUM_DIMM_BANKS) & 0x0f) { - case 1: + switch (sysinfo->dimm_info[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 +412,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_info[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 +428,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))) { + /* Possibly does not boot in this case */ printk(BIOS_INFO, "Channel 0 has no memory populated.\n"); } } @@ -438,7 +448,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 +455,86 @@ 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_info[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) { - 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"); - } - - 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 - }; + u8 selected_cas; + u8 cas_mask = SPD_CAS_LATENCY_DDR2_3 | SPD_CAS_LATENCY_DDR2_4 + | SPD_CAS_LATENCY_DDR2_5; + u32 common_tCLK, min_tCLK = TCK_200MHZ;
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; - } - - 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; + case 400: min_tCLK = TCK_200MHZ; break; + case 533: min_tCLK = TCK_266MHZ; break; + case 667: min_tCLK = TCK_333MHZ; break; } - 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, sysinfo->dimm_info, + 2 * DIMM_SOCKETS, &selected_cas); + if (common_tCLK == 0) die("Could not find common memory frequency and CAS\n"); - } -} - -static void sdram_detect_smallest_tRAS(struct sys_info * sysinfo) -{ - int i; - int tRAS_time; - int tRAS_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 */ - } - - 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; -} - -static void sdram_detect_smallest_tRP(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; - - for (i = 0; i < 2*DIMM_SOCKETS; i++) { - u8 reg8; + common_tCLK = MAX(common_tCLK, min_tCLK);
- 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"); - } - - while (tRP_time < reg8) { - tRP_time += freq_multiplier; - tRP_cycles++; - } - } + sysinfo->cas = selected_cas; + sysinfo->tclk = common_tCLK;
- if (tRP_cycles > 6) { - die("DDR-II Module does not support this frequency (tRP error)\n"); + 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; } - - printk(BIOS_DEBUG, "tRP = %d cycles\n", tRP_cycles); - sysinfo->trp = tRP_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_tRCD(struct sys_info * sysinfo) +static void select_dram_timings(struct sys_info * sysinfo) { int i; - int tRCD_time; - int tRCD_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 */ - } - - tRCD_cycles = 2; /* 2 clocks minimum */ - tRCD_time = tRCD_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_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]); + tRAS_cycles = DIV_ROUND_UP(sysinfo->dimm_info[i].tRAS, tCLK); + if (tRAS_cycles > 0x18) + die("DDR-II Module does not support this frequency (tRAS error)\n"); + if (tRAS_cycles > sysinfo->tras) + sysinfo->tras = tRAS_cycles; + + tRP_cycles = DIV_ROUND_UP(sysinfo->dimm_info[i].tRP, tCLK); + if (tRP_cycles > 6) + die("DDR-II Module does not support this frequency (tRP error)\n"); + if (tRP_cycles > sysinfo->trp) + sysinfo->trp = tRP_cycles; + + tRCD_cycles = DIV_ROUND_UP(sysinfo->dimm_info[i].tRCD, tCLK); + if (tRCD_cycles > 6) + die("DDR-II Module does not support this frequency (tRCD error)\n"); + if (tRCD_cycles > sysinfo->trcd) + sysinfo->trcd = tRCD_cycles; + + tWR_cycles = DIV_ROUND_UP(sysinfo->dimm_info[i].tWR, tCLK); + if (tWR_cycles > 5) + die("DDR-II Module does not support this frequency (tWR error)\n"); + if (tWR_cycles > sysinfo->twr) + sysinfo->twr = tWR_cycles; + + tRFC_cycles = DIV_ROUND_UP(sysinfo->dimm_info[i].tRFC, tCLK); + if (tRFC_cycles > sysinfo->trfc) + sysinfo->trfc = tRFC_cycles; + + } + 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 +549,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_info[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 +575,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_info[i].flags.bl8) die("Only DDR-II RAM with burst length 8 is supported by this chipset.\n"); } } @@ -1376,121 +1102,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_info[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_info[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_info[i].ranks == 1) 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_info[i].ranksize_mb / 32; printk(BIOS_DEBUG, "DIMM %d side 1 = %d MB\n", i, sysinfo->banksize[(i * 2) + 1] * 32); } } @@ -1564,25 +1195,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_info[i].row_bits & 0x0f) + | (sysinfo->dimm_info[i].col_bits & 0xf) << 4;
switch (columnsrows) { case 0x9d: dra = 2; break; @@ -1630,7 +1255,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_info[i].banks != 8) continue;
printk(BIOS_SPEW, "DIMM%d has 8 banks.\n", i); @@ -3039,7 +2664,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");
@@ -3057,20 +2682,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); @@ -3078,15 +2694,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..965998a 100644 --- a/src/northbridge/intel/i945/raminit.h +++ b/src/northbridge/intel/i945/raminit.h @@ -23,15 +23,18 @@ /* 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() */ - u8 tras; /* calculated by sdram_detect_smallest_tRAS() */ - u8 trfc; /* calculated by sdram_detect_smallest_tRFC() */ - u8 twr; /* calculated by sdram_detect_smallest_tWR() */ + u8 trp; + u8 trcd; + u8 tras; + u8 trfc; + u8 twr;
u8 cas; /* 3, 4 or 5 */ u8 refresh; /* 0 = 15.6us, 1 = 7.8us */ @@ -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_info[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;