Lines Matching +full:cn10k +full:- +full:tad +full:- +full:pmu

1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell CN10K LLC-TAD perf driver
24 #define to_tad_pmu(p) (container_of(p, struct tad_pmu, pmu))
31 struct pmu pmu; member
44 struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu); in tad_pmu_event_counter_read()
45 struct hw_perf_event *hwc = &event->hw; in tad_pmu_event_counter_read()
46 u32 counter_idx = hwc->idx; in tad_pmu_event_counter_read()
51 prev = local64_read(&hwc->prev_count); in tad_pmu_event_counter_read()
52 for (i = 0, new = 0; i < tad_pmu->region_cnt; i++) in tad_pmu_event_counter_read()
53 new += readq(tad_pmu->regions[i].base + in tad_pmu_event_counter_read()
55 } while (local64_cmpxchg(&hwc->prev_count, prev, new) != prev); in tad_pmu_event_counter_read()
57 local64_add(new - prev, &event->count); in tad_pmu_event_counter_read()
62 struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu); in tad_pmu_event_counter_stop()
63 struct hw_perf_event *hwc = &event->hw; in tad_pmu_event_counter_stop()
64 u32 counter_idx = hwc->idx; in tad_pmu_event_counter_stop()
67 /* TAD()_PFC() stop counting on the write in tad_pmu_event_counter_stop()
68 * which sets TAD()_PRF()[CNTSEL] == 0 in tad_pmu_event_counter_stop()
70 for (i = 0; i < tad_pmu->region_cnt; i++) { in tad_pmu_event_counter_stop()
71 writeq_relaxed(0, tad_pmu->regions[i].base + in tad_pmu_event_counter_stop()
76 hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; in tad_pmu_event_counter_stop()
81 struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu); in tad_pmu_event_counter_start()
82 struct hw_perf_event *hwc = &event->hw; in tad_pmu_event_counter_start()
83 u32 event_idx = event->attr.config; in tad_pmu_event_counter_start()
84 u32 counter_idx = hwc->idx; in tad_pmu_event_counter_start()
88 hwc->state = 0; in tad_pmu_event_counter_start()
91 for (i = 0; i < tad_pmu->region_cnt; i++) in tad_pmu_event_counter_start()
92 writeq_relaxed(0, tad_pmu->regions[i].base + in tad_pmu_event_counter_start()
95 /* TAD()_PFC() start counting on the write in tad_pmu_event_counter_start()
96 * which sets TAD()_PRF()[CNTSEL] != 0 in tad_pmu_event_counter_start()
98 for (i = 0; i < tad_pmu->region_cnt; i++) { in tad_pmu_event_counter_start()
100 writeq_relaxed(reg_val, tad_pmu->regions[i].base + in tad_pmu_event_counter_start()
107 struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu); in tad_pmu_event_counter_del()
108 struct hw_perf_event *hwc = &event->hw; in tad_pmu_event_counter_del()
109 int idx = hwc->idx; in tad_pmu_event_counter_del()
112 tad_pmu->events[idx] = NULL; in tad_pmu_event_counter_del()
113 clear_bit(idx, tad_pmu->counters_map); in tad_pmu_event_counter_del()
118 struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu); in tad_pmu_event_counter_add()
119 struct hw_perf_event *hwc = &event->hw; in tad_pmu_event_counter_add()
123 idx = find_first_zero_bit(tad_pmu->counters_map, TAD_MAX_COUNTERS); in tad_pmu_event_counter_add()
125 return -EAGAIN; in tad_pmu_event_counter_add()
127 set_bit(idx, tad_pmu->counters_map); in tad_pmu_event_counter_add()
129 hwc->idx = idx; in tad_pmu_event_counter_add()
130 hwc->state = PERF_HES_STOPPED; in tad_pmu_event_counter_add()
131 tad_pmu->events[idx] = event; in tad_pmu_event_counter_add()
141 struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu); in tad_pmu_event_init()
143 if (event->attr.type != event->pmu->type) in tad_pmu_event_init()
144 return -ENOENT; in tad_pmu_event_init()
146 if (!event->attr.disabled) in tad_pmu_event_init()
147 return -EINVAL; in tad_pmu_event_init()
149 if (event->state != PERF_EVENT_STATE_OFF) in tad_pmu_event_init()
150 return -EINVAL; in tad_pmu_event_init()
152 event->cpu = tad_pmu->cpu; in tad_pmu_event_init()
153 event->hw.idx = -1; in tad_pmu_event_init()
154 event->hw.config_base = event->attr.config; in tad_pmu_event_init()
165 return sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id); in tad_pmu_event_show()
217 PMU_FORMAT_ATTR(event, "config:0-7");
234 return cpumap_print_to_pagebuf(true, buf, cpumask_of(tad_pmu->cpu)); in tad_pmu_cpumask_show()
257 struct device *dev = &pdev->dev; in tad_pmu_probe()
267 tad_pmu = devm_kzalloc(&pdev->dev, sizeof(*tad_pmu), GFP_KERNEL); in tad_pmu_probe()
269 return -ENOMEM; in tad_pmu_probe()
275 dev_err(&pdev->dev, "Mem resource not found\n"); in tad_pmu_probe()
276 return -ENODEV; in tad_pmu_probe()
279 ret = device_property_read_u32(dev, "marvell,tad-page-size", in tad_pmu_probe()
282 dev_err(&pdev->dev, "Can't find tad-page-size property\n"); in tad_pmu_probe()
286 ret = device_property_read_u32(dev, "marvell,tad-pmu-page-size", in tad_pmu_probe()
289 dev_err(&pdev->dev, "Can't find tad-pmu-page-size property\n"); in tad_pmu_probe()
293 ret = device_property_read_u32(dev, "marvell,tad-cnt", &tad_cnt); in tad_pmu_probe()
295 dev_err(&pdev->dev, "Can't find tad-cnt property\n"); in tad_pmu_probe()
299 regions = devm_kcalloc(&pdev->dev, tad_cnt, in tad_pmu_probe()
302 return -ENOMEM; in tad_pmu_probe()
304 /* ioremap the distributed TAD pmu regions */ in tad_pmu_probe()
305 for (i = 0; i < tad_cnt && res->start < res->end; i++) { in tad_pmu_probe()
306 regions[i].base = devm_ioremap(&pdev->dev, in tad_pmu_probe()
307 res->start, in tad_pmu_probe()
310 dev_err(&pdev->dev, "TAD%d ioremap fail\n", i); in tad_pmu_probe()
311 return -ENOMEM; in tad_pmu_probe()
313 res->start += tad_page_size; in tad_pmu_probe()
316 tad_pmu->regions = regions; in tad_pmu_probe()
317 tad_pmu->region_cnt = tad_cnt; in tad_pmu_probe()
319 tad_pmu->pmu = (struct pmu) { in tad_pmu_probe()
335 tad_pmu->cpu = raw_smp_processor_id(); in tad_pmu_probe()
337 /* Register pmu instance for cpu hotplug */ in tad_pmu_probe()
339 &tad_pmu->node); in tad_pmu_probe()
341 dev_err(&pdev->dev, "Error %d registering hotplug\n", ret); in tad_pmu_probe()
345 name = "tad"; in tad_pmu_probe()
346 ret = perf_pmu_register(&tad_pmu->pmu, name, -1); in tad_pmu_probe()
349 &tad_pmu->node); in tad_pmu_probe()
356 struct tad_pmu *pmu = platform_get_drvdata(pdev); in tad_pmu_remove() local
359 &pmu->node); in tad_pmu_remove()
360 perf_pmu_unregister(&pmu->pmu); in tad_pmu_remove()
365 { .compatible = "marvell,cn10k-tad-pmu", },
391 struct tad_pmu *pmu = hlist_entry_safe(node, struct tad_pmu, node); in tad_pmu_offline_cpu() local
394 if (cpu != pmu->cpu) in tad_pmu_offline_cpu()
401 perf_pmu_migrate_context(&pmu->pmu, cpu, target); in tad_pmu_offline_cpu()
402 pmu->cpu = target; in tad_pmu_offline_cpu()
412 "perf/cn10k/tadpmu:online", in tad_pmu_init()
434 MODULE_DESCRIPTION("Marvell CN10K LLC-TAD Perf driver");