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
53 struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu); in tad_pmu_event_counter_read()
54 struct hw_perf_event *hwc = &event->hw; in tad_pmu_event_counter_read()
55 u32 counter_idx = hwc->idx; in tad_pmu_event_counter_read()
60 prev = local64_read(&hwc->prev_count); in tad_pmu_event_counter_read()
61 for (i = 0, new = 0; i < tad_pmu->region_cnt; i++) in tad_pmu_event_counter_read()
62 new += readq(tad_pmu->regions[i].base + in tad_pmu_event_counter_read()
64 } while (local64_cmpxchg(&hwc->prev_count, prev, new) != prev); in tad_pmu_event_counter_read()
66 local64_add(new - prev, &event->count); in tad_pmu_event_counter_read()
71 struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu); in tad_pmu_event_counter_stop()
72 struct hw_perf_event *hwc = &event->hw; in tad_pmu_event_counter_stop()
73 u32 counter_idx = hwc->idx; in tad_pmu_event_counter_stop()
76 /* TAD()_PFC() stop counting on the write in tad_pmu_event_counter_stop()
77 * which sets TAD()_PRF()[CNTSEL] == 0 in tad_pmu_event_counter_stop()
79 for (i = 0; i < tad_pmu->region_cnt; i++) { in tad_pmu_event_counter_stop()
80 writeq_relaxed(0, tad_pmu->regions[i].base + in tad_pmu_event_counter_stop()
85 hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE; in tad_pmu_event_counter_stop()
90 struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu); in tad_pmu_event_counter_start()
91 struct hw_perf_event *hwc = &event->hw; in tad_pmu_event_counter_start()
92 u32 event_idx = event->attr.config; in tad_pmu_event_counter_start()
93 u32 counter_idx = hwc->idx; in tad_pmu_event_counter_start()
97 hwc->state = 0; in tad_pmu_event_counter_start()
100 for (i = 0; i < tad_pmu->region_cnt; i++) in tad_pmu_event_counter_start()
101 writeq_relaxed(0, tad_pmu->regions[i].base + in tad_pmu_event_counter_start()
104 /* TAD()_PFC() start counting on the write in tad_pmu_event_counter_start()
105 * which sets TAD()_PRF()[CNTSEL] != 0 in tad_pmu_event_counter_start()
107 for (i = 0; i < tad_pmu->region_cnt; i++) { in tad_pmu_event_counter_start()
109 writeq_relaxed(reg_val, tad_pmu->regions[i].base + in tad_pmu_event_counter_start()
116 struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu); in tad_pmu_event_counter_del()
117 struct hw_perf_event *hwc = &event->hw; in tad_pmu_event_counter_del()
118 int idx = hwc->idx; in tad_pmu_event_counter_del()
121 tad_pmu->events[idx] = NULL; in tad_pmu_event_counter_del()
122 clear_bit(idx, tad_pmu->counters_map); in tad_pmu_event_counter_del()
127 struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu); in tad_pmu_event_counter_add()
128 struct hw_perf_event *hwc = &event->hw; in tad_pmu_event_counter_add()
132 idx = find_first_zero_bit(tad_pmu->counters_map, TAD_MAX_COUNTERS); in tad_pmu_event_counter_add()
134 return -EAGAIN; in tad_pmu_event_counter_add()
136 set_bit(idx, tad_pmu->counters_map); in tad_pmu_event_counter_add()
138 hwc->idx = idx; in tad_pmu_event_counter_add()
139 hwc->state = PERF_HES_STOPPED; in tad_pmu_event_counter_add()
140 tad_pmu->events[idx] = event; in tad_pmu_event_counter_add()
150 struct tad_pmu *tad_pmu = to_tad_pmu(event->pmu); in tad_pmu_event_init()
152 if (event->attr.type != event->pmu->type) in tad_pmu_event_init()
153 return -ENOENT; in tad_pmu_event_init()
155 if (!event->attr.disabled) in tad_pmu_event_init()
156 return -EINVAL; in tad_pmu_event_init()
158 if (event->state != PERF_EVENT_STATE_OFF) in tad_pmu_event_init()
159 return -EINVAL; in tad_pmu_event_init()
161 event->cpu = tad_pmu->cpu; in tad_pmu_event_init()
162 event->hw.idx = -1; in tad_pmu_event_init()
163 event->hw.config_base = event->attr.config; in tad_pmu_event_init()
174 return sysfs_emit(page, "event=0x%02llx\n", pmu_attr->id); in tad_pmu_event_show()
244 PMU_FORMAT_ATTR(event, "config:0-7");
261 return cpumap_print_to_pagebuf(true, buf, cpumask_of(tad_pmu->cpu)); in tad_pmu_cpumask_show()
292 struct device *dev = &pdev->dev; in tad_pmu_probe()
303 tad_pmu = devm_kzalloc(&pdev->dev, sizeof(*tad_pmu), GFP_KERNEL); in tad_pmu_probe()
305 return -ENOMEM; in tad_pmu_probe()
309 dev_data = device_get_match_data(&pdev->dev); in tad_pmu_probe()
311 dev_err(&pdev->dev, "Error: No device match data found\n"); in tad_pmu_probe()
312 return -ENODEV; in tad_pmu_probe()
314 version = dev_data->id; in tad_pmu_probe()
318 dev_err(&pdev->dev, "Mem resource not found\n"); in tad_pmu_probe()
319 return -ENODEV; in tad_pmu_probe()
322 ret = device_property_read_u32(dev, "marvell,tad-page-size", in tad_pmu_probe()
325 dev_err(&pdev->dev, "Can't find tad-page-size property\n"); in tad_pmu_probe()
329 ret = device_property_read_u32(dev, "marvell,tad-pmu-page-size", in tad_pmu_probe()
332 dev_err(&pdev->dev, "Can't find tad-pmu-page-size property\n"); in tad_pmu_probe()
336 ret = device_property_read_u32(dev, "marvell,tad-cnt", &tad_cnt); in tad_pmu_probe()
338 dev_err(&pdev->dev, "Can't find tad-cnt property\n"); in tad_pmu_probe()
342 regions = devm_kcalloc(&pdev->dev, tad_cnt, in tad_pmu_probe()
345 return -ENOMEM; in tad_pmu_probe()
347 /* ioremap the distributed TAD pmu regions */ in tad_pmu_probe()
348 for (i = 0; i < tad_cnt && res->start < res->end; i++) { in tad_pmu_probe()
349 regions[i].base = devm_ioremap(&pdev->dev, in tad_pmu_probe()
350 res->start, in tad_pmu_probe()
353 dev_err(&pdev->dev, "TAD%d ioremap fail\n", i); in tad_pmu_probe()
354 return -ENOMEM; in tad_pmu_probe()
356 res->start += tad_page_size; in tad_pmu_probe()
359 tad_pmu->regions = regions; in tad_pmu_probe()
360 tad_pmu->region_cnt = tad_cnt; in tad_pmu_probe()
362 tad_pmu->pmu = (struct pmu) { in tad_pmu_probe()
378 tad_pmu->pmu.attr_groups = tad_pmu_attr_groups; in tad_pmu_probe()
380 tad_pmu->pmu.attr_groups = ody_tad_pmu_attr_groups; in tad_pmu_probe()
382 tad_pmu->cpu = raw_smp_processor_id(); in tad_pmu_probe()
384 /* Register pmu instance for cpu hotplug */ in tad_pmu_probe()
386 &tad_pmu->node); in tad_pmu_probe()
388 dev_err(&pdev->dev, "Error %d registering hotplug\n", ret); in tad_pmu_probe()
392 name = "tad"; in tad_pmu_probe()
393 ret = perf_pmu_register(&tad_pmu->pmu, name, -1); in tad_pmu_probe()
396 &tad_pmu->node); in tad_pmu_probe()
403 struct tad_pmu *pmu = platform_get_drvdata(pdev); in tad_pmu_remove() local
406 &pmu->node); in tad_pmu_remove()
407 perf_pmu_unregister(&pmu->pmu); in tad_pmu_remove()
424 { .compatible = "marvell,cn10k-tad-pmu", .data = &tad_pmu_data },
451 struct tad_pmu *pmu = hlist_entry_safe(node, struct tad_pmu, node); in tad_pmu_offline_cpu() local
454 if (cpu != pmu->cpu) in tad_pmu_offline_cpu()
461 perf_pmu_migrate_context(&pmu->pmu, cpu, target); in tad_pmu_offline_cpu()
462 pmu->cpu = target; in tad_pmu_offline_cpu()
472 "perf/cn10k/tadpmu:online", in tad_pmu_init()
494 MODULE_DESCRIPTION("Marvell CN10K LLC-TAD Perf driver");