]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
coresight: tpda: add sysfs nodes for tpda cross-trigger configuration
authorTao Zhang <tao.zhang@oss.qualcomm.com>
Tue, 23 Dec 2025 10:09:50 +0000 (18:09 +0800)
committerSuzuki K Poulose <suzuki.poulose@arm.com>
Mon, 5 Jan 2026 16:51:50 +0000 (16:51 +0000)
Introduce sysfs nodes to configure cross-trigger parameters for TPDA.
These registers define the characteristics of cross-trigger packets,
including generation frequency and flag values.

Signed-off-by: Tao Zhang <tao.zhang@oss.qualcomm.com>
Reviewed-by: James Clark <james.clark@linaro.org>
Co-developed-by: Jie Gan <jie.gan@oss.qualcomm.com>
Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
[ Fix kernel version in the Documentation ]
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Link: https://lore.kernel.org/r/20251223-add_sysfs_nodes_to_configure_tpda-v8-1-4c95db608b62@oss.qualcomm.com
Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda [new file with mode: 0644]
drivers/hwtracing/coresight/coresight-tpda.c
drivers/hwtracing/coresight/coresight-tpda.h

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
new file mode 100644 (file)
index 0000000..8519a08
--- /dev/null
@@ -0,0 +1,35 @@
+What:          /sys/bus/coresight/devices/<tpda-name>/trig_async_enable
+Date:          December 2025
+KernelVersion: 6.20
+Contact:       Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
+Description:
+               (RW) Enable/disable cross trigger synchronization sequence interface.
+
+What:          /sys/bus/coresight/devices/<tpda-name>/trig_flag_ts_enable
+Date:          December 2025
+KernelVersion: 6.20
+Contact:       Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
+Description:
+               (RW) Enable/disable cross trigger FLAG packet request interface.
+
+What:          /sys/bus/coresight/devices/<tpda-name>/trig_freq_enable
+Date:          December 2025
+KernelVersion: 6.20
+Contact:       Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
+Description:
+               (RW) Enable/disable cross trigger FREQ packet request interface.
+
+What:          /sys/bus/coresight/devices/<tpda-name>/freq_ts_enable
+Date:          December 2025
+KernelVersion: 6.20
+Contact:       Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
+Description:
+               (RW) Enable/disable the timestamp for all FREQ packets.
+
+What:          /sys/bus/coresight/devices/<tpda-name>/cmbchan_mode
+Date:          December 2025
+KernelVersion: 6.20
+Contact:       Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
+Description:
+               (RW) Configure the CMB/MCMB channel mode for all enabled ports.
+               Value 0 means raw channel mapping mode. Value 1 means channel pair marking mode.
index 3a3825d27f861585ca1d847929747f8096004089..2186223ad33ee19b8355a1b3790db0fd06da4ede 100644 (file)
@@ -137,12 +137,32 @@ static int tpda_get_element_size(struct tpda_drvdata *drvdata,
 /* Settings pre enabling port control register */
 static void tpda_enable_pre_port(struct tpda_drvdata *drvdata)
 {
-       u32 val;
+       u32 val = 0;
 
-       val = readl_relaxed(drvdata->base + TPDA_CR);
-       val &= ~TPDA_CR_ATID;
        val |= FIELD_PREP(TPDA_CR_ATID, drvdata->atid);
+       if (drvdata->trig_async)
+               val |= TPDA_CR_SRIE;
+
+       if (drvdata->trig_flag_ts)
+               val |= TPDA_CR_FLRIE;
+
+       if (drvdata->trig_freq)
+               val |= TPDA_CR_FRIE;
+
+       if (drvdata->freq_ts)
+               val |= TPDA_CR_FREQTS;
+
+       if (drvdata->cmbchan_mode)
+               val |= TPDA_CR_CMBCHANMODE;
+
        writel_relaxed(val, drvdata->base + TPDA_CR);
+
+       /*
+        * If FLRIE bit is set, set the master and channel
+        * id as zero
+        */
+       if (drvdata->trig_flag_ts)
+               writel_relaxed(0x0, drvdata->base + TPDA_FPID_CR);
 }
 
 static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
@@ -258,6 +278,87 @@ static const struct coresight_ops tpda_cs_ops = {
        .link_ops       = &tpda_link_ops,
 };
 
+/* Read cross-trigger register member */
+static ssize_t tpda_trig_sysfs_show(struct device *dev,
+                                   struct device_attribute *attr,
+                                   char *buf)
+{
+       struct tpda_trig_sysfs_attribute *tpda_attr =
+               container_of(attr, struct tpda_trig_sysfs_attribute, attr);
+       struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+       guard(spinlock)(&drvdata->spinlock);
+       switch (tpda_attr->mem) {
+       case FREQTS:
+               return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->freq_ts);
+       case FRIE:
+               return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_freq);
+       case FLRIE:
+               return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_flag_ts);
+       case SRIE:
+               return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_async);
+       case CMBCHANMODE:
+               return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->cmbchan_mode);
+
+       }
+       return -EINVAL;
+}
+
+static ssize_t tpda_trig_sysfs_store(struct device *dev,
+                                    struct device_attribute *attr,
+                                    const char *buf,
+                                    size_t size)
+{
+       struct tpda_trig_sysfs_attribute *tpda_attr =
+               container_of(attr, struct tpda_trig_sysfs_attribute, attr);
+       struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
+       unsigned long val;
+
+       if (kstrtoul(buf, 0, &val))
+               return -EINVAL;
+
+       guard(spinlock)(&drvdata->spinlock);
+       switch (tpda_attr->mem) {
+       case FREQTS:
+               drvdata->freq_ts = !!val;
+               break;
+       case FRIE:
+               drvdata->trig_freq = !!val;
+               break;
+       case FLRIE:
+               drvdata->trig_flag_ts = !!val;
+               break;
+       case SRIE:
+               drvdata->trig_async = !!val;
+               break;
+       case CMBCHANMODE:
+               drvdata->cmbchan_mode = !!val;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return size;
+}
+
+static struct attribute *tpda_attrs[] = {
+       tpda_trig_sysfs_rw(freq_ts_enable, FREQTS),
+       tpda_trig_sysfs_rw(trig_freq_enable, FRIE),
+       tpda_trig_sysfs_rw(trig_flag_ts_enable, FLRIE),
+       tpda_trig_sysfs_rw(trig_async_enable, SRIE),
+       tpda_trig_sysfs_rw(cmbchan_mode, CMBCHANMODE),
+       NULL,
+};
+
+static struct attribute_group tpda_attr_grp = {
+       .attrs  = tpda_attrs,
+};
+
+static const struct attribute_group *tpda_attr_grps[] = {
+       &tpda_attr_grp,
+       NULL,
+};
+
 static int tpda_init_default_data(struct tpda_drvdata *drvdata)
 {
        int atid;
@@ -273,6 +374,7 @@ static int tpda_init_default_data(struct tpda_drvdata *drvdata)
                return atid;
 
        drvdata->atid = atid;
+       drvdata->freq_ts = true;
        return 0;
 }
 
@@ -316,6 +418,7 @@ static int tpda_probe(struct amba_device *adev, const struct amba_id *id)
        desc.ops = &tpda_cs_ops;
        desc.pdata = adev->dev.platform_data;
        desc.dev = &adev->dev;
+       desc.groups = tpda_attr_grps;
        desc.access = CSDEV_ACCESS_IOMEM(base);
        drvdata->csdev = coresight_register(&desc);
        if (IS_ERR(drvdata->csdev))
index c6af3d2da3efeaeef64ba9023f1c280583b542e6..c93732e04af2c2ff6d47f41ccdaee5f87d89dc9a 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2023,2025 Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #ifndef _CORESIGHT_CORESIGHT_TPDA_H
@@ -8,6 +8,25 @@
 
 #define TPDA_CR                        (0x000)
 #define TPDA_Pn_CR(n)          (0x004 + (n * 4))
+#define TPDA_FPID_CR           (0x084)
+
+/* Cross trigger FREQ packets timestamp bit */
+#define TPDA_CR_FREQTS         BIT(2)
+/* Cross trigger FREQ packet request bit */
+#define TPDA_CR_FRIE           BIT(3)
+/* Cross trigger FLAG packet request interface bit */
+#define TPDA_CR_FLRIE          BIT(4)
+/* Cross trigger synchronization bit */
+#define TPDA_CR_SRIE           BIT(5)
+/* Bits 6 ~ 12 is for atid value */
+#define TPDA_CR_ATID           GENMASK(12, 6)
+/*
+ * Channel mode bit of the packetization of CMB/MCB traffic
+ * 0 - raw channel mapping mode
+ * 1 - channel pair marking mode
+ */
+#define TPDA_CR_CMBCHANMODE    BIT(20)
+
 /* Aggregator port enable bit */
 #define TPDA_Pn_CR_ENA         BIT(0)
 /* Aggregator port CMB data set element size bit */
@@ -17,9 +36,6 @@
 
 #define TPDA_MAX_INPORTS       32
 
-/* Bits 6 ~ 12 is for atid value */
-#define TPDA_CR_ATID           GENMASK(12, 6)
-
 /**
  * struct tpda_drvdata - specifics associated to an TPDA component
  * @base:       memory mapped base address for this component.
  * @enable:     enable status of the component.
  * @dsb_esize   Record the DSB element size.
  * @cmb_esize   Record the CMB element size.
+ * @trig_async:        Enable/disable cross trigger synchronization sequence interface.
+ * @trig_flag_ts: Enable/disable cross trigger FLAG packet request interface.
+ * @trig_freq: Enable/disable cross trigger FREQ packet request interface.
+ * @freq_ts:   Enable/disable the timestamp for all FREQ packets.
+ * @cmbchan_mode: Configure the CMB/MCMB channel mode.
  */
 struct tpda_drvdata {
        void __iomem            *base;
@@ -38,6 +59,40 @@ struct tpda_drvdata {
        u8                      atid;
        u32                     dsb_esize;
        u32                     cmb_esize;
+       bool                    trig_async;
+       bool                    trig_flag_ts;
+       bool                    trig_freq;
+       bool                    freq_ts;
+       bool                    cmbchan_mode;
+};
+
+/* Enumerate members of global control register(cr) */
+enum tpda_cr_mem {
+       FREQTS,
+       FRIE,
+       FLRIE,
+       SRIE,
+       CMBCHANMODE
+};
+
+/**
+ * struct tpda_trig_sysfs_attribute - Record the member variables of cross
+ * trigger register that need to be operated by sysfs file
+ * @attr:      The device attribute
+ * @mem:       The member in the control register data structure
+ */
+struct tpda_trig_sysfs_attribute {
+       struct device_attribute attr;
+       enum tpda_cr_mem mem;
 };
 
+#define tpda_trig_sysfs_rw(name, mem)                          \
+       (&((struct tpda_trig_sysfs_attribute[]) {               \
+          {                                                    \
+               __ATTR(name, 0644, tpda_trig_sysfs_show,        \
+               tpda_trig_sysfs_store),                         \
+               mem,                                            \
+          }                                                    \
+          })[0].attr.attr)
+
 #endif  /* _CORESIGHT_CORESIGHT_TPDA_H */