perf/arm-cmn: Add CMN-700 r3 support
authorRobin Murphy <robin.murphy@arm.com>
Fri, 7 Jul 2023 16:38:13 +0000 (17:38 +0100)
committerWill Deacon <will@kernel.org>
Fri, 28 Jul 2023 13:31:06 +0000 (14:31 +0100)
CMN-700 r3 has a special configuration option for a so-called "Super
Home Node", which is a superset of the standard HN-F that also manages
remote-chip coherency for multi-chip setups. As such it has a similar
but expanded set of PMU events compared to HN-F, with some additional
filtering options to boot.

Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Link: https://lore.kernel.org/r/49153b72253f6af0e625cb55b9e1b825b110c49c.1688746690.git.robin.murphy@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
drivers/perf/arm-cmn.c

index 1efe9b7..913dc04 100644 (file)
@@ -72,6 +72,8 @@
 /* For most nodes, this is all there is */
 #define CMN_PMU_EVENT_SEL              0x000
 #define CMN__PMU_CBUSY_SNTHROTTLE_SEL  GENMASK_ULL(44, 42)
+#define CMN__PMU_SN_HOME_SEL           GENMASK_ULL(40, 39)
+#define CMN__PMU_HBT_LBT_SEL           GENMASK_ULL(38, 37)
 #define CMN__PMU_CLASS_OCCUP_ID                GENMASK_ULL(36, 35)
 /* Technically this is 4 bits wide on DNs, but we only use 2 there anyway */
 #define CMN__PMU_OCCUP1_ID             GENMASK_ULL(34, 32)
@@ -226,6 +228,7 @@ enum cmn_revision {
        REV_CMN700_R0P0 = 0,
        REV_CMN700_R1P0,
        REV_CMN700_R2P0,
+       REV_CMN700_R3P0,
        REV_CI700_R0P0 = 0,
        REV_CI700_R1P0,
        REV_CI700_R2P0,
@@ -254,6 +257,9 @@ enum cmn_node_type {
        CMN_TYPE_CCHA,
        CMN_TYPE_CCLA,
        CMN_TYPE_CCLA_RNI,
+       CMN_TYPE_HNS = 0x200,
+       CMN_TYPE_HNS_MPAM_S,
+       CMN_TYPE_HNS_MPAM_NS,
        /* Not a real node type */
        CMN_TYPE_WP = 0x7770
 };
@@ -263,6 +269,8 @@ enum cmn_filter_select {
        SEL_OCCUP1ID,
        SEL_CLASS_OCCUP_ID,
        SEL_CBUSY_SNTHROTTLE_SEL,
+       SEL_HBT_LBT_SEL,
+       SEL_SN_HOME_SEL,
        SEL_MAX
 };
 
@@ -768,6 +776,8 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
        CMN_EVENT_ATTR(CMN_ANY, ccla_##_name, CMN_TYPE_CCLA, _event)
 #define CMN_EVENT_CCLA_RNI(_name, _event)                              \
        CMN_EVENT_ATTR(CMN_ANY, ccla_rni_##_name, CMN_TYPE_CCLA_RNI, _event)
+#define CMN_EVENT_HNS(_name, _event)                           \
+       CMN_EVENT_ATTR(CMN_ANY, hns_##_name, CMN_TYPE_HNS, _event)
 
 #define CMN_EVENT_DVM(_model, _name, _event)                   \
        _CMN_EVENT_DVM(_model, _name, _event, 0, SEL_NONE)
@@ -803,6 +813,23 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
 #define CMN_EVENT_HNF_SNT(_model, _name, _event)                       \
        CMN_EVENT_HN_SNT(_model, hnf_##_name, CMN_TYPE_HNF, _event)
 
+#define CMN_EVENT_HNS_OCC(_name, _event)                               \
+       CMN_EVENT_HN_OCC(CMN_ANY, hns_##_name, CMN_TYPE_HNS, _event),   \
+       _CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_rxsnp, CMN_TYPE_HNS, _event, 5, SEL_OCCUP1ID), \
+       _CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_lbt, CMN_TYPE_HNS, _event, 6, SEL_OCCUP1ID), \
+       _CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_hbt, CMN_TYPE_HNS, _event, 7, SEL_OCCUP1ID)
+#define CMN_EVENT_HNS_CLS( _name, _event)                              \
+       CMN_EVENT_HN_CLS(CMN_ANY, hns_##_name, CMN_TYPE_HNS, _event)
+#define CMN_EVENT_HNS_SNT(_name, _event)                               \
+       CMN_EVENT_HN_SNT(CMN_ANY, hns_##_name, CMN_TYPE_HNS, _event)
+#define CMN_EVENT_HNS_HBT(_name, _event)                               \
+       _CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_all, CMN_TYPE_HNS, _event, 0, SEL_HBT_LBT_SEL), \
+       _CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_hbt, CMN_TYPE_HNS, _event, 1, SEL_HBT_LBT_SEL), \
+       _CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_lbt, CMN_TYPE_HNS, _event, 2, SEL_HBT_LBT_SEL)
+#define CMN_EVENT_HNS_SNH(_name, _event)                               \
+       _CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_all, CMN_TYPE_HNS, _event, 0, SEL_SN_HOME_SEL), \
+       _CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_sn, CMN_TYPE_HNS, _event, 1, SEL_SN_HOME_SEL), \
+       _CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_home, CMN_TYPE_HNS, _event, 2, SEL_SN_HOME_SEL)
 
 #define _CMN_EVENT_XP_MESH(_name, _event)                      \
        __CMN_EVENT_XP(e_##_name, (_event) | (0 << 2)),         \
@@ -1151,6 +1178,66 @@ static struct attribute *arm_cmn_event_attrs[] = {
        CMN_EVENT_CCLA(pfwd_sndr_stalls_static_crd,     0x2a),
        CMN_EVENT_CCLA(pfwd_sndr_stalls_dynmaic_crd,    0x2b),
 
+       CMN_EVENT_HNS_HBT(cache_miss,                   0x01),
+       CMN_EVENT_HNS_HBT(slc_sf_cache_access,          0x02),
+       CMN_EVENT_HNS_HBT(cache_fill,                   0x03),
+       CMN_EVENT_HNS_HBT(pocq_retry,                   0x04),
+       CMN_EVENT_HNS_HBT(pocq_reqs_recvd,              0x05),
+       CMN_EVENT_HNS_HBT(sf_hit,                       0x06),
+       CMN_EVENT_HNS_HBT(sf_evictions,                 0x07),
+       CMN_EVENT_HNS(dir_snoops_sent,                  0x08),
+       CMN_EVENT_HNS(brd_snoops_sent,                  0x09),
+       CMN_EVENT_HNS_HBT(slc_eviction,                 0x0a),
+       CMN_EVENT_HNS_HBT(slc_fill_invalid_way,         0x0b),
+       CMN_EVENT_HNS(mc_retries_local,                 0x0c),
+       CMN_EVENT_HNS_SNH(mc_reqs_local,                0x0d),
+       CMN_EVENT_HNS(qos_hh_retry,                     0x0e),
+       CMN_EVENT_HNS_OCC(qos_pocq_occupancy,           0x0f),
+       CMN_EVENT_HNS(pocq_addrhaz,                     0x10),
+       CMN_EVENT_HNS(pocq_atomic_addrhaz,              0x11),
+       CMN_EVENT_HNS(ld_st_swp_adq_full,               0x12),
+       CMN_EVENT_HNS(cmp_adq_full,                     0x13),
+       CMN_EVENT_HNS(txdat_stall,                      0x14),
+       CMN_EVENT_HNS(txrsp_stall,                      0x15),
+       CMN_EVENT_HNS(seq_full,                         0x16),
+       CMN_EVENT_HNS(seq_hit,                          0x17),
+       CMN_EVENT_HNS(snp_sent,                         0x18),
+       CMN_EVENT_HNS(sfbi_dir_snp_sent,                0x19),
+       CMN_EVENT_HNS(sfbi_brd_snp_sent,                0x1a),
+       CMN_EVENT_HNS(intv_dirty,                       0x1c),
+       CMN_EVENT_HNS(stash_snp_sent,                   0x1d),
+       CMN_EVENT_HNS(stash_data_pull,                  0x1e),
+       CMN_EVENT_HNS(snp_fwded,                        0x1f),
+       CMN_EVENT_HNS(atomic_fwd,                       0x20),
+       CMN_EVENT_HNS(mpam_hardlim,                     0x21),
+       CMN_EVENT_HNS(mpam_softlim,                     0x22),
+       CMN_EVENT_HNS(snp_sent_cluster,                 0x23),
+       CMN_EVENT_HNS(sf_imprecise_evict,               0x24),
+       CMN_EVENT_HNS(sf_evict_shared_line,             0x25),
+       CMN_EVENT_HNS_CLS(pocq_class_occup,             0x26),
+       CMN_EVENT_HNS_CLS(pocq_class_retry,             0x27),
+       CMN_EVENT_HNS_CLS(class_mc_reqs_local,          0x28),
+       CMN_EVENT_HNS_CLS(class_cgnt_cmin,              0x29),
+       CMN_EVENT_HNS_SNT(sn_throttle,                  0x2a),
+       CMN_EVENT_HNS_SNT(sn_throttle_min,              0x2b),
+       CMN_EVENT_HNS(sf_precise_to_imprecise,          0x2c),
+       CMN_EVENT_HNS(snp_intv_cln,                     0x2d),
+       CMN_EVENT_HNS(nc_excl,                          0x2e),
+       CMN_EVENT_HNS(excl_mon_ovfl,                    0x2f),
+       CMN_EVENT_HNS(snp_req_recvd,                    0x30),
+       CMN_EVENT_HNS(snp_req_byp_pocq,                 0x31),
+       CMN_EVENT_HNS(dir_ccgha_snp_sent,               0x32),
+       CMN_EVENT_HNS(brd_ccgha_snp_sent,               0x33),
+       CMN_EVENT_HNS(ccgha_snp_stall,                  0x34),
+       CMN_EVENT_HNS(lbt_req_hardlim,                  0x35),
+       CMN_EVENT_HNS(hbt_req_hardlim,                  0x36),
+       CMN_EVENT_HNS(sf_reupdate,                      0x37),
+       CMN_EVENT_HNS(excl_sf_imprecise,                0x38),
+       CMN_EVENT_HNS(snp_pocq_addrhaz,                 0x39),
+       CMN_EVENT_HNS(mc_retries_remote,                0x3a),
+       CMN_EVENT_HNS_SNH(mc_reqs_remote,               0x3b),
+       CMN_EVENT_HNS_CLS(class_mc_reqs_remote,         0x3c),
+
        NULL
 };
 
@@ -1392,6 +1479,10 @@ static int arm_cmn_set_event_sel_hi(struct arm_cmn_node *dn,
                dn->occupid[fsel].val = occupid;
                reg = FIELD_PREP(CMN__PMU_CBUSY_SNTHROTTLE_SEL,
                                 dn->occupid[SEL_CBUSY_SNTHROTTLE_SEL].val) |
+                     FIELD_PREP(CMN__PMU_SN_HOME_SEL,
+                                dn->occupid[SEL_SN_HOME_SEL].val) |
+                     FIELD_PREP(CMN__PMU_HBT_LBT_SEL,
+                                dn->occupid[SEL_HBT_LBT_SEL].val) |
                      FIELD_PREP(CMN__PMU_CLASS_OCCUP_ID,
                                 dn->occupid[SEL_CLASS_OCCUP_ID].val) |
                      FIELD_PREP(CMN__PMU_OCCUP1_ID,
@@ -2219,6 +2310,7 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
                        case CMN_TYPE_CCRA:
                        case CMN_TYPE_CCHA:
                        case CMN_TYPE_CCLA:
+                       case CMN_TYPE_HNS:
                                dn++;
                                break;
                        /* Nothing to see here */
@@ -2226,6 +2318,8 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
                        case CMN_TYPE_MPAM_NS:
                        case CMN_TYPE_RNSAM:
                        case CMN_TYPE_CXLA:
+                       case CMN_TYPE_HNS_MPAM_S:
+                       case CMN_TYPE_HNS_MPAM_NS:
                                break;
                        /*
                         * Split "optimised" combination nodes into separate