nb/intel/sandybridge: support more XMP timings
Tested with a pair of GSkill F3-1866C9-8GSR. This makes sure in particular that we honor the CMD rate requested by the XMP profile. This memory kit needs a CMD rate of 2 to be stable at DDR3-1600 and up, even though it passes training at 1. Also respect requested CWL to match vendor firmware and for a potential increase in performance. The tested kit requests a tighter value than the per-frequency table provides and has shown to be stable using that setting. Change-Id: I634bed764d76345c27f02a2fae5abb2d81b38fd9 Signed-off-by: Dan Elkouby <streetwalkermc@gmail.com> Reviewed-on: https://review.coreboot.org/25664 Reviewed-by: Patrick Rudolph <siro@das-labor.org> Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
0c024208cd
commit
dabebc3716
|
@ -160,6 +160,8 @@ void dram_find_common_params(ramctr_timing *ctrl)
|
||||||
ctrl->tWTR = MAX(ctrl->tWTR, dimm->tWTR);
|
ctrl->tWTR = MAX(ctrl->tWTR, dimm->tWTR);
|
||||||
ctrl->tRTP = MAX(ctrl->tRTP, dimm->tRTP);
|
ctrl->tRTP = MAX(ctrl->tRTP, dimm->tRTP);
|
||||||
ctrl->tFAW = MAX(ctrl->tFAW, dimm->tFAW);
|
ctrl->tFAW = MAX(ctrl->tFAW, dimm->tFAW);
|
||||||
|
ctrl->tCWL = MAX(ctrl->tCWL, dimm->tCWL);
|
||||||
|
ctrl->tCMD = MAX(ctrl->tCMD, dimm->tCMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ctrl->cas_supported)
|
if (!ctrl->cas_supported)
|
||||||
|
@ -2350,12 +2352,16 @@ int command_training(ramctr_timing *ctrl)
|
||||||
* will fail in write training.
|
* will fail in write training.
|
||||||
* Workaround: Skip 1T in dual DIMM mode, that's only
|
* Workaround: Skip 1T in dual DIMM mode, that's only
|
||||||
* supported by a few DIMMs.
|
* supported by a few DIMMs.
|
||||||
* TODO: How to detect "1T" DIMMs ?
|
* Only try 1T mode for XMP DIMMs that request it in dual DIMM
|
||||||
|
* mode.
|
||||||
*
|
*
|
||||||
* Single DIMM per channel:
|
* Single DIMM per channel:
|
||||||
* Try command rate 1T and 2T
|
* Try command rate 1T and 2T
|
||||||
*/
|
*/
|
||||||
cmdrate = ((ctrl->rankmap[channel] & 0x5) == 0x5);
|
cmdrate = ((ctrl->rankmap[channel] & 0x5) == 0x5);
|
||||||
|
if (ctrl->tCMD)
|
||||||
|
/* XMP gives the CMD rate in clock ticks, not ns */
|
||||||
|
cmdrate = MIN(DIV_ROUND_UP(ctrl->tCMD, 256) - 1, 1);
|
||||||
|
|
||||||
for (; cmdrate < 2; cmdrate++) {
|
for (; cmdrate < 2; cmdrate++) {
|
||||||
err = try_cmd_stretch(ctrl, channel, cmdrate << 1);
|
err = try_cmd_stretch(ctrl, channel, cmdrate << 1);
|
||||||
|
|
|
@ -94,6 +94,8 @@ typedef struct ramctr_timing_st {
|
||||||
u32 tWTR;
|
u32 tWTR;
|
||||||
u32 tRTP;
|
u32 tRTP;
|
||||||
u32 tFAW;
|
u32 tFAW;
|
||||||
|
u32 tCWL;
|
||||||
|
u32 tCMD;
|
||||||
/* Latencies in terms of clock cycles
|
/* Latencies in terms of clock cycles
|
||||||
* They are saved separately as they are needed for DRAM MRS commands*/
|
* They are saved separately as they are needed for DRAM MRS commands*/
|
||||||
u8 CAS; /* CAS read latency */
|
u8 CAS; /* CAS read latency */
|
||||||
|
|
|
@ -479,6 +479,9 @@ static void dram_timing(ramctr_timing *ctrl)
|
||||||
/* DLL_CONFIG_MDLL_W_TIMER */
|
/* DLL_CONFIG_MDLL_W_TIMER */
|
||||||
ctrl->reg_5064b0 = (128000 / ctrl->tCK) + 3;
|
ctrl->reg_5064b0 = (128000 / ctrl->tCK) + 3;
|
||||||
|
|
||||||
|
if (ctrl->tCWL)
|
||||||
|
ctrl->CWL = DIV_ROUND_UP(ctrl->tCWL, ctrl->tCK);
|
||||||
|
else
|
||||||
ctrl->CWL = get_CWL(ctrl->tCK);
|
ctrl->CWL = get_CWL(ctrl->tCK);
|
||||||
printk(BIOS_DEBUG, "Selected CWL latency : %uT\n", ctrl->CWL);
|
printk(BIOS_DEBUG, "Selected CWL latency : %uT\n", ctrl->CWL);
|
||||||
|
|
||||||
|
|
|
@ -251,6 +251,9 @@ static void dram_timing(ramctr_timing *ctrl)
|
||||||
/* DLL_CONFIG_MDLL_W_TIMER */
|
/* DLL_CONFIG_MDLL_W_TIMER */
|
||||||
ctrl->reg_5064b0 = (128000 / ctrl->tCK) + 3;
|
ctrl->reg_5064b0 = (128000 / ctrl->tCK) + 3;
|
||||||
|
|
||||||
|
if (ctrl->tCWL)
|
||||||
|
ctrl->CWL = DIV_ROUND_UP(ctrl->tCWL, ctrl->tCK);
|
||||||
|
else
|
||||||
ctrl->CWL = get_CWL(ctrl->tCK);
|
ctrl->CWL = get_CWL(ctrl->tCK);
|
||||||
printk(BIOS_DEBUG, "Selected CWL latency : %uT\n", ctrl->CWL);
|
printk(BIOS_DEBUG, "Selected CWL latency : %uT\n", ctrl->CWL);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue