diff options
author | Arthur Heymans <arthur@aheymans.xyz> | 2017-05-16 17:58:25 +0200 |
---|---|---|
committer | Arthur Heymans <arthur@aheymans.xyz> | 2017-06-12 11:42:56 +0200 |
commit | dcd3cef8744b9d126370565fb3551a1fced8ab04 (patch) | |
tree | 2094823e83af0f34bb964ce3e5e3b2b25de812cf | |
parent | f6934f5c6c32af9261a6f45d0c3eaf1ad45b2d32 (diff) | |
download | coreboot-dcd3cef8744b9d126370565fb3551a1fced8ab04.tar.xz |
nb/intel/sandybridge: Improve CAS freq selection
The previous code seemed weird and tried to check if its selected
value is supported three times.
This also lower the clock if a selected frequency does not result in a
supported CAS number.
Change-Id: I97244bc3940813c5a5fcbd770d71cca76d21fcae
Signed-off-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-on: https://review.coreboot.org/19716
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Patrick Rudolph <siro@das-labor.org>
-rw-r--r-- | src/include/device/dram/ddr3.h | 2 | ||||
-rw-r--r-- | src/northbridge/intel/sandybridge/raminit_sandy.c | 119 |
2 files changed, 65 insertions, 56 deletions
diff --git a/src/include/device/dram/ddr3.h b/src/include/device/dram/ddr3.h index 11f98c56af..9597a3140b 100644 --- a/src/include/device/dram/ddr3.h +++ b/src/include/device/dram/ddr3.h @@ -39,6 +39,8 @@ * These values are in 1/256 ns units. * @{ */ +#define NS2MHZ_DIV256 1000 << 8 + #define TCK_1333MHZ 192 #define TCK_1200MHZ 212 #define TCK_1100MHZ 232 diff --git a/src/northbridge/intel/sandybridge/raminit_sandy.c b/src/northbridge/intel/sandybridge/raminit_sandy.c index 084c6ec38a..3acc5631a3 100644 --- a/src/northbridge/intel/sandybridge/raminit_sandy.c +++ b/src/northbridge/intel/sandybridge/raminit_sandy.c @@ -136,16 +136,65 @@ static u32 get_COMP2(u32 tCK) return frq_comp2_map[get_FRQ(tCK) - 3]; } -static void dram_timing(ramctr_timing * ctrl) +static void snb_normalize_tclk(u32 *tclk) +{ + if (*tclk <= TCK_1066MHZ) { + *tclk = TCK_1066MHZ; + } else if (*tclk <= TCK_933MHZ) { + *tclk = TCK_933MHZ; + } else if (*tclk <= TCK_800MHZ) { + *tclk = TCK_800MHZ; + } else if (*tclk <= TCK_666MHZ) { + *tclk = TCK_666MHZ; + } else if (*tclk <= TCK_533MHZ) { + *tclk = TCK_533MHZ; + } else if (*tclk <= TCK_400MHZ) { + *tclk = TCK_400MHZ; + } else { + *tclk = 0; + } +} + +static void find_cas_tck(ramctr_timing *ctrl) { u8 val; u32 val32; + /* Find CAS latency */ + while (1) { + /* Normalising tCK before computing clock could potentially + * results in lower selected CAS, which is desired. + */ + snb_normalize_tclk(&(ctrl->tCK)); + if (!(ctrl->tCK)) + die("Couldn't find compatible clock / CAS settings\n"); + val = DIV_ROUND_UP(ctrl->tAA, ctrl->tCK); + printk(BIOS_DEBUG, "Trying CAS %u, tCK %u.\n", val, ctrl->tCK); + for (; val <= MAX_CAS; val++) + if ((ctrl->cas_supported >> (val - MIN_CAS)) & 1) + break; + if (val == (MAX_CAS + 1)) { + ctrl->tCK++; + continue; + } else { + printk(BIOS_DEBUG, "Found compatible clock, CAS pair.\n"); + break; + } + } + + val32 = NS2MHZ_DIV256 / ctrl->tCK; + printk(BIOS_DEBUG, "Selected DRAM frequency: %u MHz\n", val32); + + printk(BIOS_DEBUG, "Selected CAS latency : %uT\n", val); + ctrl->CAS = val; +} + +static void dram_timing(ramctr_timing *ctrl) +{ /* Maximum supported DDR3 frequency is 1066MHz (DDR3 2133) so make sure * we cap it if we have faster DIMMs. * Then, align it to the closest JEDEC standard frequency */ - if (ctrl->tCK <= TCK_1066MHZ) { - ctrl->tCK = TCK_1066MHZ; + if (ctrl->tCK == TCK_1066MHZ) { ctrl->edge_offset[0] = 16; ctrl->edge_offset[1] = 7; ctrl->edge_offset[2] = 7; @@ -153,8 +202,7 @@ static void dram_timing(ramctr_timing * ctrl) ctrl->timC_offset[1] = 7; ctrl->timC_offset[2] = 7; ctrl->reg_320c_range_threshold = 13; - } else if (ctrl->tCK <= TCK_933MHZ) { - ctrl->tCK = TCK_933MHZ; + } else if (ctrl->tCK == TCK_933MHZ) { ctrl->edge_offset[0] = 14; ctrl->edge_offset[1] = 6; ctrl->edge_offset[2] = 6; @@ -162,8 +210,7 @@ static void dram_timing(ramctr_timing * ctrl) ctrl->timC_offset[1] = 6; ctrl->timC_offset[2] = 6; ctrl->reg_320c_range_threshold = 15; - } else if (ctrl->tCK <= TCK_800MHZ) { - ctrl->tCK = TCK_800MHZ; + } else if (ctrl->tCK == TCK_800MHZ) { ctrl->edge_offset[0] = 13; ctrl->edge_offset[1] = 5; ctrl->edge_offset[2] = 5; @@ -171,8 +218,7 @@ static void dram_timing(ramctr_timing * ctrl) ctrl->timC_offset[1] = 5; ctrl->timC_offset[2] = 5; ctrl->reg_320c_range_threshold = 15; - } else if (ctrl->tCK <= TCK_666MHZ) { - ctrl->tCK = TCK_666MHZ; + } else if (ctrl->tCK == TCK_666MHZ) { ctrl->edge_offset[0] = 10; ctrl->edge_offset[1] = 4; ctrl->edge_offset[2] = 4; @@ -180,8 +226,7 @@ static void dram_timing(ramctr_timing * ctrl) ctrl->timC_offset[1] = 4; ctrl->timC_offset[2] = 4; ctrl->reg_320c_range_threshold = 16; - } else if (ctrl->tCK <= TCK_533MHZ) { - ctrl->tCK = TCK_533MHZ; + } else if (ctrl->tCK == TCK_533MHZ) { ctrl->edge_offset[0] = 8; ctrl->edge_offset[1] = 3; ctrl->edge_offset[2] = 3; @@ -206,30 +251,6 @@ static void dram_timing(ramctr_timing * ctrl) /* DLL_CONFIG_MDLL_W_TIMER */ ctrl->reg_5064b0 = (128000 / ctrl->tCK) + 3; - val32 = (1000 << 8) / ctrl->tCK; - printk(BIOS_DEBUG, "Selected DRAM frequency: %u MHz\n", val32); - - /* Find CAS latency */ - val = DIV_ROUND_UP(ctrl->tAA, ctrl->tCK); - printk(BIOS_DEBUG, "Minimum CAS latency : %uT\n", val); - /* Find lowest supported CAS latency that satisfies the minimum value */ - while (!((ctrl->cas_supported >> (val - MIN_CAS)) & 1) - && (ctrl->cas_supported >> (val - MIN_CAS))) { - val++; - } - /* Is CAS supported */ - if (!(ctrl->cas_supported & (1 << (val - MIN_CAS)))) { - printk(BIOS_ERR, "CAS %uT not supported. ", val); - val = MAX_CAS; - /* Find highest supported CAS latency */ - while (!((ctrl->cas_supported >> (val - MIN_CAS)) & 1)) - val--; - - printk(BIOS_ERR, "Using CAS %uT instead.\n", val); - } - - printk(BIOS_DEBUG, "Selected CAS latency : %uT\n", val); - ctrl->CAS = val; ctrl->CWL = get_CWL(ctrl->tCK); printk(BIOS_DEBUG, "Selected CWL latency : %uT\n", ctrl->CWL); @@ -280,32 +301,18 @@ static void dram_timing(ramctr_timing * ctrl) static void dram_freq(ramctr_timing * ctrl) { + if (ctrl->tCK > TCK_400MHZ) { - printk (BIOS_ERR, "DRAM frequency is under lowest supported " - "frequency (400 MHz). Increasing to 400 MHz as last resort"); + printk(BIOS_ERR, "DRAM frequency is under lowest supported " + "frequency (400 MHz). Increasing to 400 MHz as last resort"); ctrl->tCK = TCK_400MHZ; } + while (1) { u8 val2; u32 reg1 = 0; - /* Step 1 - Set target PCU frequency */ - - if (ctrl->tCK <= TCK_1066MHZ) { - ctrl->tCK = TCK_1066MHZ; - } else if (ctrl->tCK <= TCK_933MHZ) { - ctrl->tCK = TCK_933MHZ; - } else if (ctrl->tCK <= TCK_800MHZ) { - ctrl->tCK = TCK_800MHZ; - } else if (ctrl->tCK <= TCK_666MHZ) { - ctrl->tCK = TCK_666MHZ; - } else if (ctrl->tCK <= TCK_533MHZ) { - ctrl->tCK = TCK_533MHZ; - } else if (ctrl->tCK <= TCK_400MHZ) { - ctrl->tCK = TCK_400MHZ; - } else { - die ("No lock frequency found"); - } + find_cas_tck(ctrl); /* Frequency multiplier. */ u32 FRQ = get_FRQ(ctrl->tCK); @@ -318,7 +325,7 @@ static void dram_freq(ramctr_timing * ctrl) if (val2) return; - /* Step 2 - Select frequency in the MCU */ + /* Step 1 - Select frequency in the MCU */ reg1 = FRQ; reg1 |= 0x80000000; // set running bit MCHBAR32(MC_BIOS_REQ) = reg1; @@ -331,7 +338,7 @@ static void dram_freq(ramctr_timing * ctrl) } printk(BIOS_DEBUG, "done in %d us\n", i * 10); - /* Step 3 - Verify lock frequency */ + /* Step 2 - Verify lock frequency */ reg1 = MCHBAR32(MC_BIOS_DATA); val2 = (u8) reg1; if (val2 >= FRQ) { |