summaryrefslogtreecommitdiff
path: root/src/northbridge
diff options
context:
space:
mode:
authorArthur Heymans <arthur@aheymans.xyz>2017-05-16 19:56:49 +0200
committerArthur Heymans <arthur@aheymans.xyz>2017-06-12 11:44:50 +0200
commit9ed74b54b573d9f26ccd1ec382206c5c0c8048ff (patch)
treecb9735290960e56471e0f13eb84fd2172e4118c9 /src/northbridge
parentdcd3cef8744b9d126370565fb3551a1fced8ab04 (diff)
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>
Diffstat (limited to 'src/northbridge')
-rw-r--r--src/northbridge/intel/sandybridge/raminit_ivy.c200
1 files changed, 101 insertions, 99 deletions
diff --git a/src/northbridge/intel/sandybridge/raminit_ivy.c b/src/northbridge/intel/sandybridge/raminit_ivy.c
index 97bf50b52d..675ac7181c 100644
--- a/src/northbridge/intel/sandybridge/raminit_ivy.c
+++ b/src/northbridge/intel/sandybridge/raminit_ivy.c
@@ -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);