Lines Matching refs:cmn

370 static int arm_cmn_xyidbits(const struct arm_cmn *cmn)
372 return fls((cmn->mesh_x - 1) | (cmn->mesh_y - 1) | 2);
375 static struct arm_cmn_nodeid arm_cmn_nid(const struct arm_cmn *cmn, u16 id)
379 if (cmn->num_xps == 1) {
385 int bits = arm_cmn_xyidbits(cmn);
389 if (cmn->ports_used & 0xc) {
400 static struct arm_cmn_node *arm_cmn_node_to_xp(const struct arm_cmn *cmn,
403 struct arm_cmn_nodeid nid = arm_cmn_nid(cmn, dn->id);
404 int xp_idx = cmn->mesh_x * nid.y + nid.x;
406 return cmn->xps + xp_idx;
408 static struct arm_cmn_node *arm_cmn_node(const struct arm_cmn *cmn,
413 for (dn = cmn->dns; dn->type; dn++)
419 static enum cmn_model arm_cmn_model(const struct arm_cmn *cmn)
421 switch (cmn->part) {
435 static u32 arm_cmn_device_connect_info(const struct arm_cmn *cmn,
441 if (cmn->part == PART_CMN600 || cmn->part == PART_CMN650)
447 if (cmn->part == PART_CI700)
494 struct arm_cmn *cmn = s->private;
497 for (dn = cmn->dns; dn->type; dn++) {
498 struct arm_cmn_nodeid nid = arm_cmn_nid(cmn, dn->id);
517 struct arm_cmn *cmn = s->private;
518 int x, y, p, pmax = fls(cmn->ports_used);
521 for (x = 0; x < cmn->mesh_x; x++)
524 y = cmn->mesh_y;
526 int xp_base = cmn->mesh_x * y;
529 for (x = 0; x < cmn->mesh_x; x++)
533 for (x = 0; x < cmn->mesh_x; x++) {
534 struct arm_cmn_node *xp = cmn->xps + xp_base + x;
537 port[p][x] = arm_cmn_device_connect_info(cmn, xp, p);
542 for (x = 0; x < cmn->mesh_x; x++) {
543 u8 dtc = cmn->xps[xp_base + x].dtc;
551 for (x = 0; x < cmn->mesh_x; x++)
556 for (x = 0; x < cmn->mesh_x; x++)
559 for (x = 0; x < cmn->mesh_x; x++)
562 for (x = 0; x < cmn->mesh_x; x++)
567 for (x = 0; x < cmn->mesh_x; x++)
574 static void arm_cmn_debugfs_init(struct arm_cmn *cmn, int id)
579 name = devm_kasprintf(cmn->dev, GFP_KERNEL, "map_%d", id);
583 cmn->debug = debugfs_create_file(name, 0444, arm_cmn_debugfs, cmn, &arm_cmn_map_fops);
586 static void arm_cmn_debugfs_init(struct arm_cmn *cmn, int id) {}
674 struct arm_cmn *cmn = to_cmn(dev_get_drvdata(dev));
681 if (!(eattr->model & arm_cmn_model(cmn)))
696 if ((intf & 4) && !(cmn->ports_used & BIT(intf & 3)))
699 if (chan == 4 && cmn->part == PART_CMN600)
702 if ((chan == 5 && cmn->rsp_vc_num < 2) ||
703 (chan == 6 && cmn->dat_vc_num < 2) ||
704 (chan == 7 && cmn->snp_vc_num < 2) ||
705 (chan == 8 && cmn->req_vc_num < 2))
710 if (cmn->part == PART_CMN600) {
711 if (cmn->rev < REV_CMN600_R1P3) {
715 if (cmn->rev < REV_CMN600_R1P2) {
721 } else if (cmn->part == PART_CMN650) {
722 if (cmn->rev < REV_CMN650_R2P0 || cmn->rev == REV_CMN650_R1P2) {
730 } else if (cmn->part == PART_CMN700) {
731 if (cmn->rev < REV_CMN700_R2P0) {
739 if (cmn->rev < REV_CMN700_R1P0) {
745 if (!arm_cmn_node(cmn, type))
1302 struct arm_cmn *cmn = to_cmn(dev_get_drvdata(dev));
1304 return cpumap_print_to_pagebuf(true, buf, cpumask_of(cmn->cpu));
1313 struct arm_cmn *cmn = to_cmn(dev_get_drvdata(dev));
1315 return sysfs_emit(buf, "%03x%02x\n", cmn->part, cmn->rev);
1366 static void arm_cmn_set_state(struct arm_cmn *cmn, u32 state)
1368 if (!cmn->state)
1369 writel_relaxed(0, cmn->dtc[0].base + CMN_DT_PMCR);
1370 cmn->state |= state;
1373 static void arm_cmn_clear_state(struct arm_cmn *cmn, u32 state)
1375 cmn->state &= ~state;
1376 if (!cmn->state)
1378 cmn->dtc[0].base + CMN_DT_PMCR);
1391 static u64 arm_cmn_read_dtm(struct arm_cmn *cmn, struct arm_cmn_hw_event *hw,
1401 if (dtm != &cmn->dtms[dn->dtm]) {
1402 dtm = &cmn->dtms[dn->dtm] + hw->dtm_offset;
1430 struct arm_cmn *cmn = to_cmn(event->pmu);
1436 writel_relaxed(CMN_COUNTER_INIT, cmn->dtc[i].base + pmevcnt);
1437 cmn->dtc[i].counters[hw->dtc_idx] = event;
1440 count = arm_cmn_read_dtm(cmn, hw, false);
1446 struct arm_cmn *cmn = to_cmn(event->pmu);
1454 delta = arm_cmn_read_cc(cmn->dtc + i);
1458 new = arm_cmn_read_dtm(cmn, hw, false);
1465 new = arm_cmn_read_counter(cmn->dtc + i, hw->dtc_idx);
1514 struct arm_cmn *cmn = to_cmn(event->pmu);
1522 writeq_relaxed(CMN_CC_INIT, cmn->dtc[i].base + CMN_DT_PMCCNTR);
1523 cmn->dtc[i].cc_active = true;
1545 struct arm_cmn *cmn = to_cmn(event->pmu);
1553 cmn->dtc[i].cc_active = false;
1580 static void arm_cmn_val_add_event(struct arm_cmn *cmn, struct arm_cmn_val *val,
1615 static int arm_cmn_validate_group(struct arm_cmn *cmn, struct perf_event *event)
1634 arm_cmn_val_add_event(cmn, val, leader);
1636 arm_cmn_val_add_event(cmn, val, sibling);
1675 static enum cmn_filter_select arm_cmn_filter_sel(const struct arm_cmn *cmn,
1680 enum cmn_model model = arm_cmn_model(cmn);
1693 struct arm_cmn *cmn = to_cmn(event->pmu);
1706 event->cpu = cmn->cpu;
1713 return arm_cmn_validate_group(cmn, event);
1723 if (cmn->multi_dtm)
1725 } else if (type == CMN_TYPE_XP && cmn->part == PART_CMN700) {
1730 hw->filter_sel = arm_cmn_filter_sel(cmn, type, eventid);
1735 hw->dn = arm_cmn_node(cmn, type);
1749 struct arm_cmn_nodeid nid = arm_cmn_nid(cmn, nodeid);
1751 dev_dbg(cmn->dev, "invalid node 0x%x (%d,%d,%d,%d) type 0x%x\n",
1760 hw->dtcs_used = (1U << cmn->num_dtcs) - 1;
1762 return arm_cmn_validate_group(cmn, event);
1765 static void arm_cmn_event_clear(struct arm_cmn *cmn, struct perf_event *event,
1772 struct arm_cmn_dtm *dtm = &cmn->dtms[hw->dn[i].dtm] + hw->dtm_offset;
1787 cmn->dtc[i].counters[hw->dtc_idx] = NULL;
1792 struct arm_cmn *cmn = to_cmn(event->pmu);
1794 struct arm_cmn_dtc *dtc = &cmn->dtc[0];
1801 while (cmn->dtc[i].cycles)
1802 if (++i == cmn->num_dtcs)
1805 cmn->dtc[i].cycles = event;
1824 struct arm_cmn_dtm *dtm = &cmn->dtms[dn->dtm] + hw->dtm_offset;
1851 struct arm_cmn_nodeid nid = arm_cmn_nid(cmn, dn->id);
1853 if (cmn->multi_dtm)
1883 arm_cmn_event_clear(cmn, event, i);
1889 struct arm_cmn *cmn = to_cmn(event->pmu);
1896 cmn->dtc[__ffs(hw->dtcs_used)].cycles = NULL;
1898 arm_cmn_event_clear(cmn, event, hw->num_dns);
1923 static void arm_cmn_migrate(struct arm_cmn *cmn, unsigned int cpu)
1927 perf_pmu_migrate_context(&cmn->pmu, cmn->cpu, cpu);
1928 for (i = 0; i < cmn->num_dtcs; i++)
1929 irq_set_affinity(cmn->dtc[i].irq, cpumask_of(cpu));
1930 cmn->cpu = cpu;
1935 struct arm_cmn *cmn;
1938 cmn = hlist_entry_safe(cpuhp_node, struct arm_cmn, cpuhp_node);
1939 node = dev_to_node(cmn->dev);
1940 if (node != NUMA_NO_NODE && cpu_to_node(cmn->cpu) != node && cpu_to_node(cpu) == node)
1941 arm_cmn_migrate(cmn, cpu);
1947 struct arm_cmn *cmn;
1952 cmn = hlist_entry_safe(cpuhp_node, struct arm_cmn, cpuhp_node);
1953 if (cpu != cmn->cpu)
1956 node = dev_to_node(cmn->dev);
1963 arm_cmn_migrate(cmn, target);
2004 static int arm_cmn_init_irqs(struct arm_cmn *cmn)
2008 for (i = 0; i < cmn->num_dtcs; i++) {
2009 irq = cmn->dtc[i].irq;
2011 if (cmn->dtc[j].irq == irq) {
2012 cmn->dtc[j].irq_friend = i - j;
2016 err = devm_request_irq(cmn->dev, irq, arm_cmn_handle_irq,
2018 dev_name(cmn->dev), &cmn->dtc[i]);
2022 err = irq_set_affinity(irq, cpumask_of(cmn->cpu));
2045 static int arm_cmn_init_dtc(struct arm_cmn *cmn, struct arm_cmn_node *dn, int idx)
2047 struct arm_cmn_dtc *dtc = cmn->dtc + idx;
2050 dtc->irq = platform_get_irq(to_platform_device(cmn->dev), idx);
2073 static int arm_cmn_init_dtcs(struct arm_cmn *cmn)
2077 u8 dtcs_present = (1 << cmn->num_dtcs) - 1;
2079 cmn->dtc = devm_kcalloc(cmn->dev, cmn->num_dtcs, sizeof(cmn->dtc[0]), GFP_KERNEL);
2080 if (!cmn->dtc)
2083 sort(cmn->dns, cmn->num_dns, sizeof(cmn->dns[0]), arm_cmn_node_cmp, NULL);
2085 cmn->xps = arm_cmn_node(cmn, CMN_TYPE_XP);
2087 for (dn = cmn->dns; dn->type; dn++) {
2093 xp = arm_cmn_node_to_xp(cmn, dn);
2095 if (cmn->multi_dtm)
2096 dn->dtm += arm_cmn_nid(cmn, dn->id).port / 2;
2103 err = arm_cmn_init_dtc(cmn, dn, dtc_idx++);
2117 arm_cmn_set_state(cmn, CMN_STATE_DISABLED);
2122 static unsigned int arm_cmn_dtc_domain(struct arm_cmn *cmn, void __iomem *xp_region)
2126 if (cmn->part == PART_CMN650 || cmn->part == PART_CI700)
2132 static void arm_cmn_init_node_info(struct arm_cmn *cmn, u32 offset, struct arm_cmn_node *node)
2135 u64 reg = readq_relaxed(cmn->base + offset + CMN_NODE_INFO);
2141 node->pmu_base = cmn->base + offset + CMN_PMU_OFFSET;
2150 dev_dbg(cmn->dev, "node%*c%#06hx%*ctype:%-#6x id:%-4hd off:%#x\n",
2167 static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
2179 arm_cmn_init_node_info(cmn, rgn_offset, &cfg);
2183 cfg_region = cmn->base + rgn_offset;
2188 if (cmn->part && cmn->part != part)
2189 dev_warn(cmn->dev,
2191 cmn->part, part);
2192 cmn->part = part;
2193 if (!arm_cmn_model(cmn))
2194 dev_warn(cmn->dev, "Unknown part number: 0x%x\n", part);
2197 cmn->rev = FIELD_GET(CMN_CFGM_PID2_REVISION, reg);
2200 cmn->multi_dtm = reg & CMN_INFO_MULTIPLE_DTM_EN;
2201 cmn->rsp_vc_num = FIELD_GET(CMN_INFO_RSP_VC_NUM, reg);
2202 cmn->dat_vc_num = FIELD_GET(CMN_INFO_DAT_VC_NUM, reg);
2205 cmn->snp_vc_num = FIELD_GET(CMN_INFO_SNP_VC_NUM, reg);
2206 cmn->req_vc_num = FIELD_GET(CMN_INFO_REQ_VC_NUM, reg);
2212 cmn->num_xps = child_count;
2213 cmn->num_dns = cmn->num_xps;
2216 for (i = 0; i < cmn->num_xps; i++) {
2220 reg = readq_relaxed(cmn->base + xp_offset[i] + CMN_CHILD_INFO);
2221 cmn->num_dns += FIELD_GET(CMN_CI_CHILD_COUNT, reg);
2229 dn = devm_kcalloc(cmn->dev, cmn->num_dns * 2 - cmn->num_xps,
2235 i = cmn->num_xps;
2236 if (cmn->multi_dtm)
2237 i += cmn->num_xps + 1;
2238 dtm = devm_kcalloc(cmn->dev, i, sizeof(*dtm), GFP_KERNEL);
2243 cmn->dns = dn;
2244 cmn->dtms = dtm;
2245 for (i = 0; i < cmn->num_xps; i++) {
2246 void __iomem *xp_region = cmn->base + xp_offset[i];
2250 arm_cmn_init_node_info(cmn, xp_offset[i], xp);
2258 cmn->mesh_x = xp->logid;
2260 if (cmn->part == PART_CMN600)
2263 xp->dtc = 1 << arm_cmn_dtc_domain(cmn, xp_region);
2265 xp->dtm = dtm - cmn->dtms;
2275 if (arm_cmn_device_connect_info(cmn, xp, p))
2278 if (cmn->multi_dtm && (xp_ports & 0xc))
2280 if (cmn->multi_dtm && (xp_ports & 0x30))
2283 cmn->ports_used |= xp_ports;
2301 dev_dbg(cmn->dev, "ignoring external node %llx\n", reg);
2311 if (reg == 0 && cmn->part != PART_CMN600) {
2312 dev_dbg(cmn->dev, "bogus child pointer?\n");
2316 arm_cmn_init_node_info(cmn, reg & CMN_CHILD_NODE_ADDR, dn);
2320 cmn->num_dtcs++;
2362 dev_err(cmn->dev, "invalid device node type: 0x%x\n", dn->type);
2369 cmn->num_dns = dn - cmn->dns;
2372 sz = (void *)(dn + 1) - (void *)cmn->dns;
2373 dn = devm_krealloc(cmn->dev, cmn->dns, sz, GFP_KERNEL);
2375 cmn->dns = dn;
2377 sz = (void *)dtm - (void *)cmn->dtms;
2378 dtm = devm_krealloc(cmn->dev, cmn->dtms, sz, GFP_KERNEL);
2380 cmn->dtms = dtm;
2386 if (!cmn->mesh_x)
2387 cmn->mesh_x = cmn->num_xps;
2388 cmn->mesh_y = cmn->num_xps / cmn->mesh_x;
2391 if (cmn->num_xps == 1)
2392 dev_warn(cmn->dev, "1x1 config not fully supported, translate XP events manually\n");
2394 dev_dbg(cmn->dev, "periph_id part 0x%03x revision %d\n", cmn->part, cmn->rev);
2395 reg = cmn->ports_used;
2396 dev_dbg(cmn->dev, "mesh %dx%d, ID width %d, ports %6pbl%s\n",
2397 cmn->mesh_x, cmn->mesh_y, arm_cmn_xyidbits(cmn), &reg,
2398 cmn->multi_dtm ? ", multi-DTM" : "");
2403 static int arm_cmn600_acpi_probe(struct platform_device *pdev, struct arm_cmn *cmn)
2423 cmn->base = devm_ioremap(cmn->dev, cfg->start, resource_size(cfg));
2424 if (!cmn->base)
2439 struct arm_cmn *cmn;
2444 cmn = devm_kzalloc(&pdev->dev, sizeof(*cmn), GFP_KERNEL);
2445 if (!cmn)
2448 cmn->dev = &pdev->dev;
2449 cmn->part = (unsigned long)device_get_match_data(cmn->dev);
2450 platform_set_drvdata(pdev, cmn);
2452 if (cmn->part == PART_CMN600 && has_acpi_companion(cmn->dev)) {
2453 rootnode = arm_cmn600_acpi_probe(pdev, cmn);
2456 cmn->base = devm_platform_ioremap_resource(pdev, 0);
2457 if (IS_ERR(cmn->base))
2458 return PTR_ERR(cmn->base);
2459 if (cmn->part == PART_CMN600)
2465 err = arm_cmn_discover(cmn, rootnode);
2469 err = arm_cmn_init_dtcs(cmn);
2473 err = arm_cmn_init_irqs(cmn);
2477 cmn->cpu = cpumask_local_spread(0, dev_to_node(cmn->dev));
2478 cmn->pmu = (struct pmu) {
2497 name = devm_kasprintf(cmn->dev, GFP_KERNEL, "arm_cmn_%d", this_id);
2501 err = cpuhp_state_add_instance(arm_cmn_hp_state, &cmn->cpuhp_node);
2505 err = perf_pmu_register(&cmn->pmu, name, -1);
2507 cpuhp_state_remove_instance_nocalls(arm_cmn_hp_state, &cmn->cpuhp_node);
2509 arm_cmn_debugfs_init(cmn, this_id);
2516 struct arm_cmn *cmn = platform_get_drvdata(pdev);
2518 writel_relaxed(0, cmn->dtc[0].base + CMN_DT_DTC_CTL);
2520 perf_pmu_unregister(&cmn->pmu);
2521 cpuhp_state_remove_instance_nocalls(arm_cmn_hp_state, &cmn->cpuhp_node);
2522 debugfs_remove(cmn->debug);
2528 { .compatible = "arm,cmn-600", .data = (void *)PART_CMN600 },
2529 { .compatible = "arm,cmn-650" },
2530 { .compatible = "arm,cmn-700" },
2549 .name = "arm-cmn",
2562 "perf/arm/cmn:online",
2569 arm_cmn_debugfs = debugfs_create_dir("arm-cmn", NULL);