2023-11-21 02:26:22

by Tao Zhang

[permalink] [raw]
Subject: [PATCH v3 0/8] Add support to configure TPDM CMB subunit

Introduction of TPDM CMB(Continuous Multi Bit) subunit
CMB subunit is responsible for creating a dataset element, and is also
optionally responsible for packing it to fit multiple elements on a
single ATB transfer if possible in the configuration. The TPDM Core
Datapath requests timestamps be stored by the TPDA and then delivering
ATB sized data (depending on ATB width and element size, this could
be smaller or larger than a dataset element) to the ATB Mast FSM.
The CMB makes trace elements in two modes. In ?continuous? mode, every
valid data cycle creates an element. In ?trace on change? mode, when
valid data changes on the bus, a trace element is created. In
continuous mode, all cycles where this condition is true create trace
elements. In trace on change mode, a data element is only when the
previously sampled input is different from the current sampled input.

The CMB subunit must be configured prior to enablement. This series
adds support for TPDM to configure the configure CMB subunit.

Once this series patches are applied properly, the new tpdm nodes for
should be observed at the tpdm path /sys/bus/coresight/devices/tpdm*
which supports CMB subunit.
e.g.
root@qemuarm64:/sys/devices/platform/soc@0/684c000.tpdm/tpdm0# ls -l
-rw-r--r-- 1 root root 4096 Jan 1 00:00 cmb_mode
drwxr-xr-x 2 root root 0 Jan 1 00:00 cmb_msr
drwxr-xr-x 2 root root 0 Jan 1 00:00 cmb_patt
drwxr-xr-x 2 root root 0 Jan 1 00:00 cmb_trig_patt
-rw-r--r-- 1 root root 4096 Jan 1 00:00 cmb_trig_ts
-rw-r--r-- 1 root root 4096 Jan 1 00:00 cmb_ts_all
drwxr-xr-x 2 root root 0 Jan 1 00:00 connections
drwxr-xr-x 2 root root 0 Jan 1 00:00 dsb_edge
drwxr-xr-x 2 root root 0 Jan 1 00:00 dsb_msr
drwxr-xr-x 2 root root 0 Jan 1 00:00 dsb_patt
drwxr-xr-x 2 root root 0 Jan 1 00:00 dsb_trig_patt
-rw-r--r-- 1 root root 4096 Jan 1 00:00 enable_source
--w------- 1 root root 4096 Jan 1 00:00 integration_test
drwxr-xr-x 2 root root 0 Ja? 1 00:00 power
--w------- 1 root root 4096 Jan 1 00:00 reset_dataset
lrwxrwxrwx 1 root root 0 Apr 5 2021 subsystem -> ../../../../../bus/coresight
-rw-r--r-- 1 root root 4096 Apr 5 2021 uevent
-r--r--r-- 1 root root 4096 Jan 1 00:00 waiting_for_supplier

We can use the commands are similar to the below to configure the
TPDMs which support CMB subunit. Enable coresight sink first.
echo 1 > /sys/bus/coresight/devices/tmc_etf0/enable_sink
echo 1 > /sys/bus/coresight/devices/tpdm0/reset_dataset
echo 1 > /sys/bus/coresight/devices/tpdm0/cmb_mode
echo 1 > /sys/bus/coresight/devices/tpdm0/cmb_patt/enable_ts
echo 0xFFFFFFFF > /sys/bus/coresight/devices/tpdm0/cmb_patt/tpmr0
echo 0 > /sys/bus/coresight/devices/tpdm0/cmb_trig_ts
echo 0xFFFFFFFF > /sys/bus/coresight/devices/tpdm0/cmb_trig_patt/xpr1
echo 1 > /sys/bus/coresight/devices/tpdm0/enable_source

codelinaro link:
https://git.codelinaro.org/clo/linux-kernel/coresight/-/commits/tpdm-cmb-v3

Changes in V3:
1. Add 8-bit support to the description in the TPDM devicetree document.
-- Rob Herring
2. Change how the result is produced in "tpdm_read_element_size".
-- James Clark
3. Calling "tpdm_clear_element_size" at the beginning of
"tpda_enable_port".
-- James Clark
4. Use "dsb_esize" and "cmb_esize" to determine whether multiple TPDMs
are detected on a TPDA input port in "tpda_get_element_size".
-- James Clark
5. Modify the judgment logic in "tpda_enable_port".
-- James Clark
6. Add more description of "cmb_mode" to TPDM SysFS document.
-- James Clark

Changes in V2:
1. Optimizate and modify this patch series based on the patch series
"Add support to configure TPDM CMB subunit".
2. Modify the functions that read the element size of DSB/CMB in TPDA driver.

Tao Zhang (8):
dt-bindings: arm: Add support for CMB element size
coresight-tpda: Add support to configure CMB element
coresight-tpdm: Add CMB dataset support
coresight-tpdm: Add support to configure CMB
coresight-tpdm: Add pattern registers support for CMB
coresight-tpdm: Add timestamp control register support for the CMB
dt-bindings: arm: Add support for TPDM CMB MSR register
coresight-tpdm: Add msr register support for CMB

.../testing/sysfs-bus-coresight-devices-tpdm | 87 ++++
.../bindings/arm/qcom,coresight-tpdm.yaml | 38 ++
drivers/hwtracing/coresight/coresight-tpda.c | 117 +++---
drivers/hwtracing/coresight/coresight-tpda.h | 6 +
drivers/hwtracing/coresight/coresight-tpdm.c | 390 +++++++++++++++++-
drivers/hwtracing/coresight/coresight-tpdm.h | 87 ++++
6 files changed, 673 insertions(+), 52 deletions(-)

--
2.17.1


2023-11-21 02:27:06

by Tao Zhang

[permalink] [raw]
Subject: [PATCH v3 5/8] coresight-tpdm: Add pattern registers support for CMB

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.

Reviewed-by: James Clark <[email protected]>
Signed-off-by: Tao Zhang <[email protected]>
Signed-off-by: Jinlong Mao <[email protected]>
---
.../testing/sysfs-bus-coresight-devices-tpdm | 30 +++++++
drivers/hwtracing/coresight/coresight-tpdm.c | 88 ++++++++++++++++++-
drivers/hwtracing/coresight/coresight-tpdm.h | 39 ++++++++
3 files changed, 156 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
index 246c77c109d7..53662ce7c2d0 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -184,3 +184,33 @@ Description: (Write) Set the data collection mode of CMB tpdm. Continuous
Accepts only one of the 2 values - 0 or 1.
0 : Continuous CMB collection mode.
1 : Trace-on-change CMB collection mode.
+
+What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_patt/xpr[0:1]
+Date: March 2023
+KernelVersion 6.7
+Contact: Jinlong Mao (QUIC) <[email protected]>, Tao Zhang (QUIC) <[email protected]>
+Description:
+ (RW) Set/Get the value of the trigger pattern for the CMB
+ subunit TPDM.
+
+What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_patt/xpmr[0:1]
+Date: March 2023
+KernelVersion 6.7
+Contact: Jinlong Mao (QUIC) <[email protected]>, Tao Zhang (QUIC) <[email protected]>
+Description:
+ (RW) Set/Get the mask of the trigger pattern for the CMB
+ subunit TPDM.
+
+What: /sys/bus/coresight/devices/<tpdm-name>/dsb_patt/tpr[0:1]
+Date: March 2023
+KernelVersion 6.7
+Contact: Jinlong Mao (QUIC) <[email protected]>, Tao Zhang (QUIC) <[email protected]>
+Description:
+ (RW) Set/Get the value of the pattern for the CMB subunit TPDM.
+
+What: /sys/bus/coresight/devices/<tpdm-name>/dsb_patt/tpmr[0:1]
+Date: March 2023
+KernelVersion 6.7
+Contact: Jinlong Mao (QUIC) <[email protected]>, Tao Zhang (QUIC) <[email protected]>
+Description:
+ (RW) Set/Get the mask of the pattern for the CMB subunit TPDM.
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index efb376e069a1..894d4309f1c7 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -66,6 +66,26 @@ static ssize_t tpdm_simple_dataset_show(struct device *dev,
return -EINVAL;
return sysfs_emit(buf, "0x%x\n",
drvdata->dsb->msr[tpdm_attr->idx]);
+ case CMB_TRIG_PATT:
+ if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
+ return -EINVAL;
+ return sysfs_emit(buf, "0x%x\n",
+ drvdata->cmb->trig_patt[tpdm_attr->idx]);
+ case CMB_TRIG_PATT_MASK:
+ if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
+ return -EINVAL;
+ return sysfs_emit(buf, "0x%x\n",
+ drvdata->cmb->trig_patt_mask[tpdm_attr->idx]);
+ case CMB_PATT:
+ if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
+ return -EINVAL;
+ return sysfs_emit(buf, "0x%x\n",
+ drvdata->cmb->patt_val[tpdm_attr->idx]);
+ case CMB_PATT_MASK:
+ if (tpdm_attr->idx >= TPDM_CMB_MAX_PATT)
+ return -EINVAL;
+ return sysfs_emit(buf, "0x%x\n",
+ drvdata->cmb->patt_mask[tpdm_attr->idx]);
}
return -EINVAL;
}
@@ -118,6 +138,30 @@ static ssize_t tpdm_simple_dataset_store(struct device *dev,
else
ret = -EINVAL;
break;
+ case CMB_TRIG_PATT:
+ if (tpdm_attr->idx < TPDM_CMB_MAX_PATT)
+ drvdata->cmb->trig_patt[tpdm_attr->idx] = val;
+ else
+ ret = -EINVAL;
+ break;
+ case CMB_TRIG_PATT_MASK:
+ if (tpdm_attr->idx < TPDM_CMB_MAX_PATT)
+ drvdata->cmb->trig_patt_mask[tpdm_attr->idx] = val;
+ else
+ ret = -EINVAL;
+ break;
+ case CMB_PATT:
+ if (tpdm_attr->idx < TPDM_CMB_MAX_PATT)
+ drvdata->cmb->patt_val[tpdm_attr->idx] = val;
+ else
+ ret = -EINVAL;
+ break;
+ case CMB_PATT_MASK:
+ if (tpdm_attr->idx < TPDM_CMB_MAX_PATT)
+ drvdata->cmb->patt_mask[tpdm_attr->idx] = val;
+ else
+ ret = -EINVAL;
+ break;
default:
ret = -EINVAL;
}
@@ -289,7 +333,19 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)

static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
{
- u32 val;
+ u32 val, 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[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);
/*
@@ -904,6 +960,22 @@ static struct attribute *tpdm_dsb_msr_attrs[] = {
NULL,
};

+static struct attribute *tpdm_cmb_trig_patt_attrs[] = {
+ CMB_TRIG_PATT_ATTR(0),
+ CMB_TRIG_PATT_ATTR(1),
+ CMB_TRIG_PATT_MASK_ATTR(0),
+ CMB_TRIG_PATT_MASK_ATTR(1),
+ NULL,
+};
+
+static struct attribute *tpdm_cmb_patt_attrs[] = {
+ CMB_PATT_ATTR(0),
+ CMB_PATT_ATTR(1),
+ CMB_PATT_MASK_ATTR(0),
+ CMB_PATT_MASK_ATTR(1),
+ NULL,
+};
+
static struct attribute *tpdm_dsb_attrs[] = {
&dev_attr_dsb_mode.attr,
&dev_attr_dsb_trig_ts.attr,
@@ -950,6 +1022,18 @@ static struct attribute_group tpdm_cmb_attr_grp = {
.is_visible = tpdm_cmb_is_visible,
};

+static struct attribute_group tpdm_cmb_trig_patt_grp = {
+ .attrs = tpdm_cmb_trig_patt_attrs,
+ .is_visible = tpdm_cmb_is_visible,
+ .name = "cmb_trig_patt",
+};
+
+static struct attribute_group tpdm_cmb_patt_grp = {
+ .attrs = tpdm_cmb_patt_attrs,
+ .is_visible = tpdm_cmb_is_visible,
+ .name = "cmb_patt",
+};
+
static const struct attribute_group *tpdm_attr_grps[] = {
&tpdm_attr_grp,
&tpdm_dsb_attr_grp,
@@ -958,6 +1042,8 @@ static const struct attribute_group *tpdm_attr_grps[] = {
&tpdm_dsb_patt_grp,
&tpdm_dsb_msr_grp,
&tpdm_cmb_attr_grp,
+ &tpdm_cmb_trig_patt_grp,
+ &tpdm_cmb_patt_grp,
NULL,
};

diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index c6b36d2fe45a..e90d008c1cb2 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -11,12 +11,23 @@

/* CMB Subunit Registers */
#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)
@@ -151,6 +162,22 @@
tpdm_simple_dataset_rw(msr##nr, \
DSB_MSR, nr)

+#define CMB_TRIG_PATT_ATTR(nr) \
+ tpdm_simple_dataset_rw(xpr##nr, \
+ CMB_TRIG_PATT, nr)
+
+#define CMB_TRIG_PATT_MASK_ATTR(nr) \
+ tpdm_simple_dataset_rw(xpmr##nr, \
+ CMB_TRIG_PATT_MASK, nr)
+
+#define CMB_PATT_ATTR(nr) \
+ tpdm_simple_dataset_rw(tpr##nr, \
+ CMB_PATT, nr)
+
+#define CMB_PATT_MASK_ATTR(nr) \
+ tpdm_simple_dataset_rw(tpmr##nr, \
+ CMB_PATT_MASK, nr)
+
/**
* struct dsb_dataset - specifics associated to dsb dataset
* @mode: DSB programming mode
@@ -186,9 +213,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: 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[TPDM_CMB_MAX_PATT];
+ u32 trig_patt_mask[TPDM_CMB_MAX_PATT];
};

/**
@@ -225,6 +260,10 @@ enum dataset_mem {
DSB_PATT,
DSB_PATT_MASK,
DSB_MSR,
+ CMB_TRIG_PATT,
+ CMB_TRIG_PATT_MASK,
+ CMB_PATT,
+ CMB_PATT_MASK
};

/**
--
2.17.1

2023-11-21 02:27:08

by Tao Zhang

[permalink] [raw]
Subject: [PATCH v3 7/8] dt-bindings: arm: Add support for TPDM CMB MSR register

Add property "qcom,cmb_msr_num" to support CMB MSR(mux select register)
for TPDM. It specifies the number of CMB MSR registers supported by
the TDPM.

Signed-off-by: Tao Zhang <[email protected]>
Signed-off-by: Mao Jinlong <[email protected]>
---
.../devicetree/bindings/arm/qcom,coresight-tpdm.yaml | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
index 0d9fe01a8b15..e9e2d162a621 100644
--- a/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
+++ b/Documentation/devicetree/bindings/arm/qcom,coresight-tpdm.yaml
@@ -70,6 +70,15 @@ properties:
minimum: 0
maximum: 32

+ qcom,cmb-msrs-num:
+ description:
+ Specifies the number of CMB MSR(mux select register) registers supported
+ by the monitor. If this property is not configured or set to 0, it means
+ this TPDM doesn't support CMB MSR.
+ $ref: /schemas/types.yaml#/definitions/uint32
+ minimum: 0
+ maximum: 32
+
clocks:
maxItems: 1

@@ -125,6 +134,7 @@ examples:
reg-names = "tpdm-base";

qcom,cmb-element-size = /bits/ 8 <64>;
+ qcom,cmb-msrs-num = <32>;

clocks = <&aoss_qmp>;
clock-names = "apb_pclk";
--
2.17.1

2023-11-21 02:28:09

by Tao Zhang

[permalink] [raw]
Subject: [PATCH v3 4/8] coresight-tpdm: Add support to configure CMB

TPDM CMB subunits support two forms of CMB data set element creation:
continuous and trace-on-change collection mode. Continuous change
creates CMB data set elements on every CMBCLK edge. Trace-on-change
creates CMB data set elements only when a new data set element differs
in value from the previous element in a CMB data set. Set CMB_CR.MODE
to 0 for continuous CMB collection mode. Set CMB_CR.MODE to 1 for
trace-on-change CMB collection mode

Reviewed-by: James Clark <[email protected]>
Signed-off-by: Tao Zhang <[email protected]>
Signed-off-by: Jinlong Mao <[email protected]>
---
.../testing/sysfs-bus-coresight-devices-tpdm | 14 ++++
drivers/hwtracing/coresight/coresight-tpdm.c | 71 +++++++++++++++++++
drivers/hwtracing/coresight/coresight-tpdm.h | 12 ++++
3 files changed, 97 insertions(+)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
index f07218e78843..246c77c109d7 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -170,3 +170,17 @@ Contact: Jinlong Mao (QUIC) <[email protected]>, Tao Zhang (QUIC) <quic_t
Description:
(RW) Set/Get the MSR(mux select register) for the DSB subunit
TPDM.
+
+What: /sys/bus/coresight/devices/<tpdm-name>/cmb_mode
+Date: March 2023
+KernelVersion 6.7
+Contact: Jinlong Mao (QUIC) <[email protected]>, Tao Zhang (QUIC) <[email protected]>
+Description: (Write) Set the data collection mode of CMB tpdm. Continuous
+ change creates CMB data set elements on every CMBCLK edge.
+ Trace-on-change creates CMB data set elements only when a new
+ data set element differs in value from the previous element
+ in a CMB data set.
+
+ Accepts only one of the 2 values - 0 or 1.
+ 0 : Continuous CMB collection mode.
+ 1 : Trace-on-change CMB collection mode.
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index c8bb38822e08..efb376e069a1 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -148,6 +148,18 @@ static umode_t tpdm_dsb_is_visible(struct kobject *kobj,
return 0;
}

+static umode_t tpdm_cmb_is_visible(struct kobject *kobj,
+ struct attribute *attr, int n)
+{
+ struct device *dev = kobj_to_dev(kobj);
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ if (drvdata && tpdm_has_cmb_dataset(drvdata))
+ return attr->mode;
+
+ return 0;
+}
+
static umode_t tpdm_dsb_msr_is_visible(struct kobject *kobj,
struct attribute *attr, int n)
{
@@ -172,6 +184,9 @@ static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata)
drvdata->dsb->trig_ts = true;
drvdata->dsb->trig_type = false;
}
+
+ if (tpdm_has_cmb_dataset(drvdata))
+ memset(drvdata->cmb, 0, sizeof(struct cmb_dataset));
}

static void set_dsb_mode(struct tpdm_drvdata *drvdata, u32 *val)
@@ -277,6 +292,16 @@ static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
u32 val;

val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
+ /*
+ * Set to 0 for continuous CMB collection mode,
+ * 1 for trace-on-change CMB collection mode.
+ */
+ if (drvdata->cmb->trace_mode)
+ val |= TPDM_CMB_CR_MODE;
+ else
+ val &= ~TPDM_CMB_CR_MODE;
+
+ /* Set the enable bit of CMB control register to 1 */
val |= TPDM_CMB_CR_ENA;

/* Set the enable bit of CMB control register to 1 */
@@ -397,6 +422,12 @@ static int tpdm_datasets_setup(struct tpdm_drvdata *drvdata)
if (!drvdata->dsb)
return -ENOMEM;
}
+ if (tpdm_has_cmb_dataset(drvdata) && (!drvdata->cmb)) {
+ drvdata->cmb = devm_kzalloc(drvdata->dev,
+ sizeof(*drvdata->cmb), GFP_KERNEL);
+ if (!drvdata->cmb)
+ return -ENOMEM;
+ }
tpdm_reset_datasets(drvdata);

return 0;
@@ -735,6 +766,35 @@ static ssize_t dsb_trig_ts_store(struct device *dev,
}
static DEVICE_ATTR_RW(dsb_trig_ts);

+static ssize_t cmb_mode_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ return sysfs_emit(buf, "%x\n",
+ drvdata->cmb->trace_mode);
+
+}
+
+static ssize_t cmb_mode_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 trace_mode;
+
+ if ((kstrtoul(buf, 0, &trace_mode)) || (trace_mode & ~1UL))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ drvdata->cmb->trace_mode = trace_mode;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(cmb_mode);
+
static struct attribute *tpdm_dsb_edge_attrs[] = {
&dev_attr_ctrl_idx.attr,
&dev_attr_ctrl_val.attr,
@@ -851,6 +911,11 @@ static struct attribute *tpdm_dsb_attrs[] = {
NULL,
};

+static struct attribute *tpdm_cmb_attrs[] = {
+ &dev_attr_cmb_mode.attr,
+ NULL,
+};
+
static struct attribute_group tpdm_dsb_attr_grp = {
.attrs = tpdm_dsb_attrs,
.is_visible = tpdm_dsb_is_visible,
@@ -880,6 +945,11 @@ static struct attribute_group tpdm_dsb_msr_grp = {
.name = "dsb_msr",
};

+static struct attribute_group tpdm_cmb_attr_grp = {
+ .attrs = tpdm_cmb_attrs,
+ .is_visible = tpdm_cmb_is_visible,
+};
+
static const struct attribute_group *tpdm_attr_grps[] = {
&tpdm_attr_grp,
&tpdm_dsb_attr_grp,
@@ -887,6 +957,7 @@ static const struct attribute_group *tpdm_attr_grps[] = {
&tpdm_dsb_trig_patt_grp,
&tpdm_dsb_patt_grp,
&tpdm_dsb_msr_grp,
+ &tpdm_cmb_attr_grp,
NULL,
};

diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index 0098c58dfdd6..c6b36d2fe45a 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -14,6 +14,8 @@

/* 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)

/* DSB Subunit Registers */
#define TPDM_DSB_CR (0x780)
@@ -181,6 +183,14 @@ struct dsb_dataset {
bool trig_type;
};

+/**
+ * struct cmb_dataset
+ * @trace_mode: Dataset collection mode
+ */
+struct cmb_dataset {
+ u32 trace_mode;
+};
+
/**
* struct tpdm_drvdata - specifics associated to an TPDM component
* @base: memory mapped base address for this component.
@@ -190,6 +200,7 @@ struct dsb_dataset {
* @enable: enable status of the component.
* @datasets: The datasets types present of the TPDM.
* @dsb Specifics associated to TPDM DSB.
+ * @cmb Specifics associated to TPDM CMB.
* @dsb_msr_num Number of MSR supported by DSB TPDM
*/

@@ -201,6 +212,7 @@ struct tpdm_drvdata {
bool enable;
unsigned long datasets;
struct dsb_dataset *dsb;
+ struct cmb_dataset *cmb;
u32 dsb_msr_num;
};

--
2.17.1

2023-11-21 02:28:09

by Tao Zhang

[permalink] [raw]
Subject: [PATCH v3 2/8] coresight-tpda: Add support to configure CMB element

Read the CMB element size from the device tree. Set the register
bit that controls the CMB element size of the corresponding port.

Signed-off-by: Tao Zhang <[email protected]>
Signed-off-by: Mao Jinlong <[email protected]>
---
drivers/hwtracing/coresight/coresight-tpda.c | 117 +++++++++++--------
drivers/hwtracing/coresight/coresight-tpda.h | 6 +
2 files changed, 74 insertions(+), 49 deletions(-)

diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
index 5f82737c37bb..e3762f38abb3 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.c
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -28,24 +28,54 @@ static bool coresight_device_is_tpdm(struct coresight_device *csdev)
CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM);
}

+static void tpdm_clear_element_size(struct coresight_device *csdev)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+ if (drvdata->dsb_esize)
+ drvdata->dsb_esize = 0;
+ if (drvdata->cmb_esize)
+ drvdata->cmb_esize = 0;
+}
+
+static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32 *val)
+{
+
+ if (drvdata->dsb_esize == 64)
+ *val |= TPDA_Pn_CR_DSBSIZE;
+ else if (drvdata->dsb_esize == 32)
+ *val &= ~TPDA_Pn_CR_DSBSIZE;
+
+ if (drvdata->cmb_esize == 64)
+ *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2);
+ else if (drvdata->cmb_esize == 32)
+ *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1);
+ else if (drvdata->cmb_esize == 8)
+ *val &= ~TPDA_Pn_CR_CMBSIZE;
+}
+
/*
- * Read the DSB element size from the TPDM device
+ * Read the element size from the TPDM device
* Returns
- * The dsb element size read from the devicetree if available.
+ * The element size read from the devicetree if available.
* 0 - Otherwise, with a warning once.
*/
-static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
+static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
+ struct coresight_device *csdev)
{
- int rc = 0;
- u8 size = 0;
-
- rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
- "qcom,dsb-element-size", &size);
+ int rc = -EINVAL;
+
+ if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
+ "qcom,dsb-element-size", &drvdata->dsb_esize))
+ rc = 0;
+ if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
+ "qcom,cmb-element-size", &drvdata->cmb_esize))
+ rc = 0;
if (rc)
dev_warn_once(&csdev->dev,
- "Failed to read TPDM DSB Element size: %d\n", rc);
+ "Failed to read TPDM Element size: %d\n", rc);

- return size;
+ return rc;
}

/*
@@ -56,11 +86,12 @@ static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
* Parameter "inport" is used to pass in the input port number
* of TPDA, and it is set to -1 in the recursize call.
*/
-static int tpda_get_element_size(struct coresight_device *csdev,
+static int tpda_get_element_size(struct tpda_drvdata *drvdata,
+ struct coresight_device *csdev,
int inport)
{
- int dsb_size = -ENOENT;
- int i, size;
+ int rc = 0;
+ int i;
struct coresight_device *in;

for (i = 0; i < csdev->pdata->nr_inconns; i++) {
@@ -74,25 +105,21 @@ static int tpda_get_element_size(struct coresight_device *csdev,
continue;

if (coresight_device_is_tpdm(in)) {
- size = tpdm_read_dsb_element_size(in);
+ if ((drvdata->dsb_esize) || (drvdata->cmb_esize))
+ return -EEXIST;
+ rc = tpdm_read_element_size(drvdata, in);
+ if (rc)
+ return rc;
} else {
/* Recurse down the path */
- size = tpda_get_element_size(in, -1);
- }
-
- if (size < 0)
- return size;
-
- if (dsb_size < 0) {
- /* Found a size, save it. */
- dsb_size = size;
- } else {
- /* Found duplicate TPDMs */
- return -EEXIST;
+ rc = tpda_get_element_size(drvdata, in, -1);
+ if (rc)
+ return rc;
}
}

- return dsb_size;
+
+ return rc;
}

/* Settings pre enabling port control register */
@@ -109,7 +136,7 @@ static void tpda_enable_pre_port(struct tpda_drvdata *drvdata)
static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
{
u32 val;
- int size;
+ int rc;

val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
/*
@@ -117,29 +144,21 @@ static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
* Set the bit to 0 if the size is 32
* Set the bit to 1 if the size is 64
*/
- size = tpda_get_element_size(drvdata->csdev, port);
- switch (size) {
- case 32:
- val &= ~TPDA_Pn_CR_DSBSIZE;
- break;
- case 64:
- val |= TPDA_Pn_CR_DSBSIZE;
- break;
- case 0:
- return -EEXIST;
- case -EEXIST:
+ tpdm_clear_element_size(drvdata->csdev);
+ rc = tpda_get_element_size(drvdata, drvdata->csdev, port);
+ if (!rc && ((drvdata->dsb_esize) || (drvdata->cmb_esize))) {
+ tpda_set_element_size(drvdata, &val);
+ /* Enable the port */
+ val |= TPDA_Pn_CR_ENA;
+ writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
+ } else if (rc == -EEXIST)
dev_warn_once(&drvdata->csdev->dev,
- "Detected multiple TPDMs on port %d", -EEXIST);
- return -EEXIST;
- default:
- return -EINVAL;
- }
-
- /* Enable the port */
- val |= TPDA_Pn_CR_ENA;
- writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
+ "Detected multiple TPDMs on port %d", -EEXIST);
+ else
+ dev_warn_once(&drvdata->csdev->dev,
+ "Didn't find TPDM elem size");

- return 0;
+ return rc;
}

static int __tpda_enable(struct tpda_drvdata *drvdata, int port)
diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h
index b3b38fd41b64..29164fd9711f 100644
--- a/drivers/hwtracing/coresight/coresight-tpda.h
+++ b/drivers/hwtracing/coresight/coresight-tpda.h
@@ -10,6 +10,8 @@
#define TPDA_Pn_CR(n) (0x004 + (n * 4))
/* Aggregator port enable bit */
#define TPDA_Pn_CR_ENA BIT(0)
+/* Aggregator port CMB data set element size bit */
+#define TPDA_Pn_CR_CMBSIZE GENMASK(7, 6)
/* Aggregator port DSB data set element size bit */
#define TPDA_Pn_CR_DSBSIZE BIT(8)

@@ -25,6 +27,8 @@
* @csdev: component vitals needed by the framework.
* @spinlock: lock for the drvdata value.
* @enable: enable status of the component.
+ * @dsb_esize Record the DSB element size.
+ * @cmb_esize Record the CMB element size.
*/
struct tpda_drvdata {
void __iomem *base;
@@ -32,6 +36,8 @@ struct tpda_drvdata {
struct coresight_device *csdev;
spinlock_t spinlock;
u8 atid;
+ u8 dsb_esize;
+ u8 cmb_esize;
};

#endif /* _CORESIGHT_CORESIGHT_TPDA_H */
--
2.17.1

2023-11-21 02:28:57

by Tao Zhang

[permalink] [raw]
Subject: [PATCH v3 6/8] coresight-tpdm: Add timestamp control register support for the CMB

CMB_TIER register is CMB subunit timestamp insertion enable register.
Bit 0 is PATT_TSENAB bit. Set this bit to 1 to request a timestamp
following a CMB interface pattern match. Bit 1 is XTRIG_TSENAB bit.
Set this bit to 1 to request a timestamp following a CMB CTI timestamp
request. Bit 2 is TS_ALL bit. Set this bit to 1 to request timestamp
for all packets.

Reviewed-by: James Clark <[email protected]>
Signed-off-by: Tao Zhang <[email protected]>
Signed-off-by: Jinlong Mao <[email protected]>
---
.../testing/sysfs-bus-coresight-devices-tpdm | 35 ++++++
drivers/hwtracing/coresight/coresight-tpdm.c | 116 +++++++++++++++++-
drivers/hwtracing/coresight/coresight-tpdm.h | 14 +++
3 files changed, 162 insertions(+), 3 deletions(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
index 53662ce7c2d0..e0b77107be13 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -214,3 +214,38 @@ KernelVersion 6.7
Contact: Jinlong Mao (QUIC) <[email protected]>, Tao Zhang (QUIC) <[email protected]>
Description:
(RW) Set/Get the mask of the pattern for the CMB subunit TPDM.
+
+What: /sys/bus/coresight/devices/<tpdm-name>/cmb_patt/enable_ts
+Date: September 2023
+KernelVersion 6.7
+Contact: Jinlong Mao (QUIC) <[email protected]>, Tao Zhang (QUIC) <[email protected]>
+Description:
+ (Write) Set the pattern timestamp of CMB tpdm. Read
+ the pattern timestamp of CMB tpdm.
+
+ Accepts only one of the 2 values - 0 or 1.
+ 0 : Disable CMB pattern timestamp.
+ 1 : Enable CMB pattern timestamp.
+
+What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_ts
+Date: September 2023
+KernelVersion 6.7
+Contact: Jinlong Mao (QUIC) <[email protected]>, Tao Zhang (QUIC) <[email protected]>
+Description:
+ (RW) Set/Get the trigger timestamp of the CMB for tpdm.
+
+ Accepts only one of the 2 values - 0 or 1.
+ 0 : Set the CMB trigger type to false
+ 1 : Set the CMB trigger type to true
+
+What: /sys/bus/coresight/devices/<tpdm-name>/cmb_ts_all
+Date: September 2023
+KernelVersion 6.7
+Contact: Jinlong Mao (QUIC) <[email protected]>, Tao Zhang (QUIC) <[email protected]>
+Description:
+ (RW) Read or write the status of timestamp upon all interface.
+ Only value 0 and 1 can be written to this node. Set this node to 1 to requeset
+ timestamp to all trace packet.
+ Accepts only one of the 2 values - 0 or 1.
+ 0 : Disable the timestamp of all trace packets.
+ 1 : Enable the timestamp of all trace packets.
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index 894d4309f1c7..f6cda5616e84 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -331,6 +331,36 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
}

+static void set_cmb_tier(struct tpdm_drvdata *drvdata)
+{
+ u32 val;
+
+ val = readl_relaxed(drvdata->base + TPDM_CMB_TIER);
+
+ /* Clear all relevant fields */
+ val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL |
+ TPDM_CMB_TIER_XTRIG_TSENAB);
+
+ /* Set pattern timestamp type and enablement */
+ if (drvdata->cmb->patt_ts)
+ val |= TPDM_CMB_TIER_PATT_TSENAB;
+ else
+ val &= ~TPDM_CMB_TIER_PATT_TSENAB;
+
+ /* Set trigger timestamp */
+ if (drvdata->cmb->trig_ts)
+ val |= TPDM_CMB_TIER_XTRIG_TSENAB;
+ else
+ val &= ~TPDM_CMB_TIER_XTRIG_TSENAB;
+
+ /* Set all timestamp enablement*/
+ if (drvdata->cmb->ts_all)
+ val |= TPDM_CMB_TIER_TS_ALL;
+ else
+ val &= ~TPDM_CMB_TIER_TS_ALL;
+ writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
+}
+
static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
{
u32 val, i;
@@ -347,6 +377,8 @@ static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
drvdata->base + TPDM_CMB_XPMR(i));
}

+ set_cmb_tier(drvdata);
+
val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
/*
* Set to 0 for continuous CMB collection mode,
@@ -695,9 +727,17 @@ static ssize_t enable_ts_show(struct device *dev,
char *buf)
{
struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+ ssize_t size = 0;

- return sysfs_emit(buf, "%u\n",
- (unsigned int)drvdata->dsb->patt_ts);
+ if (tpdm_has_dsb_dataset(drvdata))
+ size = sysfs_emit(buf, "%u\n",
+ (unsigned int)drvdata->dsb->patt_ts);
+
+ if (tpdm_has_cmb_dataset(drvdata))
+ size = sysfs_emit(buf, "%u\n",
+ (unsigned int)drvdata->cmb->patt_ts);
+
+ return size;
}

/*
@@ -715,8 +755,13 @@ static ssize_t enable_ts_store(struct device *dev,
return -EINVAL;

spin_lock(&drvdata->spinlock);
- drvdata->dsb->patt_ts = !!val;
+ if (tpdm_has_dsb_dataset(drvdata))
+ drvdata->dsb->patt_ts = !!val;
+
+ if (tpdm_has_cmb_dataset(drvdata))
+ drvdata->cmb->patt_ts = !!val;
spin_unlock(&drvdata->spinlock);
+
return size;
}
static DEVICE_ATTR_RW(enable_ts);
@@ -851,6 +896,68 @@ static ssize_t cmb_mode_store(struct device *dev,
}
static DEVICE_ATTR_RW(cmb_mode);

+static ssize_t cmb_ts_all_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ return sysfs_emit(buf, "%u\n",
+ (unsigned int)drvdata->cmb->ts_all);
+}
+
+static ssize_t cmb_ts_all_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 val;
+
+ if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ if (val)
+ drvdata->cmb->ts_all = true;
+ else
+ drvdata->cmb->ts_all = false;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(cmb_ts_all);
+
+static ssize_t cmb_trig_ts_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ return sysfs_emit(buf, "%u\n",
+ (unsigned int)drvdata->cmb->trig_ts);
+}
+
+static ssize_t cmb_trig_ts_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 val;
+
+ if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
+ return -EINVAL;
+
+ spin_lock(&drvdata->spinlock);
+ if (val)
+ drvdata->cmb->trig_ts = true;
+ else
+ drvdata->cmb->trig_ts = false;
+ spin_unlock(&drvdata->spinlock);
+ return size;
+}
+static DEVICE_ATTR_RW(cmb_trig_ts);
+
static struct attribute *tpdm_dsb_edge_attrs[] = {
&dev_attr_ctrl_idx.attr,
&dev_attr_ctrl_val.attr,
@@ -973,6 +1080,7 @@ static struct attribute *tpdm_cmb_patt_attrs[] = {
CMB_PATT_ATTR(1),
CMB_PATT_MASK_ATTR(0),
CMB_PATT_MASK_ATTR(1),
+ &dev_attr_enable_ts.attr,
NULL,
};

@@ -985,6 +1093,8 @@ static struct attribute *tpdm_dsb_attrs[] = {

static struct attribute *tpdm_cmb_attrs[] = {
&dev_attr_cmb_mode.attr,
+ &dev_attr_cmb_ts_all.attr,
+ &dev_attr_cmb_trig_ts.attr,
NULL,
};

diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index e90d008c1cb2..65b7ca6c4077 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -11,6 +11,8 @@

/* CMB Subunit Registers */
#define TPDM_CMB_CR (0xA00)
+/*CMB subunit timestamp insertion enable register*/
+#define TPDM_CMB_TIER (0xA04)
/*CMB subunit timestamp pattern registers*/
#define TPDM_CMB_TPR(n) (0xA08 + (n * 4))
/*CMB subunit timestamp pattern mask registers*/
@@ -24,6 +26,12 @@
#define TPDM_CMB_CR_ENA BIT(0)
/* Trace collection mode for CMB subunit */
#define TPDM_CMB_CR_MODE BIT(1)
+/* Timestamp control for pattern match */
+#define TPDM_CMB_TIER_PATT_TSENAB BIT(0)
+/* CMB CTI timestamp request */
+#define TPDM_CMB_TIER_XTRIG_TSENAB BIT(1)
+/* For timestamp fo all trace */
+#define TPDM_CMB_TIER_TS_ALL BIT(2)

/*Patten register number*/
#define TPDM_CMB_MAX_PATT 2
@@ -217,6 +225,9 @@ struct dsb_dataset {
* @patt_mask: Save value for pattern mask
* @trig_patt: Save value for trigger pattern
* @trig_patt_mask: Save value for trigger pattern mask
+ * @patt_ts: Indicates if pattern match for timestamp is enabled.
+ * @trig_ts: Indicates if CTI trigger for timestamp is enabled.
+ * @ts_all: Indicates if timestamp is enabled for all packets.
*/
struct cmb_dataset {
u32 trace_mode;
@@ -224,6 +235,9 @@ struct cmb_dataset {
u32 patt_mask[TPDM_CMB_MAX_PATT];
u32 trig_patt[TPDM_CMB_MAX_PATT];
u32 trig_patt_mask[TPDM_CMB_MAX_PATT];
+ bool patt_ts;
+ bool trig_ts;
+ bool ts_all;
};

/**
--
2.17.1

2023-11-21 02:28:58

by Tao Zhang

[permalink] [raw]
Subject: [PATCH v3 8/8] coresight-tpdm: Add msr register support for CMB

Add the nodes for CMB subunit MSR(mux select register) support.
CMB MSRs(mux select registers) is to separate mux,arbitration,
,interleaving,data packing control from stream filtering control.

Reviewed-by: James Clark <[email protected]>
Signed-off-by: Tao Zhang <[email protected]>
Signed-off-by: Mao Jinlong <[email protected]>
---
.../testing/sysfs-bus-coresight-devices-tpdm | 8 ++
drivers/hwtracing/coresight/coresight-tpdm.c | 86 +++++++++++++++++++
drivers/hwtracing/coresight/coresight-tpdm.h | 16 +++-
3 files changed, 109 insertions(+), 1 deletion(-)

diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
index e0b77107be13..914f3fd81525 100644
--- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -249,3 +249,11 @@ Description:
Accepts only one of the 2 values - 0 or 1.
0 : Disable the timestamp of all trace packets.
1 : Enable the timestamp of all trace packets.
+
+What: /sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
+Date: September 2023
+KernelVersion 6.7
+Contact: Jinlong Mao (QUIC) <[email protected]>, Tao Zhang (QUIC) <[email protected]>
+Description:
+ (RW) Set/Get the MSR(mux select register) for the CMB subunit
+ TPDM.
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index f6cda5616e84..7e331ea436cc 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -86,6 +86,11 @@ static ssize_t tpdm_simple_dataset_show(struct device *dev,
return -EINVAL;
return sysfs_emit(buf, "0x%x\n",
drvdata->cmb->patt_mask[tpdm_attr->idx]);
+ case CMB_MSR:
+ if (tpdm_attr->idx >= drvdata->cmb_msr_num)
+ return -EINVAL;
+ return sysfs_emit(buf, "0x%x\n",
+ drvdata->cmb->msr[tpdm_attr->idx]);
}
return -EINVAL;
}
@@ -162,6 +167,12 @@ static ssize_t tpdm_simple_dataset_store(struct device *dev,
else
ret = -EINVAL;
break;
+ case CMB_MSR:
+ if (tpdm_attr->idx < drvdata->cmb_msr_num)
+ drvdata->cmb->msr[tpdm_attr->idx] = val;
+ else
+ ret = -EINVAL;
+ break;
default:
ret = -EINVAL;
}
@@ -220,6 +231,23 @@ static umode_t tpdm_dsb_msr_is_visible(struct kobject *kobj,
return 0;
}

+static umode_t tpdm_cmb_msr_is_visible(struct kobject *kobj,
+ struct attribute *attr, int n)
+{
+ struct device *dev = kobj_to_dev(kobj);
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ struct device_attribute *dev_attr =
+ container_of(attr, struct device_attribute, attr);
+ struct tpdm_dataset_attribute *tpdm_attr =
+ container_of(dev_attr, struct tpdm_dataset_attribute, attr);
+
+ if (tpdm_attr->idx < drvdata->cmb_msr_num)
+ return attr->mode;
+
+ return 0;
+}
+
static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata)
{
if (tpdm_has_dsb_dataset(drvdata)) {
@@ -361,6 +389,15 @@ static void set_cmb_tier(struct tpdm_drvdata *drvdata)
writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
}

+static void set_cmb_msr(struct tpdm_drvdata *drvdata)
+{
+ int i;
+
+ for (i = 0; i < drvdata->cmb_msr_num; i++)
+ writel_relaxed(drvdata->cmb->msr[i],
+ drvdata->base + TPDM_CMB_MSR(i));
+}
+
static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
{
u32 val, i;
@@ -379,6 +416,8 @@ static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)

set_cmb_tier(drvdata);

+ set_cmb_msr(drvdata);
+
val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
/*
* Set to 0 for continuous CMB collection mode,
@@ -1084,6 +1123,42 @@ static struct attribute *tpdm_cmb_patt_attrs[] = {
NULL,
};

+static struct attribute *tpdm_cmb_msr_attrs[] = {
+ CMB_MSR_ATTR(0),
+ CMB_MSR_ATTR(1),
+ CMB_MSR_ATTR(2),
+ CMB_MSR_ATTR(3),
+ CMB_MSR_ATTR(4),
+ CMB_MSR_ATTR(5),
+ CMB_MSR_ATTR(6),
+ CMB_MSR_ATTR(7),
+ CMB_MSR_ATTR(8),
+ CMB_MSR_ATTR(9),
+ CMB_MSR_ATTR(10),
+ CMB_MSR_ATTR(11),
+ CMB_MSR_ATTR(12),
+ CMB_MSR_ATTR(13),
+ CMB_MSR_ATTR(14),
+ CMB_MSR_ATTR(15),
+ CMB_MSR_ATTR(16),
+ CMB_MSR_ATTR(17),
+ CMB_MSR_ATTR(18),
+ CMB_MSR_ATTR(19),
+ CMB_MSR_ATTR(20),
+ CMB_MSR_ATTR(21),
+ CMB_MSR_ATTR(22),
+ CMB_MSR_ATTR(23),
+ CMB_MSR_ATTR(24),
+ CMB_MSR_ATTR(25),
+ CMB_MSR_ATTR(26),
+ CMB_MSR_ATTR(27),
+ CMB_MSR_ATTR(28),
+ CMB_MSR_ATTR(29),
+ CMB_MSR_ATTR(30),
+ CMB_MSR_ATTR(31),
+ NULL,
+};
+
static struct attribute *tpdm_dsb_attrs[] = {
&dev_attr_dsb_mode.attr,
&dev_attr_dsb_trig_ts.attr,
@@ -1144,6 +1219,12 @@ static struct attribute_group tpdm_cmb_patt_grp = {
.name = "cmb_patt",
};

+static struct attribute_group tpdm_cmb_msr_grp = {
+ .attrs = tpdm_cmb_msr_attrs,
+ .is_visible = tpdm_cmb_msr_is_visible,
+ .name = "cmb_msr",
+};
+
static const struct attribute_group *tpdm_attr_grps[] = {
&tpdm_attr_grp,
&tpdm_dsb_attr_grp,
@@ -1154,6 +1235,7 @@ static const struct attribute_group *tpdm_attr_grps[] = {
&tpdm_cmb_attr_grp,
&tpdm_cmb_trig_patt_grp,
&tpdm_cmb_patt_grp,
+ &tpdm_cmb_msr_grp,
NULL,
};

@@ -1192,6 +1274,10 @@ static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
of_property_read_u32(drvdata->dev->of_node,
"qcom,dsb-msrs-num", &drvdata->dsb_msr_num);

+ if (drvdata && tpdm_has_cmb_dataset(drvdata))
+ of_property_read_u32(drvdata->dev->of_node,
+ "qcom,cmb-msrs-num", &drvdata->cmb_msr_num);
+
/* Set up coresight component description */
desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
if (!desc.name)
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index 65b7ca6c4077..255104d024ab 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -21,6 +21,8 @@
#define TPDM_CMB_XPR(n) (0xA18 + (n * 4))
/*CMB subunit trigger pattern mask registers*/
#define TPDM_CMB_XPMR(n) (0xA20 + (n * 4))
+/* CMB MSR register */
+#define TPDM_CMB_MSR(n) (0xA80 + (n * 4))

/* Enable bit for CMB subunit */
#define TPDM_CMB_CR_ENA BIT(0)
@@ -36,6 +38,9 @@
/*Patten register number*/
#define TPDM_CMB_MAX_PATT 2

+/* MAX number of DSB MSR */
+#define TPDM_CMB_MAX_MSR 32
+
/* DSB Subunit Registers */
#define TPDM_DSB_CR (0x780)
#define TPDM_DSB_TIER (0x784)
@@ -186,6 +191,10 @@
tpdm_simple_dataset_rw(tpmr##nr, \
CMB_PATT_MASK, nr)

+#define CMB_MSR_ATTR(nr) \
+ tpdm_simple_dataset_rw(msr##nr, \
+ CMB_MSR, nr)
+
/**
* struct dsb_dataset - specifics associated to dsb dataset
* @mode: DSB programming mode
@@ -225,6 +234,7 @@ struct dsb_dataset {
* @patt_mask: Save value for pattern mask
* @trig_patt: Save value for trigger pattern
* @trig_patt_mask: Save value for trigger pattern mask
+ * @msr Save value for MSR
* @patt_ts: Indicates if pattern match for timestamp is enabled.
* @trig_ts: Indicates if CTI trigger for timestamp is enabled.
* @ts_all: Indicates if timestamp is enabled for all packets.
@@ -235,6 +245,7 @@ struct cmb_dataset {
u32 patt_mask[TPDM_CMB_MAX_PATT];
u32 trig_patt[TPDM_CMB_MAX_PATT];
u32 trig_patt_mask[TPDM_CMB_MAX_PATT];
+ u32 msr[TPDM_CMB_MAX_MSR];
bool patt_ts;
bool trig_ts;
bool ts_all;
@@ -251,6 +262,7 @@ struct cmb_dataset {
* @dsb Specifics associated to TPDM DSB.
* @cmb Specifics associated to TPDM CMB.
* @dsb_msr_num Number of MSR supported by DSB TPDM
+ * @cmb_msr_num Number of MSR supported by CMB TPDM
*/

struct tpdm_drvdata {
@@ -263,6 +275,7 @@ struct tpdm_drvdata {
struct dsb_dataset *dsb;
struct cmb_dataset *cmb;
u32 dsb_msr_num;
+ u32 cmb_msr_num;
};

/* Enumerate members of various datasets */
@@ -277,7 +290,8 @@ enum dataset_mem {
CMB_TRIG_PATT,
CMB_TRIG_PATT_MASK,
CMB_PATT,
- CMB_PATT_MASK
+ CMB_PATT_MASK,
+ CMB_MSR
};

/**
--
2.17.1

2023-11-21 07:24:50

by Krzysztof Kozlowski

[permalink] [raw]
Subject: Re: [PATCH v3 7/8] dt-bindings: arm: Add support for TPDM CMB MSR register

On 21/11/2023 03:24, Tao Zhang wrote:
> Add property "qcom,cmb_msr_num" to support CMB MSR(mux select register)
> for TPDM. It specifies the number of CMB MSR registers supported by
> the TDPM.
>
> Signed-off-by: Tao Zhang <[email protected]>
> Signed-off-by: Mao Jinlong <[email protected]>
> ---

I prefer not to take any new Qualcomm Coresight bindings or Qualcomm SoC
DTS nodes with Coresight till we fix all existing warnings. I don't know
how to fix them, so I need help with them. No such fixing happened so
far from Qcom, so pushback is my only way to get any attention.

I already commented on this in other email thread.

Best regards,
Krzysztof

2023-12-15 11:20:42

by James Clark

[permalink] [raw]
Subject: Re: [PATCH v3 2/8] coresight-tpda: Add support to configure CMB element



On 21/11/2023 02:24, Tao Zhang wrote:
> Read the CMB element size from the device tree. Set the register
> bit that controls the CMB element size of the corresponding port.
>
> Signed-off-by: Tao Zhang <[email protected]>
> Signed-off-by: Mao Jinlong <[email protected]>

Reviewed-by: James Clark <[email protected]>

> ---
> drivers/hwtracing/coresight/coresight-tpda.c | 117 +++++++++++--------
> drivers/hwtracing/coresight/coresight-tpda.h | 6 +
> 2 files changed, 74 insertions(+), 49 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
> index 5f82737c37bb..e3762f38abb3 100644
> --- a/drivers/hwtracing/coresight/coresight-tpda.c
> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
> @@ -28,24 +28,54 @@ static bool coresight_device_is_tpdm(struct coresight_device *csdev)
> CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM);
> }
>
> +static void tpdm_clear_element_size(struct coresight_device *csdev)
> +{
> + struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> +
> + if (drvdata->dsb_esize)
> + drvdata->dsb_esize = 0;
> + if (drvdata->cmb_esize)
> + drvdata->cmb_esize = 0;
> +}
> +
> +static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32 *val)
> +{
> +
> + if (drvdata->dsb_esize == 64)
> + *val |= TPDA_Pn_CR_DSBSIZE;
> + else if (drvdata->dsb_esize == 32)
> + *val &= ~TPDA_Pn_CR_DSBSIZE;
> +
> + if (drvdata->cmb_esize == 64)
> + *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2);
> + else if (drvdata->cmb_esize == 32)
> + *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1);
> + else if (drvdata->cmb_esize == 8)
> + *val &= ~TPDA_Pn_CR_CMBSIZE;
> +}
> +
> /*
> - * Read the DSB element size from the TPDM device
> + * Read the element size from the TPDM device
> * Returns
> - * The dsb element size read from the devicetree if available.
> + * The element size read from the devicetree if available.
> * 0 - Otherwise, with a warning once.
> */
> -static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
> +static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
> + struct coresight_device *csdev)
> {
> - int rc = 0;
> - u8 size = 0;
> -
> - rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
> - "qcom,dsb-element-size", &size);
> + int rc = -EINVAL;
> +
> + if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
> + "qcom,dsb-element-size", &drvdata->dsb_esize))
> + rc = 0;
> + if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
> + "qcom,cmb-element-size", &drvdata->cmb_esize))
> + rc = 0;
> if (rc)
> dev_warn_once(&csdev->dev,
> - "Failed to read TPDM DSB Element size: %d\n", rc);
> + "Failed to read TPDM Element size: %d\n", rc);
>
> - return size;
> + return rc;
> }
>
> /*
> @@ -56,11 +86,12 @@ static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
> * Parameter "inport" is used to pass in the input port number
> * of TPDA, and it is set to -1 in the recursize call.
> */
> -static int tpda_get_element_size(struct coresight_device *csdev,
> +static int tpda_get_element_size(struct tpda_drvdata *drvdata,
> + struct coresight_device *csdev,
> int inport)
> {
> - int dsb_size = -ENOENT;
> - int i, size;
> + int rc = 0;
> + int i;
> struct coresight_device *in;
>
> for (i = 0; i < csdev->pdata->nr_inconns; i++) {
> @@ -74,25 +105,21 @@ static int tpda_get_element_size(struct coresight_device *csdev,
> continue;
>
> if (coresight_device_is_tpdm(in)) {
> - size = tpdm_read_dsb_element_size(in);
> + if ((drvdata->dsb_esize) || (drvdata->cmb_esize))
> + return -EEXIST;
> + rc = tpdm_read_element_size(drvdata, in);
> + if (rc)
> + return rc;
> } else {
> /* Recurse down the path */
> - size = tpda_get_element_size(in, -1);
> - }
> -
> - if (size < 0)
> - return size;
> -
> - if (dsb_size < 0) {
> - /* Found a size, save it. */
> - dsb_size = size;
> - } else {
> - /* Found duplicate TPDMs */
> - return -EEXIST;
> + rc = tpda_get_element_size(drvdata, in, -1);
> + if (rc)
> + return rc;
> }
> }
>
> - return dsb_size;
> +
> + return rc;
> }
>
> /* Settings pre enabling port control register */
> @@ -109,7 +136,7 @@ static void tpda_enable_pre_port(struct tpda_drvdata *drvdata)
> static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
> {
> u32 val;
> - int size;
> + int rc;
>
> val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
> /*
> @@ -117,29 +144,21 @@ static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
> * Set the bit to 0 if the size is 32
> * Set the bit to 1 if the size is 64
> */
> - size = tpda_get_element_size(drvdata->csdev, port);
> - switch (size) {
> - case 32:
> - val &= ~TPDA_Pn_CR_DSBSIZE;
> - break;
> - case 64:
> - val |= TPDA_Pn_CR_DSBSIZE;
> - break;
> - case 0:
> - return -EEXIST;
> - case -EEXIST:
> + tpdm_clear_element_size(drvdata->csdev);
> + rc = tpda_get_element_size(drvdata, drvdata->csdev, port);
> + if (!rc && ((drvdata->dsb_esize) || (drvdata->cmb_esize))) {
> + tpda_set_element_size(drvdata, &val);
> + /* Enable the port */
> + val |= TPDA_Pn_CR_ENA;
> + writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
> + } else if (rc == -EEXIST)
> dev_warn_once(&drvdata->csdev->dev,
> - "Detected multiple TPDMs on port %d", -EEXIST);
> - return -EEXIST;
> - default:
> - return -EINVAL;
> - }
> -
> - /* Enable the port */
> - val |= TPDA_Pn_CR_ENA;
> - writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
> + "Detected multiple TPDMs on port %d", -EEXIST);
> + else
> + dev_warn_once(&drvdata->csdev->dev,
> + "Didn't find TPDM elem size");
>
> - return 0;
> + return rc;
> }
>
> static int __tpda_enable(struct tpda_drvdata *drvdata, int port)
> diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h
> index b3b38fd41b64..29164fd9711f 100644
> --- a/drivers/hwtracing/coresight/coresight-tpda.h
> +++ b/drivers/hwtracing/coresight/coresight-tpda.h
> @@ -10,6 +10,8 @@
> #define TPDA_Pn_CR(n) (0x004 + (n * 4))
> /* Aggregator port enable bit */
> #define TPDA_Pn_CR_ENA BIT(0)
> +/* Aggregator port CMB data set element size bit */
> +#define TPDA_Pn_CR_CMBSIZE GENMASK(7, 6)
> /* Aggregator port DSB data set element size bit */
> #define TPDA_Pn_CR_DSBSIZE BIT(8)
>
> @@ -25,6 +27,8 @@
> * @csdev: component vitals needed by the framework.
> * @spinlock: lock for the drvdata value.
> * @enable: enable status of the component.
> + * @dsb_esize Record the DSB element size.
> + * @cmb_esize Record the CMB element size.
> */
> struct tpda_drvdata {
> void __iomem *base;
> @@ -32,6 +36,8 @@ struct tpda_drvdata {
> struct coresight_device *csdev;
> spinlock_t spinlock;
> u8 atid;
> + u8 dsb_esize;
> + u8 cmb_esize;
> };
>
> #endif /* _CORESIGHT_CORESIGHT_TPDA_H */

2023-12-15 11:24:44

by James Clark

[permalink] [raw]
Subject: Re: [PATCH v3 8/8] coresight-tpdm: Add msr register support for CMB



On 21/11/2023 02:24, Tao Zhang wrote:
> Add the nodes for CMB subunit MSR(mux select register) support.
> CMB MSRs(mux select registers) is to separate mux,arbitration,
> ,interleaving,data packing control from stream filtering control.
>
> Reviewed-by: James Clark <[email protected]>
> Signed-off-by: Tao Zhang <[email protected]>
> Signed-off-by: Mao Jinlong <[email protected]>
> ---
> .../testing/sysfs-bus-coresight-devices-tpdm | 8 ++
> drivers/hwtracing/coresight/coresight-tpdm.c | 86 +++++++++++++++++++
> drivers/hwtracing/coresight/coresight-tpdm.h | 16 +++-
> 3 files changed, 109 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> index e0b77107be13..914f3fd81525 100644
> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> @@ -249,3 +249,11 @@ Description:
> Accepts only one of the 2 values - 0 or 1.
> 0 : Disable the timestamp of all trace packets.
> 1 : Enable the timestamp of all trace packets.
> +
> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
> +Date: September 2023
> +KernelVersion 6.7

This probably needs bumping now. Maybe 6.9?

2023-12-18 10:28:35

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH v3 2/8] coresight-tpda: Add support to configure CMB element

On 21/11/2023 02:24, Tao Zhang wrote:
> Read the CMB element size from the device tree. Set the register
> bit that controls the CMB element size of the corresponding port.
>
> Signed-off-by: Tao Zhang <[email protected]>
> Signed-off-by: Mao Jinlong <[email protected]>
> ---
> drivers/hwtracing/coresight/coresight-tpda.c | 117 +++++++++++--------
> drivers/hwtracing/coresight/coresight-tpda.h | 6 +
> 2 files changed, 74 insertions(+), 49 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
> index 5f82737c37bb..e3762f38abb3 100644
> --- a/drivers/hwtracing/coresight/coresight-tpda.c
> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
> @@ -28,24 +28,54 @@ static bool coresight_device_is_tpdm(struct coresight_device *csdev)
> CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM);
> }
>
> +static void tpdm_clear_element_size(struct coresight_device *csdev)
> +{
> + struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> +
> + if (drvdata->dsb_esize)
> + drvdata->dsb_esize = 0;
> + if (drvdata->cmb_esize)
> + drvdata->cmb_esize = 0;

Why do we need the if (...) check here ?

> +}
> +
> +static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32 *val)
> +{
> +
> + if (drvdata->dsb_esize == 64)
> + *val |= TPDA_Pn_CR_DSBSIZE;
> + else if (drvdata->dsb_esize == 32)
> + *val &= ~TPDA_Pn_CR_DSBSIZE;
> +
> + if (drvdata->cmb_esize == 64)
> + *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2);
> + else if (drvdata->cmb_esize == 32)
> + *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1);
> + else if (drvdata->cmb_esize == 8)
> + *val &= ~TPDA_Pn_CR_CMBSIZE;
> +}
> +


> /*
> - * Read the DSB element size from the TPDM device
> + * Read the element size from the TPDM device
> * Returns
> - * The dsb element size read from the devicetree if available.
> + * The element size read from the devicetree if available.
> * 0 - Otherwise, with a warning once.

This doesn't match the function ? It return 0 on success and
error (-EINVAL) on failure ?

> */
> -static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
> +static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
> + struct coresight_device *csdev)
> {
> - int rc = 0;
> - u8 size = 0;
> -
> - rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
> - "qcom,dsb-element-size", &size);
> + int rc = -EINVAL;
> +
> + if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
> + "qcom,dsb-element-size", &drvdata->dsb_esize))
> + rc = 0;
> + if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
> + "qcom,cmb-element-size", &drvdata->cmb_esize))
> + rc = 0;

Are we not silently resetting the error if the former failed ?

Could we not :

rc |= fwnode_...

rc |= fwnode_...

instead ?

Also what is the expectation here ? Are these properties a MUST for
TPDM ?

> if (rc)
> dev_warn_once(&csdev->dev,
> - "Failed to read TPDM DSB Element size: %d\n", rc);
> + "Failed to read TPDM Element size: %d\n", rc);
>
> - return size;
> + return rc;
> }
>
> /*
> @@ -56,11 +86,12 @@ static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
> * Parameter "inport" is used to pass in the input port number
> * of TPDA, and it is set to -1 in the recursize call.
> */
> -static int tpda_get_element_size(struct coresight_device *csdev,
> +static int tpda_get_element_size(struct tpda_drvdata *drvdata,
> + struct coresight_device *csdev,
> int inport)
> {
> - int dsb_size = -ENOENT;
> - int i, size;
> + int rc = 0;
> + int i;
> struct coresight_device *in;
>
> for (i = 0; i < csdev->pdata->nr_inconns; i++) {
> @@ -74,25 +105,21 @@ static int tpda_get_element_size(struct coresight_device *csdev,
> continue;
>
> if (coresight_device_is_tpdm(in)) {
> - size = tpdm_read_dsb_element_size(in);
> + if ((drvdata->dsb_esize) || (drvdata->cmb_esize))
> + return -EEXIST;
> + rc = tpdm_read_element_size(drvdata, in);
> + if (rc)
> + return rc;
> } else {
> /* Recurse down the path */
> - size = tpda_get_element_size(in, -1);
> - }
> -
> - if (size < 0)
> - return size;
> -
> - if (dsb_size < 0) {
> - /* Found a size, save it. */
> - dsb_size = size;
> - } else {
> - /* Found duplicate TPDMs */
> - return -EEXIST;
> + rc = tpda_get_element_size(drvdata, in, -1);
> + if (rc)
> + return rc;
> }
> }
>
> - return dsb_size;
> +
> + return rc;
> }
>
> /* Settings pre enabling port control register */
> @@ -109,7 +136,7 @@ static void tpda_enable_pre_port(struct tpda_drvdata *drvdata)
> static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
> {
> u32 val;
> - int size;
> + int rc;
>
> val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
> /*
> @@ -117,29 +144,21 @@ static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
> * Set the bit to 0 if the size is 32
> * Set the bit to 1 if the size is 64
> */
> - size = tpda_get_element_size(drvdata->csdev, port);
> - switch (size) {
> - case 32:
> - val &= ~TPDA_Pn_CR_DSBSIZE;
> - break;
> - case 64:
> - val |= TPDA_Pn_CR_DSBSIZE;
> - break;
> - case 0:
> - return -EEXIST;
> - case -EEXIST:
> + tpdm_clear_element_size(drvdata->csdev);
> + rc = tpda_get_element_size(drvdata, drvdata->csdev, port);
> + if (!rc && ((drvdata->dsb_esize) || (drvdata->cmb_esize))) {
> + tpda_set_element_size(drvdata, &val);
> + /* Enable the port */
> + val |= TPDA_Pn_CR_ENA;
> + writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
> + } else if (rc == -EEXIST)
> dev_warn_once(&drvdata->csdev->dev,
> - "Detected multiple TPDMs on port %d", -EEXIST);
> - return -EEXIST;
> - default:
> - return -EINVAL;
> - }
> -
> - /* Enable the port */
> - val |= TPDA_Pn_CR_ENA;
> - writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
> + "Detected multiple TPDMs on port %d", -EEXIST);
> + else
> + dev_warn_once(&drvdata->csdev->dev,
> + "Didn't find TPDM elem size");

"element size"

>
> - return 0;
> + return rc;
> }
>
> static int __tpda_enable(struct tpda_drvdata *drvdata, int port)
> diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h
> index b3b38fd41b64..29164fd9711f 100644
> --- a/drivers/hwtracing/coresight/coresight-tpda.h
> +++ b/drivers/hwtracing/coresight/coresight-tpda.h
> @@ -10,6 +10,8 @@
> #define TPDA_Pn_CR(n) (0x004 + (n * 4))
> /* Aggregator port enable bit */
> #define TPDA_Pn_CR_ENA BIT(0)
> +/* Aggregator port CMB data set element size bit */
> +#define TPDA_Pn_CR_CMBSIZE GENMASK(7, 6)
> /* Aggregator port DSB data set element size bit */
> #define TPDA_Pn_CR_DSBSIZE BIT(8)
>
> @@ -25,6 +27,8 @@
> * @csdev: component vitals needed by the framework.
> * @spinlock: lock for the drvdata value.
> * @enable: enable status of the component.
> + * @dsb_esize Record the DSB element size.
> + * @cmb_esize Record the CMB element size.
> */
> struct tpda_drvdata {
> void __iomem *base;
> @@ -32,6 +36,8 @@ struct tpda_drvdata {
> struct coresight_device *csdev;
> spinlock_t spinlock;
> u8 atid;
> + u8 dsb_esize;
> + u8 cmb_esize;
> };
>
> #endif /* _CORESIGHT_CORESIGHT_TPDA_H */

Suzuki



2023-12-18 10:47:15

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH v3 6/8] coresight-tpdm: Add timestamp control register support for the CMB

On 21/11/2023 02:24, Tao Zhang wrote:
> CMB_TIER register is CMB subunit timestamp insertion enable register.
> Bit 0 is PATT_TSENAB bit. Set this bit to 1 to request a timestamp
> following a CMB interface pattern match. Bit 1 is XTRIG_TSENAB bit.
> Set this bit to 1 to request a timestamp following a CMB CTI timestamp
> request. Bit 2 is TS_ALL bit. Set this bit to 1 to request timestamp
> for all packets.
>
> Reviewed-by: James Clark <[email protected]>
> Signed-off-by: Tao Zhang <[email protected]>
> Signed-off-by: Jinlong Mao <[email protected]>
> ---
> .../testing/sysfs-bus-coresight-devices-tpdm | 35 ++++++
> drivers/hwtracing/coresight/coresight-tpdm.c | 116 +++++++++++++++++-
> drivers/hwtracing/coresight/coresight-tpdm.h | 14 +++
> 3 files changed, 162 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> index 53662ce7c2d0..e0b77107be13 100644
> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> @@ -214,3 +214,38 @@ KernelVersion 6.7
> Contact: Jinlong Mao (QUIC) <[email protected]>, Tao Zhang (QUIC) <[email protected]>
> Description:
> (RW) Set/Get the mask of the pattern for the CMB subunit TPDM.
> +
> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_patt/enable_ts
> +Date: September 2023
> +KernelVersion 6.7
> +Contact: Jinlong Mao (QUIC) <[email protected]>, Tao Zhang (QUIC) <[email protected]>
> +Description:
> + (Write) Set the pattern timestamp of CMB tpdm. Read
> + the pattern timestamp of CMB tpdm.
> +
> + Accepts only one of the 2 values - 0 or 1.
> + 0 : Disable CMB pattern timestamp.
> + 1 : Enable CMB pattern timestamp.
> +
> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_ts
> +Date: September 2023
> +KernelVersion 6.7
> +Contact: Jinlong Mao (QUIC) <[email protected]>, Tao Zhang (QUIC) <[email protected]>
> +Description:
> + (RW) Set/Get the trigger timestamp of the CMB for tpdm.
> +
> + Accepts only one of the 2 values - 0 or 1.
> + 0 : Set the CMB trigger type to false
> + 1 : Set the CMB trigger type to true
> +
> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_ts_all
> +Date: September 2023
> +KernelVersion 6.7
> +Contact: Jinlong Mao (QUIC) <[email protected]>, Tao Zhang (QUIC) <[email protected]>
> +Description:
> + (RW) Read or write the status of timestamp upon all interface.
> + Only value 0 and 1 can be written to this node. Set this node to 1 to requeset
> + timestamp to all trace packet.
> + Accepts only one of the 2 values - 0 or 1.
> + 0 : Disable the timestamp of all trace packets.
> + 1 : Enable the timestamp of all trace packets.
> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
> index 894d4309f1c7..f6cda5616e84 100644
> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
> @@ -331,6 +331,36 @@ static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
> writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
> }
>
> +static void set_cmb_tier(struct tpdm_drvdata *drvdata)
> +{
> + u32 val;
> +
> + val = readl_relaxed(drvdata->base + TPDM_CMB_TIER);
> +
> + /* Clear all relevant fields */
> + val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL |
> + TPDM_CMB_TIER_XTRIG_TSENAB);
> +
> + /* Set pattern timestamp type and enablement */
> + if (drvdata->cmb->patt_ts)
> + val |= TPDM_CMB_TIER_PATT_TSENAB;

-- cut --
> + else
> + val &= ~TPDM_CMB_TIER_PATT_TSENAB;


All the else cases in this function are superfluous. Please remove all
of them.

> +
> + /* Set trigger timestamp */
> + if (drvdata->cmb->trig_ts)
> + val |= TPDM_CMB_TIER_XTRIG_TSENAB;
> + else
> + val &= ~TPDM_CMB_TIER_XTRIG_TSENAB;
> +
> + /* Set all timestamp enablement*/
> + if (drvdata->cmb->ts_all)
> + val |= TPDM_CMB_TIER_TS_ALL;
> + else
> + val &= ~TPDM_CMB_TIER_TS_ALL;
> + writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
> +}
> +
> static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
> {
> u32 val, i;
> @@ -347,6 +377,8 @@ static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
> drvdata->base + TPDM_CMB_XPMR(i));
> }
>
> + set_cmb_tier(drvdata);
> +
> val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
> /*
> * Set to 0 for continuous CMB collection mode,
> @@ -695,9 +727,17 @@ static ssize_t enable_ts_show(struct device *dev,
> char *buf)
> {
> struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
> + ssize_t size = 0;
>
> - return sysfs_emit(buf, "%u\n",
> - (unsigned int)drvdata->dsb->patt_ts);
> + if (tpdm_has_dsb_dataset(drvdata))
> + size = sysfs_emit(buf, "%u\n",
> + (unsigned int)drvdata->dsb->patt_ts);
> +
> + if (tpdm_has_cmb_dataset(drvdata))
> + size = sysfs_emit(buf, "%u\n",
> + (unsigned int)drvdata->cmb->patt_ts);

Why does this need to show two values ? This must only show ONE value.
How you deduce that might be based on the availability of the feature
set. Or store the TS value in the drvdata and use that instead for
controlling CMB/DSB.

Also, the sysfs documentation needs update, if this is going to
control the CMB.

Suzuki


> +
> + return size;
> }
>
> /*
> @@ -715,8 +755,13 @@ static ssize_t enable_ts_store(struct device *dev,
> return -EINVAL;
>
> spin_lock(&drvdata->spinlock);
> - drvdata->dsb->patt_ts = !!val;
> + if (tpdm_has_dsb_dataset(drvdata))
> + drvdata->dsb->patt_ts = !!val;
> +
> + if (tpdm_has_cmb_dataset(drvdata))
> + drvdata->cmb->patt_ts = !!val;
> spin_unlock(&drvdata->spinlock);
> +
> return size;
> }
> static DEVICE_ATTR_RW(enable_ts);
> @@ -851,6 +896,68 @@ static ssize_t cmb_mode_store(struct device *dev,
> }
> static DEVICE_ATTR_RW(cmb_mode);
>
> +static ssize_t cmb_ts_all_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
> +
> + return sysfs_emit(buf, "%u\n",
> + (unsigned int)drvdata->cmb->ts_all);
> +}
> +
> +static ssize_t cmb_ts_all_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 val;
> +
> + if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
> + return -EINVAL;
> +
> + spin_lock(&drvdata->spinlock);
> + if (val)
> + drvdata->cmb->ts_all = true;
> + else
> + drvdata->cmb->ts_all = false;
> + spin_unlock(&drvdata->spinlock);
> + return size;
> +}
> +static DEVICE_ATTR_RW(cmb_ts_all);
> +
> +static ssize_t cmb_trig_ts_show(struct device *dev,
> + struct device_attribute *attr,
> + char *buf)
> +{
> + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
> +
> + return sysfs_emit(buf, "%u\n",
> + (unsigned int)drvdata->cmb->trig_ts);
> +}
> +
> +static ssize_t cmb_trig_ts_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 val;
> +
> + if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
> + return -EINVAL;
> +
> + spin_lock(&drvdata->spinlock);
> + if (val)
> + drvdata->cmb->trig_ts = true;
> + else
> + drvdata->cmb->trig_ts = false;
> + spin_unlock(&drvdata->spinlock);
> + return size;
> +}
> +static DEVICE_ATTR_RW(cmb_trig_ts);
> +
> static struct attribute *tpdm_dsb_edge_attrs[] = {
> &dev_attr_ctrl_idx.attr,
> &dev_attr_ctrl_val.attr,
> @@ -973,6 +1080,7 @@ static struct attribute *tpdm_cmb_patt_attrs[] = {
> CMB_PATT_ATTR(1),
> CMB_PATT_MASK_ATTR(0),
> CMB_PATT_MASK_ATTR(1),
> + &dev_attr_enable_ts.attr,
> NULL,
> };
>
> @@ -985,6 +1093,8 @@ static struct attribute *tpdm_dsb_attrs[] = {
>
> static struct attribute *tpdm_cmb_attrs[] = {
> &dev_attr_cmb_mode.attr,
> + &dev_attr_cmb_ts_all.attr,
> + &dev_attr_cmb_trig_ts.attr,
> NULL,
> };
>
> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
> index e90d008c1cb2..65b7ca6c4077 100644
> --- a/drivers/hwtracing/coresight/coresight-tpdm.h
> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
> @@ -11,6 +11,8 @@
>
> /* CMB Subunit Registers */
> #define TPDM_CMB_CR (0xA00)
> +/*CMB subunit timestamp insertion enable register*/
> +#define TPDM_CMB_TIER (0xA04)
> /*CMB subunit timestamp pattern registers*/
> #define TPDM_CMB_TPR(n) (0xA08 + (n * 4))
> /*CMB subunit timestamp pattern mask registers*/
> @@ -24,6 +26,12 @@
> #define TPDM_CMB_CR_ENA BIT(0)
> /* Trace collection mode for CMB subunit */
> #define TPDM_CMB_CR_MODE BIT(1)
> +/* Timestamp control for pattern match */
> +#define TPDM_CMB_TIER_PATT_TSENAB BIT(0)
> +/* CMB CTI timestamp request */
> +#define TPDM_CMB_TIER_XTRIG_TSENAB BIT(1)
> +/* For timestamp fo all trace */
> +#define TPDM_CMB_TIER_TS_ALL BIT(2)
>
> /*Patten register number*/
> #define TPDM_CMB_MAX_PATT 2
> @@ -217,6 +225,9 @@ struct dsb_dataset {
> * @patt_mask: Save value for pattern mask
> * @trig_patt: Save value for trigger pattern
> * @trig_patt_mask: Save value for trigger pattern mask
> + * @patt_ts: Indicates if pattern match for timestamp is enabled.
> + * @trig_ts: Indicates if CTI trigger for timestamp is enabled.
> + * @ts_all: Indicates if timestamp is enabled for all packets.
> */
> struct cmb_dataset {
> u32 trace_mode;
> @@ -224,6 +235,9 @@ struct cmb_dataset {
> u32 patt_mask[TPDM_CMB_MAX_PATT];
> u32 trig_patt[TPDM_CMB_MAX_PATT];
> u32 trig_patt_mask[TPDM_CMB_MAX_PATT];
> + bool patt_ts;
> + bool trig_ts;
> + bool ts_all;
> };
>
> /**


2023-12-18 10:49:15

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH v3 7/8] dt-bindings: arm: Add support for TPDM CMB MSR register

Tao Zhang,

On 21/11/2023 07:24, Krzysztof Kozlowski wrote:
> On 21/11/2023 03:24, Tao Zhang wrote:
>> Add property "qcom,cmb_msr_num" to support CMB MSR(mux select register)
>> for TPDM. It specifies the number of CMB MSR registers supported by
>> the TDPM.
>>
>> Signed-off-by: Tao Zhang <[email protected]>
>> Signed-off-by: Mao Jinlong <[email protected]>
>> ---
>
> I prefer not to take any new Qualcomm Coresight bindings or Qualcomm SoC
> DTS nodes with Coresight till we fix all existing warnings. I don't know
> how to fix them, so I need help with them. No such fixing happened so
> far from Qcom, so pushback is my only way to get any attention.
>
> I already commented on this in other email thread.

Are you addressing this ?

Suzuki

>
> Best regards,
> Krzysztof
>


2023-12-18 11:03:04

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH v3 8/8] coresight-tpdm: Add msr register support for CMB

On 21/11/2023 02:24, Tao Zhang wrote:
> Add the nodes for CMB subunit MSR(mux select register) support.
> CMB MSRs(mux select registers) is to separate mux,arbitration,
> ,interleaving,data packing control from stream filtering control.
>
> Reviewed-by: James Clark <[email protected]>
> Signed-off-by: Tao Zhang <[email protected]>
> Signed-off-by: Mao Jinlong <[email protected]>
> ---
> .../testing/sysfs-bus-coresight-devices-tpdm | 8 ++
> drivers/hwtracing/coresight/coresight-tpdm.c | 86 +++++++++++++++++++
> drivers/hwtracing/coresight/coresight-tpdm.h | 16 +++-
> 3 files changed, 109 insertions(+), 1 deletion(-)
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> index e0b77107be13..914f3fd81525 100644
> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> @@ -249,3 +249,11 @@ Description:
> Accepts only one of the 2 values - 0 or 1.
> 0 : Disable the timestamp of all trace packets.
> 1 : Enable the timestamp of all trace packets.
> +
> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
> +Date: September 2023
> +KernelVersion 6.7
> +Contact: Jinlong Mao (QUIC) <[email protected]>, Tao Zhang (QUIC) <[email protected]>
> +Description:
> + (RW) Set/Get the MSR(mux select register) for the CMB subunit
> + TPDM.
> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
> index f6cda5616e84..7e331ea436cc 100644
> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
> @@ -86,6 +86,11 @@ static ssize_t tpdm_simple_dataset_show(struct device *dev,
> return -EINVAL;
> return sysfs_emit(buf, "0x%x\n",
> drvdata->cmb->patt_mask[tpdm_attr->idx]);
> + case CMB_MSR:
> + if (tpdm_attr->idx >= drvdata->cmb_msr_num)
> + return -EINVAL;
> + return sysfs_emit(buf, "0x%x\n",
> + drvdata->cmb->msr[tpdm_attr->idx]);
> }
> return -EINVAL;
> }
> @@ -162,6 +167,12 @@ static ssize_t tpdm_simple_dataset_store(struct device *dev,
> else
> ret = -EINVAL;
> break;
> + case CMB_MSR:
> + if (tpdm_attr->idx < drvdata->cmb_msr_num)
> + drvdata->cmb->msr[tpdm_attr->idx] = val;
> + else
> + ret = -EINVAL;


minor nit: Could we not break from here instead of adding return -EINVAL
for each case ? (I understand it has been done for the existing cases.
But I think we should clean up all of that, including the ones you added
in Patch 5. Similarly for the dataset_show()


Suzuki


> + break;
> default:
> ret = -EINVAL;
> }
> @@ -220,6 +231,23 @@ static umode_t tpdm_dsb_msr_is_visible(struct kobject *kobj,
> return 0;
> }
>
> +static umode_t tpdm_cmb_msr_is_visible(struct kobject *kobj,
> + struct attribute *attr, int n)
> +{
> + struct device *dev = kobj_to_dev(kobj);
> + struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
> +
> + struct device_attribute *dev_attr =
> + container_of(attr, struct device_attribute, attr);
> + struct tpdm_dataset_attribute *tpdm_attr =
> + container_of(dev_attr, struct tpdm_dataset_attribute, attr);
> +
> + if (tpdm_attr->idx < drvdata->cmb_msr_num)
> + return attr->mode;
> +
> + return 0;
> +}
> +
> static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata)
> {
> if (tpdm_has_dsb_dataset(drvdata)) {
> @@ -361,6 +389,15 @@ static void set_cmb_tier(struct tpdm_drvdata *drvdata)
> writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
> }
>
> +static void set_cmb_msr(struct tpdm_drvdata *drvdata)
> +{
> + int i;
> +
> + for (i = 0; i < drvdata->cmb_msr_num; i++)
> + writel_relaxed(drvdata->cmb->msr[i],
> + drvdata->base + TPDM_CMB_MSR(i));
> +}
> +
> static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
> {
> u32 val, i;
> @@ -379,6 +416,8 @@ static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
>
> set_cmb_tier(drvdata);
>
> + set_cmb_msr(drvdata);
> +
> val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
> /*
> * Set to 0 for continuous CMB collection mode,
> @@ -1084,6 +1123,42 @@ static struct attribute *tpdm_cmb_patt_attrs[] = {
> NULL,
> };
>
> +static struct attribute *tpdm_cmb_msr_attrs[] = {
> + CMB_MSR_ATTR(0),
> + CMB_MSR_ATTR(1),
> + CMB_MSR_ATTR(2),
> + CMB_MSR_ATTR(3),
> + CMB_MSR_ATTR(4),
> + CMB_MSR_ATTR(5),
> + CMB_MSR_ATTR(6),
> + CMB_MSR_ATTR(7),
> + CMB_MSR_ATTR(8),
> + CMB_MSR_ATTR(9),
> + CMB_MSR_ATTR(10),
> + CMB_MSR_ATTR(11),
> + CMB_MSR_ATTR(12),
> + CMB_MSR_ATTR(13),
> + CMB_MSR_ATTR(14),
> + CMB_MSR_ATTR(15),
> + CMB_MSR_ATTR(16),
> + CMB_MSR_ATTR(17),
> + CMB_MSR_ATTR(18),
> + CMB_MSR_ATTR(19),
> + CMB_MSR_ATTR(20),
> + CMB_MSR_ATTR(21),
> + CMB_MSR_ATTR(22),
> + CMB_MSR_ATTR(23),
> + CMB_MSR_ATTR(24),
> + CMB_MSR_ATTR(25),
> + CMB_MSR_ATTR(26),
> + CMB_MSR_ATTR(27),
> + CMB_MSR_ATTR(28),
> + CMB_MSR_ATTR(29),
> + CMB_MSR_ATTR(30),
> + CMB_MSR_ATTR(31),
> + NULL,
> +};
> +
> static struct attribute *tpdm_dsb_attrs[] = {
> &dev_attr_dsb_mode.attr,
> &dev_attr_dsb_trig_ts.attr,
> @@ -1144,6 +1219,12 @@ static struct attribute_group tpdm_cmb_patt_grp = {
> .name = "cmb_patt",
> };
>
> +static struct attribute_group tpdm_cmb_msr_grp = {
> + .attrs = tpdm_cmb_msr_attrs,
> + .is_visible = tpdm_cmb_msr_is_visible,
> + .name = "cmb_msr",
> +};
> +
> static const struct attribute_group *tpdm_attr_grps[] = {
> &tpdm_attr_grp,
> &tpdm_dsb_attr_grp,
> @@ -1154,6 +1235,7 @@ static const struct attribute_group *tpdm_attr_grps[] = {
> &tpdm_cmb_attr_grp,
> &tpdm_cmb_trig_patt_grp,
> &tpdm_cmb_patt_grp,
> + &tpdm_cmb_msr_grp,
> NULL,
> };
>
> @@ -1192,6 +1274,10 @@ static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
> of_property_read_u32(drvdata->dev->of_node,
> "qcom,dsb-msrs-num", &drvdata->dsb_msr_num);
>
> + if (drvdata && tpdm_has_cmb_dataset(drvdata))
> + of_property_read_u32(drvdata->dev->of_node,
> + "qcom,cmb-msrs-num", &drvdata->cmb_msr_num);
> +
> /* Set up coresight component description */
> desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
> if (!desc.name)
> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
> index 65b7ca6c4077..255104d024ab 100644
> --- a/drivers/hwtracing/coresight/coresight-tpdm.h
> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
> @@ -21,6 +21,8 @@
> #define TPDM_CMB_XPR(n) (0xA18 + (n * 4))
> /*CMB subunit trigger pattern mask registers*/
> #define TPDM_CMB_XPMR(n) (0xA20 + (n * 4))
> +/* CMB MSR register */
> +#define TPDM_CMB_MSR(n) (0xA80 + (n * 4))
>
> /* Enable bit for CMB subunit */
> #define TPDM_CMB_CR_ENA BIT(0)
> @@ -36,6 +38,9 @@
> /*Patten register number*/
> #define TPDM_CMB_MAX_PATT 2
>
> +/* MAX number of DSB MSR */
> +#define TPDM_CMB_MAX_MSR 32
> +
> /* DSB Subunit Registers */
> #define TPDM_DSB_CR (0x780)
> #define TPDM_DSB_TIER (0x784)
> @@ -186,6 +191,10 @@
> tpdm_simple_dataset_rw(tpmr##nr, \
> CMB_PATT_MASK, nr)
>
> +#define CMB_MSR_ATTR(nr) \
> + tpdm_simple_dataset_rw(msr##nr, \
> + CMB_MSR, nr)
> +
> /**
> * struct dsb_dataset - specifics associated to dsb dataset
> * @mode: DSB programming mode
> @@ -225,6 +234,7 @@ struct dsb_dataset {
> * @patt_mask: Save value for pattern mask
> * @trig_patt: Save value for trigger pattern
> * @trig_patt_mask: Save value for trigger pattern mask
> + * @msr Save value for MSR
> * @patt_ts: Indicates if pattern match for timestamp is enabled.
> * @trig_ts: Indicates if CTI trigger for timestamp is enabled.
> * @ts_all: Indicates if timestamp is enabled for all packets.
> @@ -235,6 +245,7 @@ struct cmb_dataset {
> u32 patt_mask[TPDM_CMB_MAX_PATT];
> u32 trig_patt[TPDM_CMB_MAX_PATT];
> u32 trig_patt_mask[TPDM_CMB_MAX_PATT];
> + u32 msr[TPDM_CMB_MAX_MSR];
> bool patt_ts;
> bool trig_ts;
> bool ts_all;
> @@ -251,6 +262,7 @@ struct cmb_dataset {
> * @dsb Specifics associated to TPDM DSB.
> * @cmb Specifics associated to TPDM CMB.
> * @dsb_msr_num Number of MSR supported by DSB TPDM
> + * @cmb_msr_num Number of MSR supported by CMB TPDM
> */
>
> struct tpdm_drvdata {
> @@ -263,6 +275,7 @@ struct tpdm_drvdata {
> struct dsb_dataset *dsb;
> struct cmb_dataset *cmb;
> u32 dsb_msr_num;
> + u32 cmb_msr_num;
> };
>
> /* Enumerate members of various datasets */
> @@ -277,7 +290,8 @@ enum dataset_mem {
> CMB_TRIG_PATT,
> CMB_TRIG_PATT_MASK,
> CMB_PATT,
> - CMB_PATT_MASK
> + CMB_PATT_MASK,
> + CMB_MSR
> };
>
> /**


2023-12-18 11:24:13

by Tingwei Zhang

[permalink] [raw]
Subject: Re: [PATCH v3 7/8] dt-bindings: arm: Add support for TPDM CMB MSR register

On 12/18/2023 6:47 PM, Suzuki K Poulose wrote:
> Tao Zhang,
>
> On 21/11/2023 07:24, Krzysztof Kozlowski wrote:
>> On 21/11/2023 03:24, Tao Zhang wrote:
>>> Add property "qcom,cmb_msr_num" to support CMB MSR(mux select register)
>>> for TPDM. It specifies the number of CMB MSR registers supported by
>>> the TDPM.
>>>
>>> Signed-off-by: Tao Zhang <[email protected]>
>>> Signed-off-by: Mao Jinlong <[email protected]>
>>> ---
>>
>> I prefer not to take any new Qualcomm Coresight bindings or Qualcomm SoC
>> DTS nodes with Coresight till we fix all existing warnings. I don't know
>> how to fix them, so I need help with them. No such fixing happened so
>> far from Qcom, so pushback is my only way to get any attention.
>>
>> I already commented on this in other email thread.
>
> Are you addressing this ?
The DT warning is fixed in
https://lore.kernel.org/linux-arm-msm/[email protected]/.
It's applied to linux-arm-msm yesterday.
>
> Suzuki
>
>>
>> Best regards,
>> Krzysztof
>>
>

--
Thanks,
Tingwei


2023-12-18 12:01:47

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH v3 7/8] dt-bindings: arm: Add support for TPDM CMB MSR register

Hi Tingwei Zhang

On 18/12/2023 11:23, Tingwei Zhang wrote:
> On 12/18/2023 6:47 PM, Suzuki K Poulose wrote:
>> Tao Zhang,
>>
>> On 21/11/2023 07:24, Krzysztof Kozlowski wrote:
>>> On 21/11/2023 03:24, Tao Zhang wrote:
>>>> Add property "qcom,cmb_msr_num" to support CMB MSR(mux select register)
>>>> for TPDM. It specifies the number of CMB MSR registers supported by
>>>> the TDPM.
>>>>
>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>> Signed-off-by: Mao Jinlong <[email protected]>
>>>> ---
>>>
>>> I prefer not to take any new Qualcomm Coresight bindings or Qualcomm SoC
>>> DTS nodes with Coresight till we fix all existing warnings. I don't know
>>> how to fix them, so I need help with them. No such fixing happened so
>>> far from Qcom, so pushback is my only way to get any attention.
>>>
>>> I already commented on this in other email thread.
>>
>> Are you addressing this ?
> The DT warning is fixed in
> https://lore.kernel.org/linux-arm-msm/[email protected]/.
> It's applied to linux-arm-msm yesterday.

How are you supporting remote-etm ? We haven't merged the support for it
in drivers ? We haven't even reviewed the remote-etm support patches ?
Why weren't the coresight maintainers Cc ed on the "new" binding support ?

Suzuki



>>
>> Suzuki
>>
>>>
>>> Best regards,
>>> Krzysztof
>>>
>>
>


2023-12-18 12:18:44

by Mao Jinlong

[permalink] [raw]
Subject: Re: [PATCH v3 7/8] dt-bindings: arm: Add support for TPDM CMB MSR register



On 12/18/2023 7:56 PM, Suzuki K Poulose wrote:
> Hi Tingwei Zhang
>
> On 18/12/2023 11:23, Tingwei Zhang wrote:
>> On 12/18/2023 6:47 PM, Suzuki K Poulose wrote:
>>> Tao Zhang,
>>>
>>> On 21/11/2023 07:24, Krzysztof Kozlowski wrote:
>>>> On 21/11/2023 03:24, Tao Zhang wrote:
>>>>> Add property "qcom,cmb_msr_num" to support CMB MSR(mux select
>>>>> register)
>>>>> for TPDM. It specifies the number of CMB MSR registers supported by
>>>>> the TDPM.
>>>>>
>>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>>> Signed-off-by: Mao Jinlong <[email protected]>
>>>>> ---
>>>>
>>>> I prefer not to take any new Qualcomm Coresight bindings or Qualcomm
>>>> SoC
>>>> DTS nodes with Coresight till we fix all existing warnings. I don't
>>>> know
>>>> how to fix them, so I need help with them. No such fixing happened so
>>>> far from Qcom, so pushback is my only way to get any attention.
>>>>
>>>> I already commented on this in other email thread.
>>>
>>> Are you addressing this ?
>> The DT warning is fixed in
>> https://lore.kernel.org/linux-arm-msm/[email protected]/.
>> It's applied to linux-arm-msm yesterday.
>
> How are you supporting remote-etm ? We haven't merged the support for it
> in drivers ? We haven't even reviewed the remote-etm support patches ?
> Why weren't the coresight maintainers Cc ed on the "new" binding support ?
>
> Suzuki
>
>
Hi Suzuki,

Sorry for missing coresight maintainers in the remote-etm binding patch.
From the comments, we can add binding for the connected hardware first.

https://lkml.org/lkml/2023/11/30/539

Thanks
Jinlong Mao

>
>>>
>>> Suzuki
>>>
>>>>
>>>> Best regards,
>>>> Krzysztof
>>>>
>>>
>>
>

2023-12-19 02:14:43

by Tao Zhang

[permalink] [raw]
Subject: Re: [PATCH v3 2/8] coresight-tpda: Add support to configure CMB element


On 12/18/2023 6:27 PM, Suzuki K Poulose wrote:
> On 21/11/2023 02:24, Tao Zhang wrote:
>> Read the CMB element size from the device tree. Set the register
>> bit that controls the CMB element size of the corresponding port.
>>
>> Signed-off-by: Tao Zhang <[email protected]>
>> Signed-off-by: Mao Jinlong <[email protected]>
>> ---
>>   drivers/hwtracing/coresight/coresight-tpda.c | 117 +++++++++++--------
>>   drivers/hwtracing/coresight/coresight-tpda.h |   6 +
>>   2 files changed, 74 insertions(+), 49 deletions(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c
>> b/drivers/hwtracing/coresight/coresight-tpda.c
>> index 5f82737c37bb..e3762f38abb3 100644
>> --- a/drivers/hwtracing/coresight/coresight-tpda.c
>> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
>> @@ -28,24 +28,54 @@ static bool coresight_device_is_tpdm(struct
>> coresight_device *csdev)
>>               CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM);
>>   }
>>   +static void tpdm_clear_element_size(struct coresight_device *csdev)
>> +{
>> +    struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> +
>> +    if (drvdata->dsb_esize)
>> +        drvdata->dsb_esize = 0;
>> +    if (drvdata->cmb_esize)
>> +        drvdata->cmb_esize = 0;
>
> Why do we need the if (...) check here ?

The element size of all the TPDM sub-unit should be set to 0 here.

I will update this in the next patch series.

>
>> +}
>> +
>> +static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32
>> *val)
>> +{
>> +
>> +    if (drvdata->dsb_esize == 64)
>> +        *val |= TPDA_Pn_CR_DSBSIZE;
>> +    else if (drvdata->dsb_esize == 32)
>> +        *val &= ~TPDA_Pn_CR_DSBSIZE;
>> +
>> +    if (drvdata->cmb_esize == 64)
>> +        *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2);
>> +    else if (drvdata->cmb_esize == 32)
>> +        *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1);
>> +    else if (drvdata->cmb_esize == 8)
>> +        *val &= ~TPDA_Pn_CR_CMBSIZE;
>> +}
>> +
>
>
>>   /*
>> - * Read the DSB element size from the TPDM device
>> + * Read the element size from the TPDM device
>>    * Returns
>> - *    The dsb element size read from the devicetree if available.
>> + *    The element size read from the devicetree if available.
>>    *    0 - Otherwise, with a warning once.
>
> This doesn't match the function ? It return 0 on success and
> error (-EINVAL) on failure ?

0 means the element size property is found from the devicetree.

Otherwise, it will return error(-EINVAL).

I will update this in the next patch series.

>
>>    */
>> -static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
>> +static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
>> +                  struct coresight_device *csdev)
>>   {
>> -    int rc = 0;
>> -    u8 size = 0;
>> -
>> -    rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>> -            "qcom,dsb-element-size", &size);
>> +    int rc = -EINVAL;
>> +
>> +    if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>> +            "qcom,dsb-element-size", &drvdata->dsb_esize))
>> +        rc = 0;
>> +    if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>> +            "qcom,cmb-element-size", &drvdata->cmb_esize))
>> +        rc = 0;
>
> Are we not silently resetting the error if the former failed ?
>
> Could we not :
>
>     rc |= fwnode_...
>
>     rc |= fwnode_...
>
> instead ?
>
> Also what is the expectation here ? Are these properties a MUST for
> TPDM ?

The TPDM must have one of the element size property. As long as one

can be found, this TPDM configuration can be considered valid. So this

function will return 0 if one of the element size property is found.


Best,

Tao

>
>>       if (rc)
>>           dev_warn_once(&csdev->dev,
>> -            "Failed to read TPDM DSB Element size: %d\n", rc);
>> +            "Failed to read TPDM Element size: %d\n", rc);
>>   -    return size;
>> +    return rc;
>>   }
>>     /*
>> @@ -56,11 +86,12 @@ static int tpdm_read_dsb_element_size(struct
>> coresight_device *csdev)
>>    * Parameter "inport" is used to pass in the input port number
>>    * of TPDA, and it is set to -1 in the recursize call.
>>    */
>> -static int tpda_get_element_size(struct coresight_device *csdev,
>> +static int tpda_get_element_size(struct tpda_drvdata *drvdata,
>> +                 struct coresight_device *csdev,
>>                    int inport)
>>   {
>> -    int dsb_size = -ENOENT;
>> -    int i, size;
>> +    int rc = 0;
>> +    int i;
>>       struct coresight_device *in;
>>         for (i = 0; i < csdev->pdata->nr_inconns; i++) {
>> @@ -74,25 +105,21 @@ static int tpda_get_element_size(struct
>> coresight_device *csdev,
>>               continue;
>>             if (coresight_device_is_tpdm(in)) {
>> -            size = tpdm_read_dsb_element_size(in);
>> +            if ((drvdata->dsb_esize) || (drvdata->cmb_esize))
>> +                return -EEXIST;
>> +            rc = tpdm_read_element_size(drvdata, in);
>> +            if (rc)
>> +                return rc;
>>           } else {
>>               /* Recurse down the path */
>> -            size = tpda_get_element_size(in, -1);
>> -        }
>> -
>> -        if (size < 0)
>> -            return size;
>> -
>> -        if (dsb_size < 0) {
>> -            /* Found a size, save it. */
>> -            dsb_size = size;
>> -        } else {
>> -            /* Found duplicate TPDMs */
>> -            return -EEXIST;
>> +            rc = tpda_get_element_size(drvdata, in, -1);
>> +            if (rc)
>> +                return rc;
>>           }
>>       }
>>   -    return dsb_size;
>> +
>> +    return rc;
>>   }
>>     /* Settings pre enabling port control register */
>> @@ -109,7 +136,7 @@ static void tpda_enable_pre_port(struct
>> tpda_drvdata *drvdata)
>>   static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
>>   {
>>       u32 val;
>> -    int size;
>> +    int rc;
>>         val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
>>       /*
>> @@ -117,29 +144,21 @@ static int tpda_enable_port(struct tpda_drvdata
>> *drvdata, int port)
>>        * Set the bit to 0 if the size is 32
>>        * Set the bit to 1 if the size is 64
>>        */
>> -    size = tpda_get_element_size(drvdata->csdev, port);
>> -    switch (size) {
>> -    case 32:
>> -        val &= ~TPDA_Pn_CR_DSBSIZE;
>> -        break;
>> -    case 64:
>> -        val |= TPDA_Pn_CR_DSBSIZE;
>> -        break;
>> -    case 0:
>> -        return -EEXIST;
>> -    case -EEXIST:
>> +    tpdm_clear_element_size(drvdata->csdev);
>> +    rc = tpda_get_element_size(drvdata, drvdata->csdev, port);
>> +    if (!rc && ((drvdata->dsb_esize) || (drvdata->cmb_esize))) {
>> +        tpda_set_element_size(drvdata, &val);
>> +        /* Enable the port */
>> +        val |= TPDA_Pn_CR_ENA;
>> +        writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
>> +    } else if (rc == -EEXIST)
>>           dev_warn_once(&drvdata->csdev->dev,
>> -            "Detected multiple TPDMs on port %d", -EEXIST);
>> -        return -EEXIST;
>> -    default:
>> -        return -EINVAL;
>> -    }
>> -
>> -    /* Enable the port */
>> -    val |= TPDA_Pn_CR_ENA;
>> -    writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
>> +                  "Detected multiple TPDMs on port %d", -EEXIST);
>> +    else
>> +        dev_warn_once(&drvdata->csdev->dev,
>> +                  "Didn't find TPDM elem size");
>
> "element size"
>
>>   -    return 0;
>> +    return rc;
>>   }
>>     static int __tpda_enable(struct tpda_drvdata *drvdata, int port)
>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.h
>> b/drivers/hwtracing/coresight/coresight-tpda.h
>> index b3b38fd41b64..29164fd9711f 100644
>> --- a/drivers/hwtracing/coresight/coresight-tpda.h
>> +++ b/drivers/hwtracing/coresight/coresight-tpda.h
>> @@ -10,6 +10,8 @@
>>   #define TPDA_Pn_CR(n)        (0x004 + (n * 4))
>>   /* Aggregator port enable bit */
>>   #define TPDA_Pn_CR_ENA        BIT(0)
>> +/* Aggregator port CMB data set element size bit */
>> +#define TPDA_Pn_CR_CMBSIZE        GENMASK(7, 6)
>>   /* Aggregator port DSB data set element size bit */
>>   #define TPDA_Pn_CR_DSBSIZE        BIT(8)
>>   @@ -25,6 +27,8 @@
>>    * @csdev:      component vitals needed by the framework.
>>    * @spinlock:   lock for the drvdata value.
>>    * @enable:     enable status of the component.
>> + * @dsb_esize   Record the DSB element size.
>> + * @cmb_esize   Record the CMB element size.
>>    */
>>   struct tpda_drvdata {
>>       void __iomem        *base;
>> @@ -32,6 +36,8 @@ struct tpda_drvdata {
>>       struct coresight_device    *csdev;
>>       spinlock_t        spinlock;
>>       u8            atid;
>> +    u8            dsb_esize;
>> +    u8            cmb_esize;
>>   };
>>     #endif  /* _CORESIGHT_CORESIGHT_TPDA_H */
>
> Suzuki
>
>

2023-12-19 02:44:15

by Tao Zhang

[permalink] [raw]
Subject: Re: [PATCH v3 6/8] coresight-tpdm: Add timestamp control register support for the CMB


On 12/18/2023 6:46 PM, Suzuki K Poulose wrote:
> On 21/11/2023 02:24, Tao Zhang wrote:
>> CMB_TIER register is CMB subunit timestamp insertion enable register.
>> Bit 0 is PATT_TSENAB bit. Set this bit to 1 to request a timestamp
>> following a CMB interface pattern match. Bit 1 is XTRIG_TSENAB bit.
>> Set this bit to 1 to request a timestamp following a CMB CTI timestamp
>> request. Bit 2 is TS_ALL bit. Set this bit to 1 to request timestamp
>> for all packets.
>>
>> Reviewed-by: James Clark <[email protected]>
>> Signed-off-by: Tao Zhang <[email protected]>
>> Signed-off-by: Jinlong Mao <[email protected]>
>> ---
>>   .../testing/sysfs-bus-coresight-devices-tpdm  |  35 ++++++
>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 116 +++++++++++++++++-
>>   drivers/hwtracing/coresight/coresight-tpdm.h  |  14 +++
>>   3 files changed, 162 insertions(+), 3 deletions(-)
>>
>> diff --git
>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>> index 53662ce7c2d0..e0b77107be13 100644
>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>> @@ -214,3 +214,38 @@ KernelVersion    6.7
>>   Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>> Zhang (QUIC) <[email protected]>
>>   Description:
>>           (RW) Set/Get the mask of the pattern for the CMB subunit TPDM.
>> +
>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_patt/enable_ts
>> +Date:        September 2023
>> +KernelVersion    6.7
>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao Zhang
>> (QUIC) <[email protected]>
>> +Description:
>> +        (Write) Set the pattern timestamp of CMB tpdm. Read
>> +        the pattern timestamp of CMB tpdm.
>> +
>> +        Accepts only one of the 2 values -  0 or 1.
>> +        0 : Disable CMB pattern timestamp.
>> +        1 : Enable CMB pattern timestamp.
>> +
>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_ts
>> +Date:        September 2023
>> +KernelVersion    6.7
>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao Zhang
>> (QUIC) <[email protected]>
>> +Description:
>> +        (RW) Set/Get the trigger timestamp of the CMB for tpdm.
>> +
>> +        Accepts only one of the 2 values -  0 or 1.
>> +        0 : Set the CMB trigger type to false
>> +        1 : Set the CMB trigger type to true
>> +
>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_ts_all
>> +Date:        September 2023
>> +KernelVersion    6.7
>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao Zhang
>> (QUIC) <[email protected]>
>> +Description:
>> +        (RW) Read or write the status of timestamp upon all interface.
>> +        Only value 0 and 1  can be written to this node. Set this
>> node to 1 to requeset
>> +        timestamp to all trace packet.
>> +        Accepts only one of the 2 values -  0 or 1.
>> +        0 : Disable the timestamp of all trace packets.
>> +        1 : Enable the timestamp of all trace packets.
>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>> index 894d4309f1c7..f6cda5616e84 100644
>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>> @@ -331,6 +331,36 @@ static void tpdm_enable_dsb(struct tpdm_drvdata
>> *drvdata)
>>       writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
>>   }
>>   +static void set_cmb_tier(struct tpdm_drvdata *drvdata)
>> +{
>> +    u32 val;
>> +
>> +    val = readl_relaxed(drvdata->base + TPDM_CMB_TIER);
>> +
>> +    /* Clear all relevant fields */
>> +    val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL |
>> +         TPDM_CMB_TIER_XTRIG_TSENAB);
>> +
>> +    /* Set pattern timestamp type and enablement */
>> +    if (drvdata->cmb->patt_ts)
>> +        val |= TPDM_CMB_TIER_PATT_TSENAB;
>
>  -- cut --
>> +    else
>> +        val &= ~TPDM_CMB_TIER_PATT_TSENAB;
>
>
> All the else cases in this function are superfluous. Please remove all
> of them.
I will update this in the next patch.
>
>> +
>> +    /* Set trigger timestamp */
>> +    if (drvdata->cmb->trig_ts)
>> +        val |= TPDM_CMB_TIER_XTRIG_TSENAB;
>> +    else
>> +        val &= ~TPDM_CMB_TIER_XTRIG_TSENAB;
>> +
>> +    /* Set all timestamp enablement*/
>> +    if (drvdata->cmb->ts_all)
>> +        val |= TPDM_CMB_TIER_TS_ALL;
>> +    else
>> +        val &= ~TPDM_CMB_TIER_TS_ALL;
>> +    writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
>> +}
>> +
>>   static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
>>   {
>>       u32 val, i;
>> @@ -347,6 +377,8 @@ static void tpdm_enable_cmb(struct tpdm_drvdata
>> *drvdata)
>>                   drvdata->base + TPDM_CMB_XPMR(i));
>>       }
>>   +    set_cmb_tier(drvdata);
>> +
>>       val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
>>       /*
>>        * Set to 0 for continuous CMB collection mode,
>> @@ -695,9 +727,17 @@ static ssize_t enable_ts_show(struct device *dev,
>>                     char *buf)
>>   {
>>       struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>> +    ssize_t size = 0;
>>   -    return sysfs_emit(buf, "%u\n",
>> -             (unsigned int)drvdata->dsb->patt_ts);
>> +    if (tpdm_has_dsb_dataset(drvdata))
>> +        size = sysfs_emit(buf, "%u\n",
>> +                 (unsigned int)drvdata->dsb->patt_ts);
>> +
>> +    if (tpdm_has_cmb_dataset(drvdata))
>> +        size = sysfs_emit(buf, "%u\n",
>> +                 (unsigned int)drvdata->cmb->patt_ts);
>
> Why does this need to show two values ? This must only show ONE value.
> How you deduce that might be based on the availability of the feature
> set. Or store the TS value in the drvdata and use that instead for
> controlling CMB/DSB.

Since both of CMB/DSB need to have "enable_ts" SysFs file, can I
separate them

as "enable_dsb_ts" and "enable_cmb_ts"? The path will be like below.

tpdm0/dsb_patt/enable_dsb_ts

tpdm1/cmb_patt/enable_cmb_ts

Is this design appropriate?

>
> Also, the sysfs documentation needs update, if this is going to
> control the CMB.

Sure. I will update the SysFs documentation according to the
modification in the

next patch series.


Best,

Tao

>
> Suzuki
>
>
>> +
>> +    return size;
>>   }
>>     /*
>> @@ -715,8 +755,13 @@ static ssize_t enable_ts_store(struct device *dev,
>>           return -EINVAL;
>>         spin_lock(&drvdata->spinlock);
>> -    drvdata->dsb->patt_ts = !!val;
>> +    if (tpdm_has_dsb_dataset(drvdata))
>> +        drvdata->dsb->patt_ts = !!val;
>> +
>> +    if (tpdm_has_cmb_dataset(drvdata))
>> +        drvdata->cmb->patt_ts = !!val;
>>       spin_unlock(&drvdata->spinlock);
>> +
>>       return size;
>>   }
>>   static DEVICE_ATTR_RW(enable_ts);
>> @@ -851,6 +896,68 @@ static ssize_t cmb_mode_store(struct device *dev,
>>   }
>>   static DEVICE_ATTR_RW(cmb_mode);
>>   +static ssize_t cmb_ts_all_show(struct device *dev,
>> +                   struct device_attribute *attr,
>> +                   char *buf)
>> +{
>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>> +
>> +    return sysfs_emit(buf, "%u\n",
>> +              (unsigned int)drvdata->cmb->ts_all);
>> +}
>> +
>> +static ssize_t cmb_ts_all_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 val;
>> +
>> +    if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
>> +        return -EINVAL;
>> +
>> +    spin_lock(&drvdata->spinlock);
>> +    if (val)
>> +        drvdata->cmb->ts_all = true;
>> +    else
>> +        drvdata->cmb->ts_all = false;
>> +    spin_unlock(&drvdata->spinlock);
>> +    return size;
>> +}
>> +static DEVICE_ATTR_RW(cmb_ts_all);
>> +
>> +static ssize_t cmb_trig_ts_show(struct device *dev,
>> +                struct device_attribute *attr,
>> +                char *buf)
>> +{
>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>> +
>> +    return sysfs_emit(buf, "%u\n",
>> +              (unsigned int)drvdata->cmb->trig_ts);
>> +}
>> +
>> +static ssize_t cmb_trig_ts_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 val;
>> +
>> +    if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
>> +        return -EINVAL;
>> +
>> +    spin_lock(&drvdata->spinlock);
>> +    if (val)
>> +        drvdata->cmb->trig_ts = true;
>> +    else
>> +        drvdata->cmb->trig_ts = false;
>> +    spin_unlock(&drvdata->spinlock);
>> +    return size;
>> +}
>> +static DEVICE_ATTR_RW(cmb_trig_ts);
>> +
>>   static struct attribute *tpdm_dsb_edge_attrs[] = {
>>       &dev_attr_ctrl_idx.attr,
>>       &dev_attr_ctrl_val.attr,
>> @@ -973,6 +1080,7 @@ static struct attribute *tpdm_cmb_patt_attrs[] = {
>>       CMB_PATT_ATTR(1),
>>       CMB_PATT_MASK_ATTR(0),
>>       CMB_PATT_MASK_ATTR(1),
>> +    &dev_attr_enable_ts.attr,
>>       NULL,
>>   };
>>   @@ -985,6 +1093,8 @@ static struct attribute *tpdm_dsb_attrs[] = {
>>     static struct attribute *tpdm_cmb_attrs[] = {
>>       &dev_attr_cmb_mode.attr,
>> +    &dev_attr_cmb_ts_all.attr,
>> +    &dev_attr_cmb_trig_ts.attr,
>>       NULL,
>>   };
>>   diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h
>> b/drivers/hwtracing/coresight/coresight-tpdm.h
>> index e90d008c1cb2..65b7ca6c4077 100644
>> --- a/drivers/hwtracing/coresight/coresight-tpdm.h
>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>> @@ -11,6 +11,8 @@
>>     /* CMB Subunit Registers */
>>   #define TPDM_CMB_CR        (0xA00)
>> +/*CMB subunit timestamp insertion enable register*/
>> +#define TPDM_CMB_TIER        (0xA04)
>>   /*CMB subunit timestamp pattern registers*/
>>   #define TPDM_CMB_TPR(n)        (0xA08 + (n * 4))
>>   /*CMB subunit timestamp pattern mask registers*/
>> @@ -24,6 +26,12 @@
>>   #define TPDM_CMB_CR_ENA        BIT(0)
>>   /* Trace collection mode for CMB subunit */
>>   #define TPDM_CMB_CR_MODE    BIT(1)
>> +/* Timestamp control for pattern match */
>> +#define TPDM_CMB_TIER_PATT_TSENAB    BIT(0)
>> +/* CMB CTI timestamp request */
>> +#define TPDM_CMB_TIER_XTRIG_TSENAB    BIT(1)
>> +/* For timestamp fo all trace */
>> +#define TPDM_CMB_TIER_TS_ALL        BIT(2)
>>     /*Patten register number*/
>>   #define TPDM_CMB_MAX_PATT        2
>> @@ -217,6 +225,9 @@ struct dsb_dataset {
>>    * @patt_mask:        Save value for pattern mask
>>    * @trig_patt:        Save value for trigger pattern
>>    * @trig_patt_mask:   Save value for trigger pattern mask
>> + * @patt_ts:          Indicates if pattern match for timestamp is
>> enabled.
>> + * @trig_ts:          Indicates if CTI trigger for timestamp is
>> enabled.
>> + * @ts_all:           Indicates if timestamp is enabled for all
>> packets.
>>    */
>>   struct cmb_dataset {
>>       u32            trace_mode;
>> @@ -224,6 +235,9 @@ struct cmb_dataset {
>>       u32            patt_mask[TPDM_CMB_MAX_PATT];
>>       u32            trig_patt[TPDM_CMB_MAX_PATT];
>>       u32            trig_patt_mask[TPDM_CMB_MAX_PATT];
>> +    bool            patt_ts;
>> +    bool            trig_ts;
>> +    bool            ts_all;
>>   };
>>     /**
>

2023-12-19 07:02:52

by Tao Zhang

[permalink] [raw]
Subject: Re: [PATCH v3 8/8] coresight-tpdm: Add msr register support for CMB


On 12/18/2023 7:02 PM, Suzuki K Poulose wrote:
> On 21/11/2023 02:24, Tao Zhang wrote:
>> Add the nodes for CMB subunit MSR(mux select register) support.
>> CMB MSRs(mux select registers) is to separate mux,arbitration,
>> ,interleaving,data packing control from stream filtering control.
>>
>> Reviewed-by: James Clark <[email protected]>
>> Signed-off-by: Tao Zhang <[email protected]>
>> Signed-off-by: Mao Jinlong <[email protected]>
>> ---
>>   .../testing/sysfs-bus-coresight-devices-tpdm  |  8 ++
>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 86 +++++++++++++++++++
>>   drivers/hwtracing/coresight/coresight-tpdm.h  | 16 +++-
>>   3 files changed, 109 insertions(+), 1 deletion(-)
>>
>> diff --git
>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>> index e0b77107be13..914f3fd81525 100644
>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>> @@ -249,3 +249,11 @@ Description:
>>           Accepts only one of the 2 values -  0 or 1.
>>           0 : Disable the timestamp of all trace packets.
>>           1 : Enable the timestamp of all trace packets.
>> +
>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
>> +Date:        September 2023
>> +KernelVersion    6.7
>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao Zhang
>> (QUIC) <[email protected]>
>> +Description:
>> +        (RW) Set/Get the MSR(mux select register) for the CMB subunit
>> +        TPDM.
>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>> index f6cda5616e84..7e331ea436cc 100644
>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>> @@ -86,6 +86,11 @@ static ssize_t tpdm_simple_dataset_show(struct
>> device *dev,
>>               return -EINVAL;
>>           return sysfs_emit(buf, "0x%x\n",
>>               drvdata->cmb->patt_mask[tpdm_attr->idx]);
>> +    case CMB_MSR:
>> +        if (tpdm_attr->idx >= drvdata->cmb_msr_num)
>> +            return -EINVAL;
>> +        return sysfs_emit(buf, "0x%x\n",
>> +                drvdata->cmb->msr[tpdm_attr->idx]);
>>       }
>>       return -EINVAL;
>>   }
>> @@ -162,6 +167,12 @@ static ssize_t tpdm_simple_dataset_store(struct
>> device *dev,
>>           else
>>               ret = -EINVAL;
>>           break;
>> +    case CMB_MSR:
>> +        if (tpdm_attr->idx < drvdata->cmb_msr_num)
>> +            drvdata->cmb->msr[tpdm_attr->idx] = val;
>> +        else
>> +            ret = -EINVAL;
>
>
> minor nit: Could we not break from here instead of adding return -EINVAL
> for each case ? (I understand it has been done for the existing cases.
> But I think we should clean up all of that, including the ones you added
> in Patch 5. Similarly for the dataset_show()

Sure, do I also need to change the DSB corresponding code? If so, how about

if I add a new patch to the next patch series to change the previous
existing cases?


Best,

Tao

>
>
> Suzuki
>
>
>> +        break;
>>       default:
>>           ret = -EINVAL;
>>       }
>> @@ -220,6 +231,23 @@ static umode_t tpdm_dsb_msr_is_visible(struct
>> kobject *kobj,
>>       return 0;
>>   }
>>   +static umode_t tpdm_cmb_msr_is_visible(struct kobject *kobj,
>> +                       struct attribute *attr, int n)
>> +{
>> +    struct device *dev = kobj_to_dev(kobj);
>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>> +
>> +    struct device_attribute *dev_attr =
>> +        container_of(attr, struct device_attribute, attr);
>> +    struct tpdm_dataset_attribute *tpdm_attr =
>> +        container_of(dev_attr, struct tpdm_dataset_attribute, attr);
>> +
>> +    if (tpdm_attr->idx < drvdata->cmb_msr_num)
>> +        return attr->mode;
>> +
>> +    return 0;
>> +}
>> +
>>   static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata)
>>   {
>>       if (tpdm_has_dsb_dataset(drvdata)) {
>> @@ -361,6 +389,15 @@ static void set_cmb_tier(struct tpdm_drvdata
>> *drvdata)
>>       writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
>>   }
>>   +static void set_cmb_msr(struct tpdm_drvdata *drvdata)
>> +{
>> +    int i;
>> +
>> +    for (i = 0; i < drvdata->cmb_msr_num; i++)
>> +        writel_relaxed(drvdata->cmb->msr[i],
>> +               drvdata->base + TPDM_CMB_MSR(i));
>> +}
>> +
>>   static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
>>   {
>>       u32 val, i;
>> @@ -379,6 +416,8 @@ static void tpdm_enable_cmb(struct tpdm_drvdata
>> *drvdata)
>>         set_cmb_tier(drvdata);
>>   +    set_cmb_msr(drvdata);
>> +
>>       val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
>>       /*
>>        * Set to 0 for continuous CMB collection mode,
>> @@ -1084,6 +1123,42 @@ static struct attribute *tpdm_cmb_patt_attrs[]
>> = {
>>       NULL,
>>   };
>>   +static struct attribute *tpdm_cmb_msr_attrs[] = {
>> +    CMB_MSR_ATTR(0),
>> +    CMB_MSR_ATTR(1),
>> +    CMB_MSR_ATTR(2),
>> +    CMB_MSR_ATTR(3),
>> +    CMB_MSR_ATTR(4),
>> +    CMB_MSR_ATTR(5),
>> +    CMB_MSR_ATTR(6),
>> +    CMB_MSR_ATTR(7),
>> +    CMB_MSR_ATTR(8),
>> +    CMB_MSR_ATTR(9),
>> +    CMB_MSR_ATTR(10),
>> +    CMB_MSR_ATTR(11),
>> +    CMB_MSR_ATTR(12),
>> +    CMB_MSR_ATTR(13),
>> +    CMB_MSR_ATTR(14),
>> +    CMB_MSR_ATTR(15),
>> +    CMB_MSR_ATTR(16),
>> +    CMB_MSR_ATTR(17),
>> +    CMB_MSR_ATTR(18),
>> +    CMB_MSR_ATTR(19),
>> +    CMB_MSR_ATTR(20),
>> +    CMB_MSR_ATTR(21),
>> +    CMB_MSR_ATTR(22),
>> +    CMB_MSR_ATTR(23),
>> +    CMB_MSR_ATTR(24),
>> +    CMB_MSR_ATTR(25),
>> +    CMB_MSR_ATTR(26),
>> +    CMB_MSR_ATTR(27),
>> +    CMB_MSR_ATTR(28),
>> +    CMB_MSR_ATTR(29),
>> +    CMB_MSR_ATTR(30),
>> +    CMB_MSR_ATTR(31),
>> +    NULL,
>> +};
>> +
>>   static struct attribute *tpdm_dsb_attrs[] = {
>>       &dev_attr_dsb_mode.attr,
>>       &dev_attr_dsb_trig_ts.attr,
>> @@ -1144,6 +1219,12 @@ static struct attribute_group
>> tpdm_cmb_patt_grp = {
>>       .name = "cmb_patt",
>>   };
>>   +static struct attribute_group tpdm_cmb_msr_grp = {
>> +    .attrs = tpdm_cmb_msr_attrs,
>> +    .is_visible = tpdm_cmb_msr_is_visible,
>> +    .name = "cmb_msr",
>> +};
>> +
>>   static const struct attribute_group *tpdm_attr_grps[] = {
>>       &tpdm_attr_grp,
>>       &tpdm_dsb_attr_grp,
>> @@ -1154,6 +1235,7 @@ static const struct attribute_group
>> *tpdm_attr_grps[] = {
>>       &tpdm_cmb_attr_grp,
>>       &tpdm_cmb_trig_patt_grp,
>>       &tpdm_cmb_patt_grp,
>> +    &tpdm_cmb_msr_grp,
>>       NULL,
>>   };
>>   @@ -1192,6 +1274,10 @@ static int tpdm_probe(struct amba_device
>> *adev, const struct amba_id *id)
>>           of_property_read_u32(drvdata->dev->of_node,
>>                  "qcom,dsb-msrs-num", &drvdata->dsb_msr_num);
>>   +    if (drvdata && tpdm_has_cmb_dataset(drvdata))
>> +        of_property_read_u32(drvdata->dev->of_node,
>> +               "qcom,cmb-msrs-num", &drvdata->cmb_msr_num);
>> +
>>       /* Set up coresight component description */
>>       desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
>>       if (!desc.name)
>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h
>> b/drivers/hwtracing/coresight/coresight-tpdm.h
>> index 65b7ca6c4077..255104d024ab 100644
>> --- a/drivers/hwtracing/coresight/coresight-tpdm.h
>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>> @@ -21,6 +21,8 @@
>>   #define TPDM_CMB_XPR(n)        (0xA18 + (n * 4))
>>   /*CMB subunit trigger pattern mask registers*/
>>   #define TPDM_CMB_XPMR(n)    (0xA20 + (n * 4))
>> +/* CMB MSR register */
>> +#define TPDM_CMB_MSR(n)        (0xA80 + (n * 4))
>>     /* Enable bit for CMB subunit */
>>   #define TPDM_CMB_CR_ENA        BIT(0)
>> @@ -36,6 +38,9 @@
>>   /*Patten register number*/
>>   #define TPDM_CMB_MAX_PATT        2
>>   +/* MAX number of DSB MSR */
>> +#define TPDM_CMB_MAX_MSR 32
>> +
>>   /* DSB Subunit Registers */
>>   #define TPDM_DSB_CR        (0x780)
>>   #define TPDM_DSB_TIER        (0x784)
>> @@ -186,6 +191,10 @@
>>           tpdm_simple_dataset_rw(tpmr##nr,        \
>>           CMB_PATT_MASK, nr)
>>   +#define CMB_MSR_ATTR(nr)                    \
>> +        tpdm_simple_dataset_rw(msr##nr,            \
>> +        CMB_MSR, nr)
>> +
>>   /**
>>    * struct dsb_dataset - specifics associated to dsb dataset
>>    * @mode:             DSB programming mode
>> @@ -225,6 +234,7 @@ struct dsb_dataset {
>>    * @patt_mask:        Save value for pattern mask
>>    * @trig_patt:        Save value for trigger pattern
>>    * @trig_patt_mask:   Save value for trigger pattern mask
>> + * @msr               Save value for MSR
>>    * @patt_ts:          Indicates if pattern match for timestamp is
>> enabled.
>>    * @trig_ts:          Indicates if CTI trigger for timestamp is
>> enabled.
>>    * @ts_all:           Indicates if timestamp is enabled for all
>> packets.
>> @@ -235,6 +245,7 @@ struct cmb_dataset {
>>       u32            patt_mask[TPDM_CMB_MAX_PATT];
>>       u32            trig_patt[TPDM_CMB_MAX_PATT];
>>       u32            trig_patt_mask[TPDM_CMB_MAX_PATT];
>> +    u32            msr[TPDM_CMB_MAX_MSR];
>>       bool            patt_ts;
>>       bool            trig_ts;
>>       bool            ts_all;
>> @@ -251,6 +262,7 @@ struct cmb_dataset {
>>    * @dsb         Specifics associated to TPDM DSB.
>>    * @cmb         Specifics associated to TPDM CMB.
>>    * @dsb_msr_num Number of MSR supported by DSB TPDM
>> + * @cmb_msr_num Number of MSR supported by CMB TPDM
>>    */
>>     struct tpdm_drvdata {
>> @@ -263,6 +275,7 @@ struct tpdm_drvdata {
>>       struct dsb_dataset    *dsb;
>>       struct cmb_dataset    *cmb;
>>       u32            dsb_msr_num;
>> +    u32            cmb_msr_num;
>>   };
>>     /* Enumerate members of various datasets */
>> @@ -277,7 +290,8 @@ enum dataset_mem {
>>       CMB_TRIG_PATT,
>>       CMB_TRIG_PATT_MASK,
>>       CMB_PATT,
>> -    CMB_PATT_MASK
>> +    CMB_PATT_MASK,
>> +    CMB_MSR
>>   };
>>     /**
>
> _______________________________________________
> CoreSight mailing list -- [email protected]
> To unsubscribe send an email to [email protected]

2023-12-19 10:27:43

by Mao Jinlong

[permalink] [raw]
Subject: Re: [PATCH v3 7/8] dt-bindings: arm: Add support for TPDM CMB MSR register



On 12/18/2023 8:17 PM, Jinlong Mao wrote:
>
>
> On 12/18/2023 7:56 PM, Suzuki K Poulose wrote:
>> Hi Tingwei Zhang
>>
>> On 18/12/2023 11:23, Tingwei Zhang wrote:
>>> On 12/18/2023 6:47 PM, Suzuki K Poulose wrote:
>>>> Tao Zhang,
>>>>
>>>> On 21/11/2023 07:24, Krzysztof Kozlowski wrote:
>>>>> On 21/11/2023 03:24, Tao Zhang wrote:
>>>>>> Add property "qcom,cmb_msr_num" to support CMB MSR(mux select
>>>>>> register)
>>>>>> for TPDM. It specifies the number of CMB MSR registers supported by
>>>>>> the TDPM.
>>>>>>
>>>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>>>> Signed-off-by: Mao Jinlong <[email protected]>
>>>>>> ---
>>>>>
>>>>> I prefer not to take any new Qualcomm Coresight bindings or
>>>>> Qualcomm SoC
>>>>> DTS nodes with Coresight till we fix all existing warnings. I don't
>>>>> know
>>>>> how to fix them, so I need help with them. No such fixing happened so
>>>>> far from Qcom, so pushback is my only way to get any attention.
>>>>>
>>>>> I already commented on this in other email thread.
>>>>
>>>> Are you addressing this ?
>>> The DT warning is fixed in
>>> https://lore.kernel.org/linux-arm-msm/[email protected]/.
>>> It's applied to linux-arm-msm yesterday.
>>
>> How are you supporting remote-etm ? We haven't merged the support for
>> it in drivers ? We haven't even reviewed the remote-etm support
>> patches ? Why weren't the coresight maintainers Cc ed on the "new"
>> binding support ?
>>
>> Suzuki
>>
>>
> Hi Suzuki,
>
> Sorry for missing coresight maintainers in the remote-etm binding patch.
> From the comments, we can add binding for the connected hardware first.
>
> https://lkml.org/lkml/2023/11/30/539
>
> Thanks
> Jinlong Mao
>
Hi Suzuki,

The dt-binding patch of remote-etm is not applied. I run dtbs_check
without dt-binding patch, there is no device tree warning. I will
merge the dt-binding patch of remote-etm to the remote etm patches to
make them review together.

[2/4] arm64: dts: qcom: msm8996: Fix 'in-ports' is a required property
commit: 9a6fc510a6a3ec150cb7450aec1e5f257e6fc77b
[3/4] arm64: dts: qcom: msm8998: Fix 'out-ports' is a required property
commit: ae5ee3562a2519214b12228545e88a203dd68bbd
[4/4] arm64: dts: qcom: Fix coresight warnings in in-ports and out-ports
commit: bdb6339fd46b8702ea7411b0b414587b86a40562

Thanks
Jinlong Mao
>>
>>>>
>>>> Suzuki
>>>>
>>>>>
>>>>> Best regards,
>>>>> Krzysztof
>>>>>
>>>>
>>>
>>

2023-12-19 13:52:49

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH v3 6/8] coresight-tpdm: Add timestamp control register support for the CMB

On 19/12/2023 02:43, Tao Zhang wrote:
>
> On 12/18/2023 6:46 PM, Suzuki K Poulose wrote:
>> On 21/11/2023 02:24, Tao Zhang wrote:
>>> CMB_TIER register is CMB subunit timestamp insertion enable register.
>>> Bit 0 is PATT_TSENAB bit. Set this bit to 1 to request a timestamp
>>> following a CMB interface pattern match. Bit 1 is XTRIG_TSENAB bit.
>>> Set this bit to 1 to request a timestamp following a CMB CTI timestamp
>>> request. Bit 2 is TS_ALL bit. Set this bit to 1 to request timestamp
>>> for all packets.
>>>
>>> Reviewed-by: James Clark <[email protected]>
>>> Signed-off-by: Tao Zhang <[email protected]>
>>> Signed-off-by: Jinlong Mao <[email protected]>
>>> ---
>>>   .../testing/sysfs-bus-coresight-devices-tpdm  |  35 ++++++
>>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 116 +++++++++++++++++-
>>>   drivers/hwtracing/coresight/coresight-tpdm.h  |  14 +++
>>>   3 files changed, 162 insertions(+), 3 deletions(-)
>>>
>>> diff --git
>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>> index 53662ce7c2d0..e0b77107be13 100644
>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>> @@ -214,3 +214,38 @@ KernelVersion    6.7
>>>   Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>> Zhang (QUIC) <[email protected]>
>>>   Description:
>>>           (RW) Set/Get the mask of the pattern for the CMB subunit TPDM.
>>> +
>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_patt/enable_ts
>>> +Date:        September 2023
>>> +KernelVersion    6.7
>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao Zhang
>>> (QUIC) <[email protected]>
>>> +Description:
>>> +        (Write) Set the pattern timestamp of CMB tpdm. Read
>>> +        the pattern timestamp of CMB tpdm.
>>> +
>>> +        Accepts only one of the 2 values -  0 or 1.
>>> +        0 : Disable CMB pattern timestamp.
>>> +        1 : Enable CMB pattern timestamp.
>>> +
>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_ts
>>> +Date:        September 2023
>>> +KernelVersion    6.7
>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao Zhang
>>> (QUIC) <[email protected]>
>>> +Description:
>>> +        (RW) Set/Get the trigger timestamp of the CMB for tpdm.
>>> +
>>> +        Accepts only one of the 2 values -  0 or 1.
>>> +        0 : Set the CMB trigger type to false
>>> +        1 : Set the CMB trigger type to true
>>> +
>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_ts_all
>>> +Date:        September 2023
>>> +KernelVersion    6.7
>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao Zhang
>>> (QUIC) <[email protected]>
>>> +Description:
>>> +        (RW) Read or write the status of timestamp upon all interface.
>>> +        Only value 0 and 1  can be written to this node. Set this
>>> node to 1 to requeset
>>> +        timestamp to all trace packet.
>>> +        Accepts only one of the 2 values -  0 or 1.
>>> +        0 : Disable the timestamp of all trace packets.
>>> +        1 : Enable the timestamp of all trace packets.
>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>> index 894d4309f1c7..f6cda5616e84 100644
>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>> @@ -331,6 +331,36 @@ static void tpdm_enable_dsb(struct tpdm_drvdata
>>> *drvdata)
>>>       writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
>>>   }
>>>   +static void set_cmb_tier(struct tpdm_drvdata *drvdata)
>>> +{
>>> +    u32 val;
>>> +
>>> +    val = readl_relaxed(drvdata->base + TPDM_CMB_TIER);
>>> +
>>> +    /* Clear all relevant fields */
>>> +    val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL |
>>> +         TPDM_CMB_TIER_XTRIG_TSENAB);
>>> +
>>> +    /* Set pattern timestamp type and enablement */
>>> +    if (drvdata->cmb->patt_ts)
>>> +        val |= TPDM_CMB_TIER_PATT_TSENAB;
>>
>>  -- cut --
>>> +    else
>>> +        val &= ~TPDM_CMB_TIER_PATT_TSENAB;
>>
>>
>> All the else cases in this function are superfluous. Please remove all
>> of them.
> I will update this in the next patch.
>>
>>> +
>>> +    /* Set trigger timestamp */
>>> +    if (drvdata->cmb->trig_ts)
>>> +        val |= TPDM_CMB_TIER_XTRIG_TSENAB;
>>> +    else
>>> +        val &= ~TPDM_CMB_TIER_XTRIG_TSENAB;
>>> +
>>> +    /* Set all timestamp enablement*/
>>> +    if (drvdata->cmb->ts_all)
>>> +        val |= TPDM_CMB_TIER_TS_ALL;
>>> +    else
>>> +        val &= ~TPDM_CMB_TIER_TS_ALL;
>>> +    writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
>>> +}
>>> +
>>>   static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
>>>   {
>>>       u32 val, i;
>>> @@ -347,6 +377,8 @@ static void tpdm_enable_cmb(struct tpdm_drvdata
>>> *drvdata)
>>>                   drvdata->base + TPDM_CMB_XPMR(i));
>>>       }
>>>   +    set_cmb_tier(drvdata);
>>> +
>>>       val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
>>>       /*
>>>        * Set to 0 for continuous CMB collection mode,
>>> @@ -695,9 +727,17 @@ static ssize_t enable_ts_show(struct device *dev,
>>>                     char *buf)
>>>   {
>>>       struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>> +    ssize_t size = 0;
>>>   -    return sysfs_emit(buf, "%u\n",
>>> -             (unsigned int)drvdata->dsb->patt_ts);
>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>> +        size = sysfs_emit(buf, "%u\n",
>>> +                 (unsigned int)drvdata->dsb->patt_ts);
>>> +
>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>> +        size = sysfs_emit(buf, "%u\n",
>>> +                 (unsigned int)drvdata->cmb->patt_ts);
>>
>> Why does this need to show two values ? This must only show ONE value.
>> How you deduce that might be based on the availability of the feature
>> set. Or store the TS value in the drvdata and use that instead for
>> controlling CMB/DSB.
>
> Since both of CMB/DSB need to have "enable_ts" SysFs file, can I
> separate them

The question really is, do we need fine grained control. i.e.,

enable TS for DSB but not for CMB or vice versa.

I am not an expert on the usage scenario of the same. So, if you/Qcomm
thinks the users need separate, fine grained control for timestamp
for the DSB and CMB, then yes, follow your recommendation below.
i.e., tpdm.../dsb_patt/enable_ts

> as "enable_dsb_ts" and "enable_cmb_ts"? The path will be like below.
>
> tpdm0/dsb_patt/enable_dsb_ts

You don't need enable_dsb_ts. It could be "enable_ts"

>
> tpdm1/cmb_patt/enable_cmb_ts
>
> Is this design appropriate?


Otherwise, stick to single enable_ts : which enables the ts for both
CMB/DSB. And it only ever show one value : 0 (TS is disabled for both
CMB/DSB) 1 : TS enabled for both.

Suzuki


>>

>> Also, the sysfs documentation needs update, if this is going to
>> control the CMB.
>
> Sure. I will update the SysFs documentation according to the
> modification in the
>
> next patch series.
>
>
> Best,
>
> Tao
>
>>
>> Suzuki
>>
>>
>>> +
>>> +    return size;
>>>   }
>>>     /*
>>> @@ -715,8 +755,13 @@ static ssize_t enable_ts_store(struct device *dev,
>>>           return -EINVAL;
>>>         spin_lock(&drvdata->spinlock);
>>> -    drvdata->dsb->patt_ts = !!val;
>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>> +        drvdata->dsb->patt_ts = !!val;
>>> +
>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>> +        drvdata->cmb->patt_ts = !!val;
>>>       spin_unlock(&drvdata->spinlock);
>>> +
>>>       return size;
>>>   }
>>>   static DEVICE_ATTR_RW(enable_ts);
>>> @@ -851,6 +896,68 @@ static ssize_t cmb_mode_store(struct device *dev,
>>>   }
>>>   static DEVICE_ATTR_RW(cmb_mode);
>>>   +static ssize_t cmb_ts_all_show(struct device *dev,
>>> +                   struct device_attribute *attr,
>>> +                   char *buf)
>>> +{
>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>> +
>>> +    return sysfs_emit(buf, "%u\n",
>>> +              (unsigned int)drvdata->cmb->ts_all);
>>> +}
>>> +
>>> +static ssize_t cmb_ts_all_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 val;
>>> +
>>> +    if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
>>> +        return -EINVAL;
>>> +
>>> +    spin_lock(&drvdata->spinlock);
>>> +    if (val)
>>> +        drvdata->cmb->ts_all = true;
>>> +    else
>>> +        drvdata->cmb->ts_all = false;
>>> +    spin_unlock(&drvdata->spinlock);
>>> +    return size;
>>> +}
>>> +static DEVICE_ATTR_RW(cmb_ts_all);
>>> +
>>> +static ssize_t cmb_trig_ts_show(struct device *dev,
>>> +                struct device_attribute *attr,
>>> +                char *buf)
>>> +{
>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>> +
>>> +    return sysfs_emit(buf, "%u\n",
>>> +              (unsigned int)drvdata->cmb->trig_ts);
>>> +}
>>> +
>>> +static ssize_t cmb_trig_ts_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 val;
>>> +
>>> +    if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
>>> +        return -EINVAL;
>>> +
>>> +    spin_lock(&drvdata->spinlock);
>>> +    if (val)
>>> +        drvdata->cmb->trig_ts = true;
>>> +    else
>>> +        drvdata->cmb->trig_ts = false;
>>> +    spin_unlock(&drvdata->spinlock);
>>> +    return size;
>>> +}
>>> +static DEVICE_ATTR_RW(cmb_trig_ts);
>>> +
>>>   static struct attribute *tpdm_dsb_edge_attrs[] = {
>>>       &dev_attr_ctrl_idx.attr,
>>>       &dev_attr_ctrl_val.attr,
>>> @@ -973,6 +1080,7 @@ static struct attribute *tpdm_cmb_patt_attrs[] = {
>>>       CMB_PATT_ATTR(1),
>>>       CMB_PATT_MASK_ATTR(0),
>>>       CMB_PATT_MASK_ATTR(1),
>>> +    &dev_attr_enable_ts.attr,
>>>       NULL,
>>>   };
>>>   @@ -985,6 +1093,8 @@ static struct attribute *tpdm_dsb_attrs[] = {
>>>     static struct attribute *tpdm_cmb_attrs[] = {
>>>       &dev_attr_cmb_mode.attr,
>>> +    &dev_attr_cmb_ts_all.attr,
>>> +    &dev_attr_cmb_trig_ts.attr,
>>>       NULL,
>>>   };
>>>   diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h
>>> b/drivers/hwtracing/coresight/coresight-tpdm.h
>>> index e90d008c1cb2..65b7ca6c4077 100644
>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.h
>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>>> @@ -11,6 +11,8 @@
>>>     /* CMB Subunit Registers */
>>>   #define TPDM_CMB_CR        (0xA00)
>>> +/*CMB subunit timestamp insertion enable register*/
>>> +#define TPDM_CMB_TIER        (0xA04)
>>>   /*CMB subunit timestamp pattern registers*/
>>>   #define TPDM_CMB_TPR(n)        (0xA08 + (n * 4))
>>>   /*CMB subunit timestamp pattern mask registers*/
>>> @@ -24,6 +26,12 @@
>>>   #define TPDM_CMB_CR_ENA        BIT(0)
>>>   /* Trace collection mode for CMB subunit */
>>>   #define TPDM_CMB_CR_MODE    BIT(1)
>>> +/* Timestamp control for pattern match */
>>> +#define TPDM_CMB_TIER_PATT_TSENAB    BIT(0)
>>> +/* CMB CTI timestamp request */
>>> +#define TPDM_CMB_TIER_XTRIG_TSENAB    BIT(1)
>>> +/* For timestamp fo all trace */
>>> +#define TPDM_CMB_TIER_TS_ALL        BIT(2)
>>>     /*Patten register number*/
>>>   #define TPDM_CMB_MAX_PATT        2
>>> @@ -217,6 +225,9 @@ struct dsb_dataset {
>>>    * @patt_mask:        Save value for pattern mask
>>>    * @trig_patt:        Save value for trigger pattern
>>>    * @trig_patt_mask:   Save value for trigger pattern mask
>>> + * @patt_ts:          Indicates if pattern match for timestamp is
>>> enabled.
>>> + * @trig_ts:          Indicates if CTI trigger for timestamp is
>>> enabled.
>>> + * @ts_all:           Indicates if timestamp is enabled for all
>>> packets.
>>>    */
>>>   struct cmb_dataset {
>>>       u32            trace_mode;
>>> @@ -224,6 +235,9 @@ struct cmb_dataset {
>>>       u32            patt_mask[TPDM_CMB_MAX_PATT];
>>>       u32            trig_patt[TPDM_CMB_MAX_PATT];
>>>       u32            trig_patt_mask[TPDM_CMB_MAX_PATT];
>>> +    bool            patt_ts;
>>> +    bool            trig_ts;
>>> +    bool            ts_all;
>>>   };
>>>     /**
>>


2023-12-19 13:54:17

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH v3 2/8] coresight-tpda: Add support to configure CMB element

On 19/12/2023 02:13, Tao Zhang wrote:
>
> On 12/18/2023 6:27 PM, Suzuki K Poulose wrote:
>> On 21/11/2023 02:24, Tao Zhang wrote:
>>> Read the CMB element size from the device tree. Set the register
>>> bit that controls the CMB element size of the corresponding port.
>>>
>>> Signed-off-by: Tao Zhang <[email protected]>
>>> Signed-off-by: Mao Jinlong <[email protected]>
>>> ---
>>>   drivers/hwtracing/coresight/coresight-tpda.c | 117 +++++++++++--------
>>>   drivers/hwtracing/coresight/coresight-tpda.h |   6 +
>>>   2 files changed, 74 insertions(+), 49 deletions(-)
>>>
>>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c
>>> b/drivers/hwtracing/coresight/coresight-tpda.c
>>> index 5f82737c37bb..e3762f38abb3 100644
>>> --- a/drivers/hwtracing/coresight/coresight-tpda.c
>>> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
>>> @@ -28,24 +28,54 @@ static bool coresight_device_is_tpdm(struct
>>> coresight_device *csdev)
>>>               CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM);
>>>   }
>>>   +static void tpdm_clear_element_size(struct coresight_device *csdev)
>>> +{
>>> +    struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>>> +
>>> +    if (drvdata->dsb_esize)
>>> +        drvdata->dsb_esize = 0;
>>> +    if (drvdata->cmb_esize)
>>> +        drvdata->cmb_esize = 0;
>>
>> Why do we need the if (...) check here ?
>
> The element size of all the TPDM sub-unit should be set to 0 here.
>
> I will update this in the next patch series.
>
>>
>>> +}
>>> +
>>> +static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32
>>> *val)
>>> +{
>>> +
>>> +    if (drvdata->dsb_esize == 64)
>>> +        *val |= TPDA_Pn_CR_DSBSIZE;
>>> +    else if (drvdata->dsb_esize == 32)
>>> +        *val &= ~TPDA_Pn_CR_DSBSIZE;
>>> +
>>> +    if (drvdata->cmb_esize == 64)
>>> +        *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2);
>>> +    else if (drvdata->cmb_esize == 32)
>>> +        *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1);
>>> +    else if (drvdata->cmb_esize == 8)
>>> +        *val &= ~TPDA_Pn_CR_CMBSIZE;
>>> +}
>>> +
>>
>>
>>>   /*
>>> - * Read the DSB element size from the TPDM device
>>> + * Read the element size from the TPDM device
>>>    * Returns
>>> - *    The dsb element size read from the devicetree if available.
>>> + *    The element size read from the devicetree if available.
>>>    *    0 - Otherwise, with a warning once.
>>
>> This doesn't match the function ? It return 0 on success and
>> error (-EINVAL) on failure ?
>
> 0 means the element size property is found from the devicetree.
>
> Otherwise, it will return error(-EINVAL).
>
> I will update this in the next patch series.
>
>>
>>>    */
>>> -static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
>>> +static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
>>> +                  struct coresight_device *csdev)
>>>   {
>>> -    int rc = 0;
>>> -    u8 size = 0;
>>> -
>>> -    rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>>> -            "qcom,dsb-element-size", &size);
>>> +    int rc = -EINVAL;
>>> +
>>> +    if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>>> +            "qcom,dsb-element-size", &drvdata->dsb_esize))
>>> +        rc = 0;
>>> +    if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>>> +            "qcom,cmb-element-size", &drvdata->cmb_esize))
>>> +        rc = 0;
>>
>> Are we not silently resetting the error if the former failed ?
>>
>> Could we not :
>>
>>     rc |= fwnode_...
>>
>>     rc |= fwnode_...
>>
>> instead ?
>>
>> Also what is the expectation here ? Are these properties a MUST for
>> TPDM ?
>
> The TPDM must have one of the element size property. As long as one

Please add a comment in the function. Someone else might try to "fix"
it otherwise.

Suzuki
>
> can be found, this TPDM configuration can be considered valid. So this
>
> function will return 0 if one of the element size property is found.


>
>
> Best,
>
> Tao
>
>>
>>>       if (rc)
>>>           dev_warn_once(&csdev->dev,
>>> -            "Failed to read TPDM DSB Element size: %d\n", rc);
>>> +            "Failed to read TPDM Element size: %d\n", rc);
>>>   -    return size;
>>> +    return rc;
>>>   }
>>>     /*
>>> @@ -56,11 +86,12 @@ static int tpdm_read_dsb_element_size(struct
>>> coresight_device *csdev)
>>>    * Parameter "inport" is used to pass in the input port number
>>>    * of TPDA, and it is set to -1 in the recursize call.
>>>    */
>>> -static int tpda_get_element_size(struct coresight_device *csdev,
>>> +static int tpda_get_element_size(struct tpda_drvdata *drvdata,
>>> +                 struct coresight_device *csdev,
>>>                    int inport)
>>>   {
>>> -    int dsb_size = -ENOENT;
>>> -    int i, size;
>>> +    int rc = 0;
>>> +    int i;
>>>       struct coresight_device *in;
>>>         for (i = 0; i < csdev->pdata->nr_inconns; i++) {
>>> @@ -74,25 +105,21 @@ static int tpda_get_element_size(struct
>>> coresight_device *csdev,
>>>               continue;
>>>             if (coresight_device_is_tpdm(in)) {
>>> -            size = tpdm_read_dsb_element_size(in);
>>> +            if ((drvdata->dsb_esize) || (drvdata->cmb_esize))
>>> +                return -EEXIST;
>>> +            rc = tpdm_read_element_size(drvdata, in);
>>> +            if (rc)
>>> +                return rc;
>>>           } else {
>>>               /* Recurse down the path */
>>> -            size = tpda_get_element_size(in, -1);
>>> -        }
>>> -
>>> -        if (size < 0)
>>> -            return size;
>>> -
>>> -        if (dsb_size < 0) {
>>> -            /* Found a size, save it. */
>>> -            dsb_size = size;
>>> -        } else {
>>> -            /* Found duplicate TPDMs */
>>> -            return -EEXIST;
>>> +            rc = tpda_get_element_size(drvdata, in, -1);
>>> +            if (rc)
>>> +                return rc;
>>>           }
>>>       }
>>>   -    return dsb_size;
>>> +
>>> +    return rc;
>>>   }
>>>     /* Settings pre enabling port control register */
>>> @@ -109,7 +136,7 @@ static void tpda_enable_pre_port(struct
>>> tpda_drvdata *drvdata)
>>>   static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
>>>   {
>>>       u32 val;
>>> -    int size;
>>> +    int rc;
>>>         val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
>>>       /*
>>> @@ -117,29 +144,21 @@ static int tpda_enable_port(struct tpda_drvdata
>>> *drvdata, int port)
>>>        * Set the bit to 0 if the size is 32
>>>        * Set the bit to 1 if the size is 64
>>>        */
>>> -    size = tpda_get_element_size(drvdata->csdev, port);
>>> -    switch (size) {
>>> -    case 32:
>>> -        val &= ~TPDA_Pn_CR_DSBSIZE;
>>> -        break;
>>> -    case 64:
>>> -        val |= TPDA_Pn_CR_DSBSIZE;
>>> -        break;
>>> -    case 0:
>>> -        return -EEXIST;
>>> -    case -EEXIST:
>>> +    tpdm_clear_element_size(drvdata->csdev);
>>> +    rc = tpda_get_element_size(drvdata, drvdata->csdev, port);
>>> +    if (!rc && ((drvdata->dsb_esize) || (drvdata->cmb_esize))) {
>>> +        tpda_set_element_size(drvdata, &val);
>>> +        /* Enable the port */
>>> +        val |= TPDA_Pn_CR_ENA;
>>> +        writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
>>> +    } else if (rc == -EEXIST)
>>>           dev_warn_once(&drvdata->csdev->dev,
>>> -            "Detected multiple TPDMs on port %d", -EEXIST);
>>> -        return -EEXIST;
>>> -    default:
>>> -        return -EINVAL;
>>> -    }
>>> -
>>> -    /* Enable the port */
>>> -    val |= TPDA_Pn_CR_ENA;
>>> -    writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
>>> +                  "Detected multiple TPDMs on port %d", -EEXIST);
>>> +    else
>>> +        dev_warn_once(&drvdata->csdev->dev,
>>> +                  "Didn't find TPDM elem size");
>>
>> "element size"
>>
>>>   -    return 0;
>>> +    return rc;
>>>   }
>>>     static int __tpda_enable(struct tpda_drvdata *drvdata, int port)
>>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.h
>>> b/drivers/hwtracing/coresight/coresight-tpda.h
>>> index b3b38fd41b64..29164fd9711f 100644
>>> --- a/drivers/hwtracing/coresight/coresight-tpda.h
>>> +++ b/drivers/hwtracing/coresight/coresight-tpda.h
>>> @@ -10,6 +10,8 @@
>>>   #define TPDA_Pn_CR(n)        (0x004 + (n * 4))
>>>   /* Aggregator port enable bit */
>>>   #define TPDA_Pn_CR_ENA        BIT(0)
>>> +/* Aggregator port CMB data set element size bit */
>>> +#define TPDA_Pn_CR_CMBSIZE        GENMASK(7, 6)
>>>   /* Aggregator port DSB data set element size bit */
>>>   #define TPDA_Pn_CR_DSBSIZE        BIT(8)
>>>   @@ -25,6 +27,8 @@
>>>    * @csdev:      component vitals needed by the framework.
>>>    * @spinlock:   lock for the drvdata value.
>>>    * @enable:     enable status of the component.
>>> + * @dsb_esize   Record the DSB element size.
>>> + * @cmb_esize   Record the CMB element size.
>>>    */
>>>   struct tpda_drvdata {
>>>       void __iomem        *base;
>>> @@ -32,6 +36,8 @@ struct tpda_drvdata {
>>>       struct coresight_device    *csdev;
>>>       spinlock_t        spinlock;
>>>       u8            atid;
>>> +    u8            dsb_esize;
>>> +    u8            cmb_esize;
>>>   };
>>>     #endif  /* _CORESIGHT_CORESIGHT_TPDA_H */
>>
>> Suzuki
>>
>>


2023-12-19 13:59:47

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH v3 2/8] coresight-tpda: Add support to configure CMB element

On 18/12/2023 10:27, Suzuki K Poulose wrote:
> On 21/11/2023 02:24, Tao Zhang wrote:
>> Read the CMB element size from the device tree. Set the register
>> bit that controls the CMB element size of the corresponding port.
>>
>> Signed-off-by: Tao Zhang <[email protected]>
>> Signed-off-by: Mao Jinlong <[email protected]>
>> ---
>>   drivers/hwtracing/coresight/coresight-tpda.c | 117 +++++++++++--------
>>   drivers/hwtracing/coresight/coresight-tpda.h |   6 +
>>   2 files changed, 74 insertions(+), 49 deletions(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c
>> b/drivers/hwtracing/coresight/coresight-tpda.c
>> index 5f82737c37bb..e3762f38abb3 100644
>> --- a/drivers/hwtracing/coresight/coresight-tpda.c
>> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
>> @@ -28,24 +28,54 @@ static bool coresight_device_is_tpdm(struct
>> coresight_device *csdev)
>>               CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM);
>>   }
>> +static void tpdm_clear_element_size(struct coresight_device *csdev)
>> +{
>> +    struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> +
>> +    if (drvdata->dsb_esize)
>> +        drvdata->dsb_esize = 0;
>> +    if (drvdata->cmb_esize)
>> +        drvdata->cmb_esize = 0;
>
> Why do we need the if (...) check here ?
>
>> +}
>> +
>> +static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32
>> *val)
>> +{
>> +
>> +    if (drvdata->dsb_esize == 64)
>> +        *val |= TPDA_Pn_CR_DSBSIZE;
>> +    else if (drvdata->dsb_esize == 32)
>> +        *val &= ~TPDA_Pn_CR_DSBSIZE;
>> +
>> +    if (drvdata->cmb_esize == 64)
>> +        *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2);
>> +    else if (drvdata->cmb_esize == 32)
>> +        *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1);
>> +    else if (drvdata->cmb_esize == 8)
>> +        *val &= ~TPDA_Pn_CR_CMBSIZE;
>> +}
>> +
>
>
>>   /*
>> - * Read the DSB element size from the TPDM device
>> + * Read the element size from the TPDM device
>>    * Returns
>> - *    The dsb element size read from the devicetree if available.
>> + *    The element size read from the devicetree if available.
>>    *    0 - Otherwise, with a warning once.
>
> This doesn't match the function ? It return 0 on success and
> error (-EINVAL) on failure ?
>
>>    */
>> -static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
>> +static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
>> +                  struct coresight_device *csdev)
>>   {
>> -    int rc = 0;
>> -    u8 size = 0;
>> -
>> -    rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>> -            "qcom,dsb-element-size", &size);
>> +    int rc = -EINVAL;
>> +
>> +    if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>> +            "qcom,dsb-element-size", &drvdata->dsb_esize))
>> +        rc = 0;
>> +    if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>> +            "qcom,cmb-element-size", &drvdata->cmb_esize))

At this point we have the csdev->dev.parent as the TPDM device and with:

#include <coresight-tpdm.h>

struct tpdm_drvdata *tpdm_data = get_drvdata(csdev->dev.parent);

if (tpdm_has_cmb(tpdm_data)) {
rc = fwnode_...(... "qcom,cmb-element-size"...)
}

if (tpdm_has_dsb(tpdm_data)) {
rc = fwnode_...(..., "qcom,dsb-element-size"..)
}

Suzuki


>> +        rc = 0;
>
> Are we not silently resetting the error if the former failed ?
>
> Could we not :
>
>     rc |= fwnode_...
>
>     rc |= fwnode_...
>
> instead ?
>
> Also what is the expectation here ? Are these properties a MUST for
> TPDM ?
>
>>       if (rc)
>>           dev_warn_once(&csdev->dev,
>> -            "Failed to read TPDM DSB Element size: %d\n", rc);
>> +            "Failed to read TPDM Element size: %d\n", rc);
>> -    return size;
>> +    return rc;
>>   }
>>   /*
>> @@ -56,11 +86,12 @@ static int tpdm_read_dsb_element_size(struct
>> coresight_device *csdev)
>>    * Parameter "inport" is used to pass in the input port number
>>    * of TPDA, and it is set to -1 in the recursize call.
>>    */
>> -static int tpda_get_element_size(struct coresight_device *csdev,
>> +static int tpda_get_element_size(struct tpda_drvdata *drvdata,
>> +                 struct coresight_device *csdev,
>>                    int inport)
>>   {
>> -    int dsb_size = -ENOENT;
>> -    int i, size;
>> +    int rc = 0;
>> +    int i;
>>       struct coresight_device *in;
>>       for (i = 0; i < csdev->pdata->nr_inconns; i++) {
>> @@ -74,25 +105,21 @@ static int tpda_get_element_size(struct
>> coresight_device *csdev,
>>               continue;
>>           if (coresight_device_is_tpdm(in)) {
>> -            size = tpdm_read_dsb_element_size(in);
>> +            if ((drvdata->dsb_esize) || (drvdata->cmb_esize))
>> +                return -EEXIST;
>> +            rc = tpdm_read_element_size(drvdata, in);
>> +            if (rc)
>> +                return rc;
>>           } else {
>>               /* Recurse down the path */
>> -            size = tpda_get_element_size(in, -1);
>> -        }
>> -
>> -        if (size < 0)
>> -            return size;
>> -
>> -        if (dsb_size < 0) {
>> -            /* Found a size, save it. */
>> -            dsb_size = size;
>> -        } else {
>> -            /* Found duplicate TPDMs */
>> -            return -EEXIST;
>> +            rc = tpda_get_element_size(drvdata, in, -1);
>> +            if (rc)
>> +                return rc;
>>           }
>>       }
>> -    return dsb_size;
>> +
>> +    return rc;
>>   }
>>   /* Settings pre enabling port control register */
>> @@ -109,7 +136,7 @@ static void tpda_enable_pre_port(struct
>> tpda_drvdata *drvdata)
>>   static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
>>   {
>>       u32 val;
>> -    int size;
>> +    int rc;
>>       val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
>>       /*
>> @@ -117,29 +144,21 @@ static int tpda_enable_port(struct tpda_drvdata
>> *drvdata, int port)
>>        * Set the bit to 0 if the size is 32
>>        * Set the bit to 1 if the size is 64
>>        */
>> -    size = tpda_get_element_size(drvdata->csdev, port);
>> -    switch (size) {
>> -    case 32:
>> -        val &= ~TPDA_Pn_CR_DSBSIZE;
>> -        break;
>> -    case 64:
>> -        val |= TPDA_Pn_CR_DSBSIZE;
>> -        break;
>> -    case 0:
>> -        return -EEXIST;
>> -    case -EEXIST:
>> +    tpdm_clear_element_size(drvdata->csdev);
>> +    rc = tpda_get_element_size(drvdata, drvdata->csdev, port);
>> +    if (!rc && ((drvdata->dsb_esize) || (drvdata->cmb_esize))) {
>> +        tpda_set_element_size(drvdata, &val);
>> +        /* Enable the port */
>> +        val |= TPDA_Pn_CR_ENA;
>> +        writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
>> +    } else if (rc == -EEXIST)
>>           dev_warn_once(&drvdata->csdev->dev,
>> -            "Detected multiple TPDMs on port %d", -EEXIST);
>> -        return -EEXIST;
>> -    default:
>> -        return -EINVAL;
>> -    }
>> -
>> -    /* Enable the port */
>> -    val |= TPDA_Pn_CR_ENA;
>> -    writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
>> +                  "Detected multiple TPDMs on port %d", -EEXIST);
>> +    else
>> +        dev_warn_once(&drvdata->csdev->dev,
>> +                  "Didn't find TPDM elem size");
>
> "element size"
>
>> -    return 0;
>> +    return rc;
>>   }
>>   static int __tpda_enable(struct tpda_drvdata *drvdata, int port)
>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.h
>> b/drivers/hwtracing/coresight/coresight-tpda.h
>> index b3b38fd41b64..29164fd9711f 100644
>> --- a/drivers/hwtracing/coresight/coresight-tpda.h
>> +++ b/drivers/hwtracing/coresight/coresight-tpda.h
>> @@ -10,6 +10,8 @@
>>   #define TPDA_Pn_CR(n)        (0x004 + (n * 4))
>>   /* Aggregator port enable bit */
>>   #define TPDA_Pn_CR_ENA        BIT(0)
>> +/* Aggregator port CMB data set element size bit */
>> +#define TPDA_Pn_CR_CMBSIZE        GENMASK(7, 6)
>>   /* Aggregator port DSB data set element size bit */
>>   #define TPDA_Pn_CR_DSBSIZE        BIT(8)
>> @@ -25,6 +27,8 @@
>>    * @csdev:      component vitals needed by the framework.
>>    * @spinlock:   lock for the drvdata value.
>>    * @enable:     enable status of the component.
>> + * @dsb_esize   Record the DSB element size.
>> + * @cmb_esize   Record the CMB element size.
>>    */
>>   struct tpda_drvdata {
>>       void __iomem        *base;
>> @@ -32,6 +36,8 @@ struct tpda_drvdata {
>>       struct coresight_device    *csdev;
>>       spinlock_t        spinlock;
>>       u8            atid;
>> +    u8            dsb_esize;
>> +    u8            cmb_esize;
>>   };
>>   #endif  /* _CORESIGHT_CORESIGHT_TPDA_H */
>
> Suzuki
>
>


2023-12-19 14:13:00

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH v3 8/8] coresight-tpdm: Add msr register support for CMB

On 19/12/2023 06:58, Tao Zhang wrote:
>
> On 12/18/2023 7:02 PM, Suzuki K Poulose wrote:
>> On 21/11/2023 02:24, Tao Zhang wrote:
>>> Add the nodes for CMB subunit MSR(mux select register) support.
>>> CMB MSRs(mux select registers) is to separate mux,arbitration,
>>> ,interleaving,data packing control from stream filtering control.
>>>
>>> Reviewed-by: James Clark <[email protected]>
>>> Signed-off-by: Tao Zhang <[email protected]>
>>> Signed-off-by: Mao Jinlong <[email protected]>
>>> ---
>>>   .../testing/sysfs-bus-coresight-devices-tpdm  |  8 ++
>>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 86 +++++++++++++++++++
>>>   drivers/hwtracing/coresight/coresight-tpdm.h  | 16 +++-
>>>   3 files changed, 109 insertions(+), 1 deletion(-)
>>>
>>> diff --git
>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>> index e0b77107be13..914f3fd81525 100644
>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>> @@ -249,3 +249,11 @@ Description:
>>>           Accepts only one of the 2 values -  0 or 1.
>>>           0 : Disable the timestamp of all trace packets.
>>>           1 : Enable the timestamp of all trace packets.
>>> +
>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
>>> +Date:        September 2023
>>> +KernelVersion    6.7
>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao Zhang
>>> (QUIC) <[email protected]>
>>> +Description:
>>> +        (RW) Set/Get the MSR(mux select register) for the CMB subunit
>>> +        TPDM.
>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>> index f6cda5616e84..7e331ea436cc 100644
>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>> @@ -86,6 +86,11 @@ static ssize_t tpdm_simple_dataset_show(struct
>>> device *dev,
>>>               return -EINVAL;
>>>           return sysfs_emit(buf, "0x%x\n",
>>>               drvdata->cmb->patt_mask[tpdm_attr->idx]);
>>> +    case CMB_MSR:
>>> +        if (tpdm_attr->idx >= drvdata->cmb_msr_num)
>>> +            return -EINVAL;
>>> +        return sysfs_emit(buf, "0x%x\n",
>>> +                drvdata->cmb->msr[tpdm_attr->idx]);
>>>       }
>>>       return -EINVAL;
>>>   }
>>> @@ -162,6 +167,12 @@ static ssize_t tpdm_simple_dataset_store(struct
>>> device *dev,
>>>           else
>>>               ret = -EINVAL;
>>>           break;
>>> +    case CMB_MSR:
>>> +        if (tpdm_attr->idx < drvdata->cmb_msr_num)
>>> +            drvdata->cmb->msr[tpdm_attr->idx] = val;
>>> +        else
>>> +            ret = -EINVAL;
>>
>>
>> minor nit: Could we not break from here instead of adding return -EINVAL
>> for each case ? (I understand it has been done for the existing cases.
>> But I think we should clean up all of that, including the ones you added
>> in Patch 5. Similarly for the dataset_show()
>
> Sure, do I also need to change the DSB corresponding code? If so, how about
>
> if I add a new patch to the next patch series to change the previous
> existing cases?

You could fix the existing cases as a preparatory patch of the next
version of this series. I can pick it up and push it to next as I see fit.

Suzuki


>
>
> Best,
>
> Tao
>
>>
>>
>> Suzuki
>>
>>
>>> +        break;
>>>       default:
>>>           ret = -EINVAL;
>>>       }
>>> @@ -220,6 +231,23 @@ static umode_t tpdm_dsb_msr_is_visible(struct
>>> kobject *kobj,
>>>       return 0;
>>>   }
>>>   +static umode_t tpdm_cmb_msr_is_visible(struct kobject *kobj,
>>> +                       struct attribute *attr, int n)
>>> +{
>>> +    struct device *dev = kobj_to_dev(kobj);
>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>> +
>>> +    struct device_attribute *dev_attr =
>>> +        container_of(attr, struct device_attribute, attr);
>>> +    struct tpdm_dataset_attribute *tpdm_attr =
>>> +        container_of(dev_attr, struct tpdm_dataset_attribute, attr);
>>> +
>>> +    if (tpdm_attr->idx < drvdata->cmb_msr_num)
>>> +        return attr->mode;
>>> +
>>> +    return 0;
>>> +}
>>> +
>>>   static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata)
>>>   {
>>>       if (tpdm_has_dsb_dataset(drvdata)) {
>>> @@ -361,6 +389,15 @@ static void set_cmb_tier(struct tpdm_drvdata
>>> *drvdata)
>>>       writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
>>>   }
>>>   +static void set_cmb_msr(struct tpdm_drvdata *drvdata)
>>> +{
>>> +    int i;
>>> +
>>> +    for (i = 0; i < drvdata->cmb_msr_num; i++)
>>> +        writel_relaxed(drvdata->cmb->msr[i],
>>> +               drvdata->base + TPDM_CMB_MSR(i));
>>> +}
>>> +
>>>   static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
>>>   {
>>>       u32 val, i;
>>> @@ -379,6 +416,8 @@ static void tpdm_enable_cmb(struct tpdm_drvdata
>>> *drvdata)
>>>         set_cmb_tier(drvdata);
>>>   +    set_cmb_msr(drvdata);
>>> +
>>>       val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
>>>       /*
>>>        * Set to 0 for continuous CMB collection mode,
>>> @@ -1084,6 +1123,42 @@ static struct attribute *tpdm_cmb_patt_attrs[]
>>> = {
>>>       NULL,
>>>   };
>>>   +static struct attribute *tpdm_cmb_msr_attrs[] = {
>>> +    CMB_MSR_ATTR(0),
>>> +    CMB_MSR_ATTR(1),
>>> +    CMB_MSR_ATTR(2),
>>> +    CMB_MSR_ATTR(3),
>>> +    CMB_MSR_ATTR(4),
>>> +    CMB_MSR_ATTR(5),
>>> +    CMB_MSR_ATTR(6),
>>> +    CMB_MSR_ATTR(7),
>>> +    CMB_MSR_ATTR(8),
>>> +    CMB_MSR_ATTR(9),
>>> +    CMB_MSR_ATTR(10),
>>> +    CMB_MSR_ATTR(11),
>>> +    CMB_MSR_ATTR(12),
>>> +    CMB_MSR_ATTR(13),
>>> +    CMB_MSR_ATTR(14),
>>> +    CMB_MSR_ATTR(15),
>>> +    CMB_MSR_ATTR(16),
>>> +    CMB_MSR_ATTR(17),
>>> +    CMB_MSR_ATTR(18),
>>> +    CMB_MSR_ATTR(19),
>>> +    CMB_MSR_ATTR(20),
>>> +    CMB_MSR_ATTR(21),
>>> +    CMB_MSR_ATTR(22),
>>> +    CMB_MSR_ATTR(23),
>>> +    CMB_MSR_ATTR(24),
>>> +    CMB_MSR_ATTR(25),
>>> +    CMB_MSR_ATTR(26),
>>> +    CMB_MSR_ATTR(27),
>>> +    CMB_MSR_ATTR(28),
>>> +    CMB_MSR_ATTR(29),
>>> +    CMB_MSR_ATTR(30),
>>> +    CMB_MSR_ATTR(31),
>>> +    NULL,
>>> +};
>>> +
>>>   static struct attribute *tpdm_dsb_attrs[] = {
>>>       &dev_attr_dsb_mode.attr,
>>>       &dev_attr_dsb_trig_ts.attr,
>>> @@ -1144,6 +1219,12 @@ static struct attribute_group
>>> tpdm_cmb_patt_grp = {
>>>       .name = "cmb_patt",
>>>   };
>>>   +static struct attribute_group tpdm_cmb_msr_grp = {
>>> +    .attrs = tpdm_cmb_msr_attrs,
>>> +    .is_visible = tpdm_cmb_msr_is_visible,
>>> +    .name = "cmb_msr",
>>> +};
>>> +
>>>   static const struct attribute_group *tpdm_attr_grps[] = {
>>>       &tpdm_attr_grp,
>>>       &tpdm_dsb_attr_grp,
>>> @@ -1154,6 +1235,7 @@ static const struct attribute_group
>>> *tpdm_attr_grps[] = {
>>>       &tpdm_cmb_attr_grp,
>>>       &tpdm_cmb_trig_patt_grp,
>>>       &tpdm_cmb_patt_grp,
>>> +    &tpdm_cmb_msr_grp,
>>>       NULL,
>>>   };
>>>   @@ -1192,6 +1274,10 @@ static int tpdm_probe(struct amba_device
>>> *adev, const struct amba_id *id)
>>>           of_property_read_u32(drvdata->dev->of_node,
>>>                  "qcom,dsb-msrs-num", &drvdata->dsb_msr_num);
>>>   +    if (drvdata && tpdm_has_cmb_dataset(drvdata))
>>> +        of_property_read_u32(drvdata->dev->of_node,
>>> +               "qcom,cmb-msrs-num", &drvdata->cmb_msr_num);
>>> +
>>>       /* Set up coresight component description */
>>>       desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
>>>       if (!desc.name)
>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h
>>> b/drivers/hwtracing/coresight/coresight-tpdm.h
>>> index 65b7ca6c4077..255104d024ab 100644
>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.h
>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>>> @@ -21,6 +21,8 @@
>>>   #define TPDM_CMB_XPR(n)        (0xA18 + (n * 4))
>>>   /*CMB subunit trigger pattern mask registers*/
>>>   #define TPDM_CMB_XPMR(n)    (0xA20 + (n * 4))
>>> +/* CMB MSR register */
>>> +#define TPDM_CMB_MSR(n)        (0xA80 + (n * 4))
>>>     /* Enable bit for CMB subunit */
>>>   #define TPDM_CMB_CR_ENA        BIT(0)
>>> @@ -36,6 +38,9 @@
>>>   /*Patten register number*/
>>>   #define TPDM_CMB_MAX_PATT        2
>>>   +/* MAX number of DSB MSR */
>>> +#define TPDM_CMB_MAX_MSR 32
>>> +
>>>   /* DSB Subunit Registers */
>>>   #define TPDM_DSB_CR        (0x780)
>>>   #define TPDM_DSB_TIER        (0x784)
>>> @@ -186,6 +191,10 @@
>>>           tpdm_simple_dataset_rw(tpmr##nr,        \
>>>           CMB_PATT_MASK, nr)
>>>   +#define CMB_MSR_ATTR(nr)                    \
>>> +        tpdm_simple_dataset_rw(msr##nr,            \
>>> +        CMB_MSR, nr)
>>> +
>>>   /**
>>>    * struct dsb_dataset - specifics associated to dsb dataset
>>>    * @mode:             DSB programming mode
>>> @@ -225,6 +234,7 @@ struct dsb_dataset {
>>>    * @patt_mask:        Save value for pattern mask
>>>    * @trig_patt:        Save value for trigger pattern
>>>    * @trig_patt_mask:   Save value for trigger pattern mask
>>> + * @msr               Save value for MSR
>>>    * @patt_ts:          Indicates if pattern match for timestamp is
>>> enabled.
>>>    * @trig_ts:          Indicates if CTI trigger for timestamp is
>>> enabled.
>>>    * @ts_all:           Indicates if timestamp is enabled for all
>>> packets.
>>> @@ -235,6 +245,7 @@ struct cmb_dataset {
>>>       u32            patt_mask[TPDM_CMB_MAX_PATT];
>>>       u32            trig_patt[TPDM_CMB_MAX_PATT];
>>>       u32            trig_patt_mask[TPDM_CMB_MAX_PATT];
>>> +    u32            msr[TPDM_CMB_MAX_MSR];
>>>       bool            patt_ts;
>>>       bool            trig_ts;
>>>       bool            ts_all;
>>> @@ -251,6 +262,7 @@ struct cmb_dataset {
>>>    * @dsb         Specifics associated to TPDM DSB.
>>>    * @cmb         Specifics associated to TPDM CMB.
>>>    * @dsb_msr_num Number of MSR supported by DSB TPDM
>>> + * @cmb_msr_num Number of MSR supported by CMB TPDM
>>>    */
>>>     struct tpdm_drvdata {
>>> @@ -263,6 +275,7 @@ struct tpdm_drvdata {
>>>       struct dsb_dataset    *dsb;
>>>       struct cmb_dataset    *cmb;
>>>       u32            dsb_msr_num;
>>> +    u32            cmb_msr_num;
>>>   };
>>>     /* Enumerate members of various datasets */
>>> @@ -277,7 +290,8 @@ enum dataset_mem {
>>>       CMB_TRIG_PATT,
>>>       CMB_TRIG_PATT_MASK,
>>>       CMB_PATT,
>>> -    CMB_PATT_MASK
>>> +    CMB_PATT_MASK,
>>> +    CMB_MSR
>>>   };
>>>     /**
>>
>> _______________________________________________
>> CoreSight mailing list -- [email protected]
>> To unsubscribe send an email to [email protected]


2023-12-20 00:28:31

by Tao Zhang

[permalink] [raw]
Subject: Re: [PATCH v3 2/8] coresight-tpda: Add support to configure CMB element


On 12/19/2023 9:54 PM, Suzuki K Poulose wrote:
> On 19/12/2023 02:13, Tao Zhang wrote:
>>
>> On 12/18/2023 6:27 PM, Suzuki K Poulose wrote:
>>> On 21/11/2023 02:24, Tao Zhang wrote:
>>>> Read the CMB element size from the device tree. Set the register
>>>> bit that controls the CMB element size of the corresponding port.
>>>>
>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>> Signed-off-by: Mao Jinlong <[email protected]>
>>>> ---
>>>>   drivers/hwtracing/coresight/coresight-tpda.c | 117
>>>> +++++++++++--------
>>>>   drivers/hwtracing/coresight/coresight-tpda.h |   6 +
>>>>   2 files changed, 74 insertions(+), 49 deletions(-)
>>>>
>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c
>>>> b/drivers/hwtracing/coresight/coresight-tpda.c
>>>> index 5f82737c37bb..e3762f38abb3 100644
>>>> --- a/drivers/hwtracing/coresight/coresight-tpda.c
>>>> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
>>>> @@ -28,24 +28,54 @@ static bool coresight_device_is_tpdm(struct
>>>> coresight_device *csdev)
>>>>               CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM);
>>>>   }
>>>>   +static void tpdm_clear_element_size(struct coresight_device *csdev)
>>>> +{
>>>> +    struct tpda_drvdata *drvdata =
>>>> dev_get_drvdata(csdev->dev.parent);
>>>> +
>>>> +    if (drvdata->dsb_esize)
>>>> +        drvdata->dsb_esize = 0;
>>>> +    if (drvdata->cmb_esize)
>>>> +        drvdata->cmb_esize = 0;
>>>
>>> Why do we need the if (...) check here ?
>>
>> The element size of all the TPDM sub-unit should be set to 0 here.
>>
>> I will update this in the next patch series.
>>
>>>
>>>> +}
>>>> +
>>>> +static void tpda_set_element_size(struct tpda_drvdata *drvdata,
>>>> u32 *val)
>>>> +{
>>>> +
>>>> +    if (drvdata->dsb_esize == 64)
>>>> +        *val |= TPDA_Pn_CR_DSBSIZE;
>>>> +    else if (drvdata->dsb_esize == 32)
>>>> +        *val &= ~TPDA_Pn_CR_DSBSIZE;
>>>> +
>>>> +    if (drvdata->cmb_esize == 64)
>>>> +        *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2);
>>>> +    else if (drvdata->cmb_esize == 32)
>>>> +        *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1);
>>>> +    else if (drvdata->cmb_esize == 8)
>>>> +        *val &= ~TPDA_Pn_CR_CMBSIZE;
>>>> +}
>>>> +
>>>
>>>
>>>>   /*
>>>> - * Read the DSB element size from the TPDM device
>>>> + * Read the element size from the TPDM device
>>>>    * Returns
>>>> - *    The dsb element size read from the devicetree if available.
>>>> + *    The element size read from the devicetree if available.
>>>>    *    0 - Otherwise, with a warning once.
>>>
>>> This doesn't match the function ? It return 0 on success and
>>> error (-EINVAL) on failure ?
>>
>> 0 means the element size property is found from the devicetree.
>>
>> Otherwise, it will return error(-EINVAL).
>>
>> I will update this in the next patch series.
>>
>>>
>>>>    */
>>>> -static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
>>>> +static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
>>>> +                  struct coresight_device *csdev)
>>>>   {
>>>> -    int rc = 0;
>>>> -    u8 size = 0;
>>>> -
>>>> -    rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>>>> -            "qcom,dsb-element-size", &size);
>>>> +    int rc = -EINVAL;
>>>> +
>>>> +    if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>>>> +            "qcom,dsb-element-size", &drvdata->dsb_esize))
>>>> +        rc = 0;
>>>> +    if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>>>> +            "qcom,cmb-element-size", &drvdata->cmb_esize))
>>>> +        rc = 0;
>>>
>>> Are we not silently resetting the error if the former failed ?
>>>
>>> Could we not :
>>>
>>>     rc |= fwnode_...
>>>
>>>     rc |= fwnode_...
>>>
>>> instead ?
>>>
>>> Also what is the expectation here ? Are these properties a MUST for
>>> TPDM ?
>>
>> The TPDM must have one of the element size property. As long as one
>
> Please add a comment in the function. Someone else might try to "fix"
> it otherwise.

Sure, I will update this in the next patch series.


Best,

Tao

>
> Suzuki
>>
>> can be found, this TPDM configuration can be considered valid. So this
>>
>> function will return 0 if one of the element size property is found.
>
>
>>
>>
>> Best,
>>
>> Tao
>>
>>>
>>>>       if (rc)
>>>>           dev_warn_once(&csdev->dev,
>>>> -            "Failed to read TPDM DSB Element size: %d\n", rc);
>>>> +            "Failed to read TPDM Element size: %d\n", rc);
>>>>   -    return size;
>>>> +    return rc;
>>>>   }
>>>>     /*
>>>> @@ -56,11 +86,12 @@ static int tpdm_read_dsb_element_size(struct
>>>> coresight_device *csdev)
>>>>    * Parameter "inport" is used to pass in the input port number
>>>>    * of TPDA, and it is set to -1 in the recursize call.
>>>>    */
>>>> -static int tpda_get_element_size(struct coresight_device *csdev,
>>>> +static int tpda_get_element_size(struct tpda_drvdata *drvdata,
>>>> +                 struct coresight_device *csdev,
>>>>                    int inport)
>>>>   {
>>>> -    int dsb_size = -ENOENT;
>>>> -    int i, size;
>>>> +    int rc = 0;
>>>> +    int i;
>>>>       struct coresight_device *in;
>>>>         for (i = 0; i < csdev->pdata->nr_inconns; i++) {
>>>> @@ -74,25 +105,21 @@ static int tpda_get_element_size(struct
>>>> coresight_device *csdev,
>>>>               continue;
>>>>             if (coresight_device_is_tpdm(in)) {
>>>> -            size = tpdm_read_dsb_element_size(in);
>>>> +            if ((drvdata->dsb_esize) || (drvdata->cmb_esize))
>>>> +                return -EEXIST;
>>>> +            rc = tpdm_read_element_size(drvdata, in);
>>>> +            if (rc)
>>>> +                return rc;
>>>>           } else {
>>>>               /* Recurse down the path */
>>>> -            size = tpda_get_element_size(in, -1);
>>>> -        }
>>>> -
>>>> -        if (size < 0)
>>>> -            return size;
>>>> -
>>>> -        if (dsb_size < 0) {
>>>> -            /* Found a size, save it. */
>>>> -            dsb_size = size;
>>>> -        } else {
>>>> -            /* Found duplicate TPDMs */
>>>> -            return -EEXIST;
>>>> +            rc = tpda_get_element_size(drvdata, in, -1);
>>>> +            if (rc)
>>>> +                return rc;
>>>>           }
>>>>       }
>>>>   -    return dsb_size;
>>>> +
>>>> +    return rc;
>>>>   }
>>>>     /* Settings pre enabling port control register */
>>>> @@ -109,7 +136,7 @@ static void tpda_enable_pre_port(struct
>>>> tpda_drvdata *drvdata)
>>>>   static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
>>>>   {
>>>>       u32 val;
>>>> -    int size;
>>>> +    int rc;
>>>>         val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
>>>>       /*
>>>> @@ -117,29 +144,21 @@ static int tpda_enable_port(struct
>>>> tpda_drvdata *drvdata, int port)
>>>>        * Set the bit to 0 if the size is 32
>>>>        * Set the bit to 1 if the size is 64
>>>>        */
>>>> -    size = tpda_get_element_size(drvdata->csdev, port);
>>>> -    switch (size) {
>>>> -    case 32:
>>>> -        val &= ~TPDA_Pn_CR_DSBSIZE;
>>>> -        break;
>>>> -    case 64:
>>>> -        val |= TPDA_Pn_CR_DSBSIZE;
>>>> -        break;
>>>> -    case 0:
>>>> -        return -EEXIST;
>>>> -    case -EEXIST:
>>>> +    tpdm_clear_element_size(drvdata->csdev);
>>>> +    rc = tpda_get_element_size(drvdata, drvdata->csdev, port);
>>>> +    if (!rc && ((drvdata->dsb_esize) || (drvdata->cmb_esize))) {
>>>> +        tpda_set_element_size(drvdata, &val);
>>>> +        /* Enable the port */
>>>> +        val |= TPDA_Pn_CR_ENA;
>>>> +        writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
>>>> +    } else if (rc == -EEXIST)
>>>>           dev_warn_once(&drvdata->csdev->dev,
>>>> -            "Detected multiple TPDMs on port %d", -EEXIST);
>>>> -        return -EEXIST;
>>>> -    default:
>>>> -        return -EINVAL;
>>>> -    }
>>>> -
>>>> -    /* Enable the port */
>>>> -    val |= TPDA_Pn_CR_ENA;
>>>> -    writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
>>>> +                  "Detected multiple TPDMs on port %d", -EEXIST);
>>>> +    else
>>>> +        dev_warn_once(&drvdata->csdev->dev,
>>>> +                  "Didn't find TPDM elem size");
>>>
>>> "element size"
>>>
>>>>   -    return 0;
>>>> +    return rc;
>>>>   }
>>>>     static int __tpda_enable(struct tpda_drvdata *drvdata, int port)
>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.h
>>>> b/drivers/hwtracing/coresight/coresight-tpda.h
>>>> index b3b38fd41b64..29164fd9711f 100644
>>>> --- a/drivers/hwtracing/coresight/coresight-tpda.h
>>>> +++ b/drivers/hwtracing/coresight/coresight-tpda.h
>>>> @@ -10,6 +10,8 @@
>>>>   #define TPDA_Pn_CR(n)        (0x004 + (n * 4))
>>>>   /* Aggregator port enable bit */
>>>>   #define TPDA_Pn_CR_ENA        BIT(0)
>>>> +/* Aggregator port CMB data set element size bit */
>>>> +#define TPDA_Pn_CR_CMBSIZE        GENMASK(7, 6)
>>>>   /* Aggregator port DSB data set element size bit */
>>>>   #define TPDA_Pn_CR_DSBSIZE        BIT(8)
>>>>   @@ -25,6 +27,8 @@
>>>>    * @csdev:      component vitals needed by the framework.
>>>>    * @spinlock:   lock for the drvdata value.
>>>>    * @enable:     enable status of the component.
>>>> + * @dsb_esize   Record the DSB element size.
>>>> + * @cmb_esize   Record the CMB element size.
>>>>    */
>>>>   struct tpda_drvdata {
>>>>       void __iomem        *base;
>>>> @@ -32,6 +36,8 @@ struct tpda_drvdata {
>>>>       struct coresight_device    *csdev;
>>>>       spinlock_t        spinlock;
>>>>       u8            atid;
>>>> +    u8            dsb_esize;
>>>> +    u8            cmb_esize;
>>>>   };
>>>>     #endif  /* _CORESIGHT_CORESIGHT_TPDA_H */
>>>
>>> Suzuki
>>>
>>>
>

2023-12-20 08:55:45

by Tao Zhang

[permalink] [raw]
Subject: Re: [PATCH v3 2/8] coresight-tpda: Add support to configure CMB element


On 12/19/2023 9:59 PM, Suzuki K Poulose wrote:
> On 18/12/2023 10:27, Suzuki K Poulose wrote:
>> On 21/11/2023 02:24, Tao Zhang wrote:
>>> Read the CMB element size from the device tree. Set the register
>>> bit that controls the CMB element size of the corresponding port.
>>>
>>> Signed-off-by: Tao Zhang <[email protected]>
>>> Signed-off-by: Mao Jinlong <[email protected]>
>>> ---
>>>   drivers/hwtracing/coresight/coresight-tpda.c | 117
>>> +++++++++++--------
>>>   drivers/hwtracing/coresight/coresight-tpda.h |   6 +
>>>   2 files changed, 74 insertions(+), 49 deletions(-)
>>>
>>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.c
>>> b/drivers/hwtracing/coresight/coresight-tpda.c
>>> index 5f82737c37bb..e3762f38abb3 100644
>>> --- a/drivers/hwtracing/coresight/coresight-tpda.c
>>> +++ b/drivers/hwtracing/coresight/coresight-tpda.c
>>> @@ -28,24 +28,54 @@ static bool coresight_device_is_tpdm(struct
>>> coresight_device *csdev)
>>>               CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM);
>>>   }
>>> +static void tpdm_clear_element_size(struct coresight_device *csdev)
>>> +{
>>> +    struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>>> +
>>> +    if (drvdata->dsb_esize)
>>> +        drvdata->dsb_esize = 0;
>>> +    if (drvdata->cmb_esize)
>>> +        drvdata->cmb_esize = 0;
>>
>> Why do we need the if (...) check here ?
>>
>>> +}
>>> +
>>> +static void tpda_set_element_size(struct tpda_drvdata *drvdata, u32
>>> *val)
>>> +{
>>> +
>>> +    if (drvdata->dsb_esize == 64)
>>> +        *val |= TPDA_Pn_CR_DSBSIZE;
>>> +    else if (drvdata->dsb_esize == 32)
>>> +        *val &= ~TPDA_Pn_CR_DSBSIZE;
>>> +
>>> +    if (drvdata->cmb_esize == 64)
>>> +        *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x2);
>>> +    else if (drvdata->cmb_esize == 32)
>>> +        *val |= FIELD_PREP(TPDA_Pn_CR_CMBSIZE, 0x1);
>>> +    else if (drvdata->cmb_esize == 8)
>>> +        *val &= ~TPDA_Pn_CR_CMBSIZE;
>>> +}
>>> +
>>
>>
>>>   /*
>>> - * Read the DSB element size from the TPDM device
>>> + * Read the element size from the TPDM device
>>>    * Returns
>>> - *    The dsb element size read from the devicetree if available.
>>> + *    The element size read from the devicetree if available.
>>>    *    0 - Otherwise, with a warning once.
>>
>> This doesn't match the function ? It return 0 on success and
>> error (-EINVAL) on failure ?
>>
>>>    */
>>> -static int tpdm_read_dsb_element_size(struct coresight_device *csdev)
>>> +static int tpdm_read_element_size(struct tpda_drvdata *drvdata,
>>> +                  struct coresight_device *csdev)
>>>   {
>>> -    int rc = 0;
>>> -    u8 size = 0;
>>> -
>>> -    rc = fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>>> -            "qcom,dsb-element-size", &size);
>>> +    int rc = -EINVAL;
>>> +
>>> +    if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>>> +            "qcom,dsb-element-size", &drvdata->dsb_esize))
>>> +        rc = 0;
>>> +    if (!fwnode_property_read_u8(dev_fwnode(csdev->dev.parent),
>>> +            "qcom,cmb-element-size", &drvdata->cmb_esize))
>
> At this point we have the csdev->dev.parent as the TPDM device and with:
>
> #include <coresight-tpdm.h>
>
>     struct tpdm_drvdata *tpdm_data = get_drvdata(csdev->dev.parent);
>
>     if (tpdm_has_cmb(tpdm_data)) {
>         rc = fwnode_...(... "qcom,cmb-element-size"...)
>     }
>
>     if (tpdm_has_dsb(tpdm_data)) {
>         rc = fwnode_...(..., "qcom,dsb-element-size"..)
>     }

I will update according to your approach in the next patch series.


Best,

Tao

>
> Suzuki
>
>
>>> +        rc = 0;
>>
>> Are we not silently resetting the error if the former failed ?
>>
>> Could we not :
>>
>>      rc |= fwnode_...
>>
>>      rc |= fwnode_...
>>
>> instead ?
>>
>> Also what is the expectation here ? Are these properties a MUST for
>> TPDM ?
>>
>>>       if (rc)
>>>           dev_warn_once(&csdev->dev,
>>> -            "Failed to read TPDM DSB Element size: %d\n", rc);
>>> +            "Failed to read TPDM Element size: %d\n", rc);
>>> -    return size;
>>> +    return rc;
>>>   }
>>>   /*
>>> @@ -56,11 +86,12 @@ static int tpdm_read_dsb_element_size(struct
>>> coresight_device *csdev)
>>>    * Parameter "inport" is used to pass in the input port number
>>>    * of TPDA, and it is set to -1 in the recursize call.
>>>    */
>>> -static int tpda_get_element_size(struct coresight_device *csdev,
>>> +static int tpda_get_element_size(struct tpda_drvdata *drvdata,
>>> +                 struct coresight_device *csdev,
>>>                    int inport)
>>>   {
>>> -    int dsb_size = -ENOENT;
>>> -    int i, size;
>>> +    int rc = 0;
>>> +    int i;
>>>       struct coresight_device *in;
>>>       for (i = 0; i < csdev->pdata->nr_inconns; i++) {
>>> @@ -74,25 +105,21 @@ static int tpda_get_element_size(struct
>>> coresight_device *csdev,
>>>               continue;
>>>           if (coresight_device_is_tpdm(in)) {
>>> -            size = tpdm_read_dsb_element_size(in);
>>> +            if ((drvdata->dsb_esize) || (drvdata->cmb_esize))
>>> +                return -EEXIST;
>>> +            rc = tpdm_read_element_size(drvdata, in);
>>> +            if (rc)
>>> +                return rc;
>>>           } else {
>>>               /* Recurse down the path */
>>> -            size = tpda_get_element_size(in, -1);
>>> -        }
>>> -
>>> -        if (size < 0)
>>> -            return size;
>>> -
>>> -        if (dsb_size < 0) {
>>> -            /* Found a size, save it. */
>>> -            dsb_size = size;
>>> -        } else {
>>> -            /* Found duplicate TPDMs */
>>> -            return -EEXIST;
>>> +            rc = tpda_get_element_size(drvdata, in, -1);
>>> +            if (rc)
>>> +                return rc;
>>>           }
>>>       }
>>> -    return dsb_size;
>>> +
>>> +    return rc;
>>>   }
>>>   /* Settings pre enabling port control register */
>>> @@ -109,7 +136,7 @@ static void tpda_enable_pre_port(struct
>>> tpda_drvdata *drvdata)
>>>   static int tpda_enable_port(struct tpda_drvdata *drvdata, int port)
>>>   {
>>>       u32 val;
>>> -    int size;
>>> +    int rc;
>>>       val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
>>>       /*
>>> @@ -117,29 +144,21 @@ static int tpda_enable_port(struct
>>> tpda_drvdata *drvdata, int port)
>>>        * Set the bit to 0 if the size is 32
>>>        * Set the bit to 1 if the size is 64
>>>        */
>>> -    size = tpda_get_element_size(drvdata->csdev, port);
>>> -    switch (size) {
>>> -    case 32:
>>> -        val &= ~TPDA_Pn_CR_DSBSIZE;
>>> -        break;
>>> -    case 64:
>>> -        val |= TPDA_Pn_CR_DSBSIZE;
>>> -        break;
>>> -    case 0:
>>> -        return -EEXIST;
>>> -    case -EEXIST:
>>> +    tpdm_clear_element_size(drvdata->csdev);
>>> +    rc = tpda_get_element_size(drvdata, drvdata->csdev, port);
>>> +    if (!rc && ((drvdata->dsb_esize) || (drvdata->cmb_esize))) {
>>> +        tpda_set_element_size(drvdata, &val);
>>> +        /* Enable the port */
>>> +        val |= TPDA_Pn_CR_ENA;
>>> +        writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
>>> +    } else if (rc == -EEXIST)
>>>           dev_warn_once(&drvdata->csdev->dev,
>>> -            "Detected multiple TPDMs on port %d", -EEXIST);
>>> -        return -EEXIST;
>>> -    default:
>>> -        return -EINVAL;
>>> -    }
>>> -
>>> -    /* Enable the port */
>>> -    val |= TPDA_Pn_CR_ENA;
>>> -    writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
>>> +                  "Detected multiple TPDMs on port %d", -EEXIST);
>>> +    else
>>> +        dev_warn_once(&drvdata->csdev->dev,
>>> +                  "Didn't find TPDM elem size");
>>
>> "element size"
>>
>>> -    return 0;
>>> +    return rc;
>>>   }
>>>   static int __tpda_enable(struct tpda_drvdata *drvdata, int port)
>>> diff --git a/drivers/hwtracing/coresight/coresight-tpda.h
>>> b/drivers/hwtracing/coresight/coresight-tpda.h
>>> index b3b38fd41b64..29164fd9711f 100644
>>> --- a/drivers/hwtracing/coresight/coresight-tpda.h
>>> +++ b/drivers/hwtracing/coresight/coresight-tpda.h
>>> @@ -10,6 +10,8 @@
>>>   #define TPDA_Pn_CR(n)        (0x004 + (n * 4))
>>>   /* Aggregator port enable bit */
>>>   #define TPDA_Pn_CR_ENA        BIT(0)
>>> +/* Aggregator port CMB data set element size bit */
>>> +#define TPDA_Pn_CR_CMBSIZE        GENMASK(7, 6)
>>>   /* Aggregator port DSB data set element size bit */
>>>   #define TPDA_Pn_CR_DSBSIZE        BIT(8)
>>> @@ -25,6 +27,8 @@
>>>    * @csdev:      component vitals needed by the framework.
>>>    * @spinlock:   lock for the drvdata value.
>>>    * @enable:     enable status of the component.
>>> + * @dsb_esize   Record the DSB element size.
>>> + * @cmb_esize   Record the CMB element size.
>>>    */
>>>   struct tpda_drvdata {
>>>       void __iomem        *base;
>>> @@ -32,6 +36,8 @@ struct tpda_drvdata {
>>>       struct coresight_device    *csdev;
>>>       spinlock_t        spinlock;
>>>       u8            atid;
>>> +    u8            dsb_esize;
>>> +    u8            cmb_esize;
>>>   };
>>>   #endif  /* _CORESIGHT_CORESIGHT_TPDA_H */
>>
>> Suzuki
>>
>>
>

2023-12-20 09:07:33

by Tao Zhang

[permalink] [raw]
Subject: Re: [PATCH v3 8/8] coresight-tpdm: Add msr register support for CMB


On 12/19/2023 10:09 PM, Suzuki K Poulose wrote:
> On 19/12/2023 06:58, Tao Zhang wrote:
>>
>> On 12/18/2023 7:02 PM, Suzuki K Poulose wrote:
>>> On 21/11/2023 02:24, Tao Zhang wrote:
>>>> Add the nodes for CMB subunit MSR(mux select register) support.
>>>> CMB MSRs(mux select registers) is to separate mux,arbitration,
>>>> ,interleaving,data packing control from stream filtering control.
>>>>
>>>> Reviewed-by: James Clark <[email protected]>
>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>> Signed-off-by: Mao Jinlong <[email protected]>
>>>> ---
>>>>   .../testing/sysfs-bus-coresight-devices-tpdm  |  8 ++
>>>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 86
>>>> +++++++++++++++++++
>>>>   drivers/hwtracing/coresight/coresight-tpdm.h  | 16 +++-
>>>>   3 files changed, 109 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git
>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>> index e0b77107be13..914f3fd81525 100644
>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>> @@ -249,3 +249,11 @@ Description:
>>>>           Accepts only one of the 2 values -  0 or 1.
>>>>           0 : Disable the timestamp of all trace packets.
>>>>           1 : Enable the timestamp of all trace packets.
>>>> +
>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
>>>> +Date:        September 2023
>>>> +KernelVersion    6.7
>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>> Zhang (QUIC) <[email protected]>
>>>> +Description:
>>>> +        (RW) Set/Get the MSR(mux select register) for the CMB subunit
>>>> +        TPDM.
>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>> index f6cda5616e84..7e331ea436cc 100644
>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>> @@ -86,6 +86,11 @@ static ssize_t tpdm_simple_dataset_show(struct
>>>> device *dev,
>>>>               return -EINVAL;
>>>>           return sysfs_emit(buf, "0x%x\n",
>>>> drvdata->cmb->patt_mask[tpdm_attr->idx]);
>>>> +    case CMB_MSR:
>>>> +        if (tpdm_attr->idx >= drvdata->cmb_msr_num)
>>>> +            return -EINVAL;
>>>> +        return sysfs_emit(buf, "0x%x\n",
>>>> + drvdata->cmb->msr[tpdm_attr->idx]);
>>>>       }
>>>>       return -EINVAL;
>>>>   }
>>>> @@ -162,6 +167,12 @@ static ssize_t
>>>> tpdm_simple_dataset_store(struct device *dev,
>>>>           else
>>>>               ret = -EINVAL;
>>>>           break;
>>>> +    case CMB_MSR:
>>>> +        if (tpdm_attr->idx < drvdata->cmb_msr_num)
>>>> +            drvdata->cmb->msr[tpdm_attr->idx] = val;
>>>> +        else
>>>> +            ret = -EINVAL;
>>>
>>>
>>> minor nit: Could we not break from here instead of adding return
>>> -EINVAL
>>> for each case ? (I understand it has been done for the existing cases.
>>> But I think we should clean up all of that, including the ones you
>>> added
>>> in Patch 5. Similarly for the dataset_show()
>>
>> Sure, do I also need to change the DSB corresponding code? If so, how
>> about
>>
>> if I add a new patch to the next patch series to change the previous
>> existing cases?
>
> You could fix the existing cases as a preparatory patch of the next
> version of this series. I can pick it up and push it to next as I see
> fit.

Got it. I will update this to the next patch series.


Best,

Tao

>
> Suzuki
>
>
>>
>>
>> Best,
>>
>> Tao
>>
>>>
>>>
>>> Suzuki
>>>
>>>
>>>> +        break;
>>>>       default:
>>>>           ret = -EINVAL;
>>>>       }
>>>> @@ -220,6 +231,23 @@ static umode_t tpdm_dsb_msr_is_visible(struct
>>>> kobject *kobj,
>>>>       return 0;
>>>>   }
>>>>   +static umode_t tpdm_cmb_msr_is_visible(struct kobject *kobj,
>>>> +                       struct attribute *attr, int n)
>>>> +{
>>>> +    struct device *dev = kobj_to_dev(kobj);
>>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>> +
>>>> +    struct device_attribute *dev_attr =
>>>> +        container_of(attr, struct device_attribute, attr);
>>>> +    struct tpdm_dataset_attribute *tpdm_attr =
>>>> +        container_of(dev_attr, struct tpdm_dataset_attribute, attr);
>>>> +
>>>> +    if (tpdm_attr->idx < drvdata->cmb_msr_num)
>>>> +        return attr->mode;
>>>> +
>>>> +    return 0;
>>>> +}
>>>> +
>>>>   static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata)
>>>>   {
>>>>       if (tpdm_has_dsb_dataset(drvdata)) {
>>>> @@ -361,6 +389,15 @@ static void set_cmb_tier(struct tpdm_drvdata
>>>> *drvdata)
>>>>       writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
>>>>   }
>>>>   +static void set_cmb_msr(struct tpdm_drvdata *drvdata)
>>>> +{
>>>> +    int i;
>>>> +
>>>> +    for (i = 0; i < drvdata->cmb_msr_num; i++)
>>>> +        writel_relaxed(drvdata->cmb->msr[i],
>>>> +               drvdata->base + TPDM_CMB_MSR(i));
>>>> +}
>>>> +
>>>>   static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
>>>>   {
>>>>       u32 val, i;
>>>> @@ -379,6 +416,8 @@ static void tpdm_enable_cmb(struct tpdm_drvdata
>>>> *drvdata)
>>>>         set_cmb_tier(drvdata);
>>>>   +    set_cmb_msr(drvdata);
>>>> +
>>>>       val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
>>>>       /*
>>>>        * Set to 0 for continuous CMB collection mode,
>>>> @@ -1084,6 +1123,42 @@ static struct attribute
>>>> *tpdm_cmb_patt_attrs[] = {
>>>>       NULL,
>>>>   };
>>>>   +static struct attribute *tpdm_cmb_msr_attrs[] = {
>>>> +    CMB_MSR_ATTR(0),
>>>> +    CMB_MSR_ATTR(1),
>>>> +    CMB_MSR_ATTR(2),
>>>> +    CMB_MSR_ATTR(3),
>>>> +    CMB_MSR_ATTR(4),
>>>> +    CMB_MSR_ATTR(5),
>>>> +    CMB_MSR_ATTR(6),
>>>> +    CMB_MSR_ATTR(7),
>>>> +    CMB_MSR_ATTR(8),
>>>> +    CMB_MSR_ATTR(9),
>>>> +    CMB_MSR_ATTR(10),
>>>> +    CMB_MSR_ATTR(11),
>>>> +    CMB_MSR_ATTR(12),
>>>> +    CMB_MSR_ATTR(13),
>>>> +    CMB_MSR_ATTR(14),
>>>> +    CMB_MSR_ATTR(15),
>>>> +    CMB_MSR_ATTR(16),
>>>> +    CMB_MSR_ATTR(17),
>>>> +    CMB_MSR_ATTR(18),
>>>> +    CMB_MSR_ATTR(19),
>>>> +    CMB_MSR_ATTR(20),
>>>> +    CMB_MSR_ATTR(21),
>>>> +    CMB_MSR_ATTR(22),
>>>> +    CMB_MSR_ATTR(23),
>>>> +    CMB_MSR_ATTR(24),
>>>> +    CMB_MSR_ATTR(25),
>>>> +    CMB_MSR_ATTR(26),
>>>> +    CMB_MSR_ATTR(27),
>>>> +    CMB_MSR_ATTR(28),
>>>> +    CMB_MSR_ATTR(29),
>>>> +    CMB_MSR_ATTR(30),
>>>> +    CMB_MSR_ATTR(31),
>>>> +    NULL,
>>>> +};
>>>> +
>>>>   static struct attribute *tpdm_dsb_attrs[] = {
>>>>       &dev_attr_dsb_mode.attr,
>>>>       &dev_attr_dsb_trig_ts.attr,
>>>> @@ -1144,6 +1219,12 @@ static struct attribute_group
>>>> tpdm_cmb_patt_grp = {
>>>>       .name = "cmb_patt",
>>>>   };
>>>>   +static struct attribute_group tpdm_cmb_msr_grp = {
>>>> +    .attrs = tpdm_cmb_msr_attrs,
>>>> +    .is_visible = tpdm_cmb_msr_is_visible,
>>>> +    .name = "cmb_msr",
>>>> +};
>>>> +
>>>>   static const struct attribute_group *tpdm_attr_grps[] = {
>>>>       &tpdm_attr_grp,
>>>>       &tpdm_dsb_attr_grp,
>>>> @@ -1154,6 +1235,7 @@ static const struct attribute_group
>>>> *tpdm_attr_grps[] = {
>>>>       &tpdm_cmb_attr_grp,
>>>>       &tpdm_cmb_trig_patt_grp,
>>>>       &tpdm_cmb_patt_grp,
>>>> +    &tpdm_cmb_msr_grp,
>>>>       NULL,
>>>>   };
>>>>   @@ -1192,6 +1274,10 @@ static int tpdm_probe(struct amba_device
>>>> *adev, const struct amba_id *id)
>>>>           of_property_read_u32(drvdata->dev->of_node,
>>>>                  "qcom,dsb-msrs-num", &drvdata->dsb_msr_num);
>>>>   +    if (drvdata && tpdm_has_cmb_dataset(drvdata))
>>>> +        of_property_read_u32(drvdata->dev->of_node,
>>>> +               "qcom,cmb-msrs-num", &drvdata->cmb_msr_num);
>>>> +
>>>>       /* Set up coresight component description */
>>>>       desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
>>>>       if (!desc.name)
>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h
>>>> b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>> index 65b7ca6c4077..255104d024ab 100644
>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.h
>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>> @@ -21,6 +21,8 @@
>>>>   #define TPDM_CMB_XPR(n)        (0xA18 + (n * 4))
>>>>   /*CMB subunit trigger pattern mask registers*/
>>>>   #define TPDM_CMB_XPMR(n)    (0xA20 + (n * 4))
>>>> +/* CMB MSR register */
>>>> +#define TPDM_CMB_MSR(n)        (0xA80 + (n * 4))
>>>>     /* Enable bit for CMB subunit */
>>>>   #define TPDM_CMB_CR_ENA        BIT(0)
>>>> @@ -36,6 +38,9 @@
>>>>   /*Patten register number*/
>>>>   #define TPDM_CMB_MAX_PATT        2
>>>>   +/* MAX number of DSB MSR */
>>>> +#define TPDM_CMB_MAX_MSR 32
>>>> +
>>>>   /* DSB Subunit Registers */
>>>>   #define TPDM_DSB_CR        (0x780)
>>>>   #define TPDM_DSB_TIER        (0x784)
>>>> @@ -186,6 +191,10 @@
>>>>           tpdm_simple_dataset_rw(tpmr##nr,        \
>>>>           CMB_PATT_MASK, nr)
>>>>   +#define CMB_MSR_ATTR(nr)                    \
>>>> +        tpdm_simple_dataset_rw(msr##nr,            \
>>>> +        CMB_MSR, nr)
>>>> +
>>>>   /**
>>>>    * struct dsb_dataset - specifics associated to dsb dataset
>>>>    * @mode:             DSB programming mode
>>>> @@ -225,6 +234,7 @@ struct dsb_dataset {
>>>>    * @patt_mask:        Save value for pattern mask
>>>>    * @trig_patt:        Save value for trigger pattern
>>>>    * @trig_patt_mask:   Save value for trigger pattern mask
>>>> + * @msr               Save value for MSR
>>>>    * @patt_ts:          Indicates if pattern match for timestamp is
>>>> enabled.
>>>>    * @trig_ts:          Indicates if CTI trigger for timestamp is
>>>> enabled.
>>>>    * @ts_all:           Indicates if timestamp is enabled for all
>>>> packets.
>>>> @@ -235,6 +245,7 @@ struct cmb_dataset {
>>>>       u32            patt_mask[TPDM_CMB_MAX_PATT];
>>>>       u32            trig_patt[TPDM_CMB_MAX_PATT];
>>>>       u32            trig_patt_mask[TPDM_CMB_MAX_PATT];
>>>> +    u32            msr[TPDM_CMB_MAX_MSR];
>>>>       bool            patt_ts;
>>>>       bool            trig_ts;
>>>>       bool            ts_all;
>>>> @@ -251,6 +262,7 @@ struct cmb_dataset {
>>>>    * @dsb         Specifics associated to TPDM DSB.
>>>>    * @cmb         Specifics associated to TPDM CMB.
>>>>    * @dsb_msr_num Number of MSR supported by DSB TPDM
>>>> + * @cmb_msr_num Number of MSR supported by CMB TPDM
>>>>    */
>>>>     struct tpdm_drvdata {
>>>> @@ -263,6 +275,7 @@ struct tpdm_drvdata {
>>>>       struct dsb_dataset    *dsb;
>>>>       struct cmb_dataset    *cmb;
>>>>       u32            dsb_msr_num;
>>>> +    u32            cmb_msr_num;
>>>>   };
>>>>     /* Enumerate members of various datasets */
>>>> @@ -277,7 +290,8 @@ enum dataset_mem {
>>>>       CMB_TRIG_PATT,
>>>>       CMB_TRIG_PATT_MASK,
>>>>       CMB_PATT,
>>>> -    CMB_PATT_MASK
>>>> +    CMB_PATT_MASK,
>>>> +    CMB_MSR
>>>>   };
>>>>     /**
>>>
>>> _______________________________________________
>>> CoreSight mailing list -- [email protected]
>>> To unsubscribe send an email to [email protected]
>

2023-12-20 09:51:53

by Tao Zhang

[permalink] [raw]
Subject: Re: [PATCH v3 6/8] coresight-tpdm: Add timestamp control register support for the CMB


On 12/19/2023 9:51 PM, Suzuki K Poulose wrote:
> On 19/12/2023 02:43, Tao Zhang wrote:
>>
>> On 12/18/2023 6:46 PM, Suzuki K Poulose wrote:
>>> On 21/11/2023 02:24, Tao Zhang wrote:
>>>> CMB_TIER register is CMB subunit timestamp insertion enable register.
>>>> Bit 0 is PATT_TSENAB bit. Set this bit to 1 to request a timestamp
>>>> following a CMB interface pattern match. Bit 1 is XTRIG_TSENAB bit.
>>>> Set this bit to 1 to request a timestamp following a CMB CTI timestamp
>>>> request. Bit 2 is TS_ALL bit. Set this bit to 1 to request timestamp
>>>> for all packets.
>>>>
>>>> Reviewed-by: James Clark <[email protected]>
>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>> Signed-off-by: Jinlong Mao <[email protected]>
>>>> ---
>>>>   .../testing/sysfs-bus-coresight-devices-tpdm  |  35 ++++++
>>>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 116
>>>> +++++++++++++++++-
>>>>   drivers/hwtracing/coresight/coresight-tpdm.h  |  14 +++
>>>>   3 files changed, 162 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git
>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>> index 53662ce7c2d0..e0b77107be13 100644
>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>> @@ -214,3 +214,38 @@ KernelVersion    6.7
>>>>   Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>> Zhang (QUIC) <[email protected]>
>>>>   Description:
>>>>           (RW) Set/Get the mask of the pattern for the CMB subunit
>>>> TPDM.
>>>> +
>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_patt/enable_ts
>>>> +Date:        September 2023
>>>> +KernelVersion    6.7
>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>> Zhang (QUIC) <[email protected]>
>>>> +Description:
>>>> +        (Write) Set the pattern timestamp of CMB tpdm. Read
>>>> +        the pattern timestamp of CMB tpdm.
>>>> +
>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>> +        0 : Disable CMB pattern timestamp.
>>>> +        1 : Enable CMB pattern timestamp.
>>>> +
>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_ts
>>>> +Date:        September 2023
>>>> +KernelVersion    6.7
>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>> Zhang (QUIC) <[email protected]>
>>>> +Description:
>>>> +        (RW) Set/Get the trigger timestamp of the CMB for tpdm.
>>>> +
>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>> +        0 : Set the CMB trigger type to false
>>>> +        1 : Set the CMB trigger type to true
>>>> +
>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_ts_all
>>>> +Date:        September 2023
>>>> +KernelVersion    6.7
>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>> Zhang (QUIC) <[email protected]>
>>>> +Description:
>>>> +        (RW) Read or write the status of timestamp upon all
>>>> interface.
>>>> +        Only value 0 and 1  can be written to this node. Set this
>>>> node to 1 to requeset
>>>> +        timestamp to all trace packet.
>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>> +        0 : Disable the timestamp of all trace packets.
>>>> +        1 : Enable the timestamp of all trace packets.
>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>> index 894d4309f1c7..f6cda5616e84 100644
>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>> @@ -331,6 +331,36 @@ static void tpdm_enable_dsb(struct
>>>> tpdm_drvdata *drvdata)
>>>>       writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
>>>>   }
>>>>   +static void set_cmb_tier(struct tpdm_drvdata *drvdata)
>>>> +{
>>>> +    u32 val;
>>>> +
>>>> +    val = readl_relaxed(drvdata->base + TPDM_CMB_TIER);
>>>> +
>>>> +    /* Clear all relevant fields */
>>>> +    val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL |
>>>> +         TPDM_CMB_TIER_XTRIG_TSENAB);
>>>> +
>>>> +    /* Set pattern timestamp type and enablement */
>>>> +    if (drvdata->cmb->patt_ts)
>>>> +        val |= TPDM_CMB_TIER_PATT_TSENAB;
>>>
>>>  -- cut --
>>>> +    else
>>>> +        val &= ~TPDM_CMB_TIER_PATT_TSENAB;
>>>
>>>
>>> All the else cases in this function are superfluous. Please remove all
>>> of them.
>> I will update this in the next patch.
>>>
>>>> +
>>>> +    /* Set trigger timestamp */
>>>> +    if (drvdata->cmb->trig_ts)
>>>> +        val |= TPDM_CMB_TIER_XTRIG_TSENAB;
>>>> +    else
>>>> +        val &= ~TPDM_CMB_TIER_XTRIG_TSENAB;
>>>> +
>>>> +    /* Set all timestamp enablement*/
>>>> +    if (drvdata->cmb->ts_all)
>>>> +        val |= TPDM_CMB_TIER_TS_ALL;
>>>> +    else
>>>> +        val &= ~TPDM_CMB_TIER_TS_ALL;
>>>> +    writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
>>>> +}
>>>> +
>>>>   static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
>>>>   {
>>>>       u32 val, i;
>>>> @@ -347,6 +377,8 @@ static void tpdm_enable_cmb(struct tpdm_drvdata
>>>> *drvdata)
>>>>                   drvdata->base + TPDM_CMB_XPMR(i));
>>>>       }
>>>>   +    set_cmb_tier(drvdata);
>>>> +
>>>>       val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
>>>>       /*
>>>>        * Set to 0 for continuous CMB collection mode,
>>>> @@ -695,9 +727,17 @@ static ssize_t enable_ts_show(struct device *dev,
>>>>                     char *buf)
>>>>   {
>>>>       struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>> +    ssize_t size = 0;
>>>>   -    return sysfs_emit(buf, "%u\n",
>>>> -             (unsigned int)drvdata->dsb->patt_ts);
>>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>>> +        size = sysfs_emit(buf, "%u\n",
>>>> +                 (unsigned int)drvdata->dsb->patt_ts);
>>>> +
>>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>>> +        size = sysfs_emit(buf, "%u\n",
>>>> +                 (unsigned int)drvdata->cmb->patt_ts);
>>>
>>> Why does this need to show two values ? This must only show ONE value.
>>> How you deduce that might be based on the availability of the feature
>>> set. Or store the TS value in the drvdata and use that instead for
>>> controlling CMB/DSB.
>>
>> Since both of CMB/DSB need to have "enable_ts" SysFs file, can I
>> separate them
>
> The question really is, do we need fine grained control. i.e.,
>
> enable TS for DSB but not for CMB or vice versa.
>
> I am not an expert on the usage scenario of the same. So, if you/Qcomm
> thinks the users need separate, fine grained control for timestamp
> for the DSB and CMB, then yes, follow your recommendation below.
> i.e., tpdm.../dsb_patt/enable_ts
>
>> as "enable_dsb_ts" and "enable_cmb_ts"? The path will be like below.
>>
>> tpdm0/dsb_patt/enable_dsb_ts
>
> You don't need enable_dsb_ts. It could be "enable_ts"
>
>>
>> tpdm1/cmb_patt/enable_cmb_ts
>>
>> Is this design appropriate?
>
>
> Otherwise, stick to single enable_ts : which enables the ts for both
> CMB/DSB. And it only ever show one value : 0 (TS is disabled for both
> CMB/DSB) 1 : TS enabled for both.

We have a very special case, such as the TPDM supporting both CMB and

DSB datasets. Although this case is very rare, it still exists.

Can I use the data bit to instruct whether timestamp is enabled for
CMB/DSB or not? For example,

size = sysfs_emit(buf, "%u\n",
                (unsigned int)(drvdata->dsb->patt_ts << 1 |
drvdata->cmb->patt_ts));

Thus, this value can instruct the following situations.

0 - TS is disabled for both CMB/DSB

1 - TS is enabled for CMB

2 - TS is enabled for DSB

3 - TS is enabled for both

Is this approach acceptable?


Best,

Tao

>
> Suzuki
>
>
>>>
>
>>> Also, the sysfs documentation needs update, if this is going to
>>> control the CMB.
>>
>> Sure. I will update the SysFs documentation according to the
>> modification in the
>>
>> next patch series.
>>
>>
>> Best,
>>
>> Tao
>>
>>>
>>> Suzuki
>>>
>>>
>>>> +
>>>> +    return size;
>>>>   }
>>>>     /*
>>>> @@ -715,8 +755,13 @@ static ssize_t enable_ts_store(struct device
>>>> *dev,
>>>>           return -EINVAL;
>>>>         spin_lock(&drvdata->spinlock);
>>>> -    drvdata->dsb->patt_ts = !!val;
>>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>>> +        drvdata->dsb->patt_ts = !!val;
>>>> +
>>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>>> +        drvdata->cmb->patt_ts = !!val;
>>>>       spin_unlock(&drvdata->spinlock);
>>>> +
>>>>       return size;
>>>>   }
>>>>   static DEVICE_ATTR_RW(enable_ts);
>>>> @@ -851,6 +896,68 @@ static ssize_t cmb_mode_store(struct device *dev,
>>>>   }
>>>>   static DEVICE_ATTR_RW(cmb_mode);
>>>>   +static ssize_t cmb_ts_all_show(struct device *dev,
>>>> +                   struct device_attribute *attr,
>>>> +                   char *buf)
>>>> +{
>>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>> +
>>>> +    return sysfs_emit(buf, "%u\n",
>>>> +              (unsigned int)drvdata->cmb->ts_all);
>>>> +}
>>>> +
>>>> +static ssize_t cmb_ts_all_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 val;
>>>> +
>>>> +    if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
>>>> +        return -EINVAL;
>>>> +
>>>> +    spin_lock(&drvdata->spinlock);
>>>> +    if (val)
>>>> +        drvdata->cmb->ts_all = true;
>>>> +    else
>>>> +        drvdata->cmb->ts_all = false;
>>>> +    spin_unlock(&drvdata->spinlock);
>>>> +    return size;
>>>> +}
>>>> +static DEVICE_ATTR_RW(cmb_ts_all);
>>>> +
>>>> +static ssize_t cmb_trig_ts_show(struct device *dev,
>>>> +                struct device_attribute *attr,
>>>> +                char *buf)
>>>> +{
>>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>> +
>>>> +    return sysfs_emit(buf, "%u\n",
>>>> +              (unsigned int)drvdata->cmb->trig_ts);
>>>> +}
>>>> +
>>>> +static ssize_t cmb_trig_ts_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 val;
>>>> +
>>>> +    if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
>>>> +        return -EINVAL;
>>>> +
>>>> +    spin_lock(&drvdata->spinlock);
>>>> +    if (val)
>>>> +        drvdata->cmb->trig_ts = true;
>>>> +    else
>>>> +        drvdata->cmb->trig_ts = false;
>>>> +    spin_unlock(&drvdata->spinlock);
>>>> +    return size;
>>>> +}
>>>> +static DEVICE_ATTR_RW(cmb_trig_ts);
>>>> +
>>>>   static struct attribute *tpdm_dsb_edge_attrs[] = {
>>>>       &dev_attr_ctrl_idx.attr,
>>>>       &dev_attr_ctrl_val.attr,
>>>> @@ -973,6 +1080,7 @@ static struct attribute *tpdm_cmb_patt_attrs[]
>>>> = {
>>>>       CMB_PATT_ATTR(1),
>>>>       CMB_PATT_MASK_ATTR(0),
>>>>       CMB_PATT_MASK_ATTR(1),
>>>> +    &dev_attr_enable_ts.attr,
>>>>       NULL,
>>>>   };
>>>>   @@ -985,6 +1093,8 @@ static struct attribute *tpdm_dsb_attrs[] = {
>>>>     static struct attribute *tpdm_cmb_attrs[] = {
>>>>       &dev_attr_cmb_mode.attr,
>>>> +    &dev_attr_cmb_ts_all.attr,
>>>> +    &dev_attr_cmb_trig_ts.attr,
>>>>       NULL,
>>>>   };
>>>>   diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h
>>>> b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>> index e90d008c1cb2..65b7ca6c4077 100644
>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.h
>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>> @@ -11,6 +11,8 @@
>>>>     /* CMB Subunit Registers */
>>>>   #define TPDM_CMB_CR        (0xA00)
>>>> +/*CMB subunit timestamp insertion enable register*/
>>>> +#define TPDM_CMB_TIER        (0xA04)
>>>>   /*CMB subunit timestamp pattern registers*/
>>>>   #define TPDM_CMB_TPR(n)        (0xA08 + (n * 4))
>>>>   /*CMB subunit timestamp pattern mask registers*/
>>>> @@ -24,6 +26,12 @@
>>>>   #define TPDM_CMB_CR_ENA        BIT(0)
>>>>   /* Trace collection mode for CMB subunit */
>>>>   #define TPDM_CMB_CR_MODE    BIT(1)
>>>> +/* Timestamp control for pattern match */
>>>> +#define TPDM_CMB_TIER_PATT_TSENAB    BIT(0)
>>>> +/* CMB CTI timestamp request */
>>>> +#define TPDM_CMB_TIER_XTRIG_TSENAB    BIT(1)
>>>> +/* For timestamp fo all trace */
>>>> +#define TPDM_CMB_TIER_TS_ALL        BIT(2)
>>>>     /*Patten register number*/
>>>>   #define TPDM_CMB_MAX_PATT        2
>>>> @@ -217,6 +225,9 @@ struct dsb_dataset {
>>>>    * @patt_mask:        Save value for pattern mask
>>>>    * @trig_patt:        Save value for trigger pattern
>>>>    * @trig_patt_mask:   Save value for trigger pattern mask
>>>> + * @patt_ts:          Indicates if pattern match for timestamp is
>>>> enabled.
>>>> + * @trig_ts:          Indicates if CTI trigger for timestamp is
>>>> enabled.
>>>> + * @ts_all:           Indicates if timestamp is enabled for all
>>>> packets.
>>>>    */
>>>>   struct cmb_dataset {
>>>>       u32            trace_mode;
>>>> @@ -224,6 +235,9 @@ struct cmb_dataset {
>>>>       u32            patt_mask[TPDM_CMB_MAX_PATT];
>>>>       u32            trig_patt[TPDM_CMB_MAX_PATT];
>>>>       u32            trig_patt_mask[TPDM_CMB_MAX_PATT];
>>>> +    bool            patt_ts;
>>>> +    bool            trig_ts;
>>>> +    bool            ts_all;
>>>>   };
>>>>     /**
>>>
>
> _______________________________________________
> CoreSight mailing list -- [email protected]
> To unsubscribe send an email to [email protected]

2023-12-20 11:07:21

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH v3 6/8] coresight-tpdm: Add timestamp control register support for the CMB

On 20/12/2023 09:51, Tao Zhang wrote:
>
> On 12/19/2023 9:51 PM, Suzuki K Poulose wrote:
>> On 19/12/2023 02:43, Tao Zhang wrote:
>>>
>>> On 12/18/2023 6:46 PM, Suzuki K Poulose wrote:
>>>> On 21/11/2023 02:24, Tao Zhang wrote:
>>>>> CMB_TIER register is CMB subunit timestamp insertion enable register.
>>>>> Bit 0 is PATT_TSENAB bit. Set this bit to 1 to request a timestamp
>>>>> following a CMB interface pattern match. Bit 1 is XTRIG_TSENAB bit.
>>>>> Set this bit to 1 to request a timestamp following a CMB CTI timestamp
>>>>> request. Bit 2 is TS_ALL bit. Set this bit to 1 to request timestamp
>>>>> for all packets.
>>>>>
>>>>> Reviewed-by: James Clark <[email protected]>
>>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>>> Signed-off-by: Jinlong Mao <[email protected]>
>>>>> ---
>>>>>   .../testing/sysfs-bus-coresight-devices-tpdm  |  35 ++++++
>>>>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 116
>>>>> +++++++++++++++++-
>>>>>   drivers/hwtracing/coresight/coresight-tpdm.h  |  14 +++
>>>>>   3 files changed, 162 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git
>>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>> index 53662ce7c2d0..e0b77107be13 100644
>>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>> @@ -214,3 +214,38 @@ KernelVersion    6.7
>>>>>   Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>> Zhang (QUIC) <[email protected]>
>>>>>   Description:
>>>>>           (RW) Set/Get the mask of the pattern for the CMB subunit
>>>>> TPDM.
>>>>> +
>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_patt/enable_ts
>>>>> +Date:        September 2023
>>>>> +KernelVersion    6.7
>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>> Zhang (QUIC) <[email protected]>
>>>>> +Description:
>>>>> +        (Write) Set the pattern timestamp of CMB tpdm. Read
>>>>> +        the pattern timestamp of CMB tpdm.
>>>>> +
>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>> +        0 : Disable CMB pattern timestamp.
>>>>> +        1 : Enable CMB pattern timestamp.
>>>>> +
>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_ts
>>>>> +Date:        September 2023
>>>>> +KernelVersion    6.7
>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>> Zhang (QUIC) <[email protected]>
>>>>> +Description:
>>>>> +        (RW) Set/Get the trigger timestamp of the CMB for tpdm.
>>>>> +
>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>> +        0 : Set the CMB trigger type to false
>>>>> +        1 : Set the CMB trigger type to true
>>>>> +
>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_ts_all
>>>>> +Date:        September 2023
>>>>> +KernelVersion    6.7
>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>> Zhang (QUIC) <[email protected]>
>>>>> +Description:
>>>>> +        (RW) Read or write the status of timestamp upon all
>>>>> interface.
>>>>> +        Only value 0 and 1  can be written to this node. Set this
>>>>> node to 1 to requeset
>>>>> +        timestamp to all trace packet.
>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>> +        0 : Disable the timestamp of all trace packets.
>>>>> +        1 : Enable the timestamp of all trace packets.
>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>> index 894d4309f1c7..f6cda5616e84 100644
>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>> @@ -331,6 +331,36 @@ static void tpdm_enable_dsb(struct
>>>>> tpdm_drvdata *drvdata)
>>>>>       writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
>>>>>   }
>>>>>   +static void set_cmb_tier(struct tpdm_drvdata *drvdata)
>>>>> +{
>>>>> +    u32 val;
>>>>> +
>>>>> +    val = readl_relaxed(drvdata->base + TPDM_CMB_TIER);
>>>>> +
>>>>> +    /* Clear all relevant fields */
>>>>> +    val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL |
>>>>> +         TPDM_CMB_TIER_XTRIG_TSENAB);
>>>>> +
>>>>> +    /* Set pattern timestamp type and enablement */
>>>>> +    if (drvdata->cmb->patt_ts)
>>>>> +        val |= TPDM_CMB_TIER_PATT_TSENAB;
>>>>
>>>>  -- cut --
>>>>> +    else
>>>>> +        val &= ~TPDM_CMB_TIER_PATT_TSENAB;
>>>>
>>>>
>>>> All the else cases in this function are superfluous. Please remove all
>>>> of them.
>>> I will update this in the next patch.
>>>>
>>>>> +
>>>>> +    /* Set trigger timestamp */
>>>>> +    if (drvdata->cmb->trig_ts)
>>>>> +        val |= TPDM_CMB_TIER_XTRIG_TSENAB;
>>>>> +    else
>>>>> +        val &= ~TPDM_CMB_TIER_XTRIG_TSENAB;
>>>>> +
>>>>> +    /* Set all timestamp enablement*/
>>>>> +    if (drvdata->cmb->ts_all)
>>>>> +        val |= TPDM_CMB_TIER_TS_ALL;
>>>>> +    else
>>>>> +        val &= ~TPDM_CMB_TIER_TS_ALL;
>>>>> +    writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
>>>>> +}
>>>>> +
>>>>>   static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
>>>>>   {
>>>>>       u32 val, i;
>>>>> @@ -347,6 +377,8 @@ static void tpdm_enable_cmb(struct tpdm_drvdata
>>>>> *drvdata)
>>>>>                   drvdata->base + TPDM_CMB_XPMR(i));
>>>>>       }
>>>>>   +    set_cmb_tier(drvdata);
>>>>> +
>>>>>       val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
>>>>>       /*
>>>>>        * Set to 0 for continuous CMB collection mode,
>>>>> @@ -695,9 +727,17 @@ static ssize_t enable_ts_show(struct device *dev,
>>>>>                     char *buf)
>>>>>   {
>>>>>       struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>>> +    ssize_t size = 0;
>>>>>   -    return sysfs_emit(buf, "%u\n",
>>>>> -             (unsigned int)drvdata->dsb->patt_ts);
>>>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>>>> +        size = sysfs_emit(buf, "%u\n",
>>>>> +                 (unsigned int)drvdata->dsb->patt_ts);
>>>>> +
>>>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>>>> +        size = sysfs_emit(buf, "%u\n",
>>>>> +                 (unsigned int)drvdata->cmb->patt_ts);
>>>>
>>>> Why does this need to show two values ? This must only show ONE value.
>>>> How you deduce that might be based on the availability of the feature
>>>> set. Or store the TS value in the drvdata and use that instead for
>>>> controlling CMB/DSB.
>>>
>>> Since both of CMB/DSB need to have "enable_ts" SysFs file, can I
>>> separate them
>>
>> The question really is, do we need fine grained control. i.e.,
>>
>> enable TS for DSB but not for CMB or vice versa.
>>
>> I am not an expert on the usage scenario of the same. So, if you/Qcomm
>> thinks the users need separate, fine grained control for timestamp
>> for the DSB and CMB, then yes, follow your recommendation below.
>> i.e., tpdm.../dsb_patt/enable_ts
>>
>>> as "enable_dsb_ts" and "enable_cmb_ts"? The path will be like below.
>>>
>>> tpdm0/dsb_patt/enable_dsb_ts
>>
>> You don't need enable_dsb_ts. It could be "enable_ts"
>>
>>>
>>> tpdm1/cmb_patt/enable_cmb_ts
>>>
>>> Is this design appropriate?
>>
>>
>> Otherwise, stick to single enable_ts : which enables the ts for both
>> CMB/DSB. And it only ever show one value : 0 (TS is disabled for both
>> CMB/DSB) 1 : TS enabled for both.
>
> We have a very special case, such as the TPDM supporting both CMB and
>
> DSB datasets. Although this case is very rare, it still exists.
>
> Can I use the data bit to instruct whether timestamp is enabled for
> CMB/DSB or not? For example,
>
> size = sysfs_emit(buf, "%u\n",
>                 (unsigned int)(drvdata->dsb->patt_ts << 1 |
> drvdata->cmb->patt_ts));
>
> Thus, this value can instruct the following situations.
>
> 0 - TS is disabled for both CMB/DSB
>
> 1 - TS is enabled for CMB
>
> 2 - TS is enabled for DSB
>
> 3 - TS is enabled for both
>
> Is this approach acceptable?
>

No, please stick to separate controls for TS. Do not complicate
the user interface.

i.e.,
tpdm0/dsb_patt/enable_ts
tpdm0/cmb_patt/enable_ts

Suzuki


>
> Best,
>
> Tao
>
>>
>> Suzuki
>>
>>
>>>>
>>
>>>> Also, the sysfs documentation needs update, if this is going to
>>>> control the CMB.
>>>
>>> Sure. I will update the SysFs documentation according to the
>>> modification in the
>>>
>>> next patch series.
>>>
>>>
>>> Best,
>>>
>>> Tao
>>>
>>>>
>>>> Suzuki
>>>>
>>>>
>>>>> +
>>>>> +    return size;
>>>>>   }
>>>>>     /*
>>>>> @@ -715,8 +755,13 @@ static ssize_t enable_ts_store(struct device
>>>>> *dev,
>>>>>           return -EINVAL;
>>>>>         spin_lock(&drvdata->spinlock);
>>>>> -    drvdata->dsb->patt_ts = !!val;
>>>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>>>> +        drvdata->dsb->patt_ts = !!val;
>>>>> +
>>>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>>>> +        drvdata->cmb->patt_ts = !!val;
>>>>>       spin_unlock(&drvdata->spinlock);
>>>>> +
>>>>>       return size;
>>>>>   }
>>>>>   static DEVICE_ATTR_RW(enable_ts);
>>>>> @@ -851,6 +896,68 @@ static ssize_t cmb_mode_store(struct device *dev,
>>>>>   }
>>>>>   static DEVICE_ATTR_RW(cmb_mode);
>>>>>   +static ssize_t cmb_ts_all_show(struct device *dev,
>>>>> +                   struct device_attribute *attr,
>>>>> +                   char *buf)
>>>>> +{
>>>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>>> +
>>>>> +    return sysfs_emit(buf, "%u\n",
>>>>> +              (unsigned int)drvdata->cmb->ts_all);
>>>>> +}
>>>>> +
>>>>> +static ssize_t cmb_ts_all_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 val;
>>>>> +
>>>>> +    if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
>>>>> +        return -EINVAL;
>>>>> +
>>>>> +    spin_lock(&drvdata->spinlock);
>>>>> +    if (val)
>>>>> +        drvdata->cmb->ts_all = true;
>>>>> +    else
>>>>> +        drvdata->cmb->ts_all = false;
>>>>> +    spin_unlock(&drvdata->spinlock);
>>>>> +    return size;
>>>>> +}
>>>>> +static DEVICE_ATTR_RW(cmb_ts_all);
>>>>> +
>>>>> +static ssize_t cmb_trig_ts_show(struct device *dev,
>>>>> +                struct device_attribute *attr,
>>>>> +                char *buf)
>>>>> +{
>>>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>>> +
>>>>> +    return sysfs_emit(buf, "%u\n",
>>>>> +              (unsigned int)drvdata->cmb->trig_ts);
>>>>> +}
>>>>> +
>>>>> +static ssize_t cmb_trig_ts_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 val;
>>>>> +
>>>>> +    if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
>>>>> +        return -EINVAL;
>>>>> +
>>>>> +    spin_lock(&drvdata->spinlock);
>>>>> +    if (val)
>>>>> +        drvdata->cmb->trig_ts = true;
>>>>> +    else
>>>>> +        drvdata->cmb->trig_ts = false;
>>>>> +    spin_unlock(&drvdata->spinlock);
>>>>> +    return size;
>>>>> +}
>>>>> +static DEVICE_ATTR_RW(cmb_trig_ts);
>>>>> +
>>>>>   static struct attribute *tpdm_dsb_edge_attrs[] = {
>>>>>       &dev_attr_ctrl_idx.attr,
>>>>>       &dev_attr_ctrl_val.attr,
>>>>> @@ -973,6 +1080,7 @@ static struct attribute *tpdm_cmb_patt_attrs[]
>>>>> = {
>>>>>       CMB_PATT_ATTR(1),
>>>>>       CMB_PATT_MASK_ATTR(0),
>>>>>       CMB_PATT_MASK_ATTR(1),
>>>>> +    &dev_attr_enable_ts.attr,
>>>>>       NULL,
>>>>>   };
>>>>>   @@ -985,6 +1093,8 @@ static struct attribute *tpdm_dsb_attrs[] = {
>>>>>     static struct attribute *tpdm_cmb_attrs[] = {
>>>>>       &dev_attr_cmb_mode.attr,
>>>>> +    &dev_attr_cmb_ts_all.attr,
>>>>> +    &dev_attr_cmb_trig_ts.attr,
>>>>>       NULL,
>>>>>   };
>>>>>   diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>> index e90d008c1cb2..65b7ca6c4077 100644
>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>> @@ -11,6 +11,8 @@
>>>>>     /* CMB Subunit Registers */
>>>>>   #define TPDM_CMB_CR        (0xA00)
>>>>> +/*CMB subunit timestamp insertion enable register*/
>>>>> +#define TPDM_CMB_TIER        (0xA04)
>>>>>   /*CMB subunit timestamp pattern registers*/
>>>>>   #define TPDM_CMB_TPR(n)        (0xA08 + (n * 4))
>>>>>   /*CMB subunit timestamp pattern mask registers*/
>>>>> @@ -24,6 +26,12 @@
>>>>>   #define TPDM_CMB_CR_ENA        BIT(0)
>>>>>   /* Trace collection mode for CMB subunit */
>>>>>   #define TPDM_CMB_CR_MODE    BIT(1)
>>>>> +/* Timestamp control for pattern match */
>>>>> +#define TPDM_CMB_TIER_PATT_TSENAB    BIT(0)
>>>>> +/* CMB CTI timestamp request */
>>>>> +#define TPDM_CMB_TIER_XTRIG_TSENAB    BIT(1)
>>>>> +/* For timestamp fo all trace */
>>>>> +#define TPDM_CMB_TIER_TS_ALL        BIT(2)
>>>>>     /*Patten register number*/
>>>>>   #define TPDM_CMB_MAX_PATT        2
>>>>> @@ -217,6 +225,9 @@ struct dsb_dataset {
>>>>>    * @patt_mask:        Save value for pattern mask
>>>>>    * @trig_patt:        Save value for trigger pattern
>>>>>    * @trig_patt_mask:   Save value for trigger pattern mask
>>>>> + * @patt_ts:          Indicates if pattern match for timestamp is
>>>>> enabled.
>>>>> + * @trig_ts:          Indicates if CTI trigger for timestamp is
>>>>> enabled.
>>>>> + * @ts_all:           Indicates if timestamp is enabled for all
>>>>> packets.
>>>>>    */
>>>>>   struct cmb_dataset {
>>>>>       u32            trace_mode;
>>>>> @@ -224,6 +235,9 @@ struct cmb_dataset {
>>>>>       u32            patt_mask[TPDM_CMB_MAX_PATT];
>>>>>       u32            trig_patt[TPDM_CMB_MAX_PATT];
>>>>>       u32            trig_patt_mask[TPDM_CMB_MAX_PATT];
>>>>> +    bool            patt_ts;
>>>>> +    bool            trig_ts;
>>>>> +    bool            ts_all;
>>>>>   };
>>>>>     /**
>>>>
>>
>> _______________________________________________
>> CoreSight mailing list -- [email protected]
>> To unsubscribe send an email to [email protected]


2023-12-25 01:56:51

by Tao Zhang

[permalink] [raw]
Subject: Re: [PATCH v3 6/8] coresight-tpdm: Add timestamp control register support for the CMB


On 12/20/2023 7:07 PM, Suzuki K Poulose wrote:
> On 20/12/2023 09:51, Tao Zhang wrote:
>>
>> On 12/19/2023 9:51 PM, Suzuki K Poulose wrote:
>>> On 19/12/2023 02:43, Tao Zhang wrote:
>>>>
>>>> On 12/18/2023 6:46 PM, Suzuki K Poulose wrote:
>>>>> On 21/11/2023 02:24, Tao Zhang wrote:
>>>>>> CMB_TIER register is CMB subunit timestamp insertion enable
>>>>>> register.
>>>>>> Bit 0 is PATT_TSENAB bit. Set this bit to 1 to request a timestamp
>>>>>> following a CMB interface pattern match. Bit 1 is XTRIG_TSENAB bit.
>>>>>> Set this bit to 1 to request a timestamp following a CMB CTI
>>>>>> timestamp
>>>>>> request. Bit 2 is TS_ALL bit. Set this bit to 1 to request timestamp
>>>>>> for all packets.
>>>>>>
>>>>>> Reviewed-by: James Clark <[email protected]>
>>>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>>>> Signed-off-by: Jinlong Mao <[email protected]>
>>>>>> ---
>>>>>>   .../testing/sysfs-bus-coresight-devices-tpdm  |  35 ++++++
>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 116
>>>>>> +++++++++++++++++-
>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.h  |  14 +++
>>>>>>   3 files changed, 162 insertions(+), 3 deletions(-)
>>>>>>
>>>>>> diff --git
>>>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>> index 53662ce7c2d0..e0b77107be13 100644
>>>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>> @@ -214,3 +214,38 @@ KernelVersion    6.7
>>>>>>   Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>> Zhang (QUIC) <[email protected]>
>>>>>>   Description:
>>>>>>           (RW) Set/Get the mask of the pattern for the CMB
>>>>>> subunit TPDM.
>>>>>> +
>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_patt/enable_ts
>>>>>> +Date:        September 2023
>>>>>> +KernelVersion    6.7
>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>> Zhang (QUIC) <[email protected]>
>>>>>> +Description:
>>>>>> +        (Write) Set the pattern timestamp of CMB tpdm. Read
>>>>>> +        the pattern timestamp of CMB tpdm.
>>>>>> +
>>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>>> +        0 : Disable CMB pattern timestamp.
>>>>>> +        1 : Enable CMB pattern timestamp.
>>>>>> +
>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_ts
>>>>>> +Date:        September 2023
>>>>>> +KernelVersion    6.7
>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>> Zhang (QUIC) <[email protected]>
>>>>>> +Description:
>>>>>> +        (RW) Set/Get the trigger timestamp of the CMB for tpdm.
>>>>>> +
>>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>>> +        0 : Set the CMB trigger type to false
>>>>>> +        1 : Set the CMB trigger type to true
>>>>>> +
>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_ts_all
>>>>>> +Date:        September 2023
>>>>>> +KernelVersion    6.7
>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>> Zhang (QUIC) <[email protected]>
>>>>>> +Description:
>>>>>> +        (RW) Read or write the status of timestamp upon all
>>>>>> interface.
>>>>>> +        Only value 0 and 1  can be written to this node. Set
>>>>>> this node to 1 to requeset
>>>>>> +        timestamp to all trace packet.
>>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>>> +        0 : Disable the timestamp of all trace packets.
>>>>>> +        1 : Enable the timestamp of all trace packets.
>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>> index 894d4309f1c7..f6cda5616e84 100644
>>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>> @@ -331,6 +331,36 @@ static void tpdm_enable_dsb(struct
>>>>>> tpdm_drvdata *drvdata)
>>>>>>       writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
>>>>>>   }
>>>>>>   +static void set_cmb_tier(struct tpdm_drvdata *drvdata)
>>>>>> +{
>>>>>> +    u32 val;
>>>>>> +
>>>>>> +    val = readl_relaxed(drvdata->base + TPDM_CMB_TIER);
>>>>>> +
>>>>>> +    /* Clear all relevant fields */
>>>>>> +    val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL |
>>>>>> +         TPDM_CMB_TIER_XTRIG_TSENAB);
>>>>>> +
>>>>>> +    /* Set pattern timestamp type and enablement */
>>>>>> +    if (drvdata->cmb->patt_ts)
>>>>>> +        val |= TPDM_CMB_TIER_PATT_TSENAB;
>>>>>
>>>>>  -- cut --
>>>>>> +    else
>>>>>> +        val &= ~TPDM_CMB_TIER_PATT_TSENAB;
>>>>>
>>>>>
>>>>> All the else cases in this function are superfluous. Please remove
>>>>> all
>>>>> of them.
>>>> I will update this in the next patch.
>>>>>
>>>>>> +
>>>>>> +    /* Set trigger timestamp */
>>>>>> +    if (drvdata->cmb->trig_ts)
>>>>>> +        val |= TPDM_CMB_TIER_XTRIG_TSENAB;
>>>>>> +    else
>>>>>> +        val &= ~TPDM_CMB_TIER_XTRIG_TSENAB;
>>>>>> +
>>>>>> +    /* Set all timestamp enablement*/
>>>>>> +    if (drvdata->cmb->ts_all)
>>>>>> +        val |= TPDM_CMB_TIER_TS_ALL;
>>>>>> +    else
>>>>>> +        val &= ~TPDM_CMB_TIER_TS_ALL;
>>>>>> +    writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
>>>>>> +}
>>>>>> +
>>>>>>   static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
>>>>>>   {
>>>>>>       u32 val, i;
>>>>>> @@ -347,6 +377,8 @@ static void tpdm_enable_cmb(struct
>>>>>> tpdm_drvdata *drvdata)
>>>>>>                   drvdata->base + TPDM_CMB_XPMR(i));
>>>>>>       }
>>>>>>   +    set_cmb_tier(drvdata);
>>>>>> +
>>>>>>       val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
>>>>>>       /*
>>>>>>        * Set to 0 for continuous CMB collection mode,
>>>>>> @@ -695,9 +727,17 @@ static ssize_t enable_ts_show(struct device
>>>>>> *dev,
>>>>>>                     char *buf)
>>>>>>   {
>>>>>>       struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>>>> +    ssize_t size = 0;
>>>>>>   -    return sysfs_emit(buf, "%u\n",
>>>>>> -             (unsigned int)drvdata->dsb->patt_ts);
>>>>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>>>>> +        size = sysfs_emit(buf, "%u\n",
>>>>>> +                 (unsigned int)drvdata->dsb->patt_ts);
>>>>>> +
>>>>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>>>>> +        size = sysfs_emit(buf, "%u\n",
>>>>>> +                 (unsigned int)drvdata->cmb->patt_ts);
>>>>>
>>>>> Why does this need to show two values ? This must only show ONE
>>>>> value.
>>>>> How you deduce that might be based on the availability of the feature
>>>>> set. Or store the TS value in the drvdata and use that instead for
>>>>> controlling CMB/DSB.
>>>>
>>>> Since both of CMB/DSB need to have "enable_ts" SysFs file, can I
>>>> separate them
>>>
>>> The question really is, do we need fine grained control. i.e.,
>>>
>>> enable TS for DSB but not for CMB or vice versa.
>>>
>>> I am not an expert on the usage scenario of the same. So, if you/Qcomm
>>> thinks the users need separate, fine grained control for timestamp
>>> for the DSB and CMB, then yes, follow your recommendation below.
>>> i.e., tpdm.../dsb_patt/enable_ts
>>>
>>>> as "enable_dsb_ts" and "enable_cmb_ts"? The path will be like below.
>>>>
>>>> tpdm0/dsb_patt/enable_dsb_ts
>>>
>>> You don't need enable_dsb_ts. It could be "enable_ts"
>>>
>>>>
>>>> tpdm1/cmb_patt/enable_cmb_ts
>>>>
>>>> Is this design appropriate?
>>>
>>>
>>> Otherwise, stick to single enable_ts : which enables the ts for both
>>> CMB/DSB. And it only ever show one value : 0 (TS is disabled for both
>>> CMB/DSB) 1 : TS enabled for both.
>>
>> We have a very special case, such as the TPDM supporting both CMB and
>>
>> DSB datasets. Although this case is very rare, it still exists.
>>
>> Can I use the data bit to instruct whether timestamp is enabled for
>> CMB/DSB or not? For example,
>>
>> size = sysfs_emit(buf, "%u\n",
>>                  (unsigned int)(drvdata->dsb->patt_ts << 1 |
>> drvdata->cmb->patt_ts));
>>
>> Thus, this value can instruct the following situations.
>>
>> 0 - TS is disabled for both CMB/DSB
>>
>> 1 - TS is enabled for CMB
>>
>> 2 - TS is enabled for DSB
>>
>> 3 - TS is enabled for both
>>
>> Is this approach acceptable?
>>
>
> No, please stick to separate controls for TS. Do not complicate
> the user interface.
>
> i.e.,
> tpdm0/dsb_patt/enable_ts
> tpdm0/cmb_patt/enable_ts

We need to be able to control/show dsb and cmb timestamp enablement
independently.

Can we achieve this requirement if we use a sysfs file with the same name?

I'm not able to find a good way to achieve it. Do you have any
suggestions for this?


Best,

Tao

>
> Suzuki
>
>
>>
>> Best,
>>
>> Tao
>>
>>>
>>> Suzuki
>>>
>>>
>>>>>
>>>
>>>>> Also, the sysfs documentation needs update, if this is going to
>>>>> control the CMB.
>>>>
>>>> Sure. I will update the SysFs documentation according to the
>>>> modification in the
>>>>
>>>> next patch series.
>>>>
>>>>
>>>> Best,
>>>>
>>>> Tao
>>>>
>>>>>
>>>>> Suzuki
>>>>>
>>>>>
>>>>>> +
>>>>>> +    return size;
>>>>>>   }
>>>>>>     /*
>>>>>> @@ -715,8 +755,13 @@ static ssize_t enable_ts_store(struct device
>>>>>> *dev,
>>>>>>           return -EINVAL;
>>>>>>         spin_lock(&drvdata->spinlock);
>>>>>> -    drvdata->dsb->patt_ts = !!val;
>>>>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>>>>> +        drvdata->dsb->patt_ts = !!val;
>>>>>> +
>>>>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>>>>> +        drvdata->cmb->patt_ts = !!val;
>>>>>>       spin_unlock(&drvdata->spinlock);
>>>>>> +
>>>>>>       return size;
>>>>>>   }
>>>>>>   static DEVICE_ATTR_RW(enable_ts);
>>>>>> @@ -851,6 +896,68 @@ static ssize_t cmb_mode_store(struct device
>>>>>> *dev,
>>>>>>   }
>>>>>>   static DEVICE_ATTR_RW(cmb_mode);
>>>>>>   +static ssize_t cmb_ts_all_show(struct device *dev,
>>>>>> +                   struct device_attribute *attr,
>>>>>> +                   char *buf)
>>>>>> +{
>>>>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>>>> +
>>>>>> +    return sysfs_emit(buf, "%u\n",
>>>>>> +              (unsigned int)drvdata->cmb->ts_all);
>>>>>> +}
>>>>>> +
>>>>>> +static ssize_t cmb_ts_all_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 val;
>>>>>> +
>>>>>> +    if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
>>>>>> +        return -EINVAL;
>>>>>> +
>>>>>> +    spin_lock(&drvdata->spinlock);
>>>>>> +    if (val)
>>>>>> +        drvdata->cmb->ts_all = true;
>>>>>> +    else
>>>>>> +        drvdata->cmb->ts_all = false;
>>>>>> +    spin_unlock(&drvdata->spinlock);
>>>>>> +    return size;
>>>>>> +}
>>>>>> +static DEVICE_ATTR_RW(cmb_ts_all);
>>>>>> +
>>>>>> +static ssize_t cmb_trig_ts_show(struct device *dev,
>>>>>> +                struct device_attribute *attr,
>>>>>> +                char *buf)
>>>>>> +{
>>>>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>>>> +
>>>>>> +    return sysfs_emit(buf, "%u\n",
>>>>>> +              (unsigned int)drvdata->cmb->trig_ts);
>>>>>> +}
>>>>>> +
>>>>>> +static ssize_t cmb_trig_ts_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 val;
>>>>>> +
>>>>>> +    if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
>>>>>> +        return -EINVAL;
>>>>>> +
>>>>>> +    spin_lock(&drvdata->spinlock);
>>>>>> +    if (val)
>>>>>> +        drvdata->cmb->trig_ts = true;
>>>>>> +    else
>>>>>> +        drvdata->cmb->trig_ts = false;
>>>>>> +    spin_unlock(&drvdata->spinlock);
>>>>>> +    return size;
>>>>>> +}
>>>>>> +static DEVICE_ATTR_RW(cmb_trig_ts);
>>>>>> +
>>>>>>   static struct attribute *tpdm_dsb_edge_attrs[] = {
>>>>>>       &dev_attr_ctrl_idx.attr,
>>>>>>       &dev_attr_ctrl_val.attr,
>>>>>> @@ -973,6 +1080,7 @@ static struct attribute
>>>>>> *tpdm_cmb_patt_attrs[] = {
>>>>>>       CMB_PATT_ATTR(1),
>>>>>>       CMB_PATT_MASK_ATTR(0),
>>>>>>       CMB_PATT_MASK_ATTR(1),
>>>>>> +    &dev_attr_enable_ts.attr,
>>>>>>       NULL,
>>>>>>   };
>>>>>>   @@ -985,6 +1093,8 @@ static struct attribute *tpdm_dsb_attrs[] = {
>>>>>>     static struct attribute *tpdm_cmb_attrs[] = {
>>>>>>       &dev_attr_cmb_mode.attr,
>>>>>> +    &dev_attr_cmb_ts_all.attr,
>>>>>> +    &dev_attr_cmb_trig_ts.attr,
>>>>>>       NULL,
>>>>>>   };
>>>>>>   diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>> index e90d008c1cb2..65b7ca6c4077 100644
>>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>> @@ -11,6 +11,8 @@
>>>>>>     /* CMB Subunit Registers */
>>>>>>   #define TPDM_CMB_CR        (0xA00)
>>>>>> +/*CMB subunit timestamp insertion enable register*/
>>>>>> +#define TPDM_CMB_TIER        (0xA04)
>>>>>>   /*CMB subunit timestamp pattern registers*/
>>>>>>   #define TPDM_CMB_TPR(n)        (0xA08 + (n * 4))
>>>>>>   /*CMB subunit timestamp pattern mask registers*/
>>>>>> @@ -24,6 +26,12 @@
>>>>>>   #define TPDM_CMB_CR_ENA        BIT(0)
>>>>>>   /* Trace collection mode for CMB subunit */
>>>>>>   #define TPDM_CMB_CR_MODE    BIT(1)
>>>>>> +/* Timestamp control for pattern match */
>>>>>> +#define TPDM_CMB_TIER_PATT_TSENAB    BIT(0)
>>>>>> +/* CMB CTI timestamp request */
>>>>>> +#define TPDM_CMB_TIER_XTRIG_TSENAB    BIT(1)
>>>>>> +/* For timestamp fo all trace */
>>>>>> +#define TPDM_CMB_TIER_TS_ALL        BIT(2)
>>>>>>     /*Patten register number*/
>>>>>>   #define TPDM_CMB_MAX_PATT        2
>>>>>> @@ -217,6 +225,9 @@ struct dsb_dataset {
>>>>>>    * @patt_mask:        Save value for pattern mask
>>>>>>    * @trig_patt:        Save value for trigger pattern
>>>>>>    * @trig_patt_mask:   Save value for trigger pattern mask
>>>>>> + * @patt_ts:          Indicates if pattern match for timestamp
>>>>>> is enabled.
>>>>>> + * @trig_ts:          Indicates if CTI trigger for timestamp is
>>>>>> enabled.
>>>>>> + * @ts_all:           Indicates if timestamp is enabled for all
>>>>>> packets.
>>>>>>    */
>>>>>>   struct cmb_dataset {
>>>>>>       u32            trace_mode;
>>>>>> @@ -224,6 +235,9 @@ struct cmb_dataset {
>>>>>>       u32            patt_mask[TPDM_CMB_MAX_PATT];
>>>>>>       u32            trig_patt[TPDM_CMB_MAX_PATT];
>>>>>>       u32            trig_patt_mask[TPDM_CMB_MAX_PATT];
>>>>>> +    bool            patt_ts;
>>>>>> +    bool            trig_ts;
>>>>>> +    bool            ts_all;
>>>>>>   };
>>>>>>     /**
>>>>>
>>>
>>> _______________________________________________
>>> CoreSight mailing list -- [email protected]
>>> To unsubscribe send an email to [email protected]
>
> _______________________________________________
> CoreSight mailing list -- [email protected]
> To unsubscribe send an email to [email protected]

2023-12-30 09:40:08

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH v3 6/8] coresight-tpdm: Add timestamp control register support for the CMB

On 25/12/2023 01:55, Tao Zhang wrote:
>
> On 12/20/2023 7:07 PM, Suzuki K Poulose wrote:
>> On 20/12/2023 09:51, Tao Zhang wrote:
>>>
>>> On 12/19/2023 9:51 PM, Suzuki K Poulose wrote:
>>>> On 19/12/2023 02:43, Tao Zhang wrote:
>>>>>
>>>>> On 12/18/2023 6:46 PM, Suzuki K Poulose wrote:
>>>>>> On 21/11/2023 02:24, Tao Zhang wrote:
>>>>>>> CMB_TIER register is CMB subunit timestamp insertion enable
>>>>>>> register.
>>>>>>> Bit 0 is PATT_TSENAB bit. Set this bit to 1 to request a timestamp
>>>>>>> following a CMB interface pattern match. Bit 1 is XTRIG_TSENAB bit.
>>>>>>> Set this bit to 1 to request a timestamp following a CMB CTI
>>>>>>> timestamp
>>>>>>> request. Bit 2 is TS_ALL bit. Set this bit to 1 to request timestamp
>>>>>>> for all packets.
>>>>>>>
>>>>>>> Reviewed-by: James Clark <[email protected]>
>>>>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>>>>> Signed-off-by: Jinlong Mao <[email protected]>
>>>>>>> ---
>>>>>>>   .../testing/sysfs-bus-coresight-devices-tpdm  |  35 ++++++
>>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 116
>>>>>>> +++++++++++++++++-
>>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.h  |  14 +++
>>>>>>>   3 files changed, 162 insertions(+), 3 deletions(-)
>>>>>>>
>>>>>>> diff --git
>>>>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>> index 53662ce7c2d0..e0b77107be13 100644
>>>>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>> @@ -214,3 +214,38 @@ KernelVersion    6.7
>>>>>>>   Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>>> Zhang (QUIC) <[email protected]>
>>>>>>>   Description:
>>>>>>>           (RW) Set/Get the mask of the pattern for the CMB
>>>>>>> subunit TPDM.
>>>>>>> +
>>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_patt/enable_ts
>>>>>>> +Date:        September 2023
>>>>>>> +KernelVersion    6.7
>>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>>> Zhang (QUIC) <[email protected]>
>>>>>>> +Description:
>>>>>>> +        (Write) Set the pattern timestamp of CMB tpdm. Read
>>>>>>> +        the pattern timestamp of CMB tpdm.
>>>>>>> +
>>>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>>>> +        0 : Disable CMB pattern timestamp.
>>>>>>> +        1 : Enable CMB pattern timestamp.
>>>>>>> +
>>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_ts
>>>>>>> +Date:        September 2023
>>>>>>> +KernelVersion    6.7
>>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>>> Zhang (QUIC) <[email protected]>
>>>>>>> +Description:
>>>>>>> +        (RW) Set/Get the trigger timestamp of the CMB for tpdm.
>>>>>>> +
>>>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>>>> +        0 : Set the CMB trigger type to false
>>>>>>> +        1 : Set the CMB trigger type to true
>>>>>>> +
>>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_ts_all
>>>>>>> +Date:        September 2023
>>>>>>> +KernelVersion    6.7
>>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>>> Zhang (QUIC) <[email protected]>
>>>>>>> +Description:
>>>>>>> +        (RW) Read or write the status of timestamp upon all
>>>>>>> interface.
>>>>>>> +        Only value 0 and 1  can be written to this node. Set
>>>>>>> this node to 1 to requeset
>>>>>>> +        timestamp to all trace packet.
>>>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>>>> +        0 : Disable the timestamp of all trace packets.
>>>>>>> +        1 : Enable the timestamp of all trace packets.
>>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>> index 894d4309f1c7..f6cda5616e84 100644
>>>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>> @@ -331,6 +331,36 @@ static void tpdm_enable_dsb(struct
>>>>>>> tpdm_drvdata *drvdata)
>>>>>>>       writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
>>>>>>>   }
>>>>>>>   +static void set_cmb_tier(struct tpdm_drvdata *drvdata)
>>>>>>> +{
>>>>>>> +    u32 val;
>>>>>>> +
>>>>>>> +    val = readl_relaxed(drvdata->base + TPDM_CMB_TIER);
>>>>>>> +
>>>>>>> +    /* Clear all relevant fields */
>>>>>>> +    val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL |
>>>>>>> +         TPDM_CMB_TIER_XTRIG_TSENAB);
>>>>>>> +
>>>>>>> +    /* Set pattern timestamp type and enablement */
>>>>>>> +    if (drvdata->cmb->patt_ts)
>>>>>>> +        val |= TPDM_CMB_TIER_PATT_TSENAB;
>>>>>>
>>>>>>  -- cut --
>>>>>>> +    else
>>>>>>> +        val &= ~TPDM_CMB_TIER_PATT_TSENAB;
>>>>>>
>>>>>>
>>>>>> All the else cases in this function are superfluous. Please remove
>>>>>> all
>>>>>> of them.
>>>>> I will update this in the next patch.
>>>>>>
>>>>>>> +
>>>>>>> +    /* Set trigger timestamp */
>>>>>>> +    if (drvdata->cmb->trig_ts)
>>>>>>> +        val |= TPDM_CMB_TIER_XTRIG_TSENAB;
>>>>>>> +    else
>>>>>>> +        val &= ~TPDM_CMB_TIER_XTRIG_TSENAB;
>>>>>>> +
>>>>>>> +    /* Set all timestamp enablement*/
>>>>>>> +    if (drvdata->cmb->ts_all)
>>>>>>> +        val |= TPDM_CMB_TIER_TS_ALL;
>>>>>>> +    else
>>>>>>> +        val &= ~TPDM_CMB_TIER_TS_ALL;
>>>>>>> +    writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
>>>>>>> +}
>>>>>>> +
>>>>>>>   static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
>>>>>>>   {
>>>>>>>       u32 val, i;
>>>>>>> @@ -347,6 +377,8 @@ static void tpdm_enable_cmb(struct
>>>>>>> tpdm_drvdata *drvdata)
>>>>>>>                   drvdata->base + TPDM_CMB_XPMR(i));
>>>>>>>       }
>>>>>>>   +    set_cmb_tier(drvdata);
>>>>>>> +
>>>>>>>       val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
>>>>>>>       /*
>>>>>>>        * Set to 0 for continuous CMB collection mode,
>>>>>>> @@ -695,9 +727,17 @@ static ssize_t enable_ts_show(struct device
>>>>>>> *dev,
>>>>>>>                     char *buf)
>>>>>>>   {
>>>>>>>       struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>>>>> +    ssize_t size = 0;
>>>>>>>   -    return sysfs_emit(buf, "%u\n",
>>>>>>> -             (unsigned int)drvdata->dsb->patt_ts);
>>>>>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>>>>>> +        size = sysfs_emit(buf, "%u\n",
>>>>>>> +                 (unsigned int)drvdata->dsb->patt_ts);
>>>>>>> +
>>>>>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>>>>>> +        size = sysfs_emit(buf, "%u\n",
>>>>>>> +                 (unsigned int)drvdata->cmb->patt_ts);
>>>>>>
>>>>>> Why does this need to show two values ? This must only show ONE
>>>>>> value.
>>>>>> How you deduce that might be based on the availability of the feature
>>>>>> set. Or store the TS value in the drvdata and use that instead for
>>>>>> controlling CMB/DSB.
>>>>>
>>>>> Since both of CMB/DSB need to have "enable_ts" SysFs file, can I
>>>>> separate them
>>>>
>>>> The question really is, do we need fine grained control. i.e.,
>>>>
>>>> enable TS for DSB but not for CMB or vice versa.
>>>>
>>>> I am not an expert on the usage scenario of the same. So, if you/Qcomm
>>>> thinks the users need separate, fine grained control for timestamp
>>>> for the DSB and CMB, then yes, follow your recommendation below.
>>>> i.e., tpdm.../dsb_patt/enable_ts
>>>>
>>>>> as "enable_dsb_ts" and "enable_cmb_ts"? The path will be like below.
>>>>>
>>>>> tpdm0/dsb_patt/enable_dsb_ts
>>>>
>>>> You don't need enable_dsb_ts. It could be "enable_ts"
>>>>
>>>>>
>>>>> tpdm1/cmb_patt/enable_cmb_ts
>>>>>
>>>>> Is this design appropriate?
>>>>
>>>>
>>>> Otherwise, stick to single enable_ts : which enables the ts for both
>>>> CMB/DSB. And it only ever show one value : 0 (TS is disabled for both
>>>> CMB/DSB) 1 : TS enabled for both.
>>>
>>> We have a very special case, such as the TPDM supporting both CMB and
>>>
>>> DSB datasets. Although this case is very rare, it still exists.
>>>
>>> Can I use the data bit to instruct whether timestamp is enabled for
>>> CMB/DSB or not? For example,
>>>
>>> size = sysfs_emit(buf, "%u\n",
>>>                  (unsigned int)(drvdata->dsb->patt_ts << 1 |
>>> drvdata->cmb->patt_ts));
>>>
>>> Thus, this value can instruct the following situations.
>>>
>>> 0 - TS is disabled for both CMB/DSB
>>>
>>> 1 - TS is enabled for CMB
>>>
>>> 2 - TS is enabled for DSB
>>>
>>> 3 - TS is enabled for both
>>>
>>> Is this approach acceptable?
>>>
>>
>> No, please stick to separate controls for TS. Do not complicate
>> the user interface.
>>
>> i.e.,
>> tpdm0/dsb_patt/enable_ts
>> tpdm0/cmb_patt/enable_ts
>
> We need to be able to control/show dsb and cmb timestamp enablement
> independently.
>
> Can we achieve this requirement if we use a sysfs file with the same name?

They are independent and in their respective directory (group) for CMB
and DSB. What am I missing ?
e.g., if you want to enable TS for DSB, you do :

$ echo 1 > dsb_patt/enable_ts

And that only works for DSB not for CMB.

Suzuki

>
> I'm not able to find a good way to achieve it. Do you have any
> suggestions for this?
>


>
> Best,
>
> Tao
>
>>
>> Suzuki
>>
>>
>>>
>>> Best,
>>>
>>> Tao
>>>
>>>>
>>>> Suzuki
>>>>
>>>>
>>>>>>
>>>>
>>>>>> Also, the sysfs documentation needs update, if this is going to
>>>>>> control the CMB.
>>>>>
>>>>> Sure. I will update the SysFs documentation according to the
>>>>> modification in the
>>>>>
>>>>> next patch series.
>>>>>
>>>>>
>>>>> Best,
>>>>>
>>>>> Tao
>>>>>
>>>>>>
>>>>>> Suzuki
>>>>>>
>>>>>>
>>>>>>> +
>>>>>>> +    return size;
>>>>>>>   }
>>>>>>>     /*
>>>>>>> @@ -715,8 +755,13 @@ static ssize_t enable_ts_store(struct device
>>>>>>> *dev,
>>>>>>>           return -EINVAL;
>>>>>>>         spin_lock(&drvdata->spinlock);
>>>>>>> -    drvdata->dsb->patt_ts = !!val;
>>>>>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>>>>>> +        drvdata->dsb->patt_ts = !!val;
>>>>>>> +
>>>>>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>>>>>> +        drvdata->cmb->patt_ts = !!val;
>>>>>>>       spin_unlock(&drvdata->spinlock);
>>>>>>> +
>>>>>>>       return size;
>>>>>>>   }
>>>>>>>   static DEVICE_ATTR_RW(enable_ts);
>>>>>>> @@ -851,6 +896,68 @@ static ssize_t cmb_mode_store(struct device
>>>>>>> *dev,
>>>>>>>   }
>>>>>>>   static DEVICE_ATTR_RW(cmb_mode);
>>>>>>>   +static ssize_t cmb_ts_all_show(struct device *dev,
>>>>>>> +                   struct device_attribute *attr,
>>>>>>> +                   char *buf)
>>>>>>> +{
>>>>>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>>>>> +
>>>>>>> +    return sysfs_emit(buf, "%u\n",
>>>>>>> +              (unsigned int)drvdata->cmb->ts_all);
>>>>>>> +}
>>>>>>> +
>>>>>>> +static ssize_t cmb_ts_all_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 val;
>>>>>>> +
>>>>>>> +    if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
>>>>>>> +        return -EINVAL;
>>>>>>> +
>>>>>>> +    spin_lock(&drvdata->spinlock);
>>>>>>> +    if (val)
>>>>>>> +        drvdata->cmb->ts_all = true;
>>>>>>> +    else
>>>>>>> +        drvdata->cmb->ts_all = false;
>>>>>>> +    spin_unlock(&drvdata->spinlock);
>>>>>>> +    return size;
>>>>>>> +}
>>>>>>> +static DEVICE_ATTR_RW(cmb_ts_all);
>>>>>>> +
>>>>>>> +static ssize_t cmb_trig_ts_show(struct device *dev,
>>>>>>> +                struct device_attribute *attr,
>>>>>>> +                char *buf)
>>>>>>> +{
>>>>>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>>>>> +
>>>>>>> +    return sysfs_emit(buf, "%u\n",
>>>>>>> +              (unsigned int)drvdata->cmb->trig_ts);
>>>>>>> +}
>>>>>>> +
>>>>>>> +static ssize_t cmb_trig_ts_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 val;
>>>>>>> +
>>>>>>> +    if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
>>>>>>> +        return -EINVAL;
>>>>>>> +
>>>>>>> +    spin_lock(&drvdata->spinlock);
>>>>>>> +    if (val)
>>>>>>> +        drvdata->cmb->trig_ts = true;
>>>>>>> +    else
>>>>>>> +        drvdata->cmb->trig_ts = false;
>>>>>>> +    spin_unlock(&drvdata->spinlock);
>>>>>>> +    return size;
>>>>>>> +}
>>>>>>> +static DEVICE_ATTR_RW(cmb_trig_ts);
>>>>>>> +
>>>>>>>   static struct attribute *tpdm_dsb_edge_attrs[] = {
>>>>>>>       &dev_attr_ctrl_idx.attr,
>>>>>>>       &dev_attr_ctrl_val.attr,
>>>>>>> @@ -973,6 +1080,7 @@ static struct attribute
>>>>>>> *tpdm_cmb_patt_attrs[] = {
>>>>>>>       CMB_PATT_ATTR(1),
>>>>>>>       CMB_PATT_MASK_ATTR(0),
>>>>>>>       CMB_PATT_MASK_ATTR(1),
>>>>>>> +    &dev_attr_enable_ts.attr,
>>>>>>>       NULL,
>>>>>>>   };
>>>>>>>   @@ -985,6 +1093,8 @@ static struct attribute *tpdm_dsb_attrs[] = {
>>>>>>>     static struct attribute *tpdm_cmb_attrs[] = {
>>>>>>>       &dev_attr_cmb_mode.attr,
>>>>>>> +    &dev_attr_cmb_ts_all.attr,
>>>>>>> +    &dev_attr_cmb_trig_ts.attr,
>>>>>>>       NULL,
>>>>>>>   };
>>>>>>>   diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>>> index e90d008c1cb2..65b7ca6c4077 100644
>>>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>>> @@ -11,6 +11,8 @@
>>>>>>>     /* CMB Subunit Registers */
>>>>>>>   #define TPDM_CMB_CR        (0xA00)
>>>>>>> +/*CMB subunit timestamp insertion enable register*/
>>>>>>> +#define TPDM_CMB_TIER        (0xA04)
>>>>>>>   /*CMB subunit timestamp pattern registers*/
>>>>>>>   #define TPDM_CMB_TPR(n)        (0xA08 + (n * 4))
>>>>>>>   /*CMB subunit timestamp pattern mask registers*/
>>>>>>> @@ -24,6 +26,12 @@
>>>>>>>   #define TPDM_CMB_CR_ENA        BIT(0)
>>>>>>>   /* Trace collection mode for CMB subunit */
>>>>>>>   #define TPDM_CMB_CR_MODE    BIT(1)
>>>>>>> +/* Timestamp control for pattern match */
>>>>>>> +#define TPDM_CMB_TIER_PATT_TSENAB    BIT(0)
>>>>>>> +/* CMB CTI timestamp request */
>>>>>>> +#define TPDM_CMB_TIER_XTRIG_TSENAB    BIT(1)
>>>>>>> +/* For timestamp fo all trace */
>>>>>>> +#define TPDM_CMB_TIER_TS_ALL        BIT(2)
>>>>>>>     /*Patten register number*/
>>>>>>>   #define TPDM_CMB_MAX_PATT        2
>>>>>>> @@ -217,6 +225,9 @@ struct dsb_dataset {
>>>>>>>    * @patt_mask:        Save value for pattern mask
>>>>>>>    * @trig_patt:        Save value for trigger pattern
>>>>>>>    * @trig_patt_mask:   Save value for trigger pattern mask
>>>>>>> + * @patt_ts:          Indicates if pattern match for timestamp
>>>>>>> is enabled.
>>>>>>> + * @trig_ts:          Indicates if CTI trigger for timestamp is
>>>>>>> enabled.
>>>>>>> + * @ts_all:           Indicates if timestamp is enabled for all
>>>>>>> packets.
>>>>>>>    */
>>>>>>>   struct cmb_dataset {
>>>>>>>       u32            trace_mode;
>>>>>>> @@ -224,6 +235,9 @@ struct cmb_dataset {
>>>>>>>       u32            patt_mask[TPDM_CMB_MAX_PATT];
>>>>>>>       u32            trig_patt[TPDM_CMB_MAX_PATT];
>>>>>>>       u32            trig_patt_mask[TPDM_CMB_MAX_PATT];
>>>>>>> +    bool            patt_ts;
>>>>>>> +    bool            trig_ts;
>>>>>>> +    bool            ts_all;
>>>>>>>   };
>>>>>>>     /**
>>>>>>
>>>>
>>>> _______________________________________________
>>>> CoreSight mailing list -- [email protected]
>>>> To unsubscribe send an email to [email protected]
>>
>> _______________________________________________
>> CoreSight mailing list -- [email protected]
>> To unsubscribe send an email to [email protected]


2024-01-05 07:50:26

by Tao Zhang

[permalink] [raw]
Subject: Re: [PATCH v3 6/8] coresight-tpdm: Add timestamp control register support for the CMB


On 12/30/2023 5:39 PM, Suzuki K Poulose wrote:
> On 25/12/2023 01:55, Tao Zhang wrote:
>>
>> On 12/20/2023 7:07 PM, Suzuki K Poulose wrote:
>>> On 20/12/2023 09:51, Tao Zhang wrote:
>>>>
>>>> On 12/19/2023 9:51 PM, Suzuki K Poulose wrote:
>>>>> On 19/12/2023 02:43, Tao Zhang wrote:
>>>>>>
>>>>>> On 12/18/2023 6:46 PM, Suzuki K Poulose wrote:
>>>>>>> On 21/11/2023 02:24, Tao Zhang wrote:
>>>>>>>> CMB_TIER register is CMB subunit timestamp insertion enable
>>>>>>>> register.
>>>>>>>> Bit 0 is PATT_TSENAB bit. Set this bit to 1 to request a timestamp
>>>>>>>> following a CMB interface pattern match. Bit 1 is XTRIG_TSENAB
>>>>>>>> bit.
>>>>>>>> Set this bit to 1 to request a timestamp following a CMB CTI
>>>>>>>> timestamp
>>>>>>>> request. Bit 2 is TS_ALL bit. Set this bit to 1 to request
>>>>>>>> timestamp
>>>>>>>> for all packets.
>>>>>>>>
>>>>>>>> Reviewed-by: James Clark <[email protected]>
>>>>>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>>>>>> Signed-off-by: Jinlong Mao <[email protected]>
>>>>>>>> ---
>>>>>>>>   .../testing/sysfs-bus-coresight-devices-tpdm  | 35 ++++++
>>>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 116
>>>>>>>> +++++++++++++++++-
>>>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.h  | 14 +++
>>>>>>>>   3 files changed, 162 insertions(+), 3 deletions(-)
>>>>>>>>
>>>>>>>> diff --git
>>>>>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>> index 53662ce7c2d0..e0b77107be13 100644
>>>>>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>> @@ -214,3 +214,38 @@ KernelVersion    6.7
>>>>>>>>   Contact:    Jinlong Mao (QUIC) <[email protected]>,
>>>>>>>> Tao Zhang (QUIC) <[email protected]>
>>>>>>>>   Description:
>>>>>>>>           (RW) Set/Get the mask of the pattern for the CMB
>>>>>>>> subunit TPDM.
>>>>>>>> +
>>>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_patt/enable_ts
>>>>>>>> +Date:        September 2023
>>>>>>>> +KernelVersion    6.7
>>>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>>>> Zhang (QUIC) <[email protected]>
>>>>>>>> +Description:
>>>>>>>> +        (Write) Set the pattern timestamp of CMB tpdm. Read
>>>>>>>> +        the pattern timestamp of CMB tpdm.
>>>>>>>> +
>>>>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>>>>> +        0 : Disable CMB pattern timestamp.
>>>>>>>> +        1 : Enable CMB pattern timestamp.
>>>>>>>> +
>>>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_ts
>>>>>>>> +Date:        September 2023
>>>>>>>> +KernelVersion    6.7
>>>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>>>> Zhang (QUIC) <[email protected]>
>>>>>>>> +Description:
>>>>>>>> +        (RW) Set/Get the trigger timestamp of the CMB for tpdm.
>>>>>>>> +
>>>>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>>>>> +        0 : Set the CMB trigger type to false
>>>>>>>> +        1 : Set the CMB trigger type to true
>>>>>>>> +
>>>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_ts_all
>>>>>>>> +Date:        September 2023
>>>>>>>> +KernelVersion    6.7
>>>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>>>> Zhang (QUIC) <[email protected]>
>>>>>>>> +Description:
>>>>>>>> +        (RW) Read or write the status of timestamp upon all
>>>>>>>> interface.
>>>>>>>> +        Only value 0 and 1  can be written to this node. Set
>>>>>>>> this node to 1 to requeset
>>>>>>>> +        timestamp to all trace packet.
>>>>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>>>>> +        0 : Disable the timestamp of all trace packets.
>>>>>>>> +        1 : Enable the timestamp of all trace packets.
>>>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>> index 894d4309f1c7..f6cda5616e84 100644
>>>>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>> @@ -331,6 +331,36 @@ static void tpdm_enable_dsb(struct
>>>>>>>> tpdm_drvdata *drvdata)
>>>>>>>>       writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
>>>>>>>>   }
>>>>>>>>   +static void set_cmb_tier(struct tpdm_drvdata *drvdata)
>>>>>>>> +{
>>>>>>>> +    u32 val;
>>>>>>>> +
>>>>>>>> +    val = readl_relaxed(drvdata->base + TPDM_CMB_TIER);
>>>>>>>> +
>>>>>>>> +    /* Clear all relevant fields */
>>>>>>>> +    val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL |
>>>>>>>> +         TPDM_CMB_TIER_XTRIG_TSENAB);
>>>>>>>> +
>>>>>>>> +    /* Set pattern timestamp type and enablement */
>>>>>>>> +    if (drvdata->cmb->patt_ts)
>>>>>>>> +        val |= TPDM_CMB_TIER_PATT_TSENAB;
>>>>>>>
>>>>>>>  -- cut --
>>>>>>>> +    else
>>>>>>>> +        val &= ~TPDM_CMB_TIER_PATT_TSENAB;
>>>>>>>
>>>>>>>
>>>>>>> All the else cases in this function are superfluous. Please
>>>>>>> remove all
>>>>>>> of them.
>>>>>> I will update this in the next patch.
>>>>>>>
>>>>>>>> +
>>>>>>>> +    /* Set trigger timestamp */
>>>>>>>> +    if (drvdata->cmb->trig_ts)
>>>>>>>> +        val |= TPDM_CMB_TIER_XTRIG_TSENAB;
>>>>>>>> +    else
>>>>>>>> +        val &= ~TPDM_CMB_TIER_XTRIG_TSENAB;
>>>>>>>> +
>>>>>>>> +    /* Set all timestamp enablement*/
>>>>>>>> +    if (drvdata->cmb->ts_all)
>>>>>>>> +        val |= TPDM_CMB_TIER_TS_ALL;
>>>>>>>> +    else
>>>>>>>> +        val &= ~TPDM_CMB_TIER_TS_ALL;
>>>>>>>> +    writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
>>>>>>>> +}
>>>>>>>> +
>>>>>>>>   static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
>>>>>>>>   {
>>>>>>>>       u32 val, i;
>>>>>>>> @@ -347,6 +377,8 @@ static void tpdm_enable_cmb(struct
>>>>>>>> tpdm_drvdata *drvdata)
>>>>>>>>                   drvdata->base + TPDM_CMB_XPMR(i));
>>>>>>>>       }
>>>>>>>>   +    set_cmb_tier(drvdata);
>>>>>>>> +
>>>>>>>>       val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
>>>>>>>>       /*
>>>>>>>>        * Set to 0 for continuous CMB collection mode,
>>>>>>>> @@ -695,9 +727,17 @@ static ssize_t enable_ts_show(struct
>>>>>>>> device *dev,
>>>>>>>>                     char *buf)
>>>>>>>>   {
>>>>>>>>       struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>>>>>> +    ssize_t size = 0;
>>>>>>>>   -    return sysfs_emit(buf, "%u\n",
>>>>>>>> -             (unsigned int)drvdata->dsb->patt_ts);
>>>>>>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>>>>>>> +        size = sysfs_emit(buf, "%u\n",
>>>>>>>> +                 (unsigned int)drvdata->dsb->patt_ts);
>>>>>>>> +
>>>>>>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>>>>>>> +        size = sysfs_emit(buf, "%u\n",
>>>>>>>> +                 (unsigned int)drvdata->cmb->patt_ts);
>>>>>>>
>>>>>>> Why does this need to show two values ? This must only show ONE
>>>>>>> value.
>>>>>>> How you deduce that might be based on the availability of the
>>>>>>> feature
>>>>>>> set. Or store the TS value in the drvdata and use that instead for
>>>>>>> controlling CMB/DSB.
>>>>>>
>>>>>> Since both of CMB/DSB need to have "enable_ts" SysFs file, can I
>>>>>> separate them
>>>>>
>>>>> The question really is, do we need fine grained control. i.e.,
>>>>>
>>>>> enable TS for DSB but not for CMB or vice versa.
>>>>>
>>>>> I am not an expert on the usage scenario of the same. So, if
>>>>> you/Qcomm
>>>>> thinks the users need separate, fine grained control for timestamp
>>>>> for the DSB and CMB, then yes, follow your recommendation below.
>>>>> i.e., tpdm.../dsb_patt/enable_ts
>>>>>
>>>>>> as "enable_dsb_ts" and "enable_cmb_ts"? The path will be like below.
>>>>>>
>>>>>> tpdm0/dsb_patt/enable_dsb_ts
>>>>>
>>>>> You don't need enable_dsb_ts. It could be "enable_ts"
>>>>>
>>>>>>
>>>>>> tpdm1/cmb_patt/enable_cmb_ts
>>>>>>
>>>>>> Is this design appropriate?
>>>>>
>>>>>
>>>>> Otherwise, stick to single enable_ts : which enables the ts for both
>>>>> CMB/DSB. And it only ever show one value : 0 (TS is disabled for both
>>>>> CMB/DSB) 1 : TS enabled for both.
>>>>
>>>> We have a very special case, such as the TPDM supporting both CMB and
>>>>
>>>> DSB datasets. Although this case is very rare, it still exists.
>>>>
>>>> Can I use the data bit to instruct whether timestamp is enabled for
>>>> CMB/DSB or not? For example,
>>>>
>>>> size = sysfs_emit(buf, "%u\n",
>>>>                  (unsigned int)(drvdata->dsb->patt_ts << 1 |
>>>> drvdata->cmb->patt_ts));
>>>>
>>>> Thus, this value can instruct the following situations.
>>>>
>>>> 0 - TS is disabled for both CMB/DSB
>>>>
>>>> 1 - TS is enabled for CMB
>>>>
>>>> 2 - TS is enabled for DSB
>>>>
>>>> 3 - TS is enabled for both
>>>>
>>>> Is this approach acceptable?
>>>>
>>>
>>> No, please stick to separate controls for TS. Do not complicate
>>> the user interface.
>>>
>>> i.e.,
>>> tpdm0/dsb_patt/enable_ts
>>> tpdm0/cmb_patt/enable_ts
>>
>> We need to be able to control/show dsb and cmb timestamp enablement
>> independently.
>>
>> Can we achieve this requirement if we use a sysfs file with the same
>> name?
>
> They are independent and in their respective directory (group) for CMB
> and DSB. What am I missing ?
> e.g., if you want to enable TS for DSB, you do :
>
> $ echo 1 > dsb_patt/enable_ts
>
> And that only works for DSB not for CMB.

We have a special case that the TPDM supports both DSB and CMB dataset.
In this special case, when we

issue this command to enable timestamp, it will call enable_ts_store
API, right?

    if (tpdm_has_dsb_dataset(drvdata))
        drvdata->dsb->patt_ts = !!val;

    if (tpdm_has_cmb_dataset(drvdata))
        drvdata->cmb->patt_ts = !!val;

Since this special TPDM supports both DSB and CMB dataset, both DSB
patt_ts and CMB patt_ts will be set

in this case even if I only configure the file in the DSB directory, right?

This is the problem we have now.


Best,

Tao

>
> Suzuki
>
>>
>> I'm not able to find a good way to achieve it. Do you have any
>> suggestions for this?
>>
>
>
>>
>> Best,
>>
>> Tao
>>
>>>
>>> Suzuki
>>>
>>>
>>>>
>>>> Best,
>>>>
>>>> Tao
>>>>
>>>>>
>>>>> Suzuki
>>>>>
>>>>>
>>>>>>>
>>>>>
>>>>>>> Also, the sysfs documentation needs update, if this is going to
>>>>>>> control the CMB.
>>>>>>
>>>>>> Sure. I will update the SysFs documentation according to the
>>>>>> modification in the
>>>>>>
>>>>>> next patch series.
>>>>>>
>>>>>>
>>>>>> Best,
>>>>>>
>>>>>> Tao
>>>>>>
>>>>>>>
>>>>>>> Suzuki
>>>>>>>
>>>>>>>
>>>>>>>> +
>>>>>>>> +    return size;
>>>>>>>>   }
>>>>>>>>     /*
>>>>>>>> @@ -715,8 +755,13 @@ static ssize_t enable_ts_store(struct
>>>>>>>> device *dev,
>>>>>>>>           return -EINVAL;
>>>>>>>>         spin_lock(&drvdata->spinlock);
>>>>>>>> -    drvdata->dsb->patt_ts = !!val;
>>>>>>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>>>>>>> +        drvdata->dsb->patt_ts = !!val;
>>>>>>>> +
>>>>>>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>>>>>>> +        drvdata->cmb->patt_ts = !!val;
>>>>>>>>       spin_unlock(&drvdata->spinlock);
>>>>>>>> +
>>>>>>>>       return size;
>>>>>>>>   }
>>>>>>>>   static DEVICE_ATTR_RW(enable_ts);
>>>>>>>> @@ -851,6 +896,68 @@ static ssize_t cmb_mode_store(struct
>>>>>>>> device *dev,
>>>>>>>>   }
>>>>>>>>   static DEVICE_ATTR_RW(cmb_mode);
>>>>>>>>   +static ssize_t cmb_ts_all_show(struct device *dev,
>>>>>>>> +                   struct device_attribute *attr,
>>>>>>>> +                   char *buf)
>>>>>>>> +{
>>>>>>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>>>>>> +
>>>>>>>> +    return sysfs_emit(buf, "%u\n",
>>>>>>>> +              (unsigned int)drvdata->cmb->ts_all);
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +static ssize_t cmb_ts_all_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 val;
>>>>>>>> +
>>>>>>>> +    if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
>>>>>>>> +        return -EINVAL;
>>>>>>>> +
>>>>>>>> +    spin_lock(&drvdata->spinlock);
>>>>>>>> +    if (val)
>>>>>>>> +        drvdata->cmb->ts_all = true;
>>>>>>>> +    else
>>>>>>>> +        drvdata->cmb->ts_all = false;
>>>>>>>> +    spin_unlock(&drvdata->spinlock);
>>>>>>>> +    return size;
>>>>>>>> +}
>>>>>>>> +static DEVICE_ATTR_RW(cmb_ts_all);
>>>>>>>> +
>>>>>>>> +static ssize_t cmb_trig_ts_show(struct device *dev,
>>>>>>>> +                struct device_attribute *attr,
>>>>>>>> +                char *buf)
>>>>>>>> +{
>>>>>>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>>>>>> +
>>>>>>>> +    return sysfs_emit(buf, "%u\n",
>>>>>>>> +              (unsigned int)drvdata->cmb->trig_ts);
>>>>>>>> +}
>>>>>>>> +
>>>>>>>> +static ssize_t cmb_trig_ts_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 val;
>>>>>>>> +
>>>>>>>> +    if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
>>>>>>>> +        return -EINVAL;
>>>>>>>> +
>>>>>>>> +    spin_lock(&drvdata->spinlock);
>>>>>>>> +    if (val)
>>>>>>>> +        drvdata->cmb->trig_ts = true;
>>>>>>>> +    else
>>>>>>>> +        drvdata->cmb->trig_ts = false;
>>>>>>>> +    spin_unlock(&drvdata->spinlock);
>>>>>>>> +    return size;
>>>>>>>> +}
>>>>>>>> +static DEVICE_ATTR_RW(cmb_trig_ts);
>>>>>>>> +
>>>>>>>>   static struct attribute *tpdm_dsb_edge_attrs[] = {
>>>>>>>>       &dev_attr_ctrl_idx.attr,
>>>>>>>>       &dev_attr_ctrl_val.attr,
>>>>>>>> @@ -973,6 +1080,7 @@ static struct attribute
>>>>>>>> *tpdm_cmb_patt_attrs[] = {
>>>>>>>>       CMB_PATT_ATTR(1),
>>>>>>>>       CMB_PATT_MASK_ATTR(0),
>>>>>>>>       CMB_PATT_MASK_ATTR(1),
>>>>>>>> +    &dev_attr_enable_ts.attr,
>>>>>>>>       NULL,
>>>>>>>>   };
>>>>>>>>   @@ -985,6 +1093,8 @@ static struct attribute
>>>>>>>> *tpdm_dsb_attrs[] = {
>>>>>>>>     static struct attribute *tpdm_cmb_attrs[] = {
>>>>>>>>       &dev_attr_cmb_mode.attr,
>>>>>>>> +    &dev_attr_cmb_ts_all.attr,
>>>>>>>> +    &dev_attr_cmb_trig_ts.attr,
>>>>>>>>       NULL,
>>>>>>>>   };
>>>>>>>>   diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>>>> index e90d008c1cb2..65b7ca6c4077 100644
>>>>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>>>> @@ -11,6 +11,8 @@
>>>>>>>>     /* CMB Subunit Registers */
>>>>>>>>   #define TPDM_CMB_CR        (0xA00)
>>>>>>>> +/*CMB subunit timestamp insertion enable register*/
>>>>>>>> +#define TPDM_CMB_TIER        (0xA04)
>>>>>>>>   /*CMB subunit timestamp pattern registers*/
>>>>>>>>   #define TPDM_CMB_TPR(n)        (0xA08 + (n * 4))
>>>>>>>>   /*CMB subunit timestamp pattern mask registers*/
>>>>>>>> @@ -24,6 +26,12 @@
>>>>>>>>   #define TPDM_CMB_CR_ENA        BIT(0)
>>>>>>>>   /* Trace collection mode for CMB subunit */
>>>>>>>>   #define TPDM_CMB_CR_MODE    BIT(1)
>>>>>>>> +/* Timestamp control for pattern match */
>>>>>>>> +#define TPDM_CMB_TIER_PATT_TSENAB    BIT(0)
>>>>>>>> +/* CMB CTI timestamp request */
>>>>>>>> +#define TPDM_CMB_TIER_XTRIG_TSENAB    BIT(1)
>>>>>>>> +/* For timestamp fo all trace */
>>>>>>>> +#define TPDM_CMB_TIER_TS_ALL        BIT(2)
>>>>>>>>     /*Patten register number*/
>>>>>>>>   #define TPDM_CMB_MAX_PATT        2
>>>>>>>> @@ -217,6 +225,9 @@ struct dsb_dataset {
>>>>>>>>    * @patt_mask:        Save value for pattern mask
>>>>>>>>    * @trig_patt:        Save value for trigger pattern
>>>>>>>>    * @trig_patt_mask:   Save value for trigger pattern mask
>>>>>>>> + * @patt_ts:          Indicates if pattern match for timestamp
>>>>>>>> is enabled.
>>>>>>>> + * @trig_ts:          Indicates if CTI trigger for timestamp
>>>>>>>> is enabled.
>>>>>>>> + * @ts_all:           Indicates if timestamp is enabled for
>>>>>>>> all packets.
>>>>>>>>    */
>>>>>>>>   struct cmb_dataset {
>>>>>>>>       u32            trace_mode;
>>>>>>>> @@ -224,6 +235,9 @@ struct cmb_dataset {
>>>>>>>>       u32            patt_mask[TPDM_CMB_MAX_PATT];
>>>>>>>>       u32            trig_patt[TPDM_CMB_MAX_PATT];
>>>>>>>>       u32 trig_patt_mask[TPDM_CMB_MAX_PATT];
>>>>>>>> +    bool            patt_ts;
>>>>>>>> +    bool            trig_ts;
>>>>>>>> +    bool            ts_all;
>>>>>>>>   };
>>>>>>>>     /**
>>>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> CoreSight mailing list -- [email protected]
>>>>> To unsubscribe send an email to [email protected]
>>>
>>> _______________________________________________
>>> CoreSight mailing list -- [email protected]
>>> To unsubscribe send an email to [email protected]
>
> _______________________________________________
> CoreSight mailing list -- [email protected]
> To unsubscribe send an email to [email protected]

2024-01-08 10:43:05

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH v3 6/8] coresight-tpdm: Add timestamp control register support for the CMB

On 05/01/2024 07:49, Tao Zhang wrote:
>
> On 12/30/2023 5:39 PM, Suzuki K Poulose wrote:
>> On 25/12/2023 01:55, Tao Zhang wrote:
>>>
>>> On 12/20/2023 7:07 PM, Suzuki K Poulose wrote:
>>>> On 20/12/2023 09:51, Tao Zhang wrote:
>>>>>
>>>>> On 12/19/2023 9:51 PM, Suzuki K Poulose wrote:
>>>>>> On 19/12/2023 02:43, Tao Zhang wrote:
>>>>>>>
>>>>>>> On 12/18/2023 6:46 PM, Suzuki K Poulose wrote:
>>>>>>>> On 21/11/2023 02:24, Tao Zhang wrote:
>>>>>>>>> CMB_TIER register is CMB subunit timestamp insertion enable
>>>>>>>>> register.
>>>>>>>>> Bit 0 is PATT_TSENAB bit. Set this bit to 1 to request a timestamp
>>>>>>>>> following a CMB interface pattern match. Bit 1 is XTRIG_TSENAB
>>>>>>>>> bit.
>>>>>>>>> Set this bit to 1 to request a timestamp following a CMB CTI
>>>>>>>>> timestamp
>>>>>>>>> request. Bit 2 is TS_ALL bit. Set this bit to 1 to request
>>>>>>>>> timestamp
>>>>>>>>> for all packets.
>>>>>>>>>
>>>>>>>>> Reviewed-by: James Clark <[email protected]>
>>>>>>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>>>>>>> Signed-off-by: Jinlong Mao <[email protected]>
>>>>>>>>> ---
>>>>>>>>>   .../testing/sysfs-bus-coresight-devices-tpdm  | 35 ++++++
>>>>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 116
>>>>>>>>> +++++++++++++++++-
>>>>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.h  | 14 +++
>>>>>>>>>   3 files changed, 162 insertions(+), 3 deletions(-)
>>>>>>>>>
>>>>>>>>> diff --git
>>>>>>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>>> index 53662ce7c2d0..e0b77107be13 100644
>>>>>>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>>> @@ -214,3 +214,38 @@ KernelVersion    6.7
>>>>>>>>>   Contact:    Jinlong Mao (QUIC) <[email protected]>,
>>>>>>>>> Tao Zhang (QUIC) <[email protected]>
>>>>>>>>>   Description:
>>>>>>>>>           (RW) Set/Get the mask of the pattern for the CMB
>>>>>>>>> subunit TPDM.
>>>>>>>>> +
>>>>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_patt/enable_ts
>>>>>>>>> +Date:        September 2023
>>>>>>>>> +KernelVersion    6.7
>>>>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>>>>> Zhang (QUIC) <[email protected]>
>>>>>>>>> +Description:
>>>>>>>>> +        (Write) Set the pattern timestamp of CMB tpdm. Read
>>>>>>>>> +        the pattern timestamp of CMB tpdm.
>>>>>>>>> +
>>>>>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>>>>>> +        0 : Disable CMB pattern timestamp.
>>>>>>>>> +        1 : Enable CMB pattern timestamp.
>>>>>>>>> +
>>>>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_ts
>>>>>>>>> +Date:        September 2023
>>>>>>>>> +KernelVersion    6.7
>>>>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>>>>> Zhang (QUIC) <[email protected]>
>>>>>>>>> +Description:
>>>>>>>>> +        (RW) Set/Get the trigger timestamp of the CMB for tpdm.
>>>>>>>>> +
>>>>>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>>>>>> +        0 : Set the CMB trigger type to false
>>>>>>>>> +        1 : Set the CMB trigger type to true
>>>>>>>>> +
>>>>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_ts_all
>>>>>>>>> +Date:        September 2023
>>>>>>>>> +KernelVersion    6.7
>>>>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>>>>> Zhang (QUIC) <[email protected]>
>>>>>>>>> +Description:
>>>>>>>>> +        (RW) Read or write the status of timestamp upon all
>>>>>>>>> interface.
>>>>>>>>> +        Only value 0 and 1  can be written to this node. Set
>>>>>>>>> this node to 1 to requeset
>>>>>>>>> +        timestamp to all trace packet.
>>>>>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>>>>>> +        0 : Disable the timestamp of all trace packets.
>>>>>>>>> +        1 : Enable the timestamp of all trace packets.
>>>>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>>> index 894d4309f1c7..f6cda5616e84 100644
>>>>>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>>> @@ -331,6 +331,36 @@ static void tpdm_enable_dsb(struct
>>>>>>>>> tpdm_drvdata *drvdata)
>>>>>>>>>       writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
>>>>>>>>>   }
>>>>>>>>>   +static void set_cmb_tier(struct tpdm_drvdata *drvdata)
>>>>>>>>> +{
>>>>>>>>> +    u32 val;
>>>>>>>>> +
>>>>>>>>> +    val = readl_relaxed(drvdata->base + TPDM_CMB_TIER);
>>>>>>>>> +
>>>>>>>>> +    /* Clear all relevant fields */
>>>>>>>>> +    val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL |
>>>>>>>>> +         TPDM_CMB_TIER_XTRIG_TSENAB);
>>>>>>>>> +
>>>>>>>>> +    /* Set pattern timestamp type and enablement */
>>>>>>>>> +    if (drvdata->cmb->patt_ts)
>>>>>>>>> +        val |= TPDM_CMB_TIER_PATT_TSENAB;
>>>>>>>>
>>>>>>>>  -- cut --
>>>>>>>>> +    else
>>>>>>>>> +        val &= ~TPDM_CMB_TIER_PATT_TSENAB;
>>>>>>>>
>>>>>>>>
>>>>>>>> All the else cases in this function are superfluous. Please
>>>>>>>> remove all
>>>>>>>> of them.
>>>>>>> I will update this in the next patch.
>>>>>>>>
>>>>>>>>> +
>>>>>>>>> +    /* Set trigger timestamp */
>>>>>>>>> +    if (drvdata->cmb->trig_ts)
>>>>>>>>> +        val |= TPDM_CMB_TIER_XTRIG_TSENAB;
>>>>>>>>> +    else
>>>>>>>>> +        val &= ~TPDM_CMB_TIER_XTRIG_TSENAB;
>>>>>>>>> +
>>>>>>>>> +    /* Set all timestamp enablement*/
>>>>>>>>> +    if (drvdata->cmb->ts_all)
>>>>>>>>> +        val |= TPDM_CMB_TIER_TS_ALL;
>>>>>>>>> +    else
>>>>>>>>> +        val &= ~TPDM_CMB_TIER_TS_ALL;
>>>>>>>>> +    writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
>>>>>>>>> +}
>>>>>>>>> +
>>>>>>>>>   static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
>>>>>>>>>   {
>>>>>>>>>       u32 val, i;
>>>>>>>>> @@ -347,6 +377,8 @@ static void tpdm_enable_cmb(struct
>>>>>>>>> tpdm_drvdata *drvdata)
>>>>>>>>>                   drvdata->base + TPDM_CMB_XPMR(i));
>>>>>>>>>       }
>>>>>>>>>   +    set_cmb_tier(drvdata);
>>>>>>>>> +
>>>>>>>>>       val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
>>>>>>>>>       /*
>>>>>>>>>        * Set to 0 for continuous CMB collection mode,
>>>>>>>>> @@ -695,9 +727,17 @@ static ssize_t enable_ts_show(struct
>>>>>>>>> device *dev,
>>>>>>>>>                     char *buf)
>>>>>>>>>   {
>>>>>>>>>       struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>>>>>>> +    ssize_t size = 0;
>>>>>>>>>   -    return sysfs_emit(buf, "%u\n",
>>>>>>>>> -             (unsigned int)drvdata->dsb->patt_ts);
>>>>>>>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>>>>>>>> +        size = sysfs_emit(buf, "%u\n",
>>>>>>>>> +                 (unsigned int)drvdata->dsb->patt_ts);
>>>>>>>>> +
>>>>>>>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>>>>>>>> +        size = sysfs_emit(buf, "%u\n",
>>>>>>>>> +                 (unsigned int)drvdata->cmb->patt_ts);
>>>>>>>>
>>>>>>>> Why does this need to show two values ? This must only show ONE
>>>>>>>> value.
>>>>>>>> How you deduce that might be based on the availability of the
>>>>>>>> feature
>>>>>>>> set. Or store the TS value in the drvdata and use that instead for
>>>>>>>> controlling CMB/DSB.
>>>>>>>
>>>>>>> Since both of CMB/DSB need to have "enable_ts" SysFs file, can I
>>>>>>> separate them
>>>>>>
>>>>>> The question really is, do we need fine grained control. i.e.,
>>>>>>
>>>>>> enable TS for DSB but not for CMB or vice versa.
>>>>>>
>>>>>> I am not an expert on the usage scenario of the same. So, if
>>>>>> you/Qcomm
>>>>>> thinks the users need separate, fine grained control for timestamp
>>>>>> for the DSB and CMB, then yes, follow your recommendation below.
>>>>>> i.e., tpdm.../dsb_patt/enable_ts
>>>>>>
>>>>>>> as "enable_dsb_ts" and "enable_cmb_ts"? The path will be like below.
>>>>>>>
>>>>>>> tpdm0/dsb_patt/enable_dsb_ts
>>>>>>
>>>>>> You don't need enable_dsb_ts. It could be "enable_ts"
>>>>>>
>>>>>>>
>>>>>>> tpdm1/cmb_patt/enable_cmb_ts
>>>>>>>
>>>>>>> Is this design appropriate?
>>>>>>
>>>>>>
>>>>>> Otherwise, stick to single enable_ts : which enables the ts for both
>>>>>> CMB/DSB. And it only ever show one value : 0 (TS is disabled for both
>>>>>> CMB/DSB) 1 : TS enabled for both.
>>>>>
>>>>> We have a very special case, such as the TPDM supporting both CMB and
>>>>>
>>>>> DSB datasets. Although this case is very rare, it still exists.
>>>>>
>>>>> Can I use the data bit to instruct whether timestamp is enabled for
>>>>> CMB/DSB or not? For example,
>>>>>
>>>>> size = sysfs_emit(buf, "%u\n",
>>>>>                  (unsigned int)(drvdata->dsb->patt_ts << 1 |
>>>>> drvdata->cmb->patt_ts));
>>>>>
>>>>> Thus, this value can instruct the following situations.
>>>>>
>>>>> 0 - TS is disabled for both CMB/DSB
>>>>>
>>>>> 1 - TS is enabled for CMB
>>>>>
>>>>> 2 - TS is enabled for DSB
>>>>>
>>>>> 3 - TS is enabled for both
>>>>>
>>>>> Is this approach acceptable?
>>>>>
>>>>
>>>> No, please stick to separate controls for TS. Do not complicate
>>>> the user interface.
>>>>
>>>> i.e.,
>>>> tpdm0/dsb_patt/enable_ts
>>>> tpdm0/cmb_patt/enable_ts
>>>
>>> We need to be able to control/show dsb and cmb timestamp enablement
>>> independently.
>>>
>>> Can we achieve this requirement if we use a sysfs file with the same
>>> name?
>>
>> They are independent and in their respective directory (group) for CMB
>> and DSB. What am I missing ?
>> e.g., if you want to enable TS for DSB, you do :
>>
>> $ echo 1 > dsb_patt/enable_ts
>>
>> And that only works for DSB not for CMB.
>
> We have a special case that the TPDM supports both DSB and CMB dataset.
> In this special case, when we
>
> issue this command to enable timestamp, it will call enable_ts_store
> API, right?
>
>     if (tpdm_has_dsb_dataset(drvdata))
>         drvdata->dsb->patt_ts = !!val;
>
>     if (tpdm_has_cmb_dataset(drvdata))
>         drvdata->cmb->patt_ts = !!val;

I don't understand. If they both are under different subgroups, why
should they be conflicting ? Are you not able to distinguish them, when
you creat those attributes ? i.e., create two different "attributes" ?

See below.

> Since this special TPDM supports both DSB and CMB dataset, both DSB
> patt_ts and CMB patt_ts will be set
>
> in this case even if I only configure the file in the DSB directory, right?
>
> This is the problem we have now.
>


>>>>>>>>
>>>>>>>>
>>>>>>>>> +
>>>>>>>>> +    return size;
>>>>>>>>>   }
>>>>>>>>>     /*
>>>>>>>>> @@ -715,8 +755,13 @@ static ssize_t enable_ts_store(struct
>>>>>>>>> device *dev,
>>>>>>>>>           return -EINVAL;
>>>>>>>>>         spin_lock(&drvdata->spinlock);
>>>>>>>>> -    drvdata->dsb->patt_ts = !!val;
>>>>>>>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>>>>>>>> +        drvdata->dsb->patt_ts = !!val;
>>>>>>>>> +
>>>>>>>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>>>>>>>> +        drvdata->cmb->patt_ts = !!val;
>>>>>>>>>       spin_unlock(&drvdata->spinlock);
>>>>>>>>> +
>>>>>>>>>       return size;
>>>>>>>>>   }
>>>>>>>>>   static DEVICE_ATTR_RW(enable_ts);

Do not overload the same for both DSB and CMB. Create one for each in
DSB and CMB ? They could share the same show/store routines, but could
be done with additional variable to indicate which attribute they are
controlling. Like the other attributes, using dev_ext_attribute or such.


Suzuki


2024-01-12 02:43:55

by Tao Zhang

[permalink] [raw]
Subject: Re: [PATCH v3 6/8] coresight-tpdm: Add timestamp control register support for the CMB


On 1/8/2024 6:42 PM, Suzuki K Poulose wrote:
> On 05/01/2024 07:49, Tao Zhang wrote:
>>
>> On 12/30/2023 5:39 PM, Suzuki K Poulose wrote:
>>> On 25/12/2023 01:55, Tao Zhang wrote:
>>>>
>>>> On 12/20/2023 7:07 PM, Suzuki K Poulose wrote:
>>>>> On 20/12/2023 09:51, Tao Zhang wrote:
>>>>>>
>>>>>> On 12/19/2023 9:51 PM, Suzuki K Poulose wrote:
>>>>>>> On 19/12/2023 02:43, Tao Zhang wrote:
>>>>>>>>
>>>>>>>> On 12/18/2023 6:46 PM, Suzuki K Poulose wrote:
>>>>>>>>> On 21/11/2023 02:24, Tao Zhang wrote:
>>>>>>>>>> CMB_TIER register is CMB subunit timestamp insertion enable
>>>>>>>>>> register.
>>>>>>>>>> Bit 0 is PATT_TSENAB bit. Set this bit to 1 to request a
>>>>>>>>>> timestamp
>>>>>>>>>> following a CMB interface pattern match. Bit 1 is
>>>>>>>>>> XTRIG_TSENAB bit.
>>>>>>>>>> Set this bit to 1 to request a timestamp following a CMB CTI
>>>>>>>>>> timestamp
>>>>>>>>>> request. Bit 2 is TS_ALL bit. Set this bit to 1 to request
>>>>>>>>>> timestamp
>>>>>>>>>> for all packets.
>>>>>>>>>>
>>>>>>>>>> Reviewed-by: James Clark <[email protected]>
>>>>>>>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>>>>>>>> Signed-off-by: Jinlong Mao <[email protected]>
>>>>>>>>>> ---
>>>>>>>>>>   .../testing/sysfs-bus-coresight-devices-tpdm | 35 ++++++
>>>>>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.c | 116
>>>>>>>>>> +++++++++++++++++-
>>>>>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.h | 14 +++
>>>>>>>>>>   3 files changed, 162 insertions(+), 3 deletions(-)
>>>>>>>>>>
>>>>>>>>>> diff --git
>>>>>>>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>>>> index 53662ce7c2d0..e0b77107be13 100644
>>>>>>>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>>>> @@ -214,3 +214,38 @@ KernelVersion    6.7
>>>>>>>>>>   Contact:    Jinlong Mao (QUIC) <[email protected]>,
>>>>>>>>>> Tao Zhang (QUIC) <[email protected]>
>>>>>>>>>>   Description:
>>>>>>>>>>           (RW) Set/Get the mask of the pattern for the CMB
>>>>>>>>>> subunit TPDM.
>>>>>>>>>> +
>>>>>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_patt/enable_ts
>>>>>>>>>> +Date:        September 2023
>>>>>>>>>> +KernelVersion    6.7
>>>>>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>,
>>>>>>>>>> Tao Zhang (QUIC) <[email protected]>
>>>>>>>>>> +Description:
>>>>>>>>>> +        (Write) Set the pattern timestamp of CMB tpdm. Read
>>>>>>>>>> +        the pattern timestamp of CMB tpdm.
>>>>>>>>>> +
>>>>>>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>>>>>>> +        0 : Disable CMB pattern timestamp.
>>>>>>>>>> +        1 : Enable CMB pattern timestamp.
>>>>>>>>>> +
>>>>>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_trig_ts
>>>>>>>>>> +Date:        September 2023
>>>>>>>>>> +KernelVersion    6.7
>>>>>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>,
>>>>>>>>>> Tao Zhang (QUIC) <[email protected]>
>>>>>>>>>> +Description:
>>>>>>>>>> +        (RW) Set/Get the trigger timestamp of the CMB for tpdm.
>>>>>>>>>> +
>>>>>>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>>>>>>> +        0 : Set the CMB trigger type to false
>>>>>>>>>> +        1 : Set the CMB trigger type to true
>>>>>>>>>> +
>>>>>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_ts_all
>>>>>>>>>> +Date:        September 2023
>>>>>>>>>> +KernelVersion    6.7
>>>>>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>,
>>>>>>>>>> Tao Zhang (QUIC) <[email protected]>
>>>>>>>>>> +Description:
>>>>>>>>>> +        (RW) Read or write the status of timestamp upon all
>>>>>>>>>> interface.
>>>>>>>>>> +        Only value 0 and 1  can be written to this node. Set
>>>>>>>>>> this node to 1 to requeset
>>>>>>>>>> +        timestamp to all trace packet.
>>>>>>>>>> +        Accepts only one of the 2 values -  0 or 1.
>>>>>>>>>> +        0 : Disable the timestamp of all trace packets.
>>>>>>>>>> +        1 : Enable the timestamp of all trace packets.
>>>>>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>>>> index 894d4309f1c7..f6cda5616e84 100644
>>>>>>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>>>> @@ -331,6 +331,36 @@ static void tpdm_enable_dsb(struct
>>>>>>>>>> tpdm_drvdata *drvdata)
>>>>>>>>>>       writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
>>>>>>>>>>   }
>>>>>>>>>>   +static void set_cmb_tier(struct tpdm_drvdata *drvdata)
>>>>>>>>>> +{
>>>>>>>>>> +    u32 val;
>>>>>>>>>> +
>>>>>>>>>> +    val = readl_relaxed(drvdata->base + TPDM_CMB_TIER);
>>>>>>>>>> +
>>>>>>>>>> +    /* Clear all relevant fields */
>>>>>>>>>> +    val &= ~(TPDM_CMB_TIER_PATT_TSENAB | TPDM_CMB_TIER_TS_ALL |
>>>>>>>>>> +         TPDM_CMB_TIER_XTRIG_TSENAB);
>>>>>>>>>> +
>>>>>>>>>> +    /* Set pattern timestamp type and enablement */
>>>>>>>>>> +    if (drvdata->cmb->patt_ts)
>>>>>>>>>> +        val |= TPDM_CMB_TIER_PATT_TSENAB;
>>>>>>>>>
>>>>>>>>>  -- cut --
>>>>>>>>>> +    else
>>>>>>>>>> +        val &= ~TPDM_CMB_TIER_PATT_TSENAB;
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> All the else cases in this function are superfluous. Please
>>>>>>>>> remove all
>>>>>>>>> of them.
>>>>>>>> I will update this in the next patch.
>>>>>>>>>
>>>>>>>>>> +
>>>>>>>>>> +    /* Set trigger timestamp */
>>>>>>>>>> +    if (drvdata->cmb->trig_ts)
>>>>>>>>>> +        val |= TPDM_CMB_TIER_XTRIG_TSENAB;
>>>>>>>>>> +    else
>>>>>>>>>> +        val &= ~TPDM_CMB_TIER_XTRIG_TSENAB;
>>>>>>>>>> +
>>>>>>>>>> +    /* Set all timestamp enablement*/
>>>>>>>>>> +    if (drvdata->cmb->ts_all)
>>>>>>>>>> +        val |= TPDM_CMB_TIER_TS_ALL;
>>>>>>>>>> +    else
>>>>>>>>>> +        val &= ~TPDM_CMB_TIER_TS_ALL;
>>>>>>>>>> +    writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
>>>>>>>>>> +}
>>>>>>>>>> +
>>>>>>>>>>   static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
>>>>>>>>>>   {
>>>>>>>>>>       u32 val, i;
>>>>>>>>>> @@ -347,6 +377,8 @@ static void tpdm_enable_cmb(struct
>>>>>>>>>> tpdm_drvdata *drvdata)
>>>>>>>>>>                   drvdata->base + TPDM_CMB_XPMR(i));
>>>>>>>>>>       }
>>>>>>>>>>   +    set_cmb_tier(drvdata);
>>>>>>>>>> +
>>>>>>>>>>       val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
>>>>>>>>>>       /*
>>>>>>>>>>        * Set to 0 for continuous CMB collection mode,
>>>>>>>>>> @@ -695,9 +727,17 @@ static ssize_t enable_ts_show(struct
>>>>>>>>>> device *dev,
>>>>>>>>>>                     char *buf)
>>>>>>>>>>   {
>>>>>>>>>>       struct tpdm_drvdata *drvdata =
>>>>>>>>>> dev_get_drvdata(dev->parent);
>>>>>>>>>> +    ssize_t size = 0;
>>>>>>>>>>   -    return sysfs_emit(buf, "%u\n",
>>>>>>>>>> -             (unsigned int)drvdata->dsb->patt_ts);
>>>>>>>>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>>>>>>>>> +        size = sysfs_emit(buf, "%u\n",
>>>>>>>>>> +                 (unsigned int)drvdata->dsb->patt_ts);
>>>>>>>>>> +
>>>>>>>>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>>>>>>>>> +        size = sysfs_emit(buf, "%u\n",
>>>>>>>>>> +                 (unsigned int)drvdata->cmb->patt_ts);
>>>>>>>>>
>>>>>>>>> Why does this need to show two values ? This must only show
>>>>>>>>> ONE value.
>>>>>>>>> How you deduce that might be based on the availability of the
>>>>>>>>> feature
>>>>>>>>> set. Or store the TS value in the drvdata and use that instead
>>>>>>>>> for
>>>>>>>>> controlling CMB/DSB.
>>>>>>>>
>>>>>>>> Since both of CMB/DSB need to have "enable_ts" SysFs file, can
>>>>>>>> I separate them
>>>>>>>
>>>>>>> The question really is, do we need fine grained control. i.e.,
>>>>>>>
>>>>>>> enable TS for DSB but not for CMB or vice versa.
>>>>>>>
>>>>>>> I am not an expert on the usage scenario of the same. So, if
>>>>>>> you/Qcomm
>>>>>>> thinks the users need separate, fine grained control for timestamp
>>>>>>> for the DSB and CMB, then yes, follow your recommendation below.
>>>>>>> i.e., tpdm.../dsb_patt/enable_ts
>>>>>>>
>>>>>>>> as "enable_dsb_ts" and "enable_cmb_ts"? The path will be like
>>>>>>>> below.
>>>>>>>>
>>>>>>>> tpdm0/dsb_patt/enable_dsb_ts
>>>>>>>
>>>>>>> You don't need enable_dsb_ts. It could be "enable_ts"
>>>>>>>
>>>>>>>>
>>>>>>>> tpdm1/cmb_patt/enable_cmb_ts
>>>>>>>>
>>>>>>>> Is this design appropriate?
>>>>>>>
>>>>>>>
>>>>>>> Otherwise, stick to single enable_ts : which enables the ts for
>>>>>>> both
>>>>>>> CMB/DSB. And it only ever show one value : 0 (TS is disabled for
>>>>>>> both
>>>>>>> CMB/DSB) 1 : TS enabled for both.
>>>>>>
>>>>>> We have a very special case, such as the TPDM supporting both CMB
>>>>>> and
>>>>>>
>>>>>> DSB datasets. Although this case is very rare, it still exists.
>>>>>>
>>>>>> Can I use the data bit to instruct whether timestamp is enabled
>>>>>> for CMB/DSB or not? For example,
>>>>>>
>>>>>> size = sysfs_emit(buf, "%u\n",
>>>>>>                  (unsigned int)(drvdata->dsb->patt_ts << 1 |
>>>>>> drvdata->cmb->patt_ts));
>>>>>>
>>>>>> Thus, this value can instruct the following situations.
>>>>>>
>>>>>> 0 - TS is disabled for both CMB/DSB
>>>>>>
>>>>>> 1 - TS is enabled for CMB
>>>>>>
>>>>>> 2 - TS is enabled for DSB
>>>>>>
>>>>>> 3 - TS is enabled for both
>>>>>>
>>>>>> Is this approach acceptable?
>>>>>>
>>>>>
>>>>> No, please stick to separate controls for TS. Do not complicate
>>>>> the user interface.
>>>>>
>>>>> i.e.,
>>>>> tpdm0/dsb_patt/enable_ts
>>>>> tpdm0/cmb_patt/enable_ts
>>>>
>>>> We need to be able to control/show dsb and cmb timestamp enablement
>>>> independently.
>>>>
>>>> Can we achieve this requirement if we use a sysfs file with the
>>>> same name?
>>>
>>> They are independent and in their respective directory (group) for
>>> CMB and DSB. What am I missing ?
>>> e.g., if you want to enable TS for DSB, you do :
>>>
>>> $ echo 1 > dsb_patt/enable_ts
>>>
>>> And that only works for DSB not for CMB.
>>
>> We have a special case that the TPDM supports both DSB and CMB
>> dataset. In this special case, when we
>>
>> issue this command to enable timestamp, it will call enable_ts_store
>> API, right?
>>
>>      if (tpdm_has_dsb_dataset(drvdata))
>>          drvdata->dsb->patt_ts = !!val;
>>
>>      if (tpdm_has_cmb_dataset(drvdata))
>>          drvdata->cmb->patt_ts = !!val;
>
> I don't understand. If they both are under different subgroups, why
> should they be conflicting ? Are you not able to distinguish them, when
>  you creat those attributes ? i.e., create two different "attributes" ?

Yes, although some TPDMs can support both CMB dataset and DSB dataset,
we need to configure them separately

in some scenarios. Based on your suggestion, I want to use the following
approach to implement it.

See below.

>
> See below.
>
>> Since this special TPDM supports both DSB and CMB dataset, both DSB
>> patt_ts and CMB patt_ts will be set
>>
>> in this case even if I only configure the file in the DSB directory,
>> right?
>>
>> This is the problem we have now.
>>
>
>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>> +
>>>>>>>>>> +    return size;
>>>>>>>>>>   }
>>>>>>>>>>     /*
>>>>>>>>>> @@ -715,8 +755,13 @@ static ssize_t enable_ts_store(struct
>>>>>>>>>> device *dev,
>>>>>>>>>>           return -EINVAL;
>>>>>>>>>>         spin_lock(&drvdata->spinlock);
>>>>>>>>>> -    drvdata->dsb->patt_ts = !!val;
>>>>>>>>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>>>>>>>>> +        drvdata->dsb->patt_ts = !!val;
>>>>>>>>>> +
>>>>>>>>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>>>>>>>>> +        drvdata->cmb->patt_ts = !!val;
>>>>>>>>>>       spin_unlock(&drvdata->spinlock);
>>>>>>>>>> +
>>>>>>>>>>       return size;
>>>>>>>>>>   }
>>>>>>>>>>   static DEVICE_ATTR_RW(enable_ts);
>
> Do not overload the same for both DSB and CMB. Create one for each in
> DSB and CMB ? They could share the same show/store routines, but could
> be done with additional variable to indicate which attribute they are
> controlling. Like the other attributes, using dev_ext_attribute or such.

New approach below, please help review to see if it is acceptable?

#define tpdm_patt_enable_ts_rw(name, mem)                \
    (&((struct tpdm_dataset_attribute[]) {            \
       {                                \
        __ATTR(name, 0644, enable_ts_show,        \
        enable_ts_store),        \
        mem,                            \
       }                                \
    })[0].attr.attr)


#define DSB_PATT_ENABLE_TS                    \
        tpdm_patt_enable_ts_rw(enable_ts,        \
        DSB_PATT)


#define CMB_PATT_ENABLE_TS                    \
        tpdm_patt_enable_ts_rw(enable_ts,        \
        CMB_PATT)


static ssize_t enable_ts_show(struct device *dev,
                  struct device_attribute *attr,
                  char *buf)
{
    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
    struct tpdm_dataset_attribute *tpdm_attr =
        container_of(attr, struct tpdm_dataset_attribute, attr);
    ssize_t size = 0;

    if (tpdm_attr->mem == DSB_PATT) {
        size = sysfs_emit(buf, "%u\n",
                 (unsigned int)drvdata->dsb->patt_ts);
    } else if (tpdm_attr->mem == CMB_PATT) {
        size = sysfs_emit(buf, "%u\n",
                (unsigned int)drvdata->cmb->patt_ts);
    } else
        return -EINVAL;

    return size;
}

static ssize_t enable_ts_store(struct device *dev,
                   struct device_attribute *attr,
                   const char *buf,
                   size_t size)
{
    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
    struct tpdm_dataset_attribute *tpdm_attr =
        container_of(attr, struct tpdm_dataset_attribute, attr);
    unsigned long val;

    if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
        return -EINVAL;

    spin_lock(&drvdata->spinlock);
    if (tpdm_attr->mem == DSB_PATT) {
        drvdata->dsb->patt_ts = !!val;
    } else if (tpdm_attr->mem == CMB_PATT) {
        drvdata->cmb->patt_ts = !!val;
    } else
        return -EINVAL;
    spin_unlock(&drvdata->spinlock);

    return size;
}


Best,

Tao

>
>
> Suzuki
>

2024-01-12 09:13:21

by Tao Zhang

[permalink] [raw]
Subject: Re: [PATCH v3 8/8] coresight-tpdm: Add msr register support for CMB


On 12/20/2023 5:06 PM, Tao Zhang wrote:
>
> On 12/19/2023 10:09 PM, Suzuki K Poulose wrote:
>> On 19/12/2023 06:58, Tao Zhang wrote:
>>>
>>> On 12/18/2023 7:02 PM, Suzuki K Poulose wrote:
>>>> On 21/11/2023 02:24, Tao Zhang wrote:
>>>>> Add the nodes for CMB subunit MSR(mux select register) support.
>>>>> CMB MSRs(mux select registers) is to separate mux,arbitration,
>>>>> ,interleaving,data packing control from stream filtering control.
>>>>>
>>>>> Reviewed-by: James Clark <[email protected]>
>>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>>> Signed-off-by: Mao Jinlong <[email protected]>
>>>>> ---
>>>>>   .../testing/sysfs-bus-coresight-devices-tpdm  |  8 ++
>>>>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 86
>>>>> +++++++++++++++++++
>>>>>   drivers/hwtracing/coresight/coresight-tpdm.h  | 16 +++-
>>>>>   3 files changed, 109 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git
>>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>> index e0b77107be13..914f3fd81525 100644
>>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>> @@ -249,3 +249,11 @@ Description:
>>>>>           Accepts only one of the 2 values -  0 or 1.
>>>>>           0 : Disable the timestamp of all trace packets.
>>>>>           1 : Enable the timestamp of all trace packets.
>>>>> +
>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
>>>>> +Date:        September 2023
>>>>> +KernelVersion    6.7
>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>> Zhang (QUIC) <[email protected]>
>>>>> +Description:
>>>>> +        (RW) Set/Get the MSR(mux select register) for the CMB
>>>>> subunit
>>>>> +        TPDM.
>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>> index f6cda5616e84..7e331ea436cc 100644
>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>> @@ -86,6 +86,11 @@ static ssize_t tpdm_simple_dataset_show(struct
>>>>> device *dev,
>>>>>               return -EINVAL;
>>>>>           return sysfs_emit(buf, "0x%x\n",
>>>>> drvdata->cmb->patt_mask[tpdm_attr->idx]);
>>>>> +    case CMB_MSR:
>>>>> +        if (tpdm_attr->idx >= drvdata->cmb_msr_num)
>>>>> +            return -EINVAL;
>>>>> +        return sysfs_emit(buf, "0x%x\n",
>>>>> + drvdata->cmb->msr[tpdm_attr->idx]);
>>>>>       }
>>>>>       return -EINVAL;
>>>>>   }
>>>>> @@ -162,6 +167,12 @@ static ssize_t
>>>>> tpdm_simple_dataset_store(struct device *dev,
>>>>>           else
>>>>>               ret = -EINVAL;
>>>>>           break;
>>>>> +    case CMB_MSR:
>>>>> +        if (tpdm_attr->idx < drvdata->cmb_msr_num)
>>>>> +            drvdata->cmb->msr[tpdm_attr->idx] = val;
>>>>> +        else
>>>>> +            ret = -EINVAL;
>>>>
>>>>
>>>> minor nit: Could we not break from here instead of adding return
>>>> -EINVAL
>>>> for each case ? (I understand it has been done for the existing cases.
>>>> But I think we should clean up all of that, including the ones you
>>>> added
>>>> in Patch 5. Similarly for the dataset_show()
>>>
>>> Sure, do I also need to change the DSB corresponding code? If so,
>>> how about
>>>
>>> if I add a new patch to the next patch series to change the previous
>>> existing cases?
>>
>> You could fix the existing cases as a preparatory patch of the next
>> version of this series. I can pick it up and push it to next as I see
>> fit.
>
> Got it. I will update this to the next patch series.

Hi Suzuki,


Since the dataset data is configured with spin lock protection, it needs
to be unlock before return.

List my modification below. Would you mind help review to see if it is
good for you.

static ssize_t tpdm_simple_dataset_store(struct device *dev,
                     struct device_attribute *attr,
                     const char *buf,
                     size_t size)
{
    unsigned long val;

    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
    struct tpdm_dataset_attribute *tpdm_attr =
        container_of(attr, struct tpdm_dataset_attribute, attr);

    if (kstrtoul(buf, 0, &val))
        return -EINVAL;

    spin_lock(&drvdata->spinlock);
    switch (tpdm_attr->mem) {
    case DSB_TRIG_PATT:
        if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
            drvdata->dsb->trig_patt[tpdm_attr->idx] = val;
        else {
            spin_unlock(&drvdata->spinlock);
            return -EINVAL;
        }
    case DSB_TRIG_PATT_MASK:
        if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
            drvdata->dsb->trig_patt_mask[tpdm_attr->idx] = val;
        else{
            spin_unlock(&drvdata->spinlock);
            return -EINVAL;
        }
    case DSB_PATT:
        if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
            drvdata->dsb->patt_val[tpdm_attr->idx] = val;
        else{
            spin_unlock(&drvdata->spinlock);
            return -EINVAL;
        }
    case DSB_PATT_MASK:
        if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
            drvdata->dsb->patt_mask[tpdm_attr->idx] = val;
        else{
            spin_unlock(&drvdata->spinlock);
            return -EINVAL;
        }
    case DSB_MSR:
        if (tpdm_attr->idx < drvdata->dsb_msr_num)
            drvdata->dsb->msr[tpdm_attr->idx] = val;
        else{
            spin_unlock(&drvdata->spinlock);
            return -EINVAL;
        }
    default:
        spin_unlock(&drvdata->spinlock);
        return -EINVAL;
    }
    return size;


Best,

Tao

>
>
> Best,
>
> Tao
>
>>
>> Suzuki
>>
>>
>>>
>>>
>>> Best,
>>>
>>> Tao
>>>
>>>>
>>>>
>>>> Suzuki
>>>>
>>>>
>>>>> +        break;
>>>>>       default:
>>>>>           ret = -EINVAL;
>>>>>       }
>>>>> @@ -220,6 +231,23 @@ static umode_t tpdm_dsb_msr_is_visible(struct
>>>>> kobject *kobj,
>>>>>       return 0;
>>>>>   }
>>>>>   +static umode_t tpdm_cmb_msr_is_visible(struct kobject *kobj,
>>>>> +                       struct attribute *attr, int n)
>>>>> +{
>>>>> +    struct device *dev = kobj_to_dev(kobj);
>>>>> +    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>>> +
>>>>> +    struct device_attribute *dev_attr =
>>>>> +        container_of(attr, struct device_attribute, attr);
>>>>> +    struct tpdm_dataset_attribute *tpdm_attr =
>>>>> +        container_of(dev_attr, struct tpdm_dataset_attribute, attr);
>>>>> +
>>>>> +    if (tpdm_attr->idx < drvdata->cmb_msr_num)
>>>>> +        return attr->mode;
>>>>> +
>>>>> +    return 0;
>>>>> +}
>>>>> +
>>>>>   static void tpdm_reset_datasets(struct tpdm_drvdata *drvdata)
>>>>>   {
>>>>>       if (tpdm_has_dsb_dataset(drvdata)) {
>>>>> @@ -361,6 +389,15 @@ static void set_cmb_tier(struct tpdm_drvdata
>>>>> *drvdata)
>>>>>       writel_relaxed(val, drvdata->base + TPDM_CMB_TIER);
>>>>>   }
>>>>>   +static void set_cmb_msr(struct tpdm_drvdata *drvdata)
>>>>> +{
>>>>> +    int i;
>>>>> +
>>>>> +    for (i = 0; i < drvdata->cmb_msr_num; i++)
>>>>> +        writel_relaxed(drvdata->cmb->msr[i],
>>>>> +               drvdata->base + TPDM_CMB_MSR(i));
>>>>> +}
>>>>> +
>>>>>   static void tpdm_enable_cmb(struct tpdm_drvdata *drvdata)
>>>>>   {
>>>>>       u32 val, i;
>>>>> @@ -379,6 +416,8 @@ static void tpdm_enable_cmb(struct
>>>>> tpdm_drvdata *drvdata)
>>>>>         set_cmb_tier(drvdata);
>>>>>   +    set_cmb_msr(drvdata);
>>>>> +
>>>>>       val = readl_relaxed(drvdata->base + TPDM_CMB_CR);
>>>>>       /*
>>>>>        * Set to 0 for continuous CMB collection mode,
>>>>> @@ -1084,6 +1123,42 @@ static struct attribute
>>>>> *tpdm_cmb_patt_attrs[] = {
>>>>>       NULL,
>>>>>   };
>>>>>   +static struct attribute *tpdm_cmb_msr_attrs[] = {
>>>>> +    CMB_MSR_ATTR(0),
>>>>> +    CMB_MSR_ATTR(1),
>>>>> +    CMB_MSR_ATTR(2),
>>>>> +    CMB_MSR_ATTR(3),
>>>>> +    CMB_MSR_ATTR(4),
>>>>> +    CMB_MSR_ATTR(5),
>>>>> +    CMB_MSR_ATTR(6),
>>>>> +    CMB_MSR_ATTR(7),
>>>>> +    CMB_MSR_ATTR(8),
>>>>> +    CMB_MSR_ATTR(9),
>>>>> +    CMB_MSR_ATTR(10),
>>>>> +    CMB_MSR_ATTR(11),
>>>>> +    CMB_MSR_ATTR(12),
>>>>> +    CMB_MSR_ATTR(13),
>>>>> +    CMB_MSR_ATTR(14),
>>>>> +    CMB_MSR_ATTR(15),
>>>>> +    CMB_MSR_ATTR(16),
>>>>> +    CMB_MSR_ATTR(17),
>>>>> +    CMB_MSR_ATTR(18),
>>>>> +    CMB_MSR_ATTR(19),
>>>>> +    CMB_MSR_ATTR(20),
>>>>> +    CMB_MSR_ATTR(21),
>>>>> +    CMB_MSR_ATTR(22),
>>>>> +    CMB_MSR_ATTR(23),
>>>>> +    CMB_MSR_ATTR(24),
>>>>> +    CMB_MSR_ATTR(25),
>>>>> +    CMB_MSR_ATTR(26),
>>>>> +    CMB_MSR_ATTR(27),
>>>>> +    CMB_MSR_ATTR(28),
>>>>> +    CMB_MSR_ATTR(29),
>>>>> +    CMB_MSR_ATTR(30),
>>>>> +    CMB_MSR_ATTR(31),
>>>>> +    NULL,
>>>>> +};
>>>>> +
>>>>>   static struct attribute *tpdm_dsb_attrs[] = {
>>>>>       &dev_attr_dsb_mode.attr,
>>>>>       &dev_attr_dsb_trig_ts.attr,
>>>>> @@ -1144,6 +1219,12 @@ static struct attribute_group
>>>>> tpdm_cmb_patt_grp = {
>>>>>       .name = "cmb_patt",
>>>>>   };
>>>>>   +static struct attribute_group tpdm_cmb_msr_grp = {
>>>>> +    .attrs = tpdm_cmb_msr_attrs,
>>>>> +    .is_visible = tpdm_cmb_msr_is_visible,
>>>>> +    .name = "cmb_msr",
>>>>> +};
>>>>> +
>>>>>   static const struct attribute_group *tpdm_attr_grps[] = {
>>>>>       &tpdm_attr_grp,
>>>>>       &tpdm_dsb_attr_grp,
>>>>> @@ -1154,6 +1235,7 @@ static const struct attribute_group
>>>>> *tpdm_attr_grps[] = {
>>>>>       &tpdm_cmb_attr_grp,
>>>>>       &tpdm_cmb_trig_patt_grp,
>>>>>       &tpdm_cmb_patt_grp,
>>>>> +    &tpdm_cmb_msr_grp,
>>>>>       NULL,
>>>>>   };
>>>>>   @@ -1192,6 +1274,10 @@ static int tpdm_probe(struct amba_device
>>>>> *adev, const struct amba_id *id)
>>>>> of_property_read_u32(drvdata->dev->of_node,
>>>>>                  "qcom,dsb-msrs-num", &drvdata->dsb_msr_num);
>>>>>   +    if (drvdata && tpdm_has_cmb_dataset(drvdata))
>>>>> +        of_property_read_u32(drvdata->dev->of_node,
>>>>> +               "qcom,cmb-msrs-num", &drvdata->cmb_msr_num);
>>>>> +
>>>>>       /* Set up coresight component description */
>>>>>       desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
>>>>>       if (!desc.name)
>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>> index 65b7ca6c4077..255104d024ab 100644
>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>> @@ -21,6 +21,8 @@
>>>>>   #define TPDM_CMB_XPR(n)        (0xA18 + (n * 4))
>>>>>   /*CMB subunit trigger pattern mask registers*/
>>>>>   #define TPDM_CMB_XPMR(n)    (0xA20 + (n * 4))
>>>>> +/* CMB MSR register */
>>>>> +#define TPDM_CMB_MSR(n)        (0xA80 + (n * 4))
>>>>>     /* Enable bit for CMB subunit */
>>>>>   #define TPDM_CMB_CR_ENA        BIT(0)
>>>>> @@ -36,6 +38,9 @@
>>>>>   /*Patten register number*/
>>>>>   #define TPDM_CMB_MAX_PATT        2
>>>>>   +/* MAX number of DSB MSR */
>>>>> +#define TPDM_CMB_MAX_MSR 32
>>>>> +
>>>>>   /* DSB Subunit Registers */
>>>>>   #define TPDM_DSB_CR        (0x780)
>>>>>   #define TPDM_DSB_TIER        (0x784)
>>>>> @@ -186,6 +191,10 @@
>>>>>           tpdm_simple_dataset_rw(tpmr##nr,        \
>>>>>           CMB_PATT_MASK, nr)
>>>>>   +#define CMB_MSR_ATTR(nr)                    \
>>>>> +        tpdm_simple_dataset_rw(msr##nr,            \
>>>>> +        CMB_MSR, nr)
>>>>> +
>>>>>   /**
>>>>>    * struct dsb_dataset - specifics associated to dsb dataset
>>>>>    * @mode:             DSB programming mode
>>>>> @@ -225,6 +234,7 @@ struct dsb_dataset {
>>>>>    * @patt_mask:        Save value for pattern mask
>>>>>    * @trig_patt:        Save value for trigger pattern
>>>>>    * @trig_patt_mask:   Save value for trigger pattern mask
>>>>> + * @msr               Save value for MSR
>>>>>    * @patt_ts:          Indicates if pattern match for timestamp
>>>>> is enabled.
>>>>>    * @trig_ts:          Indicates if CTI trigger for timestamp is
>>>>> enabled.
>>>>>    * @ts_all:           Indicates if timestamp is enabled for all
>>>>> packets.
>>>>> @@ -235,6 +245,7 @@ struct cmb_dataset {
>>>>>       u32            patt_mask[TPDM_CMB_MAX_PATT];
>>>>>       u32            trig_patt[TPDM_CMB_MAX_PATT];
>>>>>       u32            trig_patt_mask[TPDM_CMB_MAX_PATT];
>>>>> +    u32            msr[TPDM_CMB_MAX_MSR];
>>>>>       bool            patt_ts;
>>>>>       bool            trig_ts;
>>>>>       bool            ts_all;
>>>>> @@ -251,6 +262,7 @@ struct cmb_dataset {
>>>>>    * @dsb         Specifics associated to TPDM DSB.
>>>>>    * @cmb         Specifics associated to TPDM CMB.
>>>>>    * @dsb_msr_num Number of MSR supported by DSB TPDM
>>>>> + * @cmb_msr_num Number of MSR supported by CMB TPDM
>>>>>    */
>>>>>     struct tpdm_drvdata {
>>>>> @@ -263,6 +275,7 @@ struct tpdm_drvdata {
>>>>>       struct dsb_dataset    *dsb;
>>>>>       struct cmb_dataset    *cmb;
>>>>>       u32            dsb_msr_num;
>>>>> +    u32            cmb_msr_num;
>>>>>   };
>>>>>     /* Enumerate members of various datasets */
>>>>> @@ -277,7 +290,8 @@ enum dataset_mem {
>>>>>       CMB_TRIG_PATT,
>>>>>       CMB_TRIG_PATT_MASK,
>>>>>       CMB_PATT,
>>>>> -    CMB_PATT_MASK
>>>>> +    CMB_PATT_MASK,
>>>>> +    CMB_MSR
>>>>>   };
>>>>>     /**
>>>>
>>>> _______________________________________________
>>>> CoreSight mailing list -- [email protected]
>>>> To unsubscribe send an email to [email protected]
>>
> _______________________________________________
> CoreSight mailing list -- [email protected]
> To unsubscribe send an email to [email protected]

2024-01-12 09:31:02

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH v3 6/8] coresight-tpdm: Add timestamp control register support for the CMB

On 12/01/2024 02:42, Tao Zhang wrote:
>
> On 1/8/2024 6:42 PM, Suzuki K Poulose wrote:
>> On 05/01/2024 07:49, Tao Zhang wrote:
>>>
>>> On 12/30/2023 5:39 PM, Suzuki K Poulose wrote:
>>>> On 25/12/2023 01:55, Tao Zhang wrote:
>>>>>
>>>>> On 12/20/2023 7:07 PM, Suzuki K Poulose wrote:
>>>>>> On 20/12/2023 09:51, Tao Zhang wrote:
>>>>>>>
>>>>>>> On 12/19/2023 9:51 PM, Suzuki K Poulose wrote:
>>>>>>>> On 19/12/2023 02:43, Tao Zhang wrote:
>>>>>>>>>
>>>>>>>>> On 12/18/2023 6:46 PM, Suzuki K Poulose wrote:
>>>>>>>>>> On 21/11/2023 02:24, Tao Zhang wrote:

..

>>>>>>>>>>>                     char *buf)
>>>>>>>>>>>   {
>>>>>>>>>>>       struct tpdm_drvdata *drvdata =
>>>>>>>>>>> dev_get_drvdata(dev->parent);
>>>>>>>>>>> +    ssize_t size = 0;
>>>>>>>>>>>   -    return sysfs_emit(buf, "%u\n",
>>>>>>>>>>> -             (unsigned int)drvdata->dsb->patt_ts);
>>>>>>>>>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>>>>>>>>>> +        size = sysfs_emit(buf, "%u\n",
>>>>>>>>>>> +                 (unsigned int)drvdata->dsb->patt_ts);
>>>>>>>>>>> +
>>>>>>>>>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>>>>>>>>>> +        size = sysfs_emit(buf, "%u\n",
>>>>>>>>>>> +                 (unsigned int)drvdata->cmb->patt_ts);
>>>>>>>>>>
>>>>>>>>>> Why does this need to show two values ? This must only show
>>>>>>>>>> ONE value.
>>>>>>>>>> How you deduce that might be based on the availability of the
>>>>>>>>>> feature
>>>>>>>>>> set. Or store the TS value in the drvdata and use that instead
>>>>>>>>>> for
>>>>>>>>>> controlling CMB/DSB.
>>>>>>>>>
>>>>>>>>> Since both of CMB/DSB need to have "enable_ts" SysFs file, can
>>>>>>>>> I separate them
>>>>>>>>
>>>>>>>> The question really is, do we need fine grained control. i.e.,
>>>>>>>>
>>>>>>>> enable TS for DSB but not for CMB or vice versa.
>>>>>>>>
>>>>>>>> I am not an expert on the usage scenario of the same. So, if
>>>>>>>> you/Qcomm
>>>>>>>> thinks the users need separate, fine grained control for timestamp
>>>>>>>> for the DSB and CMB, then yes, follow your recommendation below.
>>>>>>>> i.e., tpdm.../dsb_patt/enable_ts
>>>>>>>>
>>>>>>>>> as "enable_dsb_ts" and "enable_cmb_ts"? The path will be like
>>>>>>>>> below.
>>>>>>>>>
>>>>>>>>> tpdm0/dsb_patt/enable_dsb_ts
>>>>>>>>
>>>>>>>> You don't need enable_dsb_ts. It could be "enable_ts"
>>>>>>>>
>>>>>>>>>
>>>>>>>>> tpdm1/cmb_patt/enable_cmb_ts
>>>>>>>>>
>>>>>>>>> Is this design appropriate?
>>>>>>>>
>>>>>>>>
>>>>>>>> Otherwise, stick to single enable_ts : which enables the ts for
>>>>>>>> both
>>>>>>>> CMB/DSB. And it only ever show one value : 0 (TS is disabled for
>>>>>>>> both
>>>>>>>> CMB/DSB) 1 : TS enabled for both.
>>>>>>>
>>>>>>> We have a very special case, such as the TPDM supporting both CMB
>>>>>>> and
>>>>>>>
>>>>>>> DSB datasets. Although this case is very rare, it still exists.
>>>>>>>
>>>>>>> Can I use the data bit to instruct whether timestamp is enabled
>>>>>>> for CMB/DSB or not? For example,
>>>>>>>
>>>>>>> size = sysfs_emit(buf, "%u\n",
>>>>>>>                  (unsigned int)(drvdata->dsb->patt_ts << 1 |
>>>>>>> drvdata->cmb->patt_ts));
>>>>>>>
>>>>>>> Thus, this value can instruct the following situations.
>>>>>>>
>>>>>>> 0 - TS is disabled for both CMB/DSB
>>>>>>>
>>>>>>> 1 - TS is enabled for CMB
>>>>>>>
>>>>>>> 2 - TS is enabled for DSB
>>>>>>>
>>>>>>> 3 - TS is enabled for both
>>>>>>>
>>>>>>> Is this approach acceptable?
>>>>>>>
>>>>>>
>>>>>> No, please stick to separate controls for TS. Do not complicate
>>>>>> the user interface.
>>>>>>
>>>>>> i.e.,
>>>>>> tpdm0/dsb_patt/enable_ts
>>>>>> tpdm0/cmb_patt/enable_ts
>>>>>
>>>>> We need to be able to control/show dsb and cmb timestamp enablement
>>>>> independently.
>>>>>
>>>>> Can we achieve this requirement if we use a sysfs file with the
>>>>> same name?
>>>>
>>>> They are independent and in their respective directory (group) for
>>>> CMB and DSB. What am I missing ?
>>>> e.g., if you want to enable TS for DSB, you do :
>>>>
>>>> $ echo 1 > dsb_patt/enable_ts
>>>>
>>>> And that only works for DSB not for CMB.
>>>
>>> We have a special case that the TPDM supports both DSB and CMB
>>> dataset. In this special case, when we
>>>
>>> issue this command to enable timestamp, it will call enable_ts_store
>>> API, right?
>>>
>>>      if (tpdm_has_dsb_dataset(drvdata))
>>>          drvdata->dsb->patt_ts = !!val;
>>>
>>>      if (tpdm_has_cmb_dataset(drvdata))
>>>          drvdata->cmb->patt_ts = !!val;
>>
>> I don't understand. If they both are under different subgroups, why
>> should they be conflicting ? Are you not able to distinguish them, when
>>  you creat those attributes ? i.e., create two different "attributes" ?
>
> Yes, although some TPDMs can support both CMB dataset and DSB dataset,
> we need to configure them separately
>
> in some scenarios. Based on your suggestion, I want to use the following
> approach to implement it.
>
> See below.
>
>>
>> See below.
>>
>>> Since this special TPDM supports both DSB and CMB dataset, both DSB
>>> patt_ts and CMB patt_ts will be set
>>>
>>> in this case even if I only configure the file in the DSB directory,
>>> right?
>>>
>>> This is the problem we have now.
>>>
>>
>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>> +
>>>>>>>>>>> +    return size;
>>>>>>>>>>>   }
>>>>>>>>>>>     /*
>>>>>>>>>>> @@ -715,8 +755,13 @@ static ssize_t enable_ts_store(struct
>>>>>>>>>>> device *dev,
>>>>>>>>>>>           return -EINVAL;
>>>>>>>>>>>         spin_lock(&drvdata->spinlock);
>>>>>>>>>>> -    drvdata->dsb->patt_ts = !!val;
>>>>>>>>>>> +    if (tpdm_has_dsb_dataset(drvdata))
>>>>>>>>>>> +        drvdata->dsb->patt_ts = !!val;
>>>>>>>>>>> +
>>>>>>>>>>> +    if (tpdm_has_cmb_dataset(drvdata))
>>>>>>>>>>> +        drvdata->cmb->patt_ts = !!val;
>>>>>>>>>>>       spin_unlock(&drvdata->spinlock);
>>>>>>>>>>> +
>>>>>>>>>>>       return size;
>>>>>>>>>>>   }
>>>>>>>>>>>   static DEVICE_ATTR_RW(enable_ts);
>>
>> Do not overload the same for both DSB and CMB. Create one for each in
>> DSB and CMB ? They could share the same show/store routines, but could
>> be done with additional variable to indicate which attribute they are
>> controlling. Like the other attributes, using dev_ext_attribute or such.
>
> New approach below, please help review to see if it is acceptable?
>
> #define tpdm_patt_enable_ts_rw(name, mem)                \
>     (&((struct tpdm_dataset_attribute[]) {            \
>        {                                \
>         __ATTR(name, 0644, enable_ts_show,        \
>         enable_ts_store),        \
>         mem,                            \
>        }                                \
>     })[0].attr.attr)
>
>
> #define DSB_PATT_ENABLE_TS                    \
>         tpdm_patt_enable_ts_rw(enable_ts,        \
>         DSB_PATT)
>
>
> #define CMB_PATT_ENABLE_TS                    \
>         tpdm_patt_enable_ts_rw(enable_ts,        \
>         CMB_PATT)
>
>
> static ssize_t enable_ts_show(struct device *dev,
>                   struct device_attribute *attr,
>                   char *buf)
> {
>     struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>     struct tpdm_dataset_attribute *tpdm_attr =
>         container_of(attr, struct tpdm_dataset_attribute, attr);
>     ssize_t size = 0;
>
>     if (tpdm_attr->mem == DSB_PATT) {
>         size = sysfs_emit(buf, "%u\n",
>                  (unsigned int)drvdata->dsb->patt_ts);
>     } else if (tpdm_attr->mem == CMB_PATT) {
>         size = sysfs_emit(buf, "%u\n",
>                 (unsigned int)drvdata->cmb->patt_ts);
>     } else
>         return -EINVAL;
>
>     return size;
> }
>
> static ssize_t enable_ts_store(struct device *dev,
>                    struct device_attribute *attr,
>                    const char *buf,
>                    size_t size)
> {
>     struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>     struct tpdm_dataset_attribute *tpdm_attr =
>         container_of(attr, struct tpdm_dataset_attribute, attr);
>     unsigned long val;
>
>     if ((kstrtoul(buf, 0, &val)) || (val & ~1UL))
>         return -EINVAL;
>
>     spin_lock(&drvdata->spinlock);
>     if (tpdm_attr->mem == DSB_PATT) {
>         drvdata->dsb->patt_ts = !!val;
>     } else if (tpdm_attr->mem == CMB_PATT) {
>         drvdata->cmb->patt_ts = !!val;
>     } else
>         return -EINVAL;
>     spin_unlock(&drvdata->spinlock);
>
>     return size;
> }
>
>

Yes, that is what I had in mind.

Thanks
Suzuki

> Best,
>
> Tao
>
>>
>>
>> Suzuki
>>


2024-01-12 09:44:28

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH v3 8/8] coresight-tpdm: Add msr register support for CMB

On 12/01/2024 09:12, Tao Zhang wrote:
>
> On 12/20/2023 5:06 PM, Tao Zhang wrote:
>>
>> On 12/19/2023 10:09 PM, Suzuki K Poulose wrote:
>>> On 19/12/2023 06:58, Tao Zhang wrote:
>>>>
>>>> On 12/18/2023 7:02 PM, Suzuki K Poulose wrote:
>>>>> On 21/11/2023 02:24, Tao Zhang wrote:
>>>>>> Add the nodes for CMB subunit MSR(mux select register) support.
>>>>>> CMB MSRs(mux select registers) is to separate mux,arbitration,
>>>>>> ,interleaving,data packing control from stream filtering control.
>>>>>>
>>>>>> Reviewed-by: James Clark <[email protected]>
>>>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>>>> Signed-off-by: Mao Jinlong <[email protected]>
>>>>>> ---
>>>>>>   .../testing/sysfs-bus-coresight-devices-tpdm  |  8 ++
>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 86
>>>>>> +++++++++++++++++++
>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.h  | 16 +++-
>>>>>>   3 files changed, 109 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git
>>>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>> index e0b77107be13..914f3fd81525 100644
>>>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>> @@ -249,3 +249,11 @@ Description:
>>>>>>           Accepts only one of the 2 values -  0 or 1.
>>>>>>           0 : Disable the timestamp of all trace packets.
>>>>>>           1 : Enable the timestamp of all trace packets.
>>>>>> +
>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
>>>>>> +Date:        September 2023
>>>>>> +KernelVersion    6.7
>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>> Zhang (QUIC) <[email protected]>
>>>>>> +Description:
>>>>>> +        (RW) Set/Get the MSR(mux select register) for the CMB
>>>>>> subunit
>>>>>> +        TPDM.
>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>> index f6cda5616e84..7e331ea436cc 100644
>>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>> @@ -86,6 +86,11 @@ static ssize_t tpdm_simple_dataset_show(struct
>>>>>> device *dev,
>>>>>>               return -EINVAL;
>>>>>>           return sysfs_emit(buf, "0x%x\n",
>>>>>> drvdata->cmb->patt_mask[tpdm_attr->idx]);
>>>>>> +    case CMB_MSR:
>>>>>> +        if (tpdm_attr->idx >= drvdata->cmb_msr_num)
>>>>>> +            return -EINVAL;
>>>>>> +        return sysfs_emit(buf, "0x%x\n",
>>>>>> + drvdata->cmb->msr[tpdm_attr->idx]);
>>>>>>       }
>>>>>>       return -EINVAL;
>>>>>>   }
>>>>>> @@ -162,6 +167,12 @@ static ssize_t
>>>>>> tpdm_simple_dataset_store(struct device *dev,
>>>>>>           else
>>>>>>               ret = -EINVAL;
>>>>>>           break;
>>>>>> +    case CMB_MSR:
>>>>>> +        if (tpdm_attr->idx < drvdata->cmb_msr_num)
>>>>>> +            drvdata->cmb->msr[tpdm_attr->idx] = val;
>>>>>> +        else
>>>>>> +            ret = -EINVAL;
>>>>>
>>>>>
>>>>> minor nit: Could we not break from here instead of adding return
>>>>> -EINVAL
>>>>> for each case ? (I understand it has been done for the existing cases.
>>>>> But I think we should clean up all of that, including the ones you
>>>>> added
>>>>> in Patch 5. Similarly for the dataset_show()
>>>>
>>>> Sure, do I also need to change the DSB corresponding code? If so,
>>>> how about
>>>>
>>>> if I add a new patch to the next patch series to change the previous
>>>> existing cases?
>>>
>>> You could fix the existing cases as a preparatory patch of the next
>>> version of this series. I can pick it up and push it to next as I see
>>> fit.
>>
>> Got it. I will update this to the next patch series.
>
> Hi Suzuki,
>
>
> Since the dataset data is configured with spin lock protection, it needs
> to be unlock before return.
>
> List my modification below. Would you mind help review to see if it is
> good for you.
>
> static ssize_t tpdm_simple_dataset_store(struct device *dev,
>                      struct device_attribute *attr,
>                      const char *buf,
>                      size_t size)
> {
>     unsigned long val;
>
>     struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>     struct tpdm_dataset_attribute *tpdm_attr =
>         container_of(attr, struct tpdm_dataset_attribute, attr);
>
>     if (kstrtoul(buf, 0, &val))
>         return -EINVAL;
>
>     spin_lock(&drvdata->spinlock);

Use guard() to avoid explicit unlock on return and then you don't need
the spin_unlock() everywhere. It would be done on return from the
function implicitly.


>     switch (tpdm_attr->mem) {
>     case DSB_TRIG_PATT:

With guard() in place:

ret = -EINVAL;

switch () {
case XXX:

if (tpdm_attr->idx < TPDM_XXXX_IDX) {
drvdata->dsb->trig_patt[tpdm_attr->idx] = val;
ret = size;
}
break;
case ...
...
}

return ret;


Suzuki


2024-01-12 11:57:48

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH v3 0/8] Add support to configure TPDM CMB subunit

On 21/11/2023 02:24, Tao Zhang wrote:
> Introduction of TPDM CMB(Continuous Multi Bit) subunit
> CMB subunit is responsible for creating a dataset element, and is also
> optionally responsible for packing it to fit multiple elements on a
> single ATB transfer if possible in the configuration. The TPDM Core
> Datapath requests timestamps be stored by the TPDA and then delivering
> ATB sized data (depending on ATB width and element size, this could
> be smaller or larger than a dataset element) to the ATB Mast FSM.
> The CMB makes trace elements in two modes. In �continuous� mode, every
> valid data cycle creates an element. In �trace on change� mode, when
> valid data changes on the bus, a trace element is created. In
> continuous mode, all cycles where this condition is true create trace
> elements. In trace on change mode, a data element is only when the
> previously sampled input is different from the current sampled input.
>
> The CMB subunit must be configured prior to enablement. This series
> adds support for TPDM to configure the configure CMB subunit.
>


Please base your next version on for-next/queue branch on the
coresight repository.

Suzuki

2024-01-15 06:20:45

by Tao Zhang

[permalink] [raw]
Subject: Re: [PATCH v3 8/8] coresight-tpdm: Add msr register support for CMB


On 1/12/2024 5:43 PM, Suzuki K Poulose wrote:
> On 12/01/2024 09:12, Tao Zhang wrote:
>>
>> On 12/20/2023 5:06 PM, Tao Zhang wrote:
>>>
>>> On 12/19/2023 10:09 PM, Suzuki K Poulose wrote:
>>>> On 19/12/2023 06:58, Tao Zhang wrote:
>>>>>
>>>>> On 12/18/2023 7:02 PM, Suzuki K Poulose wrote:
>>>>>> On 21/11/2023 02:24, Tao Zhang wrote:
>>>>>>> Add the nodes for CMB subunit MSR(mux select register) support.
>>>>>>> CMB MSRs(mux select registers) is to separate mux,arbitration,
>>>>>>> ,interleaving,data packing control from stream filtering control.
>>>>>>>
>>>>>>> Reviewed-by: James Clark <[email protected]>
>>>>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>>>>> Signed-off-by: Mao Jinlong <[email protected]>
>>>>>>> ---
>>>>>>>   .../testing/sysfs-bus-coresight-devices-tpdm  |  8 ++
>>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 86
>>>>>>> +++++++++++++++++++
>>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.h  | 16 +++-
>>>>>>>   3 files changed, 109 insertions(+), 1 deletion(-)
>>>>>>>
>>>>>>> diff --git
>>>>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>> index e0b77107be13..914f3fd81525 100644
>>>>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>> @@ -249,3 +249,11 @@ Description:
>>>>>>>           Accepts only one of the 2 values -  0 or 1.
>>>>>>>           0 : Disable the timestamp of all trace packets.
>>>>>>>           1 : Enable the timestamp of all trace packets.
>>>>>>> +
>>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
>>>>>>> +Date:        September 2023
>>>>>>> +KernelVersion    6.7
>>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>>> Zhang (QUIC) <[email protected]>
>>>>>>> +Description:
>>>>>>> +        (RW) Set/Get the MSR(mux select register) for the CMB
>>>>>>> subunit
>>>>>>> +        TPDM.
>>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>> index f6cda5616e84..7e331ea436cc 100644
>>>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>> @@ -86,6 +86,11 @@ static ssize_t
>>>>>>> tpdm_simple_dataset_show(struct device *dev,
>>>>>>>               return -EINVAL;
>>>>>>>           return sysfs_emit(buf, "0x%x\n",
>>>>>>> drvdata->cmb->patt_mask[tpdm_attr->idx]);
>>>>>>> +    case CMB_MSR:
>>>>>>> +        if (tpdm_attr->idx >= drvdata->cmb_msr_num)
>>>>>>> +            return -EINVAL;
>>>>>>> +        return sysfs_emit(buf, "0x%x\n",
>>>>>>> + drvdata->cmb->msr[tpdm_attr->idx]);
>>>>>>>       }
>>>>>>>       return -EINVAL;
>>>>>>>   }
>>>>>>> @@ -162,6 +167,12 @@ static ssize_t
>>>>>>> tpdm_simple_dataset_store(struct device *dev,
>>>>>>>           else
>>>>>>>               ret = -EINVAL;
>>>>>>>           break;
>>>>>>> +    case CMB_MSR:
>>>>>>> +        if (tpdm_attr->idx < drvdata->cmb_msr_num)
>>>>>>> + drvdata->cmb->msr[tpdm_attr->idx] = val;
>>>>>>> +        else
>>>>>>> +            ret = -EINVAL;
>>>>>>
>>>>>>
>>>>>> minor nit: Could we not break from here instead of adding return
>>>>>> -EINVAL
>>>>>> for each case ? (I understand it has been done for the existing
>>>>>> cases.
>>>>>> But I think we should clean up all of that, including the ones
>>>>>> you added
>>>>>> in Patch 5. Similarly for the dataset_show()
>>>>>
>>>>> Sure, do I also need to change the DSB corresponding code? If so,
>>>>> how about
>>>>>
>>>>> if I add a new patch to the next patch series to change the
>>>>> previous existing cases?
>>>>
>>>> You could fix the existing cases as a preparatory patch of the next
>>>> version of this series. I can pick it up and push it to next as I
>>>> see fit.
>>>
>>> Got it. I will update this to the next patch series.
>>
>> Hi Suzuki,
>>
>>
>> Since the dataset data is configured with spin lock protection, it
>> needs to be unlock before return.
>>
>> List my modification below. Would you mind help review to see if it
>> is good for you.
>>
>> static ssize_t tpdm_simple_dataset_store(struct device *dev,
>>                       struct device_attribute *attr,
>>                       const char *buf,
>>                       size_t size)
>> {
>>      unsigned long val;
>>
>>      struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>      struct tpdm_dataset_attribute *tpdm_attr =
>>          container_of(attr, struct tpdm_dataset_attribute, attr);
>>
>>      if (kstrtoul(buf, 0, &val))
>>          return -EINVAL;
>>
>>      spin_lock(&drvdata->spinlock);
>
> Use guard() to avoid explicit unlock on return and then you don't need
> the spin_unlock() everywhere. It would be done on return from the
> function implicitly.
>
>
>>      switch (tpdm_attr->mem) {
>>      case DSB_TRIG_PATT:
>
> With guard() in place:
>
>     ret = -EINVAL;
>
>     switch () {
>     case XXX:
>
>        if (tpdm_attr->idx < TPDM_XXXX_IDX) {
>            drvdata->dsb->trig_patt[tpdm_attr->idx] = val;
>            ret = size;
>        }
>        break;
>     case ...
>         ...
>     }
>
>     return ret;

Thanks for your suggestion. I will update the code like below.

I will update it in the next version of the patch series if it meets
your expectation.

static ssize_t tpdm_simple_dataset_store(struct device *dev,
                     struct device_attribute *attr,
                     const char *buf,
                     size_t size)
{
    unsigned long val;
    ssize_t ret = -EINVAL;

    struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
    struct tpdm_dataset_attribute *tpdm_attr =
        container_of(attr, struct tpdm_dataset_attribute, attr);

    if (kstrtoul(buf, 0, &val))
        return ret;

    guard(spinlock)(&drvdata->spinlock);
    switch (tpdm_attr->mem) {
    case DSB_TRIG_PATT:
        if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
            drvdata->dsb->trig_patt[tpdm_attr->idx] = val;
            ret =size;
        }
        break;
    case ...

        ...
    }
    return ret;
}

Best,

Tao

>
>
> Suzuki
>

2024-01-15 09:21:21

by Suzuki K Poulose

[permalink] [raw]
Subject: Re: [PATCH v3 8/8] coresight-tpdm: Add msr register support for CMB

On 15/01/2024 06:20, Tao Zhang wrote:
>
> On 1/12/2024 5:43 PM, Suzuki K Poulose wrote:
>> On 12/01/2024 09:12, Tao Zhang wrote:
>>>
>>> On 12/20/2023 5:06 PM, Tao Zhang wrote:
>>>>
>>>> On 12/19/2023 10:09 PM, Suzuki K Poulose wrote:
>>>>> On 19/12/2023 06:58, Tao Zhang wrote:
>>>>>>
>>>>>> On 12/18/2023 7:02 PM, Suzuki K Poulose wrote:
>>>>>>> On 21/11/2023 02:24, Tao Zhang wrote:
>>>>>>>> Add the nodes for CMB subunit MSR(mux select register) support.
>>>>>>>> CMB MSRs(mux select registers) is to separate mux,arbitration,
>>>>>>>> ,interleaving,data packing control from stream filtering control.
>>>>>>>>
>>>>>>>> Reviewed-by: James Clark <[email protected]>
>>>>>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>>>>>> Signed-off-by: Mao Jinlong <[email protected]>
>>>>>>>> ---
>>>>>>>>   .../testing/sysfs-bus-coresight-devices-tpdm  |  8 ++
>>>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 86
>>>>>>>> +++++++++++++++++++
>>>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.h  | 16 +++-
>>>>>>>>   3 files changed, 109 insertions(+), 1 deletion(-)
>>>>>>>>
>>>>>>>> diff --git
>>>>>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>> index e0b77107be13..914f3fd81525 100644
>>>>>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>> @@ -249,3 +249,11 @@ Description:
>>>>>>>>           Accepts only one of the 2 values -  0 or 1.
>>>>>>>>           0 : Disable the timestamp of all trace packets.
>>>>>>>>           1 : Enable the timestamp of all trace packets.
>>>>>>>> +
>>>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
>>>>>>>> +Date:        September 2023
>>>>>>>> +KernelVersion    6.7
>>>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>>>> Zhang (QUIC) <[email protected]>
>>>>>>>> +Description:
>>>>>>>> +        (RW) Set/Get the MSR(mux select register) for the CMB
>>>>>>>> subunit
>>>>>>>> +        TPDM.
>>>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>> index f6cda5616e84..7e331ea436cc 100644
>>>>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>> @@ -86,6 +86,11 @@ static ssize_t
>>>>>>>> tpdm_simple_dataset_show(struct device *dev,
>>>>>>>>               return -EINVAL;
>>>>>>>>           return sysfs_emit(buf, "0x%x\n",
>>>>>>>> drvdata->cmb->patt_mask[tpdm_attr->idx]);
>>>>>>>> +    case CMB_MSR:
>>>>>>>> +        if (tpdm_attr->idx >= drvdata->cmb_msr_num)
>>>>>>>> +            return -EINVAL;
>>>>>>>> +        return sysfs_emit(buf, "0x%x\n",
>>>>>>>> + drvdata->cmb->msr[tpdm_attr->idx]);
>>>>>>>>       }
>>>>>>>>       return -EINVAL;
>>>>>>>>   }
>>>>>>>> @@ -162,6 +167,12 @@ static ssize_t
>>>>>>>> tpdm_simple_dataset_store(struct device *dev,
>>>>>>>>           else
>>>>>>>>               ret = -EINVAL;
>>>>>>>>           break;
>>>>>>>> +    case CMB_MSR:
>>>>>>>> +        if (tpdm_attr->idx < drvdata->cmb_msr_num)
>>>>>>>> + drvdata->cmb->msr[tpdm_attr->idx] = val;
>>>>>>>> +        else
>>>>>>>> +            ret = -EINVAL;
>>>>>>>
>>>>>>>
>>>>>>> minor nit: Could we not break from here instead of adding return
>>>>>>> -EINVAL
>>>>>>> for each case ? (I understand it has been done for the existing
>>>>>>> cases.
>>>>>>> But I think we should clean up all of that, including the ones
>>>>>>> you added
>>>>>>> in Patch 5. Similarly for the dataset_show()
>>>>>>
>>>>>> Sure, do I also need to change the DSB corresponding code? If so,
>>>>>> how about
>>>>>>
>>>>>> if I add a new patch to the next patch series to change the
>>>>>> previous existing cases?
>>>>>
>>>>> You could fix the existing cases as a preparatory patch of the next
>>>>> version of this series. I can pick it up and push it to next as I
>>>>> see fit.
>>>>
>>>> Got it. I will update this to the next patch series.
>>>
>>> Hi Suzuki,
>>>
>>>
>>> Since the dataset data is configured with spin lock protection, it
>>> needs to be unlock before return.
>>>
>>> List my modification below. Would you mind help review to see if it
>>> is good for you.
>>>
>>> static ssize_t tpdm_simple_dataset_store(struct device *dev,
>>>                       struct device_attribute *attr,
>>>                       const char *buf,
>>>                       size_t size)
>>> {
>>>      unsigned long val;
>>>
>>>      struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>      struct tpdm_dataset_attribute *tpdm_attr =
>>>          container_of(attr, struct tpdm_dataset_attribute, attr);
>>>
>>>      if (kstrtoul(buf, 0, &val))
>>>          return -EINVAL;
>>>
>>>      spin_lock(&drvdata->spinlock);
>>
>> Use guard() to avoid explicit unlock on return and then you don't need
>> the spin_unlock() everywhere. It would be done on return from the
>> function implicitly.
>>
>>
>>>      switch (tpdm_attr->mem) {
>>>      case DSB_TRIG_PATT:
>>
>> With guard() in place:
>>
>>     ret = -EINVAL;
>>
>>     switch () {
>>     case XXX:
>>
>>        if (tpdm_attr->idx < TPDM_XXXX_IDX) {
>>            drvdata->dsb->trig_patt[tpdm_attr->idx] = val;
>>            ret = size;
>>        }
>>        break;
>>     case ...
>>         ...
>>     }
>>
>>     return ret;
>
> Thanks for your suggestion. I will update the code like below.
>
> I will update it in the next version of the patch series if it meets
> your expectation.
>
> static ssize_t tpdm_simple_dataset_store(struct device *dev,
>                      struct device_attribute *attr,
>                      const char *buf,
>                      size_t size)
> {
>     unsigned long val;
>     ssize_t ret = -EINVAL;
>
>     struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>     struct tpdm_dataset_attribute *tpdm_attr =
>         container_of(attr, struct tpdm_dataset_attribute, attr);
>
>     if (kstrtoul(buf, 0, &val))
>         return ret;
>
>     guard(spinlock)(&drvdata->spinlock);
>     switch (tpdm_attr->mem) {
>     case DSB_TRIG_PATT:
>         if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
>             drvdata->dsb->trig_patt[tpdm_attr->idx] = val;
>             ret =size;
>         }
>         break;
>     case ...
>
>         ...
>     }
>     return ret;
> }
>

Yes that looks good to me. Please rebase this on to for-next/queue
branch on the coresight repository.

Suzuki


2024-01-15 09:56:12

by James Clark

[permalink] [raw]
Subject: Re: [PATCH v3 8/8] coresight-tpdm: Add msr register support for CMB



On 12/01/2024 09:12, Tao Zhang wrote:
>
> On 12/20/2023 5:06 PM, Tao Zhang wrote:
>>
>> On 12/19/2023 10:09 PM, Suzuki K Poulose wrote:
>>> On 19/12/2023 06:58, Tao Zhang wrote:
>>>>
>>>> On 12/18/2023 7:02 PM, Suzuki K Poulose wrote:
>>>>> On 21/11/2023 02:24, Tao Zhang wrote:
>>>>>> Add the nodes for CMB subunit MSR(mux select register) support.
>>>>>> CMB MSRs(mux select registers) is to separate mux,arbitration,
>>>>>> ,interleaving,data packing control from stream filtering control.
>>>>>>
>>>>>> Reviewed-by: James Clark <[email protected]>
>>>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>>>> Signed-off-by: Mao Jinlong <[email protected]>
>>>>>> ---
>>>>>>   .../testing/sysfs-bus-coresight-devices-tpdm  |  8 ++
>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 86
>>>>>> +++++++++++++++++++
>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.h  | 16 +++-
>>>>>>   3 files changed, 109 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git
>>>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>> index e0b77107be13..914f3fd81525 100644
>>>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>> @@ -249,3 +249,11 @@ Description:
>>>>>>           Accepts only one of the 2 values -  0 or 1.
>>>>>>           0 : Disable the timestamp of all trace packets.
>>>>>>           1 : Enable the timestamp of all trace packets.
>>>>>> +
>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
>>>>>> +Date:        September 2023
>>>>>> +KernelVersion    6.7
>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>> Zhang (QUIC) <[email protected]>
>>>>>> +Description:
>>>>>> +        (RW) Set/Get the MSR(mux select register) for the CMB
>>>>>> subunit
>>>>>> +        TPDM.
>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>> index f6cda5616e84..7e331ea436cc 100644
>>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>> @@ -86,6 +86,11 @@ static ssize_t tpdm_simple_dataset_show(struct
>>>>>> device *dev,
>>>>>>               return -EINVAL;
>>>>>>           return sysfs_emit(buf, "0x%x\n",
>>>>>> drvdata->cmb->patt_mask[tpdm_attr->idx]);
>>>>>> +    case CMB_MSR:
>>>>>> +        if (tpdm_attr->idx >= drvdata->cmb_msr_num)
>>>>>> +            return -EINVAL;
>>>>>> +        return sysfs_emit(buf, "0x%x\n",
>>>>>> + drvdata->cmb->msr[tpdm_attr->idx]);
>>>>>>       }
>>>>>>       return -EINVAL;
>>>>>>   }
>>>>>> @@ -162,6 +167,12 @@ static ssize_t
>>>>>> tpdm_simple_dataset_store(struct device *dev,
>>>>>>           else
>>>>>>               ret = -EINVAL;
>>>>>>           break;
>>>>>> +    case CMB_MSR:
>>>>>> +        if (tpdm_attr->idx < drvdata->cmb_msr_num)
>>>>>> +            drvdata->cmb->msr[tpdm_attr->idx] = val;
>>>>>> +        else
>>>>>> +            ret = -EINVAL;
>>>>>
>>>>>
>>>>> minor nit: Could we not break from here instead of adding return
>>>>> -EINVAL
>>>>> for each case ? (I understand it has been done for the existing cases.
>>>>> But I think we should clean up all of that, including the ones you
>>>>> added
>>>>> in Patch 5. Similarly for the dataset_show()
>>>>
>>>> Sure, do I also need to change the DSB corresponding code? If so,
>>>> how about
>>>>
>>>> if I add a new patch to the next patch series to change the previous
>>>> existing cases?
>>>
>>> You could fix the existing cases as a preparatory patch of the next
>>> version of this series. I can pick it up and push it to next as I see
>>> fit.
>>
>> Got it. I will update this to the next patch series.
>
> Hi Suzuki,
>
>
> Since the dataset data is configured with spin lock protection, it needs
> to be unlock before return.
>
> List my modification below. Would you mind help review to see if it is
> good for you.
>
> static ssize_t tpdm_simple_dataset_store(struct device *dev,
>                      struct device_attribute *attr,
>                      const char *buf,
>                      size_t size)
> {
>     unsigned long val;
>
>     struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>     struct tpdm_dataset_attribute *tpdm_attr =
>         container_of(attr, struct tpdm_dataset_attribute, attr);
>
>     if (kstrtoul(buf, 0, &val))
>         return -EINVAL;
>
>     spin_lock(&drvdata->spinlock);
>     switch (tpdm_attr->mem) {
>     case DSB_TRIG_PATT:
>         if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
>             drvdata->dsb->trig_patt[tpdm_attr->idx] = val;
>         else {
>             spin_unlock(&drvdata->spinlock);
>             return -EINVAL;
>         }
>     case DSB_TRIG_PATT_MASK:
>         if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
>             drvdata->dsb->trig_patt_mask[tpdm_attr->idx] = val;
>         else{
>             spin_unlock(&drvdata->spinlock);
>             return -EINVAL;
>         }
>     case DSB_PATT:
>         if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
>             drvdata->dsb->patt_val[tpdm_attr->idx] = val;
>         else{
>             spin_unlock(&drvdata->spinlock);
>             return -EINVAL;
>         }
>     case DSB_PATT_MASK:
>         if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
>             drvdata->dsb->patt_mask[tpdm_attr->idx] = val;
>         else{
>             spin_unlock(&drvdata->spinlock);
>             return -EINVAL;
>         }
>     case DSB_MSR:
>         if (tpdm_attr->idx < drvdata->dsb_msr_num)
>             drvdata->dsb->msr[tpdm_attr->idx] = val;
>         else{
>             spin_unlock(&drvdata->spinlock);
>             return -EINVAL;
>         }
>     default:
>         spin_unlock(&drvdata->spinlock);
>         return -EINVAL;
>     }
>     return size;
>
>
> Best,
>
> Tao
>

This looks like a good fit for the new
guard(spinlock)(&drvdata->spinlock) thing. Then there is no need to do
all the manual unlocking.


2024-01-15 10:05:55

by James Clark

[permalink] [raw]
Subject: Re: [PATCH v3 8/8] coresight-tpdm: Add msr register support for CMB



On 15/01/2024 09:55, James Clark wrote:
>
>
> On 12/01/2024 09:12, Tao Zhang wrote:
>>
>> On 12/20/2023 5:06 PM, Tao Zhang wrote:
>>>
>>> On 12/19/2023 10:09 PM, Suzuki K Poulose wrote:
>>>> On 19/12/2023 06:58, Tao Zhang wrote:
>>>>>
>>>>> On 12/18/2023 7:02 PM, Suzuki K Poulose wrote:
>>>>>> On 21/11/2023 02:24, Tao Zhang wrote:
>>>>>>> Add the nodes for CMB subunit MSR(mux select register) support.
>>>>>>> CMB MSRs(mux select registers) is to separate mux,arbitration,
>>>>>>> ,interleaving,data packing control from stream filtering control.
>>>>>>>
>>>>>>> Reviewed-by: James Clark <[email protected]>
>>>>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>>>>> Signed-off-by: Mao Jinlong <[email protected]>
>>>>>>> ---
>>>>>>>   .../testing/sysfs-bus-coresight-devices-tpdm  |  8 ++
>>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 86
>>>>>>> +++++++++++++++++++
>>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.h  | 16 +++-
>>>>>>>   3 files changed, 109 insertions(+), 1 deletion(-)
>>>>>>>
>>>>>>> diff --git
>>>>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>> index e0b77107be13..914f3fd81525 100644
>>>>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>> @@ -249,3 +249,11 @@ Description:
>>>>>>>           Accepts only one of the 2 values -  0 or 1.
>>>>>>>           0 : Disable the timestamp of all trace packets.
>>>>>>>           1 : Enable the timestamp of all trace packets.
>>>>>>> +
>>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
>>>>>>> +Date:        September 2023
>>>>>>> +KernelVersion    6.7
>>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>, Tao
>>>>>>> Zhang (QUIC) <[email protected]>
>>>>>>> +Description:
>>>>>>> +        (RW) Set/Get the MSR(mux select register) for the CMB
>>>>>>> subunit
>>>>>>> +        TPDM.
>>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>> index f6cda5616e84..7e331ea436cc 100644
>>>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>> @@ -86,6 +86,11 @@ static ssize_t tpdm_simple_dataset_show(struct
>>>>>>> device *dev,
>>>>>>>               return -EINVAL;
>>>>>>>           return sysfs_emit(buf, "0x%x\n",
>>>>>>> drvdata->cmb->patt_mask[tpdm_attr->idx]);
>>>>>>> +    case CMB_MSR:
>>>>>>> +        if (tpdm_attr->idx >= drvdata->cmb_msr_num)
>>>>>>> +            return -EINVAL;
>>>>>>> +        return sysfs_emit(buf, "0x%x\n",
>>>>>>> + drvdata->cmb->msr[tpdm_attr->idx]);
>>>>>>>       }
>>>>>>>       return -EINVAL;
>>>>>>>   }
>>>>>>> @@ -162,6 +167,12 @@ static ssize_t
>>>>>>> tpdm_simple_dataset_store(struct device *dev,
>>>>>>>           else
>>>>>>>               ret = -EINVAL;
>>>>>>>           break;
>>>>>>> +    case CMB_MSR:
>>>>>>> +        if (tpdm_attr->idx < drvdata->cmb_msr_num)
>>>>>>> +            drvdata->cmb->msr[tpdm_attr->idx] = val;
>>>>>>> +        else
>>>>>>> +            ret = -EINVAL;
>>>>>>
>>>>>>
>>>>>> minor nit: Could we not break from here instead of adding return
>>>>>> -EINVAL
>>>>>> for each case ? (I understand it has been done for the existing cases.
>>>>>> But I think we should clean up all of that, including the ones you
>>>>>> added
>>>>>> in Patch 5. Similarly for the dataset_show()
>>>>>
>>>>> Sure, do I also need to change the DSB corresponding code? If so,
>>>>> how about
>>>>>
>>>>> if I add a new patch to the next patch series to change the previous
>>>>> existing cases?
>>>>
>>>> You could fix the existing cases as a preparatory patch of the next
>>>> version of this series. I can pick it up and push it to next as I see
>>>> fit.
>>>
>>> Got it. I will update this to the next patch series.
>>
>> Hi Suzuki,
>>
>>
>> Since the dataset data is configured with spin lock protection, it needs
>> to be unlock before return.
>>
>> List my modification below. Would you mind help review to see if it is
>> good for you.
>>
>> static ssize_t tpdm_simple_dataset_store(struct device *dev,
>>                      struct device_attribute *attr,
>>                      const char *buf,
>>                      size_t size)
>> {
>>     unsigned long val;
>>
>>     struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>     struct tpdm_dataset_attribute *tpdm_attr =
>>         container_of(attr, struct tpdm_dataset_attribute, attr);
>>
>>     if (kstrtoul(buf, 0, &val))
>>         return -EINVAL;
>>
>>     spin_lock(&drvdata->spinlock);
>>     switch (tpdm_attr->mem) {
>>     case DSB_TRIG_PATT:
>>         if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
>>             drvdata->dsb->trig_patt[tpdm_attr->idx] = val;
>>         else {
>>             spin_unlock(&drvdata->spinlock);
>>             return -EINVAL;
>>         }
>>     case DSB_TRIG_PATT_MASK:
>>         if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
>>             drvdata->dsb->trig_patt_mask[tpdm_attr->idx] = val;
>>         else{
>>             spin_unlock(&drvdata->spinlock);
>>             return -EINVAL;
>>         }
>>     case DSB_PATT:
>>         if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
>>             drvdata->dsb->patt_val[tpdm_attr->idx] = val;
>>         else{
>>             spin_unlock(&drvdata->spinlock);
>>             return -EINVAL;
>>         }
>>     case DSB_PATT_MASK:
>>         if (tpdm_attr->idx < TPDM_DSB_MAX_PATT)
>>             drvdata->dsb->patt_mask[tpdm_attr->idx] = val;
>>         else{
>>             spin_unlock(&drvdata->spinlock);
>>             return -EINVAL;
>>         }
>>     case DSB_MSR:
>>         if (tpdm_attr->idx < drvdata->dsb_msr_num)
>>             drvdata->dsb->msr[tpdm_attr->idx] = val;
>>         else{
>>             spin_unlock(&drvdata->spinlock);
>>             return -EINVAL;
>>         }
>>     default:
>>         spin_unlock(&drvdata->spinlock);
>>         return -EINVAL;
>>     }
>>     return size;
>>
>>
>> Best,
>>
>> Tao
>>
>
> This looks like a good fit for the new
> guard(spinlock)(&drvdata->spinlock) thing. Then there is no need to do
> all the manual unlocking.
>

Oh I see Suzuki already suggested it, nevermind.

2024-01-15 14:16:29

by Tao Zhang

[permalink] [raw]
Subject: Re: [PATCH v3 8/8] coresight-tpdm: Add msr register support for CMB


On 1/15/2024 5:20 PM, Suzuki K Poulose wrote:
> On 15/01/2024 06:20, Tao Zhang wrote:
>>
>> On 1/12/2024 5:43 PM, Suzuki K Poulose wrote:
>>> On 12/01/2024 09:12, Tao Zhang wrote:
>>>>
>>>> On 12/20/2023 5:06 PM, Tao Zhang wrote:
>>>>>
>>>>> On 12/19/2023 10:09 PM, Suzuki K Poulose wrote:
>>>>>> On 19/12/2023 06:58, Tao Zhang wrote:
>>>>>>>
>>>>>>> On 12/18/2023 7:02 PM, Suzuki K Poulose wrote:
>>>>>>>> On 21/11/2023 02:24, Tao Zhang wrote:
>>>>>>>>> Add the nodes for CMB subunit MSR(mux select register) support.
>>>>>>>>> CMB MSRs(mux select registers) is to separate mux,arbitration,
>>>>>>>>> ,interleaving,data packing control from stream filtering control.
>>>>>>>>>
>>>>>>>>> Reviewed-by: James Clark <[email protected]>
>>>>>>>>> Signed-off-by: Tao Zhang <[email protected]>
>>>>>>>>> Signed-off-by: Mao Jinlong <[email protected]>
>>>>>>>>> ---
>>>>>>>>>   .../testing/sysfs-bus-coresight-devices-tpdm  | 8 ++
>>>>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.c  | 86
>>>>>>>>> +++++++++++++++++++
>>>>>>>>>   drivers/hwtracing/coresight/coresight-tpdm.h  | 16 +++-
>>>>>>>>>   3 files changed, 109 insertions(+), 1 deletion(-)
>>>>>>>>>
>>>>>>>>> diff --git
>>>>>>>>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>>> index e0b77107be13..914f3fd81525 100644
>>>>>>>>> --- a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>>>>>>>> @@ -249,3 +249,11 @@ Description:
>>>>>>>>>           Accepts only one of the 2 values -  0 or 1.
>>>>>>>>>           0 : Disable the timestamp of all trace packets.
>>>>>>>>>           1 : Enable the timestamp of all trace packets.
>>>>>>>>> +
>>>>>>>>> +What: /sys/bus/coresight/devices/<tpdm-name>/cmb_msr/msr[0:31]
>>>>>>>>> +Date:        September 2023
>>>>>>>>> +KernelVersion    6.7
>>>>>>>>> +Contact:    Jinlong Mao (QUIC) <[email protected]>,
>>>>>>>>> Tao Zhang (QUIC) <[email protected]>
>>>>>>>>> +Description:
>>>>>>>>> +        (RW) Set/Get the MSR(mux select register) for the CMB
>>>>>>>>> subunit
>>>>>>>>> +        TPDM.
>>>>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>>> b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>>> index f6cda5616e84..7e331ea436cc 100644
>>>>>>>>> --- a/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>>>>>>>>> @@ -86,6 +86,11 @@ static ssize_t
>>>>>>>>> tpdm_simple_dataset_show(struct device *dev,
>>>>>>>>>               return -EINVAL;
>>>>>>>>>           return sysfs_emit(buf, "0x%x\n",
>>>>>>>>> drvdata->cmb->patt_mask[tpdm_attr->idx]);
>>>>>>>>> +    case CMB_MSR:
>>>>>>>>> +        if (tpdm_attr->idx >= drvdata->cmb_msr_num)
>>>>>>>>> +            return -EINVAL;
>>>>>>>>> +        return sysfs_emit(buf, "0x%x\n",
>>>>>>>>> + drvdata->cmb->msr[tpdm_attr->idx]);
>>>>>>>>>       }
>>>>>>>>>       return -EINVAL;
>>>>>>>>>   }
>>>>>>>>> @@ -162,6 +167,12 @@ static ssize_t
>>>>>>>>> tpdm_simple_dataset_store(struct device *dev,
>>>>>>>>>           else
>>>>>>>>>               ret = -EINVAL;
>>>>>>>>>           break;
>>>>>>>>> +    case CMB_MSR:
>>>>>>>>> +        if (tpdm_attr->idx < drvdata->cmb_msr_num)
>>>>>>>>> + drvdata->cmb->msr[tpdm_attr->idx] = val;
>>>>>>>>> +        else
>>>>>>>>> +            ret = -EINVAL;
>>>>>>>>
>>>>>>>>
>>>>>>>> minor nit: Could we not break from here instead of adding
>>>>>>>> return -EINVAL
>>>>>>>> for each case ? (I understand it has been done for the existing
>>>>>>>> cases.
>>>>>>>> But I think we should clean up all of that, including the ones
>>>>>>>> you added
>>>>>>>> in Patch 5. Similarly for the dataset_show()
>>>>>>>
>>>>>>> Sure, do I also need to change the DSB corresponding code? If
>>>>>>> so, how about
>>>>>>>
>>>>>>> if I add a new patch to the next patch series to change the
>>>>>>> previous existing cases?
>>>>>>
>>>>>> You could fix the existing cases as a preparatory patch of the
>>>>>> next version of this series. I can pick it up and push it to next
>>>>>> as I see fit.
>>>>>
>>>>> Got it. I will update this to the next patch series.
>>>>
>>>> Hi Suzuki,
>>>>
>>>>
>>>> Since the dataset data is configured with spin lock protection, it
>>>> needs to be unlock before return.
>>>>
>>>> List my modification below. Would you mind help review to see if it
>>>> is good for you.
>>>>
>>>> static ssize_t tpdm_simple_dataset_store(struct device *dev,
>>>>                       struct device_attribute *attr,
>>>>                       const char *buf,
>>>>                       size_t size)
>>>> {
>>>>      unsigned long val;
>>>>
>>>>      struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>>>      struct tpdm_dataset_attribute *tpdm_attr =
>>>>          container_of(attr, struct tpdm_dataset_attribute, attr);
>>>>
>>>>      if (kstrtoul(buf, 0, &val))
>>>>          return -EINVAL;
>>>>
>>>>      spin_lock(&drvdata->spinlock);
>>>
>>> Use guard() to avoid explicit unlock on return and then you don't
>>> need the spin_unlock() everywhere. It would be done on return from the
>>> function implicitly.
>>>
>>>
>>>>      switch (tpdm_attr->mem) {
>>>>      case DSB_TRIG_PATT:
>>>
>>> With guard() in place:
>>>
>>>     ret = -EINVAL;
>>>
>>>     switch () {
>>>     case XXX:
>>>
>>>        if (tpdm_attr->idx < TPDM_XXXX_IDX) {
>>>            drvdata->dsb->trig_patt[tpdm_attr->idx] = val;
>>>            ret = size;
>>>        }
>>>        break;
>>>     case ...
>>>         ...
>>>     }
>>>
>>>     return ret;
>>
>> Thanks for your suggestion. I will update the code like below.
>>
>> I will update it in the next version of the patch series if it meets
>> your expectation.
>>
>> static ssize_t tpdm_simple_dataset_store(struct device *dev,
>>                       struct device_attribute *attr,
>>                       const char *buf,
>>                       size_t size)
>> {
>>      unsigned long val;
>>      ssize_t ret = -EINVAL;
>>
>>      struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
>>      struct tpdm_dataset_attribute *tpdm_attr =
>>          container_of(attr, struct tpdm_dataset_attribute, attr);
>>
>>      if (kstrtoul(buf, 0, &val))
>>          return ret;
>>
>>      guard(spinlock)(&drvdata->spinlock);
>>      switch (tpdm_attr->mem) {
>>      case DSB_TRIG_PATT:
>>          if (tpdm_attr->idx < TPDM_DSB_MAX_PATT) {
>>              drvdata->dsb->trig_patt[tpdm_attr->idx] = val;
>>              ret =size;
>>          }
>>          break;
>>      case ...
>>
>>          ...
>>      }
>>      return ret;
>> }
>>
>
> Yes that looks good to me. Please rebase this on to for-next/queue
> branch on the coresight repository.

Got it. Thanks for your mention.


Best,

Tao

>
> Suzuki
>