1 // SPDX-License-Identifier: GPL-2.0-only
3 * StarFive's StarLink PMU driver
5 * Copyright (C) 2023 StarFive Technology Co., Ltd.
11 #define STARLINK_PMU_PDEV_NAME "starfive_starlink_pmu"
12 #define pr_fmt(fmt) STARLINK_PMU_PDEV_NAME ": " fmt
14 #include <linux/bitmap.h>
15 #include <linux/cpu_pm.h>
17 #include <linux/irq.h>
18 #include <linux/kernel.h>
19 #include <linux/module.h>
20 #include <linux/mod_devicetable.h>
21 #include <linux/perf_event.h>
22 #include <linux/platform_device.h>
23 #include <linux/sysfs.h>
25 #define STARLINK_PMU_MAX_COUNTERS 64
26 #define STARLINK_PMU_NUM_COUNTERS 16
27 #define STARLINK_PMU_IDX_CYCLE_COUNTER 63
29 #define STARLINK_PMU_EVENT_SELECT 0x060
30 #define STARLINK_PMU_EVENT_COUNTER 0x160
31 #define STARLINK_PMU_COUNTER_MASK GENMASK_ULL(63, 0)
32 #define STARLINK_PMU_CYCLE_COUNTER 0x058
34 #define STARLINK_PMU_CONTROL 0x040
35 #define STARLINK_PMU_GLOBAL_ENABLE BIT_ULL(0)
37 #define STARLINK_PMU_INTERRUPT_ENABLE 0x050
38 #define STARLINK_PMU_COUNTER_OVERFLOW_STATUS 0x048
39 #define STARLINK_PMU_CYCLE_OVERFLOW_MASK BIT_ULL(63)
41 #define STARLINK_CYCLES 0x058
42 #define CACHE_READ_REQUEST 0x04000701
43 #define CACHE_WRITE_REQUEST 0x03000001
44 #define CACHE_RELEASE_REQUEST 0x0003e001
45 #define CACHE_READ_HIT 0x00901202
46 #define CACHE_READ_MISS 0x04008002
47 #define CACHE_WRITE_HIT 0x006c0002
48 #define CACHE_WRITE_MISS 0x03000002
49 #define CACHE_WRITEBACK 0x00000403
51 #define to_starlink_pmu(p) (container_of(p, struct starlink_pmu, pmu))
53 #define STARLINK_FORMAT_ATTR(_name, _config) \
54 (&((struct dev_ext_attribute[]) { \
55 { .attr = __ATTR(_name, 0444, starlink_pmu_sysfs_format_show, NULL), \
56 .var = (void *)_config, } \
59 #define STARLINK_EVENT_ATTR(_name, _id) \
60 PMU_EVENT_ATTR_ID(_name, starlink_pmu_sysfs_event_show, _id)
62 static int starlink_pmu_cpuhp_state;
64 struct starlink_hw_events {
65 struct perf_event *events[STARLINK_PMU_MAX_COUNTERS];
66 DECLARE_BITMAP(used_mask, STARLINK_PMU_MAX_COUNTERS);
71 struct starlink_hw_events __percpu *hw_events;
72 struct hlist_node node;
73 struct notifier_block starlink_pmu_pm_nb;
74 void __iomem *pmu_base;
80 starlink_pmu_sysfs_format_show(struct device *dev,
81 struct device_attribute *attr,
84 struct dev_ext_attribute *eattr = container_of(attr,
85 struct dev_ext_attribute, attr);
87 return sysfs_emit(buf, "%s\n", (char *)eattr->var);
90 static struct attribute *starlink_pmu_format_attrs[] = {
91 STARLINK_FORMAT_ATTR(event, "config:0-31"),
95 static const struct attribute_group starlink_pmu_format_attr_group = {
97 .attrs = starlink_pmu_format_attrs,
101 starlink_pmu_sysfs_event_show(struct device *dev,
102 struct device_attribute *attr,
105 struct perf_pmu_events_attr *eattr = container_of(attr,
106 struct perf_pmu_events_attr, attr);
108 return sysfs_emit(buf, "event=0x%02llx\n", eattr->id);
111 static struct attribute *starlink_pmu_event_attrs[] = {
112 STARLINK_EVENT_ATTR(cycles, STARLINK_CYCLES),
113 STARLINK_EVENT_ATTR(read_request, CACHE_READ_REQUEST),
114 STARLINK_EVENT_ATTR(write_request, CACHE_WRITE_REQUEST),
115 STARLINK_EVENT_ATTR(release_request, CACHE_RELEASE_REQUEST),
116 STARLINK_EVENT_ATTR(read_hit, CACHE_READ_HIT),
117 STARLINK_EVENT_ATTR(read_miss, CACHE_READ_MISS),
118 STARLINK_EVENT_ATTR(write_hit, CACHE_WRITE_HIT),
119 STARLINK_EVENT_ATTR(write_miss, CACHE_WRITE_MISS),
120 STARLINK_EVENT_ATTR(writeback, CACHE_WRITEBACK),
124 static const struct attribute_group starlink_pmu_events_attr_group = {
126 .attrs = starlink_pmu_event_attrs,
130 cpumask_show(struct device *dev, struct device_attribute *attr, char *buf)
132 struct starlink_pmu *starlink_pmu = to_starlink_pmu(dev_get_drvdata(dev));
134 return cpumap_print_to_pagebuf(true, buf, &starlink_pmu->cpumask);
137 static DEVICE_ATTR_RO(cpumask);
139 static struct attribute *starlink_pmu_cpumask_attrs[] = {
140 &dev_attr_cpumask.attr,
144 static const struct attribute_group starlink_pmu_cpumask_attr_group = {
145 .attrs = starlink_pmu_cpumask_attrs,
148 static const struct attribute_group *starlink_pmu_attr_groups[] = {
149 &starlink_pmu_format_attr_group,
150 &starlink_pmu_events_attr_group,
151 &starlink_pmu_cpumask_attr_group,
155 static void starlink_pmu_set_event_period(struct perf_event *event)
157 struct starlink_pmu *starlink_pmu = to_starlink_pmu(event->pmu);
158 struct hw_perf_event *hwc = &event->hw;
159 int idx = event->hw.idx;
162 * Program counter to half of it's max count to handle
163 * cases of extreme interrupt latency.
165 u64 val = STARLINK_PMU_COUNTER_MASK >> 1;
167 local64_set(&hwc->prev_count, val);
168 if (hwc->config == STARLINK_CYCLES)
169 writeq(val, starlink_pmu->pmu_base + STARLINK_PMU_CYCLE_COUNTER);
171 writeq(val, starlink_pmu->pmu_base + STARLINK_PMU_EVENT_COUNTER +
175 static void starlink_pmu_counter_start(struct perf_event *event,
176 struct starlink_pmu *starlink_pmu)
178 struct hw_perf_event *hwc = &event->hw;
179 int idx = event->hw.idx;
183 * Enable counter overflow interrupt[63:0],
184 * which is mapped as follow:
186 * event counter 0 - Bit [0]
187 * event counter 1 - Bit [1]
189 * cycle counter - Bit [63]
191 val = readq(starlink_pmu->pmu_base + STARLINK_PMU_INTERRUPT_ENABLE);
193 if (hwc->config == STARLINK_CYCLES) {
195 * Cycle count has its dedicated register, and it starts
196 * counting as soon as STARLINK_PMU_GLOBAL_ENABLE is set.
198 val |= STARLINK_PMU_CYCLE_OVERFLOW_MASK;
200 writeq(event->hw.config, starlink_pmu->pmu_base +
201 STARLINK_PMU_EVENT_SELECT + idx * sizeof(u64));
206 writeq(val, starlink_pmu->pmu_base + STARLINK_PMU_INTERRUPT_ENABLE);
208 writeq(STARLINK_PMU_GLOBAL_ENABLE, starlink_pmu->pmu_base +
209 STARLINK_PMU_CONTROL);
212 static void starlink_pmu_counter_stop(struct perf_event *event,
213 struct starlink_pmu *starlink_pmu)
215 struct hw_perf_event *hwc = &event->hw;
216 int idx = event->hw.idx;
219 val = readq(starlink_pmu->pmu_base + STARLINK_PMU_CONTROL);
220 val &= ~STARLINK_PMU_GLOBAL_ENABLE;
221 writeq(val, starlink_pmu->pmu_base + STARLINK_PMU_CONTROL);
223 val = readq(starlink_pmu->pmu_base + STARLINK_PMU_INTERRUPT_ENABLE);
224 if (hwc->config == STARLINK_CYCLES)
225 val &= ~STARLINK_PMU_CYCLE_OVERFLOW_MASK;
227 val &= ~BIT_ULL(idx);
229 writeq(val, starlink_pmu->pmu_base + STARLINK_PMU_INTERRUPT_ENABLE);
232 static void starlink_pmu_update(struct perf_event *event)
234 struct starlink_pmu *starlink_pmu = to_starlink_pmu(event->pmu);
235 struct hw_perf_event *hwc = &event->hw;
237 u64 prev_raw_count, new_raw_count;
242 prev_raw_count = local64_read(&hwc->prev_count);
243 if (hwc->config == STARLINK_CYCLES)
244 new_raw_count = readq(starlink_pmu->pmu_base +
245 STARLINK_PMU_CYCLE_COUNTER);
247 new_raw_count = readq(starlink_pmu->pmu_base +
248 STARLINK_PMU_EVENT_COUNTER +
250 oldval = local64_cmpxchg(&hwc->prev_count, prev_raw_count,
252 } while (oldval != prev_raw_count);
254 delta = (new_raw_count - prev_raw_count) & STARLINK_PMU_COUNTER_MASK;
255 local64_add(delta, &event->count);
258 static void starlink_pmu_start(struct perf_event *event, int flags)
260 struct starlink_pmu *starlink_pmu = to_starlink_pmu(event->pmu);
261 struct hw_perf_event *hwc = &event->hw;
263 if (WARN_ON_ONCE(!(hwc->state & PERF_HES_STOPPED)))
266 if (flags & PERF_EF_RELOAD)
267 WARN_ON_ONCE(!(event->hw.state & PERF_HES_UPTODATE));
271 starlink_pmu_set_event_period(event);
272 starlink_pmu_counter_start(event, starlink_pmu);
274 perf_event_update_userpage(event);
277 static void starlink_pmu_stop(struct perf_event *event, int flags)
279 struct starlink_pmu *starlink_pmu = to_starlink_pmu(event->pmu);
280 struct hw_perf_event *hwc = &event->hw;
282 if (hwc->state & PERF_HES_STOPPED)
285 starlink_pmu_counter_stop(event, starlink_pmu);
286 starlink_pmu_update(event);
287 hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
290 static int starlink_pmu_add(struct perf_event *event, int flags)
292 struct starlink_pmu *starlink_pmu = to_starlink_pmu(event->pmu);
293 struct starlink_hw_events *hw_events =
294 this_cpu_ptr(starlink_pmu->hw_events);
295 struct hw_perf_event *hwc = &event->hw;
296 unsigned long *used_mask = hw_events->used_mask;
297 u32 n_events = STARLINK_PMU_NUM_COUNTERS;
301 * Cycle counter has dedicated register to hold counter value.
302 * Event other than cycle count has to be enabled through
303 * event select register, and assigned with independent counter
307 if (hwc->config == STARLINK_CYCLES) {
308 idx = STARLINK_PMU_IDX_CYCLE_COUNTER;
310 idx = find_first_zero_bit(used_mask, n_events);
311 /* All counter are in use */
315 set_bit(idx, used_mask);
319 hw_events->events[idx] = event;
320 hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
322 if (flags & PERF_EF_START)
323 starlink_pmu_start(event, PERF_EF_RELOAD);
325 perf_event_update_userpage(event);
330 static void starlink_pmu_del(struct perf_event *event, int flags)
332 struct starlink_pmu *starlink_pmu = to_starlink_pmu(event->pmu);
333 struct starlink_hw_events *hw_events =
334 this_cpu_ptr(starlink_pmu->hw_events);
335 struct hw_perf_event *hwc = &event->hw;
337 starlink_pmu_stop(event, PERF_EF_UPDATE);
338 hw_events->events[hwc->idx] = NULL;
339 clear_bit(hwc->idx, hw_events->used_mask);
341 perf_event_update_userpage(event);
344 static bool starlink_pmu_validate_event_group(struct perf_event *event)
346 struct perf_event *leader = event->group_leader;
347 struct perf_event *sibling;
351 * Ensure hardware events in the group are on the same PMU,
352 * software events are acceptable.
354 if (event->group_leader->pmu != event->pmu &&
355 !is_software_event(event->group_leader))
358 for_each_sibling_event(sibling, leader) {
359 if (sibling->pmu != event->pmu && !is_software_event(sibling))
365 return counter <= STARLINK_PMU_NUM_COUNTERS;
368 static int starlink_pmu_event_init(struct perf_event *event)
370 struct starlink_pmu *starlink_pmu = to_starlink_pmu(event->pmu);
371 struct hw_perf_event *hwc = &event->hw;
374 * Sampling is not supported, as counters are shared
377 if (hwc->sample_period)
381 * Per-task and attach to a task are not supported,
382 * as uncore events are not specific to any CPU.
384 if (event->cpu < 0 || event->attach_state & PERF_ATTACH_TASK)
387 if (!starlink_pmu_validate_event_group(event))
391 hwc->config = event->attr.config;
392 event->cpu = cpumask_first(&starlink_pmu->cpumask);
397 static irqreturn_t starlink_pmu_handle_irq(int irq_num, void *data)
399 struct starlink_pmu *starlink_pmu = data;
400 struct starlink_hw_events *hw_events =
401 this_cpu_ptr(starlink_pmu->hw_events);
402 bool handled = false;
406 for (idx = 0; idx < STARLINK_PMU_MAX_COUNTERS; idx++) {
407 struct perf_event *event = hw_events->events[idx];
412 overflow_status = readq(starlink_pmu->pmu_base +
413 STARLINK_PMU_COUNTER_OVERFLOW_STATUS);
414 if (!(overflow_status & BIT_ULL(idx)))
417 writeq(BIT_ULL(idx), starlink_pmu->pmu_base +
418 STARLINK_PMU_COUNTER_OVERFLOW_STATUS);
420 starlink_pmu_update(event);
421 starlink_pmu_set_event_period(event);
424 return IRQ_RETVAL(handled);
427 static int starlink_setup_irqs(struct starlink_pmu *starlink_pmu,
428 struct platform_device *pdev)
432 irq = platform_get_irq(pdev, 0);
436 ret = devm_request_irq(&pdev->dev, irq, starlink_pmu_handle_irq,
437 0, STARLINK_PMU_PDEV_NAME, starlink_pmu);
439 return dev_err_probe(&pdev->dev, ret, "Failed to request IRQ\n");
441 starlink_pmu->irq = irq;
446 static int starlink_pmu_pm_notify(struct notifier_block *b,
447 unsigned long cmd, void *v)
449 struct starlink_pmu *starlink_pmu = container_of(b, struct starlink_pmu,
451 struct starlink_hw_events *hw_events =
452 this_cpu_ptr(starlink_pmu->hw_events);
453 int enabled = bitmap_weight(hw_events->used_mask,
454 STARLINK_PMU_MAX_COUNTERS);
455 struct perf_event *event;
461 for (idx = 0; idx < STARLINK_PMU_MAX_COUNTERS; idx++) {
462 event = hw_events->events[idx];
468 /* Stop and update the counter */
469 starlink_pmu_stop(event, PERF_EF_UPDATE);
472 case CPU_PM_ENTER_FAILED:
473 /* Restore and enable the counter */
474 starlink_pmu_start(event, PERF_EF_RELOAD);
484 static int starlink_pmu_pm_register(struct starlink_pmu *starlink_pmu)
486 if (!IS_ENABLED(CONFIG_CPU_PM))
489 starlink_pmu->starlink_pmu_pm_nb.notifier_call = starlink_pmu_pm_notify;
490 return cpu_pm_register_notifier(&starlink_pmu->starlink_pmu_pm_nb);
493 static void starlink_pmu_pm_unregister(struct starlink_pmu *starlink_pmu)
495 if (!IS_ENABLED(CONFIG_CPU_PM))
498 cpu_pm_unregister_notifier(&starlink_pmu->starlink_pmu_pm_nb);
501 static void starlink_pmu_destroy(struct starlink_pmu *starlink_pmu)
503 starlink_pmu_pm_unregister(starlink_pmu);
504 cpuhp_state_remove_instance(starlink_pmu_cpuhp_state,
505 &starlink_pmu->node);
508 static int starlink_pmu_probe(struct platform_device *pdev)
510 struct starlink_pmu *starlink_pmu;
511 struct starlink_hw_events *hw_events;
512 struct resource *res;
515 starlink_pmu = devm_kzalloc(&pdev->dev, sizeof(*starlink_pmu), GFP_KERNEL);
519 starlink_pmu->pmu_base =
520 devm_platform_get_and_ioremap_resource(pdev, 0, &res);
521 if (IS_ERR(starlink_pmu->pmu_base))
522 return PTR_ERR(starlink_pmu->pmu_base);
524 starlink_pmu->hw_events = alloc_percpu_gfp(struct starlink_hw_events,
526 if (!starlink_pmu->hw_events) {
527 dev_err(&pdev->dev, "Failed to allocate per-cpu PMU data\n");
531 for_each_possible_cpu(cpuid) {
532 hw_events = per_cpu_ptr(starlink_pmu->hw_events, cpuid);
533 for (i = 0; i < STARLINK_PMU_MAX_COUNTERS; i++)
534 hw_events->events[i] = NULL;
537 ret = starlink_setup_irqs(starlink_pmu, pdev);
541 ret = cpuhp_state_add_instance(starlink_pmu_cpuhp_state,
542 &starlink_pmu->node);
544 dev_err(&pdev->dev, "Failed to register hotplug\n");
548 ret = starlink_pmu_pm_register(starlink_pmu);
550 cpuhp_state_remove_instance(starlink_pmu_cpuhp_state,
551 &starlink_pmu->node);
555 starlink_pmu->pmu = (struct pmu) {
556 .task_ctx_nr = perf_invalid_context,
557 .event_init = starlink_pmu_event_init,
558 .add = starlink_pmu_add,
559 .del = starlink_pmu_del,
560 .start = starlink_pmu_start,
561 .stop = starlink_pmu_stop,
562 .read = starlink_pmu_update,
563 .attr_groups = starlink_pmu_attr_groups,
566 ret = perf_pmu_register(&starlink_pmu->pmu, STARLINK_PMU_PDEV_NAME, -1);
568 starlink_pmu_destroy(starlink_pmu);
573 static const struct of_device_id starlink_pmu_of_match[] = {
574 { .compatible = "starfive,jh8100-starlink-pmu" },
577 MODULE_DEVICE_TABLE(of, starlink_pmu_of_match);
579 static struct platform_driver starlink_pmu_driver = {
581 .name = STARLINK_PMU_PDEV_NAME,
582 .of_match_table = starlink_pmu_of_match,
583 .suppress_bind_attrs = true,
585 .probe = starlink_pmu_probe,
589 starlink_pmu_online_cpu(unsigned int cpu, struct hlist_node *node)
591 struct starlink_pmu *starlink_pmu = hlist_entry_safe(node,
595 if (cpumask_empty(&starlink_pmu->cpumask))
596 cpumask_set_cpu(cpu, &starlink_pmu->cpumask);
598 WARN_ON(irq_set_affinity(starlink_pmu->irq, cpumask_of(cpu)));
604 starlink_pmu_offline_cpu(unsigned int cpu, struct hlist_node *node)
606 struct starlink_pmu *starlink_pmu = hlist_entry_safe(node,
611 if (!cpumask_test_and_clear_cpu(cpu, &starlink_pmu->cpumask))
614 target = cpumask_any_but(cpu_online_mask, cpu);
615 if (target >= nr_cpu_ids)
618 perf_pmu_migrate_context(&starlink_pmu->pmu, cpu, target);
620 cpumask_set_cpu(target, &starlink_pmu->cpumask);
621 WARN_ON(irq_set_affinity(starlink_pmu->irq, cpumask_of(target)));
626 static int __init starlink_pmu_init(void)
630 ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
631 "soc/starfive/starlink_pmu:online",
632 starlink_pmu_online_cpu,
633 starlink_pmu_offline_cpu);
637 starlink_pmu_cpuhp_state = ret;
639 return platform_driver_register(&starlink_pmu_driver);
642 device_initcall(starlink_pmu_init);