aboutsummaryrefslogtreecommitdiff
path: root/src/northbridge/intel/x4x/x4x.h
diff options
context:
space:
mode:
authorArthur Heymans <arthur@aheymans.xyz>2017-04-05 16:17:26 +0200
committerArthur Heymans <arthur@aheymans.xyz>2017-12-16 10:00:10 +0000
commit3cf94032bced9345f4b9d71b7d2becab4dfcd530 (patch)
tree49546878d13dc164f18db96fe6cc1ddc914d3026 /src/northbridge/intel/x4x/x4x.h
parentcb0c40d3503badee7939393360903ebdc904609a (diff)
nb/x4x/raminit: Rewrite SPD decode and timing selection
This is mostly written from scratch and uses common spd ddr2 decode functions. This improves the following: * This fixes incorrect CAS/Freq detection on DDR2; * Fixes tRFC computation; tRFC == 78 is a valid timing which is excluded and 0 ends up being used; (TESTED) * Timings selection does not use loops; * Removes ddr3 spd decode and is re-added in follow-up patches using common ddr3 spd functions; * Raminit would bail out if a dimm was unsupported, now in some cases it just marks the dimm slot as empty; * It dramatically reduces stack usage since it does not allocate 4 times 256 bytes to store full SPDs, amongs other unused things that were stored in sysinfo; * Reports when no dimms are present; * Uses i2c block read to read SPD which is about 5 times faster than bytewise read, with a fallback to smbus mode in case of failure, which does seem to happen when the system is forcefully powered off. Change-Id: I760eeaa3bd4f2bc25a517ddb1b9533c971454071 Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-on: https://review.coreboot.org/19143 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src/northbridge/intel/x4x/x4x.h')
-rw-r--r--src/northbridge/intel/x4x/x4x.h31
1 files changed, 10 insertions, 21 deletions
diff --git a/src/northbridge/intel/x4x/x4x.h b/src/northbridge/intel/x4x/x4x.h
index 9db6c12122..cbb1853fab 100644
--- a/src/northbridge/intel/x4x/x4x.h
+++ b/src/northbridge/intel/x4x/x4x.h
@@ -144,6 +144,7 @@
#define TOTAL_DIMMS 4
#define DIMMS_PER_CHANNEL (TOTAL_DIMMS / TOTAL_CHANNELS)
#define RAW_CARD_UNPOPULATED 0xff
+#define RAW_CARD_POPULATED 0
#define DIMM_IS_POPULATED(dimms, idx) (dimms[idx].card_type != RAW_CARD_UNPOPULATED)
#define IF_DIMM_POPULATED(dimms, idx) if (dimms[idx].card_type != RAW_CARD_UNPOPULATED)
@@ -249,8 +250,14 @@ struct dll_setting {
u8 coarse;
};
+enum n_banks {
+ N_BANKS_4 = 0,
+ N_BANKS_8 = 1,
+};
+
struct timings {
unsigned int CAS;
+ unsigned int tclk;
enum fsb_clock fsb_clk;
enum mem_clock mem_clk;
unsigned int tRAS;
@@ -267,40 +274,20 @@ struct dimminfo {
unsigned int card_type; /* 0xff: unpopulated,
0xa - 0xf: raw card type A - F */
enum chip_width width;
- enum chip_cap chip_capacity;
unsigned int page_size; /* of whole DIMM in Bytes (4096 or 8192) */
- unsigned int sides;
- unsigned int banks;
+ enum n_banks n_banks;
unsigned int ranks;
unsigned int rows;
unsigned int cols;
- unsigned int cas_latencies;
- unsigned int tAAmin;
- unsigned int tCKmin;
- unsigned int tWR;
- unsigned int tRP;
- unsigned int tRCD;
- unsigned int tRAS;
- unsigned int rank_capacity_mb; /* per rank in Megabytes */
- u8 spd_data[256];
};
/* The setup is up to two DIMMs per channel */
struct sysinfo {
- int txt_enabled;
- int cores;
int boot_path;
int max_ddr2_mhz;
- int max_ddr3_mt;
enum fsb_clock max_fsb;
- int max_fsb_mhz;
- int max_render_mhz;
- int enable_igd;
- int enable_peg;
- u16 ggc;
int dimm_config[2];
- int dimms_per_ch;
int spd_type;
int channel_capacity[2];
struct timings selected_timings;
@@ -346,6 +333,8 @@ u8 decode_pciebar(u32 *const base, u32 *const len);
void sdram_initialize(int boot_path, const u8 *spd_map);
void raminit_ddr2(struct sysinfo *);
void rcven(const struct sysinfo *);
+u32 fsb2mhz(u32 speed);
+u32 ddr2mhz(u32 speed);
struct acpi_rsdp;
#ifndef __SIMPLE_DEVICE__