aboutsummaryrefslogtreecommitdiff
path: root/common/ddr_spd.c
diff options
context:
space:
mode:
authorDave Liu2009-03-14 12:48:30 +0800
committerKumar Gala2009-03-30 13:33:50 -0500
commitc360ceac0286159f94d9d1a9496fc9858c8d9bec (patch)
treefdd1868af478993fdb547171665c5c517ee6c071 /common/ddr_spd.c
parent6a8197836702991468cead5ead073f589e2623ad (diff)
fsl-ddr: add the DDR3 SPD infrastructure
- support mirrored DIMMs, not support register DIMMs - test passed on P2020DS board with MT9JSF12872AY-1G1D1 - test passed on MPC8569MDS board with MT8JSF12864HY-1G1D1 Signed-off-by: Dave Liu <daveliu@freescale.com> Signed-off-by: Travis Wheatley <travis.wheatley@freescale.com>
Diffstat (limited to 'common/ddr_spd.c')
-rw-r--r--common/ddr_spd.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/common/ddr_spd.c b/common/ddr_spd.c
index 78e3c5d9f29..c058e4f18a3 100644
--- a/common/ddr_spd.c
+++ b/common/ddr_spd.c
@@ -59,3 +59,56 @@ ddr2_spd_check(const ddr2_spd_eeprom_t *spd)
return spd_check(p, spd->spd_rev, spd->cksum);
}
+
+/*
+ * CRC16 compute for DDR3 SPD
+ * Copied from DDR3 SPD spec.
+ */
+static int
+crc16(char *ptr, int count)
+{
+ int crc, i;
+
+ crc = 0;
+ while (--count >= 0) {
+ crc = crc ^ (int)*ptr++ << 8;
+ for (i = 0; i < 8; ++i)
+ if (crc & 0x8000)
+ crc = crc << 1 ^ 0x1021;
+ else
+ crc = crc << 1;
+ }
+ return crc & 0xffff;
+}
+
+unsigned int
+ddr3_spd_check(const ddr3_spd_eeprom_t *spd)
+{
+ char *p = (char *)spd;
+ int csum16;
+ int len;
+ char crc_lsb; /* byte 126 */
+ char crc_msb; /* byte 127 */
+
+ /*
+ * SPD byte0[7] - CRC coverage
+ * 0 = CRC covers bytes 0~125
+ * 1 = CRC covers bytes 0~116
+ */
+
+ len = !(spd->info_size_crc & 0x80) ? 126 : 117;
+ csum16 = crc16(p, len);
+
+ crc_lsb = (char) (csum16 & 0xff);
+ crc_msb = (char) (csum16 >> 8);
+
+ if (spd->crc[0] == crc_lsb && spd->crc[1] == crc_msb) {
+ return 0;
+ } else {
+ printf("SPD checksum unexpected.\n"
+ "Checksum lsb in SPD = %02X, computed SPD = %02X\n"
+ "Checksum msb in SPD = %02X, computed SPD = %02X\n",
+ spd->crc[0], crc_lsb, spd->crc[1], crc_msb);
+ return 1;
+ }
+}