Lines Matching defs:hisi_ptt
22 #include "hisi_ptt.h"
27 static bool hisi_ptt_wait_tuning_finish(struct hisi_ptt *hisi_ptt)
31 return !readl_poll_timeout(hisi_ptt->iobase + HISI_PTT_TUNING_INT_STAT,
41 struct hisi_ptt *hisi_ptt = to_hisi_ptt(dev_get_drvdata(dev));
50 mutex_lock(&hisi_ptt->tune_lock);
52 reg = readl(hisi_ptt->iobase + HISI_PTT_TUNING_CTRL);
56 writel(reg, hisi_ptt->iobase + HISI_PTT_TUNING_CTRL);
59 writel(~0U, hisi_ptt->iobase + HISI_PTT_TUNING_DATA);
61 if (!hisi_ptt_wait_tuning_finish(hisi_ptt)) {
62 mutex_unlock(&hisi_ptt->tune_lock);
66 reg = readl(hisi_ptt->iobase + HISI_PTT_TUNING_DATA);
70 mutex_unlock(&hisi_ptt->tune_lock);
78 struct hisi_ptt *hisi_ptt = to_hisi_ptt(dev_get_drvdata(dev));
90 mutex_lock(&hisi_ptt->tune_lock);
92 reg = readl(hisi_ptt->iobase + HISI_PTT_TUNING_CTRL);
96 writel(reg, hisi_ptt->iobase + HISI_PTT_TUNING_CTRL);
98 hisi_ptt->iobase + HISI_PTT_TUNING_DATA);
100 if (!hisi_ptt_wait_tuning_finish(hisi_ptt)) {
101 mutex_unlock(&hisi_ptt->tune_lock);
105 mutex_unlock(&hisi_ptt->tune_lock);
128 * completion TLPs. See hisi_ptt.rst documentation for more information.
164 static bool hisi_ptt_wait_trace_hw_idle(struct hisi_ptt *hisi_ptt)
168 return !readl_poll_timeout_atomic(hisi_ptt->iobase + HISI_PTT_TRACE_STS,
174 static void hisi_ptt_wait_dma_reset_done(struct hisi_ptt *hisi_ptt)
178 readl_poll_timeout_atomic(hisi_ptt->iobase + HISI_PTT_TRACE_WR_STS,
183 static void hisi_ptt_trace_end(struct hisi_ptt *hisi_ptt)
185 writel(0, hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
186 hisi_ptt->trace_ctrl.started = false;
189 static int hisi_ptt_trace_start(struct hisi_ptt *hisi_ptt)
191 struct hisi_ptt_trace_ctrl *ctrl = &hisi_ptt->trace_ctrl;
196 if (!hisi_ptt_wait_trace_hw_idle(hisi_ptt)) {
197 pci_err(hisi_ptt->pdev, "Failed to start trace, the device is still busy\n");
204 val = readl(hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
206 writel(val, hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
208 hisi_ptt_wait_dma_reset_done(hisi_ptt);
210 val = readl(hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
212 writel(val, hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
215 hisi_ptt->trace_ctrl.buf_index = 0;
222 writel(HISI_PTT_TRACE_INT_STAT_MASK, hisi_ptt->iobase + HISI_PTT_TRACE_INT_STAT);
223 writel(0, hisi_ptt->iobase + HISI_PTT_TRACE_INT_MASK);
229 val |= FIELD_PREP(HISI_PTT_TRACE_CTRL_TARGET_SEL, hisi_ptt->trace_ctrl.filter);
230 if (!hisi_ptt->trace_ctrl.is_port)
235 writel(val, hisi_ptt->iobase + HISI_PTT_TRACE_CTRL);
240 static int hisi_ptt_update_aux(struct hisi_ptt *hisi_ptt, int index, bool stop)
242 struct hisi_ptt_trace_ctrl *ctrl = &hisi_ptt->trace_ctrl;
263 reg = readl(hisi_ptt->iobase + HISI_PTT_TRACE_WR_STS);
298 struct hisi_ptt *hisi_ptt = context;
301 status = readl(hisi_ptt->iobase + HISI_PTT_TRACE_INT_STAT);
308 writel(status, hisi_ptt->iobase + HISI_PTT_TRACE_INT_STAT);
316 if (hisi_ptt_update_aux(hisi_ptt, buf_idx, false))
317 hisi_ptt_trace_end(hisi_ptt);
319 hisi_ptt->trace_ctrl.buf_index = (buf_idx + 1) % HISI_PTT_TRACE_BUF_CNT;
329 static int hisi_ptt_register_irq(struct hisi_ptt *hisi_ptt)
331 struct pci_dev *pdev = hisi_ptt->pdev;
344 hisi_ptt->trace_irq = pci_irq_vector(pdev, HISI_PTT_TRACE_DMA_IRQ);
345 ret = devm_request_irq(&pdev->dev, hisi_ptt->trace_irq, hisi_ptt_isr,
347 hisi_ptt);
350 hisi_ptt->trace_irq, ret);
357 static void hisi_ptt_del_free_filter(struct hisi_ptt *hisi_ptt,
361 hisi_ptt->port_mask &= ~hisi_ptt_get_filter_val(filter->devid, true);
369 hisi_ptt_alloc_add_filter(struct hisi_ptt *hisi_ptt, u16 devid, bool is_port)
375 filter_name = kasprintf(GFP_KERNEL, "%04x:%02x:%02x.%d", pci_domain_nr(hisi_ptt->pdev->bus),
378 pci_err(hisi_ptt->pdev, "failed to allocate name for filter %04x:%02x:%02x.%d\n",
379 pci_domain_nr(hisi_ptt->pdev->bus), PCI_BUS_NUM(devid),
386 pci_err(hisi_ptt->pdev, "failed to add filter for %s\n",
397 list_add_tail(&filter->list, &hisi_ptt->port_filters);
400 hisi_ptt->port_mask |= hisi_ptt_get_filter_val(filter->devid, true);
402 list_add_tail(&filter->list, &hisi_ptt->req_filters);
421 static int hisi_ptt_create_rp_filter_attr(struct hisi_ptt *hisi_ptt,
424 struct kobject *kobj = &hisi_ptt->hisi_ptt_pmu.dev->kobj;
435 static void hisi_ptt_remove_rp_filter_attr(struct hisi_ptt *hisi_ptt,
438 struct kobject *kobj = &hisi_ptt->hisi_ptt_pmu.dev->kobj;
444 static int hisi_ptt_create_req_filter_attr(struct hisi_ptt *hisi_ptt,
447 struct kobject *kobj = &hisi_ptt->hisi_ptt_pmu.dev->kobj;
458 static void hisi_ptt_remove_req_filter_attr(struct hisi_ptt *hisi_ptt,
461 struct kobject *kobj = &hisi_ptt->hisi_ptt_pmu.dev->kobj;
467 static int hisi_ptt_create_filter_attr(struct hisi_ptt *hisi_ptt,
473 ret = hisi_ptt_create_rp_filter_attr(hisi_ptt, filter);
475 ret = hisi_ptt_create_req_filter_attr(hisi_ptt, filter);
478 pci_err(hisi_ptt->pdev, "failed to create sysfs attribute for filter %s\n",
484 static void hisi_ptt_remove_filter_attr(struct hisi_ptt *hisi_ptt,
488 hisi_ptt_remove_rp_filter_attr(hisi_ptt, filter);
490 hisi_ptt_remove_req_filter_attr(hisi_ptt, filter);
496 struct hisi_ptt *hisi_ptt = data;
498 mutex_lock(&hisi_ptt->filter_lock);
500 list_for_each_entry(filter, &hisi_ptt->req_filters, list)
501 hisi_ptt_remove_filter_attr(hisi_ptt, filter);
503 list_for_each_entry(filter, &hisi_ptt->port_filters, list)
504 hisi_ptt_remove_filter_attr(hisi_ptt, filter);
506 hisi_ptt->sysfs_inited = false;
507 mutex_unlock(&hisi_ptt->filter_lock);
510 static int hisi_ptt_init_filter_attributes(struct hisi_ptt *hisi_ptt)
515 mutex_lock(&hisi_ptt->filter_lock);
522 ret = devm_add_action(&hisi_ptt->pdev->dev,
524 hisi_ptt);
528 list_for_each_entry(filter, &hisi_ptt->port_filters, list) {
529 ret = hisi_ptt_create_filter_attr(hisi_ptt, filter);
534 list_for_each_entry(filter, &hisi_ptt->req_filters, list) {
535 ret = hisi_ptt_create_filter_attr(hisi_ptt, filter);
540 hisi_ptt->sysfs_inited = true;
542 mutex_unlock(&hisi_ptt->filter_lock);
551 struct hisi_ptt *hisi_ptt;
553 hisi_ptt = container_of(delayed_work, struct hisi_ptt, work);
555 if (!mutex_trylock(&hisi_ptt->filter_lock)) {
556 schedule_delayed_work(&hisi_ptt->work, HISI_PTT_WORK_DELAY_MS);
560 while (kfifo_get(&hisi_ptt->filter_update_kfifo, &info)) {
567 filter = hisi_ptt_alloc_add_filter(hisi_ptt, info.devid, info.is_port);
577 if (hisi_ptt->sysfs_inited &&
578 hisi_ptt_create_filter_attr(hisi_ptt, filter)) {
579 hisi_ptt_del_free_filter(hisi_ptt, filter);
586 target_list = info.is_port ? &hisi_ptt->port_filters :
587 &hisi_ptt->req_filters;
591 if (hisi_ptt->sysfs_inited)
592 hisi_ptt_remove_filter_attr(hisi_ptt, filter);
594 hisi_ptt_del_free_filter(hisi_ptt, filter);
600 mutex_unlock(&hisi_ptt->filter_lock);
610 struct hisi_ptt *hisi_ptt = container_of(nb, struct hisi_ptt, hisi_ptt_nb);
622 if (port_devid < hisi_ptt->lower_bdf ||
623 port_devid > hisi_ptt->upper_bdf)
646 if (kfifo_in_spinlocked(&hisi_ptt->filter_update_kfifo, &info, 1,
647 &hisi_ptt->filter_update_lock))
648 schedule_delayed_work(&hisi_ptt->work, 0);
650 pci_warn(hisi_ptt->pdev,
661 struct hisi_ptt *hisi_ptt = data;
668 if (port_devid < hisi_ptt->lower_bdf ||
669 port_devid > hisi_ptt->upper_bdf)
677 filter = hisi_ptt_alloc_add_filter(hisi_ptt, pci_dev_id(pdev),
688 struct hisi_ptt *hisi_ptt = data;
690 list_for_each_entry_safe(filter, tmp, &hisi_ptt->req_filters, list)
691 hisi_ptt_del_free_filter(hisi_ptt, filter);
693 list_for_each_entry_safe(filter, tmp, &hisi_ptt->port_filters, list)
694 hisi_ptt_del_free_filter(hisi_ptt, filter);
697 static int hisi_ptt_config_trace_buf(struct hisi_ptt *hisi_ptt)
699 struct hisi_ptt_trace_ctrl *ctrl = &hisi_ptt->trace_ctrl;
700 struct device *dev = &hisi_ptt->pdev->dev;
719 hisi_ptt->iobase + HISI_PTT_TRACE_ADDR_BASE_LO_0 +
722 hisi_ptt->iobase + HISI_PTT_TRACE_ADDR_BASE_HI_0 +
725 writel(HISI_PTT_TRACE_BUF_SIZE, hisi_ptt->iobase + HISI_PTT_TRACE_ADDR_SIZE);
730 static int hisi_ptt_init_ctrls(struct hisi_ptt *hisi_ptt)
732 struct pci_dev *pdev = hisi_ptt->pdev;
737 INIT_DELAYED_WORK(&hisi_ptt->work, hisi_ptt_update_filters);
738 INIT_KFIFO(hisi_ptt->filter_update_kfifo);
739 spin_lock_init(&hisi_ptt->filter_update_lock);
741 INIT_LIST_HEAD(&hisi_ptt->port_filters);
742 INIT_LIST_HEAD(&hisi_ptt->req_filters);
743 mutex_init(&hisi_ptt->filter_lock);
745 ret = hisi_ptt_config_trace_buf(hisi_ptt);
758 reg = readl(hisi_ptt->iobase + HISI_PTT_DEVICE_RANGE);
759 hisi_ptt->upper_bdf = FIELD_GET(HISI_PTT_DEVICE_RANGE_UPPER, reg);
760 hisi_ptt->lower_bdf = FIELD_GET(HISI_PTT_DEVICE_RANGE_LOWER, reg);
762 bus = pci_find_bus(pci_domain_nr(pdev->bus), PCI_BUS_NUM(hisi_ptt->upper_bdf));
764 pci_walk_bus(bus, hisi_ptt_init_filters, hisi_ptt);
766 ret = devm_add_action_or_reset(&pdev->dev, hisi_ptt_release_filters, hisi_ptt);
770 hisi_ptt->trace_ctrl.on_cpu = -1;
777 struct hisi_ptt *hisi_ptt = to_hisi_ptt(dev_get_drvdata(dev));
778 const cpumask_t *cpumask = cpumask_of_node(dev_to_node(&hisi_ptt->pdev->dev));
799 * See hisi_ptt.rst documentation for detailed information.
879 * set of TLP types. See hisi_ptt.rst documentation for more details.
940 static int hisi_ptt_trace_valid_filter(struct hisi_ptt *hisi_ptt, u64 config)
942 unsigned long val, port_mask = hisi_ptt->port_mask;
946 hisi_ptt->trace_ctrl.is_port = FIELD_GET(HISI_PTT_PMU_FILTER_IS_PORT, config);
951 * the bits in the @val are within the range of hisi_ptt->port_mask
958 mutex_lock(&hisi_ptt->filter_lock);
959 if (!hisi_ptt->trace_ctrl.is_port) {
960 list_for_each_entry(filter, &hisi_ptt->req_filters, list) {
970 mutex_unlock(&hisi_ptt->filter_lock);
974 static void hisi_ptt_pmu_init_configs(struct hisi_ptt *hisi_ptt, struct perf_event *event)
976 struct hisi_ptt_trace_ctrl *ctrl = &hisi_ptt->trace_ctrl;
980 hisi_ptt->trace_ctrl.filter = val;
994 struct hisi_ptt *hisi_ptt = to_hisi_ptt(event->pmu);
998 if (event->attr.type != hisi_ptt->hisi_ptt_pmu.type)
1009 ret = hisi_ptt_trace_valid_filter(hisi_ptt, event->attr.config);
1081 struct hisi_ptt *hisi_ptt = to_hisi_ptt(event->pmu);
1082 struct perf_output_handle *handle = &hisi_ptt->trace_ctrl.handle;
1092 spin_lock(&hisi_ptt->pmu_lock);
1093 if (hisi_ptt->trace_ctrl.started) {
1104 ret = irq_set_affinity(hisi_ptt->trace_irq, cpumask_of(cpu));
1108 hisi_ptt->trace_ctrl.on_cpu = cpu;
1118 hisi_ptt_pmu_init_configs(hisi_ptt, event);
1120 ret = hisi_ptt_trace_start(hisi_ptt);
1127 spin_unlock(&hisi_ptt->pmu_lock);
1131 spin_unlock(&hisi_ptt->pmu_lock);
1136 struct hisi_ptt *hisi_ptt = to_hisi_ptt(event->pmu);
1142 spin_lock(&hisi_ptt->pmu_lock);
1143 if (hisi_ptt->trace_ctrl.started) {
1144 hisi_ptt_trace_end(hisi_ptt);
1146 if (!hisi_ptt_wait_trace_hw_idle(hisi_ptt))
1149 hisi_ptt_update_aux(hisi_ptt, hisi_ptt->trace_ctrl.buf_index, true);
1151 spin_unlock(&hisi_ptt->pmu_lock);
1160 struct hisi_ptt *hisi_ptt = to_hisi_ptt(event->pmu);
1165 if (!cpumask_test_cpu(cpu, cpumask_of_node(dev_to_node(&hisi_ptt->pdev->dev))))
1198 static int hisi_ptt_register_pmu(struct hisi_ptt *hisi_ptt)
1206 &hisi_ptt->hotplug_node);
1210 ret = devm_add_action_or_reset(&hisi_ptt->pdev->dev,
1212 &hisi_ptt->hotplug_node);
1216 mutex_init(&hisi_ptt->tune_lock);
1217 spin_lock_init(&hisi_ptt->pmu_lock);
1219 hisi_ptt->hisi_ptt_pmu = (struct pmu) {
1234 reg = readl(hisi_ptt->iobase + HISI_PTT_LOCATION);
1238 pmu_name = devm_kasprintf(&hisi_ptt->pdev->dev, GFP_KERNEL, "hisi_ptt%u_%u",
1243 ret = perf_pmu_register(&hisi_ptt->hisi_ptt_pmu, pmu_name, -1);
1247 return devm_add_action_or_reset(&hisi_ptt->pdev->dev,
1249 &hisi_ptt->hisi_ptt_pmu);
1254 struct hisi_ptt *hisi_ptt = data;
1256 bus_unregister_notifier(&pci_bus_type, &hisi_ptt->hisi_ptt_nb);
1259 cancel_delayed_work_sync(&hisi_ptt->work);
1263 static int hisi_ptt_register_filter_update_notifier(struct hisi_ptt *hisi_ptt)
1267 hisi_ptt->hisi_ptt_nb.notifier_call = hisi_ptt_notifier_call;
1268 ret = bus_register_notifier(&pci_bus_type, &hisi_ptt->hisi_ptt_nb);
1272 return devm_add_action_or_reset(&hisi_ptt->pdev->dev,
1274 hisi_ptt);
1300 struct hisi_ptt *hisi_ptt;
1309 hisi_ptt = devm_kzalloc(&pdev->dev, sizeof(*hisi_ptt), GFP_KERNEL);
1310 if (!hisi_ptt)
1313 hisi_ptt->pdev = pdev;
1314 pci_set_drvdata(pdev, hisi_ptt);
1328 hisi_ptt->iobase = pcim_iomap_table(pdev)[2];
1338 ret = hisi_ptt_register_irq(hisi_ptt);
1342 ret = hisi_ptt_init_ctrls(hisi_ptt);
1348 ret = hisi_ptt_register_filter_update_notifier(hisi_ptt);
1352 ret = hisi_ptt_register_pmu(hisi_ptt);
1358 ret = hisi_ptt_init_filter_attributes(hisi_ptt);
1381 struct hisi_ptt *hisi_ptt;
1385 hisi_ptt = hlist_entry_safe(node, struct hisi_ptt, hotplug_node);
1386 src = hisi_ptt->trace_ctrl.on_cpu;
1387 dev = hisi_ptt->hisi_ptt_pmu.dev;
1389 if (!hisi_ptt->trace_ctrl.started || src != cpu)
1392 target = cpumask_any_but(cpumask_of_node(dev_to_node(&hisi_ptt->pdev->dev)), cpu);
1398 perf_pmu_migrate_context(&hisi_ptt->hisi_ptt_pmu, src, target);
1404 if (irq_set_affinity(hisi_ptt->trace_irq, cpumask_of(target)))
1407 hisi_ptt->trace_ctrl.on_cpu = target;