Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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 <mark.rutland@arm.com>
Reviewed-by: Ilkka Koskinen <ilkka@os.amperecomputing.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Link: https://lore.kernel.org/r/2ec9eec5b6bf215a9886f3b69e3b00e4cd85095c.1725296395.git.robin.murphy@arm.com
Signed-off-by: Will Deacon <will@kernel.org>

authored by

Robin Murphy and committed by
Will Deacon
0dc2f496 a87ef537

+76 -43
+76 -43
drivers/perf/arm-cmn.c
··· 45 45 #define CMN_CFGM_PERIPH_ID_23 0x0010 46 46 #define CMN_CFGM_PID2_REVISION GENMASK_ULL(7, 4) 47 47 48 - #define CMN_CFGM_INFO_GLOBAL 0x900 48 + #define CMN_CFGM_INFO_GLOBAL 0x0900 49 49 #define CMN_INFO_MULTIPLE_DTM_EN BIT_ULL(63) 50 50 #define CMN_INFO_RSP_VC_NUM GENMASK_ULL(53, 52) 51 51 #define CMN_INFO_DAT_VC_NUM GENMASK_ULL(51, 50) 52 + #define CMN_INFO_DEVICE_ISO_ENABLE BIT_ULL(44) 52 53 53 - #define CMN_CFGM_INFO_GLOBAL_1 0x908 54 + #define CMN_CFGM_INFO_GLOBAL_1 0x0908 54 55 #define CMN_INFO_SNP_VC_NUM GENMASK_ULL(3, 2) 55 56 #define CMN_INFO_REQ_VC_NUM GENMASK_ULL(1, 0) 56 57 57 58 /* XPs also have some local topology info which has uses too */ 58 59 #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) 60 61 61 62 #define CMN_MAX_PORTS 6 62 63 #define CI700_CONNECT_INFO_P2_5_OFFSET 0x10 63 64 64 65 /* PMU registers occupy the 3rd 4KB page of each node's region */ 65 66 #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 66 70 67 71 /* For most nodes, this is all there is */ 68 72 #define CMN_PMU_EVENT_SEL 0x000 ··· 199 195 CMN650 = 2, 200 196 CMN700 = 4, 201 197 CI700 = 8, 198 + CMNS3 = 16, 202 199 /* ...and then we can use bitmap tricks for commonality */ 203 200 CMN_ANY = -1, 204 201 NOT_CMN600 = -2, 205 - CMN_650ON = CMN650 | CMN700, 202 + CMN_650ON = CMN650 | CMN700 | CMNS3, 206 203 }; 207 204 208 205 /* Actual part numbers and revision IDs defined by the hardware */ ··· 212 207 PART_CMN650 = 0x436, 213 208 PART_CMN700 = 0x43c, 214 209 PART_CI700 = 0x43a, 210 + PART_CMN_S3 = 0x43e, 215 211 }; 216 212 217 213 /* CMN-600 r0px shouldn't exist in silicon, thankfully */ ··· 264 258 CMN_TYPE_HNS = 0x200, 265 259 CMN_TYPE_HNS_MPAM_S, 266 260 CMN_TYPE_HNS_MPAM_NS, 261 + CMN_TYPE_APB = 0x1000, 267 262 /* Not a real node type */ 268 263 CMN_TYPE_WP = 0x7770 269 264 }; ··· 415 408 return CMN700; 416 409 case PART_CI700: 417 410 return CI700; 411 + case PART_CMN_S3: 412 + return CMNS3; 418 413 default: 419 414 return 0; 420 415 }; ··· 424 415 425 416 static int arm_cmn_pmu_offset(const struct arm_cmn *cmn, const struct arm_cmn_node *dn) 426 417 { 418 + if (cmn->part == PART_CMN_S3) { 419 + if (dn->type == CMN_TYPE_XP) 420 + return CMN_S3_DTM_OFFSET; 421 + return CMN_S3_PMU_OFFSET; 422 + } 427 423 return CMN_PMU_OFFSET; 428 424 } 429 425 ··· 482 468 case 0x17: return "RN-F_C_E|"; 483 469 case 0x18: return " RN-F_E |"; 484 470 case 0x19: return "RN-F_E_E|"; 471 + case 0x1a: return " HN-S |"; 472 + case 0x1b: return " LCN |"; 485 473 case 0x1c: return " MTSX |"; 486 474 case 0x1d: return " HN-V |"; 487 475 case 0x1e: return " CCG |"; 476 + case 0x20: return " RN-F_F |"; 477 + case 0x21: return "RN-F_F_E|"; 478 + case 0x22: return " SN-F_F |"; 488 479 default: return " ???? |"; 489 480 } 490 481 } ··· 798 779 CMN_EVENT_ATTR(CMN_ANY, cxha_##_name, CMN_TYPE_CXHA, _event) 799 780 #define CMN_EVENT_CCRA(_name, _event) \ 800 781 CMN_EVENT_ATTR(CMN_ANY, ccra_##_name, CMN_TYPE_CCRA, _event) 801 - #define CMN_EVENT_CCHA(_name, _event) \ 802 - CMN_EVENT_ATTR(CMN_ANY, ccha_##_name, CMN_TYPE_CCHA, _event) 782 + #define CMN_EVENT_CCHA(_model, _name, _event) \ 783 + CMN_EVENT_ATTR(_model, ccha_##_name, CMN_TYPE_CCHA, _event) 803 784 #define CMN_EVENT_CCLA(_name, _event) \ 804 785 CMN_EVENT_ATTR(CMN_ANY, ccla_##_name, CMN_TYPE_CCLA, _event) 805 786 #define CMN_EVENT_CCLA_RNI(_name, _event) \ ··· 1157 1138 CMN_EVENT_CCRA(wdb_alloc, 0x59), 1158 1139 CMN_EVENT_CCRA(ssb_alloc, 0x5a), 1159 1140 1160 - CMN_EVENT_CCHA(rddatbyp, 0x61), 1161 - CMN_EVENT_CCHA(chirsp_up_stall, 0x62), 1162 - CMN_EVENT_CCHA(chidat_up_stall, 0x63), 1163 - CMN_EVENT_CCHA(snppcrd_link0_stall, 0x64), 1164 - CMN_EVENT_CCHA(snppcrd_link1_stall, 0x65), 1165 - CMN_EVENT_CCHA(snppcrd_link2_stall, 0x66), 1166 - CMN_EVENT_CCHA(reqtrk_occ, 0x67), 1167 - CMN_EVENT_CCHA(rdb_occ, 0x68), 1168 - CMN_EVENT_CCHA(rdbyp_occ, 0x69), 1169 - CMN_EVENT_CCHA(wdb_occ, 0x6a), 1170 - CMN_EVENT_CCHA(snptrk_occ, 0x6b), 1171 - CMN_EVENT_CCHA(sdb_occ, 0x6c), 1172 - CMN_EVENT_CCHA(snphaz_occ, 0x6d), 1173 - CMN_EVENT_CCHA(reqtrk_alloc, 0x6e), 1174 - CMN_EVENT_CCHA(rdb_alloc, 0x6f), 1175 - CMN_EVENT_CCHA(rdbyp_alloc, 0x70), 1176 - CMN_EVENT_CCHA(wdb_alloc, 0x71), 1177 - CMN_EVENT_CCHA(snptrk_alloc, 0x72), 1178 - CMN_EVENT_CCHA(sdb_alloc, 0x73), 1179 - CMN_EVENT_CCHA(snphaz_alloc, 0x74), 1180 - CMN_EVENT_CCHA(pb_rhu_req_occ, 0x75), 1181 - CMN_EVENT_CCHA(pb_rhu_req_alloc, 0x76), 1182 - CMN_EVENT_CCHA(pb_rhu_pcie_req_occ, 0x77), 1183 - CMN_EVENT_CCHA(pb_rhu_pcie_req_alloc, 0x78), 1184 - CMN_EVENT_CCHA(pb_pcie_wr_req_occ, 0x79), 1185 - CMN_EVENT_CCHA(pb_pcie_wr_req_alloc, 0x7a), 1186 - CMN_EVENT_CCHA(pb_pcie_reg_req_occ, 0x7b), 1187 - CMN_EVENT_CCHA(pb_pcie_reg_req_alloc, 0x7c), 1188 - CMN_EVENT_CCHA(pb_pcie_rsvd_req_occ, 0x7d), 1189 - CMN_EVENT_CCHA(pb_pcie_rsvd_req_alloc, 0x7e), 1190 - CMN_EVENT_CCHA(pb_rhu_dat_occ, 0x7f), 1191 - CMN_EVENT_CCHA(pb_rhu_dat_alloc, 0x80), 1192 - CMN_EVENT_CCHA(pb_rhu_pcie_dat_occ, 0x81), 1193 - CMN_EVENT_CCHA(pb_rhu_pcie_dat_alloc, 0x82), 1194 - CMN_EVENT_CCHA(pb_pcie_wr_dat_occ, 0x83), 1195 - CMN_EVENT_CCHA(pb_pcie_wr_dat_alloc, 0x84), 1141 + CMN_EVENT_CCHA(CMN_ANY, rddatbyp, 0x61), 1142 + CMN_EVENT_CCHA(CMN_ANY, chirsp_up_stall, 0x62), 1143 + CMN_EVENT_CCHA(CMN_ANY, chidat_up_stall, 0x63), 1144 + CMN_EVENT_CCHA(CMN_ANY, snppcrd_link0_stall, 0x64), 1145 + CMN_EVENT_CCHA(CMN_ANY, snppcrd_link1_stall, 0x65), 1146 + CMN_EVENT_CCHA(CMN_ANY, snppcrd_link2_stall, 0x66), 1147 + CMN_EVENT_CCHA(CMN_ANY, reqtrk_occ, 0x67), 1148 + CMN_EVENT_CCHA(CMN_ANY, rdb_occ, 0x68), 1149 + CMN_EVENT_CCHA(CMN_ANY, rdbyp_occ, 0x69), 1150 + CMN_EVENT_CCHA(CMN_ANY, wdb_occ, 0x6a), 1151 + CMN_EVENT_CCHA(CMN_ANY, snptrk_occ, 0x6b), 1152 + CMN_EVENT_CCHA(CMN_ANY, sdb_occ, 0x6c), 1153 + CMN_EVENT_CCHA(CMN_ANY, snphaz_occ, 0x6d), 1154 + CMN_EVENT_CCHA(CMN_ANY, reqtrk_alloc, 0x6e), 1155 + CMN_EVENT_CCHA(CMN_ANY, rdb_alloc, 0x6f), 1156 + CMN_EVENT_CCHA(CMN_ANY, rdbyp_alloc, 0x70), 1157 + CMN_EVENT_CCHA(CMN_ANY, wdb_alloc, 0x71), 1158 + CMN_EVENT_CCHA(CMN_ANY, snptrk_alloc, 0x72), 1159 + CMN_EVENT_CCHA(CMN_ANY, db_alloc, 0x73), 1160 + CMN_EVENT_CCHA(CMN_ANY, snphaz_alloc, 0x74), 1161 + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_req_occ, 0x75), 1162 + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_req_alloc, 0x76), 1163 + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_pcie_req_occ, 0x77), 1164 + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_pcie_req_alloc, 0x78), 1165 + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_wr_req_occ, 0x79), 1166 + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_wr_req_alloc, 0x7a), 1167 + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_reg_req_occ, 0x7b), 1168 + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_reg_req_alloc, 0x7c), 1169 + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_rsvd_req_occ, 0x7d), 1170 + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_rsvd_req_alloc, 0x7e), 1171 + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_dat_occ, 0x7f), 1172 + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_dat_alloc, 0x80), 1173 + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_pcie_dat_occ, 0x81), 1174 + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_pcie_dat_alloc, 0x82), 1175 + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_wr_dat_occ, 0x83), 1176 + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_wr_dat_alloc, 0x84), 1177 + CMN_EVENT_CCHA(CMNS3, chirsp1_up_stall, 0x85), 1196 1178 1197 1179 CMN_EVENT_CCLA(rx_cxs, 0x21), 1198 1180 CMN_EVENT_CCLA(tx_cxs, 0x22), ··· 1799 1779 /* ...but the DTM may depend on which port we're watching */ 1800 1780 if (cmn->multi_dtm) 1801 1781 hw->dtm_offset = CMN_EVENT_WP_DEV_SEL(event) / 2; 1802 - } else if (type == CMN_TYPE_XP && cmn->part == PART_CMN700) { 1782 + } else if (type == CMN_TYPE_XP && 1783 + (cmn->part == PART_CMN700 || cmn->part == PART_CMN_S3)) { 1803 1784 hw->wide_sel = true; 1804 1785 } 1805 1786 ··· 2287 2266 reg = readl_relaxed(cfg_region + CMN_CFGM_PERIPH_ID_23); 2288 2267 cmn->rev = FIELD_GET(CMN_CFGM_PID2_REVISION, reg); 2289 2268 2269 + /* 2270 + * With the device isolation feature, if firmware has neglected to enable 2271 + * an XP port then we risk locking up if we try to access anything behind 2272 + * it; however we also have no way to tell from Non-Secure whether any 2273 + * given port is disabled or not, so the only way to win is not to play... 2274 + */ 2290 2275 reg = readq_relaxed(cfg_region + CMN_CFGM_INFO_GLOBAL); 2276 + if (reg & CMN_INFO_DEVICE_ISO_ENABLE) { 2277 + dev_err(cmn->dev, "Device isolation enabled, not continuing due to risk of lockup\n"); 2278 + return -ENODEV; 2279 + } 2291 2280 cmn->multi_dtm = reg & CMN_INFO_MULTIPLE_DTM_EN; 2292 2281 cmn->rsp_vc_num = FIELD_GET(CMN_INFO_RSP_VC_NUM, reg); 2293 2282 cmn->dat_vc_num = FIELD_GET(CMN_INFO_DAT_VC_NUM, reg); ··· 2456 2425 case CMN_TYPE_CXLA: 2457 2426 case CMN_TYPE_HNS_MPAM_S: 2458 2427 case CMN_TYPE_HNS_MPAM_NS: 2428 + case CMN_TYPE_APB: 2459 2429 break; 2460 2430 /* 2461 2431 * Split "optimised" combination nodes into separate ··· 2642 2610 { .compatible = "arm,cmn-600", .data = (void *)PART_CMN600 }, 2643 2611 { .compatible = "arm,cmn-650" }, 2644 2612 { .compatible = "arm,cmn-700" }, 2613 + { .compatible = "arm,cmn-s3" }, 2645 2614 { .compatible = "arm,ci-700" }, 2646 2615 {} 2647 2616 };