Lines Matching refs:cmn
297 static int arm_cmn_xyidbits(const struct arm_cmn *cmn)
299 return cmn->mesh_x > 4 || cmn->mesh_y > 4 ? 3 : 2;
302 static void arm_cmn_init_node_to_xp(const struct arm_cmn *cmn,
305 int bits = arm_cmn_xyidbits(cmn);
308 int xp_idx = cmn->mesh_x * y + x;
310 dn->to_xp = (cmn->xps + xp_idx) - dn;
318 static struct arm_cmn_node *arm_cmn_node(const struct arm_cmn *cmn,
323 for (i = 0; i < cmn->num_dns; i++)
324 if (cmn->dns[i].type == type)
325 return &cmn->dns[i];
371 struct arm_cmn *cmn = to_cmn(dev_get_drvdata(dev));
383 if (cmn->rev < CMN600_R1P2) {
388 if (!arm_cmn_node(cmn, type))
606 struct arm_cmn *cmn = to_cmn(dev_get_drvdata(dev));
608 return cpumap_print_to_pagebuf(true, buf, cpumask_of(cmn->cpu));
654 static void arm_cmn_set_state(struct arm_cmn *cmn, u32 state)
656 if (!cmn->state)
657 writel_relaxed(0, cmn->dtc[0].base + CMN_DT_PMCR);
658 cmn->state |= state;
661 static void arm_cmn_clear_state(struct arm_cmn *cmn, u32 state)
663 cmn->state &= ~state;
664 if (!cmn->state)
666 cmn->dtc[0].base + CMN_DT_PMCR);
679 static u64 arm_cmn_read_dtm(struct arm_cmn *cmn, struct arm_cmn_hw_event *hw,
717 struct arm_cmn *cmn = to_cmn(event->pmu);
723 writel_relaxed(CMN_COUNTER_INIT, cmn->dtc[i].base + pmevcnt);
724 cmn->dtc[i].counters[hw->dtc_idx] = event;
727 count = arm_cmn_read_dtm(cmn, hw, false);
733 struct arm_cmn *cmn = to_cmn(event->pmu);
741 delta = arm_cmn_read_cc(cmn->dtc + i);
745 new = arm_cmn_read_dtm(cmn, hw, false);
752 new = arm_cmn_read_counter(cmn->dtc + i, hw->dtc_idx);
761 struct arm_cmn *cmn = to_cmn(event->pmu);
769 writeq_relaxed(CMN_CC_INIT, cmn->dtc[i].base + CMN_DT_PMCCNTR);
770 cmn->dtc[i].cc_active = true;
790 struct arm_cmn *cmn = to_cmn(event->pmu);
798 cmn->dtc[i].cc_active = false;
921 struct arm_cmn *cmn = to_cmn(event->pmu);
934 event->cpu = cmn->cpu;
955 hw->dn = arm_cmn_node(cmn, type);
956 for (i = hw->dn - cmn->dns; i < cmn->num_dns && cmn->dns[i].type == type; i++) {
959 } else if (cmn->dns[i].id != nodeid) {
968 int bits = arm_cmn_xyidbits(cmn);
970 dev_dbg(cmn->dev, "invalid node 0x%x (%d,%d,%d,%d) type 0x%x\n",
979 hw->dtcs_used = (1U << cmn->num_dtcs) - 1;
984 static void arm_cmn_event_clear(struct arm_cmn *cmn, struct perf_event *event,
1006 cmn->dtc[i].counters[hw->dtc_idx] = NULL;
1011 struct arm_cmn *cmn = to_cmn(event->pmu);
1013 struct arm_cmn_dtc *dtc = &cmn->dtc[0];
1020 while (cmn->dtc[i].cycles)
1021 if (++i == cmn->num_dtcs)
1024 cmn->dtc[i].cycles = event;
1110 arm_cmn_event_clear(cmn, event, i);
1116 struct arm_cmn *cmn = to_cmn(event->pmu);
1123 cmn->dtc[__ffs(hw->dtcs_used)].cycles = NULL;
1125 arm_cmn_event_clear(cmn, event, hw->num_dns);
1152 struct arm_cmn *cmn;
1155 cmn = hlist_entry_safe(node, struct arm_cmn, cpuhp_node);
1156 if (cpu != cmn->cpu)
1163 perf_pmu_migrate_context(&cmn->pmu, cpu, target);
1164 for (i = 0; i < cmn->num_dtcs; i++)
1165 irq_set_affinity_hint(cmn->dtc[i].irq, cpumask_of(target));
1166 cmn->cpu = target;
1207 static int arm_cmn_init_irqs(struct arm_cmn *cmn)
1211 for (i = 0; i < cmn->num_dtcs; i++) {
1212 irq = cmn->dtc[i].irq;
1214 if (cmn->dtc[j].irq == irq) {
1215 cmn->dtc[j].irq_friend = i - j;
1219 err = devm_request_irq(cmn->dev, irq, arm_cmn_handle_irq,
1221 dev_name(cmn->dev), &cmn->dtc[i]);
1225 err = irq_set_affinity_hint(irq, cpumask_of(cmn->cpu));
1247 static int arm_cmn_init_dtc(struct arm_cmn *cmn, struct arm_cmn_node *dn, int idx)
1249 struct arm_cmn_dtc *dtc = cmn->dtc + idx;
1253 dtc->irq = platform_get_irq(to_platform_device(cmn->dev), idx);
1280 static int arm_cmn_init_dtcs(struct arm_cmn *cmn)
1285 cmn->dtc = devm_kcalloc(cmn->dev, cmn->num_dtcs, sizeof(cmn->dtc[0]), GFP_KERNEL);
1286 if (!cmn->dtc)
1289 sort(cmn->dns, cmn->num_dns, sizeof(cmn->dns[0]), arm_cmn_node_cmp, NULL);
1291 cmn->xps = arm_cmn_node(cmn, CMN_TYPE_XP);
1293 for (dn = cmn->dns; dn < cmn->dns + cmn->num_dns; dn++) {
1295 arm_cmn_init_node_to_xp(cmn, dn);
1296 else if (cmn->num_dtcs == 1)
1300 arm_cmn_init_dtc(cmn, dn, dtc_idx++);
1307 arm_cmn_set_state(cmn, CMN_STATE_DISABLED);
1312 static void arm_cmn_init_node_info(struct arm_cmn *cmn, u32 offset, struct arm_cmn_node *node)
1315 u64 reg = readq_relaxed(cmn->base + offset + CMN_NODE_INFO);
1321 node->pmu_base = cmn->base + offset + CMN_PMU_OFFSET;
1330 dev_dbg(cmn->dev, "node%*c%#06hx%*ctype:%-#6x id:%-4hd off:%#x\n",
1335 static int arm_cmn_discover(struct arm_cmn *cmn, unsigned int rgn_offset)
1344 cfg_region = cmn->base + rgn_offset;
1346 cmn->rev = FIELD_GET(CMN_CFGM_PID2_REVISION, reg);
1347 dev_dbg(cmn->dev, "periph_id_2 revision: %d\n", cmn->rev);
1349 arm_cmn_init_node_info(cmn, rgn_offset, &cfg);
1357 cmn->num_xps = child_count;
1358 cmn->num_dns = cmn->num_xps;
1361 for (i = 0; i < cmn->num_xps; i++) {
1365 reg = readq_relaxed(cmn->base + xp_offset[i] + CMN_CHILD_INFO);
1366 cmn->num_dns += FIELD_GET(CMN_CI_CHILD_COUNT, reg);
1370 cmn->dns = devm_kcalloc(cmn->dev, cmn->num_dns + 1,
1371 sizeof(*cmn->dns), GFP_KERNEL);
1372 if (!cmn->dns)
1376 dn = cmn->dns;
1377 for (i = 0; i < cmn->num_xps; i++) {
1378 void __iomem *xp_region = cmn->base + xp_offset[i];
1381 arm_cmn_init_node_info(cmn, xp_offset[i], xp);
1390 cmn->mesh_x = xp->logid;
1408 dev_dbg(cmn->dev, "ignoring external node %llx\n", reg);
1412 arm_cmn_init_node_info(cmn, reg & CMN_CHILD_NODE_ADDR, dn);
1416 cmn->num_dtcs++;
1436 dev_err(cmn->dev, "invalid device node type: 0x%x\n", dn->type);
1443 cmn->num_dns = dn - cmn->dns;
1449 if (!cmn->mesh_x)
1450 cmn->mesh_x = cmn->num_xps;
1451 cmn->mesh_y = cmn->num_xps / cmn->mesh_x;
1453 dev_dbg(cmn->dev, "mesh %dx%d, ID width %d\n",
1454 cmn->mesh_x, cmn->mesh_y, arm_cmn_xyidbits(cmn));
1459 static int arm_cmn_acpi_probe(struct platform_device *pdev, struct arm_cmn *cmn)
1479 cmn->base = devm_ioremap(cmn->dev, cfg->start, resource_size(cfg));
1480 if (!cmn->base)
1486 static int arm_cmn_of_probe(struct platform_device *pdev, struct arm_cmn *cmn)
1492 cmn->base = devm_platform_ioremap_resource(pdev, 0);
1493 if (IS_ERR(cmn->base))
1494 return PTR_ERR(cmn->base);
1505 struct arm_cmn *cmn;
1510 cmn = devm_kzalloc(&pdev->dev, sizeof(*cmn), GFP_KERNEL);
1511 if (!cmn)
1514 cmn->dev = &pdev->dev;
1515 platform_set_drvdata(pdev, cmn);
1517 if (has_acpi_companion(cmn->dev))
1518 rootnode = arm_cmn_acpi_probe(pdev, cmn);
1520 rootnode = arm_cmn_of_probe(pdev, cmn);
1524 err = arm_cmn_discover(cmn, rootnode);
1528 err = arm_cmn_init_dtcs(cmn);
1532 err = arm_cmn_init_irqs(cmn);
1536 cmn->cpu = raw_smp_processor_id();
1537 cmn->pmu = (struct pmu) {
1555 name = devm_kasprintf(cmn->dev, GFP_KERNEL, "arm_cmn_%d", atomic_fetch_inc(&id));
1559 err = cpuhp_state_add_instance(arm_cmn_hp_state, &cmn->cpuhp_node);
1563 err = perf_pmu_register(&cmn->pmu, name, -1);
1565 cpuhp_state_remove_instance(arm_cmn_hp_state, &cmn->cpuhp_node);
1571 struct arm_cmn *cmn = platform_get_drvdata(pdev);
1574 writel_relaxed(0, cmn->dtc[0].base + CMN_DT_DTC_CTL);
1576 perf_pmu_unregister(&cmn->pmu);
1577 cpuhp_state_remove_instance(arm_cmn_hp_state, &cmn->cpuhp_node);
1579 for (i = 0; i < cmn->num_dtcs; i++)
1580 irq_set_affinity_hint(cmn->dtc[i].irq, NULL);
1587 { .compatible = "arm,cmn-600", },
1603 .name = "arm-cmn",
1616 "perf/arm/cmn:online", NULL,