<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>