<p>Arthur Heymans has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/22992">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">nb/intel/x4x: Move decoding DDR2 SPD to separate file<br><br>This is needed to avoid type conflicts when decoding DDR3 when using<br>functions in device/dram/ddr3.c.<br><br>Nothing functional is changed.<br><br>Change-Id: I965fb8261c14381a35b361df2a3b40a9ea192669<br>Signed-off-by: Arthur Heymans <arthur@aheymans.xyz><br>---<br>M src/northbridge/intel/x4x/Makefile.inc<br>M src/northbridge/intel/x4x/raminit.c<br>A src/northbridge/intel/x4x/spd_ddr2_decode.c<br>M src/northbridge/intel/x4x/x4x.h<br>4 files changed, 163 insertions(+), 132 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/92/22992/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/northbridge/intel/x4x/Makefile.inc b/src/northbridge/intel/x4x/Makefile.inc</span><br><span>index 29ece07..ef9b991 100644</span><br><span>--- a/src/northbridge/intel/x4x/Makefile.inc</span><br><span>+++ b/src/northbridge/intel/x4x/Makefile.inc</span><br><span>@@ -23,6 +23,7 @@</span><br><span> romstage-y += rcven.c</span><br><span> romstage-y += raminit_tables.c</span><br><span> romstage-y += dq_dqs.c</span><br><span style="color: hsl(120, 100%, 40%);">+romstage-y += spd_ddr2_decode.c</span><br><span> </span><br><span> ramstage-y += acpi.c</span><br><span> ramstage-y += ram_calc.c</span><br><span>diff --git a/src/northbridge/intel/x4x/raminit.c b/src/northbridge/intel/x4x/raminit.c</span><br><span>index 3cd75be..81dcc1d 100644</span><br><span>--- a/src/northbridge/intel/x4x/raminit.c</span><br><span>+++ b/src/northbridge/intel/x4x/raminit.c</span><br><span>@@ -83,59 +83,8 @@</span><br><span>       return CB_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-struct abs_timings {</span><br><span style="color: hsl(0, 100%, 40%);">- u32 min_tclk;</span><br><span style="color: hsl(0, 100%, 40%);">-   u32 min_tRAS;</span><br><span style="color: hsl(0, 100%, 40%);">-   u32 min_tRP;</span><br><span style="color: hsl(0, 100%, 40%);">-    u32 min_tRCD;</span><br><span style="color: hsl(0, 100%, 40%);">-   u32 min_tWR;</span><br><span style="color: hsl(0, 100%, 40%);">-    u32 min_tRFC;</span><br><span style="color: hsl(0, 100%, 40%);">-   u32 min_tWTR;</span><br><span style="color: hsl(0, 100%, 40%);">-   u32 min_tRRD;</span><br><span style="color: hsl(0, 100%, 40%);">-   u32 min_tRTP;</span><br><span style="color: hsl(0, 100%, 40%);">-   u32 min_tCLK_cas[8];</span><br><span style="color: hsl(0, 100%, 40%);">-    u32 cas_supported;</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> #define CTRL_MIN_TCLK_DDR2 TCK_400MHZ</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static void select_cas_dramfreq_ddr2(struct sysinfo *s,</span><br><span style="color: hsl(0, 100%, 40%);">-                                const struct abs_timings *saved_timings)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-       u8 try_cas;</span><br><span style="color: hsl(0, 100%, 40%);">-     /* Currently only these CAS are supported */</span><br><span style="color: hsl(0, 100%, 40%);">-    u8 cas_mask = SPD_CAS_LATENCY_DDR2_5 | SPD_CAS_LATENCY_DDR2_6;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  cas_mask &= saved_timings->cas_supported;</span><br><span style="color: hsl(0, 100%, 40%);">-        try_cas = spd_get_msbs(cas_mask);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       while (cas_mask & (1 << try_cas) && try_cas > 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-         s->selected_timings.CAS = try_cas;</span><br><span style="color: hsl(0, 100%, 40%);">-           s->selected_timings.tclk = saved_timings->min_tCLK_cas[try_cas];</span><br><span style="color: hsl(0, 100%, 40%);">-          if (s->selected_timings.tclk >= CTRL_MIN_TCLK_DDR2 &&</span><br><span style="color: hsl(0, 100%, 40%);">-                             saved_timings->min_tCLK_cas[try_cas] !=</span><br><span style="color: hsl(0, 100%, 40%);">-                              saved_timings->min_tCLK_cas[try_cas - 1])</span><br><span style="color: hsl(0, 100%, 40%);">-                    break;</span><br><span style="color: hsl(0, 100%, 40%);">-          try_cas--;</span><br><span style="color: hsl(0, 100%, 40%);">-      }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if ((s->selected_timings.CAS < 3) || (s->selected_timings.tclk == 0))</span><br><span style="color: hsl(0, 100%, 40%);">-          die("Could not find common memory frequency and CAS\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      switch (s->selected_timings.tclk) {</span><br><span style="color: hsl(0, 100%, 40%);">-  case TCK_200MHZ:</span><br><span style="color: hsl(0, 100%, 40%);">-        case TCK_266MHZ:</span><br><span style="color: hsl(0, 100%, 40%);">-                /* FIXME: this works on vendor BIOS */</span><br><span style="color: hsl(0, 100%, 40%);">-          die("Selected dram frequency not supported\n");</span><br><span style="color: hsl(0, 100%, 40%);">-       case TCK_333MHZ:</span><br><span style="color: hsl(0, 100%, 40%);">-                s->selected_timings.mem_clk = MEM_CLOCK_667MHz;</span><br><span style="color: hsl(0, 100%, 40%);">-              break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case TCK_400MHZ:</span><br><span style="color: hsl(0, 100%, 40%);">-                s->selected_timings.mem_clk = MEM_CLOCK_800MHz;</span><br><span style="color: hsl(0, 100%, 40%);">-              break;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span> </span><br><span> static void mchinfo_ddr2(struct sysinfo *s)</span><br><span> {</span><br><span>@@ -160,87 +109,6 @@</span><br><span>            printk(BIOS_WARNING, "VT-d enabled\n");</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int ddr2_save_dimminfo(u8 dimm_idx, u8 *raw_spd,</span><br><span style="color: hsl(0, 100%, 40%);">-               struct abs_timings *saved_timings, struct sysinfo *s)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  struct dimm_attr_st decoded_dimm;</span><br><span style="color: hsl(0, 100%, 40%);">-       int i;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  if (spd_decode_ddr2(&decoded_dimm, raw_spd) != SPD_STATUS_OK) {</span><br><span style="color: hsl(0, 100%, 40%);">-             printk(BIOS_DEBUG, "Problems decoding SPD\n");</span><br><span style="color: hsl(0, 100%, 40%);">-                return CB_ERR;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (IS_ENABLED(CONFIG_DEBUG_RAM_SETUP))</span><br><span style="color: hsl(0, 100%, 40%);">-         dram_print_spd_ddr2(&decoded_dimm);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!(decoded_dimm.width & (0x08 | 0x10))) {</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-                printk(BIOS_ERR,</span><br><span style="color: hsl(0, 100%, 40%);">-                        "DIMM%d Unsupported width: x%d. Disabling dimm\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                    dimm_idx, s->dimms[dimm_idx].width);</span><br><span style="color: hsl(0, 100%, 40%);">-         return CB_ERR;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-       s->dimms[dimm_idx].width = (decoded_dimm.width >> 3) - 1;</span><br><span style="color: hsl(0, 100%, 40%);">-      /*</span><br><span style="color: hsl(0, 100%, 40%);">-       * This boils down to:</span><br><span style="color: hsl(0, 100%, 40%);">-   * "Except for the x16 configuration, all DDR2 devices have a</span><br><span style="color: hsl(0, 100%, 40%);">-       * 1KB page size. For the x16 configuration, the page size is 2KB</span><br><span style="color: hsl(0, 100%, 40%);">-        * for all densities except the 256Mb device, which has a 1KB page</span><br><span style="color: hsl(0, 100%, 40%);">-       * size." Micron, 'TN-47-16 Designing for High-Density DDR2 Memory'</span><br><span style="color: hsl(0, 100%, 40%);">-         * The formula is pagesize in KiB = width * 2^col_bits / 8.</span><br><span style="color: hsl(0, 100%, 40%);">-      */</span><br><span style="color: hsl(0, 100%, 40%);">-     s->dimms[dimm_idx].page_size = decoded_dimm.width *</span><br><span style="color: hsl(0, 100%, 40%);">-           (1 << decoded_dimm.col_bits) / 8;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        switch (decoded_dimm.banks) {</span><br><span style="color: hsl(0, 100%, 40%);">-   case 4:</span><br><span style="color: hsl(0, 100%, 40%);">-         s->dimms[dimm_idx].n_banks = N_BANKS_4;</span><br><span style="color: hsl(0, 100%, 40%);">-              break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case 8:</span><br><span style="color: hsl(0, 100%, 40%);">-         s->dimms[dimm_idx].n_banks = N_BANKS_8;</span><br><span style="color: hsl(0, 100%, 40%);">-              break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                printk(BIOS_ERR,</span><br><span style="color: hsl(0, 100%, 40%);">-                        "DIMM%d Unsupported #banks: x%d. Disabling dimm\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                    dimm_idx, decoded_dimm.banks);</span><br><span style="color: hsl(0, 100%, 40%);">-         return CB_ERR;</span><br><span style="color: hsl(0, 100%, 40%);">-  }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       s->dimms[dimm_idx].ranks = decoded_dimm.ranks;</span><br><span style="color: hsl(0, 100%, 40%);">-       s->dimms[dimm_idx].rows = decoded_dimm.row_bits;</span><br><span style="color: hsl(0, 100%, 40%);">-     s->dimms[dimm_idx].cols = decoded_dimm.col_bits;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-     saved_timings->cas_supported &= decoded_dimm.cas_supported;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      saved_timings->min_tRAS =</span><br><span style="color: hsl(0, 100%, 40%);">-            MAX(saved_timings->min_tRAS, decoded_dimm.tRAS);</span><br><span style="color: hsl(0, 100%, 40%);">-     saved_timings->min_tRP =</span><br><span style="color: hsl(0, 100%, 40%);">-             MAX(saved_timings->min_tRP, decoded_dimm.tRP);</span><br><span style="color: hsl(0, 100%, 40%);">-       saved_timings->min_tRCD =</span><br><span style="color: hsl(0, 100%, 40%);">-            MAX(saved_timings->min_tRCD, decoded_dimm.tRCD);</span><br><span style="color: hsl(0, 100%, 40%);">-     saved_timings->min_tWR =</span><br><span style="color: hsl(0, 100%, 40%);">-             MAX(saved_timings->min_tWR, decoded_dimm.tWR);</span><br><span style="color: hsl(0, 100%, 40%);">-       saved_timings->min_tRFC =</span><br><span style="color: hsl(0, 100%, 40%);">-            MAX(saved_timings->min_tRFC, decoded_dimm.tRFC);</span><br><span style="color: hsl(0, 100%, 40%);">-     saved_timings->min_tWTR =</span><br><span style="color: hsl(0, 100%, 40%);">-            MAX(saved_timings->min_tWTR, decoded_dimm.tWTR);</span><br><span style="color: hsl(0, 100%, 40%);">-     saved_timings->min_tRRD =</span><br><span style="color: hsl(0, 100%, 40%);">-            MAX(saved_timings->min_tRRD, decoded_dimm.tRRD);</span><br><span style="color: hsl(0, 100%, 40%);">-     saved_timings->min_tRTP =</span><br><span style="color: hsl(0, 100%, 40%);">-            MAX(saved_timings->min_tRTP, decoded_dimm.tRTP);</span><br><span style="color: hsl(0, 100%, 40%);">-     for (i = 0; i < 8; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">-            if (!(saved_timings->cas_supported & (1 << i)))</span><br><span style="color: hsl(0, 100%, 40%);">-                    saved_timings->min_tCLK_cas[i] = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-          else</span><br><span style="color: hsl(0, 100%, 40%);">-                    saved_timings->min_tCLK_cas[i] =</span><br><span style="color: hsl(0, 100%, 40%);">-                             MAX(saved_timings->min_tCLK_cas[i],</span><br><span style="color: hsl(0, 100%, 40%);">-                                  decoded_dimm.cycle_time[i]);</span><br><span style="color: hsl(0, 100%, 40%);">-    }</span><br><span style="color: hsl(0, 100%, 40%);">-       s->dimms[dimm_idx].checksum = decoded_dimm.checksum;</span><br><span style="color: hsl(0, 100%, 40%);">- return CB_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> static void select_discrete_timings(struct sysinfo *s,</span><br><span>                                const struct abs_timings *timings)</span><br><span> {</span><br><span>diff --git a/src/northbridge/intel/x4x/spd_ddr2_decode.c b/src/northbridge/intel/x4x/spd_ddr2_decode.c</span><br><span>new file mode 100644</span><br><span>index 0000000..b3415f3</span><br><span>--- /dev/null</span><br><span>+++ b/src/northbridge/intel/x4x/spd_ddr2_decode.c</span><br><span>@@ -0,0 +1,144 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2015 Damien Zammit <damien@zamaudio.com></span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2017 Arthur Heymans <arthur@aheymans.xyz></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or</span><br><span style="color: hsl(120, 100%, 40%);">+ * modify it under the terms of the GNU General Public License as</span><br><span style="color: hsl(120, 100%, 40%);">+ * published by the Free Software Foundation; either version 2 of</span><br><span style="color: hsl(120, 100%, 40%);">+ * the License, or (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/io.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <spd.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <types.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <console/console.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <device/dram/ddr2.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include "x4x.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define CTRL_MIN_TCLK_DDR2 TCK_400MHZ</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void select_cas_dramfreq_ddr2(struct sysinfo *s,</span><br><span style="color: hsl(120, 100%, 40%);">+                                const struct abs_timings *saved_timings)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   u8 try_cas;</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Currently only these CAS are supported */</span><br><span style="color: hsl(120, 100%, 40%);">+  u8 cas_mask = SPD_CAS_LATENCY_DDR2_5 | SPD_CAS_LATENCY_DDR2_6;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      cas_mask &= saved_timings->cas_supported;</span><br><span style="color: hsl(120, 100%, 40%);">+      try_cas = spd_get_msbs(cas_mask);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   while (cas_mask & (1 << try_cas) && try_cas > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               s->selected_timings.CAS = try_cas;</span><br><span style="color: hsl(120, 100%, 40%);">+         s->selected_timings.tclk = saved_timings->min_tCLK_cas[try_cas];</span><br><span style="color: hsl(120, 100%, 40%);">+                if (s->selected_timings.tclk >= CTRL_MIN_TCLK_DDR2 &&</span><br><span style="color: hsl(120, 100%, 40%);">+                           saved_timings->min_tCLK_cas[try_cas] !=</span><br><span style="color: hsl(120, 100%, 40%);">+                            saved_timings->min_tCLK_cas[try_cas - 1])</span><br><span style="color: hsl(120, 100%, 40%);">+                  break;</span><br><span style="color: hsl(120, 100%, 40%);">+                try_cas--;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if ((s->selected_timings.CAS < 3) || (s->selected_timings.tclk == 0))</span><br><span style="color: hsl(120, 100%, 40%);">+                die("Could not find common memory frequency and CAS\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  switch (s->selected_timings.tclk) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case TCK_200MHZ:</span><br><span style="color: hsl(120, 100%, 40%);">+      case TCK_266MHZ:</span><br><span style="color: hsl(120, 100%, 40%);">+              /* FIXME: this works on vendor BIOS */</span><br><span style="color: hsl(120, 100%, 40%);">+                die("Selected dram frequency not supported\n");</span><br><span style="color: hsl(120, 100%, 40%);">+     case TCK_333MHZ:</span><br><span style="color: hsl(120, 100%, 40%);">+              s->selected_timings.mem_clk = MEM_CLOCK_667MHz;</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case TCK_400MHZ:</span><br><span style="color: hsl(120, 100%, 40%);">+              s->selected_timings.mem_clk = MEM_CLOCK_800MHz;</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int ddr2_save_dimminfo(u8 dimm_idx, u8 *raw_spd,</span><br><span style="color: hsl(120, 100%, 40%);">+              struct abs_timings *saved_timings, struct sysinfo *s)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct dimm_attr_st decoded_dimm;</span><br><span style="color: hsl(120, 100%, 40%);">+     int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (spd_decode_ddr2(&decoded_dimm, raw_spd) != SPD_STATUS_OK) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printk(BIOS_DEBUG, "Problems decoding SPD\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              return CB_ERR;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (IS_ENABLED(CONFIG_DEBUG_RAM_SETUP))</span><br><span style="color: hsl(120, 100%, 40%);">+               dram_print_spd_ddr2(&decoded_dimm);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!(decoded_dimm.width & (0x08 | 0x10))) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printk(BIOS_ERR,</span><br><span style="color: hsl(120, 100%, 40%);">+                      "DIMM%d Unsupported width: x%d. Disabling dimm\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  dimm_idx, s->dimms[dimm_idx].width);</span><br><span style="color: hsl(120, 100%, 40%);">+               return CB_ERR;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     s->dimms[dimm_idx].width = (decoded_dimm.width >> 3) - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+    /*</span><br><span style="color: hsl(120, 100%, 40%);">+     * This boils down to:</span><br><span style="color: hsl(120, 100%, 40%);">+         * "Except for the x16 configuration, all DDR2 devices have a</span><br><span style="color: hsl(120, 100%, 40%);">+     * 1KB page size. For the x16 configuration, the page size is 2KB</span><br><span style="color: hsl(120, 100%, 40%);">+      * for all densities except the 256Mb device, which has a 1KB page</span><br><span style="color: hsl(120, 100%, 40%);">+     * size." Micron, 'TN-47-16 Designing for High-Density DDR2 Memory'</span><br><span style="color: hsl(120, 100%, 40%);">+       * The formula is pagesize in KiB = width * 2^col_bits / 8</span><br><span style="color: hsl(120, 100%, 40%);">+     */</span><br><span style="color: hsl(120, 100%, 40%);">+   s->dimms[dimm_idx].page_size = decoded_dimm.width *</span><br><span style="color: hsl(120, 100%, 40%);">+                (1 << decoded_dimm.col_bits) / 8;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     switch (decoded_dimm.banks) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case 4:</span><br><span style="color: hsl(120, 100%, 40%);">+               s->dimms[dimm_idx].n_banks = N_BANKS_4;</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case 8:</span><br><span style="color: hsl(120, 100%, 40%);">+               s->dimms[dimm_idx].n_banks = N_BANKS_8;</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              printk(BIOS_ERR,</span><br><span style="color: hsl(120, 100%, 40%);">+                      "DIMM%d Unsupported #banks: x%d. Disabling dimm\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  dimm_idx, decoded_dimm.banks);</span><br><span style="color: hsl(120, 100%, 40%);">+               return CB_ERR;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   s->dimms[dimm_idx].ranks = decoded_dimm.ranks;</span><br><span style="color: hsl(120, 100%, 40%);">+     s->dimms[dimm_idx].rows = decoded_dimm.row_bits;</span><br><span style="color: hsl(120, 100%, 40%);">+   s->dimms[dimm_idx].cols = decoded_dimm.col_bits;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ saved_timings->cas_supported &= decoded_dimm.cas_supported;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  saved_timings->min_tRAS =</span><br><span style="color: hsl(120, 100%, 40%);">+          MAX(saved_timings->min_tRAS, decoded_dimm.tRAS);</span><br><span style="color: hsl(120, 100%, 40%);">+   saved_timings->min_tRP =</span><br><span style="color: hsl(120, 100%, 40%);">+           MAX(saved_timings->min_tRP, decoded_dimm.tRP);</span><br><span style="color: hsl(120, 100%, 40%);">+     saved_timings->min_tRCD =</span><br><span style="color: hsl(120, 100%, 40%);">+          MAX(saved_timings->min_tRCD, decoded_dimm.tRCD);</span><br><span style="color: hsl(120, 100%, 40%);">+   saved_timings->min_tWR =</span><br><span style="color: hsl(120, 100%, 40%);">+           MAX(saved_timings->min_tWR, decoded_dimm.tWR);</span><br><span style="color: hsl(120, 100%, 40%);">+     saved_timings->min_tRFC =</span><br><span style="color: hsl(120, 100%, 40%);">+          MAX(saved_timings->min_tRFC, decoded_dimm.tRFC);</span><br><span style="color: hsl(120, 100%, 40%);">+   saved_timings->min_tWTR =</span><br><span style="color: hsl(120, 100%, 40%);">+          MAX(saved_timings->min_tWTR, decoded_dimm.tWTR);</span><br><span style="color: hsl(120, 100%, 40%);">+   saved_timings->min_tRRD =</span><br><span style="color: hsl(120, 100%, 40%);">+          MAX(saved_timings->min_tRRD, decoded_dimm.tRRD);</span><br><span style="color: hsl(120, 100%, 40%);">+   saved_timings->min_tRTP =</span><br><span style="color: hsl(120, 100%, 40%);">+          MAX(saved_timings->min_tRTP, decoded_dimm.tRTP);</span><br><span style="color: hsl(120, 100%, 40%);">+   for (i = 0; i < 8; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (!(saved_timings->cas_supported & (1 << i)))</span><br><span style="color: hsl(120, 100%, 40%);">+                  saved_timings->min_tCLK_cas[i] = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                else</span><br><span style="color: hsl(120, 100%, 40%);">+                  saved_timings->min_tCLK_cas[i] =</span><br><span style="color: hsl(120, 100%, 40%);">+                           MAX(saved_timings->min_tCLK_cas[i],</span><br><span style="color: hsl(120, 100%, 40%);">+                                        decoded_dimm.cycle_time[i]);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+     s->dimms[dimm_idx].checksum = decoded_dimm.checksum;</span><br><span style="color: hsl(120, 100%, 40%);">+       return CB_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/northbridge/intel/x4x/x4x.h b/src/northbridge/intel/x4x/x4x.h</span><br><span>index b9e683b..4ac901c 100644</span><br><span>--- a/src/northbridge/intel/x4x/x4x.h</span><br><span>+++ b/src/northbridge/intel/x4x/x4x.h</span><br><span>@@ -354,6 +354,20 @@</span><br><span>        CTRL3,</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct abs_timings {</span><br><span style="color: hsl(120, 100%, 40%);">+        u32 min_tclk;</span><br><span style="color: hsl(120, 100%, 40%);">+ u32 min_tRAS;</span><br><span style="color: hsl(120, 100%, 40%);">+ u32 min_tRP;</span><br><span style="color: hsl(120, 100%, 40%);">+  u32 min_tRCD;</span><br><span style="color: hsl(120, 100%, 40%);">+ u32 min_tWR;</span><br><span style="color: hsl(120, 100%, 40%);">+  u32 min_tRFC;</span><br><span style="color: hsl(120, 100%, 40%);">+ u32 min_tWTR;</span><br><span style="color: hsl(120, 100%, 40%);">+ u32 min_tRRD;</span><br><span style="color: hsl(120, 100%, 40%);">+ u32 min_tRTP;</span><br><span style="color: hsl(120, 100%, 40%);">+ u32 min_tCLK_cas[8];</span><br><span style="color: hsl(120, 100%, 40%);">+  u32 cas_supported;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #ifndef __BOOTBLOCK__</span><br><span> void x4x_early_init(void);</span><br><span> void x4x_late_init(int s3resume);</span><br><span>@@ -372,6 +386,10 @@</span><br><span>          struct rt_dqs_setting *dqs_setting);</span><br><span> int do_write_training(struct sysinfo *s);</span><br><span> int do_read_training(struct sysinfo *s);</span><br><span style="color: hsl(120, 100%, 40%);">+void select_cas_dramfreq_ddr2(struct sysinfo *s,</span><br><span style="color: hsl(120, 100%, 40%);">+                       const struct abs_timings *saved_timings);</span><br><span style="color: hsl(120, 100%, 40%);">+int ddr2_save_dimminfo(u8 dimm_idx, u8 *raw_spd,</span><br><span style="color: hsl(120, 100%, 40%);">+           struct abs_timings *saved_timings, struct sysinfo *s);</span><br><span> </span><br><span> extern const struct dll_setting default_ddr2_667_ctrl[7];</span><br><span> extern const struct dll_setting default_ddr2_800_ctrl[7];</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/22992">change 22992</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/22992"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I965fb8261c14381a35b361df2a3b40a9ea192669 </div>
<div style="display:none"> Gerrit-Change-Number: 22992 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Arthur Heymans <arthur@aheymans.xyz> </div>