1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
6 #include <linux/amba/bus.h>
7 #include <linux/bitfield.h>
8 #include <linux/bitmap.h>
9 #include <linux/coresight.h>
10 #include <linux/coresight-pmu.h>
11 #include <linux/device.h>
12 #include <linux/err.h>
15 #include <linux/kernel.h>
16 #include <linux/module.h>
19 #include "coresight-priv.h"
20 #include "coresight-tpdm.h"
22 DEFINE_CORESIGHT_DEVLIST(tpdm_devs, "tpdm");
24 /* Read dataset array member with the index number */
25 static ssize_t tpdm_simple_dataset_show(struct device *dev,
26 struct device_attribute *attr,
29 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
30 struct tpdm_dataset_attribute *tpdm_attr =
31 container_of(attr, struct tpdm_dataset_attribute, attr);
33 switch (tpdm_attr->mem) {
35 if (tpdm_attr->idx >= TPDM_DSB_MAX_EDCR)
37 return sysfs_emit(buf, "0x%x\n",
38 drvdata->dsb->edge_ctrl[tpdm_attr->idx]);
39 case DSB_EDGE_CTRL_MASK:
40 if (tpdm_attr->idx >= TPDM_DSB_MAX_EDCMR)
42 return sysfs_emit(buf, "0x%x\n",
43 drvdata->dsb->edge_ctrl_mask[tpdm_attr->idx]);
45 if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT)
47 return sysfs_emit(buf, "0x%x\n",
48 drvdata->dsb->trig_patt[tpdm_attr->idx]);
49 case DSB_TRIG_PATT_MASK:
50 if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT)
52 return sysfs_emit(buf, "0x%x\n",
53 drvdata->dsb->trig_patt_mask[tpdm_attr->idx]);
55 if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT)
57 return sysfs_emit(buf, "0x%x\n",
58 drvdata->dsb->patt_val[tpdm_attr->idx]);
60 if (tpdm_attr->idx >= TPDM_DSB_MAX_PATT)
62 return sysfs_emit(buf, "0x%x\n",
63 drvdata->dsb->patt_mask[tpdm_attr->idx]);
65 if (tpdm_attr->idx >= drvdata->dsb_msr_num)
67 return sysfs_emit(buf, "0x%x\n",
68 drvdata->dsb->msr[tpdm_attr->idx]);
73 /* Write dataset array member with the index number */
74 static ssize_t tpdm_simple_dataset_store(struct device *dev,
75 struct device_attribute *attr,
82 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
83 struct tpdm_dataset_attribute *tpdm_attr =
84 container_of(attr, struct tpdm_dataset_attribute, attr);
86 if (kstrtoul(buf, 0, &val))
89 spin_lock(&drvdata->spinlock);
90 switch (tpdm_attr->mem) {
92 if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
93 drvdata->dsb->trig_patt[tpdm_attr->idx] = val;
97 case DSB_TRIG_PATT_MASK:
98 if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
99 drvdata->dsb->trig_patt_mask[tpdm_attr->idx] = val;
104 if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
105 drvdata->dsb->patt_val[tpdm_attr->idx] = val;
110 if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
111 drvdata->dsb->patt_mask[tpdm_attr->idx] = val;
116 if (tpdm_attr->idx < drvdata->dsb_msr_num)
117 drvdata->dsb->msr[tpdm_attr->idx] = val;
124 spin_unlock(&drvdata->spinlock);
129 static bool tpdm_has_dsb_dataset(struct tpdm_drvdata *drvdata)
131 return (drvdata->datasets & TPDM_PIDR0_DS_DSB);
134 static umode_t tpdm_dsb_is_visible(struct kobject *kobj,
135 struct attribute *attr, int n)
137 struct device *dev = kobj_to_dev(kobj);
138 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
140 if (drvdata && tpdm_has_dsb_dataset(drvdata))
146 static umode_t tpdm_dsb_msr_is_visible(struct kobject *kobj,
147 struct attribute *attr, int n)
149 struct device *dev = kobj_to_dev(kobj);
150 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
151 struct device_attribute *dev_attr =
152 container_of(attr, struct device_attribute, attr);
153 struct tpdm_dataset_attribute *tpdm_attr =
154 container_of(dev_attr, struct tpdm_dataset_attribute, attr);
156 if (tpdm_attr->idx < drvdata->dsb_msr_num)
162 static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata)
164 if (tpdm_has_dsb_dataset(drvdata)) {
165 memset(drvdata->dsb, 0, sizeof(struct dsb_dataset));
167 drvdata->dsb->trig_ts = true;
168 drvdata->dsb->trig_type = false;
172 static void set_dsb_mode(struct tpdm_drvdata *drvdata, u32 *val)
176 /* Set the test accurate mode */
177 mode = TPDM_DSB_MODE_TEST(drvdata->dsb->mode);
178 *val &= ~TPDM_DSB_CR_TEST_MODE;
179 *val |= FIELD_PREP(TPDM_DSB_CR_TEST_MODE, mode);
181 /* Set the byte lane for high-performance mode */
182 mode = TPDM_DSB_MODE_HPBYTESEL(drvdata->dsb->mode);
183 *val &= ~TPDM_DSB_CR_HPSEL;
184 *val |= FIELD_PREP(TPDM_DSB_CR_HPSEL, mode);
186 /* Set the performance mode */
187 if (drvdata->dsb->mode & TPDM_DSB_MODE_PERF)
188 *val |= TPDM_DSB_CR_MODE;
190 *val &= ~TPDM_DSB_CR_MODE;
193 static void set_dsb_tier(struct tpdm_drvdata *drvdata)
197 val = readl_relaxed(drvdata->base + TPDM_DSB_TIER);
199 /* Clear all relevant fields */
200 val &= ~(TPDM_DSB_TIER_PATT_TSENAB | TPDM_DSB_TIER_PATT_TYPE |
201 TPDM_DSB_TIER_XTRIG_TSENAB);
203 /* Set pattern timestamp type and enablement */
204 if (drvdata->dsb->patt_ts) {
205 val |= TPDM_DSB_TIER_PATT_TSENAB;
206 if (drvdata->dsb->patt_type)
207 val |= TPDM_DSB_TIER_PATT_TYPE;
209 val &= ~TPDM_DSB_TIER_PATT_TYPE;
211 val &= ~TPDM_DSB_TIER_PATT_TSENAB;
214 /* Set trigger timestamp */
215 if (drvdata->dsb->trig_ts)
216 val |= TPDM_DSB_TIER_XTRIG_TSENAB;
218 val &= ~TPDM_DSB_TIER_XTRIG_TSENAB;
220 writel_relaxed(val, drvdata->base + TPDM_DSB_TIER);
223 static void set_dsb_msr(struct tpdm_drvdata *drvdata)
227 for (i = 0; i < drvdata->dsb_msr_num; i++)
228 writel_relaxed(drvdata->dsb->msr[i],
229 drvdata->base + TPDM_DSB_MSR(i));
232 static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
236 for (i = 0; i < TPDM_DSB_MAX_EDCR; i++)
237 writel_relaxed(drvdata->dsb->edge_ctrl[i],
238 drvdata->base + TPDM_DSB_EDCR(i));
239 for (i = 0; i < TPDM_DSB_MAX_EDCMR; i++)
240 writel_relaxed(drvdata->dsb->edge_ctrl_mask[i],
241 drvdata->base + TPDM_DSB_EDCMR(i));
242 for (i = 0; i < TPDM_DSB_MAX_PATT; i++) {
243 writel_relaxed(drvdata->dsb->patt_val[i],
244 drvdata->base + TPDM_DSB_TPR(i));
245 writel_relaxed(drvdata->dsb->patt_mask[i],
246 drvdata->base + TPDM_DSB_TPMR(i));
247 writel_relaxed(drvdata->dsb->trig_patt[i],
248 drvdata->base + TPDM_DSB_XPR(i));
249 writel_relaxed(drvdata->dsb->trig_patt_mask[i],
250 drvdata->base + TPDM_DSB_XPMR(i));
253 set_dsb_tier(drvdata);
255 set_dsb_msr(drvdata);
257 val = readl_relaxed(drvdata->base + TPDM_DSB_CR);
258 /* Set the mode of DSB dataset */
259 set_dsb_mode(drvdata, &val);
260 /* Set trigger type */
261 if (drvdata->dsb->trig_type)
262 val |= TPDM_DSB_CR_TRIG_TYPE;
264 val &= ~TPDM_DSB_CR_TRIG_TYPE;
265 /* Set the enable bit of DSB control register to 1 */
266 val |= TPDM_DSB_CR_ENA;
267 writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
271 * TPDM enable operations
272 * The TPDM or Monitor serves as data collection component for various
273 * dataset types. It covers Basic Counts(BC), Tenure Counts(TC),
274 * Continuous Multi-Bit(CMB), Multi-lane CMB(MCMB) and Discrete Single
275 * Bit(DSB). This function will initialize the configuration according
276 * to the dataset type supported by the TPDM.
278 static void __tpdm_enable(struct tpdm_drvdata *drvdata)
280 CS_UNLOCK(drvdata->base);
282 if (tpdm_has_dsb_dataset(drvdata))
283 tpdm_enable_dsb(drvdata);
285 CS_LOCK(drvdata->base);
288 static int tpdm_enable(struct coresight_device *csdev, struct perf_event *event,
291 struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
293 spin_lock(&drvdata->spinlock);
294 if (drvdata->enable) {
295 spin_unlock(&drvdata->spinlock);
299 __tpdm_enable(drvdata);
300 drvdata->enable = true;
301 spin_unlock(&drvdata->spinlock);
303 dev_dbg(drvdata->dev, "TPDM tracing enabled\n");
307 static void tpdm_disable_dsb(struct tpdm_drvdata *drvdata)
311 /* Set the enable bit of DSB control register to 0 */
312 val = readl_relaxed(drvdata->base + TPDM_DSB_CR);
313 val &= ~TPDM_DSB_CR_ENA;
314 writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
317 /* TPDM disable operations */
318 static void __tpdm_disable(struct tpdm_drvdata *drvdata)
320 CS_UNLOCK(drvdata->base);
322 if (tpdm_has_dsb_dataset(drvdata))
323 tpdm_disable_dsb(drvdata);
325 CS_LOCK(drvdata->base);
328 static void tpdm_disable(struct coresight_device *csdev,
329 struct perf_event *event)
331 struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
333 spin_lock(&drvdata->spinlock);
334 if (!drvdata->enable) {
335 spin_unlock(&drvdata->spinlock);
339 __tpdm_disable(drvdata);
340 drvdata->enable = false;
341 spin_unlock(&drvdata->spinlock);
343 dev_dbg(drvdata->dev, "TPDM tracing disabled\n");
346 static const struct coresight_ops_source tpdm_source_ops = {
347 .enable = tpdm_enable,
348 .disable = tpdm_disable,
351 static const struct coresight_ops tpdm_cs_ops = {
352 .source_ops = &tpdm_source_ops,
355 static int tpdm_datasets_setup(struct tpdm_drvdata *drvdata)
359 /* Get the datasets present on the TPDM. */
360 pidr = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR0);
361 drvdata->datasets |= pidr & GENMASK(TPDM_DATASETS - 1, 0);
363 if (tpdm_has_dsb_dataset(drvdata) && (!drvdata->dsb)) {
364 drvdata->dsb = devm_kzalloc(drvdata->dev,
365 sizeof(*drvdata->dsb), GFP_KERNEL);
369 tpdm_reset_datasets(drvdata);
374 static ssize_t reset_dataset_store(struct device *dev,
375 struct device_attribute *attr,
381 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
383 ret = kstrtoul(buf, 0, &val);
387 spin_lock(&drvdata->spinlock);
388 tpdm_reset_datasets(drvdata);
389 spin_unlock(&drvdata->spinlock);
393 static DEVICE_ATTR_WO(reset_dataset);
396 * value 1: 64 bits test data
397 * value 2: 32 bits test data
399 static ssize_t integration_test_store(struct device *dev,
400 struct device_attribute *attr,
406 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
408 ret = kstrtoul(buf, 10, &val);
412 if (val != 1 && val != 2)
415 if (!drvdata->enable)
419 val = ATBCNTRL_VAL_64;
421 val = ATBCNTRL_VAL_32;
422 CS_UNLOCK(drvdata->base);
423 writel_relaxed(0x1, drvdata->base + TPDM_ITCNTRL);
425 for (i = 0; i < INTEGRATION_TEST_CYCLE; i++)
426 writel_relaxed(val, drvdata->base + TPDM_ITATBCNTRL);
428 writel_relaxed(0, drvdata->base + TPDM_ITCNTRL);
429 CS_LOCK(drvdata->base);
432 static DEVICE_ATTR_WO(integration_test);
434 static struct attribute *tpdm_attrs[] = {
435 &dev_attr_reset_dataset.attr,
436 &dev_attr_integration_test.attr,
440 static struct attribute_group tpdm_attr_grp = {
444 static ssize_t dsb_mode_show(struct device *dev,
445 struct device_attribute *attr,
448 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
450 return sysfs_emit(buf, "%x\n", drvdata->dsb->mode);
453 static ssize_t dsb_mode_store(struct device *dev,
454 struct device_attribute *attr,
458 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
461 if ((kstrtoul(buf, 0, &val)) || (val < 0) ||
462 (val & ~TPDM_DSB_MODE_MASK))
465 spin_lock(&drvdata->spinlock);
466 drvdata->dsb->mode = val & TPDM_DSB_MODE_MASK;
467 spin_unlock(&drvdata->spinlock);
470 static DEVICE_ATTR_RW(dsb_mode);
472 static ssize_t ctrl_idx_show(struct device *dev,
473 struct device_attribute *attr,
476 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
478 return sysfs_emit(buf, "%u\n",
479 (unsigned int)drvdata->dsb->edge_ctrl_idx);
483 * The EDCR registers can include up to 16 32-bit registers, and each
484 * one can be configured to control up to 16 edge detections(2 bits
485 * control one edge detection). So a total 256 edge detections can be
486 * configured. This function provides a way to set the index number of
487 * the edge detection which needs to be configured.
489 static ssize_t ctrl_idx_store(struct device *dev,
490 struct device_attribute *attr,
494 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
497 if ((kstrtoul(buf, 0, &val)) || (val >= TPDM_DSB_MAX_LINES))
500 spin_lock(&drvdata->spinlock);
501 drvdata->dsb->edge_ctrl_idx = val;
502 spin_unlock(&drvdata->spinlock);
506 static DEVICE_ATTR_RW(ctrl_idx);
509 * This function is used to control the edge detection according
510 * to the index number that has been set.
511 * "edge_ctrl" should be one of the following values.
512 * 0 - Rising edge detection
513 * 1 - Falling edge detection
514 * 2 - Rising and falling edge detection (toggle detection)
516 static ssize_t ctrl_val_store(struct device *dev,
517 struct device_attribute *attr,
521 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
522 unsigned long val, edge_ctrl;
525 if ((kstrtoul(buf, 0, &edge_ctrl)) || (edge_ctrl > 0x2))
528 spin_lock(&drvdata->spinlock);
530 * There are 2 bit per DSB Edge Control line.
531 * Thus we have 16 lines in a 32bit word.
533 reg = EDCR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx);
534 val = drvdata->dsb->edge_ctrl[reg];
535 val &= ~EDCR_TO_WORD_MASK(drvdata->dsb->edge_ctrl_idx);
536 val |= EDCR_TO_WORD_VAL(edge_ctrl, drvdata->dsb->edge_ctrl_idx);
537 drvdata->dsb->edge_ctrl[reg] = val;
538 spin_unlock(&drvdata->spinlock);
542 static DEVICE_ATTR_WO(ctrl_val);
544 static ssize_t ctrl_mask_store(struct device *dev,
545 struct device_attribute *attr,
549 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
554 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
557 spin_lock(&drvdata->spinlock);
559 * There is 1 bit per DSB Edge Control Mark line.
560 * Thus we have 32 lines in a 32bit word.
562 reg = EDCMR_TO_WORD_IDX(drvdata->dsb->edge_ctrl_idx);
563 set = drvdata->dsb->edge_ctrl_mask[reg];
565 set |= BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx));
567 set &= ~BIT(EDCMR_TO_WORD_SHIFT(drvdata->dsb->edge_ctrl_idx));
568 drvdata->dsb->edge_ctrl_mask[reg] = set;
569 spin_unlock(&drvdata->spinlock);
573 static DEVICE_ATTR_WO(ctrl_mask);
575 static ssize_t enable_ts_show(struct device *dev,
576 struct device_attribute *attr,
579 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
581 return sysfs_emit(buf, "%u\n",
582 (unsigned int)drvdata->dsb->patt_ts);
586 * value 1: Enable/Disable DSB pattern timestamp
588 static ssize_t enable_ts_store(struct device *dev,
589 struct device_attribute *attr,
593 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
596 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
599 spin_lock(&drvdata->spinlock);
600 drvdata->dsb->patt_ts = !!val;
601 spin_unlock(&drvdata->spinlock);
604 static DEVICE_ATTR_RW(enable_ts);
606 static ssize_t set_type_show(struct device *dev,
607 struct device_attribute *attr,
610 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
612 return sysfs_emit(buf, "%u\n",
613 (unsigned int)drvdata->dsb->patt_type);
617 * value 1: Set DSB pattern type
619 static ssize_t set_type_store(struct device *dev,
620 struct device_attribute *attr,
621 const char *buf, size_t size)
623 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
626 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
629 spin_lock(&drvdata->spinlock);
630 drvdata->dsb->patt_type = val;
631 spin_unlock(&drvdata->spinlock);
634 static DEVICE_ATTR_RW(set_type);
636 static ssize_t dsb_trig_type_show(struct device *dev,
637 struct device_attribute *attr, char *buf)
639 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
641 return sysfs_emit(buf, "%u\n",
642 (unsigned int)drvdata->dsb->trig_type);
646 * Trigger type (boolean):
647 * false - Disable trigger type.
648 * true - Enable trigger type.
650 static ssize_t dsb_trig_type_store(struct device *dev,
651 struct device_attribute *attr,
655 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
658 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
661 spin_lock(&drvdata->spinlock);
663 drvdata->dsb->trig_type = true;
665 drvdata->dsb->trig_type = false;
666 spin_unlock(&drvdata->spinlock);
669 static DEVICE_ATTR_RW(dsb_trig_type);
671 static ssize_t dsb_trig_ts_show(struct device *dev,
672 struct device_attribute *attr,
675 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
677 return sysfs_emit(buf, "%u\n",
678 (unsigned int)drvdata->dsb->trig_ts);
682 * Trigger timestamp (boolean):
683 * false - Disable trigger timestamp.
684 * true - Enable trigger timestamp.
686 static ssize_t dsb_trig_ts_store(struct device *dev,
687 struct device_attribute *attr,
691 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
694 if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
697 spin_lock(&drvdata->spinlock);
699 drvdata->dsb->trig_ts = true;
701 drvdata->dsb->trig_ts = false;
702 spin_unlock(&drvdata->spinlock);
705 static DEVICE_ATTR_RW(dsb_trig_ts);
707 static struct attribute *tpdm_dsb_edge_attrs[] = {
708 &dev_attr_ctrl_idx.attr,
709 &dev_attr_ctrl_val.attr,
710 &dev_attr_ctrl_mask.attr,
711 DSB_EDGE_CTRL_ATTR(0),
712 DSB_EDGE_CTRL_ATTR(1),
713 DSB_EDGE_CTRL_ATTR(2),
714 DSB_EDGE_CTRL_ATTR(3),
715 DSB_EDGE_CTRL_ATTR(4),
716 DSB_EDGE_CTRL_ATTR(5),
717 DSB_EDGE_CTRL_ATTR(6),
718 DSB_EDGE_CTRL_ATTR(7),
719 DSB_EDGE_CTRL_ATTR(8),
720 DSB_EDGE_CTRL_ATTR(9),
721 DSB_EDGE_CTRL_ATTR(10),
722 DSB_EDGE_CTRL_ATTR(11),
723 DSB_EDGE_CTRL_ATTR(12),
724 DSB_EDGE_CTRL_ATTR(13),
725 DSB_EDGE_CTRL_ATTR(14),
726 DSB_EDGE_CTRL_ATTR(15),
727 DSB_EDGE_CTRL_MASK_ATTR(0),
728 DSB_EDGE_CTRL_MASK_ATTR(1),
729 DSB_EDGE_CTRL_MASK_ATTR(2),
730 DSB_EDGE_CTRL_MASK_ATTR(3),
731 DSB_EDGE_CTRL_MASK_ATTR(4),
732 DSB_EDGE_CTRL_MASK_ATTR(5),
733 DSB_EDGE_CTRL_MASK_ATTR(6),
734 DSB_EDGE_CTRL_MASK_ATTR(7),
738 static struct attribute *tpdm_dsb_trig_patt_attrs[] = {
739 DSB_TRIG_PATT_ATTR(0),
740 DSB_TRIG_PATT_ATTR(1),
741 DSB_TRIG_PATT_ATTR(2),
742 DSB_TRIG_PATT_ATTR(3),
743 DSB_TRIG_PATT_ATTR(4),
744 DSB_TRIG_PATT_ATTR(5),
745 DSB_TRIG_PATT_ATTR(6),
746 DSB_TRIG_PATT_ATTR(7),
747 DSB_TRIG_PATT_MASK_ATTR(0),
748 DSB_TRIG_PATT_MASK_ATTR(1),
749 DSB_TRIG_PATT_MASK_ATTR(2),
750 DSB_TRIG_PATT_MASK_ATTR(3),
751 DSB_TRIG_PATT_MASK_ATTR(4),
752 DSB_TRIG_PATT_MASK_ATTR(5),
753 DSB_TRIG_PATT_MASK_ATTR(6),
754 DSB_TRIG_PATT_MASK_ATTR(7),
758 static struct attribute *tpdm_dsb_patt_attrs[] = {
767 DSB_PATT_MASK_ATTR(0),
768 DSB_PATT_MASK_ATTR(1),
769 DSB_PATT_MASK_ATTR(2),
770 DSB_PATT_MASK_ATTR(3),
771 DSB_PATT_MASK_ATTR(4),
772 DSB_PATT_MASK_ATTR(5),
773 DSB_PATT_MASK_ATTR(6),
774 DSB_PATT_MASK_ATTR(7),
775 &dev_attr_enable_ts.attr,
776 &dev_attr_set_type.attr,
780 static struct attribute *tpdm_dsb_msr_attrs[] = {
816 static struct attribute *tpdm_dsb_attrs[] = {
817 &dev_attr_dsb_mode.attr,
818 &dev_attr_dsb_trig_ts.attr,
819 &dev_attr_dsb_trig_type.attr,
823 static struct attribute_group tpdm_dsb_attr_grp = {
824 .attrs = tpdm_dsb_attrs,
825 .is_visible = tpdm_dsb_is_visible,
828 static struct attribute_group tpdm_dsb_edge_grp = {
829 .attrs = tpdm_dsb_edge_attrs,
830 .is_visible = tpdm_dsb_is_visible,
834 static struct attribute_group tpdm_dsb_trig_patt_grp = {
835 .attrs = tpdm_dsb_trig_patt_attrs,
836 .is_visible = tpdm_dsb_is_visible,
837 .name = "dsb_trig_patt",
840 static struct attribute_group tpdm_dsb_patt_grp = {
841 .attrs = tpdm_dsb_patt_attrs,
842 .is_visible = tpdm_dsb_is_visible,
846 static struct attribute_group tpdm_dsb_msr_grp = {
847 .attrs = tpdm_dsb_msr_attrs,
848 .is_visible = tpdm_dsb_msr_is_visible,
852 static const struct attribute_group *tpdm_attr_grps[] = {
856 &tpdm_dsb_trig_patt_grp,
862 static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
865 struct device *dev = &adev->dev;
866 struct coresight_platform_data *pdata;
867 struct tpdm_drvdata *drvdata;
868 struct coresight_desc desc = { 0 };
871 pdata = coresight_get_platform_data(dev);
873 return PTR_ERR(pdata);
874 adev->dev.platform_data = pdata;
877 drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
880 drvdata->dev = &adev->dev;
881 dev_set_drvdata(dev, drvdata);
883 base = devm_ioremap_resource(dev, &adev->res);
885 return PTR_ERR(base);
887 drvdata->base = base;
889 ret = tpdm_datasets_setup(drvdata);
893 if (drvdata && tpdm_has_dsb_dataset(drvdata))
894 of_property_read_u32(drvdata->dev->of_node,
895 "qcom,dsb-msrs-num", &drvdata->dsb_msr_num);
897 /* Set up coresight component description */
898 desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
901 desc.type = CORESIGHT_DEV_TYPE_SOURCE;
902 desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM;
903 desc.ops = &tpdm_cs_ops;
904 desc.pdata = adev->dev.platform_data;
905 desc.dev = &adev->dev;
906 desc.access = CSDEV_ACCESS_IOMEM(base);
907 desc.groups = tpdm_attr_grps;
908 drvdata->csdev = coresight_register(&desc);
909 if (IS_ERR(drvdata->csdev))
910 return PTR_ERR(drvdata->csdev);
912 spin_lock_init(&drvdata->spinlock);
914 /* Decrease pm refcount when probe is done.*/
915 pm_runtime_put(&adev->dev);
920 static void tpdm_remove(struct amba_device *adev)
922 struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
924 coresight_unregister(drvdata->csdev);
928 * Different TPDM has different periph id.
929 * The difference is 0-7 bits' value. So ignore 0-7 bits.
931 static struct amba_id tpdm_ids[] = {
939 static struct amba_driver tpdm_driver = {
941 .name = "coresight-tpdm",
942 .owner = THIS_MODULE,
943 .suppress_bind_attrs = true,
946 .id_table = tpdm_ids,
947 .remove = tpdm_remove,
950 module_amba_driver(tpdm_driver);
952 MODULE_LICENSE("GPL");
953 MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");