nb/intel/i945/raminit.c: Refactor tRD selection

Inspired by gm45 code, which sets this value the same way.

Some values for tRD on 800 and 1067MHz FSB were set wrong because the
CAS/Freq selection was wrong. CAS was often selected to low and when
fixing CAS this results in tRD being too high, due to an incorrect
lookup table which caused instability.

PASSED memtest86+ during 10h+ on 1067MHZ fsb with 667MHz ddr2, CAS 5
on GA-945GCM-S2L.

Change-Id: I8002daf25b7603131b78b01075f43fd23747dd94
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/18354
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
This commit is contained in:
Arthur Heymans 2017-02-12 23:34:39 +01:00 committed by Martin Roth
parent 3397aa1fd4
commit 250272340b
1 changed files with 13 additions and 33 deletions

View File

@ -1775,21 +1775,11 @@ static void sdram_program_odt_tristate(struct sys_info *sysinfo)
static void sdram_set_timing_and_control(struct sys_info *sysinfo) static void sdram_set_timing_and_control(struct sys_info *sysinfo)
{ {
u32 reg32, off32; u32 reg32, tRD_min;
u32 tWTR; u32 tWTR;
u32 temp_drt; u32 temp_drt;
int i, page_size; int i, page_size;
static const u8 drt0_table[] = {
/* 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 */
5, 6, 7, /* FSB1066, DDR400 */
7, 8, 9, /* FSB1066, DDR533/DDR667 */
};
static const u8 cas_table[] = { static const u8 cas_table[] = {
2, 1, 0, 3 2, 1, 0, 3
}; };
@ -1841,34 +1831,24 @@ static void sdram_set_timing_and_control(struct sys_info *sysinfo)
/* CxDRT0 [23:22], [21:20], [19:18] [16] have fixed values */ /* CxDRT0 [23:22], [21:20], [19:18] [16] have fixed values */
temp_drt |= ((1 << 22) | (3 << 20) | (1 << 18) | (0 << 16)); temp_drt |= ((1 << 22) | (3 << 20) | (1 << 18) | (0 << 16));
/* Program Write Auto Precharge to Activate */ /*
off32 = 0; * tRD is the delay the memory controller is waiting on the FSB,
* in mclk domain.
* This parameter is important for stability and performance.
* Those values might not be optimal but seem stable.
*/
tRD_min = sysinfo->cas;
switch (sysinfo->fsb_frequency) { switch (sysinfo->fsb_frequency) {
case 533: case 533: break;
off32 = 0; case 667: tRD_min += 1;
break; break;
case 667: case 800: tRD_min += 2;
off32 = 3;
break; break;
case 800: case 1066: tRD_min += 3;
if (sysinfo->memory_frequency <= 533) {
off32 = 6;
break;
}
off32 = 9;
break;
case 1066:
if (sysinfo->memory_frequency == 400) {
off32 = 12;
break;
}
off32 = 15;
break; break;
} }
off32 += sysinfo->cas - 3; temp_drt |= (tRD_min << 11);
reg32 = drt0_table[off32];
temp_drt |= (reg32 << 11);
/* Read Auto Precharge to Activate */ /* Read Auto Precharge to Activate */