Lines Matching +full:multi +full:- +full:attr

1 // SPDX-License-Identifier: GPL-2.0
10 #include <linux/coresight-pmu.h>
19 #include "coresight-priv.h"
20 #include "coresight-tpdm.h"
26 struct device_attribute *attr, in tpdm_simple_dataset_show() argument
29 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in tpdm_simple_dataset_show()
31 container_of(attr, struct tpdm_dataset_attribute, attr); in tpdm_simple_dataset_show()
33 switch (tpdm_attr->mem) { in tpdm_simple_dataset_show()
35 if (tpdm_attr->idx >= TPDM_DSB_MAX_EDCR) in tpdm_simple_dataset_show()
36 return -EINVAL; in tpdm_simple_dataset_show()
38 drvdata->dsb->edge_ctrl[tpdm_attr->idx]); in tpdm_simple_dataset_show()
40 if (tpdm_attr->idx >= TPDM_DSB_MAX_EDCMR) in tpdm_simple_dataset_show()
41 return -EINVAL; in tpdm_simple_dataset_show()
43 drvdata->dsb->edge_ctrl_mask[tpdm_attr->idx]); in tpdm_simple_dataset_show()
45 if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT) in tpdm_simple_dataset_show()
46 return -EINVAL; in tpdm_simple_dataset_show()
48 drvdata->dsb->trig_patt[tpdm_attr->idx]); in tpdm_simple_dataset_show()
50 if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT) in tpdm_simple_dataset_show()
51 return -EINVAL; in tpdm_simple_dataset_show()
53 drvdata->dsb->trig_patt_mask[tpdm_attr->idx]); in tpdm_simple_dataset_show()
55 if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT) in tpdm_simple_dataset_show()
56 return -EINVAL; in tpdm_simple_dataset_show()
58 drvdata->dsb->patt_val[tpdm_attr->idx]); in tpdm_simple_dataset_show()
60 if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT) in tpdm_simple_dataset_show()
61 return -EINVAL; in tpdm_simple_dataset_show()
63 drvdata->dsb->patt_mask[tpdm_attr->idx]); in tpdm_simple_dataset_show()
65 if (tpdm_attr->idx >= drvdata->dsb_msr_num) in tpdm_simple_dataset_show()
66 return -EINVAL; in tpdm_simple_dataset_show()
68 drvdata->dsb->msr[tpdm_attr->idx]); in tpdm_simple_dataset_show()
70 return -EINVAL; in tpdm_simple_dataset_show()
75 struct device_attribute *attr, in tpdm_simple_dataset_store() argument
82 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in tpdm_simple_dataset_store()
84 container_of(attr, struct tpdm_dataset_attribute, attr); in tpdm_simple_dataset_store()
87 return -EINVAL; in tpdm_simple_dataset_store()
89 spin_lock(&drvdata->spinlock); in tpdm_simple_dataset_store()
90 switch (tpdm_attr->mem) { in tpdm_simple_dataset_store()
92 if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) in tpdm_simple_dataset_store()
93 drvdata->dsb->trig_patt[tpdm_attr->idx] = val; in tpdm_simple_dataset_store()
95 ret = -EINVAL; in tpdm_simple_dataset_store()
98 if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) in tpdm_simple_dataset_store()
99 drvdata->dsb->trig_patt_mask[tpdm_attr->idx] = val; in tpdm_simple_dataset_store()
101 ret = -EINVAL; in tpdm_simple_dataset_store()
104 if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) in tpdm_simple_dataset_store()
105 drvdata->dsb->patt_val[tpdm_attr->idx] = val; in tpdm_simple_dataset_store()
107 ret = -EINVAL; in tpdm_simple_dataset_store()
110 if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) in tpdm_simple_dataset_store()
111 drvdata->dsb->patt_mask[tpdm_attr->idx] = val; in tpdm_simple_dataset_store()
113 ret = -EINVAL; in tpdm_simple_dataset_store()
116 if (tpdm_attr->idx < drvdata->dsb_msr_num) in tpdm_simple_dataset_store()
117 drvdata->dsb->msr[tpdm_attr->idx] = val; in tpdm_simple_dataset_store()
119 ret = -EINVAL; in tpdm_simple_dataset_store()
122 ret = -EINVAL; in tpdm_simple_dataset_store()
124 spin_unlock(&drvdata->spinlock); in tpdm_simple_dataset_store()
131 return (drvdata->datasets & TPDM_PIDR0_DS_DSB); in tpdm_has_dsb_dataset()
135 struct attribute *attr, int n) in tpdm_dsb_is_visible() argument
138 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in tpdm_dsb_is_visible()
141 return attr->mode; in tpdm_dsb_is_visible()
147 struct attribute *attr, int n) in tpdm_dsb_msr_is_visible() argument
150 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in tpdm_dsb_msr_is_visible()
152 container_of(attr, struct device_attribute, attr); in tpdm_dsb_msr_is_visible()
154 container_of(dev_attr, struct tpdm_dataset_attribute, attr); in tpdm_dsb_msr_is_visible()
156 if (tpdm_attr->idx < drvdata->dsb_msr_num) in tpdm_dsb_msr_is_visible()
157 return attr->mode; in tpdm_dsb_msr_is_visible()
165 memset(drvdata->dsb, 0, sizeof(struct dsb_dataset)); in tpdm_reset_datasets()
167 drvdata->dsb->trig_ts = true; in tpdm_reset_datasets()
168 drvdata->dsb->trig_type = false; in tpdm_reset_datasets()
177 mode = TPDM_DSB_MODE_TEST(drvdata->dsb->mode); in set_dsb_mode()
181 /* Set the byte lane for high-performance mode */ in set_dsb_mode()
182 mode = TPDM_DSB_MODE_HPBYTESEL(drvdata->dsb->mode); in set_dsb_mode()
187 if (drvdata->dsb->mode & TPDM_DSB_MODE_PERF) in set_dsb_mode()
197 val = readl_relaxed(drvdata->base + TPDM_DSB_TIER); in set_dsb_tier()
204 if (drvdata->dsb->patt_ts) { in set_dsb_tier()
206 if (drvdata->dsb->patt_type) in set_dsb_tier()
215 if (drvdata->dsb->trig_ts) in set_dsb_tier()
220 writel_relaxed(val, drvdata->base + TPDM_DSB_TIER); in set_dsb_tier()
227 for (i = 0; i < drvdata->dsb_msr_num; i++) in set_dsb_msr()
228 writel_relaxed(drvdata->dsb->msr[i], in set_dsb_msr()
229 drvdata->base + TPDM_DSB_MSR(i)); in set_dsb_msr()
237 writel_relaxed(drvdata->dsb->edge_ctrl[i], in tpdm_enable_dsb()
238 drvdata->base + TPDM_DSB_EDCR(i)); in tpdm_enable_dsb()
240 writel_relaxed(drvdata->dsb->edge_ctrl_mask[i], in tpdm_enable_dsb()
241 drvdata->base + TPDM_DSB_EDCMR(i)); in tpdm_enable_dsb()
243 writel_relaxed(drvdata->dsb->patt_val[i], in tpdm_enable_dsb()
244 drvdata->base + TPDM_DSB_TPR(i)); in tpdm_enable_dsb()
245 writel_relaxed(drvdata->dsb->patt_mask[i], in tpdm_enable_dsb()
246 drvdata->base + TPDM_DSB_TPMR(i)); in tpdm_enable_dsb()
247 writel_relaxed(drvdata->dsb->trig_patt[i], in tpdm_enable_dsb()
248 drvdata->base + TPDM_DSB_XPR(i)); in tpdm_enable_dsb()
249 writel_relaxed(drvdata->dsb->trig_patt_mask[i], in tpdm_enable_dsb()
250 drvdata->base + TPDM_DSB_XPMR(i)); in tpdm_enable_dsb()
257 val = readl_relaxed(drvdata->base + TPDM_DSB_CR); in tpdm_enable_dsb()
261 if (drvdata->dsb->trig_type) in tpdm_enable_dsb()
267 writel_relaxed(val, drvdata->base + TPDM_DSB_CR); in tpdm_enable_dsb()
274 * Continuous Multi-Bit(CMB), Multi-lane CMB(MCMB) and Discrete Single
280 CS_UNLOCK(drvdata->base); in __tpdm_enable()
285 CS_LOCK(drvdata->base); in __tpdm_enable()
291 struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); in tpdm_enable()
293 spin_lock(&drvdata->spinlock); in tpdm_enable()
294 if (drvdata->enable) { in tpdm_enable()
295 spin_unlock(&drvdata->spinlock); in tpdm_enable()
296 return -EBUSY; in tpdm_enable()
300 drvdata->enable = true; in tpdm_enable()
301 spin_unlock(&drvdata->spinlock); in tpdm_enable()
303 dev_dbg(drvdata->dev, "TPDM tracing enabled\n"); in tpdm_enable()
312 val = readl_relaxed(drvdata->base + TPDM_DSB_CR); in tpdm_disable_dsb()
314 writel_relaxed(val, drvdata->base + TPDM_DSB_CR); in tpdm_disable_dsb()
320 CS_UNLOCK(drvdata->base); in __tpdm_disable()
325 CS_LOCK(drvdata->base); in __tpdm_disable()
331 struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); in tpdm_disable()
333 spin_lock(&drvdata->spinlock); in tpdm_disable()
334 if (!drvdata->enable) { in tpdm_disable()
335 spin_unlock(&drvdata->spinlock); in tpdm_disable()
340 drvdata->enable = false; in tpdm_disable()
341 spin_unlock(&drvdata->spinlock); in tpdm_disable()
343 dev_dbg(drvdata->dev, "TPDM tracing disabled\n"); in tpdm_disable()
360 pidr = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR0); in tpdm_datasets_setup()
361 drvdata->datasets |= pidr & GENMASK(TPDM_DATASETS - 1, 0); in tpdm_datasets_setup()
363 if (tpdm_has_dsb_dataset(drvdata) && (!drvdata->dsb)) { in tpdm_datasets_setup()
364 drvdata->dsb = devm_kzalloc(drvdata->dev, in tpdm_datasets_setup()
365 sizeof(*drvdata->dsb), GFP_KERNEL); in tpdm_datasets_setup()
366 if (!drvdata->dsb) in tpdm_datasets_setup()
367 return -ENOMEM; in tpdm_datasets_setup()
375 struct device_attribute *attr, in reset_dataset_store() argument
381 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in reset_dataset_store()
385 return -EINVAL; in reset_dataset_store()
387 spin_lock(&drvdata->spinlock); in reset_dataset_store()
389 spin_unlock(&drvdata->spinlock); in reset_dataset_store()
400 struct device_attribute *attr, in integration_test_store() argument
406 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in integration_test_store()
413 return -EINVAL; in integration_test_store()
415 if (!drvdata->enable) in integration_test_store()
416 return -EINVAL; in integration_test_store()
422 CS_UNLOCK(drvdata->base); in integration_test_store()
423 writel_relaxed(0x1, drvdata->base + TPDM_ITCNTRL); in integration_test_store()
426 writel_relaxed(val, drvdata->base + TPDM_ITATBCNTRL); in integration_test_store()
428 writel_relaxed(0, drvdata->base + TPDM_ITCNTRL); in integration_test_store()
429 CS_LOCK(drvdata->base); in integration_test_store()
435 &dev_attr_reset_dataset.attr,
436 &dev_attr_integration_test.attr,
445 struct device_attribute *attr, in dsb_mode_show() argument
448 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in dsb_mode_show()
450 return sysfs_emit(buf, "%x\n", drvdata->dsb->mode); in dsb_mode_show()
454 struct device_attribute *attr, in dsb_mode_store() argument
458 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in dsb_mode_store()
463 return -EINVAL; in dsb_mode_store()
465 spin_lock(&drvdata->spinlock); in dsb_mode_store()
466 drvdata->dsb->mode = val & TPDM_DSB_MODE_MASK; in dsb_mode_store()
467 spin_unlock(&drvdata->spinlock); in dsb_mode_store()
473 struct device_attribute *attr, in ctrl_idx_show() argument
476 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in ctrl_idx_show()
479 (unsigned int)drvdata->dsb->edge_ctrl_idx); in ctrl_idx_show()
483 * The EDCR registers can include up to 16 32-bit registers, and each
490 struct device_attribute *attr, in ctrl_idx_store() argument
494 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in ctrl_idx_store()
498 return -EINVAL; in ctrl_idx_store()
500 spin_lock(&drvdata->spinlock); in ctrl_idx_store()
501 drvdata->dsb->edge_ctrl_idx = val; in ctrl_idx_store()
502 spin_unlock(&drvdata->spinlock); in ctrl_idx_store()
512 * 0 - Rising edge detection
513 * 1 - Falling edge detection
514 * 2 - Rising and falling edge detection (toggle detection)
517 struct device_attribute *attr, in ctrl_val_store() argument
521 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in ctrl_val_store()
526 return -EINVAL; in ctrl_val_store()
528 spin_lock(&drvdata->spinlock); in ctrl_val_store()
533 reg = EDCR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); in ctrl_val_store()
534 val = drvdata->dsb->edge_ctrl[reg]; in ctrl_val_store()
535 val &= ~EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx); in ctrl_val_store()
536 val |= EDCR_TO_WORD_VAL(edge_ctrl, drvdata->dsb->edge_ctrl_idx); in ctrl_val_store()
537 drvdata->dsb->edge_ctrl[reg] = val; in ctrl_val_store()
538 spin_unlock(&drvdata->spinlock); in ctrl_val_store()
545 struct device_attribute *attr, in ctrl_mask_store() argument
549 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in ctrl_mask_store()
555 return -EINVAL; in ctrl_mask_store()
557 spin_lock(&drvdata->spinlock); in ctrl_mask_store()
562 reg = EDCMR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx); in ctrl_mask_store()
563 set = drvdata->dsb->edge_ctrl_mask[reg]; in ctrl_mask_store()
565 set |= BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); in ctrl_mask_store()
567 set &= ~BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx)); in ctrl_mask_store()
568 drvdata->dsb->edge_ctrl_mask[reg] = set; in ctrl_mask_store()
569 spin_unlock(&drvdata->spinlock); in ctrl_mask_store()
576 struct device_attribute *attr, in enable_ts_show() argument
579 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in enable_ts_show()
582 (unsigned int)drvdata->dsb->patt_ts); in enable_ts_show()
589 struct device_attribute *attr, in enable_ts_store() argument
593 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in enable_ts_store()
597 return -EINVAL; in enable_ts_store()
599 spin_lock(&drvdata->spinlock); in enable_ts_store()
600 drvdata->dsb->patt_ts = !!val; in enable_ts_store()
601 spin_unlock(&drvdata->spinlock); in enable_ts_store()
607 struct device_attribute *attr, in set_type_show() argument
610 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in set_type_show()
613 (unsigned int)drvdata->dsb->patt_type); in set_type_show()
620 struct device_attribute *attr, in set_type_store() argument
623 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in set_type_store()
627 return -EINVAL; in set_type_store()
629 spin_lock(&drvdata->spinlock); in set_type_store()
630 drvdata->dsb->patt_type = val; in set_type_store()
631 spin_unlock(&drvdata->spinlock); in set_type_store()
637 struct device_attribute *attr, char *buf) in dsb_trig_type_show() argument
639 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in dsb_trig_type_show()
642 (unsigned int)drvdata->dsb->trig_type); in dsb_trig_type_show()
647 * false - Disable trigger type.
648 * true - Enable trigger type.
651 struct device_attribute *attr, in dsb_trig_type_store() argument
655 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in dsb_trig_type_store()
659 return -EINVAL; in dsb_trig_type_store()
661 spin_lock(&drvdata->spinlock); in dsb_trig_type_store()
663 drvdata->dsb->trig_type = true; in dsb_trig_type_store()
665 drvdata->dsb->trig_type = false; in dsb_trig_type_store()
666 spin_unlock(&drvdata->spinlock); in dsb_trig_type_store()
672 struct device_attribute *attr, in dsb_trig_ts_show() argument
675 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in dsb_trig_ts_show()
678 (unsigned int)drvdata->dsb->trig_ts); in dsb_trig_ts_show()
683 * false - Disable trigger timestamp.
684 * true - Enable trigger timestamp.
687 struct device_attribute *attr, in dsb_trig_ts_store() argument
691 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); in dsb_trig_ts_store()
695 return -EINVAL; in dsb_trig_ts_store()
697 spin_lock(&drvdata->spinlock); in dsb_trig_ts_store()
699 drvdata->dsb->trig_ts = true; in dsb_trig_ts_store()
701 drvdata->dsb->trig_ts = false; in dsb_trig_ts_store()
702 spin_unlock(&drvdata->spinlock); in dsb_trig_ts_store()
708 &dev_attr_ctrl_idx.attr,
709 &dev_attr_ctrl_val.attr,
710 &dev_attr_ctrl_mask.attr,
775 &dev_attr_enable_ts.attr,
776 &dev_attr_set_type.attr,
817 &dev_attr_dsb_mode.attr,
818 &dev_attr_dsb_trig_ts.attr,
819 &dev_attr_dsb_trig_type.attr,
865 struct device *dev = &adev->dev; in tpdm_probe()
874 adev->dev.platform_data = pdata; in tpdm_probe()
879 return -ENOMEM; in tpdm_probe()
880 drvdata->dev = &adev->dev; in tpdm_probe()
883 base = devm_ioremap_resource(dev, &adev->res); in tpdm_probe()
887 drvdata->base = base; in tpdm_probe()
894 of_property_read_u32(drvdata->dev->of_node, in tpdm_probe()
895 "qcom,dsb-msrs-num", &drvdata->dsb_msr_num); in tpdm_probe()
900 return -ENOMEM; in tpdm_probe()
904 desc.pdata = adev->dev.platform_data; in tpdm_probe()
905 desc.dev = &adev->dev; in tpdm_probe()
908 drvdata->csdev = coresight_register(&desc); in tpdm_probe()
909 if (IS_ERR(drvdata->csdev)) in tpdm_probe()
910 return PTR_ERR(drvdata->csdev); in tpdm_probe()
912 spin_lock_init(&drvdata->spinlock); in tpdm_probe()
915 pm_runtime_put(&adev->dev); in tpdm_probe()
922 struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev); in tpdm_remove()
924 coresight_unregister(drvdata->csdev); in tpdm_remove()
929 * The difference is 0-7 bits' value. So ignore 0-7 bits.
941 .name = "coresight-tpdm",