Changeset 5152

Show
Ignore:
Timestamp:
03/21/08 18:14:25 (7 years ago)
Author:
khali
Message:

Patch from Trent Piepho:

This lets decode-dimms.pl decode almost all of the SPD data for DDR2 dimms.
Included are all the detailed timing parameters with their standard tXXX
names, useful if one is trying to program a DDR memory controller for
example. Or just to compare against any other SPD dump or memory spec
sheet.

Location:
i2c-tools/trunk
Files:
2 modified

Legend:

Unmodified
Added
Removed
  • i2c-tools/trunk/CHANGES

    r5151 r5152  
    44SVN 
    55  decode-dimms: Fix DDR2 SDRAM module speed decoding 
    6                 Update manufacturer IDs. 
     6                Update manufacturer IDs 
    77                Don't print anything by default if checksum fails 
     8                Decode all DDR2 SDRAM timing information 
    89  decode-vaio: Private data might not be readable by non-root users 
    910               Print the asset tag 
  • i2c-tools/trunk/eeprom/decode-dimms.pl

    r5150 r5152  
    407407} 
    408408 
     409sub tns($) # print a time in ns 
     410{ 
     411        return sprintf("%3.2f ns", $_[0]); 
     412} 
     413 
    409414# Parameter: bytes 0-63 
    410415sub decode_sdr_sdram($) 
     
    835840} 
    836841 
     842# Base, high-bit, 3-bit fraction code 
     843sub ddr2_sdram_rtime($$$) 
     844{ 
     845        my ($rtime, $msb, $ext) = @_; 
     846        my @table = (0, .25, .33, .50, .66, .75); 
     847 
     848        return $rtime + $msb * 256 + $table[$ext]; 
     849} 
     850 
     851sub ddr2_module_types($) 
     852{ 
     853        my $byte = shift; 
     854        my @types = qw(RDIMM UDIMM SO-DIMM Micro-DIMM Mini-RDIMM Mini-UDIMM); 
     855        my @widths = (133.35, 133.25, 67.6, 45.5, 82.0, 82.0); 
     856        my @suptypes; 
     857        local $_; 
     858 
     859        foreach (0..5) { 
     860                push @suptypes, "$types[$_] ($widths[$_] mm)" 
     861                        if ($byte & (1 << $_)); 
     862        } 
     863 
     864        return @suptypes; 
     865} 
     866 
     867sub ddr2_refresh_rate($) 
     868{ 
     869        my $byte = shift; 
     870        my @refresh = qw(Normal Reduced Reduced Extended Extended Extended); 
     871        my @refresht = (15.625, 3.9, 7.8, 31.3, 62.5, 125); 
     872 
     873        return "$refresh[$byte & 0x7f] ($refresht[$byte & 0x7f] us)". 
     874               ($byte & 0x80 ? " - Self Refresh" : ""); 
     875} 
     876 
    837877# Parameter: bytes 0-63 
    838878sub decode_ddr2_sdram($) 
     
    876916        } 
    877917 
     918        printl "Banks x Rows x Columns x Bits", 
     919               join(' x ', $bytes->[17], $bytes->[3], $bytes->[4], $bytes->[6]); 
     920        printl "Ranks", ($bytes->[5] & 7) + 1; 
     921 
     922        printl "SDRAM Device Width", $bytes->[13]." bits"; 
     923 
     924        my @heights = ('< 25.4', '25.4', '25.4 - 30.0', '30.0', '30.5', '> 30.5'); 
     925        printl "Module Height", $heights[$bytes->[5] >> 5]." mm"; 
     926 
     927        my @suptypes = ddr2_module_types($bytes->[20]); 
     928        printl "Module Type".(@suptypes > 1 ? 's' : ''), join(', ', @suptypes); 
     929 
     930        printl "DRAM Package", $bytes->[5] & 0x10 ? "Stack" : "Planar"; 
     931 
     932        my @volts = ("TTL (5V Tolerant)", "LVTTL", "HSTL 1.5V", 
     933                     "SSTL 3.3V", "SSTL 2.5V", "SSTL 1.8V", "TBD"); 
     934        printl "Voltage Interface Level", $volts[$bytes->[8]]; 
     935 
     936        printl "Refresh Rate", ddr2_refresh_rate($bytes->[12]); 
     937 
     938        my @burst; 
     939        push @burst, 4 if ($bytes->[16] & 4); 
     940        push @burst, 8 if ($bytes->[16] & 8); 
     941        $burst[0] = 'None' if !@burst; 
     942        printl "Supported Burst Lengths", join(', ', @burst); 
     943 
    878944        my $highestCAS = 0; 
    879945        my %cas; 
     
    900966 
    901967# latencies 
    902         if (keys %cas) { $temp = join ', ', sort { $b <=> $a } keys %cas; } 
     968        if (keys %cas) { $temp = join ', ', map("${_}T", sort { $b <=> $a } keys %cas); } 
    903969        else { $temp = "None"; } 
    904         printl "Supported CAS Latencies", $temp; 
     970        printl "Supported CAS Latencies (tCL)", $temp; 
    905971 
    906972# timings 
    907973        if (exists $cas{$highestCAS}) { 
    908                 printl "Minimum Cycle Time (CAS $highestCAS)", 
    909                        "$ctime ns"; 
    910                 printl "Maximum Access Time (CAS $highestCAS)", 
    911                        ddr2_sdram_atime($bytes->[10]) . " ns"; 
     974                printl "Minimum Cycle Time at CAS $highestCAS (tCK min)", 
     975                       tns($ctime); 
     976                printl "Maximum Access Time at CAS $highestCAS (tAC)", 
     977                       tns(ddr2_sdram_atime($bytes->[10])); 
    912978        } 
    913979 
    914980        if (exists $cas{$highestCAS-1} && spd_written(@$bytes[23..24])) { 
    915                 printl "Minimum Cycle Time (CAS ".($highestCAS-1).")", 
    916                        ddr2_sdram_ctime($bytes->[23]) . " ns"; 
    917                 printl "Maximum Access Time (CAS ".($highestCAS-1).")", 
    918                        ddr2_sdram_atime($bytes->[24]) . " ns"; 
     981                printl "Minimum Cycle Time at CAS ".($highestCAS-1), 
     982                       tns(ddr2_sdram_ctime($bytes->[23])); 
     983                printl "Maximum Access Time at CAS ".($highestCAS-1), 
     984                       tns(ddr2_sdram_atime($bytes->[24])); 
    919985        } 
    920986 
    921987        if (exists $cas{$highestCAS-2} && spd_written(@$bytes[25..26])) { 
    922                 printl "Minimum Cycle Time (CAS ".($highestCAS-2).")", 
    923                        ddr2_sdram_ctime($bytes->[25]) . " ns"; 
    924                 printl "Maximum Access Time (CAS ".($highestCAS-2).")", 
    925                        ddr2_sdram_atime($bytes->[26]) . " ns"; 
    926         } 
     988                printl "Minimum Cycle Time at CAS ".($highestCAS-2), 
     989                       tns(ddr2_sdram_ctime($bytes->[25])); 
     990                printl "Maximum Access Time at CAS ".($highestCAS-2), 
     991                       tns(ddr2_sdram_atime($bytes->[26])); 
     992        } 
     993        printl "Maximum Cycle Time (tCK max)", 
     994               tns(ddr2_sdram_ctime($bytes->[43])); 
     995 
     996# more timing information 
     997        prints("Timing Parameters"); 
     998        printl "Address/Command Setup Time Before Clock (tIS)", 
     999               tns(ddr2_sdram_atime($bytes->[32])); 
     1000        printl "Address/Command Hold Time After Clock (tIH)", 
     1001               tns(ddr2_sdram_atime($bytes->[33])); 
     1002        printl "Data Input Setup Time Before Strobe (tDS)", 
     1003               tns(ddr2_sdram_atime($bytes->[34])); 
     1004        printl "Data Input Hold Time After Strobe (tDH)", 
     1005               tns(ddr2_sdram_atime($bytes->[35])); 
     1006        printl "Minimum Row Precharge Delay (tRP)", tns($trp); 
     1007        printl "Minimum Row Active to Row Active Delay (tRRD)", 
     1008               tns($bytes->[28]/4); 
     1009        printl "Minimum RAS# to CAS# Delay (tRCD)", tns($trcd); 
     1010        printl "Minimum RAS# Pulse Width (tRAS)", tns($tras); 
     1011        printl "Write Recovery Time (tWR)", tns($bytes->[36]/4); 
     1012        printl "Minimum Write to Read CMD Delay (tWTR)", tns($bytes->[37]/4); 
     1013        printl "Minimum Read to Pre-charge CMD Delay (tRTP)", tns($bytes->[38]/4); 
     1014        printl "Minimum Active to Auto-refresh Delay (tRC)", 
     1015               tns(ddr2_sdram_rtime($bytes->[41], 0, ($bytes->[40] >> 4) & 7)); 
     1016        printl "Minimum Recovery Delay (tRFC)", 
     1017               tns(ddr2_sdram_rtime($bytes->[42], $bytes->[40] & 1, 
     1018                                    ($bytes->[40] >> 1) & 7)); 
     1019        printl "Maximum DQS to DQ Skew (tDQSQ)", tns($bytes->[44]/100); 
     1020        printl "Maximum Read Data Hold Skew (tQHS)", tns($bytes->[45]/100); 
     1021        printl "PLL Relock Time", $bytes->[46] . " us" if ($bytes->[46]); 
    9271022} 
    9281023