Lines Matching +full:imx6q +full:- +full:mmdc

1 // SPDX-License-Identifier: GPL-2.0-or-later
75 { .compatible = "fsl,imx6q-mmdc", .data = (void *)&imx6q_data},
76 { .compatible = "fsl,imx6qp-mmdc", .data = (void *)&imx6qp_data},
85 PMU_EVENT_ATTR_STRING(total-cycles, mmdc_pmu_total_cycles, "event=0x00")
86 PMU_EVENT_ATTR_STRING(busy-cycles, mmdc_pmu_busy_cycles, "event=0x01")
87 PMU_EVENT_ATTR_STRING(read-accesses, mmdc_pmu_read_accesses, "event=0x02")
88 PMU_EVENT_ATTR_STRING(write-accesses, mmdc_pmu_write_accesses, "event=0x03")
89 PMU_EVENT_ATTR_STRING(read-bytes, mmdc_pmu_read_bytes, "event=0x04")
90 PMU_EVENT_ATTR_STRING(read-bytes.unit, mmdc_pmu_read_bytes_unit, "MB");
91 PMU_EVENT_ATTR_STRING(read-bytes.scale, mmdc_pmu_read_bytes_scale, "0.000001");
92 PMU_EVENT_ATTR_STRING(write-bytes, mmdc_pmu_write_bytes, "event=0x05")
93 PMU_EVENT_ATTR_STRING(write-bytes.unit, mmdc_pmu_write_bytes_unit, "MB");
94 PMU_EVENT_ATTR_STRING(write-bytes.scale, mmdc_pmu_write_bytes_scale, "0.000001");
110 * Polling period is set to one second, overflow of total-cycles (the fastest
128 return cpumap_print_to_pagebuf(true, buf, &pmu_mmdc->cpu); in mmdc_pmu_cpumask_show()
162 PMU_FORMAT_ATTR(event, "config:0-63");
163 PMU_FORMAT_ATTR(axi_id, "config1:0-63");
187 mmdc_base = pmu_mmdc->mmdc_base; in mmdc_pmu_read_counter()
210 "invalid configuration %d for mmdc counter", cfg); in mmdc_pmu_read_counter()
220 if (!cpumask_test_and_clear_cpu(cpu, &pmu_mmdc->cpu)) in mmdc_pmu_offline_cpu()
227 perf_pmu_migrate_context(&pmu_mmdc->pmu, cpu, target); in mmdc_pmu_offline_cpu()
228 cpumask_set_cpu(target, &pmu_mmdc->cpu); in mmdc_pmu_offline_cpu()
237 int cfg = event->attr.config; in mmdc_pmu_group_event_is_valid()
242 if (event->pmu != pmu) in mmdc_pmu_group_event_is_valid()
249 * Each event has a single fixed-purpose counter, so we can only have a
256 struct pmu *pmu = event->pmu; in mmdc_pmu_group_is_valid()
257 struct perf_event *leader = event->group_leader; in mmdc_pmu_group_is_valid()
261 set_bit(leader->attr.config, &counter_mask); in mmdc_pmu_group_is_valid()
278 struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu); in mmdc_pmu_event_init()
279 int cfg = event->attr.config; in mmdc_pmu_event_init()
281 if (event->attr.type != event->pmu->type) in mmdc_pmu_event_init()
282 return -ENOENT; in mmdc_pmu_event_init()
284 if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK) in mmdc_pmu_event_init()
285 return -EOPNOTSUPP; in mmdc_pmu_event_init()
287 if (event->cpu < 0) { in mmdc_pmu_event_init()
288 dev_warn(pmu_mmdc->dev, "Can't provide per-task data!\n"); in mmdc_pmu_event_init()
289 return -EOPNOTSUPP; in mmdc_pmu_event_init()
292 if (event->attr.sample_period) in mmdc_pmu_event_init()
293 return -EINVAL; in mmdc_pmu_event_init()
296 return -EINVAL; in mmdc_pmu_event_init()
299 return -EINVAL; in mmdc_pmu_event_init()
301 event->cpu = cpumask_first(&pmu_mmdc->cpu); in mmdc_pmu_event_init()
307 struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu); in mmdc_pmu_event_update()
308 struct hw_perf_event *hwc = &event->hw; in mmdc_pmu_event_update()
312 prev_raw_count = local64_read(&hwc->prev_count); in mmdc_pmu_event_update()
314 event->attr.config); in mmdc_pmu_event_update()
315 } while (local64_cmpxchg(&hwc->prev_count, prev_raw_count, in mmdc_pmu_event_update()
318 delta = (new_raw_count - prev_raw_count) & 0xFFFFFFFF; in mmdc_pmu_event_update()
320 local64_add(delta, &event->count); in mmdc_pmu_event_update()
325 struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu); in mmdc_pmu_event_start()
326 struct hw_perf_event *hwc = &event->hw; in mmdc_pmu_event_start()
330 mmdc_base = pmu_mmdc->mmdc_base; in mmdc_pmu_event_start()
334 * hrtimer is required because mmdc does not provide an interrupt so in mmdc_pmu_event_start()
337 hrtimer_start(&pmu_mmdc->hrtimer, mmdc_pmu_timer_period(), in mmdc_pmu_event_start()
340 local64_set(&hwc->prev_count, 0); in mmdc_pmu_event_start()
347 val = event->attr.config1; in mmdc_pmu_event_start()
353 if (pmu_mmdc->devtype_data->flags & MMDC_FLAG_PROFILE_SEL) in mmdc_pmu_event_start()
361 struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu); in mmdc_pmu_event_add()
362 struct hw_perf_event *hwc = &event->hw; in mmdc_pmu_event_add()
364 int cfg = event->attr.config; in mmdc_pmu_event_add()
369 if (pmu_mmdc->mmdc_events[cfg] != NULL) in mmdc_pmu_event_add()
370 return -EAGAIN; in mmdc_pmu_event_add()
372 pmu_mmdc->mmdc_events[cfg] = event; in mmdc_pmu_event_add()
373 pmu_mmdc->active_events++; in mmdc_pmu_event_add()
375 local64_set(&hwc->prev_count, mmdc_pmu_read_counter(pmu_mmdc, cfg)); in mmdc_pmu_event_add()
382 struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu); in mmdc_pmu_event_stop()
385 mmdc_base = pmu_mmdc->mmdc_base; in mmdc_pmu_event_stop()
398 struct mmdc_pmu *pmu_mmdc = to_mmdc_pmu(event->pmu); in mmdc_pmu_event_del()
399 int cfg = event->attr.config; in mmdc_pmu_event_del()
401 pmu_mmdc->mmdc_events[cfg] = NULL; in mmdc_pmu_event_del()
402 pmu_mmdc->active_events--; in mmdc_pmu_event_del()
404 if (pmu_mmdc->active_events == 0) in mmdc_pmu_event_del()
405 hrtimer_cancel(&pmu_mmdc->hrtimer); in mmdc_pmu_event_del()
415 struct perf_event *event = pmu_mmdc->mmdc_events[i]; in mmdc_pmu_overflow_handler()
464 cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node); in imx_mmdc_remove()
465 perf_pmu_unregister(&pmu_mmdc->pmu); in imx_mmdc_remove()
466 iounmap(pmu_mmdc->mmdc_base); in imx_mmdc_remove()
467 clk_disable_unprepare(pmu_mmdc->mmdc_ipg_clk); in imx_mmdc_remove()
480 of_match_device(imx_mmdc_dt_ids, &pdev->dev); in imx_mmdc_perf_init()
485 return -ENOMEM; in imx_mmdc_perf_init()
491 "perf/arm/mmdc:online", NULL, in imx_mmdc_perf_init()
500 mmdc_num = mmdc_pmu_init(pmu_mmdc, mmdc_base, &pdev->dev); in imx_mmdc_perf_init()
501 pmu_mmdc->mmdc_ipg_clk = mmdc_ipg_clk; in imx_mmdc_perf_init()
503 name = "mmdc"; in imx_mmdc_perf_init()
505 name = devm_kasprintf(&pdev->dev, in imx_mmdc_perf_init()
506 GFP_KERNEL, "mmdc%d", mmdc_num); in imx_mmdc_perf_init()
508 pmu_mmdc->devtype_data = (struct fsl_mmdc_devtype_data *)of_id->data; in imx_mmdc_perf_init()
510 hrtimer_init(&pmu_mmdc->hrtimer, CLOCK_MONOTONIC, in imx_mmdc_perf_init()
512 pmu_mmdc->hrtimer.function = mmdc_pmu_timer_handler; in imx_mmdc_perf_init()
514 cpumask_set_cpu(raw_smp_processor_id(), &pmu_mmdc->cpu); in imx_mmdc_perf_init()
517 cpuhp_state_add_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node); in imx_mmdc_perf_init()
519 ret = perf_pmu_register(&(pmu_mmdc->pmu), name, -1); in imx_mmdc_perf_init()
527 pr_warn("MMDC Perf PMU failed (%d), disabled\n", ret); in imx_mmdc_perf_init()
528 cpuhp_state_remove_instance_nocalls(cpuhp_mmdc_state, &pmu_mmdc->node); in imx_mmdc_perf_init()
529 hrtimer_cancel(&pmu_mmdc->hrtimer); in imx_mmdc_perf_init()
542 struct device_node *np = pdev->dev.of_node; in imx_mmdc_probe()
549 mmdc_ipg_clk = devm_clk_get(&pdev->dev, NULL); in imx_mmdc_probe()
555 dev_err(&pdev->dev, "Unable to enable mmdc ipg clock.\n"); in imx_mmdc_probe()
591 .name = "imx-mmdc",