* [PATCH v2 0/3] add sysfs nodes to configure TPDA's registers
@ 2025-08-27 4:20 Jie Gan
2025-08-27 4:20 ` [PATCH v2 1/3] coresight: tpda: add sysfs nodes for tpda cross-trigger configuration Jie Gan
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Jie Gan @ 2025-08-27 4:20 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Tingwei Zhang
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm
Patchset 1 introduces configuration of the cross-trigger registers with
appropriate values to enable proper generation of cross-trigger packets.
Patchset 2 introduces a logic to configure the TPDA_SYNCR register,
which determines the frequency of ASYNC packet generation. These packets
assist userspace tools in accurately identifying each valid packet.
Patchset 3 introduces a sysfs node to initiate a flush request for the
specific port, forcing the data to synchronize and be transmitted to the
sink device.
Changes in V2:
1. Refactoring the code based on James's comment for optimization.
Link to V1 - https://lore.kernel.org/all/20250826070150.5603-1-jie.gan@oss.qualcomm.com/
Tao Zhang (3):
coresight: tpda: add sysfs nodes for tpda cross-trigger configuration
coresight: tpda: add logic to configure TPDA_SYNCR register
coresight: tpda: add sysfs node to flush specific port
.../testing/sysfs-bus-coresight-devices-tpda | 50 ++++
drivers/hwtracing/coresight/coresight-tpda.c | 276 ++++++++++++++++++
drivers/hwtracing/coresight/coresight-tpda.h | 35 ++-
3 files changed, 360 insertions(+), 1 deletion(-)
create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
--
2.34.1
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 1/3] coresight: tpda: add sysfs nodes for tpda cross-trigger configuration
2025-08-27 4:20 [PATCH v2 0/3] add sysfs nodes to configure TPDA's registers Jie Gan
@ 2025-08-27 4:20 ` Jie Gan
2025-08-27 9:06 ` James Clark
2025-08-27 4:20 ` [PATCH v2 2/3] coresight: tpda: add logic to configure TPDA_SYNCR register Jie Gan
2025-08-27 4:20 ` [PATCH v2 3/3] coresight: tpda: add sysfs node to flush specific port Jie Gan
2 siblings, 1 reply; 12+ messages in thread
From: Jie Gan @ 2025-08-27 4:20 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Tingwei Zhang
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm
From: Tao Zhang <tao.zhang@oss.qualcomm.com>
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>
Co-developed-by: Jie Gan <jie.gan@oss.qualcomm.com>
Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
---
.../testing/sysfs-bus-coresight-devices-tpda | 43 ++++
drivers/hwtracing/coresight/coresight-tpda.c | 227 ++++++++++++++++++
drivers/hwtracing/coresight/coresight-tpda.h | 27 ++-
3 files changed, 296 insertions(+), 1 deletion(-)
create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
new file mode 100644
index 000000000000..fb651aebeb31
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
@@ -0,0 +1,43 @@
+What: /sys/bus/coresight/devices/<tpda-name>/trig_async_enable
+Date: August 2025
+KernelVersion: 6.17
+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: August 2025
+KernelVersion: 6.17
+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: August 2025
+KernelVersion: 6.17
+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: August 2025
+KernelVersion: 6.17
+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>/global_flush_req
+Date: August 2025
+KernelVersion: 6.17
+Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
+Description:
+ (RW) Set global (all ports) flush request bit. The bit remains set until a
+ global flush request sequence completes.
+
+What: /sys/bus/coresight/devices/<tpda-name>/cmbchan_mode
+Date: August 2025
+KernelVersion: 6.17
+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.
diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
index 4e93fa5bace4..647ab49a98d7 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.c
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -156,9 +156,37 @@ static void tpda_enable_pre_port(struct tpda_drvdata *drvdata)
u32 val;
val = readl_relaxed(drvdata->base + TPDA_CR);
+ val &= ~TPDA_CR_MID;
val &= ~TPDA_CR_ATID;
val |= FIELD_PREP(TPDA_CR_ATID, drvdata->atid);
+ if (drvdata->trig_async)
+ val |= TPDA_CR_SRIE;
+ else
+ val &= ~TPDA_CR_SRIE;
+ if (drvdata->trig_flag_ts)
+ val |= TPDA_CR_FLRIE;
+ else
+ val &= ~TPDA_CR_FLRIE;
+ if (drvdata->trig_freq)
+ val |= TPDA_CR_FRIE;
+ else
+ val &= ~TPDA_CR_FRIE;
+ if (drvdata->freq_ts)
+ val |= TPDA_CR_FREQTS;
+ else
+ val &= ~TPDA_CR_FREQTS;
+ if (drvdata->cmbchan_mode)
+ val |= TPDA_CR_CMBCHANMODE;
+ else
+ 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)
@@ -274,6 +302,203 @@ static const struct coresight_ops tpda_cs_ops = {
.link_ops = &tpda_link_ops,
};
+static ssize_t trig_async_enable_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_async);
+}
+
+static ssize_t trig_async_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ unsigned long val;
+
+ if (kstrtoul(buf, 0, &val))
+ return -EINVAL;
+
+ guard(spinlock)(&drvdata->spinlock);
+ drvdata->trig_async = !!val;
+
+ return size;
+}
+static DEVICE_ATTR_RW(trig_async_enable);
+
+static ssize_t trig_flag_ts_enable_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_flag_ts);
+}
+
+static ssize_t trig_flag_ts_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ unsigned long val;
+
+ if (kstrtoul(buf, 0, &val))
+ return -EINVAL;
+
+ guard(spinlock)(&drvdata->spinlock);
+ drvdata->trig_flag_ts = !!val;
+
+ return size;
+}
+static DEVICE_ATTR_RW(trig_flag_ts_enable);
+
+static ssize_t trig_freq_enable_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_freq);
+}
+
+static ssize_t trig_freq_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ unsigned long val;
+
+ if (kstrtoul(buf, 0, &val))
+ return -EINVAL;
+
+ guard(spinlock)(&drvdata->spinlock);
+ drvdata->trig_freq = !!val;
+
+ return size;
+}
+static DEVICE_ATTR_RW(trig_freq_enable);
+
+static ssize_t freq_ts_enable_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->freq_ts);
+}
+
+static ssize_t freq_ts_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ unsigned long val;
+
+ if (kstrtoul(buf, 0, &val))
+ return -EINVAL;
+
+ guard(spinlock)(&drvdata->spinlock);
+ drvdata->freq_ts = !!val;
+
+ return size;
+}
+static DEVICE_ATTR_RW(freq_ts_enable);
+
+static ssize_t global_flush_req_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ unsigned long val;
+
+ if (!drvdata->csdev->refcnt)
+ return -EINVAL;
+
+ guard(spinlock)(&drvdata->spinlock);
+ CS_UNLOCK(drvdata->base);
+ val = readl_relaxed(drvdata->base + TPDA_CR);
+ CS_LOCK(drvdata->base);
+
+ return sysfs_emit(buf, "%lx\n", val);
+}
+
+static ssize_t global_flush_req_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ unsigned long val;
+
+ if (kstrtoul(buf, 0, &val))
+ return -EINVAL;
+
+ if (!drvdata->csdev->refcnt || !val)
+ return -EINVAL;
+
+ guard(spinlock)(&drvdata->spinlock);
+ CS_UNLOCK(drvdata->base);
+ val = readl_relaxed(drvdata->base + TPDA_CR);
+ val |= BIT(0);
+ writel_relaxed(val, drvdata->base + TPDA_CR);
+ CS_LOCK(drvdata->base);
+
+ return size;
+}
+static DEVICE_ATTR_RW(global_flush_req);
+
+static ssize_t cmbchan_mode_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->cmbchan_mode);
+}
+
+static ssize_t cmbchan_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ unsigned long val;
+
+ if (kstrtoul(buf, 0, &val))
+ return -EINVAL;
+
+ guard(spinlock)(&drvdata->spinlock);
+ drvdata->cmbchan_mode = !!val;
+
+ return size;
+}
+static DEVICE_ATTR_RW(cmbchan_mode);
+
+static struct attribute *tpda_attrs[] = {
+ &dev_attr_trig_async_enable.attr,
+ &dev_attr_trig_flag_ts_enable.attr,
+ &dev_attr_trig_freq_enable.attr,
+ &dev_attr_freq_ts_enable.attr,
+ &dev_attr_global_flush_req.attr,
+ &dev_attr_cmbchan_mode.attr,
+ 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;
@@ -289,6 +514,7 @@ static int tpda_init_default_data(struct tpda_drvdata *drvdata)
return atid;
drvdata->atid = atid;
+ drvdata->freq_ts = true;
return 0;
}
@@ -332,6 +558,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))
diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h
index c6af3d2da3ef..0be625fb52fd 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.h
+++ b/drivers/hwtracing/coresight/coresight-tpda.h
@@ -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,19 @@
#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)
+/* Packetize CMB/MCMB traffic bit */
+#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 */
@@ -19,6 +32,8 @@
/* Bits 6 ~ 12 is for atid value */
#define TPDA_CR_ATID GENMASK(12, 6)
+/* Bits 13 ~ 19 is for mid value */
+#define TPDA_CR_MID GENMASK(19, 13)
/**
* struct tpda_drvdata - specifics associated to an TPDA component
@@ -29,6 +44,11 @@
* @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 +58,11 @@ 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;
};
#endif /* _CORESIGHT_CORESIGHT_TPDA_H */
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 2/3] coresight: tpda: add logic to configure TPDA_SYNCR register
2025-08-27 4:20 [PATCH v2 0/3] add sysfs nodes to configure TPDA's registers Jie Gan
2025-08-27 4:20 ` [PATCH v2 1/3] coresight: tpda: add sysfs nodes for tpda cross-trigger configuration Jie Gan
@ 2025-08-27 4:20 ` Jie Gan
2025-08-27 9:21 ` James Clark
2025-08-27 4:20 ` [PATCH v2 3/3] coresight: tpda: add sysfs node to flush specific port Jie Gan
2 siblings, 1 reply; 12+ messages in thread
From: Jie Gan @ 2025-08-27 4:20 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Tingwei Zhang
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm
From: Tao Zhang <tao.zhang@oss.qualcomm.com>
The TPDA_SYNCR register defines the frequency at which TPDA generates
ASYNC packets, enabling userspace tools to accurately parse each valid
packet.
Signed-off-by: Tao Zhang <tao.zhang@oss.qualcomm.com>
Co-developed-by: Jie Gan <jie.gan@oss.qualcomm.com>
Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
---
drivers/hwtracing/coresight/coresight-tpda.c | 7 +++++++
drivers/hwtracing/coresight/coresight-tpda.h | 6 ++++++
2 files changed, 13 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
index 647ab49a98d7..430f76c559f2 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.c
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -187,6 +187,13 @@ static void tpda_enable_pre_port(struct tpda_drvdata *drvdata)
*/
if (drvdata->trig_flag_ts)
writel_relaxed(0x0, drvdata->base + TPDA_FPID_CR);
+
+ /* Program the counter value for TPDA_SYNCR */
+ val = readl_relaxed(drvdata->base + TPDA_SYNCR);
+ /* Clear the mode */
+ val &= ~TPDA_SYNCR_MODE_CTRL;
+ val |= FIELD_PREP(TPDA_SYNCR_COUNTER_MASK, TPDA_SYNCR_MAX_COUNTER_VAL);
+ writel_relaxed(val, drvdata->base + TPDA_SYNCR);
}
static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h
index 0be625fb52fd..8e1b66115ad1 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.h
+++ b/drivers/hwtracing/coresight/coresight-tpda.h
@@ -9,6 +9,7 @@
#define TPDA_CR (0x000)
#define TPDA_Pn_CR(n) (0x004 + (n * 4))
#define TPDA_FPID_CR (0x084)
+#define TPDA_SYNCR (0x08C)
/* Cross trigger FREQ packets timestamp bit */
#define TPDA_CR_FREQTS BIT(2)
@@ -27,6 +28,11 @@
#define TPDA_Pn_CR_CMBSIZE GENMASK(7, 6)
/* Aggregator port DSB data set element size bit */
#define TPDA_Pn_CR_DSBSIZE BIT(8)
+/* TPDA_SYNCR mode control bit */
+#define TPDA_SYNCR_MODE_CTRL BIT(12)
+/* TPDA_SYNCR counter mask */
+#define TPDA_SYNCR_COUNTER_MASK GENMASK(11, 0)
+#define TPDA_SYNCR_MAX_COUNTER_VAL (0xFFF)
#define TPDA_MAX_INPORTS 32
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v2 3/3] coresight: tpda: add sysfs node to flush specific port
2025-08-27 4:20 [PATCH v2 0/3] add sysfs nodes to configure TPDA's registers Jie Gan
2025-08-27 4:20 ` [PATCH v2 1/3] coresight: tpda: add sysfs nodes for tpda cross-trigger configuration Jie Gan
2025-08-27 4:20 ` [PATCH v2 2/3] coresight: tpda: add logic to configure TPDA_SYNCR register Jie Gan
@ 2025-08-27 4:20 ` Jie Gan
2025-08-27 9:17 ` James Clark
2 siblings, 1 reply; 12+ messages in thread
From: Jie Gan @ 2025-08-27 4:20 UTC (permalink / raw)
To: Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Tingwei Zhang
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm
From: Tao Zhang <tao.zhang@oss.qualcomm.com>
Setting bit i in the TPDA_FLUSH_CR register initiates a flush request
for port i, forcing the data to synchronize and be transmitted to the
sink device.
Signed-off-by: Tao Zhang <tao.zhang@oss.qualcomm.com>
Co-developed-by: Jie Gan <jie.gan@oss.qualcomm.com>
Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
---
.../testing/sysfs-bus-coresight-devices-tpda | 7 ++++
drivers/hwtracing/coresight/coresight-tpda.c | 42 +++++++++++++++++++
drivers/hwtracing/coresight/coresight-tpda.h | 2 +
3 files changed, 51 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
index fb651aebeb31..2cf2dcfc13c8 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
@@ -41,3 +41,10 @@ Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qu
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.
+
+What: /sys/bus/coresight/devices/<tpda-name>/port_flush_req
+Date: August 2025
+KernelVersion: 6.17
+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 bit i to requests a flush operation of port i on the TPDA.
diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
index 430f76c559f2..8b1fe128881d 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.c
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -487,6 +487,47 @@ static ssize_t cmbchan_mode_store(struct device *dev,
}
static DEVICE_ATTR_RW(cmbchan_mode);
+static ssize_t port_flush_req_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ unsigned long val;
+
+ if (!drvdata->csdev->refcnt)
+ return -EINVAL;
+
+ guard(spinlock)(&drvdata->spinlock);
+ CS_UNLOCK(drvdata->base);
+ val = readl_relaxed(drvdata->base + TPDA_FLUSH_CR);
+ CS_LOCK(drvdata->base);
+ return sysfs_emit(buf, "%lx\n", val);
+}
+
+static ssize_t port_flush_req_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ unsigned long val;
+
+ if (kstrtoul(buf, 0, &val))
+ return -EINVAL;
+
+ if (!drvdata->csdev->refcnt || !val)
+ return -EINVAL;
+
+ val |= FIELD_PREP(TPDA_MAX_INPORTS_MASK, val);
+ guard(spinlock)(&drvdata->spinlock);
+ CS_UNLOCK(drvdata->base);
+ writel_relaxed(val, drvdata->base + TPDA_FLUSH_CR);
+ CS_LOCK(drvdata->base);
+
+ return size;
+}
+static DEVICE_ATTR_RW(port_flush_req);
+
static struct attribute *tpda_attrs[] = {
&dev_attr_trig_async_enable.attr,
&dev_attr_trig_flag_ts_enable.attr,
@@ -494,6 +535,7 @@ static struct attribute *tpda_attrs[] = {
&dev_attr_freq_ts_enable.attr,
&dev_attr_global_flush_req.attr,
&dev_attr_cmbchan_mode.attr,
+ &dev_attr_port_flush_req.attr,
NULL,
};
diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h
index 8e1b66115ad1..56d3ad293e46 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.h
+++ b/drivers/hwtracing/coresight/coresight-tpda.h
@@ -10,6 +10,7 @@
#define TPDA_Pn_CR(n) (0x004 + (n * 4))
#define TPDA_FPID_CR (0x084)
#define TPDA_SYNCR (0x08C)
+#define TPDA_FLUSH_CR (0x090)
/* Cross trigger FREQ packets timestamp bit */
#define TPDA_CR_FREQTS BIT(2)
@@ -35,6 +36,7 @@
#define TPDA_SYNCR_MAX_COUNTER_VAL (0xFFF)
#define TPDA_MAX_INPORTS 32
+#define TPDA_MAX_INPORTS_MASK GENMASK(31, 0)
/* Bits 6 ~ 12 is for atid value */
#define TPDA_CR_ATID GENMASK(12, 6)
--
2.34.1
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] coresight: tpda: add sysfs nodes for tpda cross-trigger configuration
2025-08-27 4:20 ` [PATCH v2 1/3] coresight: tpda: add sysfs nodes for tpda cross-trigger configuration Jie Gan
@ 2025-08-27 9:06 ` James Clark
2025-08-27 9:18 ` Jie Gan
0 siblings, 1 reply; 12+ messages in thread
From: James Clark @ 2025-08-27 9:06 UTC (permalink / raw)
To: Jie Gan
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
Suzuki K Poulose, Mike Leach, Alexander Shishkin, Tingwei Zhang
On 27/08/2025 5:20 am, Jie Gan wrote:
> From: Tao Zhang <tao.zhang@oss.qualcomm.com>
>
> 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>
> Co-developed-by: Jie Gan <jie.gan@oss.qualcomm.com>
> Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
> ---
> .../testing/sysfs-bus-coresight-devices-tpda | 43 ++++
> drivers/hwtracing/coresight/coresight-tpda.c | 227 ++++++++++++++++++
> drivers/hwtracing/coresight/coresight-tpda.h | 27 ++-
> 3 files changed, 296 insertions(+), 1 deletion(-)
> create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
> new file mode 100644
> index 000000000000..fb651aebeb31
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
> @@ -0,0 +1,43 @@
> +What: /sys/bus/coresight/devices/<tpda-name>/trig_async_enable
> +Date: August 2025
> +KernelVersion: 6.17
> +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: August 2025
> +KernelVersion: 6.17
> +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: August 2025
> +KernelVersion: 6.17
> +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: August 2025
> +KernelVersion: 6.17
> +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>/global_flush_req
> +Date: August 2025
> +KernelVersion: 6.17
> +Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
> +Description:
> + (RW) Set global (all ports) flush request bit. The bit remains set until a
> + global flush request sequence completes.
> +
> +What: /sys/bus/coresight/devices/<tpda-name>/cmbchan_mode
> +Date: August 2025
> +KernelVersion: 6.17
> +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.
> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
> index 4e93fa5bace4..647ab49a98d7 100644
> --- a/drivers/hwtracing/coresight/coresight-tpda.c
> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
> @@ -156,9 +156,37 @@ static void tpda_enable_pre_port(struct tpda_drvdata *drvdata)
> u32 val;
>
> val = readl_relaxed(drvdata->base + TPDA_CR);
> + val &= ~TPDA_CR_MID;
> val &= ~TPDA_CR_ATID;
> val |= FIELD_PREP(TPDA_CR_ATID, drvdata->atid);
> + if (drvdata->trig_async)
> + val |= TPDA_CR_SRIE;
> + else
> + val &= ~TPDA_CR_SRIE;
> + if (drvdata->trig_flag_ts)
> + val |= TPDA_CR_FLRIE;
> + else
> + val &= ~TPDA_CR_FLRIE;
> + if (drvdata->trig_freq)
> + val |= TPDA_CR_FRIE;
> + else
> + val &= ~TPDA_CR_FRIE;
> + if (drvdata->freq_ts)
> + val |= TPDA_CR_FREQTS;
> + else
> + val &= ~TPDA_CR_FREQTS;
> + if (drvdata->cmbchan_mode)
> + val |= TPDA_CR_CMBCHANMODE;
> + else
> + 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)
> @@ -274,6 +302,203 @@ static const struct coresight_ops tpda_cs_ops = {
> .link_ops = &tpda_link_ops,
> };
>
> +static ssize_t trig_async_enable_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
> +
> + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_async);
> +}
> +
> +static ssize_t trig_async_enable_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf,
> + size_t size)
> +{
> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
> + unsigned long val;
> +
> + if (kstrtoul(buf, 0, &val))
> + return -EINVAL;
> +
> + guard(spinlock)(&drvdata->spinlock);
> + drvdata->trig_async = !!val;
> +
> + return size;
> +}
> +static DEVICE_ATTR_RW(trig_async_enable);
> +
> +static ssize_t trig_flag_ts_enable_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
> +
> + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_flag_ts);
> +}
> +
> +static ssize_t trig_flag_ts_enable_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf,
> + size_t size)
> +{
> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
> + unsigned long val;
> +
> + if (kstrtoul(buf, 0, &val))
> + return -EINVAL;
> +
> + guard(spinlock)(&drvdata->spinlock);
> + drvdata->trig_flag_ts = !!val;
> +
> + return size;
> +}
> +static DEVICE_ATTR_RW(trig_flag_ts_enable);
> +
> +static ssize_t trig_freq_enable_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
> +
> + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_freq);
> +}
> +
> +static ssize_t trig_freq_enable_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf,
> + size_t size)
> +{
> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
> + unsigned long val;
> +
> + if (kstrtoul(buf, 0, &val))
> + return -EINVAL;
> +
> + guard(spinlock)(&drvdata->spinlock);
> + drvdata->trig_freq = !!val;
> +
> + return size;
> +}
> +static DEVICE_ATTR_RW(trig_freq_enable);
> +
> +static ssize_t freq_ts_enable_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
> +
> + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->freq_ts);
> +}
> +
> +static ssize_t freq_ts_enable_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf,
> + size_t size)
> +{
> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
> + unsigned long val;
> +
> + if (kstrtoul(buf, 0, &val))
> + return -EINVAL;
> +
> + guard(spinlock)(&drvdata->spinlock);
> + drvdata->freq_ts = !!val;
> +
> + return size;
> +}
> +static DEVICE_ATTR_RW(freq_ts_enable);
> +
> +static ssize_t global_flush_req_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
> + unsigned long val;
> +
> + if (!drvdata->csdev->refcnt)
> + return -EINVAL;
> +
> + guard(spinlock)(&drvdata->spinlock);
> + CS_UNLOCK(drvdata->base);
> + val = readl_relaxed(drvdata->base + TPDA_CR);
> + CS_LOCK(drvdata->base);
> +
> + return sysfs_emit(buf, "%lx\n", val);
I know in practice it's probably only either 0 or 1, but this should
either be decimal or have the 0x prefix otherwise it looks like a mistake.
> +}
> +
> +static ssize_t global_flush_req_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf,
> + size_t size)
> +{
> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
> + unsigned long val;
> +
> + if (kstrtoul(buf, 0, &val))
> + return -EINVAL;
> +
> + if (!drvdata->csdev->refcnt || !val)
> + return -EINVAL;
> +
> + guard(spinlock)(&drvdata->spinlock);
> + CS_UNLOCK(drvdata->base);
> + val = readl_relaxed(drvdata->base + TPDA_CR);
> + val |= BIT(0);
If you only set bit 0 do you only want to show bit 0 in
global_flush_req_show() above? The sysfs files should be divided up by
function rather than dumping the whole register, otherwise tools need
their own copy of the fields to interperet them.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/3] coresight: tpda: add sysfs node to flush specific port
2025-08-27 4:20 ` [PATCH v2 3/3] coresight: tpda: add sysfs node to flush specific port Jie Gan
@ 2025-08-27 9:17 ` James Clark
2025-08-27 9:48 ` Jie Gan
0 siblings, 1 reply; 12+ messages in thread
From: James Clark @ 2025-08-27 9:17 UTC (permalink / raw)
To: Jie Gan
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
Suzuki K Poulose, Mike Leach, Alexander Shishkin, Tingwei Zhang
On 27/08/2025 5:20 am, Jie Gan wrote:
> From: Tao Zhang <tao.zhang@oss.qualcomm.com>
>
> Setting bit i in the TPDA_FLUSH_CR register initiates a flush request
> for port i, forcing the data to synchronize and be transmitted to the
> sink device.
>
> Signed-off-by: Tao Zhang <tao.zhang@oss.qualcomm.com>
> Co-developed-by: Jie Gan <jie.gan@oss.qualcomm.com>
> Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
> ---
> .../testing/sysfs-bus-coresight-devices-tpda | 7 ++++
> drivers/hwtracing/coresight/coresight-tpda.c | 42 +++++++++++++++++++
> drivers/hwtracing/coresight/coresight-tpda.h | 2 +
> 3 files changed, 51 insertions(+)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
> index fb651aebeb31..2cf2dcfc13c8 100644
> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
> @@ -41,3 +41,10 @@ Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qu
> 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.
> +
> +What: /sys/bus/coresight/devices/<tpda-name>/port_flush_req
> +Date: August 2025
> +KernelVersion: 6.17
> +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 bit i to requests a flush operation of port i on the TPDA.
> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
> index 430f76c559f2..8b1fe128881d 100644
> --- a/drivers/hwtracing/coresight/coresight-tpda.c
> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
> @@ -487,6 +487,47 @@ static ssize_t cmbchan_mode_store(struct device *dev,
> }
> static DEVICE_ATTR_RW(cmbchan_mode);
>
> +static ssize_t port_flush_req_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
> + unsigned long val;
> +
> + if (!drvdata->csdev->refcnt)
> + return -EINVAL;
> +
> + guard(spinlock)(&drvdata->spinlock);
> + CS_UNLOCK(drvdata->base);
> + val = readl_relaxed(drvdata->base + TPDA_FLUSH_CR);
> + CS_LOCK(drvdata->base);
> + return sysfs_emit(buf, "%lx\n", val);
Still missing the 0x prefix
> +}
> +
> +static ssize_t port_flush_req_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf,
> + size_t size)
> +{
> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
> + unsigned long val;
> +
> + if (kstrtoul(buf, 0, &val))
> + return -EINVAL;
> +
> + if (!drvdata->csdev->refcnt || !val)
> + return -EINVAL;
> +
> + val |= FIELD_PREP(TPDA_MAX_INPORTS_MASK, val);
Using FIELD_PREP() now that it's the full width of the register makes
less sense. Especially when there is no corresponding FIELD_FIT() check,
which is fine because everything always fits. But if you didn't know
the mask was the full width you'd wonder if the check is missing.
I would just write val directly to TPDA_FLUSH_CR so it's simpler.
It should also have been val = FIELD_PREP(...)
> + guard(spinlock)(&drvdata->spinlock);
> + CS_UNLOCK(drvdata->base);
> + writel_relaxed(val, drvdata->base + TPDA_FLUSH_CR);
> + CS_LOCK(drvdata->base);
> +
> + return size;
> +}
> +static DEVICE_ATTR_RW(port_flush_req);
> +
> static struct attribute *tpda_attrs[] = {
> &dev_attr_trig_async_enable.attr,
> &dev_attr_trig_flag_ts_enable.attr,
> @@ -494,6 +535,7 @@ static struct attribute *tpda_attrs[] = {
> &dev_attr_freq_ts_enable.attr,
> &dev_attr_global_flush_req.attr,
> &dev_attr_cmbchan_mode.attr,
> + &dev_attr_port_flush_req.attr,
> NULL,
> };
>
> diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h
> index 8e1b66115ad1..56d3ad293e46 100644
> --- a/drivers/hwtracing/coresight/coresight-tpda.h
> +++ b/drivers/hwtracing/coresight/coresight-tpda.h
> @@ -10,6 +10,7 @@
> #define TPDA_Pn_CR(n) (0x004 + (n * 4))
> #define TPDA_FPID_CR (0x084)
> #define TPDA_SYNCR (0x08C)
> +#define TPDA_FLUSH_CR (0x090)
>
> /* Cross trigger FREQ packets timestamp bit */
> #define TPDA_CR_FREQTS BIT(2)
> @@ -35,6 +36,7 @@
> #define TPDA_SYNCR_MAX_COUNTER_VAL (0xFFF)
>
> #define TPDA_MAX_INPORTS 32
> +#define TPDA_MAX_INPORTS_MASK GENMASK(31, 0)
>
> /* Bits 6 ~ 12 is for atid value */
> #define TPDA_CR_ATID GENMASK(12, 6)
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] coresight: tpda: add sysfs nodes for tpda cross-trigger configuration
2025-08-27 9:06 ` James Clark
@ 2025-08-27 9:18 ` Jie Gan
0 siblings, 0 replies; 12+ messages in thread
From: Jie Gan @ 2025-08-27 9:18 UTC (permalink / raw)
To: James Clark
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
Suzuki K Poulose, Mike Leach, Alexander Shishkin, Tingwei Zhang
On 8/27/2025 5:06 PM, James Clark wrote:
>
>
> On 27/08/2025 5:20 am, Jie Gan wrote:
>> From: Tao Zhang <tao.zhang@oss.qualcomm.com>
>>
>> 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>
>> Co-developed-by: Jie Gan <jie.gan@oss.qualcomm.com>
>> Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
>> ---
>> .../testing/sysfs-bus-coresight-devices-tpda | 43 ++++
>> drivers/hwtracing/coresight/coresight-tpda.c | 227 ++++++++++++++++++
>> drivers/hwtracing/coresight/coresight-tpda.h | 27 ++-
>> 3 files changed, 296 insertions(+), 1 deletion(-)
>> create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-
>> devices-tpda
>>
>> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-
>> tpda b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
>> new file mode 100644
>> index 000000000000..fb651aebeb31
>> --- /dev/null
>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
>> @@ -0,0 +1,43 @@
>> +What: /sys/bus/coresight/devices/<tpda-name>/trig_async_enable
>> +Date: August 2025
>> +KernelVersion: 6.17
>> +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: August 2025
>> +KernelVersion: 6.17
>> +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: August 2025
>> +KernelVersion: 6.17
>> +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: August 2025
>> +KernelVersion: 6.17
>> +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>/global_flush_req
>> +Date: August 2025
>> +KernelVersion: 6.17
>> +Contact: Jinlong Mao <jinlong.mao@oss.qualcomm.com>, Tao Zhang
>> <tao.zhang@oss.qualcomm.com>, Jie Gan <jie.gan@oss.qualcomm.com>
>> +Description:
>> + (RW) Set global (all ports) flush request bit. The bit
>> remains set until a
>> + global flush request sequence completes.
>> +
>> +What: /sys/bus/coresight/devices/<tpda-name>/cmbchan_mode
>> +Date: August 2025
>> +KernelVersion: 6.17
>> +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.
>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/
>> hwtracing/coresight/coresight-tpda.c
>> index 4e93fa5bace4..647ab49a98d7 100644
>> --- a/drivers/hwtracing/coresight/coresight-tpda.c
>> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
>> @@ -156,9 +156,37 @@ static void tpda_enable_pre_port(struct
>> tpda_drvdata *drvdata)
>> u32 val;
>> val = readl_relaxed(drvdata->base + TPDA_CR);
>> + val &= ~TPDA_CR_MID;
>> val &= ~TPDA_CR_ATID;
>> val |= FIELD_PREP(TPDA_CR_ATID, drvdata->atid);
>> + if (drvdata->trig_async)
>> + val |= TPDA_CR_SRIE;
>> + else
>> + val &= ~TPDA_CR_SRIE;
>> + if (drvdata->trig_flag_ts)
>> + val |= TPDA_CR_FLRIE;
>> + else
>> + val &= ~TPDA_CR_FLRIE;
>> + if (drvdata->trig_freq)
>> + val |= TPDA_CR_FRIE;
>> + else
>> + val &= ~TPDA_CR_FRIE;
>> + if (drvdata->freq_ts)
>> + val |= TPDA_CR_FREQTS;
>> + else
>> + val &= ~TPDA_CR_FREQTS;
>> + if (drvdata->cmbchan_mode)
>> + val |= TPDA_CR_CMBCHANMODE;
>> + else
>> + 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)
>> @@ -274,6 +302,203 @@ static const struct coresight_ops tpda_cs_ops = {
>> .link_ops = &tpda_link_ops,
>> };
>> +static ssize_t trig_async_enable_show(struct device *dev,
>> + struct device_attribute *attr,
>> + char *buf)
>> +{
>> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
>> +
>> + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_async);
>> +}
>> +
>> +static ssize_t trig_async_enable_store(struct device *dev,
>> + struct device_attribute *attr,
>> + const char *buf,
>> + size_t size)
>> +{
>> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
>> + unsigned long val;
>> +
>> + if (kstrtoul(buf, 0, &val))
>> + return -EINVAL;
>> +
>> + guard(spinlock)(&drvdata->spinlock);
>> + drvdata->trig_async = !!val;
>> +
>> + return size;
>> +}
>> +static DEVICE_ATTR_RW(trig_async_enable);
>> +
>> +static ssize_t trig_flag_ts_enable_show(struct device *dev,
>> + struct device_attribute *attr,
>> + char *buf)
>> +{
>> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
>> +
>> + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_flag_ts);
>> +}
>> +
>> +static ssize_t trig_flag_ts_enable_store(struct device *dev,
>> + struct device_attribute *attr,
>> + const char *buf,
>> + size_t size)
>> +{
>> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
>> + unsigned long val;
>> +
>> + if (kstrtoul(buf, 0, &val))
>> + return -EINVAL;
>> +
>> + guard(spinlock)(&drvdata->spinlock);
>> + drvdata->trig_flag_ts = !!val;
>> +
>> + return size;
>> +}
>> +static DEVICE_ATTR_RW(trig_flag_ts_enable);
>> +
>> +static ssize_t trig_freq_enable_show(struct device *dev,
>> + struct device_attribute *attr,
>> + char *buf)
>> +{
>> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
>> +
>> + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->trig_freq);
>> +}
>> +
>> +static ssize_t trig_freq_enable_store(struct device *dev,
>> + struct device_attribute *attr,
>> + const char *buf,
>> + size_t size)
>> +{
>> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
>> + unsigned long val;
>> +
>> + if (kstrtoul(buf, 0, &val))
>> + return -EINVAL;
>> +
>> + guard(spinlock)(&drvdata->spinlock);
>> + drvdata->trig_freq = !!val;
>> +
>> + return size;
>> +}
>> +static DEVICE_ATTR_RW(trig_freq_enable);
>> +
>> +static ssize_t freq_ts_enable_show(struct device *dev,
>> + struct device_attribute *attr,
>> + char *buf)
>> +{
>> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
>> +
>> + return sysfs_emit(buf, "%u\n", (unsigned int)drvdata->freq_ts);
>> +}
>> +
>> +static ssize_t freq_ts_enable_store(struct device *dev,
>> + struct device_attribute *attr,
>> + const char *buf,
>> + size_t size)
>> +{
>> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
>> + unsigned long val;
>> +
>> + if (kstrtoul(buf, 0, &val))
>> + return -EINVAL;
>> +
>> + guard(spinlock)(&drvdata->spinlock);
>> + drvdata->freq_ts = !!val;
>> +
>> + return size;
>> +}
>> +static DEVICE_ATTR_RW(freq_ts_enable);
>> +
>> +static ssize_t global_flush_req_show(struct device *dev,
>> + struct device_attribute *attr,
>> + char *buf)
>> +{
>> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
>> + unsigned long val;
>> +
>> + if (!drvdata->csdev->refcnt)
>> + return -EINVAL;
>> +
>> + guard(spinlock)(&drvdata->spinlock);
>> + CS_UNLOCK(drvdata->base);
>> + val = readl_relaxed(drvdata->base + TPDA_CR);
>> + CS_LOCK(drvdata->base);
>> +
>> + return sysfs_emit(buf, "%lx\n", val);
>
> I know in practice it's probably only either 0 or 1, but this should
> either be decimal or have the 0x prefix otherwise it looks like a mistake.
>
You are right. It looks strange here and I missed this point. I think
display the value in decimal would be better.
>> +}
>> +
>> +static ssize_t global_flush_req_store(struct device *dev,
>> + struct device_attribute *attr,
>> + const char *buf,
>> + size_t size)
>> +{
>> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
>> + unsigned long val;
>> +
>> + if (kstrtoul(buf, 0, &val))
>> + return -EINVAL;
>> +
>> + if (!drvdata->csdev->refcnt || !val)
>> + return -EINVAL;
>> +
>> + guard(spinlock)(&drvdata->spinlock);
>> + CS_UNLOCK(drvdata->base);
>> + val = readl_relaxed(drvdata->base + TPDA_CR);
>> + val |= BIT(0);
>
> If you only set bit 0 do you only want to show bit 0 in
> global_flush_req_show() above? The sysfs files should be divided up by
> function rather than dumping the whole register, otherwise tools need
> their own copy of the fields to interperet them.
Got your point here. In the show function, we only need read the value
of the bit 0 and display the value.
Thanks,
Jie
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/3] coresight: tpda: add logic to configure TPDA_SYNCR register
2025-08-27 4:20 ` [PATCH v2 2/3] coresight: tpda: add logic to configure TPDA_SYNCR register Jie Gan
@ 2025-08-27 9:21 ` James Clark
2025-08-27 9:52 ` Jie Gan
0 siblings, 1 reply; 12+ messages in thread
From: James Clark @ 2025-08-27 9:21 UTC (permalink / raw)
To: Jie Gan
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
Suzuki K Poulose, Mike Leach, Alexander Shishkin, Tingwei Zhang
On 27/08/2025 5:20 am, Jie Gan wrote:
> From: Tao Zhang <tao.zhang@oss.qualcomm.com>
>
> The TPDA_SYNCR register defines the frequency at which TPDA generates
> ASYNC packets, enabling userspace tools to accurately parse each valid
> packet.
>
> Signed-off-by: Tao Zhang <tao.zhang@oss.qualcomm.com>
> Co-developed-by: Jie Gan <jie.gan@oss.qualcomm.com>
> Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
> ---
> drivers/hwtracing/coresight/coresight-tpda.c | 7 +++++++
> drivers/hwtracing/coresight/coresight-tpda.h | 6 ++++++
> 2 files changed, 13 insertions(+)
>
> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
> index 647ab49a98d7..430f76c559f2 100644
> --- a/drivers/hwtracing/coresight/coresight-tpda.c
> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
> @@ -187,6 +187,13 @@ static void tpda_enable_pre_port(struct tpda_drvdata *drvdata)
> */
> if (drvdata->trig_flag_ts)
> writel_relaxed(0x0, drvdata->base + TPDA_FPID_CR);
> +
> + /* Program the counter value for TPDA_SYNCR */
> + val = readl_relaxed(drvdata->base + TPDA_SYNCR);
> + /* Clear the mode */
> + val &= ~TPDA_SYNCR_MODE_CTRL;
> + val |= FIELD_PREP(TPDA_SYNCR_COUNTER_MASK, TPDA_SYNCR_MAX_COUNTER_VAL);
Just use the mask directly if you want to set all the bits. This makes
it seem like the MAX_COUNTER_VAL is something different.
val |= TPDA_SYNCR_COUNTER_MASK
> + writel_relaxed(val, drvdata->base + TPDA_SYNCR);
> }
>
> static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
> diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h
> index 0be625fb52fd..8e1b66115ad1 100644
> --- a/drivers/hwtracing/coresight/coresight-tpda.h
> +++ b/drivers/hwtracing/coresight/coresight-tpda.h
> @@ -9,6 +9,7 @@
> #define TPDA_CR (0x000)
> #define TPDA_Pn_CR(n) (0x004 + (n * 4))
> #define TPDA_FPID_CR (0x084)
> +#define TPDA_SYNCR (0x08C)
>
> /* Cross trigger FREQ packets timestamp bit */
> #define TPDA_CR_FREQTS BIT(2)
> @@ -27,6 +28,11 @@
> #define TPDA_Pn_CR_CMBSIZE GENMASK(7, 6)
> /* Aggregator port DSB data set element size bit */
> #define TPDA_Pn_CR_DSBSIZE BIT(8)
> +/* TPDA_SYNCR mode control bit */
> +#define TPDA_SYNCR_MODE_CTRL BIT(12)
> +/* TPDA_SYNCR counter mask */
> +#define TPDA_SYNCR_COUNTER_MASK GENMASK(11, 0)
> +#define TPDA_SYNCR_MAX_COUNTER_VAL (0xFFF)
No need to define a numeric value that's the same as the mask. It also
opens the possibility of making a mistake.
>
> #define TPDA_MAX_INPORTS 32
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/3] coresight: tpda: add sysfs node to flush specific port
2025-08-27 9:17 ` James Clark
@ 2025-08-27 9:48 ` Jie Gan
2025-08-27 10:16 ` James Clark
0 siblings, 1 reply; 12+ messages in thread
From: Jie Gan @ 2025-08-27 9:48 UTC (permalink / raw)
To: James Clark, Jie Gan
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
Suzuki K Poulose, Mike Leach, Alexander Shishkin, Tingwei Zhang
On 8/27/2025 5:17 PM, James Clark wrote:
>
>
> On 27/08/2025 5:20 am, Jie Gan wrote:
>> From: Tao Zhang <tao.zhang@oss.qualcomm.com>
>>
>> Setting bit i in the TPDA_FLUSH_CR register initiates a flush request
>> for port i, forcing the data to synchronize and be transmitted to the
>> sink device.
>>
>> Signed-off-by: Tao Zhang <tao.zhang@oss.qualcomm.com>
>> Co-developed-by: Jie Gan <jie.gan@oss.qualcomm.com>
>> Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
>> ---
>> .../testing/sysfs-bus-coresight-devices-tpda | 7 ++++
>> drivers/hwtracing/coresight/coresight-tpda.c | 42 +++++++++++++++++++
>> drivers/hwtracing/coresight/coresight-tpda.h | 2 +
>> 3 files changed, 51 insertions(+)
>>
>> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-
>> tpda b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
>> index fb651aebeb31..2cf2dcfc13c8 100644
>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
>> @@ -41,3 +41,10 @@ Contact: Jinlong Mao
>> <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qu
>> 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.
>> +
>> +What: /sys/bus/coresight/devices/<tpda-name>/port_flush_req
>> +Date: August 2025
>> +KernelVersion: 6.17
>> +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 bit i to requests a flush operation of
>> port i on the TPDA.
>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/
>> hwtracing/coresight/coresight-tpda.c
>> index 430f76c559f2..8b1fe128881d 100644
>> --- a/drivers/hwtracing/coresight/coresight-tpda.c
>> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
>> @@ -487,6 +487,47 @@ static ssize_t cmbchan_mode_store(struct device
>> *dev,
>> }
>> static DEVICE_ATTR_RW(cmbchan_mode);
>> +static ssize_t port_flush_req_show(struct device *dev,
>> + struct device_attribute *attr,
>> + char *buf)
>> +{
>> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
>> + unsigned long val;
>> +
>> + if (!drvdata->csdev->refcnt)
>> + return -EINVAL;
>> +
>> + guard(spinlock)(&drvdata->spinlock);
>> + CS_UNLOCK(drvdata->base);
>> + val = readl_relaxed(drvdata->base + TPDA_FLUSH_CR);
>> + CS_LOCK(drvdata->base);
>> + return sysfs_emit(buf, "%lx\n", val);
>
> Still missing the 0x prefix
Will re-check rest of the codes and add prefix. Sorry I missed it during
the review process.
>
>> +}
>> +
>> +static ssize_t port_flush_req_store(struct device *dev,
>> + struct device_attribute *attr,
>> + const char *buf,
>> + size_t size)
>> +{
>> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
>> + unsigned long val;
>> +
>> + if (kstrtoul(buf, 0, &val))
>> + return -EINVAL;
>> +
>> + if (!drvdata->csdev->refcnt || !val)
>> + return -EINVAL;
>> +
>> + val |= FIELD_PREP(TPDA_MAX_INPORTS_MASK, val);
>
> Using FIELD_PREP() now that it's the full width of the register makes
> less sense. Especially when there is no corresponding FIELD_FIT() check,
> which is fine because everything always fits. But if you didn't know
> the mask was the full width you'd wonder if the check is missing.
>
> I would just write val directly to TPDA_FLUSH_CR so it's simpler.
>
> It should also have been val = FIELD_PREP(...)
Yeah, it should have been val = FIELD_PREP(...) here... sorry for the
mistake here..
I was thinking the unsigned long here could be 64 or 32 bits and we only
need the value of the lower 32 bits. So that's why I am using val =
FIELD_PREP(...) here. We shouldn't write a value greater than UINT32_MAX
to the register.
Thanks,
Jie
>
>> + guard(spinlock)(&drvdata->spinlock);
>> + CS_UNLOCK(drvdata->base);
>> + writel_relaxed(val, drvdata->base + TPDA_FLUSH_CR);
>> + CS_LOCK(drvdata->base);
>> +
>> + return size;
>> +}
>> +static DEVICE_ATTR_RW(port_flush_req);
>> +
>> static struct attribute *tpda_attrs[] = {
>> &dev_attr_trig_async_enable.attr,
>> &dev_attr_trig_flag_ts_enable.attr,
>> @@ -494,6 +535,7 @@ static struct attribute *tpda_attrs[] = {
>> &dev_attr_freq_ts_enable.attr,
>> &dev_attr_global_flush_req.attr,
>> &dev_attr_cmbchan_mode.attr,
>> + &dev_attr_port_flush_req.attr,
>> NULL,
>> };
>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/
>> hwtracing/coresight/coresight-tpda.h
>> index 8e1b66115ad1..56d3ad293e46 100644
>> --- a/drivers/hwtracing/coresight/coresight-tpda.h
>> +++ b/drivers/hwtracing/coresight/coresight-tpda.h
>> @@ -10,6 +10,7 @@
>> #define TPDA_Pn_CR(n) (0x004 + (n * 4))
>> #define TPDA_FPID_CR (0x084)
>> #define TPDA_SYNCR (0x08C)
>> +#define TPDA_FLUSH_CR (0x090)
>> /* Cross trigger FREQ packets timestamp bit */
>> #define TPDA_CR_FREQTS BIT(2)
>> @@ -35,6 +36,7 @@
>> #define TPDA_SYNCR_MAX_COUNTER_VAL (0xFFF)
>> #define TPDA_MAX_INPORTS 32
>> +#define TPDA_MAX_INPORTS_MASK GENMASK(31, 0)
>> /* Bits 6 ~ 12 is for atid value */
>> #define TPDA_CR_ATID GENMASK(12, 6)
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/3] coresight: tpda: add logic to configure TPDA_SYNCR register
2025-08-27 9:21 ` James Clark
@ 2025-08-27 9:52 ` Jie Gan
0 siblings, 0 replies; 12+ messages in thread
From: Jie Gan @ 2025-08-27 9:52 UTC (permalink / raw)
To: James Clark, Jie Gan
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
Suzuki K Poulose, Mike Leach, Alexander Shishkin, Tingwei Zhang
On 8/27/2025 5:21 PM, James Clark wrote:
>
>
> On 27/08/2025 5:20 am, Jie Gan wrote:
>> From: Tao Zhang <tao.zhang@oss.qualcomm.com>
>>
>> The TPDA_SYNCR register defines the frequency at which TPDA generates
>> ASYNC packets, enabling userspace tools to accurately parse each valid
>> packet.
>>
>> Signed-off-by: Tao Zhang <tao.zhang@oss.qualcomm.com>
>> Co-developed-by: Jie Gan <jie.gan@oss.qualcomm.com>
>> Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
>> ---
>> drivers/hwtracing/coresight/coresight-tpda.c | 7 +++++++
>> drivers/hwtracing/coresight/coresight-tpda.h | 6 ++++++
>> 2 files changed, 13 insertions(+)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/
>> hwtracing/coresight/coresight-tpda.c
>> index 647ab49a98d7..430f76c559f2 100644
>> --- a/drivers/hwtracing/coresight/coresight-tpda.c
>> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
>> @@ -187,6 +187,13 @@ static void tpda_enable_pre_port(struct
>> tpda_drvdata *drvdata)
>> */
>> if (drvdata->trig_flag_ts)
>> writel_relaxed(0x0, drvdata->base + TPDA_FPID_CR);
>> +
>> + /* Program the counter value for TPDA_SYNCR */
>> + val = readl_relaxed(drvdata->base + TPDA_SYNCR);
>> + /* Clear the mode */
>> + val &= ~TPDA_SYNCR_MODE_CTRL;
>> + val |= FIELD_PREP(TPDA_SYNCR_COUNTER_MASK,
>> TPDA_SYNCR_MAX_COUNTER_VAL);
>
> Just use the mask directly if you want to set all the bits. This makes
> it seem like the MAX_COUNTER_VAL is something different.
>
You are right. will fix it.
> val |= TPDA_SYNCR_COUNTER_MASK
>
>> + writel_relaxed(val, drvdata->base + TPDA_SYNCR);
>> }
>> static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/
>> hwtracing/coresight/coresight-tpda.h
>> index 0be625fb52fd..8e1b66115ad1 100644
>> --- a/drivers/hwtracing/coresight/coresight-tpda.h
>> +++ b/drivers/hwtracing/coresight/coresight-tpda.h
>> @@ -9,6 +9,7 @@
>> #define TPDA_CR (0x000)
>> #define TPDA_Pn_CR(n) (0x004 + (n * 4))
>> #define TPDA_FPID_CR (0x084)
>> +#define TPDA_SYNCR (0x08C)
>> /* Cross trigger FREQ packets timestamp bit */
>> #define TPDA_CR_FREQTS BIT(2)
>> @@ -27,6 +28,11 @@
>> #define TPDA_Pn_CR_CMBSIZE GENMASK(7, 6)
>> /* Aggregator port DSB data set element size bit */
>> #define TPDA_Pn_CR_DSBSIZE BIT(8)
>> +/* TPDA_SYNCR mode control bit */
>> +#define TPDA_SYNCR_MODE_CTRL BIT(12)
>> +/* TPDA_SYNCR counter mask */
>> +#define TPDA_SYNCR_COUNTER_MASK GENMASK(11, 0)
>> +#define TPDA_SYNCR_MAX_COUNTER_VAL (0xFFF)
>
> No need to define a numeric value that's the same as the mask. It also
> opens the possibility of making a mistake.
>
will remove.
Thanks,
Jie
>> #define TPDA_MAX_INPORTS 32
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/3] coresight: tpda: add sysfs node to flush specific port
2025-08-27 9:48 ` Jie Gan
@ 2025-08-27 10:16 ` James Clark
2025-08-27 10:21 ` Jie Gan
0 siblings, 1 reply; 12+ messages in thread
From: James Clark @ 2025-08-27 10:16 UTC (permalink / raw)
To: Jie Gan
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
Suzuki K Poulose, Mike Leach, Alexander Shishkin, Tingwei Zhang
On 27/08/2025 10:48 am, Jie Gan wrote:
>
>
> On 8/27/2025 5:17 PM, James Clark wrote:
>>
>>
>> On 27/08/2025 5:20 am, Jie Gan wrote:
>>> From: Tao Zhang <tao.zhang@oss.qualcomm.com>
>>>
>>> Setting bit i in the TPDA_FLUSH_CR register initiates a flush request
>>> for port i, forcing the data to synchronize and be transmitted to the
>>> sink device.
>>>
>>> Signed-off-by: Tao Zhang <tao.zhang@oss.qualcomm.com>
>>> Co-developed-by: Jie Gan <jie.gan@oss.qualcomm.com>
>>> Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
>>> ---
>>> .../testing/sysfs-bus-coresight-devices-tpda | 7 ++++
>>> drivers/hwtracing/coresight/coresight-tpda.c | 42 +++++++++++++++++++
>>> drivers/hwtracing/coresight/coresight-tpda.h | 2 +
>>> 3 files changed, 51 insertions(+)
>>>
>>> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-
>>> tpda b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
>>> index fb651aebeb31..2cf2dcfc13c8 100644
>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
>>> @@ -41,3 +41,10 @@ Contact: Jinlong Mao
>>> <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qu
>>> 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.
>>> +
>>> +What: /sys/bus/coresight/devices/<tpda-name>/port_flush_req
>>> +Date: August 2025
>>> +KernelVersion: 6.17
>>> +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 bit i to requests a flush operation of
>>> port i on the TPDA.
>>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/
>>> hwtracing/coresight/coresight-tpda.c
>>> index 430f76c559f2..8b1fe128881d 100644
>>> --- a/drivers/hwtracing/coresight/coresight-tpda.c
>>> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
>>> @@ -487,6 +487,47 @@ static ssize_t cmbchan_mode_store(struct device
>>> *dev,
>>> }
>>> static DEVICE_ATTR_RW(cmbchan_mode);
>>> +static ssize_t port_flush_req_show(struct device *dev,
>>> + struct device_attribute *attr,
>>> + char *buf)
>>> +{
>>> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>> + unsigned long val;
>>> +
>>> + if (!drvdata->csdev->refcnt)
>>> + return -EINVAL;
>>> +
>>> + guard(spinlock)(&drvdata->spinlock);
>>> + CS_UNLOCK(drvdata->base);
>>> + val = readl_relaxed(drvdata->base + TPDA_FLUSH_CR);
>>> + CS_LOCK(drvdata->base);
>>> + return sysfs_emit(buf, "%lx\n", val);
>>
>> Still missing the 0x prefix
>
> Will re-check rest of the codes and add prefix. Sorry I missed it during
> the review process.
>
>>
>>> +}
>>> +
>>> +static ssize_t port_flush_req_store(struct device *dev,
>>> + struct device_attribute *attr,
>>> + const char *buf,
>>> + size_t size)
>>> +{
>>> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>> + unsigned long val;
>>> +
>>> + if (kstrtoul(buf, 0, &val))
>>> + return -EINVAL;
>>> +
>>> + if (!drvdata->csdev->refcnt || !val)
>>> + return -EINVAL;
>>> +
>>> + val |= FIELD_PREP(TPDA_MAX_INPORTS_MASK, val);
>>
>> Using FIELD_PREP() now that it's the full width of the register makes
>> less sense. Especially when there is no corresponding FIELD_FIT()
>> check, which is fine because everything always fits. But if you
>> didn't know the mask was the full width you'd wonder if the check is
>> missing.
>>
>> I would just write val directly to TPDA_FLUSH_CR so it's simpler.
>>
>> It should also have been val = FIELD_PREP(...)
>
> Yeah, it should have been val = FIELD_PREP(...) here... sorry for the
> mistake here..
>
> I was thinking the unsigned long here could be 64 or 32 bits and we only
> need the value of the lower 32 bits. So that's why I am using val =
> FIELD_PREP(...) here. We shouldn't write a value greater than UINT32_MAX
> to the register.
>
> Thanks,
> Jie
>
writel_relaxed() is always 32 bits though so it is a bit confusing if
you truncate the user value without an error. Also a reason to use u32
instead of unsigned long types.
Are you trying to support arm and arm64 with tpda? Or just arm64? For it
to be consistent you can use kstrtou32(), or use kstrtoull() and then
FIELD_FIT() to error on truncation. kstrtou32() is probably the cleanest.
>>
>>> + guard(spinlock)(&drvdata->spinlock);
>>> + CS_UNLOCK(drvdata->base);
>>> + writel_relaxed(val, drvdata->base + TPDA_FLUSH_CR);
>>> + CS_LOCK(drvdata->base);
>>> +
>>> + return size;
>>> +}
>>> +static DEVICE_ATTR_RW(port_flush_req);
>>> +
>>> static struct attribute *tpda_attrs[] = {
>>> &dev_attr_trig_async_enable.attr,
>>> &dev_attr_trig_flag_ts_enable.attr,
>>> @@ -494,6 +535,7 @@ static struct attribute *tpda_attrs[] = {
>>> &dev_attr_freq_ts_enable.attr,
>>> &dev_attr_global_flush_req.attr,
>>> &dev_attr_cmbchan_mode.attr,
>>> + &dev_attr_port_flush_req.attr,
>>> NULL,
>>> };
>>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/
>>> hwtracing/coresight/coresight-tpda.h
>>> index 8e1b66115ad1..56d3ad293e46 100644
>>> --- a/drivers/hwtracing/coresight/coresight-tpda.h
>>> +++ b/drivers/hwtracing/coresight/coresight-tpda.h
>>> @@ -10,6 +10,7 @@
>>> #define TPDA_Pn_CR(n) (0x004 + (n * 4))
>>> #define TPDA_FPID_CR (0x084)
>>> #define TPDA_SYNCR (0x08C)
>>> +#define TPDA_FLUSH_CR (0x090)
>>> /* Cross trigger FREQ packets timestamp bit */
>>> #define TPDA_CR_FREQTS BIT(2)
>>> @@ -35,6 +36,7 @@
>>> #define TPDA_SYNCR_MAX_COUNTER_VAL (0xFFF)
>>> #define TPDA_MAX_INPORTS 32
>>> +#define TPDA_MAX_INPORTS_MASK GENMASK(31, 0)
>>> /* Bits 6 ~ 12 is for atid value */
>>> #define TPDA_CR_ATID GENMASK(12, 6)
>>
>>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 3/3] coresight: tpda: add sysfs node to flush specific port
2025-08-27 10:16 ` James Clark
@ 2025-08-27 10:21 ` Jie Gan
0 siblings, 0 replies; 12+ messages in thread
From: Jie Gan @ 2025-08-27 10:21 UTC (permalink / raw)
To: James Clark, Jie Gan
Cc: coresight, linux-arm-kernel, linux-kernel, linux-arm-msm,
Suzuki K Poulose, Mike Leach, Alexander Shishkin, Tingwei Zhang
On 8/27/2025 6:16 PM, James Clark wrote:
>
>
> On 27/08/2025 10:48 am, Jie Gan wrote:
>>
>>
>> On 8/27/2025 5:17 PM, James Clark wrote:
>>>
>>>
>>> On 27/08/2025 5:20 am, Jie Gan wrote:
>>>> From: Tao Zhang <tao.zhang@oss.qualcomm.com>
>>>>
>>>> Setting bit i in the TPDA_FLUSH_CR register initiates a flush request
>>>> for port i, forcing the data to synchronize and be transmitted to the
>>>> sink device.
>>>>
>>>> Signed-off-by: Tao Zhang <tao.zhang@oss.qualcomm.com>
>>>> Co-developed-by: Jie Gan <jie.gan@oss.qualcomm.com>
>>>> Signed-off-by: Jie Gan <jie.gan@oss.qualcomm.com>
>>>> ---
>>>> .../testing/sysfs-bus-coresight-devices-tpda | 7 ++++
>>>> drivers/hwtracing/coresight/coresight-tpda.c | 42 +++++++++++++++
>>>> ++++
>>>> drivers/hwtracing/coresight/coresight-tpda.h | 2 +
>>>> 3 files changed, 51 insertions(+)
>>>>
>>>> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-
>>>> tpda b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
>>>> index fb651aebeb31..2cf2dcfc13c8 100644
>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpda
>>>> @@ -41,3 +41,10 @@ Contact: Jinlong Mao
>>>> <jinlong.mao@oss.qualcomm.com>, Tao Zhang <tao.zhang@oss.qu
>>>> 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.
>>>> +
>>>> +What: /sys/bus/coresight/devices/<tpda-name>/port_flush_req
>>>> +Date: August 2025
>>>> +KernelVersion: 6.17
>>>> +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 bit i to requests a flush operation of
>>>> port i on the TPDA.
>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/
>>>> hwtracing/coresight/coresight-tpda.c
>>>> index 430f76c559f2..8b1fe128881d 100644
>>>> --- a/drivers/hwtracing/coresight/coresight-tpda.c
>>>> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
>>>> @@ -487,6 +487,47 @@ static ssize_t cmbchan_mode_store(struct device
>>>> *dev,
>>>> }
>>>> static DEVICE_ATTR_RW(cmbchan_mode);
>>>> +static ssize_t port_flush_req_show(struct device *dev,
>>>> + struct device_attribute *attr,
>>>> + char *buf)
>>>> +{
>>>> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>> + unsigned long val;
>>>> +
>>>> + if (!drvdata->csdev->refcnt)
>>>> + return -EINVAL;
>>>> +
>>>> + guard(spinlock)(&drvdata->spinlock);
>>>> + CS_UNLOCK(drvdata->base);
>>>> + val = readl_relaxed(drvdata->base + TPDA_FLUSH_CR);
>>>> + CS_LOCK(drvdata->base);
>>>> + return sysfs_emit(buf, "%lx\n", val);
>>>
>>> Still missing the 0x prefix
>>
>> Will re-check rest of the codes and add prefix. Sorry I missed it
>> during the review process.
>>
>>>
>>>> +}
>>>> +
>>>> +static ssize_t port_flush_req_store(struct device *dev,
>>>> + struct device_attribute *attr,
>>>> + const char *buf,
>>>> + size_t size)
>>>> +{
>>>> + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>> + unsigned long val;
>>>> +
>>>> + if (kstrtoul(buf, 0, &val))
>>>> + return -EINVAL;
>>>> +
>>>> + if (!drvdata->csdev->refcnt || !val)
>>>> + return -EINVAL;
>>>> +
>>>> + val |= FIELD_PREP(TPDA_MAX_INPORTS_MASK, val);
>>>
>>> Using FIELD_PREP() now that it's the full width of the register makes
>>> less sense. Especially when there is no corresponding FIELD_FIT()
>>> check, which is fine because everything always fits. But if you
>>> didn't know the mask was the full width you'd wonder if the check is
>>> missing.
>>>
>>> I would just write val directly to TPDA_FLUSH_CR so it's simpler.
>>>
>>> It should also have been val = FIELD_PREP(...)
>>
>> Yeah, it should have been val = FIELD_PREP(...) here... sorry for the
>> mistake here..
>>
>> I was thinking the unsigned long here could be 64 or 32 bits and we
>> only need the value of the lower 32 bits. So that's why I am using val
>> = FIELD_PREP(...) here. We shouldn't write a value greater than
>> UINT32_MAX to the register.
>>
>> Thanks,
>> Jie
>>
>
> writel_relaxed() is always 32 bits though so it is a bit confusing if
> you truncate the user value without an error. Also a reason to use u32
> instead of unsigned long types.
>
> Are you trying to support arm and arm64 with tpda? Or just arm64? For it
> to be consistent you can use kstrtou32(), or use kstrtoull() and then
> FIELD_FIT() to error on truncation. kstrtou32() is probably the cleanest.
Only arm64. Will try kstrtou32() with u32.
Thanks,
Jie
>
>>>
>>>> + guard(spinlock)(&drvdata->spinlock);
>>>> + CS_UNLOCK(drvdata->base);
>>>> + writel_relaxed(val, drvdata->base + TPDA_FLUSH_CR);
>>>> + CS_LOCK(drvdata->base);
>>>> +
>>>> + return size;
>>>> +}
>>>> +static DEVICE_ATTR_RW(port_flush_req);
>>>> +
>>>> static struct attribute *tpda_attrs[] = {
>>>> &dev_attr_trig_async_enable.attr,
>>>> &dev_attr_trig_flag_ts_enable.attr,
>>>> @@ -494,6 +535,7 @@ static struct attribute *tpda_attrs[] = {
>>>> &dev_attr_freq_ts_enable.attr,
>>>> &dev_attr_global_flush_req.attr,
>>>> &dev_attr_cmbchan_mode.attr,
>>>> + &dev_attr_port_flush_req.attr,
>>>> NULL,
>>>> };
>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/
>>>> hwtracing/coresight/coresight-tpda.h
>>>> index 8e1b66115ad1..56d3ad293e46 100644
>>>> --- a/drivers/hwtracing/coresight/coresight-tpda.h
>>>> +++ b/drivers/hwtracing/coresight/coresight-tpda.h
>>>> @@ -10,6 +10,7 @@
>>>> #define TPDA_Pn_CR(n) (0x004 + (n * 4))
>>>> #define TPDA_FPID_CR (0x084)
>>>> #define TPDA_SYNCR (0x08C)
>>>> +#define TPDA_FLUSH_CR (0x090)
>>>> /* Cross trigger FREQ packets timestamp bit */
>>>> #define TPDA_CR_FREQTS BIT(2)
>>>> @@ -35,6 +36,7 @@
>>>> #define TPDA_SYNCR_MAX_COUNTER_VAL (0xFFF)
>>>> #define TPDA_MAX_INPORTS 32
>>>> +#define TPDA_MAX_INPORTS_MASK GENMASK(31, 0)
>>>> /* Bits 6 ~ 12 is for atid value */
>>>> #define TPDA_CR_ATID GENMASK(12, 6)
>>>
>>>
>>
>
>
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2025-08-27 14:08 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-27 4:20 [PATCH v2 0/3] add sysfs nodes to configure TPDA's registers Jie Gan
2025-08-27 4:20 ` [PATCH v2 1/3] coresight: tpda: add sysfs nodes for tpda cross-trigger configuration Jie Gan
2025-08-27 9:06 ` James Clark
2025-08-27 9:18 ` Jie Gan
2025-08-27 4:20 ` [PATCH v2 2/3] coresight: tpda: add logic to configure TPDA_SYNCR register Jie Gan
2025-08-27 9:21 ` James Clark
2025-08-27 9:52 ` Jie Gan
2025-08-27 4:20 ` [PATCH v2 3/3] coresight: tpda: add sysfs node to flush specific port Jie Gan
2025-08-27 9:17 ` James Clark
2025-08-27 9:48 ` Jie Gan
2025-08-27 10:16 ` James Clark
2025-08-27 10:21 ` Jie Gan
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).