]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
perf/x86/intel/uncore: Add IMH PMON support for Diamond Rapids
authorZide Chen <zide.chen@intel.com>
Wed, 31 Dec 2025 22:42:21 +0000 (14:42 -0800)
committerPeter Zijlstra <peterz@infradead.org>
Tue, 6 Jan 2026 15:34:24 +0000 (16:34 +0100)
DMR supports IMH PMON units for PCU, UBox, iMC, and CXL:
- PCU and UBox are same with SPR.
- iMC is similar to SPR but uses different offsets for fixed registers.
- CXL introduces a new port_enable field and changes the position of
  the threshold field.

DMR also introduces additional PMON units: SCA, HAMVF, D2D_ULA, UBR,
PCIE4, CRS, CPC, ITC, OTC, CMS, and PCIE6.  Among these, PCIE4 and
PCIE6 use different unit types, but share the same config register
layout, and the generic PCIe PMON events apply to both.

Additionally, ignore the broken MSE unit.

Signed-off-by: Zide Chen <zide.chen@intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20251231224233.113839-5-zide.chen@intel.com
arch/x86/events/intel/uncore.c
arch/x86/events/intel/uncore.h
arch/x86/events/intel/uncore_discovery.h
arch/x86/events/intel/uncore_snbep.c

index 2387b1a80ca05ceb3e6a08abceb324a3ba9f8a8f..40cf9bf79b81413879ac63dabd78a9639a0cef1c 100644 (file)
@@ -1831,6 +1831,14 @@ static const struct uncore_plat_init gnr_uncore_init __initconst = {
        .domain[0].units_ignore = gnr_uncore_units_ignore,
 };
 
+static const struct uncore_plat_init dmr_uncore_init __initconst = {
+       .pci_init = dmr_uncore_pci_init,
+       .mmio_init = dmr_uncore_mmio_init,
+       .domain[0].base_is_pci = true,
+       .domain[0].discovery_base = DMR_UNCORE_DISCOVERY_TABLE_DEVICE,
+       .domain[0].units_ignore = dmr_uncore_imh_units_ignore,
+};
+
 static const struct uncore_plat_init generic_uncore_init __initconst = {
        .cpu_init = intel_uncore_generic_uncore_cpu_init,
        .pci_init = intel_uncore_generic_uncore_pci_init,
@@ -1898,6 +1906,7 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
        X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X,   &gnr_uncore_init),
        X86_MATCH_VFM(INTEL_ATOM_CRESTMONT,     &gnr_uncore_init),
        X86_MATCH_VFM(INTEL_ATOM_DARKMONT_X,    &gnr_uncore_init),
+       X86_MATCH_VFM(INTEL_DIAMONDRAPIDS_X,    &dmr_uncore_init),
        {},
 };
 MODULE_DEVICE_TABLE(x86cpu, intel_uncore_match);
index 1574ffc7ee053021cb9509538cfb537ac276a27b..1e4b3a22403c5dbe30d7b95a1c68be87e7f29aa0 100644 (file)
@@ -614,6 +614,7 @@ extern struct pci_extra_dev *uncore_extra_pci_dev;
 extern struct event_constraint uncore_constraint_empty;
 extern int spr_uncore_units_ignore[];
 extern int gnr_uncore_units_ignore[];
+extern int dmr_uncore_imh_units_ignore[];
 
 /* uncore_snb.c */
 int snb_uncore_pci_init(void);
@@ -662,6 +663,8 @@ void spr_uncore_mmio_init(void);
 int gnr_uncore_pci_init(void);
 void gnr_uncore_cpu_init(void);
 void gnr_uncore_mmio_init(void);
+int dmr_uncore_pci_init(void);
+void dmr_uncore_mmio_init(void);
 
 /* uncore_nhmex.c */
 void nhmex_uncore_cpu_init(void);
index dfc237a2b6dfc792fd012fe3bbcfc20cc1703ab1..618788c30ac62ea123431f68723ff8cc6240d5c8 100644 (file)
@@ -5,6 +5,8 @@
 
 /* Generic device ID of a discovery table device */
 #define UNCORE_DISCOVERY_TABLE_DEVICE          0x09a7
+/* Device ID used on DMR */
+#define DMR_UNCORE_DISCOVERY_TABLE_DEVICE      0x09a1
 /* Capability ID for a discovery table device */
 #define UNCORE_EXT_CAP_ID_DISCOVERY            0x23
 /* First DVSEC offset */
index e1f370b8d065f9ffffd27a8fc0b5200a8fe68c83..4b72560dc13ff73ca711c3de4eb2b62244f84d06 100644 (file)
 
 #define SPR_C0_MSR_PMON_BOX_FILTER0            0x200e
 
+/* DMR */
+#define DMR_CXLCM_EVENT_MASK_EXT               0xf
+#define DMR_HAMVF_EVENT_MASK_EXT               0xffffffff
+#define DMR_PCIE4_EVENT_MASK_EXT               0xffffff
+
+#define DMR_IMC_PMON_FIXED_CTR                 0x18
+#define DMR_IMC_PMON_FIXED_CTL                 0x10
+
 DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
 DEFINE_UNCORE_FORMAT_ATTR(event2, event, "config:0-6");
 DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21");
@@ -486,6 +494,10 @@ DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
 DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19");
 DEFINE_UNCORE_FORMAT_ATTR(tid_en2, tid_en, "config:16");
 DEFINE_UNCORE_FORMAT_ATTR(inv, inv, "config:23");
+DEFINE_UNCORE_FORMAT_ATTR(inv2, inv, "config:21");
+DEFINE_UNCORE_FORMAT_ATTR(thresh_ext, thresh_ext, "config:32-35");
+DEFINE_UNCORE_FORMAT_ATTR(thresh10, thresh, "config:23-32");
+DEFINE_UNCORE_FORMAT_ATTR(thresh9_2, thresh, "config:23-31");
 DEFINE_UNCORE_FORMAT_ATTR(thresh9, thresh, "config:24-35");
 DEFINE_UNCORE_FORMAT_ATTR(thresh8, thresh, "config:24-31");
 DEFINE_UNCORE_FORMAT_ATTR(thresh6, thresh, "config:24-29");
@@ -494,6 +506,13 @@ DEFINE_UNCORE_FORMAT_ATTR(occ_sel, occ_sel, "config:14-15");
 DEFINE_UNCORE_FORMAT_ATTR(occ_invert, occ_invert, "config:30");
 DEFINE_UNCORE_FORMAT_ATTR(occ_edge, occ_edge, "config:14-51");
 DEFINE_UNCORE_FORMAT_ATTR(occ_edge_det, occ_edge_det, "config:31");
+DEFINE_UNCORE_FORMAT_ATTR(port_en, port_en, "config:32-35");
+DEFINE_UNCORE_FORMAT_ATTR(rs3_sel, rs3_sel, "config:36");
+DEFINE_UNCORE_FORMAT_ATTR(rx_sel, rx_sel, "config:37");
+DEFINE_UNCORE_FORMAT_ATTR(tx_sel, tx_sel, "config:38");
+DEFINE_UNCORE_FORMAT_ATTR(iep_sel, iep_sel, "config:39");
+DEFINE_UNCORE_FORMAT_ATTR(vc_sel, vc_sel, "config:40-47");
+DEFINE_UNCORE_FORMAT_ATTR(port_sel, port_sel, "config:48-55");
 DEFINE_UNCORE_FORMAT_ATTR(ch_mask, ch_mask, "config:36-43");
 DEFINE_UNCORE_FORMAT_ATTR(ch_mask2, ch_mask, "config:36-47");
 DEFINE_UNCORE_FORMAT_ATTR(fc_mask, fc_mask, "config:44-46");
@@ -6709,3 +6728,213 @@ void gnr_uncore_mmio_init(void)
 }
 
 /* end of GNR uncore support */
+
+/* DMR uncore support */
+#define UNCORE_DMR_NUM_UNCORE_TYPES    52
+
+static struct attribute *dmr_imc_uncore_formats_attr[] = {
+       &format_attr_event.attr,
+       &format_attr_umask.attr,
+       &format_attr_edge.attr,
+       &format_attr_inv.attr,
+       &format_attr_thresh10.attr,
+       NULL,
+};
+
+static const struct attribute_group dmr_imc_uncore_format_group = {
+       .name = "format",
+       .attrs = dmr_imc_uncore_formats_attr,
+};
+
+static struct intel_uncore_type dmr_uncore_imc = {
+       .name                   = "imc",
+       .fixed_ctr_bits         = 48,
+       .fixed_ctr              = DMR_IMC_PMON_FIXED_CTR,
+       .fixed_ctl              = DMR_IMC_PMON_FIXED_CTL,
+       .ops                    = &spr_uncore_mmio_ops,
+       .format_group           = &dmr_imc_uncore_format_group,
+       .attr_update            = uncore_alias_groups,
+};
+
+static struct attribute *dmr_sca_uncore_formats_attr[] = {
+       &format_attr_event.attr,
+       &format_attr_umask_ext5.attr,
+       &format_attr_edge.attr,
+       &format_attr_inv.attr,
+       &format_attr_thresh8.attr,
+       NULL,
+};
+
+static const struct attribute_group dmr_sca_uncore_format_group = {
+       .name = "format",
+       .attrs = dmr_sca_uncore_formats_attr,
+};
+
+static struct intel_uncore_type dmr_uncore_sca = {
+       .name                   = "sca",
+       .event_mask_ext         = DMR_HAMVF_EVENT_MASK_EXT,
+       .format_group           = &dmr_sca_uncore_format_group,
+       .attr_update            = uncore_alias_groups,
+};
+
+static struct attribute *dmr_cxlcm_uncore_formats_attr[] = {
+       &format_attr_event.attr,
+       &format_attr_umask.attr,
+       &format_attr_edge.attr,
+       &format_attr_inv2.attr,
+       &format_attr_thresh9_2.attr,
+       &format_attr_port_en.attr,
+       NULL,
+};
+
+static const struct attribute_group dmr_cxlcm_uncore_format_group = {
+       .name = "format",
+       .attrs = dmr_cxlcm_uncore_formats_attr,
+};
+
+static struct intel_uncore_type dmr_uncore_cxlcm = {
+       .name                   = "cxlcm",
+       .event_mask             = GENERIC_PMON_RAW_EVENT_MASK,
+       .event_mask_ext         = DMR_CXLCM_EVENT_MASK_EXT,
+       .format_group           = &dmr_cxlcm_uncore_format_group,
+       .attr_update            = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_hamvf = {
+       .name                   = "hamvf",
+       .event_mask_ext         = DMR_HAMVF_EVENT_MASK_EXT,
+       .format_group           = &dmr_sca_uncore_format_group,
+       .attr_update            = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_ula = {
+       .name                   = "ula",
+       .event_mask_ext         = DMR_HAMVF_EVENT_MASK_EXT,
+       .format_group           = &dmr_sca_uncore_format_group,
+       .attr_update            = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_ubr = {
+       .name                   = "ubr",
+       .event_mask_ext         = DMR_HAMVF_EVENT_MASK_EXT,
+       .format_group           = &dmr_sca_uncore_format_group,
+       .attr_update            = uncore_alias_groups,
+};
+
+static struct attribute *dmr_pcie4_uncore_formats_attr[] = {
+       &format_attr_event.attr,
+       &format_attr_umask.attr,
+       &format_attr_edge.attr,
+       &format_attr_inv.attr,
+       &format_attr_thresh8.attr,
+       &format_attr_thresh_ext.attr,
+       &format_attr_rs3_sel.attr,
+       &format_attr_rx_sel.attr,
+       &format_attr_tx_sel.attr,
+       &format_attr_iep_sel.attr,
+       &format_attr_vc_sel.attr,
+       &format_attr_port_sel.attr,
+       NULL,
+};
+
+static const struct attribute_group dmr_pcie4_uncore_format_group = {
+       .name = "format",
+       .attrs = dmr_pcie4_uncore_formats_attr,
+};
+
+static struct intel_uncore_type dmr_uncore_pcie4 = {
+       .name                   = "pcie4",
+       .event_mask_ext         = DMR_PCIE4_EVENT_MASK_EXT,
+       .format_group           = &dmr_pcie4_uncore_format_group,
+       .attr_update            = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_crs = {
+       .name                   = "crs",
+       .attr_update            = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_cpc = {
+       .name                   = "cpc",
+       .event_mask_ext         = DMR_HAMVF_EVENT_MASK_EXT,
+       .format_group           = &dmr_sca_uncore_format_group,
+       .attr_update            = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_itc = {
+       .name                   = "itc",
+       .event_mask_ext         = DMR_HAMVF_EVENT_MASK_EXT,
+       .format_group           = &dmr_sca_uncore_format_group,
+       .attr_update            = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_otc = {
+       .name                   = "otc",
+       .event_mask_ext         = DMR_HAMVF_EVENT_MASK_EXT,
+       .format_group           = &dmr_sca_uncore_format_group,
+       .attr_update            = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_cms = {
+       .name                   = "cms",
+       .attr_update            = uncore_alias_groups,
+};
+
+static struct intel_uncore_type dmr_uncore_pcie6 = {
+       .name                   = "pcie6",
+       .event_mask_ext         = DMR_PCIE4_EVENT_MASK_EXT,
+       .format_group           = &dmr_pcie4_uncore_format_group,
+       .attr_update            = uncore_alias_groups,
+};
+
+static struct intel_uncore_type *dmr_uncores[UNCORE_DMR_NUM_UNCORE_TYPES] = {
+       NULL, NULL, NULL, NULL,
+       &spr_uncore_pcu,
+       &gnr_uncore_ubox,
+       &dmr_uncore_imc,
+       NULL,
+       NULL, NULL, NULL, NULL,
+       NULL, NULL, NULL, NULL,
+       NULL, NULL, NULL, NULL,
+       NULL, NULL, NULL,
+       &dmr_uncore_sca,
+       &dmr_uncore_cxlcm,
+       NULL, NULL, NULL,
+       NULL, NULL,
+       &dmr_uncore_hamvf,
+       NULL,
+       NULL, NULL, NULL,
+       &dmr_uncore_ula,
+       NULL, NULL, NULL, NULL,
+       NULL, NULL, NULL,
+       &dmr_uncore_ubr,
+       NULL,
+       &dmr_uncore_pcie4,
+       &dmr_uncore_crs,
+       &dmr_uncore_cpc,
+       &dmr_uncore_itc,
+       &dmr_uncore_otc,
+       &dmr_uncore_cms,
+       &dmr_uncore_pcie6,
+};
+
+int dmr_uncore_imh_units_ignore[] = {
+       0x13,           /* MSE */
+       UNCORE_IGNORE_END
+};
+
+int dmr_uncore_pci_init(void)
+{
+       uncore_pci_uncores = uncore_get_uncores(UNCORE_ACCESS_PCI, 0, NULL,
+                                               UNCORE_DMR_NUM_UNCORE_TYPES,
+                                               dmr_uncores);
+       return 0;
+}
+void dmr_uncore_mmio_init(void)
+{
+       uncore_mmio_uncores = uncore_get_uncores(UNCORE_ACCESS_MMIO, 0, NULL,
+                                                UNCORE_DMR_NUM_UNCORE_TYPES,
+                                                dmr_uncores);
+}
+
+/* end of DMR uncore support */