summaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorJames Yang <James.Yang@freescale.com>2008-08-26 15:01:27 -0500
committerWolfgang Denk <wd@denx.de>2008-08-27 02:05:53 +0200
commit0f2cbe3f5eddbdf3848265f35e4f714434929cff (patch)
treeb0d310ad0246afd183e6458c53f21d56368a3de9 /common
parent285db74716c724ae8a0ff177878fd09a74428c7b (diff)
downloadbootable_bootloader_goldelico_gta04-0f2cbe3f5eddbdf3848265f35e4f714434929cff.zip
bootable_bootloader_goldelico_gta04-0f2cbe3f5eddbdf3848265f35e4f714434929cff.tar.gz
bootable_bootloader_goldelico_gta04-0f2cbe3f5eddbdf3848265f35e4f714434929cff.tar.bz2
Add proper SPD definitions for DDR1/2/3
Also adds helper functions for DDR1/2 to verify the checksum. Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Diffstat (limited to 'common')
-rw-r--r--common/Makefile1
-rw-r--r--common/ddr_spd.c61
2 files changed, 62 insertions, 0 deletions
diff --git a/common/Makefile b/common/Makefile
index 7811032..944b1c0 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -151,6 +151,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..78e3c5d
--- /dev/null
+++ b/common/ddr_spd.c
@@ -0,0 +1,61 @@
+/*
+ * 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>
+
+/* 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);
+}