lkml.org 
[lkml]   [2023]   [Mar]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH v1 3/8] coresight-tpdm: Add pattern registers support for CMB data set
Date
Timestamps are requested if the monitor’s CMB data set unit input
data matches the value in the Monitor CMB timestamp pattern and mask
registers (M_CMB_TPR and M_CMB_TPMR) when CMB timestamp enabled
via the timestamp insertion enable register bit(CMB_TIER.PATT_TSENAB).
The pattern match trigger output is achieved via setting values into
the CMB trigger pattern and mask registers (CMB_XPR and CMB_XPMR).
After configuring a pattern through these registers, the TPDM subunit
will assert an output trigger every time it receives new input data
that matches the configured pattern value. Values in a given bit
number of the mask register correspond to the same bit number in
the corresponding pattern register.

Signed-off-by: Mao Jinlong <quic_jinlmao@quicinc.com>
---
.../testing/sysfs-bus-coresight-devices-tpdm | 25 +++
drivers/hwtracing/coresight/coresight-tpdm.c | 169 ++++++++++++++++++
drivers/hwtracing/coresight/coresight-tpdm.h | 19 ++
3 files changed, 213 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
index 89051018dd70..4cc22ad5c485 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -163,3 +163,28 @@ Contact: Jinlong Mao <quic_jinlmao@quicinc.com>
Description: (RW) Read or write CMB data collection mode. Only value 0 and 1 can be written to this node.
Set to 0 is for continuous CMB collection mode. Set to 1 is for trace-on-change CMB
collection mode.
+
+What: /sys/bus/coresight/devices/<tpdm-name>/cmb_patt_mask
+Date: March 2023
+KernelVersion 6.3
+Contact: Jinlong Mao <quic_jinlmao@quicinc.com>
+Description: (RW) Read or write CMB timestamp pattern mask.
+
+What: /sys/bus/coresight/devices/<tpdm-name>/cmb_patt_val
+Date: March 2023
+KernelVersion 6.3
+Contact: Jinlong Mao <quic_jinlmao@quicinc.com>
+Description: (RW) Read or write CMB interface timestamp request pattern match control.
+
+What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_patt_mask
+Date: March 2023
+KernelVersion 6.3
+Contact: Jinlong Mao <quic_jinlmao@quicinc.com>
+Description: (RW) Read or write the value of CMB subunit trigger pattern mask.
+
+What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_patt_val
+Date: March 2023
+KernelVersion 6.3
+Contact: Jinlong Mao <quic_jinlmao@quicinc.com>
+Description: (RW) Read or write the value of CMB subunit trigger pattern match.
+
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index 68244abfc8b9..05341fa7a6b7 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -176,6 +176,19 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
{
u32 val;
+ int i;
+
+ /* Configure pattern registers*/
+ for (i = 0; i < TPDM_CMB_MAX_PATT; i++) {
+ writel_relaxed(drvdata->cmb->patt_val[i],
+ drvdata->base + TPDM_CMB_TPR(i));
+ writel_relaxed(drvdata->cmb->patt_mask[i],
+ drvdata->base + TPDM_CMB_TPMR(i));
+ writel_relaxed(drvdata->cmb->trig_patt_val[i],
+ drvdata->base + TPDM_CMB_XPR(i));
+ writel_relaxed(drvdata->cmb->trig_patt_mask[i],
+ drvdata->base + TPDM_CMB_XPMR(i));
+ }

val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
/*
@@ -883,6 +896,158 @@ static ssize_t cmb_mode_store(struct device *dev,
}
static DEVICE_ATTR_RW(cmb_mode);

+static ssize_t cmb_patt_val_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ ssize_t size = 0;
+ int i;
+
+ spin_lock(&drvdata->spinlock);
+ for (i = 0; i < TPDM_CMB_MAX_PATT; i++) {
+ size += sysfs_emit_at(buf, size,
+ "Index: 0x%x Value: 0x%x\n", i,
+ drvdata->cmb->patt_val[i]);
+ }
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+
+static ssize_t cmb_patt_val_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ unsigned long index, val;
+
+ if (sscanf(buf, "%lx %lx", &index, &val) != 2)
+ return -EINVAL;
+ if (index >= TPDM_CMB_MAX_PATT)
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ drvdata->cmb->patt_val[index] = val;
+ spin_unlock(&drvdata->spinlock);
+
+ return size;
+}
+static DEVICE_ATTR_RW(cmb_patt_val);
+
+static ssize_t cmb_patt_mask_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ ssize_t size = 0;
+ int i;
+
+ spin_lock(&drvdata->spinlock);
+ for (i = 0; i < TPDM_CMB_MAX_PATT; i++) {
+ size += sysfs_emit_at(buf, size,
+ "Index: 0x%x Value: 0x%x\n", i,
+ drvdata->cmb->patt_mask[i]);
+ }
+ spin_unlock(&drvdata->spinlock);
+ return size;
+
+}
+
+static ssize_t cmb_patt_mask_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ unsigned long index, val;
+
+ if (sscanf(buf, "%lx %lx", &index, &val) != 2)
+ return -EINVAL;
+ if (index >= TPDM_CMB_MAX_PATT)
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ drvdata->cmb->patt_mask[index] = val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(cmb_patt_mask);
+
+static ssize_t cmb_trig_patt_val_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ ssize_t size = 0;
+ int i;
+
+ spin_lock(&drvdata->spinlock);
+ for (i = 0; i < TPDM_CMB_MAX_PATT; i++) {
+ size += sysfs_emit_at(buf, size,
+ "Index: 0x%x Value: 0x%x\n", i,
+ drvdata->cmb->trig_patt_val[i]);
+ }
+ spin_unlock(&drvdata->spinlock);
+
+ return size;
+}
+
+static ssize_t cmb_trig_patt_val_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ unsigned long index, val;
+
+ if (sscanf(buf, "%lx %lx", &index, &val) != 2)
+ return -EINVAL;
+ if (index >= TPDM_CMB_MAX_PATT)
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ drvdata->cmb->trig_patt_val[index] = val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(cmb_trig_patt_val);
+
+static ssize_t cmb_trig_patt_mask_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ ssize_t size = 0;
+ int i;
+
+ spin_lock(&drvdata->spinlock);
+ for (i = 0; i < TPDM_CMB_MAX_PATT; i++) {
+ size += sysfs_emit_at(buf, size,
+ "Index: 0x%x Value: 0x%x\n", i,
+ drvdata->cmb->trig_patt_mask[i]);
+ }
+ spin_unlock(&drvdata->spinlock);
+
+ return size;
+}
+
+static ssize_t cmb_trig_patt_mask_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ unsigned long index, val;
+
+ if (sscanf(buf, "%lx %lx", &index, &val) != 2)
+ return -EINVAL;
+ if (index >= TPDM_CMB_MAX_PATT)
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ drvdata->cmb->trig_patt_mask[index] = val;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(cmb_trig_patt_mask);
+
static struct attribute *tpdm_dsb_attrs[] = {
&dev_attr_dsb_mode.attr,
&dev_attr_dsb_edge_ctrl.attr,
@@ -901,6 +1066,10 @@ static struct attribute *tpdm_dsb_attrs[] = {

static struct attribute *tpdm_cmb_attrs[] = {
&dev_attr_cmb_mode.attr,
+ &dev_attr_cmb_patt_val.attr,
+ &dev_attr_cmb_patt_mask.attr,
+ &dev_attr_cmb_trig_patt_val.attr,
+ &dev_attr_cmb_trig_patt_mask.attr,
NULL,
};

diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index d716963bee10..616b6df41e00 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -12,12 +12,23 @@
/* CMB Subunit Registers*/
/*CMB subunit global control register*/
#define TPDM_CMB_CR (0xA00)
+/*CMB subunit timestamp pattern registers*/
+#define TPDM_CMB_TPR(n) (0xA08 + (n * 4))
+/*CMB subunit timestamp pattern mask registers*/
+#define TPDM_CMB_TPMR(n) (0xA10 + (n * 4))
+/*CMB subunit trigger pattern registers*/
+#define TPDM_CMB_XPR(n) (0xA18 + (n * 4))
+/*CMB subunit trigger pattern mask registers*/
+#define TPDM_CMB_XPMR(n) (0xA20 + (n * 4))

/* Enable bit for CMB subunit */
#define TPDM_CMB_CR_ENA BIT(0)
/* Trace collection mode for CMB subunit*/
#define TPDM_CMB_CR_MODE BIT(1)

+/*Patten register number*/
+#define TPDM_CMB_MAX_PATT 2
+
/* DSB Subunit Registers */
#define TPDM_DSB_CR (0x780)
#define TPDM_DSB_TIER (0x784)
@@ -122,9 +133,17 @@ struct dsb_dataset {
/*
* struct cmb_dataset
* @trace_mode: Dataset collection mode
+ * @patt_val: Save value for pattern
+ * @patt_mask: Save value for pattern mask
+ * @trig_patt_val: Save value for trigger pattern
+ * @trig_patt_mask: Save value for trigger pattern mask
*/
struct cmb_dataset {
u32 trace_mode;
+ u32 patt_val[TPDM_CMB_MAX_PATT];
+ u32 patt_mask[TPDM_CMB_MAX_PATT];
+ u32 trig_patt_val[TPDM_CMB_MAX_PATT];
+ u32 trig_patt_mask[TPDM_CMB_MAX_PATT];
};

/**
--
2.39.0
\
 
 \ /
  Last update: 2023-03-29 10:50    [W:0.076 / U:0.204 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site