[coreboot-gerrit] Change in coreboot[master]: nb/intel/x4x: Move decoding DDR2 SPD to separate file

Arthur Heymans (Code Review) gerrit at coreboot.org
Wed Dec 27 00:21:36 CET 2017


Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/22992


Change subject: nb/intel/x4x: Move decoding DDR2 SPD to separate file
......................................................................

nb/intel/x4x: Move decoding DDR2 SPD to separate file

This is needed to avoid type conflicts when decoding DDR3 when using
functions in device/dram/ddr3.c.

Nothing functional is changed.

Change-Id: I965fb8261c14381a35b361df2a3b40a9ea192669
Signed-off-by: Arthur Heymans <arthur at aheymans.xyz>
---
M src/northbridge/intel/x4x/Makefile.inc
M src/northbridge/intel/x4x/raminit.c
A src/northbridge/intel/x4x/spd_ddr2_decode.c
M src/northbridge/intel/x4x/x4x.h
4 files changed, 163 insertions(+), 132 deletions(-)



  git pull ssh://review.coreboot.org:29418/coreboot refs/changes/92/22992/1

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

-- 
To view, visit https://review.coreboot.org/22992
To unsubscribe, or for help writing mail filters, visit https://review.coreboot.org/settings

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I965fb8261c14381a35b361df2a3b40a9ea192669
Gerrit-Change-Number: 22992
Gerrit-PatchSet: 1
Gerrit-Owner: Arthur Heymans <arthur at aheymans.xyz>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.coreboot.org/pipermail/coreboot-gerrit/attachments/20171226/59fe7460/attachment-0001.html>


More information about the coreboot-gerrit mailing list