2
0
mirror of https://github.com/lm-sensors/lm-sensors synced 2025-08-31 22:35:23 +00:00

Fix detection of SPD EEPROM on DDR3 memory modules. DDR3 uses CRC16 over

128 bytes instead of basic checksum over 64 bytes. Contributed by
Clemens Ladisch.


git-svn-id: http://lm-sensors.org/svn/lm-sensors/trunk@5930 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Jean Delvare
2011-02-16 15:08:25 +00:00
parent edb64c42ca
commit 1ca80a309e
2 changed files with 33 additions and 7 deletions

View File

@@ -5264,19 +5264,44 @@ sub it8712_i2c_detect
}
# Registers used:
# 0-63: SPD Data and Checksum
# 0-63: SPD Data and Checksum (up to DDR2)
# 0-127: SPD data and CRC (DDR3)
sub eeprom_detect
{
my ($file, $addr) = @_;
my $device_type = i2c_smbus_read_byte_data($file, 2);
my $checksum = 0;
# Check the checksum for validity (works for most DIMMs and RIMMs)
for (my $i = 0; $i <= 62; $i++) {
$checksum += i2c_smbus_read_byte_data($file, $i);
}
$checksum &= 255;
# Check the checksum or CRC16 for validity
if ($device_type >= 1 and $device_type <= 8) {
for (my $i = 0; $i < 63; $i++) {
$checksum += i2c_smbus_read_byte_data($file, $i);
}
$checksum &= 0xff;
return 8 if $checksum == i2c_smbus_read_byte_data($file, 63);
} elsif ($device_type => 9 && $device_type <= 11) {
# see JEDEC 21-C 4.1.2.11 2.4
my $crc_coverage = i2c_smbus_read_byte_data($file, 0);
$crc_coverage = ($crc_coverage & 0x80) ? 117 : 126;
for (my $i = 0; $i < $crc_coverage; $i++) {
$checksum ^= i2c_smbus_read_byte_data($file, $i) << 8;
for (my $bit = 0; $bit < 8; $bit++) {
if ($checksum & 0x8000) {
$checksum = ($checksum << 1) ^ 0x1021;
} else {
$checksum <<= 1;
}
}
}
$checksum &= 0xffff;
return 8 if ($checksum & 0xff) == i2c_smbus_read_byte_data($file, 126) and
($checksum >> 8) == i2c_smbus_read_byte_data($file, 127);
# note: if bit 7 of byte 32 is set, a jc42 sensor is at $addr-0x38
}
return 8 if $checksum == i2c_smbus_read_byte_data($file, 63);
return;
}