diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/northbridge/intel/i945/raminit.c | 852 | ||||
-rw-r--r-- | src/northbridge/intel/i945/raminit.h | 14 |
2 files changed, 226 insertions, 640 deletions
diff --git a/src/northbridge/intel/i945/raminit.c b/src/northbridge/intel/i945/raminit.c index f10f1088d6..a9d183cb31 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 IS_ENABLED(CONFIG_DEBUG_RAM_SETUP) @@ -283,7 +285,8 @@ static void sdram_detect_errors(struct sys_info *sysinfo) pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, reg8); /* clear self refresh status if check is disabled or not a resume */ - if (!CONFIG_CHECK_SLFRCS_ON_RESUME || sysinfo->boot_path != BOOT_PATH_RESUME) { + if (!CONFIG_CHECK_SLFRCS_ON_RESUME + || sysinfo->boot_path != BOOT_PATH_RESUME) { MCHBAR8(SLFRCS) |= 3; } else { /* Validate self refresh config */ @@ -307,21 +310,32 @@ static void sdram_detect_errors(struct sys_info *sysinfo) } } +struct timings { + u32 min_tCLK_cas[8]; + u32 min_tRAS; + u32 min_tRP; + u32 min_tRCD; + u32 min_tWR; + u32 min_tRFC; + u32 max_tRR; + u8 cas_mask; +}; + /** - * @brief Get generic DIMM parameters. - * @param sysinfo Central memory controller information structure - * - * This function gathers several pieces of information for each system DIMM: - * o DIMM width (x8 / x16) - * o DIMM sides (single sided / dual sided) - * - * Also, some non-supported scenarios are detected. + * @brief loop over dimms and save maximal timings */ - -static void sdram_get_dram_configuration(struct sys_info *sysinfo) +static void gather_common_timing(struct sys_info *sysinfo, + struct timings *saved_timings) { - u32 dimm_mask = 0; - int i; + + int i, j; + u8 raw_spd[SPD_SIZE_MAX_DDR2]; + u8 dimm_mask = 0; + + memset(saved_timings, 0, sizeof(*saved_timings)); + saved_timings->max_tRR = UINT32_MAX; + saved_timings->cas_mask = SPD_CAS_LATENCY_DDR2_3 + | SPD_CAS_LATENCY_DDR2_4 | SPD_CAS_LATENCY_DDR2_5; /** * i945 supports two DIMMs, in two configurations: @@ -336,36 +350,19 @@ static void sdram_get_dram_configuration(struct sys_info *sysinfo) * but for now we stick with the information we gather via SPD. */ + printk(BIOS_DEBUG, "This mainboard supports "); if (sdram_capabilities_dual_channel()) { sysinfo->dual_channel = 1; - printk(BIOS_DEBUG, "This mainboard supports Dual Channel Operation.\n"); + printk(BIOS_DEBUG, "Dual Channel Operation.\n"); } else { sysinfo->dual_channel = 0; - printk(BIOS_DEBUG, "This mainboard supports only Single Channel Operation.\n"); + printk(BIOS_DEBUG, "only Single Channel Operation.\n"); } - /** - * Since we only support two DIMMs in total, there is a limited number - * of combinations. This function returns the type of DIMMs. - * return value: - * [0:7] lower DIMM population - * [8-15] higher DIMM population - * [16] dual channel? - * - * There are 5 different possible populations for a DIMM socket: - * 1. x16 double sided (X16DS) - * 2. x8 double sided (X8DS) - * 3. x16 single sided (X16SS) - * 4. x8 double stacked (X8DDS) - * 5. not populated (NC) - * - * For the return value we start counting at zero. - * - */ for (i = 0; i < (2 * DIMM_SOCKETS); i++) { - int device = get_dimm_spd_address(sysinfo, i); - u8 reg8; + int device = get_dimm_spd_address(sysinfo, i), bytes_read; + struct dimm_attr_st dimm_info; /* Initialize the socket information with a sane value */ sysinfo->dimm[i] = SYSINFO_DIMM_NOT_POPULATED; @@ -374,31 +371,62 @@ 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"); + if (spd_read_byte(device, SPD_MEMORY_TYPE) != + SPD_MEMORY_TYPE_SDRAM_DDR2) { + 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"); - - 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"); + /* + * spd_decode_ddr2() needs a 128-byte sized array but + * only the first 64 bytes contain data needed for raminit. + */ - switch (spd_read_byte(device, SPD_PRIMARY_SDRAM_WIDTH)) { - case 0x08: - switch (spd_read_byte(device, SPD_NUM_DIMM_BANKS) & 0x0f) { - case 1: + bytes_read = i2c_block_read(device, 0, 64, raw_spd); + printk(BIOS_DEBUG, "Reading SPD using i2c block operation.\n"); + if (IS_ENABLED(CONFIG_DEBUG_RAM_SETUP) && bytes_read > 0) + hexdump(raw_spd, bytes_read); + if (bytes_read != 64 || spd_decode_ddr2(&dimm_info, raw_spd) + != SPD_STATUS_OK) { + /* Try again with SMBUS byte read */ + printk(BIOS_DEBUG, "i2c block operation failed," + "trying smbus byte operation.\n"); + for (j = 0; j < 64; j++) + raw_spd[j] = spd_read_byte(device, j); + if (IS_ENABLED(CONFIG_DEBUG_RAM_SETUP)) + hexdump(raw_spd, 64); + if (spd_decode_ddr2(&dimm_info, raw_spd) + != SPD_STATUS_OK) + continue; + } + if (IS_ENABLED(CONFIG_DEBUG_RAM_SETUP)) + dram_print_spd_ddr2(&dimm_info); + + if (dimm_info.flags.is_ecc) + die("\nError: ECC memory not supported by this chipset\n"); + + if (spd_dimm_is_registered_ddr2(dimm_info.dimm_type)) + die("\nError: Registered memory not supported by this chipset\n"); + + printk(BIOS_DEBUG, "DDR II Channel %d Socket %d: ", (i >> 1), + (i & 1)); + /** + * There are 5 different possible populations for a DIMM socket: + * 0. x16 double ranked (X16DS) + * 1. x8 double ranked (X8DS) + * 2. x16 single ranked (X16SS) + * 3. x8 double stacked (X8DDS) + * 4. Unpopulated + */ + switch (dimm_info.width) { + case 8: + switch (dimm_info.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; @@ -406,13 +434,13 @@ static void sdram_get_dram_configuration(struct sys_info *sysinfo) printk(BIOS_DEBUG, "Unsupported.\n"); } break; - case 0x10: - switch (spd_read_byte(device, SPD_NUM_DIMM_BANKS) & 0x0f) { - case 1: + case 16: + switch (dimm_info.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; @@ -424,449 +452,178 @@ static void sdram_get_dram_configuration(struct sys_info *sysinfo) 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))) - printk(BIOS_INFO, "Channel 0 has no memory populated.\n"); -} - -/** - * @brief determine if any DIMMs are stacked - * - * @param sysinfo central sysinfo data structure. - */ -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++) { - if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED) - continue; - /* Is the current DIMM a stacked DIMM? */ - if (spd_read_byte(get_dimm_spd_address(sysinfo, i), SPD_NUM_DIMM_BANKS) & (1 << 4)) - sysinfo->package = 1; - } -} - -static u8 sdram_possible_cas_latencies(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 - }; - - 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; - } + if (dimm_info.flags.stacked) + sysinfo->package = SYSINFO_PACKAGE_STACKED; - 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 { - 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; + if (!dimm_info.flags.bl8) + die("Only DDR-II RAM with burst length 8 is supported by this chipset.\n"); - reg8 = spd_read_byte(get_dimm_spd_address(sysinfo, i), SPD_MIN_ACTIVE_TO_PRECHARGE_DELAY); - if (!reg8) - die("Invalid tRAS value.\n"); + if (dimm_info.ranksize_mb < 128) + die("DDR-II rank size smaller than 128MB is not supported.\n"); - while ((tRAS_time >> 2) < reg8) { - tRAS_time += freq_multiplier; - tRAS_cycles++; + sysinfo->banksize[i * 2] = dimm_info.ranksize_mb / 32; + printk(BIOS_DEBUG, "DIMM %d side 0 = %d MB\n", i, + sysinfo->banksize[i * 2] * 32); + if (dimm_info.ranks == 2) { + sysinfo->banksize[(i * 2) + 1] = + dimm_info.ranksize_mb / 32; + printk(BIOS_DEBUG, "DIMM %d side 1 = %d MB\n", + i, sysinfo->banksize[(i * 2) + 1] * 32); } - } - 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; - - 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->rows[i] = dimm_info.row_bits; + sysinfo->cols[i] = dimm_info.col_bits; + sysinfo->banks[i] = dimm_info.banks; + + /* int min_tRAS, min_tRP, min_tRCD, min_tWR, min_tRFC; */ + saved_timings->min_tRAS = MAX(saved_timings->min_tRAS, + dimm_info.tRAS); + saved_timings->min_tRP = MAX(saved_timings->min_tRP, + dimm_info.tRP); + saved_timings->min_tRCD = MAX(saved_timings->min_tRCD, + dimm_info.tRCD); + saved_timings->min_tWR = MAX(saved_timings->min_tWR, + dimm_info.tWR); + saved_timings->min_tRFC = MAX(saved_timings->min_tRFC, + dimm_info.tRFC); + saved_timings->max_tRR = MIN(saved_timings->max_tRR, + dimm_info.tRR); + saved_timings->cas_mask &= dimm_info.cas_supported; + for (j = 0; j < 8; j++) { + if (!(saved_timings->cas_mask & (1 << j))) + saved_timings->min_tCLK_cas[j] = 0; + else + saved_timings->min_tCLK_cas[j] = + MAX(dimm_info.cycle_time[j], + saved_timings->min_tCLK_cas[j]); } + dimm_mask |= (1 << i); } - - if (tRP_cycles > 6) - die("DDR-II Module does not support this frequency (tRP error)\n"); - - printk(BIOS_DEBUG, "tRP = %d cycles\n", tRP_cycles); - sysinfo->trp = tRP_cycles; -} - -static void sdram_detect_smallest_tRCD(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 */ + if (!dimm_mask) { + die("No memory installed.\n"); } - 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 (!(dimm_mask & ((1 << DIMM_SOCKETS) - 1))) { + /* Possibly does not boot in this case */ + printk(BIOS_INFO, "Channel 0 has no memory populated.\n"); } - 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) +static void choose_tclk(struct sys_info *sysinfo, + struct timings *saved_timings) { - 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; + u32 ctrl_min_tclk; + int try_cas; - if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED) - continue; + ctrl_min_tclk = 2 * 256 * 1000 + / sdram_capabilities_max_supported_memory_frequency(); + normalize_tck(&ctrl_min_tclk); - reg8 = spd_read_byte(get_dimm_spd_address(sysinfo, i), SPD_WRITE_RECOVERY_TIME); - if (!reg8) - die("Invalid tWR value.\n"); + try_cas = spd_get_msbs(saved_timings->cas_mask); - while (tWR_time < reg8) { - tWR_time += freq_multiplier; - tWR_cycles++; - } + while (saved_timings->cas_mask & (1 << try_cas) && try_cas > 0) { + sysinfo->cas = try_cas; + sysinfo->tclk = saved_timings->min_tCLK_cas[try_cas]; + if (sysinfo->tclk >= ctrl_min_tclk && + saved_timings->min_tCLK_cas[try_cas] != + saved_timings->min_tCLK_cas[try_cas - 1]) + break; + try_cas--; } - 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++; + normalize_tck(&sysinfo->tclk); - 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 ((sysinfo->cas < 3) || (sysinfo->tclk == 0)) + die("Could not find common memory frequency and CAS\n"); - if (reg8 > index) - index = reg8; + /* + * The loop can still results in a timing too fast for the + * memory controller. + */ + if (sysinfo->tclk < ctrl_min_tclk) + sysinfo->tclk = ctrl_min_tclk; - } - index--; - switch (sysinfo->memory_frequency) { - case 667: - index += 3; /* Fallthrough */ - case 533: - index += 3; /* Fallthrough */ - case 400: + 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; } - sysinfo->trfc = tRFC_cycles[index]; - printk(BIOS_DEBUG, "tRFC = %d cycles\n", tRFC_cycles[index]); + printk(BIOS_DEBUG, + "Memory will be driven at %dMT with CAS=%d clocks\n", + sysinfo->memory_frequency, sysinfo->cas); } -static void sdram_detect_smallest_refresh(struct sys_info *sysinfo) +static void derive_timings(struct sys_info *sysinfo, + struct timings *saved_timings) { - int i; + sysinfo->tras = DIV_ROUND_UP(saved_timings->min_tRAS, sysinfo->tclk); + if (sysinfo->tras > 0x18) + die("DDR-II Module does not support this frequency (tRAS error)\n"); - sysinfo->refresh = 0; + sysinfo->trp = DIV_ROUND_UP(saved_timings->min_tRP, sysinfo->tclk); + if (sysinfo->trp > 6) + die("DDR-II Module does not support this frequency (tRP error)\n"); - for (i = 0; i < 2*DIMM_SOCKETS; i++) { - int refresh; + sysinfo->trcd = DIV_ROUND_UP(saved_timings->min_tRCD, sysinfo->tclk); + if (sysinfo->trcd > 6) + die("DDR-II Module does not support this frequency (tRCD error)\n"); - if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED) - continue; + sysinfo->twr = DIV_ROUND_UP(saved_timings->min_tWR, sysinfo->tclk); + if (sysinfo->twr > 5) + die("DDR-II Module does not support this frequency (tWR error)\n"); - refresh = spd_read_byte(get_dimm_spd_address(sysinfo, i), - SPD_REFRESH) & ~(1 << 7); + sysinfo->trfc = DIV_ROUND_UP(saved_timings->min_tRFC, sysinfo->tclk); - /* 15.6us */ - if (!refresh) - continue; + 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); - /* Refresh is slower than 15.6us, use 15.6us */ - if (refresh > 2) - continue; + /* Refresh is slower than 15.6us, use 15.6us */ + /* tRR is decoded in units of 1/256us */ - if (refresh == 2) { - sysinfo->refresh = 1; - break; - } +#define T_RR_7_8US 2000000 +#define T_RR_15_6US 4000000 +#define REFRESH_7_8US 1 +#define REFRESH_15_6US 0 + if (saved_timings->max_tRR < T_RR_7_8US) die("DDR-II module has unsupported refresh value\n"); - } + else if (saved_timings->max_tRR < T_RR_15_6US) + sysinfo->refresh = REFRESH_7_8US; + else + sysinfo->refresh = REFRESH_15_6US; printk(BIOS_DEBUG, "Refresh: %s\n", sysinfo->refresh?"7.8us":"15.6us"); } -static void sdram_verify_burst_length(struct sys_info *sysinfo) -{ - int i; +/** + * @brief Get generic DIMM parameters. + * @param sysinfo Central memory controller information structure + * + * This function gathers several pieces of information for each system DIMM: + * o DIMM width (x8 / x16) + * o DIMM rank (single ranked / dual ranked) + * + * Also, some non-supported scenarios are detected. + */ - for (i = 0; i < 2*DIMM_SOCKETS; i++) { - if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED) - continue; +static void sdram_get_dram_configuration(struct sys_info *sysinfo) +{ + struct timings saved_timings; - if (!(spd_read_byte(get_dimm_spd_address(sysinfo, i), - SPD_SUPPORTED_BURST_LENGTHS) & SPD_BURST_LENGTH_8)) - die("Only DDR-II RAM with burst length 8 is supported by this chipset.\n"); - } + gather_common_timing(sysinfo, &saved_timings); + choose_tclk(sysinfo, &saved_timings); + derive_timings(sysinfo, &saved_timings); } static void sdram_program_dram_width(struct sys_info *sysinfo) @@ -1419,138 +1176,6 @@ 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) - die("DDR-II rank size smaller than 128MB is not supported.\n"); - - sysinfo->banksize[i * 2] = 1 << (sz.side1 - 28); - - printk(BIOS_DEBUG, "DIMM %d side 0 = %d MB\n", i, sysinfo->banksize[i * 2] * 32); - - if (!sz.side2) - 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); - - printk(BIOS_DEBUG, "DIMM %d side 1 = %d MB\n", i, sysinfo->banksize[(i * 2) + 1] * 32); - } -} - static int sdram_program_row_boundaries(struct sys_info *sysinfo) { int i; @@ -1620,24 +1245,18 @@ 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->rows[i] & 0x0f) + | (sysinfo->cols[i] & 0xf) << 4; switch (columnsrows) { case 0x9d: @@ -1702,8 +1321,6 @@ static void sdram_set_bank_architecture(struct sys_info *sysinfo) } } -#define REFRESH_7_8US 1 -#define REFRESH_15_6US 0 static void sdram_program_refresh_rate(struct sys_info *sysinfo) { u32 reg32; @@ -3116,7 +2733,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"); @@ -3131,39 +2748,6 @@ void sdram_initialize(int boot_path, const u8 *spd_addresses) /* If error, do cold boot */ sdram_detect_errors(&sysinfo); - /* Check whether we have stacked DIMMs */ - sdram_verify_package_type(&sysinfo); - - /* Determine common CAS */ - cas_mask = sdram_possible_cas_latencies(&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); - - /* Determine smallest refresh period */ - sdram_detect_smallest_refresh(&sysinfo); - - /* 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 4c97d05b7d..7d8555774e 100644 --- a/src/northbridge/intel/i945/raminit.h +++ b/src/northbridge/intel/i945/raminit.h @@ -28,12 +28,13 @@ 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 */ @@ -52,6 +53,8 @@ struct sys_info { #define SYSINFO_PACKAGE_PLANAR 0x00 #define SYSINFO_PACKAGE_STACKED 0x01 u8 dimm[2 * DIMM_SOCKETS]; + u8 rows[2 * DIMM_SOCKETS]; + u8 cols[2 * DIMM_SOCKETS]; #define SYSINFO_DIMM_X16DS 0x00 #define SYSINFO_DIMM_X8DS 0x01 #define SYSINFO_DIMM_X16SS 0x02 @@ -59,7 +62,6 @@ struct sys_info { #define SYSINFO_DIMM_NOT_POPULATED 0x04 u8 banks[2 * DIMM_SOCKETS]; - u8 banksize[2 * 2 * DIMM_SOCKETS]; const u8 *spd_addresses; |