Skip to content

Commit 0dc2f49

Browse files
rmurphy-armwilldeacon
authored andcommitted
perf/arm-cmn: Support CMN S3
CMN S3 is the latest and greatest evolution for 2024, although most of the new features don't impact the PMU, so from our point of view it ends up looking a lot like CMN-700 r3 still. We have some new device types to ignore, a mildly irritating rearrangement of the register layouts, and a scary new configuration option that makes it potentially unsafe to even walk the full discovery tree, let alone attempt to use the PMU. Acked-by: Mark Rutland <[email protected]> Reviewed-by: Ilkka Koskinen <[email protected]> Signed-off-by: Robin Murphy <[email protected]> Link: https://lore.kernel.org/r/2ec9eec5b6bf215a9886f3b69e3b00e4cd85095c.1725296395.git.robin.murphy@arm.com Signed-off-by: Will Deacon <[email protected]>
1 parent a87ef53 commit 0dc2f49

File tree

1 file changed

+76
-43
lines changed

1 file changed

+76
-43
lines changed

drivers/perf/arm-cmn.c

Lines changed: 76 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -45,24 +45,28 @@
4545
#define CMN_CFGM_PERIPH_ID_23 0x0010
4646
#define CMN_CFGM_PID2_REVISION GENMASK_ULL(7, 4)
4747

48-
#define CMN_CFGM_INFO_GLOBAL 0x900
48+
#define CMN_CFGM_INFO_GLOBAL 0x0900
4949
#define CMN_INFO_MULTIPLE_DTM_EN BIT_ULL(63)
5050
#define CMN_INFO_RSP_VC_NUM GENMASK_ULL(53, 52)
5151
#define CMN_INFO_DAT_VC_NUM GENMASK_ULL(51, 50)
52+
#define CMN_INFO_DEVICE_ISO_ENABLE BIT_ULL(44)
5253

53-
#define CMN_CFGM_INFO_GLOBAL_1 0x908
54+
#define CMN_CFGM_INFO_GLOBAL_1 0x0908
5455
#define CMN_INFO_SNP_VC_NUM GENMASK_ULL(3, 2)
5556
#define CMN_INFO_REQ_VC_NUM GENMASK_ULL(1, 0)
5657

5758
/* XPs also have some local topology info which has uses too */
5859
#define CMN_MXP__CONNECT_INFO(p) (0x0008 + 8 * (p))
59-
#define CMN__CONNECT_INFO_DEVICE_TYPE GENMASK_ULL(4, 0)
60+
#define CMN__CONNECT_INFO_DEVICE_TYPE GENMASK_ULL(5, 0)
6061

6162
#define CMN_MAX_PORTS 6
6263
#define CI700_CONNECT_INFO_P2_5_OFFSET 0x10
6364

6465
/* PMU registers occupy the 3rd 4KB page of each node's region */
6566
#define CMN_PMU_OFFSET 0x2000
67+
/* ...except when they don't :( */
68+
#define CMN_S3_DTM_OFFSET 0xa000
69+
#define CMN_S3_PMU_OFFSET 0xd900
6670

6771
/* For most nodes, this is all there is */
6872
#define CMN_PMU_EVENT_SEL 0x000
@@ -195,10 +199,11 @@ enum cmn_model {
195199
CMN650 = 2,
196200
CMN700 = 4,
197201
CI700 = 8,
202+
CMNS3 = 16,
198203
/* ...and then we can use bitmap tricks for commonality */
199204
CMN_ANY = -1,
200205
NOT_CMN600 = -2,
201-
CMN_650ON = CMN650 | CMN700,
206+
CMN_650ON = CMN650 | CMN700 | CMNS3,
202207
};
203208

204209
/* Actual part numbers and revision IDs defined by the hardware */
@@ -207,6 +212,7 @@ enum cmn_part {
207212
PART_CMN650 = 0x436,
208213
PART_CMN700 = 0x43c,
209214
PART_CI700 = 0x43a,
215+
PART_CMN_S3 = 0x43e,
210216
};
211217

212218
/* CMN-600 r0px shouldn't exist in silicon, thankfully */
@@ -258,6 +264,7 @@ enum cmn_node_type {
258264
CMN_TYPE_HNS = 0x200,
259265
CMN_TYPE_HNS_MPAM_S,
260266
CMN_TYPE_HNS_MPAM_NS,
267+
CMN_TYPE_APB = 0x1000,
261268
/* Not a real node type */
262269
CMN_TYPE_WP = 0x7770
263270
};
@@ -408,13 +415,20 @@ static enum cmn_model arm_cmn_model(const struct arm_cmn *cmn)
408415
return CMN700;
409416
case PART_CI700:
410417
return CI700;
418+
case PART_CMN_S3:
419+
return CMNS3;
411420
default:
412421
return 0;
413422
};
414423
}
415424

416425
static int arm_cmn_pmu_offset(const struct arm_cmn *cmn, const struct arm_cmn_node *dn)
417426
{
427+
if (cmn->part == PART_CMN_S3) {
428+
if (dn->type == CMN_TYPE_XP)
429+
return CMN_S3_DTM_OFFSET;
430+
return CMN_S3_PMU_OFFSET;
431+
}
418432
return CMN_PMU_OFFSET;
419433
}
420434

@@ -468,9 +482,14 @@ static const char *arm_cmn_device_type(u8 type)
468482
case 0x17: return "RN-F_C_E|";
469483
case 0x18: return " RN-F_E |";
470484
case 0x19: return "RN-F_E_E|";
485+
case 0x1a: return " HN-S |";
486+
case 0x1b: return " LCN |";
471487
case 0x1c: return " MTSX |";
472488
case 0x1d: return " HN-V |";
473489
case 0x1e: return " CCG |";
490+
case 0x20: return " RN-F_F |";
491+
case 0x21: return "RN-F_F_E|";
492+
case 0x22: return " SN-F_F |";
474493
default: return " ???? |";
475494
}
476495
}
@@ -779,8 +798,8 @@ static umode_t arm_cmn_event_attr_is_visible(struct kobject *kobj,
779798
CMN_EVENT_ATTR(CMN_ANY, cxha_##_name, CMN_TYPE_CXHA, _event)
780799
#define CMN_EVENT_CCRA(_name, _event) \
781800
CMN_EVENT_ATTR(CMN_ANY, ccra_##_name, CMN_TYPE_CCRA, _event)
782-
#define CMN_EVENT_CCHA(_name, _event) \
783-
CMN_EVENT_ATTR(CMN_ANY, ccha_##_name, CMN_TYPE_CCHA, _event)
801+
#define CMN_EVENT_CCHA(_model, _name, _event) \
802+
CMN_EVENT_ATTR(_model, ccha_##_name, CMN_TYPE_CCHA, _event)
784803
#define CMN_EVENT_CCLA(_name, _event) \
785804
CMN_EVENT_ATTR(CMN_ANY, ccla_##_name, CMN_TYPE_CCLA, _event)
786805
#define CMN_EVENT_CCLA_RNI(_name, _event) \
@@ -1138,42 +1157,43 @@ static struct attribute *arm_cmn_event_attrs[] = {
11381157
CMN_EVENT_CCRA(wdb_alloc, 0x59),
11391158
CMN_EVENT_CCRA(ssb_alloc, 0x5a),
11401159

1141-
CMN_EVENT_CCHA(rddatbyp, 0x61),
1142-
CMN_EVENT_CCHA(chirsp_up_stall, 0x62),
1143-
CMN_EVENT_CCHA(chidat_up_stall, 0x63),
1144-
CMN_EVENT_CCHA(snppcrd_link0_stall, 0x64),
1145-
CMN_EVENT_CCHA(snppcrd_link1_stall, 0x65),
1146-
CMN_EVENT_CCHA(snppcrd_link2_stall, 0x66),
1147-
CMN_EVENT_CCHA(reqtrk_occ, 0x67),
1148-
CMN_EVENT_CCHA(rdb_occ, 0x68),
1149-
CMN_EVENT_CCHA(rdbyp_occ, 0x69),
1150-
CMN_EVENT_CCHA(wdb_occ, 0x6a),
1151-
CMN_EVENT_CCHA(snptrk_occ, 0x6b),
1152-
CMN_EVENT_CCHA(sdb_occ, 0x6c),
1153-
CMN_EVENT_CCHA(snphaz_occ, 0x6d),
1154-
CMN_EVENT_CCHA(reqtrk_alloc, 0x6e),
1155-
CMN_EVENT_CCHA(rdb_alloc, 0x6f),
1156-
CMN_EVENT_CCHA(rdbyp_alloc, 0x70),
1157-
CMN_EVENT_CCHA(wdb_alloc, 0x71),
1158-
CMN_EVENT_CCHA(snptrk_alloc, 0x72),
1159-
CMN_EVENT_CCHA(sdb_alloc, 0x73),
1160-
CMN_EVENT_CCHA(snphaz_alloc, 0x74),
1161-
CMN_EVENT_CCHA(pb_rhu_req_occ, 0x75),
1162-
CMN_EVENT_CCHA(pb_rhu_req_alloc, 0x76),
1163-
CMN_EVENT_CCHA(pb_rhu_pcie_req_occ, 0x77),
1164-
CMN_EVENT_CCHA(pb_rhu_pcie_req_alloc, 0x78),
1165-
CMN_EVENT_CCHA(pb_pcie_wr_req_occ, 0x79),
1166-
CMN_EVENT_CCHA(pb_pcie_wr_req_alloc, 0x7a),
1167-
CMN_EVENT_CCHA(pb_pcie_reg_req_occ, 0x7b),
1168-
CMN_EVENT_CCHA(pb_pcie_reg_req_alloc, 0x7c),
1169-
CMN_EVENT_CCHA(pb_pcie_rsvd_req_occ, 0x7d),
1170-
CMN_EVENT_CCHA(pb_pcie_rsvd_req_alloc, 0x7e),
1171-
CMN_EVENT_CCHA(pb_rhu_dat_occ, 0x7f),
1172-
CMN_EVENT_CCHA(pb_rhu_dat_alloc, 0x80),
1173-
CMN_EVENT_CCHA(pb_rhu_pcie_dat_occ, 0x81),
1174-
CMN_EVENT_CCHA(pb_rhu_pcie_dat_alloc, 0x82),
1175-
CMN_EVENT_CCHA(pb_pcie_wr_dat_occ, 0x83),
1176-
CMN_EVENT_CCHA(pb_pcie_wr_dat_alloc, 0x84),
1160+
CMN_EVENT_CCHA(CMN_ANY, rddatbyp, 0x61),
1161+
CMN_EVENT_CCHA(CMN_ANY, chirsp_up_stall, 0x62),
1162+
CMN_EVENT_CCHA(CMN_ANY, chidat_up_stall, 0x63),
1163+
CMN_EVENT_CCHA(CMN_ANY, snppcrd_link0_stall, 0x64),
1164+
CMN_EVENT_CCHA(CMN_ANY, snppcrd_link1_stall, 0x65),
1165+
CMN_EVENT_CCHA(CMN_ANY, snppcrd_link2_stall, 0x66),
1166+
CMN_EVENT_CCHA(CMN_ANY, reqtrk_occ, 0x67),
1167+
CMN_EVENT_CCHA(CMN_ANY, rdb_occ, 0x68),
1168+
CMN_EVENT_CCHA(CMN_ANY, rdbyp_occ, 0x69),
1169+
CMN_EVENT_CCHA(CMN_ANY, wdb_occ, 0x6a),
1170+
CMN_EVENT_CCHA(CMN_ANY, snptrk_occ, 0x6b),
1171+
CMN_EVENT_CCHA(CMN_ANY, sdb_occ, 0x6c),
1172+
CMN_EVENT_CCHA(CMN_ANY, snphaz_occ, 0x6d),
1173+
CMN_EVENT_CCHA(CMN_ANY, reqtrk_alloc, 0x6e),
1174+
CMN_EVENT_CCHA(CMN_ANY, rdb_alloc, 0x6f),
1175+
CMN_EVENT_CCHA(CMN_ANY, rdbyp_alloc, 0x70),
1176+
CMN_EVENT_CCHA(CMN_ANY, wdb_alloc, 0x71),
1177+
CMN_EVENT_CCHA(CMN_ANY, snptrk_alloc, 0x72),
1178+
CMN_EVENT_CCHA(CMN_ANY, db_alloc, 0x73),
1179+
CMN_EVENT_CCHA(CMN_ANY, snphaz_alloc, 0x74),
1180+
CMN_EVENT_CCHA(CMN_ANY, pb_rhu_req_occ, 0x75),
1181+
CMN_EVENT_CCHA(CMN_ANY, pb_rhu_req_alloc, 0x76),
1182+
CMN_EVENT_CCHA(CMN_ANY, pb_rhu_pcie_req_occ, 0x77),
1183+
CMN_EVENT_CCHA(CMN_ANY, pb_rhu_pcie_req_alloc, 0x78),
1184+
CMN_EVENT_CCHA(CMN_ANY, pb_pcie_wr_req_occ, 0x79),
1185+
CMN_EVENT_CCHA(CMN_ANY, pb_pcie_wr_req_alloc, 0x7a),
1186+
CMN_EVENT_CCHA(CMN_ANY, pb_pcie_reg_req_occ, 0x7b),
1187+
CMN_EVENT_CCHA(CMN_ANY, pb_pcie_reg_req_alloc, 0x7c),
1188+
CMN_EVENT_CCHA(CMN_ANY, pb_pcie_rsvd_req_occ, 0x7d),
1189+
CMN_EVENT_CCHA(CMN_ANY, pb_pcie_rsvd_req_alloc, 0x7e),
1190+
CMN_EVENT_CCHA(CMN_ANY, pb_rhu_dat_occ, 0x7f),
1191+
CMN_EVENT_CCHA(CMN_ANY, pb_rhu_dat_alloc, 0x80),
1192+
CMN_EVENT_CCHA(CMN_ANY, pb_rhu_pcie_dat_occ, 0x81),
1193+
CMN_EVENT_CCHA(CMN_ANY, pb_rhu_pcie_dat_alloc, 0x82),
1194+
CMN_EVENT_CCHA(CMN_ANY, pb_pcie_wr_dat_occ, 0x83),
1195+
CMN_EVENT_CCHA(CMN_ANY, pb_pcie_wr_dat_alloc, 0x84),
1196+
CMN_EVENT_CCHA(CMNS3, chirsp1_up_stall, 0x85),
11771197

11781198
CMN_EVENT_CCLA(rx_cxs, 0x21),
11791199
CMN_EVENT_CCLA(tx_cxs, 0x22),
@@ -1779,7 +1799,8 @@ static int arm_cmn_event_init(struct perf_event *event)
17791799
/* ...but the DTM may depend on which port we're watching */
17801800
if (cmn->multi_dtm)
17811801
hw->dtm_offset = CMN_EVENT_WP_DEV_SEL(event) / 2;
1782-
} else if (type == CMN_TYPE_XP && cmn->part == PART_CMN700) {
1802+
} else if (type == CMN_TYPE_XP &&
1803+
(cmn->part == PART_CMN700 || cmn->part == PART_CMN_S3)) {
17831804
hw->wide_sel = true;
17841805
}
17851806

@@ -2266,7 +2287,17 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
22662287
reg = readl_relaxed(cfg_region + CMN_CFGM_PERIPH_ID_23);
22672288
cmn->rev = FIELD_GET(CMN_CFGM_PID2_REVISION, reg);
22682289

2290+
/*
2291+
* With the device isolation feature, if firmware has neglected to enable
2292+
* an XP port then we risk locking up if we try to access anything behind
2293+
* it; however we also have no way to tell from Non-Secure whether any
2294+
* given port is disabled or not, so the only way to win is not to play...
2295+
*/
22692296
reg = readq_relaxed(cfg_region + CMN_CFGM_INFO_GLOBAL);
2297+
if (reg & CMN_INFO_DEVICE_ISO_ENABLE) {
2298+
dev_err(cmn->dev, "Device isolation enabled, not continuing due to risk of lockup\n");
2299+
return -ENODEV;
2300+
}
22702301
cmn->multi_dtm = reg & CMN_INFO_MULTIPLE_DTM_EN;
22712302
cmn->rsp_vc_num = FIELD_GET(CMN_INFO_RSP_VC_NUM, reg);
22722303
cmn->dat_vc_num = FIELD_GET(CMN_INFO_DAT_VC_NUM, reg);
@@ -2425,6 +2456,7 @@ static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
24252456
case CMN_TYPE_CXLA:
24262457
case CMN_TYPE_HNS_MPAM_S:
24272458
case CMN_TYPE_HNS_MPAM_NS:
2459+
case CMN_TYPE_APB:
24282460
break;
24292461
/*
24302462
* Split "optimised" combination nodes into separate
@@ -2610,6 +2642,7 @@ static const struct of_device_id arm_cmn_of_match[] = {
26102642
{ .compatible = "arm,cmn-600", .data = (void *)PART_CMN600 },
26112643
{ .compatible = "arm,cmn-650" },
26122644
{ .compatible = "arm,cmn-700" },
2645+
{ .compatible = "arm,cmn-s3" },
26132646
{ .compatible = "arm,ci-700" },
26142647
{}
26152648
};

0 commit comments

Comments
 (0)