[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