Tue Apr 14 17:39:28 2020 UTC ()
Pull up following revision(s) (requested by msaitoh in ticket #1528):

	sys/dev/ic/spdmemvar.h: revision 1.15
	sys/dev/ic/spdmemvar.h: revision 1.16
	sys/dev/ic/spdmem.c: revision 1.31
	sys/dev/ic/spdmem.c: revision 1.32
	sys/dev/ic/spdmem.c: revision 1.33
	sys/dev/ic/spdmem.c: revision 1.34
	sys/dev/ic/spdmem.c: revision 1.35

Fix spelling of symeti^Hric

  Print DDR3's row and column correctly.

KNF. No functional change.

- Define some new parameters of DDR3 SPD ROM.
- Use fine timebase parameters for time calculation on DDR3. This change
   makes PC3-XXXX value more correctly on newer DDR3.

Calculate DDR3's tRAS correctly.

  Fix unused area size found by pgoyette@.


(martin)
diff -r1.24.6.2 -r1.24.6.3 src/sys/dev/ic/spdmem.c
diff -r1.13.6.1 -r1.13.6.2 src/sys/dev/ic/spdmemvar.h

cvs diff -r1.24.6.2 -r1.24.6.3 src/sys/dev/ic/spdmem.c (expand / switch to unified diff)

--- src/sys/dev/ic/spdmem.c 2019/01/03 11:23:54 1.24.6.2
+++ src/sys/dev/ic/spdmem.c 2020/04/14 17:39:28 1.24.6.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: spdmem.c,v 1.24.6.2 2019/01/03 11:23:54 martin Exp $ */ 1/* $NetBSD: spdmem.c,v 1.24.6.3 2020/04/14 17:39:28 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2007 Nicolas Joly 4 * Copyright (c) 2007 Nicolas Joly
5 * Copyright (c) 2007 Paul Goyette 5 * Copyright (c) 2007 Paul Goyette
6 * Copyright (c) 2007 Tobias Nygren 6 * Copyright (c) 2007 Tobias Nygren
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
@@ -25,27 +25,27 @@ @@ -25,27 +25,27 @@
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * Serial Presence Detect (SPD) memory identification 34 * Serial Presence Detect (SPD) memory identification
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: spdmem.c,v 1.24.6.2 2019/01/03 11:23:54 martin Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: spdmem.c,v 1.24.6.3 2020/04/14 17:39:28 martin Exp $");
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/device.h> 41#include <sys/device.h>
42#include <sys/endian.h> 42#include <sys/endian.h>
43#include <sys/sysctl.h> 43#include <sys/sysctl.h>
44#include <machine/bswap.h> 44#include <machine/bswap.h>
45 45
46#include <dev/i2c/i2cvar.h> 46#include <dev/i2c/i2cvar.h>
47#include <dev/ic/spdmemreg.h> 47#include <dev/ic/spdmemreg.h>
48#include <dev/ic/spdmemvar.h> 48#include <dev/ic/spdmemvar.h>
49 49
50/* Routines for decoding spd data */ 50/* Routines for decoding spd data */
51static void decode_edofpm(const struct sysctlnode *, device_t, struct spdmem *); 51static void decode_edofpm(const struct sysctlnode *, device_t, struct spdmem *);
@@ -330,32 +330,32 @@ spdmem_common_attach(struct spdmem_softc @@ -330,32 +330,32 @@ spdmem_common_attach(struct spdmem_softc
330 spd_len = sizeof(struct spdmem); 330 spd_len = sizeof(struct spdmem);
331 for (i = 3; i < spd_len; i++) 331 for (i = 3; i < spd_len; i++)
332 (sc->sc_read)(sc, i, &((uint8_t *)s)[i]); 332 (sc->sc_read)(sc, i, &((uint8_t *)s)[i]);
333 333
334 /* 334 /*
335 * Setup our sysctl subtree, hw.spdmemN 335 * Setup our sysctl subtree, hw.spdmemN
336 */ 336 */
337 sc->sc_sysctl_log = NULL; 337 sc->sc_sysctl_log = NULL;
338 sysctl_createv(&sc->sc_sysctl_log, 0, NULL, &node, 338 sysctl_createv(&sc->sc_sysctl_log, 0, NULL, &node,
339 0, CTLTYPE_NODE, 339 0, CTLTYPE_NODE,
340 device_xname(self), NULL, NULL, 0, NULL, 0, 340 device_xname(self), NULL, NULL, 0, NULL, 0,
341 CTL_HW, CTL_CREATE, CTL_EOL); 341 CTL_HW, CTL_CREATE, CTL_EOL);
342 if (node != NULL && spd_len != 0) 342 if (node != NULL && spd_len != 0)
343 sysctl_createv(&sc->sc_sysctl_log, 0, NULL, NULL, 343 sysctl_createv(&sc->sc_sysctl_log, 0, NULL, NULL,
344 0, 344 0,
345 CTLTYPE_STRUCT, "spd_data", 345 CTLTYPE_STRUCT, "spd_data",
346 SYSCTL_DESCR("raw spd data"), NULL, 346 SYSCTL_DESCR("raw spd data"), NULL,
347 0, s, spd_len, 347 0, s, spd_len,
348 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); 348 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
349 349
350 /* 350 /*
351 * Decode and print key SPD contents 351 * Decode and print key SPD contents
352 */ 352 */
353 if (IS_RAMBUS_TYPE) { 353 if (IS_RAMBUS_TYPE) {
354 if (s->sm_type == SPDMEM_MEMTYPE_RAMBUS) 354 if (s->sm_type == SPDMEM_MEMTYPE_RAMBUS)
355 type = "Rambus"; 355 type = "Rambus";
356 else if (s->sm_type == SPDMEM_MEMTYPE_DIRECTRAMBUS) 356 else if (s->sm_type == SPDMEM_MEMTYPE_DIRECTRAMBUS)
357 type = "Direct Rambus"; 357 type = "Direct Rambus";
358 else 358 else
359 type = "Rambus (unknown)"; 359 type = "Rambus (unknown)";
360 360
361 switch (s->sm_len) { 361 switch (s->sm_len) {
@@ -401,27 +401,27 @@ spdmem_common_attach(struct spdmem_softc @@ -401,27 +401,27 @@ spdmem_common_attach(struct spdmem_softc
401 401
402 strlcpy(sc->sc_type, type, SPDMEM_TYPE_MAXLEN); 402 strlcpy(sc->sc_type, type, SPDMEM_TYPE_MAXLEN);
403 403
404 if (s->sm_type == SPDMEM_MEMTYPE_DDR4SDRAM) { 404 if (s->sm_type == SPDMEM_MEMTYPE_DDR4SDRAM) {
405 /* 405 /*
406 * The latest spec (DDR4 SPD Document Release 3) defines 406 * The latest spec (DDR4 SPD Document Release 3) defines
407 * NVDIMM Hybrid only. 407 * NVDIMM Hybrid only.
408 */ 408 */
409 if ((s->sm_ddr4.ddr4_hybrid) 409 if ((s->sm_ddr4.ddr4_hybrid)
410 && (s->sm_ddr4.ddr4_hybrid_media == 1)) 410 && (s->sm_ddr4.ddr4_hybrid_media == 1))
411 strlcat(sc->sc_type, " NVDIMM hybrid", 411 strlcat(sc->sc_type, " NVDIMM hybrid",
412 SPDMEM_TYPE_MAXLEN); 412 SPDMEM_TYPE_MAXLEN);
413 } 413 }
414  414
415 if (node != NULL) 415 if (node != NULL)
416 sysctl_createv(&sc->sc_sysctl_log, 0, NULL, NULL, 416 sysctl_createv(&sc->sc_sysctl_log, 0, NULL, NULL,
417 0, 417 0,
418 CTLTYPE_STRING, "mem_type", 418 CTLTYPE_STRING, "mem_type",
419 SYSCTL_DESCR("memory module type"), NULL, 419 SYSCTL_DESCR("memory module type"), NULL,
420 0, sc->sc_type, 0, 420 0, sc->sc_type, 0,
421 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL); 421 CTL_HW, node->sysctl_num, CTL_CREATE, CTL_EOL);
422 422
423 if (IS_RAMBUS_TYPE) { 423 if (IS_RAMBUS_TYPE) {
424 aprint_naive("\n"); 424 aprint_naive("\n");
425 aprint_normal("\n"); 425 aprint_normal("\n");
426 aprint_normal_dev(self, "%s, SPD Revision %s", type, rambus_rev); 426 aprint_normal_dev(self, "%s, SPD Revision %s", type, rambus_rev);
427 dimm_size = 1 << (s->sm_rdr.rdr_rows + s->sm_rdr.rdr_cols - 13); 427 dimm_size = 1 << (s->sm_rdr.rdr_rows + s->sm_rdr.rdr_cols - 13);
@@ -605,27 +605,27 @@ decode_sdram(const struct sysctlnode *no @@ -605,27 +605,27 @@ decode_sdram(const struct sysctlnode *no
605 cycle_time = s->sm_sdr.sdr_cycle_whole * 1000 + 605 cycle_time = s->sm_sdr.sdr_cycle_whole * 1000 +
606 s->sm_sdr.sdr_cycle_tenths * 100; 606 s->sm_sdr.sdr_cycle_tenths * 100;
607 bits = le16toh(s->sm_sdr.sdr_datawidth); 607 bits = le16toh(s->sm_sdr.sdr_datawidth);
608 if (s->sm_config == 1 || s->sm_config == 2) 608 if (s->sm_config == 1 || s->sm_config == 2)
609 bits -= 8; 609 bits -= 8;
610 610
611 /* Calculate speed here - from OpenBSD */ 611 /* Calculate speed here - from OpenBSD */
612 if (spd_len >= 128) 612 if (spd_len >= 128)
613 freq = ((uint8_t *)s)[126]; 613 freq = ((uint8_t *)s)[126];
614 else 614 else
615 freq = 0; 615 freq = 0;
616 switch (freq) { 616 switch (freq) {
617 /* 617 /*
618 * Must check cycle time since some PC-133 DIMMs  618 * Must check cycle time since some PC-133 DIMMs
619 * actually report PC-100 619 * actually report PC-100
620 */ 620 */
621 case 100: 621 case 100:
622 case 133: 622 case 133:
623 if (cycle_time < 8000) 623 if (cycle_time < 8000)
624 speed = 133; 624 speed = 133;
625 else 625 else
626 speed = 100; 626 speed = 100;
627 break; 627 break;
628 case 0x66: /* Legacy DIMMs use _hex_ 66! */ 628 case 0x66: /* Legacy DIMMs use _hex_ 66! */
629 default: 629 default:
630 speed = 66; 630 speed = 66;
631 } 631 }
@@ -746,26 +746,50 @@ decode_ddr2(const struct sysctlnode *nod @@ -746,26 +746,50 @@ decode_ddr2(const struct sysctlnode *nod
746 746
747 decode_voltage_refresh(self, s); 747 decode_voltage_refresh(self, s);
748} 748}
749 749
750static void 750static void
751print_part(const char *part, size_t pnsize) 751print_part(const char *part, size_t pnsize)
752{ 752{
753 const char *p = memchr(part, ' ', pnsize); 753 const char *p = memchr(part, ' ', pnsize);
754 if (p == NULL) 754 if (p == NULL)
755 p = part + pnsize; 755 p = part + pnsize;
756 aprint_normal(": %.*s\n", (int)(p - part), part); 756 aprint_normal(": %.*s\n", (int)(p - part), part);
757} 757}
758 758
 759static u_int
 760ddr3_value_pico(struct spdmem *s, uint8_t txx_mtb, uint8_t txx_ftb)
 761{
 762 u_int mtb, ftb; /* in picoseconds */
 763 intmax_t signed_txx_ftb;
 764 u_int val;
 765
 766 mtb = (u_int)s->sm_ddr3.ddr3_mtb_dividend * 1000 /
 767 s->sm_ddr3.ddr3_mtb_divisor;
 768 ftb = (u_int)s->sm_ddr3.ddr3_ftb_dividend * 1000 /
 769 s->sm_ddr3.ddr3_ftb_divisor;
 770
 771 /* tXX_ftb is signed value */
 772 signed_txx_ftb = (int8_t)txx_ftb;
 773 val = txx_mtb * mtb +
 774 ((txx_ftb > 127) ? signed_txx_ftb : txx_ftb) * ftb / 1000;
 775
 776 return val;
 777}
 778
 779#define __DDR3_VALUE_PICO(s, field) \
 780 ddr3_value_pico(s, s->sm_ddr3.ddr3_##field##_mtb, \
 781 s->sm_ddr3.ddr3_##field##_ftb)
 782
759static void 783static void
760decode_ddr3(const struct sysctlnode *node, device_t self, struct spdmem *s) 784decode_ddr3(const struct sysctlnode *node, device_t self, struct spdmem *s)
761{ 785{
762 int dimm_size, cycle_time, bits; 786 int dimm_size, cycle_time, bits;
763 787
764 aprint_naive("\n"); 788 aprint_naive("\n");
765 print_part(s->sm_ddr3.ddr3_part, sizeof(s->sm_ddr3.ddr3_part)); 789 print_part(s->sm_ddr3.ddr3_part, sizeof(s->sm_ddr3.ddr3_part));
766 aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]); 790 aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]);
767 791
768 if (s->sm_ddr3.ddr3_mod_type == 792 if (s->sm_ddr3.ddr3_mod_type ==
769 SPDMEM_DDR3_TYPE_MINI_RDIMM || 793 SPDMEM_DDR3_TYPE_MINI_RDIMM ||
770 s->sm_ddr3.ddr3_mod_type == SPDMEM_DDR3_TYPE_RDIMM) 794 s->sm_ddr3.ddr3_mod_type == SPDMEM_DDR3_TYPE_RDIMM)
771 aprint_normal(" (registered)"); 795 aprint_normal(" (registered)");
@@ -776,48 +800,49 @@ decode_ddr3(const struct sysctlnode *nod @@ -776,48 +800,49 @@ decode_ddr3(const struct sysctlnode *nod
776 /* 800 /*
777 * DDR3 size specification is quite different from others 801 * DDR3 size specification is quite different from others
778 * 802 *
779 * Module capacity is defined as 803 * Module capacity is defined as
780 * Chip_Capacity_in_bits / 8bits-per-byte * 804 * Chip_Capacity_in_bits / 8bits-per-byte *
781 * external_bus_width / internal_bus_width 805 * external_bus_width / internal_bus_width
782 * We further divide by 2**20 to get our answer in MB 806 * We further divide by 2**20 to get our answer in MB
783 */ 807 */
784 dimm_size = (s->sm_ddr3.ddr3_chipsize + 28 - 20) - 3 + 808 dimm_size = (s->sm_ddr3.ddr3_chipsize + 28 - 20) - 3 +
785 (s->sm_ddr3.ddr3_datawidth + 3) - 809 (s->sm_ddr3.ddr3_datawidth + 3) -
786 (s->sm_ddr3.ddr3_chipwidth + 2); 810 (s->sm_ddr3.ddr3_chipwidth + 2);
787 dimm_size = (1 << dimm_size) * (s->sm_ddr3.ddr3_physbanks + 1); 811 dimm_size = (1 << dimm_size) * (s->sm_ddr3.ddr3_physbanks + 1);
788 812
789 cycle_time = (1000 * s->sm_ddr3.ddr3_mtb_dividend +  813 cycle_time = __DDR3_VALUE_PICO(s, tCKmin);
790 (s->sm_ddr3.ddr3_mtb_divisor / 2)) / 
791 s->sm_ddr3.ddr3_mtb_divisor; 
792 cycle_time *= s->sm_ddr3.ddr3_tCKmin; 
793 bits = 1 << (s->sm_ddr3.ddr3_datawidth + 3); 814 bits = 1 << (s->sm_ddr3.ddr3_datawidth + 3);
794 decode_size_speed(self, node, dimm_size, cycle_time, 2, bits, FALSE, 815 decode_size_speed(self, node, dimm_size, cycle_time, 2, bits, FALSE,
795 "PC3", 0); 816 "PC3", 0);
796 817
797 aprint_verbose_dev(self, 818 aprint_verbose_dev(self,
798 "%d rows, %d cols, %d log. banks, %d phys. banks, " 819 "%d rows, %d cols, %d log. banks, %d phys. banks, "
799 "%d.%03dns cycle time\n", 820 "%d.%03dns cycle time\n",
800 s->sm_ddr3.ddr3_rows + 9, s->sm_ddr3.ddr3_cols + 12, 821 s->sm_ddr3.ddr3_rows + 12, s->sm_ddr3.ddr3_cols + 9,
801 1 << (s->sm_ddr3.ddr3_logbanks + 3), 822 1 << (s->sm_ddr3.ddr3_logbanks + 3),
802 s->sm_ddr3.ddr3_physbanks + 1, 823 s->sm_ddr3.ddr3_physbanks + 1,
803 cycle_time/1000, cycle_time % 1000); 824 cycle_time/1000, cycle_time % 1000);
804 825
805#define __DDR3_CYCLES(field) (s->sm_ddr3.field / s->sm_ddr3.ddr3_tCKmin) 826#define __DDR3_CYCLES(val) \
 827 ((val / cycle_time) + ((val % cycle_time) ? 1 : 0))
806 828
807 aprint_verbose_dev(self, LATENCY, __DDR3_CYCLES(ddr3_tAAmin), 829 aprint_verbose_dev(self, LATENCY,
808 __DDR3_CYCLES(ddr3_tRCDmin), __DDR3_CYCLES(ddr3_tRPmin),  830 __DDR3_CYCLES(__DDR3_VALUE_PICO(s, tAAmin)),
809 (s->sm_ddr3.ddr3_tRAS_msb * 256 + s->sm_ddr3.ddr3_tRAS_lsb) / 831 __DDR3_CYCLES(__DDR3_VALUE_PICO(s, tRCDmin)),
810 s->sm_ddr3.ddr3_tCKmin); 832 __DDR3_CYCLES(__DDR3_VALUE_PICO(s, tRPmin)),
 833 __DDR3_CYCLES((s->sm_ddr3.ddr3_tRAS_msb * 256
 834 + s->sm_ddr3.ddr3_tRAS_lsb) * s->sm_ddr3.ddr3_mtb_dividend
 835 / s->sm_ddr3.ddr3_mtb_divisor * 1000));
811 836
812#undef __DDR3_CYCLES 837#undef __DDR3_CYCLES
813 838
814 /* For DDR3, Voltage is written in another area */ 839 /* For DDR3, Voltage is written in another area */
815 if (!s->sm_ddr3.ddr3_NOT15V || s->sm_ddr3.ddr3_135V 840 if (!s->sm_ddr3.ddr3_NOT15V || s->sm_ddr3.ddr3_135V
816 || s->sm_ddr3.ddr3_125V) { 841 || s->sm_ddr3.ddr3_125V) {
817 aprint_verbose("%s:", device_xname(self)); 842 aprint_verbose("%s:", device_xname(self));
818 if (!s->sm_ddr3.ddr3_NOT15V) 843 if (!s->sm_ddr3.ddr3_NOT15V)
819 aprint_verbose(" 1.5V"); 844 aprint_verbose(" 1.5V");
820 if (s->sm_ddr3.ddr3_135V) 845 if (s->sm_ddr3.ddr3_135V)
821 aprint_verbose(" 1.35V"); 846 aprint_verbose(" 1.35V");
822 if (s->sm_ddr3.ddr3_125V) 847 if (s->sm_ddr3.ddr3_125V)
823 aprint_verbose(" 1.25V"); 848 aprint_verbose(" 1.25V");
@@ -847,47 +872,47 @@ decode_fbdimm(const struct sysctlnode *n @@ -847,47 +872,47 @@ decode_fbdimm(const struct sysctlnode *n
847 bits = 1 << (s->sm_fbd.fbdimm_dev_width + 2); 872 bits = 1 << (s->sm_fbd.fbdimm_dev_width + 2);
848 decode_size_speed(self, node, dimm_size, cycle_time, 2, bits, TRUE, 873 decode_size_speed(self, node, dimm_size, cycle_time, 2, bits, TRUE,
849 "PC2", 0); 874 "PC2", 0);
850 875
851 aprint_verbose_dev(self, 876 aprint_verbose_dev(self,
852 "%d rows, %d cols, %d banks, %d.%02dns cycle time\n", 877 "%d rows, %d cols, %d banks, %d.%02dns cycle time\n",
853 s->sm_fbd.fbdimm_rows, s->sm_fbd.fbdimm_cols, 878 s->sm_fbd.fbdimm_rows, s->sm_fbd.fbdimm_cols,
854 1 << (s->sm_fbd.fbdimm_banks + 2), 879 1 << (s->sm_fbd.fbdimm_banks + 2),
855 cycle_time / 1000, (cycle_time % 1000 + 5) /10 ); 880 cycle_time / 1000, (cycle_time % 1000 + 5) /10 );
856 881
857#define __FBDIMM_CYCLES(field) (s->sm_fbd.field / s->sm_fbd.fbdimm_tCKmin) 882#define __FBDIMM_CYCLES(field) (s->sm_fbd.field / s->sm_fbd.fbdimm_tCKmin)
858 883
859 aprint_verbose_dev(self, LATENCY, __FBDIMM_CYCLES(fbdimm_tAAmin), 884 aprint_verbose_dev(self, LATENCY, __FBDIMM_CYCLES(fbdimm_tAAmin),
860 __FBDIMM_CYCLES(fbdimm_tRCDmin), __FBDIMM_CYCLES(fbdimm_tRPmin),  885 __FBDIMM_CYCLES(fbdimm_tRCDmin), __FBDIMM_CYCLES(fbdimm_tRPmin),
861 (s->sm_fbd.fbdimm_tRAS_msb * 256 + s->sm_fbd.fbdimm_tRAS_lsb) / 886 (s->sm_fbd.fbdimm_tRAS_msb * 256 + s->sm_fbd.fbdimm_tRAS_lsb) /
862 s->sm_fbd.fbdimm_tCKmin); 887 s->sm_fbd.fbdimm_tCKmin);
863 888
864#undef __FBDIMM_CYCLES 889#undef __FBDIMM_CYCLES
865 890
866 decode_voltage_refresh(self, s); 891 decode_voltage_refresh(self, s);
867} 892}
868 893
869static void 894static void
870decode_ddr4(const struct sysctlnode *node, device_t self, struct spdmem *s) 895decode_ddr4(const struct sysctlnode *node, device_t self, struct spdmem *s)
871{ 896{
872 int dimm_size, cycle_time, ranks; 897 int dimm_size, cycle_time, ranks;
873 int tAA_clocks, tRCD_clocks,tRP_clocks, tRAS_clocks; 898 int tAA_clocks, tRCD_clocks, tRP_clocks, tRAS_clocks;
874 899
875 aprint_naive("\n"); 900 aprint_naive("\n");
876 print_part(s->sm_ddr4.ddr4_part_number, 901 print_part(s->sm_ddr4.ddr4_part_number,
877 sizeof(s->sm_ddr4.ddr4_part_number)); 902 sizeof(s->sm_ddr4.ddr4_part_number));
878 aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]); 903 aprint_normal_dev(self, "%s", spdmem_basic_types[s->sm_type]);
879 if (s->sm_ddr4.ddr4_mod_type < __arraycount(spdmem_ddr4_module_types)) 904 if (s->sm_ddr4.ddr4_mod_type < __arraycount(spdmem_ddr4_module_types))
880 aprint_normal(" (%s)",  905 aprint_normal(" (%s)",
881 spdmem_ddr4_module_types[s->sm_ddr4.ddr4_mod_type]); 906 spdmem_ddr4_module_types[s->sm_ddr4.ddr4_mod_type]);
882 aprint_normal(", %sECC, %stemp-sensor, ", 907 aprint_normal(", %sECC, %stemp-sensor, ",
883 (s->sm_ddr4.ddr4_bus_width_extension) ? "" : "no ", 908 (s->sm_ddr4.ddr4_bus_width_extension) ? "" : "no ",
884 (s->sm_ddr4.ddr4_has_therm_sensor) ? "" : "no "); 909 (s->sm_ddr4.ddr4_has_therm_sensor) ? "" : "no ");
885 910
886 /* 911 /*
887 * DDR4 size calculation from JEDEC spec 912 * DDR4 size calculation from JEDEC spec
888 * 913 *
889 * Module capacity in bytes is defined as 914 * Module capacity in bytes is defined as
890 * Chip_Capacity_in_bits / 8bits-per-byte * 915 * Chip_Capacity_in_bits / 8bits-per-byte *
891 * primary_bus_width / DRAM_width * 916 * primary_bus_width / DRAM_width *
892 * logical_ranks_per_DIMM 917 * logical_ranks_per_DIMM
893 * 918 *
@@ -902,57 +927,57 @@ decode_ddr4(const struct sysctlnode *nod @@ -902,57 +927,57 @@ decode_ddr4(const struct sysctlnode *nod
902 + (s->sm_ddr4.ddr4_primary_bus_width + 3); /* bus width */ 927 + (s->sm_ddr4.ddr4_primary_bus_width + 3); /* bus width */
903 switch (s->sm_ddr4.ddr4_device_width) { /* DRAM width */ 928 switch (s->sm_ddr4.ddr4_device_width) { /* DRAM width */
904 case 0: dimm_size -= 2; 929 case 0: dimm_size -= 2;
905 break; 930 break;
906 case 1: dimm_size -= 3; 931 case 1: dimm_size -= 3;
907 break; 932 break;
908 case 2: dimm_size -= 4; 933 case 2: dimm_size -= 4;
909 break; 934 break;
910 case 4: dimm_size -= 5; 935 case 4: dimm_size -= 5;
911 break; 936 break;
912 default: 937 default:
913 dimm_size = -1; /* flag invalid value */ 938 dimm_size = -1; /* flag invalid value */
914 } 939 }
915 if (dimm_size >= 0) {  940 if (dimm_size >= 0) {
916 dimm_size = (1 << dimm_size) * 941 dimm_size = (1 << dimm_size) *
917 (s->sm_ddr4.ddr4_package_ranks + 1); /* log.ranks/DIMM */ 942 (s->sm_ddr4.ddr4_package_ranks + 1); /* log.ranks/DIMM */
918 if (s->sm_ddr4.ddr4_signal_loading == 2) { 943 if (s->sm_ddr4.ddr4_signal_loading == 2) {
919 dimm_size *= (s->sm_ddr4.ddr4_diecount + 1); 944 dimm_size *= (s->sm_ddr4.ddr4_diecount + 1);
920 } 945 }
921 } 946 }
922 947
923/* 948/*
924 * Note that the ddr4_xxx_ftb fields are actually signed offsets from 949 * Note that the ddr4_xxx_ftb fields are actually signed offsets from
925 * the corresponding mtb value, so we might have to subtract 256! 950 * the corresponding mtb value, so we might have to subtract 256!
926 */ 951 */
927#define __DDR4_VALUE(field) ((s->sm_ddr4.ddr4_##field##_mtb * 125 + \ 952#define __DDR4_VALUE(field) ((s->sm_ddr4.ddr4_##field##_mtb * 125 + \
928 s->sm_ddr4.ddr4_##field##_ftb) - \ 953 s->sm_ddr4.ddr4_##field##_ftb) - \
929 ((s->sm_ddr4.ddr4_##field##_ftb > 127)?256:0)) 954 ((s->sm_ddr4.ddr4_##field##_ftb > 127)?256:0))
930 /* 955 /*
931 * For now, the only value for mtb is 0 = 125ps, and ftb = 1ps  956 * For now, the only value for mtb is 0 = 125ps, and ftb = 1ps
932 * so we don't need to figure out the time-base units - just 957 * so we don't need to figure out the time-base units - just
933 * hard-code them for now. 958 * hard-code them for now.
934 */ 959 */
935 cycle_time = __DDR4_VALUE(tCKAVGmin); 960 cycle_time = __DDR4_VALUE(tCKAVGmin);
936 decode_size_speed(self, node, dimm_size, cycle_time, 2, 961 decode_size_speed(self, node, dimm_size, cycle_time, 2,
937 1 << (s->sm_ddr4.ddr4_primary_bus_width + 3), 962 1 << (s->sm_ddr4.ddr4_primary_bus_width + 3),
938 TRUE, "PC4", 0); 963 TRUE, "PC4", 0);
939 964
940 ranks = s->sm_ddr4.ddr4_package_ranks + 1; 965 ranks = s->sm_ddr4.ddr4_package_ranks + 1;
941 aprint_verbose_dev(self, 966 aprint_verbose_dev(self,
942 "%d rows, %d cols, %d ranks%s, %d banks/group, %d bank groups\n", 967 "%d rows, %d cols, %d ranks%s, %d banks/group, %d bank groups\n",
943 s->sm_ddr4.ddr4_rows + 12, s->sm_ddr4.ddr4_cols + 9, 968 s->sm_ddr4.ddr4_rows + 12, s->sm_ddr4.ddr4_cols + 9,
944 ranks, (ranks > 1) ? ((s->sm_ddr4.ddr4_rank_mix == 1) 969 ranks, (ranks > 1) ? ((s->sm_ddr4.ddr4_rank_mix == 1)
945 ? " (asymmetric)" : " (symmetiric)") : "", 970 ? " (asymmetric)" : " (symmetric)") : "",
946 1 << (2 + s->sm_ddr4.ddr4_logbanks), 971 1 << (2 + s->sm_ddr4.ddr4_logbanks),
947 1 << s->sm_ddr4.ddr4_bankgroups); 972 1 << s->sm_ddr4.ddr4_bankgroups);
948 973
949 aprint_verbose_dev(self, "%d.%03dns cycle time\n", 974 aprint_verbose_dev(self, "%d.%03dns cycle time\n",
950 cycle_time / 1000, cycle_time % 1000); 975 cycle_time / 1000, cycle_time % 1000);
951 976
952 tAA_clocks = __DDR4_VALUE(tAAmin) * 1000 / cycle_time; 977 tAA_clocks = __DDR4_VALUE(tAAmin) * 1000 / cycle_time;
953 tRCD_clocks = __DDR4_VALUE(tRCDmin) * 1000 / cycle_time; 978 tRCD_clocks = __DDR4_VALUE(tRCDmin) * 1000 / cycle_time;
954 tRP_clocks = __DDR4_VALUE(tRPmin) * 1000 / cycle_time; 979 tRP_clocks = __DDR4_VALUE(tRPmin) * 1000 / cycle_time;
955 tRAS_clocks = (s->sm_ddr4.ddr4_tRASmin_msb * 256 + 980 tRAS_clocks = (s->sm_ddr4.ddr4_tRASmin_msb * 256 +
956 s->sm_ddr4.ddr4_tRASmin_lsb) * 125 * 1000 / cycle_time; 981 s->sm_ddr4.ddr4_tRASmin_lsb) * 125 * 1000 / cycle_time;
957 982
958/* 983/*

cvs diff -r1.13.6.1 -r1.13.6.2 src/sys/dev/ic/spdmemvar.h (expand / switch to unified diff)

--- src/sys/dev/ic/spdmemvar.h 2019/01/03 11:23:54 1.13.6.1
+++ src/sys/dev/ic/spdmemvar.h 2020/04/14 17:39:28 1.13.6.2
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: spdmemvar.h,v 1.13.6.1 2019/01/03 11:23:54 martin Exp $ */ 1/* $NetBSD: spdmemvar.h,v 1.13.6.2 2020/04/14 17:39:28 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2007 Paul Goyette 4 * Copyright (c) 2007 Paul Goyette
5 * Copyright (c) 2007 Tobias Nygren 5 * Copyright (c) 2007 Tobias Nygren
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -453,66 +453,73 @@ struct spdmem_ddr3 { /* Dual Data Rat @@ -453,66 +453,73 @@ struct spdmem_ddr3 { /* Dual Data Rat
453 /* datawidth in bits offset by 3: 1 = 16b, 2 = 32b, 3 = 64b */ 453 /* datawidth in bits offset by 3: 1 = 16b, 2 = 32b, 3 = 64b */
454 SPD_BITFIELD( \ 454 SPD_BITFIELD( \
455 uint8_t ddr3_datawidth:3, \ 455 uint8_t ddr3_datawidth:3, \
456 uint8_t ddr3_hasECC:2, \ 456 uint8_t ddr3_hasECC:2, \
457 uint8_t ddr3_unused2a:3 , \ 457 uint8_t ddr3_unused2a:3 , \
458 ); 458 );
459 /* Fine time base, in pico-seconds */ 459 /* Fine time base, in pico-seconds */
460 SPD_BITFIELD( \ 460 SPD_BITFIELD( \
461 uint8_t ddr3_ftb_divisor:4, \ 461 uint8_t ddr3_ftb_divisor:4, \
462 uint8_t ddr3_ftb_dividend:4, , \ 462 uint8_t ddr3_ftb_dividend:4, , \
463 ); 463 );
464 uint8_t ddr3_mtb_dividend; /* 0x0108 = 0.1250ns */ 464 uint8_t ddr3_mtb_dividend; /* 0x0108 = 0.1250ns */
465 uint8_t ddr3_mtb_divisor; /* 0x010f = 0.0625ns */ 465 uint8_t ddr3_mtb_divisor; /* 0x010f = 0.0625ns */
466 uint8_t ddr3_tCKmin; /* in terms of mtb */ 466 uint8_t ddr3_tCKmin_mtb;
467 uint8_t ddr3_unused3; 467 uint8_t ddr3_unused3;
468 uint16_t ddr3_CAS_sup; /* Bit 0 ==> CAS 4 cycles */ 468 uint16_t ddr3_CAS_sup; /* Bit 0 ==> CAS 4 cycles */
469 uint8_t ddr3_tAAmin; /* in terms of mtb */ 469 uint8_t ddr3_tAAmin_mtb;
470 uint8_t ddr3_tWRmin; 470 uint8_t ddr3_tWRmin;
471 uint8_t ddr3_tRCDmin; 471 uint8_t ddr3_tRCDmin_mtb;
472 uint8_t ddr3_tRRDmin; 472 uint8_t ddr3_tRRDmin;
473 uint8_t ddr3_tRPmin; 473 uint8_t ddr3_tRPmin_mtb;
474 SPD_BITFIELD( \ 474 SPD_BITFIELD( \
475 uint8_t ddr3_tRAS_msb:4, \ 475 uint8_t ddr3_tRAS_msb:4, \
476 uint8_t ddr3_tRC_msb:4, , \ 476 uint8_t ddr3_tRCmin_mtb_msb:4, , \
477 ); 477 );
478 uint8_t ddr3_tRAS_lsb; 478 uint8_t ddr3_tRAS_lsb;
479 uint8_t ddr3_tRC_lsb; 479 uint8_t ddr3_tRCmin_mtb_lsb;
480 uint8_t ddr3_tRFCmin_lsb; 480 uint8_t ddr3_tRFCmin_lsb;
481 uint8_t ddr3_tRFCmin_msb; 481 uint8_t ddr3_tRFCmin_msb;
482 uint8_t ddr3_tWTRmin; 482 uint8_t ddr3_tWTRmin;
483 uint8_t ddr3_tRTPmin; 483 uint8_t ddr3_tRTPmin;
484 SPD_BITFIELD( \ 484 SPD_BITFIELD( \
485 uint8_t ddr3_tFAW_msb:4, , , \ 485 uint8_t ddr3_tFAW_msb:4, , , \
486 ); 486 );
487 uint8_t ddr3_tFAW_lsb; 487 uint8_t ddr3_tFAW_lsb;
488 uint8_t ddr3_output_drvrs; 488 uint8_t ddr3_output_drvrs;
489 SPD_BITFIELD( \ 489 SPD_BITFIELD( \
490 uint8_t ddr3_ext_temp_range:1, \ 490 uint8_t ddr3_ext_temp_range:1, \
491 uint8_t ddr3_ext_temp_2x_refresh:1, \ 491 uint8_t ddr3_ext_temp_2x_refresh:1, \
492 uint8_t ddr3_asr_refresh:1, \ 492 uint8_t ddr3_asr_refresh:1, \
493 /* Bit 4 indicates on-die thermal sensor */ 493 /* Bit 4 indicates on-die thermal sensor */
494 /* Bit 7 indicates Partial-Array Self-Refresh (PASR) */ 494 /* Bit 7 indicates Partial-Array Self-Refresh (PASR) */
495 uint8_t ddr3_unused7:5 \ 495 uint8_t ddr3_unused7:5 \
496 ); 496 );
497 SPD_BITFIELD( \ 497 SPD_BITFIELD( \
498 uint8_t ddr3_therm_sensor_acc:7,\ 498 uint8_t ddr3_therm_sensor_acc:7,\
499 uint8_t ddr3_has_therm_sensor:1, , \ 499 uint8_t ddr3_has_therm_sensor:1, , \
500 ); 500 );
501 SPD_BITFIELD( \ 501 SPD_BITFIELD( \
502 uint8_t ddr3_non_std_devtype:7, \ 502 uint8_t ddr3_non_std_devtype:7, \
503 uint8_t ddr3_std_device:1, , \ 503 uint8_t ddr3_std_device:1, , \
504 ); 504 );
505 uint8_t ddr3_unused4[26]; 505 uint8_t ddr3_tCKmin_ftb;
 506 uint8_t ddr3_tAAmin_ftb;
 507 uint8_t ddr3_tRCDmin_ftb;
 508 uint8_t ddr3_tRPmin_ftb;
 509 uint8_t ddr3_tRCmin_ftb;
 510 uint8_t ddr3_unused4[2];
 511 uint8_t ddr3_MAC;
 512 uint8_t ddr3_unused4a[18];
506 uint8_t ddr3_mod_height; 513 uint8_t ddr3_mod_height;
507 uint8_t ddr3_mod_thickness; 514 uint8_t ddr3_mod_thickness;
508 uint8_t ddr3_ref_card; 515 uint8_t ddr3_ref_card;
509 uint8_t ddr3_mapping; 516 uint8_t ddr3_mapping;
510 uint8_t ddr3_unused5[53]; 517 uint8_t ddr3_unused5[53];
511 uint8_t ddr3_mfgID_lsb; 518 uint8_t ddr3_mfgID_lsb;
512 uint8_t ddr3_mfgID_msb; 519 uint8_t ddr3_mfgID_msb;
513 uint8_t ddr3_mfgloc; 520 uint8_t ddr3_mfgloc;
514 uint8_t ddr3_mfg_year; 521 uint8_t ddr3_mfg_year;
515 uint8_t ddr3_mfg_week; 522 uint8_t ddr3_mfg_week;
516 uint8_t ddr3_serial[4]; 523 uint8_t ddr3_serial[4];
517 uint16_t ddr3_crc; 524 uint16_t ddr3_crc;
518 uint8_t ddr3_part[18]; 525 uint8_t ddr3_part[18];