Lines Matching full:ccn

326 	struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev));  in arm_ccn_pmu_event_show()  local
353 res += sysfs_emit_at(buf, res, ",node=%d", ccn->mn_id); in arm_ccn_pmu_event_show()
369 struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev)); in arm_ccn_pmu_events_is_visible() local
375 if (event->type == CCN_TYPE_SBAS && !ccn->sbas_present) in arm_ccn_pmu_events_is_visible()
377 if (event->type == CCN_TYPE_SBSX && !ccn->sbsx_present) in arm_ccn_pmu_events_is_visible()
450 static u64 *arm_ccn_pmu_get_cmp_mask(struct arm_ccn *ccn, const char *name) in arm_ccn_pmu_get_cmp_mask() argument
460 return &ccn->dt.cmp_mask[i].l; in arm_ccn_pmu_get_cmp_mask()
462 return &ccn->dt.cmp_mask[i].h; in arm_ccn_pmu_get_cmp_mask()
471 struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev)); in arm_ccn_pmu_cmp_mask_show() local
472 u64 *mask = arm_ccn_pmu_get_cmp_mask(ccn, attr->attr.name); in arm_ccn_pmu_cmp_mask_show()
480 struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev)); in arm_ccn_pmu_cmp_mask_store() local
481 u64 *mask = arm_ccn_pmu_get_cmp_mask(ccn, attr->attr.name); in arm_ccn_pmu_cmp_mask_store()
548 struct arm_ccn *ccn = pmu_to_arm_ccn(dev_get_drvdata(dev)); in arm_ccn_pmu_cpumask_show() local
550 return cpumap_print_to_pagebuf(true, buf, cpumask_of(ccn->dt.cpu)); in arm_ccn_pmu_cpumask_show()
633 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); in arm_ccn_pmu_event_alloc() local
646 ccn->dt.pmu_counters_mask)) in arm_ccn_pmu_event_alloc()
650 ccn->dt.pmu_counters[CCN_IDX_PMU_CYCLE_COUNTER].event = event; in arm_ccn_pmu_event_alloc()
656 hw->idx = arm_ccn_pmu_alloc_bit(ccn->dt.pmu_counters_mask, in arm_ccn_pmu_event_alloc()
659 dev_dbg(ccn->dev, "No more counters available!\n"); in arm_ccn_pmu_event_alloc()
664 source = &ccn->xp[node_xp]; in arm_ccn_pmu_event_alloc()
666 source = &ccn->node[node_xp]; in arm_ccn_pmu_event_alloc()
667 ccn->dt.pmu_counters[hw->idx].source = source; in arm_ccn_pmu_event_alloc()
677 dev_dbg(ccn->dev, "No more event sources/watchpoints on node/XP %d!\n", in arm_ccn_pmu_event_alloc()
679 clear_bit(hw->idx, ccn->dt.pmu_counters_mask); in arm_ccn_pmu_event_alloc()
684 ccn->dt.pmu_counters[hw->idx].event = event; in arm_ccn_pmu_event_alloc()
691 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); in arm_ccn_pmu_event_release() local
695 clear_bit(CCN_IDX_PMU_CYCLE_COUNTER, ccn->dt.pmu_counters_mask); in arm_ccn_pmu_event_release()
698 ccn->dt.pmu_counters[hw->idx].source; in arm_ccn_pmu_event_release()
706 clear_bit(hw->idx, ccn->dt.pmu_counters_mask); in arm_ccn_pmu_event_release()
709 ccn->dt.pmu_counters[hw->idx].source = NULL; in arm_ccn_pmu_event_release()
710 ccn->dt.pmu_counters[hw->idx].event = NULL; in arm_ccn_pmu_event_release()
715 struct arm_ccn *ccn; in arm_ccn_pmu_event_init() local
725 ccn = pmu_to_arm_ccn(event->pmu); in arm_ccn_pmu_event_init()
728 dev_dbg(ccn->dev, "Sampling not supported!\n"); in arm_ccn_pmu_event_init()
733 dev_dbg(ccn->dev, "Can't exclude execution levels!\n"); in arm_ccn_pmu_event_init()
738 dev_dbg(ccn->dev, "Can't provide per-task data!\n"); in arm_ccn_pmu_event_init()
745 * but can lead to issues for off-core PMUs, like CCN, where each in arm_ccn_pmu_event_init()
750 event->cpu = ccn->dt.cpu; in arm_ccn_pmu_event_init()
759 if (node_xp != ccn->mn_id) { in arm_ccn_pmu_event_init()
760 dev_dbg(ccn->dev, "Invalid MN ID %d!\n", node_xp); in arm_ccn_pmu_event_init()
765 if (node_xp >= ccn->num_xps) { in arm_ccn_pmu_event_init()
766 dev_dbg(ccn->dev, "Invalid XP ID %d!\n", node_xp); in arm_ccn_pmu_event_init()
773 if (node_xp >= ccn->num_nodes) { in arm_ccn_pmu_event_init()
774 dev_dbg(ccn->dev, "Invalid node ID %d!\n", node_xp); in arm_ccn_pmu_event_init()
777 if (!arm_ccn_pmu_type_eq(type, ccn->node[node_xp].type)) { in arm_ccn_pmu_event_init()
778 dev_dbg(ccn->dev, "Invalid type 0x%x for node %d!\n", in arm_ccn_pmu_event_init()
797 dev_dbg(ccn->dev, "Invalid port %d for node/XP %d!\n", in arm_ccn_pmu_event_init()
802 dev_dbg(ccn->dev, "Invalid vc %d for node/XP %d!\n", in arm_ccn_pmu_event_init()
809 dev_dbg(ccn->dev, "Invalid event 0x%x for node/XP %d!\n", in arm_ccn_pmu_event_init()
828 * events are acceptable (for example to create a CCN group in arm_ccn_pmu_event_init()
844 static u64 arm_ccn_pmu_read_counter(struct arm_ccn *ccn, int idx) in arm_ccn_pmu_read_counter() argument
850 res = readq(ccn->dt.base + CCN_DT_PMCCNTR); in arm_ccn_pmu_read_counter()
853 writel(0x1, ccn->dt.base + CCN_DT_PMSR_REQ); in arm_ccn_pmu_read_counter()
854 while (!(readl(ccn->dt.base + CCN_DT_PMSR) & 0x1)) in arm_ccn_pmu_read_counter()
856 writel(0x1, ccn->dt.base + CCN_DT_PMSR_CLR); in arm_ccn_pmu_read_counter()
857 res = readl(ccn->dt.base + CCN_DT_PMCCNTRSR + 4) & 0xff; in arm_ccn_pmu_read_counter()
859 res |= readl(ccn->dt.base + CCN_DT_PMCCNTRSR); in arm_ccn_pmu_read_counter()
862 res = readl(ccn->dt.base + CCN_DT_PMEVCNT(idx)); in arm_ccn_pmu_read_counter()
870 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); in arm_ccn_pmu_event_update() local
876 new_count = arm_ccn_pmu_read_counter(ccn, hw->idx); in arm_ccn_pmu_event_update()
886 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); in arm_ccn_pmu_xp_dt_config() local
896 xp = &ccn->xp[CCN_CONFIG_XP(event->attr.config)]; in arm_ccn_pmu_xp_dt_config()
898 xp = &ccn->xp[arm_ccn_node_to_xp( in arm_ccn_pmu_xp_dt_config()
906 spin_lock(&ccn->dt.config_lock); in arm_ccn_pmu_xp_dt_config()
914 spin_unlock(&ccn->dt.config_lock); in arm_ccn_pmu_xp_dt_config()
919 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); in arm_ccn_pmu_event_start() local
923 arm_ccn_pmu_read_counter(ccn, hw->idx)); in arm_ccn_pmu_event_start()
945 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); in arm_ccn_pmu_xp_watchpoint_config() local
948 ccn->dt.pmu_counters[hw->idx].source; in arm_ccn_pmu_xp_watchpoint_config()
953 u64 mask_l = ccn->dt.cmp_mask[CCN_CONFIG_MASK(event->attr.config)].l; in arm_ccn_pmu_xp_watchpoint_config()
954 u64 mask_h = ccn->dt.cmp_mask[CCN_CONFIG_MASK(event->attr.config)].h; in arm_ccn_pmu_xp_watchpoint_config()
993 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); in arm_ccn_pmu_xp_event_config() local
996 ccn->dt.pmu_counters[hw->idx].source; in arm_ccn_pmu_xp_event_config()
1014 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); in arm_ccn_pmu_node_event_config() local
1017 ccn->dt.pmu_counters[hw->idx].source; in arm_ccn_pmu_node_event_config()
1051 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); in arm_ccn_pmu_event_config() local
1064 spin_lock(&ccn->dt.config_lock); in arm_ccn_pmu_event_config()
1068 val = readl(ccn->dt.base + CCN_DT_ACTIVE_DSM + offset); in arm_ccn_pmu_event_config()
1072 writel(val, ccn->dt.base + CCN_DT_ACTIVE_DSM + offset); in arm_ccn_pmu_event_config()
1084 spin_unlock(&ccn->dt.config_lock); in arm_ccn_pmu_event_config()
1087 static int arm_ccn_pmu_active_counters(struct arm_ccn *ccn) in arm_ccn_pmu_active_counters() argument
1089 return bitmap_weight(ccn->dt.pmu_counters_mask, in arm_ccn_pmu_active_counters()
1097 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); in arm_ccn_pmu_event_add() local
1108 if (!ccn->irq && arm_ccn_pmu_active_counters(ccn) == 1) in arm_ccn_pmu_event_add()
1109 hrtimer_start(&ccn->dt.hrtimer, arm_ccn_pmu_timer_period(), in arm_ccn_pmu_event_add()
1124 struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu); in arm_ccn_pmu_event_del() local
1130 if (!ccn->irq && arm_ccn_pmu_active_counters(ccn) == 0) in arm_ccn_pmu_event_del()
1131 hrtimer_cancel(&ccn->dt.hrtimer); in arm_ccn_pmu_event_del()
1141 struct arm_ccn *ccn = pmu_to_arm_ccn(pmu); in arm_ccn_pmu_enable() local
1143 u32 val = readl(ccn->dt.base + CCN_DT_PMCR); in arm_ccn_pmu_enable()
1145 writel(val, ccn->dt.base + CCN_DT_PMCR); in arm_ccn_pmu_enable()
1150 struct arm_ccn *ccn = pmu_to_arm_ccn(pmu); in arm_ccn_pmu_disable() local
1152 u32 val = readl(ccn->dt.base + CCN_DT_PMCR); in arm_ccn_pmu_disable()
1154 writel(val, ccn->dt.base + CCN_DT_PMCR); in arm_ccn_pmu_disable()
1203 struct arm_ccn *ccn = container_of(dt, struct arm_ccn, dt); in arm_ccn_pmu_offline_cpu() local
1213 if (ccn->irq) in arm_ccn_pmu_offline_cpu()
1214 WARN_ON(irq_set_affinity(ccn->irq, cpumask_of(dt->cpu))); in arm_ccn_pmu_offline_cpu()
1220 static int arm_ccn_pmu_init(struct arm_ccn *ccn) in arm_ccn_pmu_init() argument
1227 ccn->dt.base = ccn->base + CCN_REGION_SIZE; in arm_ccn_pmu_init()
1228 spin_lock_init(&ccn->dt.config_lock); in arm_ccn_pmu_init()
1229 writel(CCN_DT_PMOVSR_CLR__MASK, ccn->dt.base + CCN_DT_PMOVSR_CLR); in arm_ccn_pmu_init()
1230 writel(CCN_DT_CTL__DT_EN, ccn->dt.base + CCN_DT_CTL); in arm_ccn_pmu_init()
1232 ccn->dt.base + CCN_DT_PMCR); in arm_ccn_pmu_init()
1233 writel(0x1, ccn->dt.base + CCN_DT_PMSR_CLR); in arm_ccn_pmu_init()
1234 for (i = 0; i < ccn->num_xps; i++) { in arm_ccn_pmu_init()
1235 writel(0, ccn->xp[i].base + CCN_XP_DT_CONFIG); in arm_ccn_pmu_init()
1241 ccn->xp[i].base + CCN_XP_DT_CONTROL); in arm_ccn_pmu_init()
1243 ccn->dt.cmp_mask[CCN_IDX_MASK_ANY].l = ~0; in arm_ccn_pmu_init()
1244 ccn->dt.cmp_mask[CCN_IDX_MASK_ANY].h = ~0; in arm_ccn_pmu_init()
1245 ccn->dt.cmp_mask[CCN_IDX_MASK_EXACT].l = 0; in arm_ccn_pmu_init()
1246 ccn->dt.cmp_mask[CCN_IDX_MASK_EXACT].h = 0; in arm_ccn_pmu_init()
1247 ccn->dt.cmp_mask[CCN_IDX_MASK_ORDER].l = ~0; in arm_ccn_pmu_init()
1248 ccn->dt.cmp_mask[CCN_IDX_MASK_ORDER].h = ~(0x1 << 15); in arm_ccn_pmu_init()
1249 ccn->dt.cmp_mask[CCN_IDX_MASK_OPCODE].l = ~0; in arm_ccn_pmu_init()
1250 ccn->dt.cmp_mask[CCN_IDX_MASK_OPCODE].h = ~(0x1f << 9); in arm_ccn_pmu_init()
1253 ccn->dt.id = ida_alloc(&arm_ccn_pmu_ida, GFP_KERNEL); in arm_ccn_pmu_init()
1254 if (ccn->dt.id == 0) { in arm_ccn_pmu_init()
1255 name = "ccn"; in arm_ccn_pmu_init()
1257 name = devm_kasprintf(ccn->dev, GFP_KERNEL, "ccn_%d", in arm_ccn_pmu_init()
1258 ccn->dt.id); in arm_ccn_pmu_init()
1266 ccn->dt.pmu = (struct pmu) { in arm_ccn_pmu_init()
1282 if (!ccn->irq) { in arm_ccn_pmu_init()
1283 dev_info(ccn->dev, "No access to interrupts, using timer.\n"); in arm_ccn_pmu_init()
1284 hrtimer_init(&ccn->dt.hrtimer, CLOCK_MONOTONIC, in arm_ccn_pmu_init()
1286 ccn->dt.hrtimer.function = arm_ccn_pmu_timer_handler; in arm_ccn_pmu_init()
1289 /* Pick one CPU which we will use to collect data from CCN... */ in arm_ccn_pmu_init()
1290 ccn->dt.cpu = raw_smp_processor_id(); in arm_ccn_pmu_init()
1293 if (ccn->irq) { in arm_ccn_pmu_init()
1294 err = irq_set_affinity(ccn->irq, cpumask_of(ccn->dt.cpu)); in arm_ccn_pmu_init()
1296 dev_err(ccn->dev, "Failed to set interrupt affinity!\n"); in arm_ccn_pmu_init()
1302 &ccn->dt.node); in arm_ccn_pmu_init()
1304 err = perf_pmu_register(&ccn->dt.pmu, name, -1); in arm_ccn_pmu_init()
1312 &ccn->dt.node); in arm_ccn_pmu_init()
1315 ida_free(&arm_ccn_pmu_ida, ccn->dt.id); in arm_ccn_pmu_init()
1316 for (i = 0; i < ccn->num_xps; i++) in arm_ccn_pmu_init()
1317 writel(0, ccn->xp[i].base + CCN_XP_DT_CONTROL); in arm_ccn_pmu_init()
1318 writel(0, ccn->dt.base + CCN_DT_PMCR); in arm_ccn_pmu_init()
1322 static void arm_ccn_pmu_cleanup(struct arm_ccn *ccn) in arm_ccn_pmu_cleanup() argument
1327 &ccn->dt.node); in arm_ccn_pmu_cleanup()
1328 for (i = 0; i < ccn->num_xps; i++) in arm_ccn_pmu_cleanup()
1329 writel(0, ccn->xp[i].base + CCN_XP_DT_CONTROL); in arm_ccn_pmu_cleanup()
1330 writel(0, ccn->dt.base + CCN_DT_PMCR); in arm_ccn_pmu_cleanup()
1331 perf_pmu_unregister(&ccn->dt.pmu); in arm_ccn_pmu_cleanup()
1332 ida_free(&arm_ccn_pmu_ida, ccn->dt.id); in arm_ccn_pmu_cleanup()
1335 static int arm_ccn_for_each_valid_region(struct arm_ccn *ccn, in arm_ccn_for_each_valid_region() argument
1336 int (*callback)(struct arm_ccn *ccn, int region, in arm_ccn_for_each_valid_region() argument
1346 val = readl(ccn->base + CCN_MN_OLY_COMP_LIST_63_0 + in arm_ccn_for_each_valid_region()
1351 base = ccn->base + region * CCN_REGION_SIZE; in arm_ccn_for_each_valid_region()
1358 err = callback(ccn, region, base, type, id); in arm_ccn_for_each_valid_region()
1366 static int arm_ccn_get_nodes_num(struct arm_ccn *ccn, int region, in arm_ccn_get_nodes_num() argument
1370 if (type == CCN_TYPE_XP && id >= ccn->num_xps) in arm_ccn_get_nodes_num()
1371 ccn->num_xps = id + 1; in arm_ccn_get_nodes_num()
1372 else if (id >= ccn->num_nodes) in arm_ccn_get_nodes_num()
1373 ccn->num_nodes = id + 1; in arm_ccn_get_nodes_num()
1378 static int arm_ccn_init_nodes(struct arm_ccn *ccn, int region, in arm_ccn_init_nodes() argument
1383 dev_dbg(ccn->dev, "Region %d: id=%u, type=0x%02x\n", region, id, type); in arm_ccn_init_nodes()
1387 ccn->mn_id = id; in arm_ccn_init_nodes()
1392 component = &ccn->xp[id]; in arm_ccn_init_nodes()
1395 ccn->sbsx_present = 1; in arm_ccn_init_nodes()
1396 component = &ccn->node[id]; in arm_ccn_init_nodes()
1399 ccn->sbas_present = 1; in arm_ccn_init_nodes()
1402 component = &ccn->node[id]; in arm_ccn_init_nodes()
1413 static irqreturn_t arm_ccn_error_handler(struct arm_ccn *ccn, in arm_ccn_error_handler() argument
1417 dev_err(ccn->dev, "Error reported in %08x%08x%08x%08x%08x%08x.\n", in arm_ccn_error_handler()
1420 dev_err(ccn->dev, "Disabling interrupt generation for all errors.\n"); in arm_ccn_error_handler()
1422 ccn->base + CCN_MN_ERRINT_STATUS); in arm_ccn_error_handler()
1431 struct arm_ccn *ccn = dev_id; in arm_ccn_irq_handler() local
1437 err_or = err_sig_val[0] = readl(ccn->base + CCN_MN_ERR_SIG_VAL_63_0); in arm_ccn_irq_handler()
1440 res = arm_ccn_pmu_overflow_handler(&ccn->dt); in arm_ccn_irq_handler()
1445 err_sig_val[i] = readl(ccn->base + in arm_ccn_irq_handler()
1450 res |= arm_ccn_error_handler(ccn, err_sig_val); in arm_ccn_irq_handler()
1454 ccn->base + CCN_MN_ERRINT_STATUS); in arm_ccn_irq_handler()
1462 struct arm_ccn *ccn; in arm_ccn_probe() local
1466 ccn = devm_kzalloc(&pdev->dev, sizeof(*ccn), GFP_KERNEL); in arm_ccn_probe()
1467 if (!ccn) in arm_ccn_probe()
1469 ccn->dev = &pdev->dev; in arm_ccn_probe()
1470 platform_set_drvdata(pdev, ccn); in arm_ccn_probe()
1472 ccn->base = devm_platform_ioremap_resource(pdev, 0); in arm_ccn_probe()
1473 if (IS_ERR(ccn->base)) in arm_ccn_probe()
1474 return PTR_ERR(ccn->base); in arm_ccn_probe()
1482 ccn->base + CCN_MN_ERRINT_STATUS); in arm_ccn_probe()
1483 if (readl(ccn->base + CCN_MN_ERRINT_STATUS) & in arm_ccn_probe()
1487 ccn->base + CCN_MN_ERRINT_STATUS); in arm_ccn_probe()
1488 err = devm_request_irq(ccn->dev, irq, arm_ccn_irq_handler, in arm_ccn_probe()
1490 dev_name(ccn->dev), ccn); in arm_ccn_probe()
1494 ccn->irq = irq; in arm_ccn_probe()
1500 err = arm_ccn_for_each_valid_region(ccn, arm_ccn_get_nodes_num); in arm_ccn_probe()
1504 ccn->node = devm_kcalloc(ccn->dev, ccn->num_nodes, sizeof(*ccn->node), in arm_ccn_probe()
1506 ccn->xp = devm_kcalloc(ccn->dev, ccn->num_xps, sizeof(*ccn->node), in arm_ccn_probe()
1508 if (!ccn->node || !ccn->xp) in arm_ccn_probe()
1511 err = arm_ccn_for_each_valid_region(ccn, arm_ccn_init_nodes); in arm_ccn_probe()
1515 return arm_ccn_pmu_init(ccn); in arm_ccn_probe()
1520 struct arm_ccn *ccn = platform_get_drvdata(pdev); in arm_ccn_remove() local
1522 arm_ccn_pmu_cleanup(ccn); in arm_ccn_remove()
1528 { .compatible = "arm,ccn-502", },
1529 { .compatible = "arm,ccn-504", },
1530 { .compatible = "arm,ccn-512", },
1537 .name = "arm-ccn",
1550 "perf/arm/ccn:online", NULL, in arm_ccn_init()