1 /* $NetBSD: spdmemvar.h,v 1.4 2014/03/18 18:20:41 riastradh Exp $ */ 2 3 /* 4 * Copyright (c) 2007 Paul Goyette 5 * Copyright (c) 2007 Tobias Nygren 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * This information is extracted from JEDEC standard SPD4_01 (www.jedec.org) 34 */ 35 36 #if BYTE_ORDER == BIG_ENDIAN 37 #define SPD_BITFIELD(a, b, c, d) d; c; b; a 38 #else 39 #define SPD_BITFIELD(a, b, c, d) a; b; c; d 40 #endif 41 42 struct spdmem_fpm { /* FPM and EDO DIMMS */ 43 uint8_t fpm_rows; 44 uint8_t fpm_cols; 45 uint8_t fpm_banks; 46 uint16_t fpm_datawidth; /* endian-sensitive */ 47 uint8_t fpm_voltage; 48 uint8_t fpm_tRAC; 49 uint8_t fpm_tCAC; 50 uint8_t fpm_config; 51 SPD_BITFIELD( \ 52 uint8_t fpm_refresh:7, \ 53 uint8_t fpm_selfrefresh:1, , \ 54 ); 55 uint8_t fpm_dram_dramwidth; 56 uint8_t fpm_dram_eccwidth; 57 uint8_t fpm_unused2[17]; 58 uint8_t fpm_superset; 59 uint8_t fpm_unused3[30]; 60 uint8_t fpm_cksum; 61 } __packed; 62 63 struct spdmem_sdram { /* PC66/PC100/PC133 SDRAM */ 64 SPD_BITFIELD( \ 65 uint8_t sdr_rows:4, \ 66 uint8_t sdr_rows2:4, , \ 67 ); 68 SPD_BITFIELD( \ 69 uint8_t sdr_cols:4, \ 70 uint8_t sdr_cols2:4, , \ 71 ); 72 uint8_t sdr_banks; 73 uint16_t sdr_datawidth; /* endian-sensitive */ 74 uint8_t sdr_voltage; 75 SPD_BITFIELD( \ 76 uint8_t sdr_cycle_tenths:4, \ 77 uint8_t sdr_cycle_whole:4, , \ 78 ); 79 SPD_BITFIELD( 80 uint8_t sdr_tAC_tenths:4, \ 81 uint8_t sdr_tAC_whole:4, , \ 82 ); 83 uint8_t sdr_config; 84 SPD_BITFIELD( \ 85 uint8_t sdr_refresh:7, \ 86 uint8_t sdr_selfrefresh:1, , \ 87 ); 88 SPD_BITFIELD( \ 89 uint8_t sdr_dramwidth:7, \ 90 uint8_t sdr_dram_asym_bank2:1, ,\ 91 ); 92 SPD_BITFIELD( \ 93 uint8_t sdr_eccwidth:7, \ 94 uint8_t sdr_ecc_asym_bank2:1, , \ 95 ); 96 uint8_t sdr_min_clk_delay; 97 SPD_BITFIELD( \ 98 uint8_t sdr_burstlengths:4, \ 99 uint8_t sdr_unused1:4, , \ 100 ); 101 uint8_t sdr_banks_per_chip; 102 uint8_t sdr_tCAS; 103 uint8_t sdr_tCS; 104 uint8_t sdr_tWE; 105 uint8_t sdr_mod_attrs; 106 uint8_t sdr_dev_attrs; 107 uint8_t sdr_min_cc_1; 108 uint8_t sdr_max_tAC_1; 109 uint8_t sdr_min_cc_2; 110 uint8_t sdr_max_tAC_2; 111 uint8_t sdr_tRP; 112 uint8_t sdr_tRRD; 113 uint8_t sdr_tRCD; 114 uint8_t sdr_tRAS; 115 uint8_t sdr_module_rank_density; 116 uint8_t sdr_tIS; 117 #define sdr_superset sdr_tIS 118 uint8_t sdr_tIH; 119 uint8_t sdr_tDS; 120 uint8_t sdr_tDH; 121 uint8_t sdr_unused2[5]; 122 uint8_t sdr_tRC; 123 uint8_t sdr_unused3[18]; 124 uint8_t sdr_esdram; 125 uint8_t sdr_super_tech; 126 uint8_t sdr_spdrev; 127 uint8_t sdr_cksum; 128 } __packed; 129 130 struct spdmem_rom { 131 uint8_t rom_rows; 132 uint8_t rom_cols; 133 uint8_t rom_banks; 134 uint16_t rom_datawidth; /* endian-sensitive */ 135 uint8_t rom_voltage; 136 uint16_t rom_tAA; /* endian-sensitive */ 137 uint8_t rom_config; 138 uint8_t rom_unused1; 139 uint8_t rom_tPA; 140 uint8_t rom_tOE; 141 uint16_t rom_tCE; /* endian-sensitive */ 142 uint8_t rom_burstlength; 143 uint8_t rom_unused2[14]; 144 uint8_t rom_superset[31]; 145 uint8_t rom_cksum; 146 } __packed; 147 148 149 struct spdmem_ddr { /* Dual Data Rate SDRAM */ 150 SPD_BITFIELD( \ 151 uint8_t ddr_rows:4, \ 152 uint8_t ddr_rows2:4, , \ 153 ); 154 SPD_BITFIELD( \ 155 uint8_t ddr_cols:4, \ 156 uint8_t ddr_cols2:4, , \ 157 ); 158 uint8_t ddr_ranks; 159 uint16_t ddr_datawidth; /* endian-sensitive */ 160 uint8_t ddr_voltage; 161 SPD_BITFIELD( \ 162 uint8_t ddr_cycle_tenths:4, \ 163 uint8_t ddr_cycle_whole:4, , \ 164 ); 165 SPD_BITFIELD( \ 166 uint8_t ddr_tAC_hundredths:4, \ 167 uint8_t ddr_tAC_tenths:4, , \ 168 ); 169 uint8_t ddr_config; 170 SPD_BITFIELD( \ 171 uint8_t ddr_refresh:7, \ 172 uint8_t ddr_selfrefresh:1, , \ 173 ); 174 SPD_BITFIELD( \ 175 uint8_t ddr_dramwidth:7, \ 176 uint8_t ddr_dram_asym_bank2:1, ,\ 177 ); 178 SPD_BITFIELD( \ 179 uint8_t ddr_eccwidth:7, \ 180 uint8_t ddr_ecc_asym_bank2:1, , \ 181 ); 182 uint8_t ddr_min_clk_delay; 183 SPD_BITFIELD( \ 184 uint8_t ddr_burstlengths:4, \ 185 uint8_t ddr_unused1:4, , \ 186 ); 187 uint8_t ddr_banks_per_chip; 188 uint8_t ddr_tCAS; 189 uint8_t ddr_tCS; 190 uint8_t ddr_tWE; 191 uint8_t ddr_mod_attrs; 192 uint8_t ddr_dev_attrs; 193 uint8_t ddr_min_cc_05; 194 uint8_t ddr_max_tAC_05; 195 uint8_t ddr_min_cc_1; 196 uint8_t ddr_max_tAC_1; 197 uint8_t ddr_tRP; 198 uint8_t ddr_tRRD; 199 uint8_t ddr_tRCD; 200 uint8_t ddr_tRAS; 201 uint8_t ddr_module_rank_density; 202 uint8_t ddr_tIS; 203 #define ddr_superset ddr_tIS 204 uint8_t ddr_tIH; 205 uint8_t ddr_tDS; 206 uint8_t ddr_tDH; 207 uint8_t ddr_unused2[5]; 208 uint8_t ddr_tRC; 209 uint8_t ddr_tRFC; 210 uint8_t ddr_tCK; 211 uint8_t ddr_tDQSQ; 212 uint8_t ddr_tQHS; 213 uint8_t ddr_unused3; 214 uint8_t ddr_height; 215 uint8_t ddr_unused4[15]; 216 uint8_t ddr_cksum; 217 } __packed; 218 219 struct spdmem_ddr2 { /* Dual Data Rate 2 SDRAM */ 220 SPD_BITFIELD( \ 221 uint8_t ddr2_rows:5, \ 222 uint8_t ddr2_unused1:3, , \ 223 ); 224 SPD_BITFIELD( \ 225 uint8_t ddr2_cols:4, \ 226 uint8_t ddr2_unused2:4, , \ 227 ); 228 SPD_BITFIELD( \ 229 uint8_t ddr2_ranks:3, 230 uint8_t ddr2_cardoncard:1, \ 231 uint8_t ddr2_package:1, \ 232 uint8_t ddr2_height:3 \ 233 ); 234 uint8_t ddr2_datawidth; 235 uint8_t ddr2_unused3; 236 uint8_t ddr2_voltage; 237 SPD_BITFIELD( \ 238 uint8_t ddr2_cycle_frac:4, \ 239 uint8_t ddr2_cycle_whole:4, , \ 240 ); 241 SPD_BITFIELD( \ 242 uint8_t ddr2_tAC_hundredths:4, \ 243 uint8_t ddr2_tAC_tenths:4, , \ 244 ); 245 uint8_t ddr2_config; 246 SPD_BITFIELD( \ 247 uint8_t ddr2_refresh:7, \ 248 uint8_t ddr2_selfrefresh:1, , \ 249 ); 250 uint8_t ddr2_dramwidth; 251 uint8_t ddr2_eccwidth; 252 uint8_t ddr2_unused4; 253 SPD_BITFIELD( \ 254 uint8_t ddr2_burstlengths:4, \ 255 uint8_t ddr2_unused5:4, , \ 256 ); 257 uint8_t ddr2_banks_per_chip; 258 uint8_t ddr2_tCAS; 259 uint8_t ddr2_mechanical; 260 uint8_t ddr2_dimm_type; 261 uint8_t ddr2_mod_attrs; 262 uint8_t ddr2_dev_attrs; 263 uint8_t ddr2_min_cc_1; 264 uint8_t ddr2_max_tAC_1; 265 uint8_t ddr2_min_cc_2; 266 uint8_t ddr2_max_tAC_2; 267 uint8_t ddr2_tRP; 268 uint8_t ddr2_tRRD; 269 uint8_t ddr2_tRCD; 270 uint8_t ddr2_tRAS; 271 uint8_t ddr2_module_rank_density; 272 uint8_t ddr2_tIS; 273 uint8_t ddr2_tIH; 274 uint8_t ddr2_tDS; 275 uint8_t ddr2_tDH; 276 uint8_t ddr2_tWR; 277 uint8_t ddr2_tWTR; 278 uint8_t ddr2_tRTP; 279 uint8_t ddr2_probe; 280 uint8_t ddr2_extensions; 281 uint8_t ddr2_tRC; 282 uint8_t ddr2_tRFC; 283 uint8_t ddr2_tCK; 284 uint8_t ddr2_tDQSQ; 285 uint8_t ddr2_tQHS; 286 uint8_t ddr2_pll_relock; 287 uint8_t ddr2_Tcasemax; 288 uint8_t ddr2_Psi_TA_DRAM; 289 uint8_t ddr2_dt0; 290 uint8_t ddr2_dt2NQ; 291 uint8_t ddr2_dr2P; 292 uint8_t ddr2_dt3N; 293 uint8_t ddr2_dt3Pfast; 294 uint8_t ddr2_dt3Pslow; 295 uint8_t ddr2_dt4R_4R4W_mode; 296 uint8_t ddr2_dt5B; 297 uint8_t ddr2_dt7; 298 uint8_t ddr2_Psi_TA_PLL; 299 uint8_t ddr2_Psi_TA_Reg; 300 uint8_t ddr2_dt_PLL_Active; 301 uint8_t ddr2_dt_Reg_Active; 302 uint8_t ddr2_spdrev; 303 uint8_t ddr2_cksum; 304 } __packed; 305 306 struct spdmem_fbdimm { /* Fully-buffered DIMM */ 307 SPD_BITFIELD( \ 308 uint8_t fbdimm_ps1_voltage:4, \ 309 uint8_t fbdimm_ps2_voltage:4, , \ 310 ); 311 SPD_BITFIELD( \ 312 uint8_t fbdimm_banks:2, \ 313 uint8_t fbdimm_cols:3, \ 314 uint8_t fbdimm_rows:3, \ 315 ); 316 SPD_BITFIELD( \ 317 uint8_t fbdimm_thick:3, \ 318 uint8_t fbdimm_height:3, \ 319 uint8_t fbdimm_unused1:2, \ 320 ); 321 uint8_t fbdimm_mod_type; 322 SPD_BITFIELD( \ 323 uint8_t fbdimm_dev_width:3, \ 324 uint8_t fbdimm_ranks:3, \ 325 uint8_t fbdimm_unused2:2, \ 326 ); 327 SPD_BITFIELD( \ 328 uint8_t fbdimm_ftb_divisor:4, \ 329 uint8_t fbdimm_ftp_dividend:4, ,\ 330 ); 331 uint8_t fbdimm_mtb_dividend; 332 uint8_t fbdimm_mtb_divisor; 333 uint8_t fbdimm_tCKmin; 334 uint8_t fbdimm_tCKmax; 335 uint8_t fbdimm_tCAS; 336 uint8_t fbdimm_tAAmin; 337 SPD_BITFIELD( \ 338 uint8_t fbdimm_tWR_min:4, \ 339 uint8_t fbdimm_WR_range:4, , \ 340 ); 341 uint8_t fbdimm_tWR; 342 SPD_BITFIELD( \ 343 uint8_t fbdimm_tWL_min:4, \ 344 uint8_t fbdimm_tWL_range:4, , \ 345 ); 346 SPD_BITFIELD( \ 347 uint8_t fbdimm_tAL_min:4, \ 348 uint8_t fbdimm_tAL_range:4, , \ 349 ); 350 uint8_t fbdimm_tRCDmin; 351 uint8_t fbdimm_tRRDmin; 352 uint8_t fbdimm_tRPmin; 353 SPD_BITFIELD( \ 354 uint8_t fbdimm_tRAS_msb:4, \ 355 uint8_t fbdimm_tRC_msb:4, , \ 356 ); 357 uint8_t fbdimm_tRAS_lsb; 358 uint8_t fbdimm_tRC_lsb; 359 uint16_t fbdimm_tRFC; /* endian-sensitive */ 360 uint8_t fbdimm_tWTR; 361 uint8_t fbdimm_tRTP; 362 SPD_BITFIELD( \ 363 uint8_t fbdimm_burst_4:1, \ 364 uint8_t fbdimm_burst_8:1, \ 365 uint8_t fbdimm_unused3:6, \ 366 ); 367 uint8_t fbdimm_terms; 368 uint8_t fbdimm_drivers; 369 uint8_t fbdimm_tREFI; 370 uint8_t fbdimm_Tcasemax; 371 uint8_t fbdimm_Psi_TA_SDRAM; 372 uint8_t fbdimm_DT0; 373 uint8_t fbdimm_DT2N_DT2Q; 374 uint8_t fbdimm_DT2P; 375 uint8_t fbdimm_DT3N; 376 uint8_t fbdimm_DT4R_DT4R4W; 377 uint8_t fbdimm_DT5B; 378 uint8_t fbdimm_DT7; 379 uint8_t fbdimm_unused4[84]; 380 uint16_t fbdimm_crc; 381 } __packed; 382 383 struct spdmem_rambus { /* Direct Rambus DRAM */ 384 SPD_BITFIELD( \ 385 uint8_t rdr_rows:4, \ 386 uint8_t rdr_cols:4, , \ 387 ); 388 } __packed; 389 390 struct spdmem_ddr3 { /* Dual Data Rate 3 SDRAM */ 391 uint8_t ddr3_mod_type; 392 SPD_BITFIELD( \ 393 /* chipsize is offset by 28: 0 = 256M, 1 = 512M, ... */ \ 394 uint8_t ddr3_chipsize:4, \ 395 /* logbanks is offset by 3 */ \ 396 uint8_t ddr3_logbanks:3, \ 397 uint8_t ddr3_unused1:1, \ 398 ); 399 /* cols is offset by 9, rows offset by 12 */ 400 SPD_BITFIELD( \ 401 uint8_t ddr3_cols:3, \ 402 uint8_t ddr3_rows:5, , \ 403 ); 404 SPD_BITFIELD( \ 405 uint8_t ddr3_NOT15V:1, \ 406 uint8_t ddr3_135V:1, \ 407 uint8_t ddr3_12XV:1, \ 408 uint8_t ddr3_unused2:5 \ 409 ); 410 /* chipwidth in bits offset by 2: 0 = X4, 1 = X8, 2 = X16 */ 411 /* physbanks is offset by 1 */ 412 SPD_BITFIELD( \ 413 uint8_t ddr3_chipwidth:3, \ 414 uint8_t ddr3_physbanks:5, , \ 415 ); 416 /* datawidth in bits offset by 3: 1 = 16b, 2 = 32b, 3 = 64b */ 417 SPD_BITFIELD( \ 418 uint8_t ddr3_datawidth:3, \ 419 uint8_t ddr3_hasECC:2, \ 420 uint8_t ddr3_unused2a:3 , \ 421 ); 422 /* Fine time base, in pico-seconds */ 423 SPD_BITFIELD( \ 424 uint8_t ddr3_ftb_divisor:4, \ 425 uint8_t ddr3_ftb_dividend:4, , \ 426 ); 427 uint8_t ddr3_mtb_dividend; /* 0x0108 = 0.1250ns */ 428 uint8_t ddr3_mtb_divisor; /* 0x010f = 0.0625ns */ 429 uint8_t ddr3_tCKmin; /* in terms of mtb */ 430 uint8_t ddr3_unused3; 431 uint16_t ddr3_CAS_sup; /* Bit 0 ==> CAS 4 cycles */ 432 uint8_t ddr3_tAAmin; /* in terms of mtb */ 433 uint8_t ddr3_tWRmin; 434 uint8_t ddr3_tRCDmin; 435 uint8_t ddr3_tRRDmin; 436 uint8_t ddr3_tRPmin; 437 SPD_BITFIELD( \ 438 uint8_t ddr3_tRAS_msb:4, \ 439 uint8_t ddr3_tRC_msb:4, , \ 440 ); 441 uint8_t ddr3_tRAS_lsb; 442 uint8_t ddr3_tRC_lsb; 443 uint8_t ddr3_tRFCmin_lsb; 444 uint8_t ddr3_tRFCmin_msb; 445 uint8_t ddr3_tWTRmin; 446 uint8_t ddr3_tRTPmin; 447 SPD_BITFIELD( \ 448 uint8_t ddr3_tFAW_msb:4, , , \ 449 ); 450 uint8_t ddr3_tFAW_lsb; 451 uint8_t ddr3_output_drvrs; 452 SPD_BITFIELD( \ 453 uint8_t ddr3_ext_temp_range:1, \ 454 uint8_t ddr3_ext_temp_2x_refresh:1, \ 455 uint8_t ddr3_asr_refresh:1, \ 456 /* Bit 4 indicates on-die thermal sensor */ 457 /* Bit 7 indicates Partial-Array Self-Refresh (PASR) */ 458 uint8_t ddr3_unused7:5 \ 459 ); 460 SPD_BITFIELD( \ 461 uint8_t ddr3_therm_sensor_acc:7,\ 462 uint8_t ddr3_has_therm_sensor:1, , \ 463 ); 464 SPD_BITFIELD( \ 465 uint8_t ddr3_non_std_devtype:7, \ 466 uint8_t ddr3_std_device:1, , \ 467 ); 468 uint8_t ddr3_unused4[26]; 469 uint8_t ddr3_mod_height; 470 uint8_t ddr3_mod_thickness; 471 uint8_t ddr3_ref_card; 472 uint8_t ddr3_mapping; 473 uint8_t ddr3_unused5[53]; 474 uint8_t ddr3_mfgID_lsb; 475 uint8_t ddr3_mfgID_msb; 476 uint8_t ddr3_mfgloc; 477 uint8_t ddr3_mfg_year; 478 uint8_t ddr3_mfg_week; 479 uint8_t ddr3_serial[4]; 480 uint16_t ddr3_crc; 481 uint8_t ddr3_part[18]; 482 uint8_t ddr3_rev[2]; 483 uint8_t ddr3_dram_mfgID_lsb; 484 uint8_t ddr3_dram_mfgID_msb; 485 uint8_t ddr3_vendor[26]; 486 } __packed; 487 488 struct spdmem { 489 uint8_t sm_len; 490 uint8_t sm_size; 491 uint8_t sm_type; 492 union { 493 struct spdmem_fbdimm u1_fbd; 494 struct spdmem_fpm u1_fpm; 495 struct spdmem_ddr u1_ddr; 496 struct spdmem_ddr2 u1_ddr2; 497 struct spdmem_sdram u1_sdr; 498 struct spdmem_rambus u1_rdr; 499 struct spdmem_rom u1_rom; 500 struct spdmem_ddr3 u1_ddr3; 501 } sm_u1; 502 } __packed; 503 #define sm_fbd sm_u1.u1_fbd 504 #define sm_fpm sm_u1.u1_fpm 505 #define sm_ddr sm_u1.u1_ddr 506 #define sm_ddr2 sm_u1.u1_ddr2 507 #define sm_rdr sm_u1.u1_rdr 508 #define sm_rom sm_u1.u1_rom 509 #define sm_ddr3 sm_u1.u1_ddr3 510 #define sm_sdr sm_u1.u1_sdr 511 512 /* some fields are in the same place for all memory types */ 513 514 #define sm_cksum sm_fpm.fpm_cksum 515 #define sm_config sm_fpm.fpm_config 516 #define sm_voltage sm_fpm.fpm_voltage 517 #define sm_refresh sm_fpm.fpm_refresh 518 #define sm_selfrefresh sm_fpm.fpm_selfrefresh 519 520 #define SPDMEM_TYPE_MAXLEN 16 521 522 struct spdmem_softc { 523 uint8_t (*sc_read)(struct spdmem_softc *, uint8_t); 524 struct spdmem sc_spd_data; 525 struct sysctllog *sc_sysctl_log; 526 char sc_type[SPDMEM_TYPE_MAXLEN]; 527 }; 528 529 int spdmem_common_probe(struct spdmem_softc *); 530 void spdmem_common_attach(struct spdmem_softc *, device_t); 531 int spdmem_common_detach(struct spdmem_softc *, device_t); 532