[U-Boot] [PATCH v3 01/16] Add proper SPD definitions for DDR1/2/3
Kumar Gala
galak at kernel.crashing.org
Thu Aug 21 01:22:43 CEST 2008
From: James Yang <James.Yang at freescale.com>
Also added a few helper functions for DDR1 & DDR2 to print SPD info and
verify the checksum.
Signed-off-by: Kumar Gala <galak at kernel.crashing.org>
---
common/Makefile | 1 +
common/ddr_spd.c | 519 +++++++++++++++++++++++++++++++++++++++++++++++++++++
include/ddr_spd.h | 292 ++++++++++++++++++++++++++++++
3 files changed, 812 insertions(+), 0 deletions(-)
create mode 100644 common/ddr_spd.c
create mode 100644 include/ddr_spd.h
diff --git a/common/Makefile b/common/Makefile
index dd139d6..8048341 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -150,6 +150,7 @@ COBJS-y += cmd_mac.o
COBJS-$(CONFIG_CMD_MFSL) += cmd_mfsl.o
COBJS-$(CONFIG_MP) += cmd_mp.o
COBJS-$(CONFIG_CMD_SF) += cmd_sf.o
+COBJS-$(CONFIG_DDR_SPD) += ddr_spd.o
COBJS := $(COBJS-y)
SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/common/ddr_spd.c b/common/ddr_spd.c
new file mode 100644
index 0000000..03cbe1d
--- /dev/null
+++ b/common/ddr_spd.c
@@ -0,0 +1,519 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ */
+
+#include <common.h>
+#include <ddr_spd.h>
+
+void
+ddr1_spd_dump(const ddr1_spd_eeprom_t *spd)
+{
+ unsigned int i;
+
+ printf("%-3d : %02x %s\n",
+ 0, spd->info_size,
+ " spd->info_size, * 0 # bytes written into serial memory *");
+ printf("%-3d : %02x %s\n",
+ 1, spd->chip_size,
+ " spd->chip_size, * 1 Total # bytes of SPD memory device *");
+ printf("%-3d : %02x %s\n",
+ 2, spd->mem_type,
+ " spd->mem_type, * 2 Fundamental memory type *");
+ printf("%-3d : %02x %s\n",
+ 3, spd->nrow_addr,
+ " spd->nrow_addr, * 3 # of Row Addresses on this assembly *");
+ printf("%-3d : %02x %s\n",
+ 4, spd->ncol_addr,
+ " spd->ncol_addr, * 4 # of Column Addrs on this assembly *");
+ printf("%-3d : %02x %s\n",
+ 5, spd->nrows,
+ " spd->nrows * 5 # of DIMM Banks *");
+ printf("%-3d : %02x %s\n",
+ 6, spd->dataw_lsb,
+ " spd->dataw_lsb, * 6 Data Width lsb of this assembly *");
+ printf("%-3d : %02x %s\n",
+ 7, spd->dataw_msb,
+ " spd->dataw_msb, * 7 Data Width msb of this assembly *");
+ printf("%-3d : %02x %s\n",
+ 8, spd->voltage,
+ " spd->voltage, * 8 Voltage intf std of this assembly *");
+ printf("%-3d : %02x %s\n",
+ 9, spd->clk_cycle,
+ " spd->clk_cycle, * 9 SDRAM Cycle time at CL=X *");
+ printf("%-3d : %02x %s\n",
+ 10, spd->clk_access,
+ " spd->clk_access, * 10 SDRAM Access from Clock at CL=X *");
+ printf("%-3d : %02x %s\n",
+ 11, spd->config,
+ " spd->config, * 11 DIMM Configuration type *");
+ printf("%-3d : %02x %s\n",
+ 12, spd->refresh,
+ " spd->refresh, * 12 Refresh Rate/Type *");
+ printf("%-3d : %02x %s\n",
+ 13, spd->primw,
+ " spd->primw, * 13 Primary SDRAM Width *");
+ printf("%-3d : %02x %s\n",
+ 14, spd->ecw,
+ " spd->ecw, * 14 Error Checking SDRAM width *");
+ printf("%-3d : %02x %s\n",
+ 15, spd->min_delay,
+ " spd->min_delay, * 15 Back to Back Random Access *");
+ printf("%-3d : %02x %s\n",
+ 16, spd->burstl,
+ " spd->burstl, * 16 Burst Lengths Supported *");
+ printf("%-3d : %02x %s\n",
+ 17, spd->nbanks,
+ " spd->nbanks, * 17 # of Banks on Each SDRAM Device *");
+ printf("%-3d : %02x %s\n",
+ 18, spd->cas_lat,
+ " spd->cas_lat, * 18 CAS# Latencies Supported *");
+ printf("%-3d : %02x %s\n",
+ 19, spd->cs_lat,
+ " spd->cs_lat, * 19 Chip Select Latency *");
+ printf("%-3d : %02x %s\n",
+ 20, spd->write_lat,
+ " spd->write_lat, * 20 Write Latency/Recovery *");
+ printf("%-3d : %02x %s\n",
+ 21, spd->mod_attr,
+ " spd->mod_attr, * 21 SDRAM Module Attributes *");
+ printf("%-3d : %02x %s\n",
+ 22, spd->dev_attr,
+ " spd->dev_attr, * 22 SDRAM Device Attributes *");
+ printf("%-3d : %02x %s\n",
+ 23, spd->clk_cycle2,
+ " spd->clk_cycle2, * 23 Min SDRAM Cycle time at CL=X-1 *");
+ printf("%-3d : %02x %s\n",
+ 24, spd->clk_access2,
+ " spd->clk_access2, * 24 SDRAM Access from Clock at CL=X-1 *");
+ printf("%-3d : %02x %s\n",
+ 25, spd->clk_cycle3,
+ " spd->clk_cycle3, * 25 Min SDRAM Cycle time at CL=X-2 *");
+ printf("%-3d : %02x %s\n",
+ 26, spd->clk_access3,
+ " spd->clk_access3, * 26 Max Access from Clock at CL=X-2 *");
+ printf("%-3d : %02x %s\n",
+ 27, spd->trp,
+ " spd->trp, * 27 Min Row Precharge Time (tRP)*");
+ printf("%-3d : %02x %s\n",
+ 28, spd->trrd,
+ " spd->trrd, * 28 Min Row Active to Row Active (tRRD) *");
+ printf("%-3d : %02x %s\n",
+ 29, spd->trcd,
+ " spd->trcd, * 29 Min RAS to CAS Delay (tRCD) *");
+ printf("%-3d : %02x %s\n",
+ 30, spd->tras,
+ " spd->tras, * 30 Minimum RAS Pulse Width (tRAS) *");
+ printf("%-3d : %02x %s\n",
+ 31, spd->bank_dens,
+ " spd->bank_dens, * 31 Density of each bank on module *");
+ printf("%-3d : %02x %s\n",
+ 32, spd->ca_setup,
+ " spd->ca_setup, * 32 Cmd + Addr signal input setup time *");
+ printf("%-3d : %02x %s\n",
+ 33, spd->ca_hold,
+ " spd->ca_hold, * 33 Cmd and Addr signal input hold time *");
+ printf("%-3d : %02x %s\n",
+ 34, spd->data_setup,
+ " spd->data_setup, * 34 Data signal input setup time *");
+ printf("%-3d : %02x %s\n",
+ 35, spd->data_hold,
+ " spd->data_hold, * 35 Data signal input hold time *");
+ printf("%-3d : %02x %s\n",
+ 36, spd->res_36_40[0],
+ " spd->res_36_40[0], * 36 Reserved / tWR *");
+ printf("%-3d : %02x %s\n",
+ 37, spd->res_36_40[1],
+ " spd->res_36_40[1], * 37 Reserved / tWTR *");
+ printf("%-3d : %02x %s\n",
+ 38, spd->res_36_40[2],
+ " spd->res_36_40[2], * 38 Reserved / tRTP *");
+ printf("%-3d : %02x %s\n",
+ 39, spd->res_36_40[3],
+ " spd->res_36_40[3], * 39 Reserved / mem_probe *");
+ printf("%-3d : %02x %s\n",
+ 40, spd->res_36_40[4],
+ " spd->res_36_40[4], * 40 Reserved / trc,trfc extensions *");
+ printf("%-3d : %02x %s\n",
+ 41, spd->trc,
+ " spd->trc, * 41 Min Active to Auto refresh time tRC *");
+ printf("%-3d : %02x %s\n",
+ 42, spd->trfc,
+ " spd->trfc, * 42 Min Auto to Active period tRFC *");
+ printf("%-3d : %02x %s\n",
+ 43, spd->tckmax,
+ " spd->tckmax, * 43 Max device cycle time tCKmax *");
+ printf("%-3d : %02x %s\n",
+ 44, spd->tdqsq,
+ " spd->tdqsq, * 44 Max DQS to DQ skew *");
+ printf("%-3d : %02x %s\n",
+ 45, spd->tqhs,
+ " spd->tqhs, * 45 Max Read DataHold skew tQHS *");
+ printf("%-3d : %02x %s\n",
+ 46, spd->res_46,
+ " spd->res_46, * 46 Reserved/ PLL Relock time *");
+ printf("%-3d : %02x %s\n",
+ 47, spd->dimm_height,
+ " spd->dimm_height * 47 SDRAM DIMM Height *");
+
+ printf("%-3d-%3d: ", 48, 61);
+ for (i = 0; i < 14; i++) {
+ printf("%02x", spd->res_48_61[i]);
+ }
+ printf(" * 48-61 IDD in SPD and Reserved space *\n");
+
+ printf("%-3d : %02x %s\n",
+ 62, spd->spd_rev,
+ " spd->spd_rev, * 62 SPD Data Revision Code *");
+ printf("%-3d : %02x %s\n",
+ 63, spd->cksum,
+ " spd->cksum, * 63 Checksum for bytes 0-62 *");
+ printf("%-3d-%3d: ", 64, 71);
+
+ for (i = 0; i < 8; i++) {
+ printf("%02x", spd->mid[i]);
+ }
+
+ printf("* 64 Mfr's JEDEC ID code per JEP-108E *\n");
+ printf("%-3d : %02x %s\n",
+ 72, spd->mloc,
+ " spd->mloc, * 72 Manufacturing Location *");
+
+ printf("%-3d-%3d: >>", 73, 90);
+ for (i = 0; i < 18; i++) {
+ printf("%c", spd->mpart[i]);
+ }
+
+ printf("<<* 73 Manufacturer's Part Number *\n");
+
+ printf("%-3d-%3d: %02x %02x %s\n",
+ 91, 92, spd->rev[0], spd->rev[1],
+ "* 91 Revision Code *");
+ printf("%-3d-%3d: %02x %02x %s\n",
+ 93, 94, spd->mdate[0], spd->mdate[1],
+ "* 93 Manufacturing Date *");
+ printf("%-3d-%3d: ", 95, 98);
+
+ for (i = 0; i < 4; i++) {
+ printf("%02x", spd->sernum[i]);
+ }
+ printf("* 95 Assembly Serial Number *\n");
+
+ printf("%-3d-%3d: ", 99, 127);
+ for (i = 0; i < 27; i++) {
+ printf("%02x", spd->mspec[i]);
+ }
+
+ printf("* 99 Manufacturer Specific Data *\n");
+}
+
+void
+ddr2_spd_dump(const ddr2_spd_eeprom_t *spd)
+{
+ unsigned int i;
+
+ printf("%-3d : %02x %s\n",
+ 0, spd->info_size,
+ " spd->info_size, * 0 # bytes written into serial memory *");
+ printf("%-3d : %02x %s\n",
+ 1, spd->chip_size,
+ " spd->chip_size, * 1 Total # bytes of SPD memory device *");
+ printf("%-3d : %02x %s\n",
+ 2, spd->mem_type,
+ " spd->mem_type, * 2 Fundamental memory type *");
+ printf("%-3d : %02x %s\n",
+ 3, spd->nrow_addr,
+ " spd->nrow_addr, * 3 # of Row Addresses on this assembly *");
+ printf("%-3d : %02x %s\n",
+ 4, spd->ncol_addr,
+ " spd->ncol_addr, * 4 # of Column Addrs on this assembly *");
+ printf("%-3d : %02x %s\n",
+ 5, spd->mod_ranks,
+ " spd->mod_ranks * 5 # of Module Rows on this assembly *");
+ printf("%-3d : %02x %s\n",
+ 6, spd->dataw,
+ " spd->dataw, * 6 Data Width of this assembly *");
+ printf("%-3d : %02x %s\n",
+ 7, spd->res_7,
+ " spd->res_7, * 7 Reserved *");
+ printf("%-3d : %02x %s\n",
+ 8, spd->voltage,
+ " spd->voltage, * 8 Voltage intf std of this assembly *");
+ printf("%-3d : %02x %s\n",
+ 9, spd->clk_cycle,
+ " spd->clk_cycle, * 9 SDRAM Cycle time at CL=X *");
+ printf("%-3d : %02x %s\n",
+ 10, spd->clk_access,
+ " spd->clk_access, * 10 SDRAM Access from Clock at CL=X *");
+ printf("%-3d : %02x %s\n",
+ 11, spd->config,
+ " spd->config, * 11 DIMM Configuration type *");
+ printf("%-3d : %02x %s\n",
+ 12, spd->refresh,
+ " spd->refresh, * 12 Refresh Rate/Type *");
+ printf("%-3d : %02x %s\n",
+ 13, spd->primw,
+ " spd->primw, * 13 Primary SDRAM Width *");
+ printf("%-3d : %02x %s\n",
+ 14, spd->ecw,
+ " spd->ecw, * 14 Error Checking SDRAM width *");
+ printf("%-3d : %02x %s\n",
+ 15, spd->res_15,
+ " spd->res_15, * 15 Reserved *");
+ printf("%-3d : %02x %s\n",
+ 16, spd->burstl,
+ " spd->burstl, * 16 Burst Lengths Supported *");
+ printf("%-3d : %02x %s\n",
+ 17, spd->nbanks,
+ " spd->nbanks, * 17 # of Banks on Each SDRAM Device *");
+ printf("%-3d : %02x %s\n",
+ 18, spd->cas_lat,
+ " spd->cas_lat, * 18 CAS# Latencies Supported *");
+ printf("%-3d : %02x %s\n",
+ 19, spd->mech_char,
+ " spd->mech_char, * 19 Mechanical Characteristics *");
+ printf("%-3d : %02x %s\n",
+ 20, spd->dimm_type,
+ " spd->dimm_type, * 20 DIMM type *");
+ printf("%-3d : %02x %s\n",
+ 21, spd->mod_attr,
+ " spd->mod_attr, * 21 SDRAM Module Attributes *");
+ printf("%-3d : %02x %s\n",
+ 22, spd->dev_attr,
+ " spd->dev_attr, * 22 SDRAM Device Attributes *");
+ printf("%-3d : %02x %s\n",
+ 23, spd->clk_cycle2,
+ " spd->clk_cycle2, * 23 Min SDRAM Cycle time at CL=X-1 *");
+ printf("%-3d : %02x %s\n",
+ 24, spd->clk_access2,
+ " spd->clk_access2, * 24 SDRAM Access from Clock at CL=X-1 *");
+ printf("%-3d : %02x %s\n",
+ 25, spd->clk_cycle3,
+ " spd->clk_cycle3, * 25 Min SDRAM Cycle time at CL=X-2 *");
+ printf("%-3d : %02x %s\n",
+ 26, spd->clk_access3,
+ " spd->clk_access3, * 26 Max Access from Clock at CL=X-2 *");
+ printf("%-3d : %02x %s\n",
+ 27, spd->trp,
+ " spd->trp, * 27 Min Row Precharge Time (tRP)*");
+ printf("%-3d : %02x %s\n",
+ 28, spd->trrd,
+ " spd->trrd, * 28 Min Row Active to Row Active (tRRD) *");
+ printf("%-3d : %02x %s\n",
+ 29, spd->trcd,
+ " spd->trcd, * 29 Min RAS to CAS Delay (tRCD) *");
+ printf("%-3d : %02x %s\n",
+ 30, spd->tras,
+ " spd->tras, * 30 Minimum RAS Pulse Width (tRAS) *");
+ printf("%-3d : %02x %s\n",
+ 31, spd->rank_dens,
+ " spd->rank_dens, * 31 Density of each rank on module *");
+ printf("%-3d : %02x %s\n",
+ 32, spd->ca_setup,
+ " spd->ca_setup, * 32 Cmd + Addr signal input setup time *");
+ printf("%-3d : %02x %s\n",
+ 33, spd->ca_hold,
+ " spd->ca_hold, * 33 Cmd and Addr signal input hold time *");
+ printf("%-3d : %02x %s\n",
+ 34, spd->data_setup,
+ " spd->data_setup, * 34 Data signal input setup time *");
+ printf("%-3d : %02x %s\n",
+ 35, spd->data_hold,
+ " spd->data_hold, * 35 Data signal input hold time *");
+ printf("%-3d : %02x %s\n",
+ 36, spd->twr,
+ " spd->twr, * 36 Write Recovery time tWR *");
+ printf("%-3d : %02x %s\n",
+ 37, spd->twtr,
+ " spd->twtr, * 37 Int write to read delay tWTR *");
+ printf("%-3d : %02x %s\n",
+ 38, spd->trtp,
+ " spd->trtp, * 38 Int read to precharge delay tRTP *");
+ printf("%-3d : %02x %s\n",
+ 39, spd->mem_probe,
+ " spd->mem_probe, * 39 Mem analysis probe characteristics *");
+ printf("%-3d : %02x %s\n",
+ 40, spd->trctrfc_ext,
+ " spd->trctrfc_ext, * 40 Extensions to trc and trfc *");
+ printf("%-3d : %02x %s\n",
+ 41, spd->trc,
+ " spd->trc, * 41 Min Active to Auto refresh time tRC *");
+ printf("%-3d : %02x %s\n",
+ 42, spd->trfc,
+ " spd->trfc, * 42 Min Auto to Active period tRFC *");
+ printf("%-3d : %02x %s\n",
+ 43, spd->tckmax,
+ " spd->tckmax, * 43 Max device cycle time tCKmax *");
+ printf("%-3d : %02x %s\n",
+ 44, spd->tdqsq,
+ " spd->tdqsq, * 44 Max DQS to DQ skew *");
+ printf("%-3d : %02x %s\n",
+ 45, spd->tqhs,
+ " spd->tqhs, * 45 Max Read DataHold skew tQHS *");
+ printf("%-3d : %02x %s\n",
+ 46, spd->pll_relock,
+ " spd->pll_relock, * 46 PLL Relock time *");
+ printf("%-3d : %02x %s\n",
+ 47, spd->Tcasemax,
+ " spd->Tcasemax, * 47 Tcasemax *");
+ printf("%-3d : %02x %s\n",
+ 48, spd->psiTAdram,
+ " spd->psiTAdram, * 48 Thermal Resistance of DRAM Package "
+ "from Top (Case) to Ambient (Psi T-A DRAM) *");
+ printf("%-3d : %02x %s\n",
+ 49, spd->dt0_mode,
+ " spd->dt0_mode, * 49 DRAM Case Temperature Rise from "
+ "Ambient due to Activate-Precharge/Mode Bits "
+ "(DT0/Mode Bits) *)");
+ printf("%-3d : %02x %s\n",
+ 50, spd->dt2n_dt2q,
+ " spd->dt2n_dt2q, * 50 DRAM Case Temperature Rise from "
+ "Ambient due to Precharge/Quiet Standby "
+ "(DT2N/DT2Q) *");
+ printf("%-3d : %02x %s\n",
+ 51, spd->dt2p,
+ " spd->dt2p, * 51 DRAM Case Temperature Rise from "
+ "Ambient due to Precharge Power-Down (DT2P) *");
+ printf("%-3d : %02x %s\n",
+ 52, spd->dt3n,
+ " spd->dt3n, * 52 DRAM Case Temperature Rise from "
+ "Ambient due to Active Standby (DT3N) *");
+ printf("%-3d : %02x %s\n",
+ 53, spd->dt3pfast,
+ " spd->dt3pfast, * 53 DRAM Case Temperature Rise from "
+ "Ambient due to Active Power-Down with Fast PDN Exit "
+ "(DT3Pfast) *");
+ printf("%-3d : %02x %s\n",
+ 54, spd->dt3pslow,
+ " spd->dt3pslow, * 54 DRAM Case Temperature Rise from "
+ "Ambient due to Active Power-Down with Slow PDN Exit "
+ "(DT3Pslow) *");
+ printf("%-3d : %02x %s\n",
+ 55, spd->dt4r_dt4r4w,
+ " spd->dt4r_dt4r4w, * 55 DRAM Case Temperature Rise from "
+ "Ambient due to Page Open Burst Read/DT4R4W Mode Bit "
+ "(DT4R/DT4R4W Mode Bit) *");
+ printf("%-3d : %02x %s\n",
+ 56, spd->dt5b,
+ " spd->dt5b, * 56 DRAM Case Temperature Rise from "
+ "Ambient due to Burst Refresh (DT5B) *");
+ printf("%-3d : %02x %s\n",
+ 57, spd->dt7,
+ " spd->dt7, * 57 DRAM Case Temperature Rise from "
+ "Ambient due to Bank Interleave Reads with "
+ "Auto-Precharge (DT7) *");
+ printf("%-3d : %02x %s\n",
+ 58, spd->psiTApll,
+ " spd->psiTApll, * 58 Thermal Resistance of PLL Package form"
+ " Top (Case) to Ambient (Psi T-A PLL) *");
+ printf("%-3d : %02x %s\n",
+ 59, spd->psiTAreg,
+ " spd->psiTAreg, * 59 Thermal Reisitance of Register Package"
+ " from Top (Case) to Ambient (Psi T-A Register) *");
+ printf("%-3d : %02x %s\n",
+ 60, spd->dtpllactive,
+ " spd->dtpllactive, * 60 PLL Case Temperature Rise from "
+ "Ambient due to PLL Active (DT PLL Active) *");
+ printf("%-3d : %02x %s\n",
+ 61, spd->dtregact,
+ " spd->dtregact, "
+ "* 61 Register Case Temperature Rise from Ambient due to "
+ "Register Active/Mode Bit (DT Register Active/Mode Bit) *");
+ printf("%-3d : %02x %s\n",
+ 62, spd->spd_rev,
+ " spd->spd_rev, * 62 SPD Data Revision Code *");
+ printf("%-3d : %02x %s\n",
+ 63, spd->cksum,
+ " spd->cksum, * 63 Checksum for bytes 0-62 *");
+ printf("%-3d-%3d: ", 64, 71);
+
+ for (i = 0; i < 8; i++) {
+ printf("%02x", spd->mid[i]);
+ }
+
+ printf("* 64 Mfr's JEDEC ID code per JEP-108E *\n");
+ printf("%-3d : %02x %s\n",
+ 72, spd->mloc,
+ " spd->mloc, * 72 Manufacturing Location *");
+
+ printf("%-3d-%3d: >>", 73, 90);
+ for (i = 0; i < 18; i++) {
+ printf("%c", spd->mpart[i]);
+ }
+
+ printf("<<* 73 Manufacturer's Part Number *\n");
+
+ printf("%-3d-%3d: %02x %02x %s\n",
+ 91, 92, spd->rev[0], spd->rev[1],
+ "* 91 Revision Code *");
+ printf("%-3d-%3d: %02x %02x %s\n",
+ 93, 94, spd->mdate[0], spd->mdate[1],
+ "* 93 Manufacturing Date *");
+ printf("%-3d-%3d: ", 95, 98);
+
+ for (i = 0; i < 4; i++) {
+ printf("%02x", spd->sernum[i]);
+ }
+ printf("* 95 Assembly Serial Number *\n");
+
+ printf("%-3d-%3d: ", 99, 127);
+ for (i = 0; i < 27; i++) {
+ printf("%02x", spd->mspec[i]);
+ }
+
+ printf("* 99 Manufacturer Specific Data *\n");
+}
+
+/* used for ddr1 and ddr2 spd */
+static int
+spd_check(const u8 *buf, u8 spd_rev, u8 spd_cksum)
+{
+ unsigned int cksum = 0;
+ unsigned int i;
+
+ /*
+ * Check SPD revision supported
+ * Rev 1.2 or less supported by this code
+ */
+ if (spd_rev > 0x12) {
+ printf("SPD revision %02X not supported by this code\n",
+ spd_rev);
+ return 1;
+ }
+
+ /*
+ * Calculate checksum
+ */
+ for (i = 0; i < 63; i++) {
+ cksum += *buf++;
+ }
+ cksum &= 0xFF;
+
+ if (cksum != spd_cksum) {
+ printf("SPD checksum unexpected. "
+ "Checksum in SPD = %02X, computed SPD = %02X\n",
+ spd_cksum, cksum);
+ return 1;
+ }
+
+ return 0;
+}
+
+unsigned int
+ddr1_spd_check(const ddr1_spd_eeprom_t *spd)
+{
+ const u8 *p = (const u8 *)spd;
+
+ return spd_check(p, spd->spd_rev, spd->cksum);
+}
+
+unsigned int
+ddr2_spd_check(const ddr2_spd_eeprom_t *spd)
+{
+ const u8 *p = (const u8 *)spd;
+
+ return spd_check(p, spd->spd_rev, spd->cksum);
+}
diff --git a/include/ddr_spd.h b/include/ddr_spd.h
new file mode 100644
index 0000000..6fdcef0
--- /dev/null
+++ b/include/ddr_spd.h
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * Version 2 as published by the Free Software Foundation.
+ */
+
+#ifndef _DDR_SPD_H_
+#define _DDR_SPD_H_
+
+/*
+ * Format from "JEDEC Standard No. 21-C,
+ * Appendix D: Rev 1.0: SPD's for DDR SDRAM
+ */
+typedef struct ddr1_spd_eeprom_s {
+ unsigned char info_size; /* 0 # bytes written into serial memory */
+ unsigned char chip_size; /* 1 Total # bytes of SPD memory device */
+ unsigned char mem_type; /* 2 Fundamental memory type */
+ unsigned char nrow_addr; /* 3 # of Row Addresses on this assembly */
+ unsigned char ncol_addr; /* 4 # of Column Addrs on this assembly */
+ unsigned char nrows; /* 5 Number of DIMM Banks */
+ unsigned char dataw_lsb; /* 6 Data Width of this assembly */
+ unsigned char dataw_msb; /* 7 ... Data Width continuation */
+ unsigned char voltage; /* 8 Voltage intf std of this assembly */
+ unsigned char clk_cycle; /* 9 SDRAM Cycle time @ CL=X */
+ unsigned char clk_access; /* 10 SDRAM Access from Clk @ CL=X (tAC) */
+ unsigned char config; /* 11 DIMM Configuration type */
+ unsigned char refresh; /* 12 Refresh Rate/Type */
+ unsigned char primw; /* 13 Primary SDRAM Width */
+ unsigned char ecw; /* 14 Error Checking SDRAM width */
+ unsigned char min_delay; /* 15 for Back to Back Random Address */
+ unsigned char burstl; /* 16 Burst Lengths Supported */
+ unsigned char nbanks; /* 17 # of Banks on SDRAM Device */
+ unsigned char cas_lat; /* 18 CAS# Latencies Supported */
+ unsigned char cs_lat; /* 19 CS# Latency */
+ unsigned char write_lat; /* 20 Write Latency (aka Write Recovery) */
+ unsigned char mod_attr; /* 21 SDRAM Module Attributes */
+ unsigned char dev_attr; /* 22 SDRAM Device Attributes */
+ unsigned char clk_cycle2; /* 23 Min SDRAM Cycle time @ CL=X-0.5 */
+ unsigned char clk_access2; /* 24 SDRAM Access from
+ Clk @ CL=X-0.5 (tAC) */
+ unsigned char clk_cycle3; /* 25 Min SDRAM Cycle time @ CL=X-1 */
+ unsigned char clk_access3; /* 26 Max Access from Clk @ CL=X-1 (tAC) */
+ unsigned char trp; /* 27 Min Row Precharge Time (tRP)*/
+ unsigned char trrd; /* 28 Min Row Active to Row Active (tRRD) */
+ unsigned char trcd; /* 29 Min RAS to CAS Delay (tRCD) */
+ unsigned char tras; /* 30 Minimum RAS Pulse Width (tRAS) */
+ unsigned char bank_dens; /* 31 Density of each bank on module */
+ unsigned char ca_setup; /* 32 Addr + Cmd Setup Time Before Clk */
+ unsigned char ca_hold; /* 33 Addr + Cmd Hold Time After Clk */
+ unsigned char data_setup; /* 34 Data Input Setup Time Before Strobe */
+ unsigned char data_hold; /* 35 Data Input Hold Time After Strobe */
+ unsigned char res_36_40[5];/* 36-40 reserved for VCSDRAM */
+ unsigned char trc; /* 41 Min Active to Auto refresh time tRC */
+ unsigned char trfc; /* 42 Min Auto to Active period tRFC */
+ unsigned char tckmax; /* 43 Max device cycle time tCKmax */
+ unsigned char tdqsq; /* 44 Max DQS to DQ skew (tDQSQ max) */
+ unsigned char tqhs; /* 45 Max Read DataHold skew (tQHS) */
+ unsigned char res_46; /* 46 Reserved */
+ unsigned char dimm_height; /* 47 DDR SDRAM DIMM Height */
+ unsigned char res_48_61[14]; /* 48-61 Reserved */
+ unsigned char spd_rev; /* 62 SPD Data Revision Code */
+ unsigned char cksum; /* 63 Checksum for bytes 0-62 */
+ unsigned char mid[8]; /* 64-71 Mfr's JEDEC ID code per JEP-106 */
+ unsigned char mloc; /* 72 Manufacturing Location */
+ unsigned char mpart[18]; /* 73 Manufacturer's Part Number */
+ unsigned char rev[2]; /* 91 Revision Code */
+ unsigned char mdate[2]; /* 93 Manufacturing Date */
+ unsigned char sernum[4]; /* 95 Assembly Serial Number */
+ unsigned char mspec[27]; /* 99-127 Manufacturer Specific Data */
+
+} ddr1_spd_eeprom_t;
+
+/*
+ * Format from "JEDEC Appendix X: Serial Presence Detects for DDR2 SDRAM",
+ * SPD Revision 1.2
+ */
+typedef struct ddr2_spd_eeprom_s {
+ unsigned char info_size; /* 0 # bytes written into serial memory */
+ unsigned char chip_size; /* 1 Total # bytes of SPD memory device */
+ unsigned char mem_type; /* 2 Fundamental memory type */
+ unsigned char nrow_addr; /* 3 # of Row Addresses on this assembly */
+ unsigned char ncol_addr; /* 4 # of Column Addrs on this assembly */
+ unsigned char mod_ranks; /* 5 Number of DIMM Ranks */
+ unsigned char dataw; /* 6 Module Data Width */
+ unsigned char res_7; /* 7 Reserved */
+ unsigned char voltage; /* 8 Voltage intf std of this assembly */
+ unsigned char clk_cycle; /* 9 SDRAM Cycle time @ CL=X */
+ unsigned char clk_access; /* 10 SDRAM Access from Clk @ CL=X (tAC) */
+ unsigned char config; /* 11 DIMM Configuration type */
+ unsigned char refresh; /* 12 Refresh Rate/Type */
+ unsigned char primw; /* 13 Primary SDRAM Width */
+ unsigned char ecw; /* 14 Error Checking SDRAM width */
+ unsigned char res_15; /* 15 Reserved */
+ unsigned char burstl; /* 16 Burst Lengths Supported */
+ unsigned char nbanks; /* 17 # of Banks on Each SDRAM Device */
+ unsigned char cas_lat; /* 18 CAS# Latencies Supported */
+ unsigned char mech_char; /* 19 DIMM Mechanical Characteristics */
+ unsigned char dimm_type; /* 20 DIMM type information */
+ unsigned char mod_attr; /* 21 SDRAM Module Attributes */
+ unsigned char dev_attr; /* 22 SDRAM Device Attributes */
+ unsigned char clk_cycle2; /* 23 Min SDRAM Cycle time @ CL=X-1 */
+ unsigned char clk_access2; /* 24 SDRAM Access from Clk @ CL=X-1 (tAC) */
+ unsigned char clk_cycle3; /* 25 Min SDRAM Cycle time @ CL=X-2 */
+ unsigned char clk_access3; /* 26 Max Access from Clk @ CL=X-2 (tAC) */
+ unsigned char trp; /* 27 Min Row Precharge Time (tRP)*/
+ unsigned char trrd; /* 28 Min Row Active to Row Active (tRRD) */
+ unsigned char trcd; /* 29 Min RAS to CAS Delay (tRCD) */
+ unsigned char tras; /* 30 Minimum RAS Pulse Width (tRAS) */
+ unsigned char rank_dens; /* 31 Density of each rank on module */
+ unsigned char ca_setup; /* 32 Addr+Cmd Setup Time Before Clk (tIS) */
+ unsigned char ca_hold; /* 33 Addr+Cmd Hold Time After Clk (tIH) */
+ unsigned char data_setup; /* 34 Data Input Setup Time
+ Before Strobe (tDS) */
+ unsigned char data_hold; /* 35 Data Input Hold Time
+ After Strobe (tDH) */
+ unsigned char twr; /* 36 Write Recovery time tWR */
+ unsigned char twtr; /* 37 Int write to read delay tWTR */
+ unsigned char trtp; /* 38 Int read to precharge delay tRTP */
+ unsigned char mem_probe; /* 39 Mem analysis probe characteristics */
+ unsigned char trctrfc_ext; /* 40 Extensions to trc and trfc */
+ unsigned char trc; /* 41 Min Active to Auto refresh time tRC */
+ unsigned char trfc; /* 42 Min Auto to Active period tRFC */
+ unsigned char tckmax; /* 43 Max device cycle time tCKmax */
+ unsigned char tdqsq; /* 44 Max DQS to DQ skew (tDQSQ max) */
+ unsigned char tqhs; /* 45 Max Read DataHold skew (tQHS) */
+ unsigned char pll_relock; /* 46 PLL Relock time */
+ unsigned char Tcasemax; /* 47 Tcasemax */
+ unsigned char psiTAdram; /* 48 Thermal Resistance of DRAM Package from
+ Top (Case) to Ambient (Psi T-A DRAM) */
+ unsigned char dt0_mode; /* 49 DRAM Case Temperature Rise from Ambient
+ due to Activate-Precharge/Mode Bits
+ (DT0/Mode Bits) */
+ unsigned char dt2n_dt2q; /* 50 DRAM Case Temperature Rise from Ambient
+ due to Precharge/Quiet Standby
+ (DT2N/DT2Q) */
+ unsigned char dt2p; /* 51 DRAM Case Temperature Rise from Ambient
+ due to Precharge Power-Down (DT2P) */
+ unsigned char dt3n; /* 52 DRAM Case Temperature Rise from Ambient
+ due to Active Standby (DT3N) */
+ unsigned char dt3pfast; /* 53 DRAM Case Temperature Rise from Ambient
+ due to Active Power-Down with
+ Fast PDN Exit (DT3Pfast) */
+ unsigned char dt3pslow; /* 54 DRAM Case Temperature Rise from Ambient
+ due to Active Power-Down with Slow
+ PDN Exit (DT3Pslow) */
+ unsigned char dt4r_dt4r4w; /* 55 DRAM Case Temperature Rise from Ambient
+ due to Page Open Burst Read/DT4R4W
+ Mode Bit (DT4R/DT4R4W Mode Bit) */
+ unsigned char dt5b; /* 56 DRAM Case Temperature Rise from Ambient
+ due to Burst Refresh (DT5B) */
+ unsigned char dt7; /* 57 DRAM Case Temperature Rise from Ambient
+ due to Bank Interleave Reads with
+ Auto-Precharge (DT7) */
+ unsigned char psiTApll; /* 58 Thermal Resistance of PLL Package form
+ Top (Case) to Ambient (Psi T-A PLL) */
+ unsigned char psiTAreg; /* 59 Thermal Reisitance of Register Package
+ from Top (Case) to Ambient
+ (Psi T-A Register) */
+ unsigned char dtpllactive; /* 60 PLL Case Temperature Rise from Ambient
+ due to PLL Active (DT PLL Active) */
+ unsigned char dtregact; /* 61 Register Case Temperature Rise from
+ Ambient due to Register Active/Mode Bit
+ (DT Register Active/Mode Bit) */
+ unsigned char spd_rev; /* 62 SPD Data Revision Code */
+ unsigned char cksum; /* 63 Checksum for bytes 0-62 */
+ unsigned char mid[8]; /* 64 Mfr's JEDEC ID code per JEP-106 */
+ unsigned char mloc; /* 72 Manufacturing Location */
+ unsigned char mpart[18]; /* 73 Manufacturer's Part Number */
+ unsigned char rev[2]; /* 91 Revision Code */
+ unsigned char mdate[2]; /* 93 Manufacturing Date */
+ unsigned char sernum[4]; /* 95 Assembly Serial Number */
+ unsigned char mspec[27]; /* 99-127 Manufacturer Specific Data */
+
+} ddr2_spd_eeprom_t;
+
+typedef struct ddr3_spd_eeprom_s {
+ /* General Section: Bytes 0-59 */
+ unsigned char info_size_crc; /* 0 # bytes written into serial memory,
+ CRC coverage */
+ unsigned char spd_rev; /* 1 Total # bytes of SPD mem device */
+ unsigned char mem_type; /* 2 Key Byte / Fundamental mem type */
+ unsigned char module_type; /* 3 Key Byte / Module Type */
+ unsigned char density_banks; /* 4 SDRAM Density and Banks */
+ unsigned char addressing; /* 5 SDRAM Addressing */
+ unsigned char res_6; /* 6 Reserved */
+ unsigned char organization; /* 7 Module Organization */
+ unsigned char bus_width; /* 8 Module Memory Bus Width */
+ unsigned char ftb_div; /* 9 Fine Timebase (FTB)
+ Dividend / Divisor */
+ unsigned char mtb_dividend; /* 10 Medium Timebase (MTB) Dividend */
+ unsigned char mtb_divisor; /* 11 Medium Timebase (MTB) Divisor */
+ unsigned char tCK_min; /* 12 SDRAM Minimum Cycle Time */
+ unsigned char res_13; /* 13 Reserved */
+ unsigned char caslat_lsb; /* 14 CAS Latencies Supported,
+ Least Significant Byte */
+ unsigned char caslat_msb; /* 15 CAS Latencies Supported,
+ Most Significant Byte */
+ unsigned char tAA_min; /* 16 Min CAS Latency Time */
+ unsigned char tWR_min; /* 17 Min Write REcovery Time */
+ unsigned char tRCD_min; /* 18 Min RAS# to CAS# Delay Time */
+ unsigned char tRRD_min; /* 19 Min Row Active to
+ Row Active Delay Time */
+ unsigned char tRP_min; /* 20 Min Row Precharge Delay Time */
+ unsigned char tRAS_tRC_ext; /* 21 Upper Nibbles for tRAS and tRC */
+ unsigned char tRAS_min_lsb; /* 22 Min Active to Precharge
+ Delay Time */
+ unsigned char tRC_min_lsb; /* 23 Min Active to Active/Refresh
+ Delay Time, LSB */
+ unsigned char tRFC_min_lsb; /* 24 Min Refresh Recovery Delay Time */
+ unsigned char tRFC_min_msb; /* 25 Min Refresh Recovery Delay Time */
+ unsigned char tWTR_min; /* 26 Min Internal Write to
+ Read Command Delay Time */
+ unsigned char tRTP_min; /* 27 Min Internal Read to Precharge
+ Command Delay Time */
+ unsigned char tFAW_msb; /* 28 Upper Nibble for tFAW */
+ unsigned char tFAW_min; /* 29 Min Four Activate Window
+ Delay Time*/
+ unsigned char opt_features; /* 30 SDRAM Optional Features */
+ unsigned char therm_ref_opt; /* 31 SDRAM Thermal and Refresh Opts */
+ unsigned char res_32_59[28]; /* 32-59 Reserved, General Section */
+
+ /* Module-Specific Section: Bytes 60-116 */
+ union {
+ struct {
+ /* 60 (Unbuffered) Module Nominal Height */
+ unsigned char mod_height;
+ /* 61 (Unbuffered) Module Maximum Thickness */
+ unsigned char mod_thickness;
+ /* 62 (Unbuffered) Reference Raw Card Used */
+ unsigned char ref_raw_card;
+ /* 63 (Unbuffered) Address Mapping from
+ Edge Connector to DRAM */
+ unsigned char addr_mapping;
+ /* 64-116 (Unbuffered) Reserved */
+ unsigned char res_64_116[53];
+ } unbuffered;
+ struct {
+ /* 60 (Registered) Module Nominal Height */
+ unsigned char mod_height;
+ /* 61 (Registered) Module Maximum Thickness */
+ unsigned char mod_thickness;
+ /* 62 (Registered) Reference Raw Card Used */
+ unsigned char ref_raw_card;
+ } registered;
+ unsigned char uc[57]; /* 60-116 Module-Specific Section */
+ } mod_section;
+
+ /* Unique Module ID: Bytes 117-125 */
+ unsigned char mmid_lsb; /* 117 Module MfgID Code LSB - JEP-106 */
+ unsigned char mmid_msb; /* 118 Module MfgID Code MSB - JEP-106 */
+ unsigned char mloc; /* 119 Mfg Location */
+ unsigned char mdate[2]; /* 120-121 Mfg Date */
+ unsigned char sernum[4]; /* 122-125 Module Serial Number */
+
+ /* CRC: Bytes 126-127 */
+ unsigned char crc[2]; /* 126-127 SPD CRC */
+
+ /* Other Manufacturer Fields and User Space: Bytes 128-255 */
+ unsigned char mpart[18]; /* 128-145 Mfg's Module Part Number */
+ unsigned char mrev[2]; /* 146-147 Module Revision Code */
+
+ unsigned char dmid_lsb; /* 148 DRAM MfgID Code LSB - JEP-106 */
+ unsigned char dmid_msb; /* 149 DRAM MfgID Code MSB - JEP-106 */
+
+ unsigned char msd[26]; /* 150-175 Mfg's Specific Data */
+ unsigned char cust[80]; /* 176-255 Open for Customer Use */
+
+} ddr3_spd_eeprom_t;
+
+extern unsigned int ddr1_spd_check(const ddr1_spd_eeprom_t *spd);
+extern void ddr1_spd_dump(const ddr1_spd_eeprom_t *spd);
+extern unsigned int ddr2_spd_check(const ddr2_spd_eeprom_t *spd);
+extern void ddr2_spd_dump(const ddr2_spd_eeprom_t *spd);
+
+/*
+ * Byte 2 Fundamental Memory Types.
+ */
+#define SPD_MEMTYPE_FPM (0x01)
+#define SPD_MEMTYPE_EDO (0x02)
+#define SPD_MEMTYPE_PIPE_NIBBLE (0x03)
+#define SPD_MEMTYPE_SDRAM (0x04)
+#define SPD_MEMTYPE_ROM (0x05)
+#define SPD_MEMTYPE_SGRAM (0x06)
+#define SPD_MEMTYPE_DDR (0x07)
+#define SPD_MEMTYPE_DDR2 (0x08)
+#define SPD_MEMTYPE_DDR2_FBDIMM (0x09)
+#define SPD_MEMTYPE_DDR2_FBDIMM_PROBE (0x0A)
+#define SPD_MEMTYPE_DDR3 (0x0B)
+
+#endif /* _DDR_SPD_H_ */
--
1.5.5.1
More information about the U-Boot
mailing list