Home | History | Annotate | Line # | Download | only in ic
spdmem.c revision 1.1.4.2
      1  1.1.4.2  rmind /* $NetBSD: spdmem.c,v 1.1.4.2 2010/05/30 05:17:26 rmind Exp $ */
      2  1.1.4.2  rmind 
      3  1.1.4.2  rmind /*
      4  1.1.4.2  rmind  * Copyright (c) 2007 Nicolas Joly
      5  1.1.4.2  rmind  * Copyright (c) 2007 Paul Goyette
      6  1.1.4.2  rmind  * Copyright (c) 2007 Tobias Nygren
      7  1.1.4.2  rmind  * All rights reserved.
      8  1.1.4.2  rmind  *
      9  1.1.4.2  rmind  * Redistribution and use in source and binary forms, with or without
     10  1.1.4.2  rmind  * modification, are permitted provided that the following conditions
     11  1.1.4.2  rmind  * are met:
     12  1.1.4.2  rmind  * 1. Redistributions of source code must retain the above copyright
     13  1.1.4.2  rmind  *    notice, this list of conditions and the following disclaimer.
     14  1.1.4.2  rmind  * 2. Redistributions in binary form must reproduce the above copyright
     15  1.1.4.2  rmind  *    notice, this list of conditions and the following disclaimer in the
     16  1.1.4.2  rmind  *    documentation and/or other materials provided with the distribution.
     17  1.1.4.2  rmind  * 3. The name of the author may not be used to endorse or promote products
     18  1.1.4.2  rmind  *    derived from this software without specific prior written permission.
     19  1.1.4.2  rmind  *
     20  1.1.4.2  rmind  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS
     21  1.1.4.2  rmind  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     22  1.1.4.2  rmind  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     23  1.1.4.2  rmind  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     24  1.1.4.2  rmind  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     25  1.1.4.2  rmind  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     26  1.1.4.2  rmind  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     27  1.1.4.2  rmind  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     28  1.1.4.2  rmind  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     29  1.1.4.2  rmind  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     30  1.1.4.2  rmind  * POSSIBILITY OF SUCH DAMAGE.
     31  1.1.4.2  rmind  */
     32  1.1.4.2  rmind 
     33  1.1.4.2  rmind /*
     34  1.1.4.2  rmind  * Serial Presence Detect (SPD) memory identification
     35  1.1.4.2  rmind  */
     36  1.1.4.2  rmind 
     37  1.1.4.2  rmind #include <sys/cdefs.h>
     38  1.1.4.2  rmind __KERNEL_RCSID(0, "$NetBSD: spdmem.c,v 1.1.4.2 2010/05/30 05:17:26 rmind Exp $");
     39  1.1.4.2  rmind 
     40  1.1.4.2  rmind #include <sys/param.h>
     41  1.1.4.2  rmind #include <sys/device.h>
     42  1.1.4.2  rmind #include <sys/endian.h>
     43  1.1.4.2  rmind #include <sys/sysctl.h>
     44  1.1.4.2  rmind #include <machine/bswap.h>
     45  1.1.4.2  rmind 
     46  1.1.4.2  rmind #include <dev/i2c/i2cvar.h>
     47  1.1.4.2  rmind #include <dev/ic/spdmemreg.h>
     48  1.1.4.2  rmind #include <dev/ic/spdmemvar.h>
     49  1.1.4.2  rmind 
     50  1.1.4.2  rmind SYSCTL_SETUP_PROTO(sysctl_spdmem_setup);
     51  1.1.4.2  rmind 
     52  1.1.4.2  rmind /* Routines for decoding spd data */
     53  1.1.4.2  rmind static void decode_edofpm(const struct sysctlnode *, device_t, struct spdmem *);
     54  1.1.4.2  rmind static void decode_rom(const struct sysctlnode *, device_t, struct spdmem *);
     55  1.1.4.2  rmind static void decode_sdram(const struct sysctlnode *, device_t, struct spdmem *,
     56  1.1.4.2  rmind 	int);
     57  1.1.4.2  rmind static void decode_ddr(const struct sysctlnode *, device_t, struct spdmem *);
     58  1.1.4.2  rmind static void decode_ddr2(const struct sysctlnode *, device_t, struct spdmem *);
     59  1.1.4.2  rmind static void decode_ddr3(const struct sysctlnode *, device_t, struct spdmem *);
     60  1.1.4.2  rmind static void decode_fbdimm(const struct sysctlnode *, device_t, struct spdmem *);
     61  1.1.4.2  rmind 
     62  1.1.4.2  rmind static void decode_size_speed(const struct sysctlnode *, int, int, int, int,
     63  1.1.4.2  rmind 			      bool, const char *, int);
     64  1.1.4.2  rmind static void decode_voltage_refresh(device_t, struct spdmem *);
     65  1.1.4.2  rmind 
     66  1.1.4.2  rmind #define IS_RAMBUS_TYPE (s->sm_len < 4)
     67  1.1.4.2  rmind 
     68  1.1.4.2  rmind static const char* spdmem_basic_types[] = {
     69  1.1.4.2  rmind 	"unknown",
     70  1.1.4.2  rmind 	"FPM",
     71  1.1.4.2  rmind 	"EDO",
     72  1.1.4.2  rmind 	"Pipelined Nibble",
     73  1.1.4.2  rmind 	"SDRAM",
     74  1.1.4.2  rmind 	"ROM",
     75  1.1.4.2  rmind 	"DDR SGRAM",
     76  1.1.4.2  rmind 	"DDR SDRAM",
     77  1.1.4.2  rmind 	"DDR2 SDRAM",
     78  1.1.4.2  rmind 	"DDR2 SDRAM FB",
     79  1.1.4.2  rmind 	"DDR2 SDRAM FB Probe",
     80  1.1.4.2  rmind 	"DDR3 SDRAM"
     81  1.1.4.2  rmind };
     82  1.1.4.2  rmind 
     83  1.1.4.2  rmind static const char* spdmem_superset_types[] = {
     84  1.1.4.2  rmind 	"unknown",
     85  1.1.4.2  rmind 	"ESDRAM",
     86  1.1.4.2  rmind 	"DDR ESDRAM",
     87  1.1.4.2  rmind 	"PEM EDO",
     88  1.1.4.2  rmind 	"PEM SDRAM"
     89  1.1.4.2  rmind };
     90  1.1.4.2  rmind 
     91  1.1.4.2  rmind static const char* spdmem_voltage_types[] = {
     92  1.1.4.2  rmind 	"TTL (5V tolerant)",
     93  1.1.4.2  rmind 	"LvTTL (not 5V tolerant)",
     94  1.1.4.2  rmind 	"HSTL 1.5V",
     95  1.1.4.2  rmind 	"SSTL 3.3V",
     96  1.1.4.2  rmind 	"SSTL 2.5V",
     97  1.1.4.2  rmind 	"SSTL 1.8V"
     98  1.1.4.2  rmind };
     99  1.1.4.2  rmind 
    100  1.1.4.2  rmind static const char* spdmem_refresh_types[] = {
    101  1.1.4.2  rmind 	"15.625us",
    102  1.1.4.2  rmind 	"3.9us",
    103  1.1.4.2  rmind 	"7.8us",
    104  1.1.4.2  rmind 	"31.3us",
    105  1.1.4.2  rmind 	"62.5us",
    106  1.1.4.2  rmind 	"125us"
    107  1.1.4.2  rmind };
    108  1.1.4.2  rmind 
    109  1.1.4.2  rmind static const char* spdmem_parity_types[] = {
    110  1.1.4.2  rmind 	"no parity or ECC",
    111  1.1.4.2  rmind 	"data parity",
    112  1.1.4.2  rmind 	"data ECC",
    113  1.1.4.2  rmind 	"data parity and ECC",
    114  1.1.4.2  rmind 	"cmd/addr parity",
    115  1.1.4.2  rmind 	"cmd/addr/data parity",
    116  1.1.4.2  rmind 	"cmd/addr parity, data ECC",
    117  1.1.4.2  rmind 	"cmd/addr/data parity, data ECC"
    118  1.1.4.2  rmind };
    119  1.1.4.2  rmind 
    120  1.1.4.2  rmind /* Cycle time fractional values (units of .001 ns) for DDR2 SDRAM */
    121  1.1.4.2  rmind static const uint16_t spdmem_cycle_frac[] = {
    122  1.1.4.2  rmind 	0, 100, 200, 300, 400, 500, 600, 700, 800, 900,
    123  1.1.4.2  rmind 	250, 333, 667, 750, 999, 999
    124  1.1.4.2  rmind };
    125  1.1.4.2  rmind 
    126  1.1.4.2  rmind /* Format string for timing info */
    127  1.1.4.2  rmind static const char* latency="tAA-tRCD-tRP-tRAS: %d-%d-%d-%d\n";
    128  1.1.4.2  rmind 
    129  1.1.4.2  rmind /* sysctl stuff */
    130  1.1.4.2  rmind static int hw_node = CTL_EOL;
    131  1.1.4.2  rmind 
    132  1.1.4.2  rmind /* CRC functions used for certain memory types */
    133  1.1.4.2  rmind 
    134  1.1.4.2  rmind static uint16_t spdcrc16 (struct spdmem_softc *sc, int count)
    135  1.1.4.2  rmind {
    136  1.1.4.2  rmind 	uint16_t crc;
    137  1.1.4.2  rmind 	int i, j;
    138  1.1.4.2  rmind 	uint8_t val;
    139  1.1.4.2  rmind 	crc = 0;
    140  1.1.4.2  rmind 	for (j = 0; j <= count; j++) {
    141  1.1.4.2  rmind 		val = (sc->sc_read)(sc, j);
    142  1.1.4.2  rmind 		crc = crc ^ val << 8;
    143  1.1.4.2  rmind 		for (i = 0; i < 8; ++i)
    144  1.1.4.2  rmind 			if (crc & 0x8000)
    145  1.1.4.2  rmind 				crc = crc << 1 ^ 0x1021;
    146  1.1.4.2  rmind 			else
    147  1.1.4.2  rmind 				crc = crc << 1;
    148  1.1.4.2  rmind 	}
    149  1.1.4.2  rmind 	return (crc & 0xFFFF);
    150  1.1.4.2  rmind }
    151  1.1.4.2  rmind 
    152  1.1.4.2  rmind int
    153  1.1.4.2  rmind spdmem_common_probe(struct spdmem_softc *sc)
    154  1.1.4.2  rmind {
    155  1.1.4.2  rmind 	int cksum = 0;
    156  1.1.4.2  rmind 	uint8_t i, val, spd_type;
    157  1.1.4.2  rmind 	int spd_len, spd_crc_cover;
    158  1.1.4.2  rmind 	uint16_t crc_calc, crc_spd;
    159  1.1.4.2  rmind 
    160  1.1.4.2  rmind 	spd_type = (sc->sc_read)(sc, 2);
    161  1.1.4.2  rmind 
    162  1.1.4.2  rmind 	/* For older memory types, validate the checksum over 1st 63 bytes */
    163  1.1.4.2  rmind 	if (spd_type <= SPDMEM_MEMTYPE_DDR2SDRAM) {
    164  1.1.4.2  rmind 		for (i = 0; i < 63; i++)
    165  1.1.4.2  rmind 			cksum += (sc->sc_read)(sc, i);
    166  1.1.4.2  rmind 
    167  1.1.4.2  rmind 		val = (sc->sc_read)(sc, 63);
    168  1.1.4.2  rmind 
    169  1.1.4.2  rmind 		if (cksum == 0 || (cksum & 0xff) != val) {
    170  1.1.4.2  rmind 			aprint_debug("spd checksum failed, calc = 0x%02x, "
    171  1.1.4.2  rmind 				     "spd = 0x%02x\n", cksum, val);
    172  1.1.4.2  rmind 			return 0;
    173  1.1.4.2  rmind 		} else
    174  1.1.4.2  rmind 			return 1;
    175  1.1.4.2  rmind 	}
    176  1.1.4.2  rmind 
    177  1.1.4.2  rmind 	/* For DDR3 and FBDIMM, verify the CRC */
    178  1.1.4.2  rmind 	else if (spd_type <= SPDMEM_MEMTYPE_DDR3SDRAM) {
    179  1.1.4.2  rmind 		spd_len = (sc->sc_read)(sc, 0);
    180  1.1.4.2  rmind 		if (spd_len && SPDMEM_SPDCRC_116)
    181  1.1.4.2  rmind 			spd_crc_cover = 116;
    182  1.1.4.2  rmind 		else
    183  1.1.4.2  rmind 			spd_crc_cover = 125;
    184  1.1.4.2  rmind 		switch (spd_len & SPDMEM_SPDLEN_MASK) {
    185  1.1.4.2  rmind 		case SPDMEM_SPDLEN_128:
    186  1.1.4.2  rmind 			spd_len = 128;
    187  1.1.4.2  rmind 			break;
    188  1.1.4.2  rmind 		case SPDMEM_SPDLEN_176:
    189  1.1.4.2  rmind 			spd_len = 176;
    190  1.1.4.2  rmind 			break;
    191  1.1.4.2  rmind 		case SPDMEM_SPDLEN_256:
    192  1.1.4.2  rmind 			spd_len = 256;
    193  1.1.4.2  rmind 			break;
    194  1.1.4.2  rmind 		default:
    195  1.1.4.2  rmind 			return 0;
    196  1.1.4.2  rmind 		}
    197  1.1.4.2  rmind 		if (spd_crc_cover > spd_len)
    198  1.1.4.2  rmind 			return 0;
    199  1.1.4.2  rmind 		crc_calc = spdcrc16(sc, spd_crc_cover);
    200  1.1.4.2  rmind 		crc_spd = (sc->sc_read)(sc, 127) << 8;
    201  1.1.4.2  rmind 		crc_spd |= (sc->sc_read)(sc, 126);
    202  1.1.4.2  rmind 		if (crc_calc != crc_spd) {
    203  1.1.4.2  rmind 			aprint_debug("crc16 failed, covers %d bytes, "
    204  1.1.4.2  rmind 				     "calc = 0x%04x, spd = 0x%04x\n",
    205  1.1.4.2  rmind 				     spd_crc_cover, crc_calc, crc_spd);
    206  1.1.4.2  rmind 			return 0;
    207  1.1.4.2  rmind 		}
    208  1.1.4.2  rmind 		return 1;
    209  1.1.4.2  rmind 	}
    210  1.1.4.2  rmind 
    211  1.1.4.2  rmind 	/* For unrecognized memory types, don't match at all */
    212  1.1.4.2  rmind 	return 0;
    213  1.1.4.2  rmind }
    214  1.1.4.2  rmind 
    215  1.1.4.2  rmind void
    216  1.1.4.2  rmind spdmem_common_attach(struct spdmem_softc *sc, device_t self)
    217  1.1.4.2  rmind {
    218  1.1.4.2  rmind 	struct spdmem *s = &(sc->sc_spd_data);
    219  1.1.4.2  rmind 	const char *type;
    220  1.1.4.2  rmind 	const char *rambus_rev = "Reserved";
    221  1.1.4.2  rmind 	int dimm_size;
    222  1.1.4.2  rmind 	int i;
    223  1.1.4.2  rmind 	unsigned int spd_len, spd_size;
    224  1.1.4.2  rmind 	const struct sysctlnode *node = NULL;
    225  1.1.4.2  rmind 
    226  1.1.4.2  rmind 	/*
    227  1.1.4.2  rmind 	 * FBDIMM and DDR3 (and probably all newer) have a different
    228  1.1.4.2  rmind 	 * encoding of the SPD EEPROM used/total sizes
    229  1.1.4.2  rmind 	 */
    230  1.1.4.2  rmind 	s->sm_len = (sc->sc_read)(sc, 0);
    231  1.1.4.2  rmind 	s->sm_size = (sc->sc_read)(sc, 1);
    232  1.1.4.2  rmind 	s->sm_type = (sc->sc_read)(sc, 2);
    233  1.1.4.2  rmind 
    234  1.1.4.2  rmind 	if (s->sm_type >= SPDMEM_MEMTYPE_FBDIMM) {
    235  1.1.4.2  rmind 		spd_size = 64 << (s->sm_len & SPDMEM_SPDSIZE_MASK);
    236  1.1.4.2  rmind 		switch (s->sm_len & SPDMEM_SPDLEN_MASK) {
    237  1.1.4.2  rmind 		case SPDMEM_SPDLEN_128:
    238  1.1.4.2  rmind 			spd_len = 128;
    239  1.1.4.2  rmind 			break;
    240  1.1.4.2  rmind 		case SPDMEM_SPDLEN_176:
    241  1.1.4.2  rmind 			spd_len = 176;
    242  1.1.4.2  rmind 			break;
    243  1.1.4.2  rmind 		case SPDMEM_SPDLEN_256:
    244  1.1.4.2  rmind 			spd_len = 256;
    245  1.1.4.2  rmind 			break;
    246  1.1.4.2  rmind 		default:
    247  1.1.4.2  rmind 			spd_len = 64;
    248  1.1.4.2  rmind 			break;
    249  1.1.4.2  rmind 		}
    250  1.1.4.2  rmind 	} else {
    251  1.1.4.2  rmind 		spd_size = 1 << s->sm_size;
    252  1.1.4.2  rmind 		spd_len = s->sm_len;
    253  1.1.4.2  rmind 		if (spd_len < 64)
    254  1.1.4.2  rmind 			spd_len = 64;
    255  1.1.4.2  rmind 	}
    256  1.1.4.2  rmind 	if (spd_len > spd_size)
    257  1.1.4.2  rmind 		spd_len = spd_size;
    258  1.1.4.2  rmind 	if (spd_len > sizeof(struct spdmem))
    259  1.1.4.2  rmind 		spd_len = sizeof(struct spdmem);
    260  1.1.4.2  rmind 	for (i = 3; i < spd_len; i++)
    261  1.1.4.2  rmind 		((uint8_t *)s)[i] = (sc->sc_read)(sc, i);
    262  1.1.4.2  rmind 
    263  1.1.4.2  rmind #ifdef DEBUG
    264  1.1.4.2  rmind 	for (i = 0; i < spd_len;  i += 16) {
    265  1.1.4.2  rmind 		int j, k;
    266  1.1.4.2  rmind 		aprint_debug("\n");
    267  1.1.4.2  rmind 		aprint_debug_dev(self, "0x%02x:", i);
    268  1.1.4.2  rmind 		k = (spd_len > i + 16) ? spd_len : i + 16;
    269  1.1.4.2  rmind 		for (j = i; j < k; j++)
    270  1.1.4.2  rmind 			aprint_debug(" %02x", ((uint8_t *)s)[j]);
    271  1.1.4.2  rmind 	}
    272  1.1.4.2  rmind 	aprint_debug("\n");
    273  1.1.4.2  rmind 	aprint_debug_dev(self, "");
    274  1.1.4.2  rmind #endif
    275  1.1.4.2  rmind 
    276  1.1.4.2  rmind 	/*
    277  1.1.4.2  rmind 	 * Setup our sysctl subtree, hw.spdmemN
    278  1.1.4.2  rmind 	 */
    279  1.1.4.2  rmind 	if (hw_node != CTL_EOL)
    280  1.1.4.2  rmind 		sysctl_createv(NULL, 0, NULL, &node,
    281  1.1.4.2  rmind 		    0, CTLTYPE_NODE,
    282  1.1.4.2  rmind 		    device_xname(self), NULL, NULL, 0, NULL, 0,
    283  1.1.4.2  rmind 		    CTL_HW, CTL_CREATE, CTL_EOL);
    284  1.1.4.2  rmind 	if (node != NULL && spd_len != 0)
    285  1.1.4.2  rmind                 sysctl_createv(NULL, 0, NULL, NULL,
    286  1.1.4.2  rmind                     0,
    287  1.1.4.2  rmind                     CTLTYPE_STRUCT, "spd_data",
    288  1.1.4.2  rmind 		    SYSCTL_DESCR("raw spd data"), NULL,
    289  1.1.4.2  rmind                     0, s, spd_len,
    290  1.1.4.2  rmind                     CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
    291  1.1.4.2  rmind 
    292  1.1.4.2  rmind 	/*
    293  1.1.4.2  rmind 	 * Decode and print key SPD contents
    294  1.1.4.2  rmind 	 */
    295  1.1.4.2  rmind 	if (IS_RAMBUS_TYPE) {
    296  1.1.4.2  rmind 		if (s->sm_type == SPDMEM_MEMTYPE_RAMBUS)
    297  1.1.4.2  rmind 			type = "Rambus";
    298  1.1.4.2  rmind 		else if (s->sm_type == SPDMEM_MEMTYPE_DIRECTRAMBUS)
    299  1.1.4.2  rmind 			type = "Direct Rambus";
    300  1.1.4.2  rmind 		else
    301  1.1.4.2  rmind 			type = "Rambus (unknown)";
    302  1.1.4.2  rmind 
    303  1.1.4.2  rmind 		switch (s->sm_len) {
    304  1.1.4.2  rmind 		case 0:
    305  1.1.4.2  rmind 			rambus_rev = "Invalid";
    306  1.1.4.2  rmind 			break;
    307  1.1.4.2  rmind 		case 1:
    308  1.1.4.2  rmind 			rambus_rev = "0.7";
    309  1.1.4.2  rmind 			break;
    310  1.1.4.2  rmind 		case 2:
    311  1.1.4.2  rmind 			rambus_rev = "1.0";
    312  1.1.4.2  rmind 			break;
    313  1.1.4.2  rmind 		default:
    314  1.1.4.2  rmind 			rambus_rev = "Reserved";
    315  1.1.4.2  rmind 			break;
    316  1.1.4.2  rmind 		}
    317  1.1.4.2  rmind 	} else {
    318  1.1.4.2  rmind 		if (s->sm_type < __arraycount(spdmem_basic_types))
    319  1.1.4.2  rmind 			type = spdmem_basic_types[s->sm_type];
    320  1.1.4.2  rmind 		else
    321  1.1.4.2  rmind 			type = "unknown memory type";
    322  1.1.4.2  rmind 
    323  1.1.4.2  rmind 		if (s->sm_type == SPDMEM_MEMTYPE_EDO &&
    324  1.1.4.2  rmind 		    s->sm_fpm.fpm_superset == SPDMEM_SUPERSET_EDO_PEM)
    325  1.1.4.2  rmind 			type = spdmem_superset_types[SPDMEM_SUPERSET_EDO_PEM];
    326  1.1.4.2  rmind 		if (s->sm_type == SPDMEM_MEMTYPE_SDRAM &&
    327  1.1.4.2  rmind 		    s->sm_sdr.sdr_superset == SPDMEM_SUPERSET_SDRAM_PEM)
    328  1.1.4.2  rmind 			type = spdmem_superset_types[SPDMEM_SUPERSET_SDRAM_PEM];
    329  1.1.4.2  rmind 		if (s->sm_type == SPDMEM_MEMTYPE_DDRSDRAM &&
    330  1.1.4.2  rmind 		    s->sm_ddr.ddr_superset == SPDMEM_SUPERSET_DDR_ESDRAM)
    331  1.1.4.2  rmind 			type =
    332  1.1.4.2  rmind 			    spdmem_superset_types[SPDMEM_SUPERSET_DDR_ESDRAM];
    333  1.1.4.2  rmind 		if (s->sm_type == SPDMEM_MEMTYPE_SDRAM &&
    334  1.1.4.2  rmind 		    s->sm_sdr.sdr_superset == SPDMEM_SUPERSET_ESDRAM) {
    335  1.1.4.2  rmind 			type = spdmem_superset_types[SPDMEM_SUPERSET_ESDRAM];
    336  1.1.4.2  rmind 		}
    337  1.1.4.2  rmind 	}
    338  1.1.4.2  rmind 
    339  1.1.4.2  rmind 	aprint_naive("\n");
    340  1.1.4.2  rmind 	aprint_normal("\n");
    341  1.1.4.2  rmind 	aprint_normal_dev(self, "%s", type);
    342  1.1.4.2  rmind 	strlcpy(sc->sc_type, type, SPDMEM_TYPE_MAXLEN);
    343  1.1.4.2  rmind 	if (node != NULL)
    344  1.1.4.2  rmind 		sysctl_createv(NULL, 0, NULL, NULL,
    345  1.1.4.2  rmind 		    0,
    346  1.1.4.2  rmind 		    CTLTYPE_STRING, "mem_type",
    347  1.1.4.2  rmind 		    SYSCTL_DESCR("memory module type"), NULL,
    348  1.1.4.2  rmind 		    0, sc->sc_type, 0,
    349  1.1.4.2  rmind 		    CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
    350  1.1.4.2  rmind 
    351  1.1.4.2  rmind 	if (IS_RAMBUS_TYPE) {
    352  1.1.4.2  rmind 		aprint_normal(", SPD Revision %s", rambus_rev);
    353  1.1.4.2  rmind 		dimm_size = 1 << (s->sm_rdr.rdr_rows + s->sm_rdr.rdr_cols - 13);
    354  1.1.4.2  rmind 		if (dimm_size >= 1024)
    355  1.1.4.2  rmind 			aprint_normal(", %dGB\n", dimm_size / 1024);
    356  1.1.4.2  rmind 		else
    357  1.1.4.2  rmind 			aprint_normal(", %dMB\n", dimm_size);
    358  1.1.4.2  rmind 
    359  1.1.4.2  rmind 		/* No further decode for RAMBUS memory */
    360  1.1.4.2  rmind 		return;
    361  1.1.4.2  rmind 	}
    362  1.1.4.2  rmind 	switch (s->sm_type) {
    363  1.1.4.2  rmind 	case SPDMEM_MEMTYPE_EDO:
    364  1.1.4.2  rmind 	case SPDMEM_MEMTYPE_FPM:
    365  1.1.4.2  rmind 		decode_edofpm(node, self, s);
    366  1.1.4.2  rmind 		break;
    367  1.1.4.2  rmind 	case SPDMEM_MEMTYPE_ROM:
    368  1.1.4.2  rmind 		decode_rom(node, self, s);
    369  1.1.4.2  rmind 		break;
    370  1.1.4.2  rmind 	case SPDMEM_MEMTYPE_SDRAM:
    371  1.1.4.2  rmind 		decode_sdram(node, self, s, spd_len);
    372  1.1.4.2  rmind 		break;
    373  1.1.4.2  rmind 	case SPDMEM_MEMTYPE_DDRSDRAM:
    374  1.1.4.2  rmind 		decode_ddr(node, self, s);
    375  1.1.4.2  rmind 		break;
    376  1.1.4.2  rmind 	case SPDMEM_MEMTYPE_DDR2SDRAM:
    377  1.1.4.2  rmind 		decode_ddr2(node, self, s);
    378  1.1.4.2  rmind 		break;
    379  1.1.4.2  rmind 	case SPDMEM_MEMTYPE_DDR3SDRAM:
    380  1.1.4.2  rmind 		decode_ddr3(node, self, s);
    381  1.1.4.2  rmind 		break;
    382  1.1.4.2  rmind 	case SPDMEM_MEMTYPE_FBDIMM:
    383  1.1.4.2  rmind 	case SPDMEM_MEMTYPE_FBDIMM_PROBE:
    384  1.1.4.2  rmind 		decode_fbdimm(node, self, s);
    385  1.1.4.2  rmind 		break;
    386  1.1.4.2  rmind 	}
    387  1.1.4.2  rmind }
    388  1.1.4.2  rmind 
    389  1.1.4.2  rmind SYSCTL_SETUP(sysctl_spdmem_setup, "sysctl hw.spdmem subtree setup")
    390  1.1.4.2  rmind {
    391  1.1.4.2  rmind 	const struct sysctlnode *node;
    392  1.1.4.2  rmind 
    393  1.1.4.2  rmind 	if (sysctl_createv(clog, 0, NULL, &node,
    394  1.1.4.2  rmind 	    CTLFLAG_PERMANENT,
    395  1.1.4.2  rmind 	    CTLTYPE_NODE, "hw", NULL,
    396  1.1.4.2  rmind 	    NULL, 0, NULL, 0,
    397  1.1.4.2  rmind 	    CTL_HW, CTL_EOL) != 0)
    398  1.1.4.2  rmind 		return;
    399  1.1.4.2  rmind 
    400  1.1.4.2  rmind 	hw_node = node->sysctl_num;
    401  1.1.4.2  rmind }
    402  1.1.4.2  rmind 
    403  1.1.4.2  rmind static void
    404  1.1.4.2  rmind decode_size_speed(const struct sysctlnode *node, int dimm_size, int cycle_time,
    405  1.1.4.2  rmind 		  int d_clk, int bits, bool round, const char *ddr_type_string,
    406  1.1.4.2  rmind 		  int speed)
    407  1.1.4.2  rmind {
    408  1.1.4.2  rmind 	int p_clk;
    409  1.1.4.2  rmind 
    410  1.1.4.2  rmind 	if (dimm_size < 1024)
    411  1.1.4.2  rmind 		aprint_normal("%dMB", dimm_size);
    412  1.1.4.2  rmind 	else
    413  1.1.4.2  rmind 		aprint_normal("%dGB", dimm_size / 1024);
    414  1.1.4.2  rmind 	if (node != NULL)
    415  1.1.4.2  rmind 		sysctl_createv(NULL, 0, NULL, NULL,
    416  1.1.4.2  rmind 		    CTLFLAG_IMMEDIATE,
    417  1.1.4.2  rmind 		    CTLTYPE_INT, "size",
    418  1.1.4.2  rmind 		    SYSCTL_DESCR("module size in MB"), NULL,
    419  1.1.4.2  rmind 		    dimm_size, NULL, 0,
    420  1.1.4.2  rmind 		    CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
    421  1.1.4.2  rmind 
    422  1.1.4.2  rmind 	if (cycle_time == 0) {
    423  1.1.4.2  rmind 		aprint_normal("\n");
    424  1.1.4.2  rmind 		return;
    425  1.1.4.2  rmind 	}
    426  1.1.4.2  rmind 
    427  1.1.4.2  rmind 	/*
    428  1.1.4.2  rmind 	 * Calculate p_clk first, since for DDR3 we need maximum significance.
    429  1.1.4.2  rmind 	 * DDR3 rating is not rounded to a multiple of 100.  This results in
    430  1.1.4.2  rmind 	 * cycle_time of 1.5ns displayed as PC3-10666.
    431  1.1.4.2  rmind 	 *
    432  1.1.4.2  rmind 	 * For SDRAM, the speed is provided by the caller so we use it.
    433  1.1.4.2  rmind 	 */
    434  1.1.4.2  rmind 	d_clk *= 1000 * 1000;
    435  1.1.4.2  rmind 	if (speed)
    436  1.1.4.2  rmind 		p_clk = speed;
    437  1.1.4.2  rmind 	else
    438  1.1.4.2  rmind 		p_clk = (d_clk * bits) / 8 / cycle_time;
    439  1.1.4.2  rmind 	d_clk = ((d_clk + cycle_time / 2) ) / cycle_time;
    440  1.1.4.2  rmind 	if (round) {
    441  1.1.4.2  rmind 		if ((p_clk % 100) >= 50)
    442  1.1.4.2  rmind 			p_clk += 50;
    443  1.1.4.2  rmind 		p_clk -= p_clk % 100;
    444  1.1.4.2  rmind 	}
    445  1.1.4.2  rmind 	aprint_normal(", %dMHz (%s-%d)\n",
    446  1.1.4.2  rmind 		      d_clk, ddr_type_string, p_clk);
    447  1.1.4.2  rmind 	if (node != NULL)
    448  1.1.4.2  rmind 		sysctl_createv(NULL, 0, NULL, NULL,
    449  1.1.4.2  rmind 			       CTLFLAG_IMMEDIATE,
    450  1.1.4.2  rmind 			       CTLTYPE_INT, "speed",
    451  1.1.4.2  rmind 			       SYSCTL_DESCR("memory speed in MHz"),
    452  1.1.4.2  rmind 			       NULL, d_clk, NULL, 0,
    453  1.1.4.2  rmind 			       CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
    454  1.1.4.2  rmind }
    455  1.1.4.2  rmind 
    456  1.1.4.2  rmind static void
    457  1.1.4.2  rmind decode_voltage_refresh(device_t self, struct spdmem *s)
    458  1.1.4.2  rmind {
    459  1.1.4.2  rmind 	const char *voltage, *refresh;
    460  1.1.4.2  rmind 
    461  1.1.4.2  rmind 	if (s->sm_voltage < __arraycount(spdmem_voltage_types))
    462  1.1.4.2  rmind 		voltage = spdmem_voltage_types[s->sm_voltage];
    463  1.1.4.2  rmind 	else
    464  1.1.4.2  rmind 		voltage = "unknown";
    465  1.1.4.2  rmind 
    466  1.1.4.2  rmind 	if (s->sm_refresh < __arraycount(spdmem_refresh_types))
    467  1.1.4.2  rmind 		refresh = spdmem_refresh_types[s->sm_refresh];
    468  1.1.4.2  rmind 	else
    469  1.1.4.2  rmind 		refresh = "unknown";
    470  1.1.4.2  rmind 
    471  1.1.4.2  rmind 	aprint_verbose_dev(self, "voltage %s, refresh time %s%s\n",
    472  1.1.4.2  rmind 			voltage, refresh,
    473  1.1.4.2  rmind 			s->sm_selfrefresh?" (self-refreshing)":"");
    474  1.1.4.2  rmind }
    475  1.1.4.2  rmind 
    476  1.1.4.2  rmind static void
    477  1.1.4.2  rmind decode_edofpm(const struct sysctlnode *node, device_t self, struct spdmem *s) {
    478  1.1.4.2  rmind 	aprint_normal("\n");
    479  1.1.4.2  rmind 	aprint_verbose_dev(self,
    480  1.1.4.2  rmind 	    "%d rows, %d cols, %d banks, %dns tRAC, %dns tCAC\n",
    481  1.1.4.2  rmind 	    s->sm_fpm.fpm_rows, s->sm_fpm.fpm_cols, s->sm_fpm.fpm_banks,
    482  1.1.4.2  rmind 	    s->sm_fpm.fpm_tRAC, s->sm_fpm.fpm_tCAC);
    483  1.1.4.2  rmind }
    484  1.1.4.2  rmind 
    485  1.1.4.2  rmind static void
    486  1.1.4.2  rmind decode_rom(const struct sysctlnode *node, device_t self, struct spdmem *s) {
    487  1.1.4.2  rmind 	aprint_normal("\n");
    488  1.1.4.2  rmind 	aprint_verbose_dev(self, "%d rows, %d cols, %d banks\n",
    489  1.1.4.2  rmind 	    s->sm_rom.rom_rows, s->sm_rom.rom_cols, s->sm_rom.rom_banks);
    490  1.1.4.2  rmind }
    491  1.1.4.2  rmind 
    492  1.1.4.2  rmind static void
    493  1.1.4.2  rmind decode_sdram(const struct sysctlnode *node, device_t self, struct spdmem *s,
    494  1.1.4.2  rmind 	     int spd_len) {
    495  1.1.4.2  rmind 	int dimm_size, cycle_time, bits, tAA, i, speed, freq;
    496  1.1.4.2  rmind 
    497  1.1.4.2  rmind 	aprint_normal("%s, %s, ",
    498  1.1.4.2  rmind 		(s->sm_sdr.sdr_mod_attrs & SPDMEM_SDR_MASK_REG)?
    499  1.1.4.2  rmind 			" (registered)":"",
    500  1.1.4.2  rmind 		(s->sm_config < __arraycount(spdmem_parity_types))?
    501  1.1.4.2  rmind 			spdmem_parity_types[s->sm_config]:"invalid parity");
    502  1.1.4.2  rmind 
    503  1.1.4.2  rmind 	dimm_size = 1 << (s->sm_sdr.sdr_rows + s->sm_sdr.sdr_cols - 17);
    504  1.1.4.2  rmind 	dimm_size *= s->sm_sdr.sdr_banks * s->sm_sdr.sdr_banks_per_chip;
    505  1.1.4.2  rmind 
    506  1.1.4.2  rmind 	cycle_time = s->sm_sdr.sdr_cycle_whole * 1000 +
    507  1.1.4.2  rmind 		     s->sm_sdr.sdr_cycle_tenths * 100;
    508  1.1.4.2  rmind 	bits = le16toh(s->sm_sdr.sdr_datawidth);
    509  1.1.4.2  rmind 	if (s->sm_config == 1 || s->sm_config == 2)
    510  1.1.4.2  rmind 		bits -= 8;
    511  1.1.4.2  rmind 
    512  1.1.4.2  rmind 	/* Calculate speed here - from OpenBSD */
    513  1.1.4.2  rmind 	if (spd_len >= 128)
    514  1.1.4.2  rmind 		freq = ((uint8_t *)s)[126];
    515  1.1.4.2  rmind 	else
    516  1.1.4.2  rmind 		freq = 0;
    517  1.1.4.2  rmind 	switch (freq) {
    518  1.1.4.2  rmind 		/*
    519  1.1.4.2  rmind 		 * Must check cycle time since some PC-133 DIMMs
    520  1.1.4.2  rmind 		 * actually report PC-100
    521  1.1.4.2  rmind 		 */
    522  1.1.4.2  rmind 	    case 100:
    523  1.1.4.2  rmind 	    case 133:
    524  1.1.4.2  rmind 		if (cycle_time < 8000)
    525  1.1.4.2  rmind 			speed = 133;
    526  1.1.4.2  rmind 		else
    527  1.1.4.2  rmind 			speed = 100;
    528  1.1.4.2  rmind 		break;
    529  1.1.4.2  rmind 	    case 0x66:		/* Legacy DIMMs use _hex_ 66! */
    530  1.1.4.2  rmind 	    default:
    531  1.1.4.2  rmind 		speed = 66;
    532  1.1.4.2  rmind 	}
    533  1.1.4.2  rmind 	decode_size_speed(node, dimm_size, cycle_time, 1, bits, FALSE, "PC",
    534  1.1.4.2  rmind 			  speed);
    535  1.1.4.2  rmind 
    536  1.1.4.2  rmind 	aprint_verbose_dev(self,
    537  1.1.4.2  rmind 	    "%d rows, %d cols, %d banks, %d banks/chip, %d.%dns cycle time\n",
    538  1.1.4.2  rmind 	    s->sm_sdr.sdr_rows, s->sm_sdr.sdr_cols, s->sm_sdr.sdr_banks,
    539  1.1.4.2  rmind 	    s->sm_sdr.sdr_banks_per_chip, cycle_time/1000,
    540  1.1.4.2  rmind 	    (cycle_time % 1000) / 100);
    541  1.1.4.2  rmind 
    542  1.1.4.2  rmind 	tAA  = 0;
    543  1.1.4.2  rmind 	for (i = 0; i < 8; i++)
    544  1.1.4.2  rmind 		if (s->sm_sdr.sdr_tCAS & (1 << i))
    545  1.1.4.2  rmind 			tAA = i;
    546  1.1.4.2  rmind 	tAA++;
    547  1.1.4.2  rmind 	aprint_verbose_dev(self, latency, tAA, s->sm_sdr.sdr_tRCD,
    548  1.1.4.2  rmind 	    s->sm_sdr.sdr_tRP, s->sm_sdr.sdr_tRAS);
    549  1.1.4.2  rmind 
    550  1.1.4.2  rmind 	decode_voltage_refresh(self, s);
    551  1.1.4.2  rmind }
    552  1.1.4.2  rmind 
    553  1.1.4.2  rmind static void
    554  1.1.4.2  rmind decode_ddr(const struct sysctlnode *node, device_t self, struct spdmem *s) {
    555  1.1.4.2  rmind 	int dimm_size, cycle_time, bits, tAA, i;
    556  1.1.4.2  rmind 
    557  1.1.4.2  rmind 	aprint_normal("%s, %s, ",
    558  1.1.4.2  rmind 		(s->sm_ddr.ddr_mod_attrs & SPDMEM_DDR_MASK_REG)?
    559  1.1.4.2  rmind 			" (registered)":"",
    560  1.1.4.2  rmind 		(s->sm_config < __arraycount(spdmem_parity_types))?
    561  1.1.4.2  rmind 			spdmem_parity_types[s->sm_config]:"invalid parity");
    562  1.1.4.2  rmind 
    563  1.1.4.2  rmind 	dimm_size = 1 << (s->sm_ddr.ddr_rows + s->sm_ddr.ddr_cols - 17);
    564  1.1.4.2  rmind 	dimm_size *= s->sm_ddr.ddr_ranks * s->sm_ddr.ddr_banks_per_chip;
    565  1.1.4.2  rmind 
    566  1.1.4.2  rmind 	cycle_time = s->sm_ddr.ddr_cycle_whole * 1000 +
    567  1.1.4.2  rmind 		  spdmem_cycle_frac[s->sm_ddr.ddr_cycle_tenths];
    568  1.1.4.2  rmind 	bits = le16toh(s->sm_ddr.ddr_datawidth);
    569  1.1.4.2  rmind 	if (s->sm_config == 1 || s->sm_config == 2)
    570  1.1.4.2  rmind 		bits -= 8;
    571  1.1.4.2  rmind 	decode_size_speed(node, dimm_size, cycle_time, 2, bits, TRUE, "PC", 0);
    572  1.1.4.2  rmind 
    573  1.1.4.2  rmind 	aprint_verbose_dev(self,
    574  1.1.4.2  rmind 	    "%d rows, %d cols, %d ranks, %d banks/chip, %d.%dns cycle time\n",
    575  1.1.4.2  rmind 	    s->sm_ddr.ddr_rows, s->sm_ddr.ddr_cols, s->sm_ddr.ddr_ranks,
    576  1.1.4.2  rmind 	    s->sm_ddr.ddr_banks_per_chip, cycle_time/1000,
    577  1.1.4.2  rmind 	    (cycle_time % 1000 + 50) / 100);
    578  1.1.4.2  rmind 
    579  1.1.4.2  rmind 	tAA  = 0;
    580  1.1.4.2  rmind 	for (i = 2; i < 8; i++)
    581  1.1.4.2  rmind 		if (s->sm_ddr.ddr_tCAS & (1 << i))
    582  1.1.4.2  rmind 			tAA = i;
    583  1.1.4.2  rmind 	tAA /= 2;
    584  1.1.4.2  rmind 
    585  1.1.4.2  rmind #define __DDR_ROUND(scale, field)	\
    586  1.1.4.2  rmind 		((scale * s->sm_ddr.field + cycle_time - 1) / cycle_time)
    587  1.1.4.2  rmind 
    588  1.1.4.2  rmind 	aprint_verbose_dev(self, latency, tAA, __DDR_ROUND(250, ddr_tRCD),
    589  1.1.4.2  rmind 		__DDR_ROUND(250, ddr_tRP), __DDR_ROUND(1000, ddr_tRAS));
    590  1.1.4.2  rmind 
    591  1.1.4.2  rmind #undef	__DDR_ROUND
    592  1.1.4.2  rmind 
    593  1.1.4.2  rmind 	decode_voltage_refresh(self, s);
    594  1.1.4.2  rmind }
    595  1.1.4.2  rmind 
    596  1.1.4.2  rmind static void
    597  1.1.4.2  rmind decode_ddr2(const struct sysctlnode *node, device_t self, struct spdmem *s) {
    598  1.1.4.2  rmind 	int dimm_size, cycle_time, bits, tAA, i;
    599  1.1.4.2  rmind 
    600  1.1.4.2  rmind 	aprint_normal("%s, %s, ",
    601  1.1.4.2  rmind 		(s->sm_ddr2.ddr2_mod_attrs & SPDMEM_DDR2_MASK_REG)?
    602  1.1.4.2  rmind 			" (registered)":"",
    603  1.1.4.2  rmind 		(s->sm_config < __arraycount(spdmem_parity_types))?
    604  1.1.4.2  rmind 			spdmem_parity_types[s->sm_config]:"invalid parity");
    605  1.1.4.2  rmind 
    606  1.1.4.2  rmind 	dimm_size = 1 << (s->sm_ddr2.ddr2_rows + s->sm_ddr2.ddr2_cols - 17);
    607  1.1.4.2  rmind 	dimm_size *= (s->sm_ddr2.ddr2_ranks + 1) *
    608  1.1.4.2  rmind 		     s->sm_ddr2.ddr2_banks_per_chip;
    609  1.1.4.2  rmind 
    610  1.1.4.2  rmind 	cycle_time = s->sm_ddr2.ddr2_cycle_whole * 1000 +
    611  1.1.4.2  rmind 		 spdmem_cycle_frac[s->sm_ddr2.ddr2_cycle_frac];
    612  1.1.4.2  rmind 	bits = s->sm_ddr2.ddr2_datawidth;
    613  1.1.4.2  rmind 	if ((s->sm_config & 0x03) != 0)
    614  1.1.4.2  rmind 		bits -= 8;
    615  1.1.4.2  rmind 	decode_size_speed(node, dimm_size, cycle_time, 2, bits, TRUE, "PC2", 0);
    616  1.1.4.2  rmind 
    617  1.1.4.2  rmind 	aprint_verbose_dev(self,
    618  1.1.4.2  rmind 	    "%d rows, %d cols, %d ranks, %d banks/chip, %d.%02dns cycle time\n",
    619  1.1.4.2  rmind 	    s->sm_ddr2.ddr2_rows, s->sm_ddr2.ddr2_cols,
    620  1.1.4.2  rmind 	    s->sm_ddr2.ddr2_ranks + 1, s->sm_ddr2.ddr2_banks_per_chip,
    621  1.1.4.2  rmind 	    cycle_time / 1000, (cycle_time % 1000 + 5) /10 );
    622  1.1.4.2  rmind 
    623  1.1.4.2  rmind 	tAA  = 0;
    624  1.1.4.2  rmind 	for (i = 2; i < 8; i++)
    625  1.1.4.2  rmind 		if (s->sm_ddr2.ddr2_tCAS & (1 << i))
    626  1.1.4.2  rmind 			tAA = i;
    627  1.1.4.2  rmind 
    628  1.1.4.2  rmind #define __DDR2_ROUND(scale, field)	\
    629  1.1.4.2  rmind 		((scale * s->sm_ddr2.field + cycle_time - 1) / cycle_time)
    630  1.1.4.2  rmind 
    631  1.1.4.2  rmind 	aprint_verbose_dev(self, latency, tAA, __DDR2_ROUND(250, ddr2_tRCD),
    632  1.1.4.2  rmind 		__DDR2_ROUND(250, ddr2_tRP), __DDR2_ROUND(1000, ddr2_tRAS));
    633  1.1.4.2  rmind 
    634  1.1.4.2  rmind #undef	__DDR_ROUND
    635  1.1.4.2  rmind 
    636  1.1.4.2  rmind 	decode_voltage_refresh(self, s);
    637  1.1.4.2  rmind }
    638  1.1.4.2  rmind 
    639  1.1.4.2  rmind static void
    640  1.1.4.2  rmind decode_ddr3(const struct sysctlnode *node, device_t self, struct spdmem *s) {
    641  1.1.4.2  rmind 	int dimm_size, cycle_time, bits;
    642  1.1.4.2  rmind 
    643  1.1.4.2  rmind 	if (s->sm_ddr3.ddr3_mod_type ==
    644  1.1.4.2  rmind 		SPDMEM_DDR3_TYPE_MINI_RDIMM ||
    645  1.1.4.2  rmind 	    s->sm_ddr3.ddr3_mod_type == SPDMEM_DDR3_TYPE_RDIMM)
    646  1.1.4.2  rmind 		aprint_normal(" (registered)");
    647  1.1.4.2  rmind 	aprint_normal(", %sECC, %stemp-sensor, ",
    648  1.1.4.2  rmind 		(s->sm_ddr3.ddr3_hasECC)?"":"no ",
    649  1.1.4.2  rmind 		(s->sm_ddr3.ddr3_has_therm_sensor)?"":"no ");
    650  1.1.4.2  rmind 
    651  1.1.4.2  rmind 	/*
    652  1.1.4.2  rmind 	 * DDR3 size specification is quite different from others
    653  1.1.4.2  rmind 	 *
    654  1.1.4.2  rmind 	 * Module capacity is defined as
    655  1.1.4.2  rmind 	 *	Chip_Capacity_in_bits / 8bits-per-byte *
    656  1.1.4.2  rmind 	 *	external_bus_width / internal_bus_width
    657  1.1.4.2  rmind 	 * We further divide by 2**20 to get our answer in MB
    658  1.1.4.2  rmind 	 */
    659  1.1.4.2  rmind 	dimm_size = (s->sm_ddr3.ddr3_chipsize + 28 - 20) - 3 +
    660  1.1.4.2  rmind 		    (s->sm_ddr3.ddr3_datawidth + 3) -
    661  1.1.4.2  rmind 		    (s->sm_ddr3.ddr3_chipwidth + 2);
    662  1.1.4.2  rmind 	dimm_size = (1 << dimm_size) * (s->sm_ddr3.ddr3_physbanks + 1);
    663  1.1.4.2  rmind 
    664  1.1.4.2  rmind 	cycle_time = (1000 * s->sm_ddr3.ddr3_mtb_dividend +
    665  1.1.4.2  rmind 			    (s->sm_ddr3.ddr3_mtb_divisor / 2)) /
    666  1.1.4.2  rmind 		     s->sm_ddr3.ddr3_mtb_divisor;
    667  1.1.4.2  rmind 	cycle_time *= s->sm_ddr3.ddr3_tCKmin;
    668  1.1.4.2  rmind 	bits = 1 << (s->sm_ddr3.ddr3_datawidth + 3);
    669  1.1.4.2  rmind 	decode_size_speed(node, dimm_size, cycle_time, 2, bits, FALSE, "PC3", 0);
    670  1.1.4.2  rmind 
    671  1.1.4.2  rmind 	aprint_verbose_dev(self,
    672  1.1.4.2  rmind 	    "%d rows, %d cols, %d log. banks, %d phys. banks, "
    673  1.1.4.2  rmind 	    "%d.%03dns cycle time\n",
    674  1.1.4.2  rmind 	    s->sm_ddr3.ddr3_rows + 9, s->sm_ddr3.ddr3_cols + 12,
    675  1.1.4.2  rmind 	    1 << (s->sm_ddr3.ddr3_logbanks + 3),
    676  1.1.4.2  rmind 	    s->sm_ddr3.ddr3_physbanks + 1,
    677  1.1.4.2  rmind 	    cycle_time/1000, cycle_time % 1000);
    678  1.1.4.2  rmind 
    679  1.1.4.2  rmind #define	__DDR3_CYCLES(field) (s->sm_ddr3.field / s->sm_ddr3.ddr3_tCKmin)
    680  1.1.4.2  rmind 
    681  1.1.4.2  rmind 	aprint_verbose_dev(self, latency, __DDR3_CYCLES(ddr3_tAAmin),
    682  1.1.4.2  rmind 		__DDR3_CYCLES(ddr3_tRCDmin), __DDR3_CYCLES(ddr3_tRPmin),
    683  1.1.4.2  rmind 		(s->sm_ddr3.ddr3_tRAS_msb * 256 + s->sm_ddr3.ddr3_tRAS_lsb) /
    684  1.1.4.2  rmind 		    s->sm_ddr3.ddr3_tCKmin);
    685  1.1.4.2  rmind 
    686  1.1.4.2  rmind #undef	__DDR3_CYCLES
    687  1.1.4.2  rmind }
    688  1.1.4.2  rmind 
    689  1.1.4.2  rmind static void
    690  1.1.4.2  rmind decode_fbdimm(const struct sysctlnode *node, device_t self, struct spdmem *s) {
    691  1.1.4.2  rmind 	int dimm_size, cycle_time, bits;
    692  1.1.4.2  rmind 
    693  1.1.4.2  rmind 	/*
    694  1.1.4.2  rmind 	 * FB-DIMM module size calculation is very much like DDR3
    695  1.1.4.2  rmind 	 */
    696  1.1.4.2  rmind 	dimm_size = s->sm_fbd.fbdimm_rows + 12 +
    697  1.1.4.2  rmind 		    s->sm_fbd.fbdimm_cols +  9 - 20 - 3;
    698  1.1.4.2  rmind 	dimm_size = (1 << dimm_size) * (1 << (s->sm_fbd.fbdimm_banks + 2));
    699  1.1.4.2  rmind 
    700  1.1.4.2  rmind 	cycle_time = (1000 * s->sm_fbd.fbdimm_mtb_dividend +
    701  1.1.4.2  rmind 			    (s->sm_fbd.fbdimm_mtb_divisor / 2)) /
    702  1.1.4.2  rmind 		     s->sm_fbd.fbdimm_mtb_divisor;
    703  1.1.4.2  rmind 	bits = 1 << (s->sm_fbd.fbdimm_dev_width + 2);
    704  1.1.4.2  rmind 	decode_size_speed(node, dimm_size, cycle_time, 2, bits, TRUE, "PC2", 0);
    705  1.1.4.2  rmind 
    706  1.1.4.2  rmind 	aprint_verbose_dev(self,
    707  1.1.4.2  rmind 	    "%d rows, %d cols, %d banks, %d.%02dns cycle time\n",
    708  1.1.4.2  rmind 	    s->sm_fbd.fbdimm_rows, s->sm_fbd.fbdimm_cols,
    709  1.1.4.2  rmind 	    1 << (s->sm_fbd.fbdimm_banks + 2),
    710  1.1.4.2  rmind 	    cycle_time / 1000, (cycle_time % 1000 + 5) /10 );
    711  1.1.4.2  rmind 
    712  1.1.4.2  rmind #define	__FBDIMM_CYCLES(field) (s->sm_fbd.field / s->sm_fbd.fbdimm_tCKmin)
    713  1.1.4.2  rmind 
    714  1.1.4.2  rmind 	aprint_verbose_dev(self, latency, __FBDIMM_CYCLES(fbdimm_tAAmin),
    715  1.1.4.2  rmind 		__FBDIMM_CYCLES(fbdimm_tRCDmin), __FBDIMM_CYCLES(fbdimm_tRPmin),
    716  1.1.4.2  rmind 		(s->sm_fbd.fbdimm_tRAS_msb * 256 +
    717  1.1.4.2  rmind 			s->sm_fbd.fbdimm_tRAS_lsb) /
    718  1.1.4.2  rmind 		    s->sm_fbd.fbdimm_tCKmin);
    719  1.1.4.2  rmind 
    720  1.1.4.2  rmind #undef	__FBDIMM_CYCLES
    721  1.1.4.2  rmind 
    722  1.1.4.2  rmind 	decode_voltage_refresh(self, s);
    723  1.1.4.2  rmind }
    724