[coreboot-gerrit] Change in coreboot[master]: nb/intel/ivybridge: Improve CAS freq selection

Arthur Heymans (Code Review) gerrit at coreboot.org
Tue May 16 19:58:29 CEST 2017


Arthur Heymans has uploaded a new change for review. ( https://review.coreboot.org/19717 )

Change subject: nb/intel/ivybridge: Improve CAS freq selection
......................................................................

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 at aheymans.xyz>
---
M src/northbridge/intel/sandybridge/raminit_ivy.c
1 file changed, 101 insertions(+), 99 deletions(-)


  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/17/19717/1

diff --git a/src/northbridge/intel/sandybridge/raminit_ivy.c b/src/northbridge/intel/sandybridge/raminit_ivy.c
index 97bf50b..666be1e 100644
--- a/src/northbridge/intel/sandybridge/raminit_ivy.c
+++ b/src/northbridge/intel/sandybridge/raminit_ivy.c
@@ -287,16 +287,103 @@
 	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++;
+			ivb_normalize_tclk(ctrl, ref_100mhz_support);
+		} else {
+			printk(BIOS_DEBUG, "Found compatible clock, CAS pair.\n");
+			break;
+		}
+	}
+
+	val32 = (1000 << 8) / 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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 		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 @@
 	/* 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_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);

-- 
To view, visit https://review.coreboot.org/19717
To unsubscribe, visit https://review.coreboot.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I1df20a0a723dc515686a766ad1b0567d815f6e89
Gerrit-PatchSet: 1
Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Owner: Arthur Heymans <arthur at aheymans.xyz>



More information about the coreboot-gerrit mailing list