diff options
| author | Tao Zhang <tao.zhang@oss.qualcomm.com> | 2025-12-23 18:09:52 +0800 |
|---|---|---|
| committer | Suzuki K Poulose <suzuki.poulose@arm.com> | 2026-01-05 16:53:23 +0000 |
| commit | 33f04ead7c498f29bca875783f13542e5ccd17ac (patch) | |
| tree | 0cb064699a18d84b6e54956bd71876b9f1c2398c /drivers/hwtracing | |
| parent | 8e1c358a3b0e69eb527bb6723366b92e982235c3 (diff) | |
| download | linux-next-33f04ead7c498f29bca875783f13542e5ccd17ac.tar.gz linux-next-33f04ead7c498f29bca875783f13542e5ccd17ac.zip | |
coresight: tpda: add logic to configure TPDA_SYNCR register
The TPDA_SYNC counter tracks the number of bytes transferred from the
aggregator. When this count reaches the value programmed in the
TPDA_SYNCR register, an ASYNC request is triggered, allowing userspace
tools to accurately parse each valid packet.
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 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-3-4c95db608b62@oss.qualcomm.com
Diffstat (limited to 'drivers/hwtracing')
| -rw-r--r-- | drivers/hwtracing/coresight/coresight-tpda.c | 90 | ||||
| -rw-r--r-- | drivers/hwtracing/coresight/coresight-tpda.h | 10 |
2 files changed, 100 insertions, 0 deletions
diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c index d24a9098f1b1..deb5a646a04c 100644 --- a/drivers/hwtracing/coresight/coresight-tpda.c +++ b/drivers/hwtracing/coresight/coresight-tpda.c @@ -163,6 +163,20 @@ static void tpda_enable_pre_port(struct tpda_drvdata *drvdata) */ if (drvdata->trig_flag_ts) writel_relaxed(0x0, drvdata->base + TPDA_FPID_CR); + + /* Initialize with a value of 0 */ + val = 0; + if (drvdata->syncr_mode) + val |= TPDA_SYNCR_MODE_CTRL_MASK; + + if (drvdata->syncr_count > 0 && + drvdata->syncr_count < TPDA_SYNCR_COUNT_MASK) + val |= drvdata->syncr_count; + else + /* Program the count to its MAX value by default */ + val |= TPDA_SYNCR_COUNT_MASK; + + writel_relaxed(val, drvdata->base + TPDA_SYNCR); } static int tpda_enable_port(struct tpda_drvdata *drvdata, int port) @@ -385,8 +399,84 @@ static ssize_t global_flush_req_store(struct device *dev, } static DEVICE_ATTR_RW(global_flush_req); +static ssize_t syncr_mode_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct tpda_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val, syncr_val; + + if (!drvdata->csdev->refcnt) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + syncr_val = readl_relaxed(drvdata->base + TPDA_SYNCR); + val = FIELD_GET(TPDA_SYNCR_MODE_CTRL_MASK, syncr_val); + + return sysfs_emit(buf, "%lu\n", val); +} + +static ssize_t syncr_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); + /* set the mode when first enabling the device */ + drvdata->syncr_mode = !!val; + + return size; +} +static DEVICE_ATTR_RW(syncr_mode); + +static ssize_t syncr_count_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); + val = readl_relaxed(drvdata->base + TPDA_SYNCR); + val &= TPDA_SYNCR_COUNT_MASK; + + return sysfs_emit(buf, "%lu\n", val); +} + +static ssize_t syncr_count_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 (val > TPDA_SYNCR_COUNT_MASK) + return -EINVAL; + + guard(spinlock)(&drvdata->spinlock); + drvdata->syncr_count = val; + + return size; +} +static DEVICE_ATTR_RW(syncr_count); + static struct attribute *tpda_attrs[] = { &dev_attr_global_flush_req.attr, + &dev_attr_syncr_mode.attr, + &dev_attr_syncr_count.attr, 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), diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h index 1cc9253293ec..56d35697303a 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 global (all ports) flush request bit */ #define TPDA_CR_FLREQ BIT(0) @@ -36,6 +37,11 @@ /* Aggregator port DSB data set element size bit */ #define TPDA_Pn_CR_DSBSIZE BIT(8) +/* TPDA_SYNCR count mask */ +#define TPDA_SYNCR_COUNT_MASK GENMASK(11, 0) +/* TPDA_SYNCR mode control bit */ +#define TPDA_SYNCR_MODE_CTRL_MASK GENMASK(12, 12) + #define TPDA_MAX_INPORTS 32 /** @@ -52,6 +58,8 @@ * @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. + * @syncr_mode: Setting the mode for counting packets. + * @syncr_count: Setting the value of the count. */ struct tpda_drvdata { void __iomem *base; @@ -66,6 +74,8 @@ struct tpda_drvdata { bool trig_freq; bool freq_ts; bool cmbchan_mode; + bool syncr_mode; + u32 syncr_count; }; /* Enumerate members of global control register(cr) */ |
