[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
Fri Feb 10 15:25:31 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 a36b251f908af542e6540d5e1f693c5894c7ad30
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
Change-Id: I97c93939d11807752797785dd88c70b43a236ee3
Signed-off-by: Arthur Heymans <arthur at aheymans.xyz>
---
src/northbridge/intel/i945/Kconfig | 1 +
src/northbridge/intel/i945/raminit.c | 483 ++++++++---------------------------
src/northbridge/intel/i945/raminit.h | 5 +-
3 files changed, 116 insertions(+), 373 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..f53c6db 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));
- if (spd_read_byte(device, SPD_MEMORY_TYPE) != SPD_MEMORY_TYPE_SDRAM_DDR2) {
- printk(BIOS_DEBUG, "N/A\n");
+ for (j = 0; j < spd_size; j++)
+ raw_spd[j] = spd_read_byte(device, j);
+
+ if (spd_decode_ddr2(&dimm, raw_spd) == SPD_STATUS_INVALID)
continue;
- }
+ dram_print_spd_ddr2(&dimm);
+
+ sysinfo->dimm_decoded[i] = dimm;
- reg8 = spd_read_byte(device, SPD_DIMM_CONFIG_TYPE);
- if (reg8 == ERROR_SCHEME_ECC)
+ 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,314 +452,85 @@ 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)
{
- int i;
- u8 cas_mask;
+ dimm_attr dimm[2 * DIMM_SOCKETS];
+ u8 selected_freq, selected_cas;
+ int max_ram_speed = 0, i;
+ int ret;
+ u8 cas_mask = SPD_CAS_LATENCY_DDR2_3 | SPD_CAS_LATENCY_DDR2_4
+ | SPD_CAS_LATENCY_DDR2_5;
- /* 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
- };
+ 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;
- }
-
- 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: max_ram_speed = DDR2_200MHZ; break;
+ case 533: max_ram_speed = DDR2_266MHZ; break;
+ case 667: max_ram_speed = DDR2_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 {
+ ret = get_common_freq_cas(max_ram_speed, cas_mask,
+ dimm, 2 * DIMM_SOCKETS, &selected_freq,
+ &selected_cas);
+ if (ret)
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 */
+ sysinfo->cas = selected_cas;
+ switch (selected_freq) {
+ case DDR2_200MHZ: sysinfo->memory_frequency = 400; break;
+ case DDR2_266MHZ: sysinfo->memory_frequency = 533; break;
+ case DDR2_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;
-}
-
-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++;
- }
- }
-
- 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 */
- }
-
- 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;
+ printk(BIOS_DEBUG, "Memory will be driven at %dMHz with CAS=%d clocks\n",
+ sysinfo->cas, sysinfo->memory_frequency);
}
-static void sdram_detect_smallest_tWR(struct sys_info * sysinfo)
+static void select_dram_timings(struct sys_info * sysinfo)
{
int i;
- int tWR_time;
- int tWR_cycles;
- int freq_multiplier = 0;
+ int tCLK = 0;
+ int tRAS_cycles, tRP_cycles, tRCD_cycles, tWR_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 */
+ case 400: tCLK = TCK_200MHZ; break;
+ case 533: tCLK = TCK_266MHZ; break;
+ case 667: tCLK = TCK_333MHZ; break;
}
- 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;
+ tRAS_cycles = sysinfo->dimm_decoded[i].tRAS / tCLK +
+ ((sysinfo->dimm_decoded[i].tRAS % tCLK) ? 1 : 0);
+ if (tRAS_cycles > sysinfo->tras)
+ sysinfo->tras = tRAS_cycles;
+
+ tRP_cycles = sysinfo->dimm_decoded[i].tRP / tCLK +
+ ((sysinfo->dimm_decoded[i].tRP % tCLK) ? 1 : 0);
+ if (tRP_cycles > sysinfo->trp)
+ sysinfo->trp = tRP_cycles;
+
+ tRCD_cycles = sysinfo->dimm_decoded[i].tRCD / tCLK +
+ ((sysinfo->dimm_decoded[i].tRCD % tCLK) ? 1 : 0);
+ if (tRCD_cycles > sysinfo->trcd)
+ sysinfo->trcd = tRCD_cycles;
+
+ tWR_cycles = sysinfo->dimm_decoded[i].tWR / tCLK +
+ ((sysinfo->dimm_decoded[i].tWR % tCLK) ? 1 : 0);
+ if (tWR_cycles > sysinfo->twr)
+ sysinfo->twr = tWR_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);
}
static void sdram_detect_smallest_tRFC(struct sys_info * sysinfo)
@@ -819,23 +596,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 +622,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");
}
}
@@ -1385,47 +1158,36 @@ 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;
+ int value, rows, columns;
- device = get_dimm_spd_address(sysinfo, dimmno);
sz.side1 = 0;
sz.side2 = 0;
- rows = spd_read_byte(device, SPD_NUM_ROWS); /* rows */
+ rows = sysinfo->dimm_decoded[dimmno].row_bits;
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 */
+ columns = sysinfo->dimm_decoded[dimmno].col_bits;
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 */
+ value = sysinfo->dimm_decoded[dimmno].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) */
+ value = sysinfo->dimm_decoded[dimmno].mod_width;
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;
+ switch (sysinfo->dimm_decoded[dimmno].ranks) {
+ case 1: goto out;
+ case 2: break;
+ default: goto val_err;
+ }
/* Start with the symmetrical case */
sz.side2 = sz.side1;
@@ -1472,9 +1234,6 @@ static void sdram_detect_dimm_size(struct sys_info * sysinfo)
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");
@@ -1564,25 +1323,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 +1383,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 +1482,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 +2815,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 +2833,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,9 +2845,6 @@ 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);
diff --git a/src/northbridge/intel/i945/raminit.h b/src/northbridge/intel/i945/raminit.h
index 0554900..56d30e5 100644
--- a/src/northbridge/intel/i945/raminit.h
+++ b/src/northbridge/intel/i945/raminit.h
@@ -23,6 +23,8 @@
/* 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 */
@@ -50,14 +52,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