]>
git.ipfire.org Git - people/ms/u-boot.git/blob - common/ddr_spd.c
2 * Copyright 2008-2014 Freescale Semiconductor, Inc.
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * Version 2 as published by the Free Software Foundation.
12 /* used for ddr1 and ddr2 spd */
14 spd_check(const u8
*buf
, u8 spd_rev
, u8 spd_cksum
)
16 unsigned int cksum
= 0;
20 * Check SPD revision supported
21 * Rev 1.X or less supported by this code
23 if (spd_rev
>= 0x20) {
24 printf("SPD revision %02X not supported by this code\n",
29 printf("SPD revision %02X not verified by this code\n",
36 for (i
= 0; i
< 63; i
++) {
41 if (cksum
!= spd_cksum
) {
42 printf("SPD checksum unexpected. "
43 "Checksum in SPD = %02X, computed SPD = %02X\n",
52 ddr1_spd_check(const ddr1_spd_eeprom_t
*spd
)
54 const u8
*p
= (const u8
*)spd
;
56 return spd_check(p
, spd
->spd_rev
, spd
->cksum
);
60 ddr2_spd_check(const ddr2_spd_eeprom_t
*spd
)
62 const u8
*p
= (const u8
*)spd
;
64 return spd_check(p
, spd
->spd_rev
, spd
->cksum
);
68 * CRC16 compute for DDR3 SPD
69 * Copied from DDR3 SPD spec.
72 crc16(char *ptr
, int count
)
77 while (--count
>= 0) {
78 crc
= crc
^ (int)*ptr
++ << 8;
79 for (i
= 0; i
< 8; ++i
)
81 crc
= crc
<< 1 ^ 0x1021;
89 ddr3_spd_check(const ddr3_spd_eeprom_t
*spd
)
91 char *p
= (char *)spd
;
94 char crc_lsb
; /* byte 126 */
95 char crc_msb
; /* byte 127 */
98 * SPD byte0[7] - CRC coverage
99 * 0 = CRC covers bytes 0~125
100 * 1 = CRC covers bytes 0~116
103 len
= !(spd
->info_size_crc
& 0x80) ? 126 : 117;
104 csum16
= crc16(p
, len
);
106 crc_lsb
= (char) (csum16
& 0xff);
107 crc_msb
= (char) (csum16
>> 8);
109 if (spd
->crc
[0] == crc_lsb
&& spd
->crc
[1] == crc_msb
) {
112 printf("SPD checksum unexpected.\n"
113 "Checksum lsb in SPD = %02X, computed SPD = %02X\n"
114 "Checksum msb in SPD = %02X, computed SPD = %02X\n",
115 spd
->crc
[0], crc_lsb
, spd
->crc
[1], crc_msb
);
120 unsigned int ddr4_spd_check(const struct ddr4_spd_eeprom_s
*spd
)
122 char *p
= (char *)spd
;
125 char crc_lsb
; /* byte 126 */
126 char crc_msb
; /* byte 127 */
129 csum16
= crc16(p
, len
);
131 crc_lsb
= (char) (csum16
& 0xff);
132 crc_msb
= (char) (csum16
>> 8);
134 if (spd
->crc
[0] != crc_lsb
|| spd
->crc
[1] != crc_msb
) {
135 printf("SPD checksum unexpected.\n"
136 "Checksum lsb in SPD = %02X, computed SPD = %02X\n"
137 "Checksum msb in SPD = %02X, computed SPD = %02X\n",
138 spd
->crc
[0], crc_lsb
, spd
->crc
[1], crc_msb
);
142 p
= (char *)((ulong
)spd
+ 128);
144 csum16
= crc16(p
, len
);
146 crc_lsb
= (char) (csum16
& 0xff);
147 crc_msb
= (char) (csum16
>> 8);
149 if (spd
->mod_section
.uc
[126] != crc_lsb
||
150 spd
->mod_section
.uc
[127] != crc_msb
) {
151 printf("SPD checksum unexpected.\n"
152 "Checksum lsb in SPD = %02X, computed SPD = %02X\n"
153 "Checksum msb in SPD = %02X, computed SPD = %02X\n",
154 spd
->mod_section
.uc
[126],
155 crc_lsb
, spd
->mod_section
.uc
[127],