summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/man/man4d/amdzen.4d12
-rw-r--r--usr/src/pkg/manifests/driver-cpu-amd-zen.p5m44
-rw-r--r--usr/src/uts/intel/io/amdzen/amdzen.c24
-rw-r--r--usr/src/uts/intel/io/amdzen/zen_umc.c110
-rw-r--r--usr/src/uts/intel/sys/amdzen/df.h4
5 files changed, 135 insertions, 59 deletions
diff --git a/usr/src/man/man4d/amdzen.4d b/usr/src/man/man4d/amdzen.4d
index 7d17a6a9d4..e8ee713c85 100644
--- a/usr/src/man/man4d/amdzen.4d
+++ b/usr/src/man/man4d/amdzen.4d
@@ -9,9 +9,9 @@
.\" http://www.illumos.org/license/CDDL.
.\"
.\"
-.\" Copyright 2021 Oxide Computer Company
+.\" Copyright 2022 Oxide Computer Company
.\"
-.Dd September 26, 2020
+.Dd August 6, 2022
.Dt AMDZEN 4D
.Os
.Sh NAME
@@ -34,11 +34,17 @@ AMD Zen Naples, Summit Ridge, Whitehaven
AMD Zen+ Colfax, Picasso, and Pinnacle Ridge
.Pq Family 17h
.It
-AMD Zen 2 Castle Peak, Matisse, Rome, and Renoir
+AMD Zen 2 Castle Peak, Matisse, Mendocino, Rome, Renoir, and Van Gogh
.Pq Family 17h
.It
AMD Zen 3 Cezanne, Milan, and Vermeer
.Pq Family 19h
+.It
+AMD Zen 3+ Rembrandt
+.Pq Family 19h
+.It
+AMD Zen 4 Genoa and Raphael
+.Pq Family 19h
.El
.Pp
This driver is a nexus driver and facilitates access to the northbridge,
diff --git a/usr/src/pkg/manifests/driver-cpu-amd-zen.p5m b/usr/src/pkg/manifests/driver-cpu-amd-zen.p5m
index 1fcd24c4bf..9bfbbf04ba 100644
--- a/usr/src/pkg/manifests/driver-cpu-amd-zen.p5m
+++ b/usr/src/pkg/manifests/driver-cpu-amd-zen.p5m
@@ -38,11 +38,18 @@ driver name=amdzen
# 1460-1467: f17h m00-0f df
# 1480: f17h m30-3f/70-7f, f19h m00-0f, m20-2f nb
# 1490-1497: f17h m30-3f df
+# 14a4: f19h m10-1f nb
+# 14ad-14b4: f19h m10-1fh df
+# 14b5: f17h ma0-af, f19h m40-4f nb
+# 14d8: f19h m60-6f nb
+# 14e0-14e7: f19h m60-6f df
# 15d0: f17h m10-m2f nb
# 15e8-15ef: f17h m10-m2f df
# 1630: f17h m60-6f, f19h m50-5f nb
# 1650-1657: f19h m00-0f df
# 166a-1671: f19h m50-5f df
+# 1679-1680: f19h m40-4f df
+# 1724-172b: f17h ma0-af df
#
driver name=amdzen_stub \
alias=pci1022,1440,p \
@@ -79,6 +86,25 @@ driver name=amdzen_stub \
alias=pci1022,1495,p \
alias=pci1022,1496,p \
alias=pci1022,1497,p \
+ alias=pci1022,14a4,p \
+ alias=pci1022,14ad,p \
+ alias=pci1022,14ae,p \
+ alias=pci1022,14af,p \
+ alias=pci1022,14b0,p \
+ alias=pci1022,14b1,p \
+ alias=pci1022,14b2,p \
+ alias=pci1022,14b3,p \
+ alias=pci1022,14b4,p \
+ alias=pci1022,14b5,p \
+ alias=pci1022,14d8,p \
+ alias=pci1022,14e0,p \
+ alias=pci1022,14e1,p \
+ alias=pci1022,14e2,p \
+ alias=pci1022,14e3,p \
+ alias=pci1022,14e4,p \
+ alias=pci1022,14e5,p \
+ alias=pci1022,14e6,p \
+ alias=pci1022,14e7,p \
alias=pci1022,15d0,p \
alias=pci1022,15e8,p \
alias=pci1022,15e9,p \
@@ -104,6 +130,22 @@ driver name=amdzen_stub \
alias=pci1022,166e,p \
alias=pci1022,166f,p \
alias=pci1022,1670,p \
- alias=pci1022,1671,p
+ alias=pci1022,1671,p \
+ alias=pci1022,1679,p \
+ alias=pci1022,167a,p \
+ alias=pci1022,167b,p \
+ alias=pci1022,167c,p \
+ alias=pci1022,167d,p \
+ alias=pci1022,167e,p \
+ alias=pci1022,167f,p \
+ alias=pci1022,1680,p \
+ alias=pci1022,1724,p \
+ alias=pci1022,1725,p \
+ alias=pci1022,1726,p \
+ alias=pci1022,1727,p \
+ alias=pci1022,1728,p \
+ alias=pci1022,1729,p \
+ alias=pci1022,172a,p \
+ alias=pci1022,172b,p
driver name=zen_umc
license lic_CDDL license=lic_CDDL
diff --git a/usr/src/uts/intel/io/amdzen/amdzen.c b/usr/src/uts/intel/io/amdzen/amdzen.c
index f6ba32d968..8f430a6f6a 100644
--- a/usr/src/uts/intel/io/amdzen/amdzen.c
+++ b/usr/src/uts/intel/io/amdzen/amdzen.c
@@ -171,8 +171,14 @@ static const uint16_t amdzen_nb_ids[] = {
0x15d0,
/* Family 17h/19h Rome, Milan, Matisse, Vermeer Zen 2/Zen 3 uarch */
0x1480,
- /* Family 17h/19h Renoir, Cezanne Zen 2/3 uarch) */
- 0x1630
+ /* Family 17h/19h Renoir, Cezanne, Van Gogh Zen 2/3 uarch */
+ 0x1630,
+ /* Family 19h Genoa */
+ 0x14a4,
+ /* Family 17h Mendocino, Family 19h Rembrandt */
+ 0x14b5,
+ /* Family 19h Raphael */
+ 0x14d8
};
typedef struct {
@@ -487,17 +493,13 @@ amdzen_c_df_iter(uint_t dfno, zen_df_type_t type, amdzen_c_iter_f func,
}
break;
case ZEN_DF_TYPE_CCM_CPU:
- df_type = DF_TYPE_CCM;
/*
- * In the Genoa/DFv4 timeframe, with the introduction of CXL and
- * related, a subtype was added here where as previously it was
- * always zero.
+ * While the wording of the PPR is a little weird, the CCM still
+ * has subtype 0 in DFv4 systems; however, what's said to be for
+ * the CPU appears to apply to the ACM.
*/
- if (df->adf_major >= 4) {
- df_subtype = DF_CCM_SUBTYPE_CPU;
- } else {
- df_subtype = 0;
- }
+ df_type = DF_TYPE_CCM;
+ df_subtype = 0;
break;
default:
return (EINVAL);
diff --git a/usr/src/uts/intel/io/amdzen/zen_umc.c b/usr/src/uts/intel/io/amdzen/zen_umc.c
index ed10a1e50b..947c17b4ff 100644
--- a/usr/src/uts/intel/io/amdzen/zen_umc.c
+++ b/usr/src/uts/intel/io/amdzen/zen_umc.c
@@ -1840,6 +1840,71 @@ zen_umc_fill_ccm_cb(const uint_t dfno, const uint32_t fabid,
}
/*
+ * This is used to fill in the common properties about a DIMM. This should occur
+ * after the rank information has been filled out. The information used is the
+ * same between DDR4 and DDR5 DIMMs. The only major difference is the register
+ * offset.
+ */
+static boolean_t
+zen_umc_fill_dimm_common(zen_umc_t *umc, zen_umc_df_t *df, zen_umc_chan_t *chan,
+ const uint_t dimmno, boolean_t ddr4)
+{
+ umc_dimm_t *dimm;
+ int ret;
+ smn_reg_t reg;
+ uint32_t val;
+ const uint32_t id = chan->chan_logid;
+
+ dimm = &chan->chan_dimms[dimmno];
+ dimm->ud_dimmno = dimmno;
+
+ if (ddr4) {
+ reg = UMC_DIMMCFG_DDR4(id, dimmno);
+ } else {
+ reg = UMC_DIMMCFG_DDR5(id, dimmno);
+ }
+ if ((ret = amdzen_c_smn_read32(df->zud_dfno, reg, &val)) != 0) {
+ dev_err(umc->umc_dip, CE_WARN, "failed to read DIMM "
+ "configuration register %x: %d", SMN_REG_ADDR(reg), ret);
+ return (B_FALSE);
+ }
+ dimm->ud_dimmcfg_raw = val;
+
+ if (UMC_DIMMCFG_GET_X16(val) != 0) {
+ dimm->ud_width = UMC_DIMM_W_X16;
+ } else if (UMC_DIMMCFG_GET_X4(val) != 0) {
+ dimm->ud_width = UMC_DIMM_W_X4;
+ } else {
+ dimm->ud_width = UMC_DIMM_W_X8;
+ }
+
+ if (UMC_DIMMCFG_GET_3DS(val) != 0) {
+ dimm->ud_kind = UMC_DIMM_K_3DS_RDIMM;
+ } else if (UMC_DIMMCFG_GET_LRDIMM(val) != 0) {
+ dimm->ud_kind = UMC_DIMM_K_LRDIMM;
+ } else if (UMC_DIMMCFG_GET_RDIMM(val) != 0) {
+ dimm->ud_kind = UMC_DIMM_K_RDIMM;
+ } else {
+ dimm->ud_kind = UMC_DIMM_K_UDIMM;
+ }
+
+ /*
+ * DIMM information in a UMC can be somewhat confusing. There are quite
+ * a number of non-zero reset values that are here. Flag whether or not
+ * we think this entry should be usable based on enabled chip-selects.
+ */
+ for (uint_t i = 0; i < ZEN_UMC_MAX_CHAN_BASE; i++) {
+ if (dimm->ud_cs[i].ucs_base.udb_valid ||
+ dimm->ud_cs[i].ucs_sec.udb_valid) {
+ dimm->ud_flags |= UMC_DIMM_F_VALID;
+ break;
+ }
+ }
+
+ return (B_TRUE);
+}
+
+/*
* Fill all the information about a DDR4 DIMM. In the DDR4 UMC, some of this
* information is on a per-chip select basis while at other times it is on a
* per-DIMM basis. In general, chip-selects 0/1 correspond to DIMM 0, and
@@ -1861,7 +1926,6 @@ zen_umc_fill_chan_dimm_ddr4(zen_umc_t *umc, zen_umc_df_t *df,
ASSERT3U(dimmno, <, ZEN_UMC_MAX_DIMMS);
dimm = &chan->chan_dimms[dimmno];
- dimm->ud_dimmno = dimmno;
cs0 = &dimm->ud_cs[0];
cs1 = &dimm->ud_cs[1];
@@ -2049,46 +2113,7 @@ zen_umc_fill_chan_dimm_ddr4(zen_umc_t *umc, zen_umc_df_t *df,
bcopy(cs0->ucs_rm_bits_sec, cs1->ucs_rm_bits_sec,
sizeof (cs0->ucs_rm_bits_sec));
- reg = UMC_DIMMCFG_DDR4(id, dimmno);
- if ((ret = amdzen_c_smn_read32(df->zud_dfno, reg, &val)) != 0) {
- dev_err(umc->umc_dip, CE_WARN, "failed to read DIMM "
- "configuration register %x: %d", SMN_REG_ADDR(reg), ret);
- return (B_FALSE);
- }
- dimm->ud_dimmcfg_raw = val;
-
- if (UMC_DIMMCFG_GET_X16(val) != 0) {
- dimm->ud_width = UMC_DIMM_W_X16;
- } else if (UMC_DIMMCFG_GET_X4(val) != 0) {
- dimm->ud_width = UMC_DIMM_W_X4;
- } else {
- dimm->ud_width = UMC_DIMM_W_X8;
- }
-
- if (UMC_DIMMCFG_GET_3DS(val) != 0) {
- dimm->ud_kind = UMC_DIMM_K_3DS_RDIMM;
- } else if (UMC_DIMMCFG_GET_LRDIMM(val) != 0) {
- dimm->ud_kind = UMC_DIMM_K_LRDIMM;
- } else if (UMC_DIMMCFG_GET_RDIMM(val) != 0) {
- dimm->ud_kind = UMC_DIMM_K_RDIMM;
- } else {
- dimm->ud_kind = UMC_DIMM_K_UDIMM;
- }
-
- /*
- * DIMM information in a UMC can be somewhat confusing. There are quite
- * a number of non-zero reset values that are here. Flag whether or not
- * we think this entry should be usable based on enabled chip-selects.
- */
- for (uint_t i = 0; i < ZEN_UMC_MAX_CHAN_BASE; i++) {
- if (dimm->ud_cs[i].ucs_base.udb_valid ||
- dimm->ud_cs[i].ucs_sec.udb_valid) {
- dimm->ud_flags |= UMC_DIMM_F_VALID;
- break;
- }
- }
-
- return (B_TRUE);
+ return (zen_umc_fill_dimm_common(umc, df, chan, dimmno, B_TRUE));
}
/*
@@ -2309,9 +2334,10 @@ zen_umc_fill_chan_rank_ddr5(zen_umc_t *umc, zen_umc_df_t *df,
bcopy(cs->ucs_rm_bits, cs->ucs_rm_bits_sec,
sizeof (cs->ucs_rm_bits));
- return (B_TRUE);
+ return (zen_umc_fill_dimm_common(umc, df, chan, dimmno, B_FALSE));
}
+
static void
zen_umc_fill_ddr_type(zen_umc_chan_t *chan, boolean_t ddr4)
{
diff --git a/usr/src/uts/intel/sys/amdzen/df.h b/usr/src/uts/intel/sys/amdzen/df.h
index 6c1e5b5c79..9e165a3db5 100644
--- a/usr/src/uts/intel/sys/amdzen/df.h
+++ b/usr/src/uts/intel/sys/amdzen/df.h
@@ -147,8 +147,8 @@ typedef enum {
* always zero.
*/
typedef enum {
- DF_CCM_SUBTYPE_CPU = 1,
- DF_CCM_SUBTYPE_ACM = 2
+ DF_CCM_SUBTYPE_CPU = 0,
+ DF_CCM_SUBTYPE_ACM = 1
} df_ccm_subtype_v4_t;
#define DF_FBIINFO0_GET_HAS_MCA(r) bitx32(r, 23, 23)
#define DF_FBIINFO0_GET_FTI_DCNT(r) bitx32(r, 21, 20)