[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