nb/intel/ivybridge: 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: I1df20a0a723dc515686a766ad1b0567d815f6e89 Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-on: https://review.coreboot.org/19717 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Patrick Rudolph <siro@das-labor.org>
This commit is contained in:
parent
dcd3cef874
commit
9ed74b54b5
|
@ -287,16 +287,103 @@ static u32 get_COMP2(u32 tCK, u8 base_freq)
|
|||
return comp2;
|
||||
}
|
||||
|
||||
static void dram_timing(ramctr_timing * ctrl)
|
||||
static void ivb_normalize_tclk(ramctr_timing *ctrl,
|
||||
bool ref_100mhz_support)
|
||||
{
|
||||
if (ctrl->tCK <= TCK_1200MHZ) {
|
||||
ctrl->tCK = TCK_1200MHZ;
|
||||
ctrl->base_freq = 100;
|
||||
} else if (ctrl->tCK <= TCK_1100MHZ) {
|
||||
ctrl->tCK = TCK_1100MHZ;
|
||||
ctrl->base_freq = 100;
|
||||
} else if (ctrl->tCK <= TCK_1066MHZ) {
|
||||
ctrl->tCK = TCK_1066MHZ;
|
||||
ctrl->base_freq = 133;
|
||||
} else if (ctrl->tCK <= TCK_1000MHZ) {
|
||||
ctrl->tCK = TCK_1000MHZ;
|
||||
ctrl->base_freq = 100;
|
||||
} else if (ctrl->tCK <= TCK_933MHZ) {
|
||||
ctrl->tCK = TCK_933MHZ;
|
||||
ctrl->base_freq = 133;
|
||||
} else if (ctrl->tCK <= TCK_900MHZ) {
|
||||
ctrl->tCK = TCK_900MHZ;
|
||||
ctrl->base_freq = 100;
|
||||
} else if (ctrl->tCK <= TCK_800MHZ) {
|
||||
ctrl->tCK = TCK_800MHZ;
|
||||
ctrl->base_freq = 133;
|
||||
} else if (ctrl->tCK <= TCK_700MHZ) {
|
||||
ctrl->tCK = TCK_700MHZ;
|
||||
ctrl->base_freq = 100;
|
||||
} else if (ctrl->tCK <= TCK_666MHZ) {
|
||||
ctrl->tCK = TCK_666MHZ;
|
||||
ctrl->base_freq = 133;
|
||||
} else if (ctrl->tCK <= TCK_533MHZ) {
|
||||
ctrl->tCK = TCK_533MHZ;
|
||||
ctrl->base_freq = 133;
|
||||
} else if (ctrl->tCK <= TCK_400MHZ) {
|
||||
ctrl->tCK = TCK_400MHZ;
|
||||
ctrl->base_freq = 133;
|
||||
} else {
|
||||
ctrl->tCK = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ref_100mhz_support && ctrl->base_freq == 100) {
|
||||
/* Skip unsupported frequency. */
|
||||
ctrl->tCK++;
|
||||
ivb_normalize_tclk(ctrl, ref_100mhz_support);
|
||||
}
|
||||
}
|
||||
|
||||
static void find_cas_tck(ramctr_timing *ctrl)
|
||||
{
|
||||
u8 val;
|
||||
u32 val32;
|
||||
u32 reg32;
|
||||
u8 ref_100mhz_support;
|
||||
|
||||
/* 100 Mhz reference clock supported */
|
||||
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), CAPID0_B);
|
||||
ref_100mhz_support = !!((reg32 >> 21) & 0x7);
|
||||
printk(BIOS_DEBUG, "100MHz reference clock support: %s\n",
|
||||
ref_100mhz_support ? "yes" : "no");
|
||||
|
||||
/* Find CAS latency */
|
||||
while (1) {
|
||||
/* Normalising tCK before computing clock could potentially
|
||||
* results in lower selected CAS, which is desired.
|
||||
*/
|
||||
ivb_normalize_tclk(ctrl, ref_100mhz_support);
|
||||
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 1400MHz (DDR3 2800).
|
||||
* We cap it at 1200Mhz (DDR3 2400).
|
||||
* Then, align it to the closest JEDEC standard frequency */
|
||||
if (ctrl->tCK <= TCK_1200MHZ) {
|
||||
ctrl->tCK = TCK_1200MHZ;
|
||||
if (ctrl->tCK == TCK_1200MHZ) {
|
||||
ctrl->edge_offset[0] = 18; //XXX: guessed
|
||||
ctrl->edge_offset[1] = 8;
|
||||
ctrl->edge_offset[2] = 8;
|
||||
|
@ -304,8 +391,7 @@ static void dram_timing(ramctr_timing * ctrl)
|
|||
ctrl->timC_offset[1] = 8;
|
||||
ctrl->timC_offset[2] = 8;
|
||||
ctrl->reg_320c_range_threshold = 10;
|
||||
} else if (ctrl->tCK <= TCK_1100MHZ) {
|
||||
ctrl->tCK = TCK_1100MHZ;
|
||||
} else if (ctrl->tCK == TCK_1100MHZ) {
|
||||
ctrl->edge_offset[0] = 17; //XXX: guessed
|
||||
ctrl->edge_offset[1] = 7;
|
||||
ctrl->edge_offset[2] = 7;
|
||||
|
@ -313,8 +399,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_1066MHZ) {
|
||||
ctrl->tCK = TCK_1066MHZ;
|
||||
} else if (ctrl->tCK == TCK_1066MHZ) {
|
||||
ctrl->edge_offset[0] = 16;
|
||||
ctrl->edge_offset[1] = 7;
|
||||
ctrl->edge_offset[2] = 7;
|
||||
|
@ -322,8 +407,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_1000MHZ) {
|
||||
ctrl->tCK = TCK_1000MHZ;
|
||||
} else if (ctrl->tCK == TCK_1000MHZ) {
|
||||
ctrl->edge_offset[0] = 15; //XXX: guessed
|
||||
ctrl->edge_offset[1] = 6;
|
||||
ctrl->edge_offset[2] = 6;
|
||||
|
@ -331,8 +415,7 @@ static void dram_timing(ramctr_timing * ctrl)
|
|||
ctrl->timC_offset[1] = 6;
|
||||
ctrl->timC_offset[2] = 6;
|
||||
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;
|
||||
|
@ -340,8 +423,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_900MHZ) {
|
||||
ctrl->tCK = TCK_900MHZ;
|
||||
} else if (ctrl->tCK == TCK_900MHZ) {
|
||||
ctrl->edge_offset[0] = 14; //XXX: guessed
|
||||
ctrl->edge_offset[1] = 6;
|
||||
ctrl->edge_offset[2] = 6;
|
||||
|
@ -349,8 +431,7 @@ static void dram_timing(ramctr_timing * ctrl)
|
|||
ctrl->timC_offset[1] = 6;
|
||||
ctrl->timC_offset[2] = 6;
|
||||
ctrl->reg_320c_range_threshold = 12;
|
||||
} 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;
|
||||
|
@ -358,8 +439,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_700MHZ) {
|
||||
ctrl->tCK = TCK_700MHZ;
|
||||
} else if (ctrl->tCK == TCK_700MHZ) {
|
||||
ctrl->edge_offset[0] = 13; //XXX: guessed
|
||||
ctrl->edge_offset[1] = 5;
|
||||
ctrl->edge_offset[2] = 5;
|
||||
|
@ -367,8 +447,7 @@ static void dram_timing(ramctr_timing * ctrl)
|
|||
ctrl->timC_offset[1] = 5;
|
||||
ctrl->timC_offset[2] = 5;
|
||||
ctrl->reg_320c_range_threshold = 16;
|
||||
} 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;
|
||||
|
@ -376,8 +455,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;
|
||||
|
@ -385,8 +463,7 @@ static void dram_timing(ramctr_timing * ctrl)
|
|||
ctrl->timC_offset[1] = 3;
|
||||
ctrl->timC_offset[2] = 3;
|
||||
ctrl->reg_320c_range_threshold = 17;
|
||||
} else {
|
||||
ctrl->tCK = TCK_400MHZ;
|
||||
} else { /* TCK_400MHZ */
|
||||
ctrl->edge_offset[0] = 6;
|
||||
ctrl->edge_offset[1] = 2;
|
||||
ctrl->edge_offset[2] = 2;
|
||||
|
@ -402,30 +479,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);
|
||||
|
||||
|
@ -476,69 +529,18 @@ static void dram_timing(ramctr_timing * ctrl)
|
|||
|
||||
static void dram_freq(ramctr_timing * ctrl)
|
||||
{
|
||||
bool ref_100mhz_support;
|
||||
u32 reg32;
|
||||
|
||||
if (ctrl->tCK > TCK_400MHZ) {
|
||||
printk (BIOS_ERR, "DRAM frequency is under lowest supported "
|
||||
"frequency (400 MHz). Increasing to 400 MHz as last resort");
|
||||
ctrl->tCK = TCK_400MHZ;
|
||||
}
|
||||
|
||||
/* 100 Mhz reference clock supported */
|
||||
reg32 = pci_read_config32(PCI_DEV(0, 0, 0), CAPID0_B);
|
||||
ref_100mhz_support = !!((reg32 >> 21) & 0x7);
|
||||
printk(BIOS_DEBUG, "100MHz reference clock support: %s\n",
|
||||
ref_100mhz_support ? "yes" : "no");
|
||||
|
||||
while (1) {
|
||||
u8 val2;
|
||||
u32 reg1 = 0;
|
||||
|
||||
/* Step 1 - Set target PCU frequency */
|
||||
|
||||
if (ctrl->tCK <= TCK_1200MHZ) {
|
||||
ctrl->tCK = TCK_1200MHZ;
|
||||
ctrl->base_freq = 100;
|
||||
} else if (ctrl->tCK <= TCK_1100MHZ) {
|
||||
ctrl->tCK = TCK_1100MHZ;
|
||||
ctrl->base_freq = 100;
|
||||
} else if (ctrl->tCK <= TCK_1066MHZ) {
|
||||
ctrl->tCK = TCK_1066MHZ;
|
||||
ctrl->base_freq = 133;
|
||||
} else if (ctrl->tCK <= TCK_1000MHZ) {
|
||||
ctrl->tCK = TCK_1000MHZ;
|
||||
ctrl->base_freq = 100;
|
||||
} else if (ctrl->tCK <= TCK_933MHZ) {
|
||||
ctrl->tCK = TCK_933MHZ;
|
||||
ctrl->base_freq = 133;
|
||||
} else if (ctrl->tCK <= TCK_900MHZ) {
|
||||
ctrl->tCK = TCK_900MHZ;
|
||||
ctrl->base_freq = 100;
|
||||
} else if (ctrl->tCK <= TCK_800MHZ) {
|
||||
ctrl->tCK = TCK_800MHZ;
|
||||
ctrl->base_freq = 133;
|
||||
} else if (ctrl->tCK <= TCK_700MHZ) {
|
||||
ctrl->tCK = TCK_700MHZ;
|
||||
ctrl->base_freq = 100;
|
||||
} else if (ctrl->tCK <= TCK_666MHZ) {
|
||||
ctrl->tCK = TCK_666MHZ;
|
||||
ctrl->base_freq = 133;
|
||||
} else if (ctrl->tCK <= TCK_533MHZ) {
|
||||
ctrl->tCK = TCK_533MHZ;
|
||||
ctrl->base_freq = 133;
|
||||
} else if (ctrl->tCK <= TCK_400MHZ) {
|
||||
ctrl->tCK = TCK_400MHZ;
|
||||
ctrl->base_freq = 133;
|
||||
} else {
|
||||
die ("No lock frequency found");
|
||||
}
|
||||
|
||||
if (!ref_100mhz_support && ctrl->base_freq == 100) {
|
||||
/* Skip unsupported frequency. */
|
||||
ctrl->tCK++;
|
||||
continue;
|
||||
}
|
||||
find_cas_tck(ctrl);
|
||||
|
||||
/* Frequency multiplier. */
|
||||
u32 FRQ = get_FRQ(ctrl->tCK, ctrl->base_freq);
|
||||
|
|
Loading…
Reference in New Issue