[coreboot-gerrit] Change in coreboot[master]: nb/x4x/raminit: Split of DDR2 specific functions to its own ...
Arthur Heymans (Code Review)
gerrit at coreboot.org
Wed May 24 22:10:31 CEST 2017
Arthur Heymans has uploaded a new change for review. ( https://review.coreboot.org/19868 )
Change subject: nb/x4x/raminit: Split of DDR2 specific functions to its own file
......................................................................
nb/x4x/raminit: Split of DDR2 specific functions to its own file
Headers for device/dram/ddr2 and ddr3 conflict so the easy solution is
have separate files for functions that use those.
Change-Id: I3ab281f4d8fcce3ef3cf8e355e7ea7286c73e4ff
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, 161 insertions(+), 138 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/68/19868/1
diff --git a/src/northbridge/intel/x4x/Makefile.inc b/src/northbridge/intel/x4x/Makefile.inc
index 34d9b0f..b433810 100644
--- a/src/northbridge/intel/x4x/Makefile.inc
+++ b/src/northbridge/intel/x4x/Makefile.inc
@@ -20,6 +20,7 @@
romstage-y += raminit.c
romstage-y += raminit_ddr2.c
romstage-y += ram_calc.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 67e9a1b..7e69b4c 100644
--- a/src/northbridge/intel/x4x/raminit.c
+++ b/src/northbridge/intel/x4x/raminit.c
@@ -28,71 +28,10 @@
#include <pc80/mc146818rtc.h>
#include <spd.h>
#include <string.h>
-#include <device/dram/ddr2.h>
static inline int spd_read_byte(unsigned int device, unsigned int address)
{
return smbus_read_byte(device, address);
-}
-
-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 tCLK_cas[TOTAL_DIMMS][8];
- u32 cas_supported;
-};
-
-static void select_cas_dramfreq_ddr2(struct sysinfo *s,
- struct abs_timings *saved_timings)
-{
- u8 selected_cas;
- u8 cas_mask = SPD_CAS_LATENCY_DDR2_5 | SPD_CAS_LATENCY_DDR2_6;
- u32 common_min_tclk[8];
- u32 common_tCLK;
-
- cas_mask &= saved_timings->cas_supported;
- get_common_min_tclk(cas_mask, TOTAL_DIMMS, common_min_tclk,
- saved_timings->tCLK_cas);
- /* On this northbridge the highest DDR2 frequency is 800MHz */
- common_tCLK = get_common_freq_cas(cas_mask, common_min_tclk,
- &selected_cas, TCK_400MHZ);
-
- if (common_tCLK == 0)
- die("Could not find common memory frequency and CAS\n");
-
- s->selected_timings.CAS = selected_cas;
- s->selected_timings.tclk = common_tCLK;
-
- switch (s->selected_timings.tclk) {
- case TCK_200MHZ:
- case TCK_266MHZ:
- /* FIXME: this works on vendor BIOS */
- die("Selected dran 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;
- }
-
- switch (s->selected_timings.tclk) {
- case TCK_200MHZ:
- s->selected_timings.mem_clk = MEM_CLOCK_400MHz; break;
- case TCK_266MHZ:
- s->selected_timings.mem_clk = MEM_CLOCK_533MHz; break;
- 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)
@@ -111,85 +50,8 @@
if (!(capid & (1<<(56-32))))
printk(BIOS_WARNING, "AMT enabled\n");
- s->max_ddr2_mhz = 800; // All chipsets in x4x support up to 800MHz DDR2
- printk(BIOS_WARNING, "Capable of DDR2 of %d MHz or lower\n", s->max_ddr2_mhz);
-
if (!(capid & (1<<(48-32))))
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)
- return 1;
-
- if (IS_ENABLED(CONFIG_DEBUG_RAM_SETUP))
- dram_print_spd_ddr2(&decoded_dimm);
-
- /*
- * Used to be content of spd byte 62 which does not make
- * that much sense.
- */
- s->dimms[dimm_idx].width = decoded_dimm.width;
- if (!(s->dimms[dimm_idx].width & (0x8 | 0x10))) {
- printk(BIOS_ERR, "DIMM%d Unsupported width: x%d. Disabling dimm\n",
- dimm_idx, s->dimms[dimm_idx].width);
- return 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'
- */
- s->dimms[dimm_idx].page_size = s->dimms[dimm_idx].width *
- (1 << decoded_dimm.col_bits);
-
- switch (decoded_dimm.banks) {
- case 4:
- s->dimms[dimm_idx].n_banks = 0;
- break;
- case 8:
- s->dimms[dimm_idx].n_banks = 1;
- break;
- default:
- printk(BIOS_ERR, "DIMM%d Unsupported #banks: x%d. Disabling dimm\n",
- dimm_idx, decoded_dimm.banks);
- return 1;
- }
-
- 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++) {
- saved_timings->tCLK_cas[dimm_idx][i] =
- decoded_dimm.cycle_time[i];
- }
- return 0;
}
static void select_discrete_timings(struct sysinfo *s,
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..938aab7
--- /dev/null
+++ b/src/northbridge/intel/x4x/spd_ddr2_decode.c
@@ -0,0 +1,142 @@
+/*
+ * 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 <arch/io.h>
+#include <console/console.h>
+#include <device/dram/ddr2.h>
+#include "x4x.h"
+
+void select_cas_dramfreq_ddr2(struct sysinfo *s,
+ struct abs_timings *saved_timings)
+{
+ u8 selected_cas;
+ u8 cas_mask = SPD_CAS_LATENCY_DDR2_5 | SPD_CAS_LATENCY_DDR2_6;
+ u32 common_min_tclk[8];
+ u32 common_tCLK;
+
+ cas_mask &= saved_timings->cas_supported;
+ get_common_min_tclk(cas_mask, TOTAL_DIMMS, common_min_tclk,
+ saved_timings->tCLK_cas);
+ /* On this northbridge the highest DDR2 frequency is 800MHz */
+ common_tCLK = get_common_freq_cas(cas_mask, common_min_tclk,
+ &selected_cas, TCK_400MHZ);
+
+ if (common_tCLK == 0)
+ die("Could not find common memory frequency and CAS\n");
+
+ s->selected_timings.CAS = selected_cas;
+ s->selected_timings.tclk = common_tCLK;
+
+ switch (s->selected_timings.tclk) {
+ case TCK_200MHZ:
+ case TCK_266MHZ:
+ /* FIXME: this works on vendor BIOS */
+ die("Selected dran 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;
+ }
+
+ switch (s->selected_timings.tclk) {
+ case TCK_200MHZ:
+ s->selected_timings.mem_clk = MEM_CLOCK_400MHz; break;
+ case TCK_266MHZ:
+ s->selected_timings.mem_clk = MEM_CLOCK_533MHz; break;
+ 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)
+ return 1;
+
+ if (IS_ENABLED(CONFIG_DEBUG_RAM_SETUP))
+ dram_print_spd_ddr2(&decoded_dimm);
+
+ /*
+ * Used to be content of spd byte 62 which does not make
+ * that much sense.
+ */
+ s->dimms[dimm_idx].width = decoded_dimm.width;
+ if (!(s->dimms[dimm_idx].width & (0x8 | 0x10))) {
+ printk(BIOS_ERR, "DIMM%d Unsupported width: x%d. Disabling dimm\n",
+ dimm_idx, s->dimms[dimm_idx].width);
+ return 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'
+ */
+ s->dimms[dimm_idx].page_size = s->dimms[dimm_idx].width *
+ (1 << decoded_dimm.col_bits);
+
+ switch (decoded_dimm.banks) {
+ case 4:
+ s->dimms[dimm_idx].n_banks = 0;
+ break;
+ case 8:
+ s->dimms[dimm_idx].n_banks = 1;
+ break;
+ default:
+ printk(BIOS_ERR, "DIMM%d Unsupported #banks: x%d. Disabling dimm\n",
+ dimm_idx, decoded_dimm.banks);
+ return 1;
+ }
+
+ 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++) {
+ saved_timings->tCLK_cas[dimm_idx][i] =
+ decoded_dimm.cycle_time[i];
+ }
+ return 0;
+}
diff --git a/src/northbridge/intel/x4x/x4x.h b/src/northbridge/intel/x4x/x4x.h
index 06d88ee..fc7fbfe 100644
--- a/src/northbridge/intel/x4x/x4x.h
+++ b/src/northbridge/intel/x4x/x4x.h
@@ -321,6 +321,20 @@
DQ8
};
+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 tCLK_cas[TOTAL_DIMMS][8];
+ u32 cas_supported;
+};
+
#ifndef __BOOTBLOCK__
void x4x_early_init(void);
void x4x_late_init(int s3resume);
@@ -331,6 +345,10 @@
void raminit_ddr2(struct sysinfo *);
u32 fsb2mhz(u32 speed);
u32 ddr2mhz(u32 speed);
+void select_cas_dramfreq_ddr2(struct sysinfo *s,
+ struct abs_timings *saved_timings);
+int ddr2_save_dimminfo(u8 dimm_idx, u8 *raw_spd,
+ struct abs_timings *saved_timings, struct sysinfo *s);
struct acpi_rsdp;
#ifndef __SIMPLE_DEVICE__
--
To view, visit https://review.coreboot.org/19868
To unsubscribe, visit https://review.coreboot.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I3ab281f4d8fcce3ef3cf8e355e7ea7286c73e4ff
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