Re: [PATCH v2 5/5] perf/arm-cmn: Support CMN S3 r2
Ilkka Koskinen <[email protected]> Mon, 3 Aug 2026 19:33:50 -0700 (PDT)
| Newsgroups | org.kernel.vger.linux-perf-users,org.infradead.lists.linux-arm-kernel |
|---|---|
| Message-ID | <[email protected]> |
On Tue, 28 Jul 2026, Robin Murphy wrote: > If you were disappointed at how minimal the initial CMN S3 support > looked compared to previous versions, then oh boy is it time to put your > party hats on... The biggest batch of incompatible changes yet comes not > with a new CMN product, but a point release of an existing one. We've > got new filters, loads of changes to existing events, register fields > moved around for no good reason, and much, much more! On the upside, we > do at least gain a means of working around the isolation feature. That's just great... > > As such, for the sake of sanity in the driver it is easiest to split it > into a distict "model" for our internal abstractions despite it bearing > the same part number as r0/r1. > > Signed-off-by: Robin Murphy <[email protected]> The patch looks good to me: Reviewed-by: Ilkka Koskinen <[email protected]> Cheers, Ilkka > --- > > v2: No change > > drivers/perf/arm-cmn.c | 270 +++++++++++++++++++++++++++++------------ > 1 file changed, 193 insertions(+), 77 deletions(-) > > diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c > index e25f46c38c23..a03e2a8ca41e 100644 > --- a/drivers/perf/arm-cmn.c > +++ b/drivers/perf/arm-cmn.c > @@ -29,6 +29,7 @@ > #define CMN_CI_CHILD_PTR_OFFSET GENMASK_ULL(31, 16) > > #define CMN_CHILD_NODE_ADDR GENMASK(29, 0) > +#define CMN_CHILD_NODE_ISOLATED BIT(30) > #define CMN_CHILD_NODE_EXTERNAL BIT(31) > > /* Some implementations use a mesh larger than the architectural max of 12 */ > @@ -48,11 +49,16 @@ > > #define CMN_CFGM_INFO_GLOBAL 0x0900 > #define CMN_INFO_MULTIPLE_DTM_EN BIT_ULL(63) > +#define CMN_S3_R2_MULTIPLE_DTM_EN BIT_ULL(59) > #define CMN_INFO_RSP_VC_NUM GENMASK_ULL(53, 52) > #define CMN_INFO_DAT_VC_NUM GENMASK_ULL(51, 50) > #define CMN_INFO_DEVICE_ISO_ENABLE BIT_ULL(44) > > #define CMN_CFGM_INFO_GLOBAL_1 0x0908 > +#define CMN_S3_R2_RSP_VC_NUM GENMASK_ULL(11, 9) > +#define CMN_S3_R2_DAT_VC_NUM GENMASK_ULL(8, 6) > +#define CMN_S3_R2_SNP_VC_NUM GENMASK_ULL(5, 3) > +#define CMN_S3_R2_REQ_VC_NUM GENMASK_ULL(2, 0) > #define CMN_INFO_SNP_VC_NUM GENMASK_ULL(3, 2) > #define CMN_INFO_REQ_VC_NUM GENMASK_ULL(1, 0) > > @@ -78,6 +84,16 @@ > /* Technically this is 4 bits wide on DNs, but we only use 2 there anyway */ > #define CMN__PMU_OCCUP1_ID GENMASK_ULL(34, 32) > > +/* But then... */ > +#define CMN__PMU_EVICT_STATE_SEL GENMASK_ULL(54, 52) > +#define CMN__PMU_ENHANCED_HBT_LBT_SEL GENMASK_ULL(51, 48) > +#define CMN__PMU_SNP_VC_SEL GENMASK_ULL(47, 46) > +#define CMN__S3_R2_CBUSY_SNTHROTTLE_SEL GENMASK_ULL(45, 42) > +#define CMN__S3_R2_SN_HOME_SEL GENMASK_ULL(41, 40) > +#define CMN__S3_R2_HBT_LBT_SEL GENMASK_ULL(39, 38) > +#define CMN__S3_R2_CLASS_OCCUP_ID GENMASK_ULL(37, 36) > +#define CMN__S3_R2_OCCUP1_ID GENMASK_ULL(35, 32) > + > /* Some types are designed to coexist with another device in the same node */ > #define CMN_CCLA_PMU_EVENT_SEL 0x008 > #define CMN_HNP_PMU_EVENT_SEL 0x008 > @@ -202,12 +218,14 @@ enum cmn_model { > CMN650 = 2, > CI700 = 4, > CMN700 = 8, > - CMNS3 = 16, > + CMNS3R01 = 16, > + CMNS3R2 = 32, > /* ...and then we can use bitmap tricks for commonality */ > CMN_ANY = -1, > NOT_CMN600 = -2, > CMN_700ON = ~(CMN700 - 1), > CMN_650ON = CMN_700ON | CMN650, > + CMNS3 = CMNS3R01 | CMNS3R2, > }; > > /* Actual part numbers and revision IDs defined by the hardware */ > @@ -243,6 +261,10 @@ enum cmn_revision { > REV_CMNS3_R0P0 = 0, > REV_CMNS3_R0P1, > REV_CMNS3_R1P0, > + REV_CMNS3_R2P0, > + REV_CMNS3_R2P1, > + REV_CMNS3_R2P2, > + REV_CMNS3_R2P5, > REV_CI700_R0P0 = 0, > REV_CI700_R1P0, > REV_CI700_R2P0, > @@ -429,7 +451,9 @@ static enum cmn_model arm_cmn_model(const struct arm_cmn *cmn) > case PART_CI700: > return CI700; > case PART_CMN_S3: > - return CMNS3; > + if (cmn->rev >= REV_CMNS3_R2P0) > + return CMNS3R2; > + return CMNS3R01; > default: > return 0; > }; > @@ -609,8 +633,10 @@ enum cmn_filter_type { > FILT_OCCUP1_ID, > FILT_HNF_700, > FILT_HNS, > + FILT_HNS_S3R2, > }; > #define CMN_FILTER(_sel) [SEL_##_sel] = CMN__PMU_##_sel > +#define CMN_FILTER_V2(_sel) [SEL_##_sel] = CMN__S3_R2_##_sel > > static const u64 arm_cmn_filters[][SEL_MAX] = { > [FILT_NONE] = {}, > @@ -632,6 +658,17 @@ static const u64 arm_cmn_filters[][SEL_MAX] = { > CMN_FILTER(HBT_LBT_SEL), > CMN_FILTER(SN_HOME_SEL) > }, > + /* Newer HN-S */ > + [FILT_HNS_S3R2] = { > + CMN_FILTER_V2(OCCUP1_ID), > + CMN_FILTER_V2(CLASS_OCCUP_ID), > + CMN_FILTER_V2(CBUSY_SNTHROTTLE_SEL), > + CMN_FILTER_V2(HBT_LBT_SEL), > + CMN_FILTER_V2(SN_HOME_SEL), > + CMN_FILTER(SNP_VC_SEL), > + CMN_FILTER(ENHANCED_HBT_LBT_SEL), > + CMN_FILTER(EVICT_STATE_SEL) > + } > }; > > static enum cmn_filter_type arm_cmn_filter(enum cmn_node_type node, > @@ -651,7 +688,9 @@ static enum cmn_filter_type arm_cmn_filter(enum cmn_node_type node, > return FILT_OCCUP1_ID; > return FILT_HNF_700; > case CMN_TYPE_HNS: > - return FILT_HNS; > + if (model < CMNS3R2) > + return FILT_HNS; > + return FILT_HNS_S3R2; > }; > } > > @@ -732,7 +771,7 @@ struct arm_cmn_event_attr { > enum cmn_model model; > enum cmn_node_type type; > u16 eventid; > - struct arm_cmn_filter_attr filter[1]; > + struct arm_cmn_filter_attr filter[2]; > }; > > struct arm_cmn_format_attr { > @@ -741,16 +780,16 @@ struct arm_cmn_format_attr { > int config; > }; > > -#define _CMN_EVENT_ATTR(_model, _name, _type, _eventid, _fa, _fb, ...) \ > +#define _CMN_EVENT_ATTR(_model, _name, _type, _eventid, _fa, _fb, _fc, _fd, ...) \ > (&((struct arm_cmn_event_attr[]) {{ \ > .attr = __ATTR(_name, 0444, arm_cmn_event_show, NULL), \ > .model = _model, \ > .type = _type, \ > .eventid = _eventid, \ > - .filter = {{_fa, _fb}}, \ > + .filter = {{_fa, _fb}, {_fc, _fd}}, \ > }})[0].attr.attr) > #define CMN_EVENT_ATTR(_model, _name, _type, _eventid, _filter...) \ > - _CMN_EVENT_ATTR(_model, _name, _type, _eventid, ##_filter, 0, 0) > + _CMN_EVENT_ATTR(_model, _name, _type, _eventid, ##_filter, 0, 0, 0, 0) > > static ssize_t arm_cmn_event_show(struct device *dev, > struct device_attribute *attr, char *buf) > @@ -769,6 +808,10 @@ static ssize_t arm_cmn_event_show(struct device *dev, > "type=0x%x,eventid=0x%x,wp_dev_sel=?,wp_chn_sel=?,wp_grp=?,wp_val=?,wp_mask=?\n", > eattr->type, eattr->eventid); > > + if (filter[1].sel) > + return sysfs_emit(buf, "type=0x%x,eventid=0x%x,filter=0x%x,filter2=0x%x\n", > + eattr->type, eattr->eventid, filter[0].val, filter[1].val); > + > if (filter[0].sel) > return sysfs_emit(buf, "type=0x%x,eventid=0x%x,filter=0x%x\n", > eattr->type, eattr->eventid, filter[0].val); > @@ -887,8 +930,8 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj, > CMN_EVENT_ATTR(_model, ccha_##_name, CMN_TYPE_CCHA, _event) > #define CMN_EVENT_CCLA(_name, _event) \ > CMN_EVENT_ATTR(CMN_ANY, ccla_##_name, CMN_TYPE_CCLA, _event) > -#define CMN_EVENT_HNS(_name, _event) \ > - CMN_EVENT_ATTR(CMN_ANY, hns_##_name, CMN_TYPE_HNS, _event) > +#define _CMN_EVENT_HNS(_model, _name, _event, _filter...) \ > + CMN_EVENT_ATTR(_model, hns_##_name, CMN_TYPE_HNS, _event, ##_filter) > > #define CMN_EVENT_DVM_OCC(_model, _name, _event) \ > CMN_EVENT_DVM(_model, _name##_all, _event, SEL_OCCUP1_ID, 0), \ > @@ -913,7 +956,12 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj, > CMN_EVENT_ATTR(_model, _name##_group1_read, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 3), \ > CMN_EVENT_ATTR(_model, _name##_group1_write, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 4), \ > CMN_EVENT_ATTR(_model, _name##_read, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 5), \ > - CMN_EVENT_ATTR(_model, _name##_write, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 6) > + CMN_EVENT_ATTR(_model, _name##_write, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 6), \ > + CMN_EVENT_ATTR(CMNS3R2, _name##_ccg_read, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 9), \ > + CMN_EVENT_ATTR(CMNS3R2, _name##_ccg_write, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 10), \ > + CMN_EVENT_ATTR(CMNS3R2, _name##_lbt_read, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 11), \ > + CMN_EVENT_ATTR(CMNS3R2, _name##_lbt_write, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 12), \ > + CMN_EVENT_ATTR(CMNS3R2, _name##_lbt, _type, _event, SEL_CBUSY_SNTHROTTLE_SEL, 13) > > #define CMN_EVENT_HNF_OCC(_model, _name, _event) \ > CMN_EVENT_HN_OCC(_model, hnf_##_name, CMN_TYPE_HNF, _event) > @@ -922,23 +970,75 @@ 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, SEL_OCCUP1_ID, 5), \ > - CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_lbt, CMN_TYPE_HNS, _event, SEL_OCCUP1_ID, 6), \ > - CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_hbt, CMN_TYPE_HNS, _event, SEL_OCCUP1_ID, 7) > +#define CMN_EVENT_HNS(_name, _event) \ > + _CMN_EVENT_HNS(CMN_ANY, _name, _event) > +#define CMN_EVENT_HNSR0(_name, _event) \ > + _CMN_EVENT_HNS(CMN700 | CMNS3R01, _name, _event) > +#define _CMN_EVENT_HNS_HBT(_model, _name, _event, _sel) \ > + _CMN_EVENT_HNS(_model, _name##_all, _event, _sel, 0), \ > + _CMN_EVENT_HNS(_model, _name##_hbt, _event, _sel, 1), \ > + _CMN_EVENT_HNS(_model, _name##_lbt, _event, _sel, 2) > +#define _CMN_EVENT_HNS_HBT2(_model, _name, _event, _fsel1, f1) \ > + _CMN_EVENT_HNS(_model, _name##_all, _event, _fsel1, f1, SEL_HBT_LBT_SEL, 0), \ > + _CMN_EVENT_HNS(_model, _name##_hbt, _event, _fsel1, f1, SEL_HBT_LBT_SEL, 1), \ > + _CMN_EVENT_HNS(_model, _name##_lbt, _event, _fsel1, f1, SEL_HBT_LBT_SEL, 2) > + > +#define CMN_EVENT_HNS_OCC(_model, _name, _event) \ > + CMN_EVENT_HN_OCC(_model, hns_##_name, CMN_TYPE_HNS, _event), \ > + _CMN_EVENT_HNS(_model, _name##_rxsnp, _event, SEL_OCCUP1_ID, 5), \ > + _CMN_EVENT_HNS(_model, _name##_lbt, _event, SEL_OCCUP1_ID, 6), \ > + _CMN_EVENT_HNS(_model, _name##_hbt, _event, SEL_OCCUP1_ID, 7), \ > + _CMN_EVENT_HNS(CMNS3R2, _name##_rnf, _event, SEL_OCCUP1_ID, 8), \ > + _CMN_EVENT_HNS(CMNS3R2, _name##_rni, _event, SEL_OCCUP1_ID, 9), \ > + _CMN_EVENT_HNS(CMNS3R2, _name##_ccglcn, _event, SEL_OCCUP1_ID, 10), \ > + _CMN_EVENT_HNS(CMNS3R2, _name##_ccgrn, _event, SEL_OCCUP1_ID, 11) > #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, SEL_HBT_LBT_SEL, 0), \ > - CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_hbt, CMN_TYPE_HNS, _event, SEL_HBT_LBT_SEL, 1), \ > - CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_lbt, CMN_TYPE_HNS, _event, SEL_HBT_LBT_SEL, 2) > -#define CMN_EVENT_HNS_SNH(_name, _event) \ > - CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_all, CMN_TYPE_HNS, _event, SEL_SN_HOME_SEL, 0), \ > - CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_sn, CMN_TYPE_HNS, _event, SEL_SN_HOME_SEL, 1), \ > - CMN_EVENT_ATTR(CMN_ANY, hns_##_name##_home, CMN_TYPE_HNS, _event, SEL_SN_HOME_SEL, 2) > +#define CMN_EVENT_HNSR0_CLS( _name, _event) \ > + CMN_EVENT_HN_CLS(CMN700 | CMNS3R01, hns_##_name, CMN_TYPE_HNS, _event) > +#define CMN_EVENT_HNS_SNT(_model, _name, _event) \ > + CMN_EVENT_HN_SNT(_model, hns_##_name, CMN_TYPE_HNS, _event) > +#define CMN_EVENT_HNS_SNH(_model, _name, _event) \ > + _CMN_EVENT_HNS(_model, _name##_all, _event, SEL_SN_HOME_SEL, 0), \ > + _CMN_EVENT_HNS(_model, _name##_sn, _event, SEL_SN_HOME_SEL, 1), \ > + _CMN_EVENT_HNS(_model, _name##_home, _event, SEL_SN_HOME_SEL, 2) > +#define CMN_EVENT_HNS_VC(_name, _event) \ > + CMN_EVENT_HNSR0(_name, _event), \ > + _CMN_EVENT_HNS(CMNS3R2, _name##_vc0, _event, SEL_SNP_VC_SEL, 0), \ > + _CMN_EVENT_HNS(CMNS3R2, _name##_vc1, _event, SEL_SNP_VC_SEL, 1), \ > + _CMN_EVENT_HNS(CMNS3R2, _name##_vc2, _event, SEL_SNP_VC_SEL, 2) > +#define CMN_EVENT_HNS_ENHBT(_name, _event) \ > + _CMN_EVENT_HNS_HBT(CMNS3R2, _name, _event, SEL_ENHANCED_HBT_LBT_SEL), \ > + _CMN_EVENT_HNS(CMNS3R2, _name##_rnf, _event, SEL_ENHANCED_HBT_LBT_SEL, 3), \ > + _CMN_EVENT_HNS(CMNS3R2, _name##_rni, _event, SEL_ENHANCED_HBT_LBT_SEL, 4), \ > + _CMN_EVENT_HNS(CMNS3R2, _name##_ccglcn, _event, SEL_ENHANCED_HBT_LBT_SEL, 5), \ > + _CMN_EVENT_HNS(CMNS3R2, _name##_ccgrn, _event, SEL_ENHANCED_HBT_LBT_SEL, 6) > +#define CMN_EVENT_HNS_EVICT(_model, _name, _event) \ > + _CMN_EVENT_HNS_HBT2(_model, _name##_all, _event, SEL_EVICT_STATE_SEL, 0), \ > + _CMN_EVENT_HNS_HBT2(_model, _name##_eu, _event, SEL_EVICT_STATE_SEL, 1), \ > + _CMN_EVENT_HNS_HBT2(_model, _name##_en, _event, SEL_EVICT_STATE_SEL, 2), \ > + _CMN_EVENT_HNS_HBT2(_model, _name##_su, _event, SEL_EVICT_STATE_SEL, 3), \ > + _CMN_EVENT_HNS_HBT2(_model, _name##_sn, _event, SEL_EVICT_STATE_SEL, 4), \ > + _CMN_EVENT_HNS_HBT2(_model, _name##_mu, _event, SEL_EVICT_STATE_SEL, 5), \ > + _CMN_EVENT_HNS_HBT2(_model, _name##_mn, _event, SEL_EVICT_STATE_SEL, 6) > + > +#define CMN_EVENT_HNSR0_HBT(_name, _event) \ > + _CMN_EVENT_HNS_HBT(CMN700 | CMNS3R01, _name, _event, SEL_HBT_LBT_SEL) > +#define CMN_EVENT_HNS_R2SNH(_name, _event) \ > + CMN_EVENT_HNSR0(_name, _event), \ > + CMN_EVENT_HNS_SNH(CMNS3R2, _name, _event) > +#define CMN_EVENT_HNS_R2HBT(_name, _event) \ > + CMN_EVENT_HNSR0(_name, _event), \ > + _CMN_EVENT_HNS_HBT(CMNS3R2, _name, _event, SEL_HBT_LBT_SEL) > +#define CMN_EVENT_HNS_HBT_ENHBT(_name, _event) \ > + CMN_EVENT_HNSR0_HBT(_name, _event), \ > + CMN_EVENT_HNS_ENHBT(_name, _event) > +#define CMN_EVENT_HNS_HBT_OCC(_name, _event) \ > + CMN_EVENT_HNSR0_HBT(_name, _event), \ > + CMN_EVENT_HNS_OCC(CMNS3R2, _name, _event) > +#define CMN_EVENT_HNS_HBT_EVICT(_name, _event) \ > + CMN_EVENT_HNSR0_HBT(_name, _event), \ > + CMN_EVENT_HNS_EVICT(CMNS3R2, _name, _event) > > #define _CMN_EVENT_XP_MESH(_name, _event) \ > __CMN_EVENT_XP(e_##_name, (_event) | (0 << 2)), \ > @@ -1288,65 +1388,72 @@ 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_HBT_ENHBT(cache_miss, 0x01), > + CMN_EVENT_HNS_HBT_ENHBT(slc_sf_cache_access, 0x02), > + CMN_EVENT_HNS_HBT_ENHBT(cache_fill, 0x03), > + CMN_EVENT_HNS_HBT_OCC(pocq_retry, 0x04), > + CMN_EVENT_HNS_HBT_OCC(pocq_reqs_recvd, 0x05), > + CMN_EVENT_HNS_HBT_ENHBT(sf_hit, 0x06), > + CMN_EVENT_HNS_HBT_EVICT(sf_evictions, 0x07), > + CMN_EVENT_HNS_VC(dir_snoops_sent, 0x08), > + CMN_EVENT_HNS_VC(brd_snoops_sent, 0x09), > + CMN_EVENT_HNS_HBT_EVICT(slc_eviction, 0x0a), > + CMN_EVENT_HNS_HBT_ENHBT(slc_fill_invalid_way, 0x0b), > + CMN_EVENT_HNS_R2SNH(mc_retries_local, 0x0c), > + CMN_EVENT_HNS_SNH(CMN_ANY, 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_OCC(CMN_ANY, qos_pocq_occupancy, 0x0f), > + CMN_EVENT_HNS_HBT_ENHBT(pocq_addrhaz, 0x10), > + CMN_EVENT_HNS_HBT_ENHBT(pocq_atomic_addrhaz, 0x11), > + CMN_EVENT_HNSR0(ld_st_swp_adq_full, 0x12), > + CMN_EVENT_HNSR0(cmp_adq_full, 0x13), > CMN_EVENT_HNS(txdat_stall, 0x14), > CMN_EVENT_HNS(txrsp_stall, 0x15), > - CMN_EVENT_HNS(seq_full, 0x16), > + CMN_EVENT_HNSR0(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_VC(snp_sent, 0x18), > + CMN_EVENT_HNS_VC(sfbi_dir_snp_sent, 0x19), > + CMN_EVENT_HNS_VC(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_HNSR0(stash_snp_sent, 0x1d), > + CMN_EVENT_HNSR0(stash_data_pull, 0x1e), > + CMN_EVENT_HNS_VC(snp_fwded, 0x1f), > + CMN_EVENT_HNSR0(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_VC(snp_sent_cluster, 0x23), > + CMN_EVENT_HNS_R2HBT(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_HNSR0_CLS(class_cgnt_cmin, 0x29), > + CMN_EVENT_HNS_SNT(CMN_ANY, sn_throttle, 0x2a), > + CMN_EVENT_HNS_SNT(CMN_ANY, 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_HNSR0(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_HNSR0(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_R2HBT(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_R2SNH(mc_retries_remote, 0x3a), > + CMN_EVENT_HNS_SNH(CMN_ANY, mc_reqs_remote, 0x3b), > CMN_EVENT_HNS_CLS(class_mc_reqs_remote, 0x3c), > + CMN_EVENT_HNS_ENHBT(readonce_hazard_detected, 0x3d), > + CMN_EVENT_HNS_ENHBT(readonce_fwd_data_completed, 0x3e), > + CMN_EVENT_HNS_SNT(CMNS3R2, cbusy00, 0x40), > + CMN_EVENT_HNS_SNT(CMNS3R2, cbusy01, 0x41), > + CMN_EVENT_HNS_SNT(CMNS3R2, cbusy10, 0x42), > + CMN_EVENT_HNS_SNT(CMNS3R2, cbusy11, 0x43), > + CMN_EVENT_HNS_ENHBT(ro_rnsd_new_alloc_hint, 0x44), > > NULL > }; > @@ -2431,21 +2538,33 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) > /* > * With the device isolation feature, if firmware has neglected to enable > * an XP port then we risk locking up if we try to access anything behind > - * it; however we also have no way to tell from Non-Secure whether any > - * given port is disabled or not, so the only way to win is not to play... > + * it; however prior to CMN S3 r2p0 we also have no way to tell from > + * Non-Secure whether any given port is disabled or not, so in that case > + * the only way to win is not to play... > */ > reg = readq_relaxed(cfg_region + CMN_CFGM_INFO_GLOBAL); > - if (reg & CMN_INFO_DEVICE_ISO_ENABLE) { > + if (reg & CMN_INFO_DEVICE_ISO_ENABLE && model == CMNS3R01) { > dev_err(cmn->dev, "Device isolation enabled, not continuing due to risk of lockup\n"); > return -ENODEV; > } > - cmn->multi_dtm = reg & CMN_INFO_MULTIPLE_DTM_EN; > - cmn->rsp_vc_num = FIELD_GET(CMN_INFO_RSP_VC_NUM, reg); > - cmn->dat_vc_num = FIELD_GET(CMN_INFO_DAT_VC_NUM, reg); > + if (model < CMNS3R2) { > + cmn->multi_dtm = reg & CMN_INFO_MULTIPLE_DTM_EN; > + cmn->rsp_vc_num = FIELD_GET(CMN_INFO_RSP_VC_NUM, reg); > + cmn->dat_vc_num = FIELD_GET(CMN_INFO_DAT_VC_NUM, reg); > + } else { > + cmn->multi_dtm = reg & CMN_S3_R2_MULTIPLE_DTM_EN; > + } > > reg = readq_relaxed(cfg_region + CMN_CFGM_INFO_GLOBAL_1); > - cmn->snp_vc_num = FIELD_GET(CMN_INFO_SNP_VC_NUM, reg); > - cmn->req_vc_num = FIELD_GET(CMN_INFO_REQ_VC_NUM, reg); > + if (model < CMNS3R2) { > + cmn->snp_vc_num = FIELD_GET(CMN_INFO_SNP_VC_NUM, reg); > + cmn->req_vc_num = FIELD_GET(CMN_INFO_REQ_VC_NUM, reg); > + } else { > + cmn->rsp_vc_num = FIELD_GET(CMN_S3_R2_RSP_VC_NUM, reg); > + cmn->dat_vc_num = FIELD_GET(CMN_S3_R2_DAT_VC_NUM, reg); > + cmn->snp_vc_num = FIELD_GET(CMN_S3_R2_SNP_VC_NUM, reg); > + cmn->req_vc_num = FIELD_GET(CMN_S3_R2_REQ_VC_NUM, reg); > + } > > reg = readq_relaxed(cfg_region + CMN_CHILD_INFO); > child_count = FIELD_GET(CMN_CI_CHILD_COUNT, reg); > @@ -2545,15 +2664,12 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset) > reg = readq_relaxed(xp_region + child_poff + j * 8); > /* > * Don't even try to touch anything external, since in general > - * we haven't a clue how to power up arbitrary CHI requesters. > - * As of CMN-600r1 these could only be RN-SAMs or CXLAs, > - * neither of which have any PMU events anyway. > - * (Actually, CXLAs do seem to have grown some events in r1p2, > - * but they don't go to regular XP DTMs, and they depend on > - * secure configuration which we can't easily deal with) > + * we haven't a clue how to power up arbitrary CHI requesters, > + * and none of them have standard PMU events anyway. Isolated > + * nodes effectively just do not exist at all from our PoV. > */ > - if (reg & CMN_CHILD_NODE_EXTERNAL) { > - dev_dbg(cmn->dev, "ignoring external node %llx\n", reg); > + if (reg & (CMN_CHILD_NODE_EXTERNAL | CMN_CHILD_NODE_ISOLATED)) { > + dev_dbg(cmn->dev, "ignoring external/isolated node %llx\n", reg); > continue; > } > /* > -- > 2.54.0.dirty > >