This series adds support for the trace performance monitoring and
diagnostics hardware (TPDM and TPDA). It is composed of two major
elements.
a) Changes for original coresight framework to support for TPDM and TPDA.
b) Add driver code for TPDM and TPDA.
Introduction of changes for original coresight framework
Support TPDM as new coresight source.
Since only STM and ETM are supported as coresight source originally.
TPDM is a newly added coresight source. We need to change
the original way of saving coresight path to support more types source
for coresight driver.
The following patch is to add support more coresight sources.
Use IDR to maintain all the enabled sources' paths.
Introduction of TPDM and TPDA
TPDM - The trace performance monitoring and diagnostics monitor or TPDM in
short serves as data collection component for various dataset types
specified in the QPMDA(Qualcomm performance monitoring and diagnostics
architecture) spec. The primary use case of the TPDM is to collect data
from different data sources and send it to a TPDA for packetization,
timestamping and funneling.
Coresight: Add coresight TPDM source driver
dt-bindings: arm: Adds CoreSight TPDM hardware definitions
coresight-tpdm: Add DSB dataset support
coresight-tpdm: Add integration test support
docs: sysfs: coresight: Add sysfs ABI documentation for TPDM
TPDA - The trace performance monitoring and diagnostics aggregator or
TPDA in short serves as an arbitration and packetization engine for the
performance monitoring and diagnostics network as specified in the QPMDA
(Qualcomm performance monitoring and diagnostics architecture)
specification. The primary use case of the TPDA is to provide
packetization, funneling and timestamping of Monitor data as specified
in the QPMDA specification.
The following patch is to add driver for TPDA.
Coresight: Add TPDA link driver
dt-bindings: arm: Adds CoreSight TPDA hardware definitions
The last patch of this series is a device tree modification, which add
the TPDM and TPDA configuration to device tree for validating.
ARM: dts: msm: Add coresight components for SM8250
Once this series patches are applied properly, the tpdm and tpda nodes
should be observed at the coresight path /sys/bus/coresight/devices
e.g.
/sys/bus/coresight/devices # ls -l | grep tpd
tpda0 -> ../../../devices/platform/soc@0/6004000.tpda/tpda0
tpdm0 -> ../../../devices/platform/soc@0/6c08000.mm.tpdm/tpdm0
We can use the commands are similar to the below to validate TPDMs.
Enable coresight sink first.
echo 1 > /sys/bus/coresight/devices/tmc_etf0/enable_sink
echo 1 > /sys/bus/coresight/devices/tpdm0/enable_source
echo 1 > /sys/bus/coresight/devices/tpdm0/integration_test
echo 2 > /sys/bus/coresight/devices/tpdm0/integration_test
The test data will be collected in the coresight sink which is enabled.
If rwp register of the sink is keeping updating when do
integration_test (by cat tmc_etf0/mgmt/rwp), it means there is data
generated from TPDM to sink.
Changes from V1:
1. Use IDR to store the path of sources. (Mathieu Poirier)
2. Only add integration_test/enable/disable for TPDM. No other configs.
(Mathieu Poirier)
3. Move coresight dtsi changes to sm8250.dtsi. (Suzuki K Poulose)
Mao Jinlong (9):
Use IDR to maintain all the enabled sources' paths.
Coresight: Add coresight TPDM source driver
dt-bindings: arm: Adds CoreSight TPDM hardware definitions
coresight-tpdm: Add DSB dataset support
coresight-tpdm: Add integration test support
docs: sysfs: coresight: Add sysfs ABI documentation for TPDM
Coresight: Add TPDA link driver
dt-bindings: arm: Adds CoreSight TPDA hardware definitions
ARM: dts: msm: Add coresight components for SM8250
.../testing/sysfs-bus-coresight-devices-tpdm | 12 +
.../bindings/arm/coresight-tpda.yaml | 131 ++++
.../bindings/arm/coresight-tpdm.yaml | 83 +++
.../devicetree/bindings/arm/coresight.txt | 7 +
MAINTAINERS | 13 +
.../arm64/boot/dts/qcom/sm8250-coresight.dtsi | 688 ++++++++++++++++++
arch/arm64/boot/dts/qcom/sm8250.dtsi | 2 +
drivers/hwtracing/coresight/Kconfig | 33 +
drivers/hwtracing/coresight/Makefile | 2 +
drivers/hwtracing/coresight/coresight-core.c | 79 +-
drivers/hwtracing/coresight/coresight-tpda.c | 201 +++++
drivers/hwtracing/coresight/coresight-tpda.h | 33 +
drivers/hwtracing/coresight/coresight-tpdm.c | 262 +++++++
drivers/hwtracing/coresight/coresight-tpdm.h | 62 ++
include/linux/coresight.h | 1 +
15 files changed, 1558 insertions(+), 51 deletions(-)
create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
create mode 100644 Documentation/devicetree/bindings/arm/coresight-tpda.yaml
create mode 100644 Documentation/devicetree/bindings/arm/coresight-tpdm.yaml
create mode 100644 arch/arm64/boot/dts/qcom/sm8250-coresight.dtsi
create mode 100644 drivers/hwtracing/coresight/coresight-tpda.c
create mode 100644 drivers/hwtracing/coresight/coresight-tpda.h
create mode 100644 drivers/hwtracing/coresight/coresight-tpdm.c
create mode 100644 drivers/hwtracing/coresight/coresight-tpdm.h
--
2.17.1
Use hash length of the source's device name to map to the pointer
of the enabled path. Using IDR will be more efficient than using
the list. And there could be other sources except STM and CPU etms
in the new HWs. It is better to maintain all the paths together.
Signed-off-by: Mao Jinlong <[email protected]>
---
drivers/hwtracing/coresight/coresight-core.c | 76 +++++++-------------
1 file changed, 26 insertions(+), 50 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index 8a18c71df37a..cc6b6cabf85f 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -7,6 +7,7 @@
#include <linux/init.h>
#include <linux/types.h>
#include <linux/device.h>
+#include <linux/idr.h>
#include <linux/io.h>
#include <linux/err.h>
#include <linux/export.h>
@@ -26,6 +27,12 @@
static DEFINE_MUTEX(coresight_mutex);
static DEFINE_PER_CPU(struct coresight_device *, csdev_sink);
+/*
+ * Use IDR to map the hash length of the source's device name
+ * to the pointer of path for the source
+ */
+static DEFINE_IDR(path_idr);
+
/**
* struct coresight_node - elements of a path, from source to sink
* @csdev: Address of an element.
@@ -36,20 +43,6 @@ struct coresight_node {
struct list_head link;
};
-/*
- * When operating Coresight drivers from the sysFS interface, only a single
- * path can exist from a tracer (associated to a CPU) to a sink.
- */
-static DEFINE_PER_CPU(struct list_head *, tracer_path);
-
-/*
- * As of this writing only a single STM can be found in CS topologies. Since
- * there is no way to know if we'll ever see more and what kind of
- * configuration they will enact, for the time being only define a single path
- * for STM.
- */
-static struct list_head *stm_path;
-
/*
* When losing synchronisation a new barrier packet needs to be inserted at the
* beginning of the data collected in a buffer. That way the decoder knows that
@@ -1088,10 +1081,11 @@ static int coresight_validate_source(struct coresight_device *csdev,
int coresight_enable(struct coresight_device *csdev)
{
- int cpu, ret = 0;
+ int ret = 0;
struct coresight_device *sink;
struct list_head *path;
enum coresight_dev_subtype_source subtype;
+ u32 hash;
subtype = csdev->subtype.source_subtype;
@@ -1133,26 +1127,14 @@ int coresight_enable(struct coresight_device *csdev)
if (ret)
goto err_source;
- switch (subtype) {
- case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
- /*
- * When working from sysFS it is important to keep track
- * of the paths that were created so that they can be
- * undone in 'coresight_disable()'. Since there can only
- * be a single session per tracer (when working from sysFS)
- * a per-cpu variable will do just fine.
- */
- cpu = source_ops(csdev)->cpu_id(csdev);
- per_cpu(tracer_path, cpu) = path;
- break;
- case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
- stm_path = path;
- break;
- default:
- /* We can't be here */
- break;
- }
-
+ /*
+ * Use the hash length of source's device name as ID
+ * and map the ID to the pointer of the path.
+ */
+ hash = hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev)));
+ ret = idr_alloc_u32(&path_idr, path, &hash, hash, GFP_KERNEL);
+ if (ret)
+ goto err_source;
out:
mutex_unlock(&coresight_mutex);
return ret;
@@ -1168,8 +1150,9 @@ EXPORT_SYMBOL_GPL(coresight_enable);
void coresight_disable(struct coresight_device *csdev)
{
- int cpu, ret;
+ int ret;
struct list_head *path = NULL;
+ u32 hash;
mutex_lock(&coresight_mutex);
@@ -1180,21 +1163,13 @@ void coresight_disable(struct coresight_device *csdev)
if (!csdev->enable || !coresight_disable_source(csdev))
goto out;
- switch (csdev->subtype.source_subtype) {
- case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
- cpu = source_ops(csdev)->cpu_id(csdev);
- path = per_cpu(tracer_path, cpu);
- per_cpu(tracer_path, cpu) = NULL;
- break;
- case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
- path = stm_path;
- stm_path = NULL;
- break;
- default:
- /* We can't be here */
- break;
- }
+ hash = hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev)));
+ /* Find the path by the hash length. */
+ path = idr_find(&path_idr, hash);
+ if (path == NULL)
+ return;
+ idr_remove(&path_idr, hash);
coresight_disable_path(path);
coresight_release_path(path);
@@ -1779,6 +1754,7 @@ static int __init coresight_init(void)
static void __exit coresight_exit(void)
{
+ idr_destroy(&path_idr);
cscfg_exit();
etm_perf_exit();
bus_unregister(&coresight_bustype);
--
2.17.1
Add driver to support Coresight device TPDM (Trace, Profiling and
Diagnostics Monitor). TPDM is a monitor to collect data from
different datasets. This change is to add probe/enable/disable
functions for tpdm source.
Signed-off-by: Tao Zhang <[email protected]>
Signed-off-by: Mao Jinlong <[email protected]>
---
MAINTAINERS | 8 +
drivers/hwtracing/coresight/Kconfig | 13 ++
drivers/hwtracing/coresight/Makefile | 1 +
drivers/hwtracing/coresight/coresight-core.c | 3 +-
drivers/hwtracing/coresight/coresight-tpdm.c | 152 +++++++++++++++++++
drivers/hwtracing/coresight/coresight-tpdm.h | 31 ++++
include/linux/coresight.h | 1 +
7 files changed, 208 insertions(+), 1 deletion(-)
create mode 100644 drivers/hwtracing/coresight/coresight-tpdm.c
create mode 100644 drivers/hwtracing/coresight/coresight-tpdm.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 7a2345ce8521..59f39b3194f6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15560,6 +15560,14 @@ L: [email protected]
S: Supported
F: drivers/net/ipa/
+QCOM CORESIGHT COMPONENTS DRIVER
+M: Tao Zhang <[email protected]>
+M: Jinlong Mao <[email protected]>
+M: Mathieu Poirier <[email protected]>
+M: Suzuki K Poulose <[email protected]>
+S: Maintained
+F: drivers/hwtracing/coresight/coresight-tpdm.c
+
QEMU MACHINE EMULATOR AND VIRTUALIZER SUPPORT
M: Gabriel Somlo <[email protected]>
M: "Michael S. Tsirkin" <[email protected]>
diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
index 514a9b8086e3..5c506a1cd08f 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -201,4 +201,17 @@ config CORESIGHT_TRBE
To compile this driver as a module, choose M here: the module will be
called coresight-trbe.
+
+config CORESIGHT_TPDM
+ tristate "CoreSight Trace, Profiling & Diagnostics Monitor driver"
+ select CORESIGHT_LINKS_AND_SINKS
+ help
+ This driver provides support for configuring monitor. Monitors are
+ primarily responsible for data set collection and support the
+ ability to collect any permutation of data set types. Monitors are
+ also responsible for interaction with system cross triggering.
+
+ To compile this driver as a module, choose M here: the module will be
+ called coresight-tpdm.
+
endif
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index b6c4a48140ec..e7392a0dddeb 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -25,5 +25,6 @@ obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o
obj-$(CONFIG_CORESIGHT_CATU) += coresight-catu.o
obj-$(CONFIG_CORESIGHT_CTI) += coresight-cti.o
obj-$(CONFIG_CORESIGHT_TRBE) += coresight-trbe.o
+obj-$(CONFIG_CORESIGHT_TPDM) += coresight-tpdm.o
coresight-cti-y := coresight-cti-core.o coresight-cti-platform.o \
coresight-cti-sysfs.o
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index cc6b6cabf85f..a7f1a6f09cfb 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -1071,7 +1071,8 @@ static int coresight_validate_source(struct coresight_device *csdev,
}
if (subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_PROC &&
- subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE) {
+ subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE &&
+ subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_SYS) {
dev_err(&csdev->dev, "wrong device subtype in %s\n", function);
return -EINVAL;
}
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
new file mode 100644
index 000000000000..f494cef4fb24
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/amba/bus.h>
+#include <linux/bitmap.h>
+#include <linux/coresight.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regulator/consumer.h>
+
+#include "coresight-priv.h"
+#include "coresight-tpdm.h"
+
+DEFINE_CORESIGHT_DEVLIST(tpdm_devs, "tpdm");
+
+static int tpdm_enable(struct coresight_device *csdev,
+ struct perf_event *event, u32 mode)
+{
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+ mutex_lock(&drvdata->lock);
+ if (drvdata->enable) {
+ mutex_unlock(&drvdata->lock);
+ return -EBUSY;
+ }
+
+ drvdata->enable = true;
+ mutex_unlock(&drvdata->lock);
+
+ dev_info(drvdata->dev, "TPDM tracing enabled\n");
+ return 0;
+}
+
+static void tpdm_disable(struct coresight_device *csdev,
+ struct perf_event *event)
+{
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+ mutex_lock(&drvdata->lock);
+ if (!drvdata->enable) {
+ mutex_unlock(&drvdata->lock);
+ return;
+ }
+
+ drvdata->enable = false;
+ mutex_unlock(&drvdata->lock);
+
+ dev_info(drvdata->dev, "TPDM tracing disabled\n");
+}
+
+static int tpdm_trace_id(struct coresight_device *csdev)
+{
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+ return drvdata->traceid;
+}
+
+static const struct coresight_ops_source tpdm_source_ops = {
+ .trace_id = tpdm_trace_id,
+ .enable = tpdm_enable,
+ .disable = tpdm_disable,
+};
+
+static const struct coresight_ops tpdm_cs_ops = {
+ .source_ops = &tpdm_source_ops,
+};
+
+static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
+{
+ static int traceid = TPDM_TRACE_ID_START;
+
+ drvdata->traceid = traceid++;
+}
+
+static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
+{
+ struct device *dev = &adev->dev;
+ struct coresight_platform_data *pdata;
+ struct tpdm_drvdata *drvdata;
+ struct coresight_desc desc = { 0 };
+
+ desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
+ if (!desc.name)
+ return -ENOMEM;
+ pdata = coresight_get_platform_data(dev);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+ adev->dev.platform_data = pdata;
+
+ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+ drvdata->dev = &adev->dev;
+ dev_set_drvdata(dev, drvdata);
+
+ drvdata->base = devm_ioremap_resource(dev, &adev->res);
+ if (!drvdata->base)
+ return -ENOMEM;
+
+ mutex_init(&drvdata->lock);
+
+ desc.type = CORESIGHT_DEV_TYPE_SOURCE;
+ desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
+ desc.ops = &tpdm_cs_ops;
+ desc.pdata = adev->dev.platform_data;
+ desc.dev = &adev->dev;
+ drvdata->csdev = coresight_register(&desc);
+ if (IS_ERR(drvdata->csdev))
+ return PTR_ERR(drvdata->csdev);
+
+ tpdm_init_default_data(drvdata);
+ pm_runtime_put(&adev->dev);
+
+ return 0;
+}
+
+static void __exit tpdm_remove(struct amba_device *adev)
+{
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
+
+ coresight_unregister(drvdata->csdev);
+}
+
+static struct amba_id tpdm_ids[] = {
+ {
+ .id = 0x000f0e00,
+ .mask = 0x000fff00,
+ },
+ { 0, 0},
+};
+
+static struct amba_driver tpdm_driver = {
+ .drv = {
+ .name = "coresight-tpdm",
+ .owner = THIS_MODULE,
+ .suppress_bind_attrs = true,
+ },
+ .probe = tpdm_probe,
+ .id_table = tpdm_ids,
+};
+
+module_amba_driver(tpdm_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
new file mode 100644
index 000000000000..980ae90ff1c8
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _CORESIGHT_CORESIGHT_TPDM_H
+#define _CORESIGHT_CORESIGHT_TPDM_H
+
+/* Default value of the traceid */
+#define TPDM_TRACE_ID_START 128
+
+/**
+ * struct tpdm_drvdata - specifics associated to an TPDM component
+ * @base: memory mapped base address for this component.
+ * @dev: The device entity associated to this component.
+ * @csdev: component vitals needed by the framework.
+ * @lock: lock for the enable value.
+ * @enable: enable status of the component.
+ * @traceid: value of the current ID for this component.
+ */
+
+struct tpdm_drvdata {
+ void __iomem *base;
+ struct device *dev;
+ struct coresight_device *csdev;
+ struct mutex lock;
+ bool enable;
+ int traceid;
+};
+
+#endif /* _CORESIGHT_CORESIGHT_TPDM_H */
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 93a2922b7653..e48d463be63b 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
+ CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
};
enum coresight_dev_subtype_helper {
--
2.17.1
Adds new coresight-tpdm.yaml file describing the bindings required
to define tpdm in the device trees.
Signed-off-by: Tao Zhang <[email protected]>
Signed-off-by: Mao Jinlong <[email protected]>
---
.../bindings/arm/coresight-tpdm.yaml | 83 +++++++++++++++++++
.../devicetree/bindings/arm/coresight.txt | 7 ++
MAINTAINERS | 1 +
3 files changed, 91 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/coresight-tpdm.yaml
diff --git a/Documentation/devicetree/bindings/arm/coresight-tpdm.yaml b/Documentation/devicetree/bindings/arm/coresight-tpdm.yaml
new file mode 100644
index 000000000000..63b0583afcfc
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/coresight-tpdm.yaml
@@ -0,0 +1,83 @@
+# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
+# Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/coresight-tpdm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Trace, Profiling and Diagnostics Monitor - TPDM
+
+description: |
+ The TPDM or Monitor serves as data collection component for various dataset
+ types specified in the QPMDA spec. It covers Implementation defined ((ImplDef),
+ Basic Counts (BC), Tenure Counts (TC), Continuous Multi-Bit (CMB), and Discrete
+ Single Bit (DSB). It performs data collection in the data producing clock
+ domain and transfers it to the data collection time domain, generally ATB
+ clock domain.
+
+ The primary use case of the TPDM is to collect data from different data
+ sources and send it to a TPDA for packetization, timestamping, and funneling.
+
+maintainers:
+ - Tao Zhang <[email protected]>
+ - Mao Jinlong <[email protected]>
+ - Suzuki K Poulose <[email protected]>
+ - Mathieu Poirier <[email protected]>
+
+properties:
+ $nodename:
+ pattern: "^tpdm(@[0-9a-f]+)$"
+ compatible:
+ items:
+ - const: qcom,coresight-tpdm
+ - const: arm,primecell
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ items:
+ - const: apb_pclk
+
+ out-ports:
+ description: |
+ Output connections from the TPDM to legacy CoreSight trace bus.
+ $ref: /schemas/graph.yaml#/properties/ports
+ properties:
+ port:
+ description: Output connection from the TPDM to legacy CoreSight
+ Trace bus.
+ $ref: /schemas/graph.yaml#/properties/port
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+
+additionalProperties: false
+
+examples:
+ # minimum TPDM definition.
+ - |
+ tpdm@6980000 {
+ compatible = "qcom,coresight-tpdm", "arm,primecell";
+ reg = <0x6980000 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ tpdm_turing_out_funnel_turing: endpoint {
+ remote-endpoint =
+ <&funnel_turing_in_tpdm_turing>;
+ };
+ };
+ };
+ };
+
+...
diff --git a/Documentation/devicetree/bindings/arm/coresight.txt b/Documentation/devicetree/bindings/arm/coresight.txt
index c68d93a35b6c..f7ce8af48574 100644
--- a/Documentation/devicetree/bindings/arm/coresight.txt
+++ b/Documentation/devicetree/bindings/arm/coresight.txt
@@ -52,6 +52,10 @@ its hardware characteristcs.
"arm,coresight-cti", "arm,primecell";
See coresight-cti.yaml for full CTI definitions.
+ - Trace, Profiling and Diagnostics Monitor (TPDM):
+ "qcom,coresight-tpdm", "arm,primecell";
+ See coresight-tpdm.yaml for full TPDM definitions.
+
* reg: physical base address and length of the register
set(s) of the component.
@@ -82,6 +86,9 @@ its hardware characteristcs.
* Required properties for Coresight Cross Trigger Interface (CTI)
See coresight-cti.yaml for full CTI definitions.
+* Required properties for Trace, Profiling and Diagnostics Monitor (TPDM)
+ See coresight-tpdm.yaml for full TPDM definitions.
+
* Required properties for devices that don't show up on the AMBA bus, such as
non-configurable replicators and non-configurable funnels:
diff --git a/MAINTAINERS b/MAINTAINERS
index 59f39b3194f6..d763ba684b99 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15566,6 +15566,7 @@ M: Jinlong Mao <[email protected]>
M: Mathieu Poirier <[email protected]>
M: Suzuki K Poulose <[email protected]>
S: Maintained
+F: Documentation/devicetree/bindings/arm/coresight-tpdm.yaml
F: drivers/hwtracing/coresight/coresight-tpdm.c
QEMU MACHINE EMULATOR AND VIRTUALIZER SUPPORT
--
2.17.1
Integration test for tpdm can help to generate the data for
verification of the topology during TPDM software bring up.
Sample:
echo 1 > /sys/bus/coresight/devices/tmc_etf0/enable_sink
echo 1 > /sys/bus/coresight/devices/tpdm1/enable_source
echo 1 > /sys/bus/coresight/devices/tpdm1/integration_test
echo 2 > /sys/bus/coresight/devices/tpdm1/integration_test
cat /dev/tmc_etf0 > /data/etf-tpdm1.bin
Signed-off-by: Tao Zhang <[email protected]>
Signed-off-by: Mao Jinlong <[email protected]>
---
drivers/hwtracing/coresight/Kconfig | 9 ++++
drivers/hwtracing/coresight/coresight-tpdm.c | 54 ++++++++++++++++++++
drivers/hwtracing/coresight/coresight-tpdm.h | 8 +++
3 files changed, 71 insertions(+)
diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
index 5c506a1cd08f..60248fef4089 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -214,4 +214,13 @@ config CORESIGHT_TPDM
To compile this driver as a module, choose M here: the module will be
called coresight-tpdm.
+config CORESIGHT_TPDM_INTEGRATION_TEST
+ bool "Enable CoreSight Integration Test For TPDM"
+ depends on CORESIGHT_TPDM
+ help
+ This option adds support for the CoreSight integration test on this
+ devie. Coresight architecture provides integration control modes of
+ operation to facilitate integration testing and software bringup
+ and/or to instrument topology discovery. The TPDM utilizes integration
+ mode to accomplish integration testing and software bringup.
endif
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index c0dd216f70eb..891c3efaf30d 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -135,6 +135,59 @@ static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
CS_LOCK(drvdata->base);
}
+#ifdef CONFIG_CORESIGHT_TPDM_INTEGRATION_TEST
+static ssize_t integration_test_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t size)
+{
+ int i, ret = 0;
+ unsigned long val;
+ struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent);
+
+ ret = kstrtoul(buf, 10, &val);
+ if (ret)
+ return ret;
+
+ if (val != 1 && val != 2)
+ return -EINVAL;
+
+ if (!drvdata->enable)
+ return -EINVAL;
+
+ if (val == 1)
+ val = ATBCNTRL_VAL_64;
+ else
+ val = ATBCNTRL_VAL_32;
+ CS_UNLOCK(drvdata->base);
+ writel_relaxed(0x1, drvdata->base + TPDM_ITCNTRL);
+
+ for (i = 1; i < 5; i++)
+ writel_relaxed(val, drvdata->base + TPDM_ITATBCNTRL);
+
+ writel_relaxed(0, drvdata->base + TPDM_ITCNTRL);
+ CS_LOCK(drvdata->base);
+ return size;
+}
+static DEVICE_ATTR_WO(integration_test);
+#endif /* CORESIGHT_TPDM_INTEGRATION_TEST */
+
+static struct attribute *tpdm_attrs[] = {
+#ifdef CONFIG_CORESIGHT_TPDM_INTEGRATION_TEST
+ &dev_attr_integration_test.attr,
+#endif /* CORESIGHT_TPDM_INTEGRATION_TEST */
+ NULL,
+};
+
+static struct attribute_group tpdm_attr_grp = {
+ .attrs = tpdm_attrs,
+};
+
+static const struct attribute_group *tpdm_attr_grps[] = {
+ &tpdm_attr_grp,
+ NULL,
+};
+
static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
{
struct device *dev = &adev->dev;
@@ -167,6 +220,7 @@ static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
desc.ops = &tpdm_cs_ops;
desc.pdata = adev->dev.platform_data;
desc.dev = &adev->dev;
+ desc.groups = tpdm_attr_grps;
drvdata->csdev = coresight_register(&desc);
if (IS_ERR(drvdata->csdev))
return PTR_ERR(drvdata->csdev);
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index ba99c20e12bb..9929a26f0f0b 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -14,6 +14,14 @@
/* DSB Subunit Registers */
#define TPDM_DSB_CR (0x780)
+/* TPDM integration test registers */
+#define TPDM_ITATBCNTRL (0xEF0)
+#define TPDM_ITCNTRL (0xF00)
+
+/* Register value for integration test */
+#define ATBCNTRL_VAL_32 0xC00F1409
+#define ATBCNTRL_VAL_64 0xC01F1409
+
/**
* This enum is for PERIPHIDR0 register of TPDM.
* The fields [6:0] of PERIPHIDR0 are used to determine what
--
2.17.1
TPDM serves as data collection component for various dataset types.
DSB(Discrete Single Bit) is one of the dataset types. DSB subunit
can be enabled for data collection by writing 1 to the first bit of
DSB_CR register. This change is to add enable/disable function for
DSB dataset by writing DSB_CR register.
Signed-off-by: Tao Zhang <[email protected]>
Signed-off-by: Mao Jinlong <[email protected]>
---
drivers/hwtracing/coresight/coresight-tpdm.c | 56 ++++++++++++++++++++
drivers/hwtracing/coresight/coresight-tpdm.h | 23 ++++++++
2 files changed, 79 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index f494cef4fb24..c0dd216f70eb 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -20,6 +20,27 @@
DEFINE_CORESIGHT_DEVLIST(tpdm_devs, "tpdm");
+static void tpdm_enable_dsb(struct tpdm_drvdata *drvdata)
+{
+ u32 val;
+
+ /* Set the enable bit of DSB control register to 1 */
+ val = readl_relaxed(drvdata->base + TPDM_DSB_CR);
+ val = val | BIT(0);
+ writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
+}
+
+static void _tpdm_enable(struct tpdm_drvdata *drvdata)
+{
+ CS_UNLOCK(drvdata->base);
+
+ /* Check if DSB datasets is present for TPDM. */
+ if (test_bit(TPDM_DS_DSB, drvdata->datasets))
+ tpdm_enable_dsb(drvdata);
+
+ CS_LOCK(drvdata->base);
+}
+
static int tpdm_enable(struct coresight_device *csdev,
struct perf_event *event, u32 mode)
{
@@ -31,6 +52,7 @@ static int tpdm_enable(struct coresight_device *csdev,
return -EBUSY;
}
+ _tpdm_enable(drvdata);
drvdata->enable = true;
mutex_unlock(&drvdata->lock);
@@ -38,6 +60,28 @@ static int tpdm_enable(struct coresight_device *csdev,
return 0;
}
+static void tpdm_disable_dsb(struct tpdm_drvdata *drvdata)
+{
+ u32 val;
+
+ /* Set the enable bit of DSB control register to 0 */
+ val = readl_relaxed(drvdata->base + TPDM_DSB_CR);
+ val = val & ~BIT(0);
+ writel_relaxed(val, drvdata->base + TPDM_DSB_CR);
+}
+
+static void _tpdm_disable(struct tpdm_drvdata *drvdata)
+{
+ CS_UNLOCK(drvdata->base);
+
+ /* Check if DSB datasets is present for TPDM. */
+ if (test_bit(TPDM_DS_DSB, drvdata->datasets))
+ tpdm_disable_dsb(drvdata);
+
+ CS_LOCK(drvdata->base);
+
+}
+
static void tpdm_disable(struct coresight_device *csdev,
struct perf_event *event)
{
@@ -49,6 +93,7 @@ static void tpdm_disable(struct coresight_device *csdev,
return;
}
+ _tpdm_disable(drvdata);
drvdata->enable = false;
mutex_unlock(&drvdata->lock);
@@ -75,8 +120,19 @@ static const struct coresight_ops tpdm_cs_ops = {
static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
{
static int traceid = TPDM_TRACE_ID_START;
+ int i;
+ u32 pidr;
+ CS_UNLOCK(drvdata->base);
drvdata->traceid = traceid++;
+
+ /* Get the datasets present on the TPDM. */
+ pidr = readl_relaxed(drvdata->base + CORESIGHT_PERIPHIDR0);
+ for (i = 0; i < TPDM_DATASETS; i++) {
+ if (pidr & BIT(i))
+ __set_bit(i, drvdata->datasets);
+ }
+ CS_LOCK(drvdata->base);
}
static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
index 980ae90ff1c8..ba99c20e12bb 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.h
+++ b/drivers/hwtracing/coresight/coresight-tpdm.h
@@ -8,6 +8,27 @@
/* Default value of the traceid */
#define TPDM_TRACE_ID_START 128
+/* The max number of the datasets that TPDM supports */
+#define TPDM_DATASETS 7
+
+/* DSB Subunit Registers */
+#define TPDM_DSB_CR (0x780)
+
+/**
+ * This enum is for PERIPHIDR0 register of TPDM.
+ * The fields [6:0] of PERIPHIDR0 are used to determine what
+ * interfaces and subunits are present on a given TPDM.
+ *
+ * PERIPHIDR0[0] : Fix to 1 if ImplDef subunit present, else 0.
+ * No TPDM supports ImplDef subunit now. But
+ * the first bit of PERIPHIDR0 is for ImplDef
+ * subunit for initial design.
+ * PERIPHIDR0[1] : Fix to 1 if DSB subunit present, else 0.
+ */
+enum tpdm_dataset {
+ TPDM_DS_IMPLDEF,
+ TPDM_DS_DSB,
+};
/**
* struct tpdm_drvdata - specifics associated to an TPDM component
@@ -16,6 +37,7 @@
* @csdev: component vitals needed by the framework.
* @lock: lock for the enable value.
* @enable: enable status of the component.
+ * @datasets: The datasets types present of the TPDM.
* @traceid: value of the current ID for this component.
*/
@@ -25,6 +47,7 @@ struct tpdm_drvdata {
struct coresight_device *csdev;
struct mutex lock;
bool enable;
+ DECLARE_BITMAP(datasets, TPDM_DATASETS);
int traceid;
};
--
2.17.1
Add API usage document for sysfs API in TPDM driver.
Signed-off-by: Mao Jinlong <[email protected]>
---
.../ABI/testing/sysfs-bus-coresight-devices-tpdm | 12 ++++++++++++
MAINTAINERS | 1 +
2 files changed, 13 insertions(+)
create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
new file mode 100644
index 000000000000..fdd0bd0e1c33
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
@@ -0,0 +1,12 @@
+What: /sys/bus/coresight/devices/<tpdm-name>/available_datasets
+Date: December 2021
+KernelVersion 5.16
+Contact: Jinlong Mao or Tao Zhang
+Description: (Read) Show available datasets for TPDM.
+
+What: /sys/bus/coresight/devices/<tpdm-name>/integration_test
+Date: December 2020
+KernelVersion 5.16
+Contact: Jinlong Mao or Tao Zhang
+Description: (Write) Run integration test for tpdm.
+
diff --git a/MAINTAINERS b/MAINTAINERS
index d763ba684b99..7e2898f1550b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15566,6 +15566,7 @@ M: Jinlong Mao <[email protected]>
M: Mathieu Poirier <[email protected]>
M: Suzuki K Poulose <[email protected]>
S: Maintained
+F: Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
F: Documentation/devicetree/bindings/arm/coresight-tpdm.yaml
F: drivers/hwtracing/coresight/coresight-tpdm.c
--
2.17.1
TPDA(Trace, Profiling and Diagnostics Aggregator) is
to provide packetization, funneling and timestamping of
TPDM data. Multiple monitors are connected to different
input ports of TPDA.This change is to add tpda
enable/disable/probe functions for coresight tpda driver.
- - - - - - - - - - - -
| TPDM 0| | TPDM 1 | | TPDM 2|
- - - - - - - - - - - -
| | |
|_ _ _ _ _ _ | _ _ _ _ |
| | |
| | |
------------------
| TPDA |
------------------
|
|
------------------
| Trace Funnel |
------------------
Signed-off-by: Tao Zhang <[email protected]>
Signed-off-by: Mao Jinlong <[email protected]>
---
MAINTAINERS | 1 +
drivers/hwtracing/coresight/Kconfig | 11 +
drivers/hwtracing/coresight/Makefile | 1 +
drivers/hwtracing/coresight/coresight-tpda.c | 201 +++++++++++++++++++
drivers/hwtracing/coresight/coresight-tpda.h | 33 +++
5 files changed, 247 insertions(+)
create mode 100644 drivers/hwtracing/coresight/coresight-tpda.c
create mode 100644 drivers/hwtracing/coresight/coresight-tpda.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 7e2898f1550b..12e4e56a252c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15568,6 +15568,7 @@ M: Suzuki K Poulose <[email protected]>
S: Maintained
F: Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
F: Documentation/devicetree/bindings/arm/coresight-tpdm.yaml
+F: drivers/hwtracing/coresight/coresight-tpda.c
F: drivers/hwtracing/coresight/coresight-tpdm.c
QEMU MACHINE EMULATOR AND VIRTUALIZER SUPPORT
diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
index 60248fef4089..317c5e7f4819 100644
--- a/drivers/hwtracing/coresight/Kconfig
+++ b/drivers/hwtracing/coresight/Kconfig
@@ -223,4 +223,15 @@ config CORESIGHT_TPDM_INTEGRATION_TEST
operation to facilitate integration testing and software bringup
and/or to instrument topology discovery. The TPDM utilizes integration
mode to accomplish integration testing and software bringup.
+
+config CORESIGHT_TPDA
+ tristate "CoreSight Trace, Profiling & Diagnostics Aggregator driver"
+ help
+ This driver provides support for configuring aggregator. This is
+ primarily useful for pulling the data sets from one or more
+ attached monitors and pushing the resultant data out. Multiple
+ monitors are connected on different input ports of TPDA.
+
+ To compile this driver as a module, choose M here: the module will be
+ called coresight-tpda.
endif
diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
index e7392a0dddeb..cd8079ec276d 100644
--- a/drivers/hwtracing/coresight/Makefile
+++ b/drivers/hwtracing/coresight/Makefile
@@ -26,5 +26,6 @@ obj-$(CONFIG_CORESIGHT_CATU) += coresight-catu.o
obj-$(CONFIG_CORESIGHT_CTI) += coresight-cti.o
obj-$(CONFIG_CORESIGHT_TRBE) += coresight-trbe.o
obj-$(CONFIG_CORESIGHT_TPDM) += coresight-tpdm.o
+obj-$(CONFIG_CORESIGHT_TPDA) += coresight-tpda.o
coresight-cti-y := coresight-cti-core.o coresight-cti-platform.o \
coresight-cti-sysfs.o
diff --git a/drivers/hwtracing/coresight/coresight-tpda.c b/drivers/hwtracing/coresight/coresight-tpda.c
new file mode 100644
index 000000000000..e51624fac567
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-tpda.c
@@ -0,0 +1,201 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#include <linux/amba/bus.h>
+#include <linux/bitmap.h>
+#include <linux/coresight.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include "coresight-priv.h"
+#include "coresight-tpda.h"
+
+DEFINE_CORESIGHT_DEVLIST(tpda_devs, "tpda");
+
+/* Settings pre enabling port control register */
+static void tpda_enable_pre_port(struct tpda_drvdata *drvdata)
+{
+ u32 val;
+
+ val = readl_relaxed(drvdata->base + TPDA_CR);
+ val |= (drvdata->atid << 6);
+ writel_relaxed(val, drvdata->base + TPDA_CR);
+}
+
+static void tpda_enable_port(struct tpda_drvdata *drvdata, int port)
+{
+ u32 val;
+
+ val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
+ /* Enable the port */
+ val = val | BIT(0);
+ writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
+}
+
+/* Settings post enabling port control register */
+static void tpda_enable_post_port(struct tpda_drvdata *drvdata)
+{
+ u32 val;
+
+ val = readl_relaxed(drvdata->base + TPDA_SYNCR);
+ /* Clear the mode */
+ val = val & ~BIT(12);
+ /* Program the counter value */
+ val = val | 0xFFF;
+ writel_relaxed(val, drvdata->base + TPDA_SYNCR);
+}
+
+static void _tpda_enable(struct tpda_drvdata *drvdata, int port)
+{
+ CS_UNLOCK(drvdata->base);
+
+ if (!drvdata->enable)
+ tpda_enable_pre_port(drvdata);
+
+ tpda_enable_port(drvdata, port);
+
+ if (!drvdata->enable)
+ tpda_enable_post_port(drvdata);
+
+ CS_LOCK(drvdata->base);
+}
+
+static int tpda_enable(struct coresight_device *csdev, int inport, int outport)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+ mutex_lock(&drvdata->lock);
+ _tpda_enable(drvdata, inport);
+ drvdata->enable = true;
+ mutex_unlock(&drvdata->lock);
+
+ dev_info(drvdata->dev, "TPDA inport %d enabled\n", inport);
+ return 0;
+}
+
+static void _tpda_disable(struct tpda_drvdata *drvdata, int port)
+{
+ u32 val;
+
+ CS_UNLOCK(drvdata->base);
+
+ val = readl_relaxed(drvdata->base + TPDA_Pn_CR(port));
+ val = val & ~BIT(0);
+ writel_relaxed(val, drvdata->base + TPDA_Pn_CR(port));
+
+ CS_LOCK(drvdata->base);
+}
+
+static void tpda_disable(struct coresight_device *csdev, int inport,
+ int outport)
+{
+ struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
+
+ mutex_lock(&drvdata->lock);
+ _tpda_disable(drvdata, inport);
+ drvdata->enable = false;
+ mutex_unlock(&drvdata->lock);
+
+ dev_info(drvdata->dev, "TPDA inport %d disabled\n", inport);
+}
+
+static const struct coresight_ops_link tpda_link_ops = {
+ .enable = tpda_enable,
+ .disable = tpda_disable,
+};
+
+static const struct coresight_ops tpda_cs_ops = {
+ .link_ops = &tpda_link_ops,
+};
+
+static int tpda_parse_of_data(struct tpda_drvdata *drvdata)
+{
+ int ret;
+ struct device_node *node = drvdata->dev->of_node;
+
+ ret = of_property_read_u32(node, "qcom,tpda-atid", &drvdata->atid);
+ if (ret) {
+ dev_err(drvdata->dev, "TPDA ATID is not specified\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int tpda_probe(struct amba_device *adev, const struct amba_id *id)
+{
+ int ret;
+ struct device *dev = &adev->dev;
+ struct coresight_platform_data *pdata;
+ struct tpda_drvdata *drvdata;
+ struct coresight_desc desc = { 0 };
+
+ desc.name = coresight_alloc_device_name(&tpda_devs, dev);
+ if (!desc.name)
+ return -ENOMEM;
+ pdata = coresight_get_platform_data(dev);
+ if (IS_ERR(pdata))
+ return PTR_ERR(pdata);
+ adev->dev.platform_data = pdata;
+
+ drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
+ if (!drvdata)
+ return -ENOMEM;
+
+ drvdata->dev = &adev->dev;
+ dev_set_drvdata(dev, drvdata);
+
+ drvdata->base = devm_ioremap_resource(dev, &adev->res);
+ if (!drvdata->base)
+ return -ENOMEM;
+
+ mutex_init(&drvdata->lock);
+
+ ret = tpda_parse_of_data(drvdata);
+ if (ret)
+ return ret;
+
+ desc.type = CORESIGHT_DEV_TYPE_LINK;
+ desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_MERG;
+ desc.ops = &tpda_cs_ops;
+ desc.pdata = adev->dev.platform_data;
+ desc.dev = &adev->dev;
+ drvdata->csdev = coresight_register(&desc);
+ if (IS_ERR(drvdata->csdev))
+ return PTR_ERR(drvdata->csdev);
+
+ pm_runtime_put(&adev->dev);
+
+ dev_dbg(drvdata->dev, "TPDA initialized\n");
+ return 0;
+}
+
+static struct amba_id tpda_ids[] = {
+ {
+ .id = 0x000f0f00,
+ .mask = 0x000fff00,
+ },
+ { 0, 0},
+};
+
+static struct amba_driver tpda_driver = {
+ .drv = {
+ .name = "coresight-tpda",
+ .owner = THIS_MODULE,
+ .suppress_bind_attrs = true,
+ },
+ .probe = tpda_probe,
+ .id_table = tpda_ids,
+};
+
+module_amba_driver(tpda_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Aggregator driver");
diff --git a/drivers/hwtracing/coresight/coresight-tpda.h b/drivers/hwtracing/coresight/coresight-tpda.h
new file mode 100644
index 000000000000..35723571ea13
--- /dev/null
+++ b/drivers/hwtracing/coresight/coresight-tpda.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+#ifndef _CORESIGHT_CORESIGHT_TPDA_H
+#define _CORESIGHT_CORESIGHT_TPDA_H
+
+#define TPDA_CR (0x000)
+#define TPDA_Pn_CR(n) (0x004 + (n * 4))
+#define TPDA_SYNCR (0x08C)
+
+#define TPDA_MAX_INPORTS 32
+
+/**
+ * struct tpda_drvdata - specifics associated to an TPDA component
+ * @base: memory mapped base address for this component.
+ * @dev: The device entity associated to this component.
+ * @csdev: component vitals needed by the framework.
+ * @lock: lock for the enable value.
+ * @enable: enable status of the component.
+ * @traceid: trace source identification for the data packet by TPDA.
+ */
+struct tpda_drvdata {
+ void __iomem *base;
+ struct device *dev;
+ struct coresight_device *csdev;
+ struct mutex lock;
+ bool enable;
+ u32 atid;
+};
+
+#endif /* _CORESIGHT_CORESIGHT_TPDA_H */
--
2.17.1
Add coresight device tree for sm8250. STM/ETM/TPDM are added.
Signed-off-by: Tao Zhang <[email protected]>
Signed-off-by: Mao Jinlong <[email protected]>
---
MAINTAINERS | 1 +
.../arm64/boot/dts/qcom/sm8250-coresight.dtsi | 688 ++++++++++++++++++
arch/arm64/boot/dts/qcom/sm8250.dtsi | 2 +
3 files changed, 691 insertions(+)
create mode 100644 arch/arm64/boot/dts/qcom/sm8250-coresight.dtsi
diff --git a/MAINTAINERS b/MAINTAINERS
index d3b7ce75ba9d..e1db5a839f2f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15566,6 +15566,7 @@ M: Jinlong Mao <[email protected]>
M: Mathieu Poirier <[email protected]>
M: Suzuki K Poulose <[email protected]>
S: Maintained
+F: arch/arm64/boot/dts/qcom/*-coresight.dtsi
F: Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
F: Documentation/devicetree/bindings/arm/coresight-tpda.yaml
F: Documentation/devicetree/bindings/arm/coresight-tpdm.yaml
diff --git a/arch/arm64/boot/dts/qcom/sm8250-coresight.dtsi b/arch/arm64/boot/dts/qcom/sm8250-coresight.dtsi
new file mode 100644
index 000000000000..e9d65c6acbd1
--- /dev/null
+++ b/arch/arm64/boot/dts/qcom/sm8250-coresight.dtsi
@@ -0,0 +1,688 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+ */
+
+&soc {
+
+ stm@6002000 {
+ compatible = "arm,coresight-stm", "arm,primecell";
+ reg = <0 0x06002000 0 0x1000>,
+ <0 0x16280000 0 0x180000>;
+ reg-names = "stm-base", "stm-stimulus-base";
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ stm_out: endpoint {
+ remote-endpoint =
+ <&funnel0_in7>;
+ };
+ };
+ };
+ };
+
+ tpda@6004000 {
+ compatible = "arm,primecell";
+ reg = <0 0x6004000 0 0x1000>;
+ reg-names = "tpda-base";
+
+ qcom,tpda-atid = <65>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ tpda_out_funnel_qatb: endpoint {
+ remote-endpoint =
+ <&funnel_qatb_in_tpda>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@9 {
+ reg = <9>;
+ tpda_9_in_tpdm_mm: endpoint {
+ remote-endpoint =
+ <&tpdm_mm_out_tpda9>;
+ };
+ };
+ };
+ };
+
+ funnel@6005000 {
+ compatible = "arm,primecell";
+
+ reg = <0 0x6005000 0 0x1000>;
+ reg-names = "funnel-base";
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ funnel_qatb_out_funnel_in0: endpoint {
+ remote-endpoint =
+ <&funnel_in0_in_funnel_qatb>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ funnel_qatb_in_tpda: endpoint {
+ remote-endpoint =
+ <&tpda_out_funnel_qatb>;
+ };
+ };
+ };
+ };
+
+ funnel@6041000 {
+ compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+ reg = <0 0x06041000 0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ funnel0_out: endpoint {
+ remote-endpoint =
+ <&merge_funnel_in0>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@6 {
+ reg = <6>;
+ funnel_in0_in_funnel_qatb: endpoint {
+ remote-endpoint =
+ <&funnel_qatb_out_funnel_in0>;
+ };
+ };
+
+ port@7 {
+ reg = <7>;
+ funnel0_in7: endpoint {
+ remote-endpoint = <&stm_out>;
+ };
+ };
+ };
+ };
+
+ funnel@6042000 {
+ compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+ reg = <0 0x06042000 0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ funnel2_out: endpoint {
+ remote-endpoint =
+ <&merge_funnel_in1>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@4 {
+ reg = <4>;
+ funnel2_in4: endpoint {
+ remote-endpoint =
+ <&apss_merge_funnel_out>;
+ };
+ };
+ };
+ };
+
+ funnel@6045000 {
+ compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+ reg = <0 0x06045000 0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ funnel_merg_out_funnel_swao: endpoint {
+ remote-endpoint = <&funnel_swao_in_funnel_merg>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ merge_funnel_in0: endpoint {
+ remote-endpoint =
+ <&funnel0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ merge_funnel_in1: endpoint {
+ remote-endpoint =
+ <&funnel2_out>;
+ };
+ };
+ };
+ };
+
+ replicator@6046000 {
+ compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+ reg = <0 0x06046000 0 0x1000>;
+
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ replicator_out: endpoint {
+ remote-endpoint = <&etr_in>;
+ };
+ };
+ };
+
+ in-ports {
+ port {
+ replicator_cx_in_swao_out: endpoint {
+ remote-endpoint = <&replicator_swao_out_cx_in>;
+ };
+ };
+ };
+ };
+
+ etr@6048000 {
+ compatible = "arm,coresight-tmc", "arm,primecell";
+ reg = <0 0x06048000 0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,scatter-gather;
+
+ in-ports {
+ port {
+ etr_in: endpoint {
+ remote-endpoint =
+ <&replicator_out>;
+ };
+ };
+ };
+ };
+
+ funnel@6b04000 {
+ compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+ arm,primecell-periphid = <0x000bb908>;
+
+ reg = <0 0x6b04000 0 0x1000>;
+ reg-names = "funnel-base";
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ merge_funnel_out: endpoint {
+ remote-endpoint =
+ <&etf_in>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@7 {
+ reg = <7>;
+ funnel_swao_in_funnel_merg: endpoint {
+ remote-endpoint=
+ <&funnel_merg_out_funnel_swao>;
+ };
+ };
+ };
+
+ };
+
+ etf@6b05000 {
+ compatible = "arm,coresight-tmc", "arm,primecell";
+ reg = <0 0x6b05000 0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ etf_out: endpoint {
+ remote-endpoint =
+ <&replicator_in>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ etf_in: endpoint {
+ remote-endpoint =
+ <&merge_funnel_out>;
+ };
+ };
+ };
+ };
+
+ replicator@6b06000 {
+ compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+ reg = <0 0x06b06000 0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ replicator_swao_out_cx_in: endpoint {
+ remote-endpoint = <&replicator_cx_in_swao_out>;
+ };
+ };
+ };
+
+ in-ports {
+ port {
+ replicator_in: endpoint {
+ remote-endpoint = <&etf_out>;
+ };
+ };
+ };
+ };
+
+
+ tpdm_mm: mm.tpdm@6c08000 {
+ compatible = "arm,primecell";
+ reg = <0 0x6c08000 0 0x1000>;
+ reg-names = "tpdm-base";
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ qcom,msr-fix-req;
+
+ out-ports {
+ port {
+ tpdm_mm_out_funnel_dl_mm: endpoint {
+ remote-endpoint =
+ <&funnel_dl_mm_in_tpdm_mm>;
+ };
+ };
+ };
+ };
+
+ funnel@6c0b000 {
+ compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+
+ reg = <0 0x6c0b000 0 0x1000>;
+ reg-names = "funnel-base";
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ funnel_dl_mm_out_funnel_dl_center: endpoint {
+ remote-endpoint =
+ <&funnel_dl_center_in_funnel_dl_mm>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@3 {
+ reg = <3>;
+ funnel_dl_mm_in_tpdm_mm: endpoint {
+ remote-endpoint =
+ <&tpdm_mm_out_funnel_dl_mm>;
+ };
+ };
+ };
+ };
+
+ funnel@6c2d000 {
+ compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+
+ reg = <0 0x6c2d000 0 0x1000>;
+ reg-names = "funnel-base";
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port {
+ tpdm_mm_out_tpda9: endpoint {
+ remote-endpoint =
+ <&tpda_9_in_tpdm_mm>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@2 {
+ reg = <2>;
+ funnel_dl_center_in_funnel_dl_mm: endpoint {
+ remote-endpoint =
+ <&funnel_dl_mm_out_funnel_dl_center>;
+ };
+ };
+ };
+ };
+
+ etm@7040000 {
+ compatible = "arm,coresight-etm4x", "arm,primecell";
+ reg = <0 0x07040000 0 0x1000>;
+
+ cpu = <&CPU0>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,coresight-loses-context-with-cpu;
+
+ out-ports {
+ port {
+ etm0_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel_in0>;
+ };
+ };
+ };
+ };
+
+ etm@7140000 {
+ compatible = "arm,coresight-etm4x", "arm,primecell";
+ reg = <0 0x07140000 0 0x1000>;
+
+ cpu = <&CPU1>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,coresight-loses-context-with-cpu;
+
+ out-ports {
+ port {
+ etm1_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel_in1>;
+ };
+ };
+ };
+ };
+
+ etm@7240000 {
+ compatible = "arm,coresight-etm4x", "arm,primecell";
+ reg = <0 0x07240000 0 0x1000>;
+
+ cpu = <&CPU2>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,coresight-loses-context-with-cpu;
+
+ out-ports {
+ port {
+ etm2_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel_in2>;
+ };
+ };
+ };
+ };
+
+ etm@7340000 {
+ compatible = "arm,coresight-etm4x", "arm,primecell";
+ reg = <0 0x07340000 0 0x1000>;
+
+ cpu = <&CPU3>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,coresight-loses-context-with-cpu;
+
+ out-ports {
+ port {
+ etm3_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel_in3>;
+ };
+ };
+ };
+ };
+
+ etm@7440000 {
+ compatible = "arm,coresight-etm4x", "arm,primecell";
+ reg = <0 0x07440000 0 0x1000>;
+
+ cpu = <&CPU4>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,coresight-loses-context-with-cpu;
+
+ out-ports {
+ port {
+ etm4_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel_in4>;
+ };
+ };
+ };
+ };
+
+ etm@7540000 {
+ compatible = "arm,coresight-etm4x", "arm,primecell";
+ reg = <0 0x07540000 0 0x1000>;
+
+ cpu = <&CPU5>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,coresight-loses-context-with-cpu;
+
+ out-ports {
+ port {
+ etm5_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel_in5>;
+ };
+ };
+ };
+ };
+
+ etm@7640000 {
+ compatible = "arm,coresight-etm4x", "arm,primecell";
+ reg = <0 0x07640000 0 0x1000>;
+
+ cpu = <&CPU6>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,coresight-loses-context-with-cpu;
+
+ out-ports {
+ port {
+ etm6_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel_in6>;
+ };
+ };
+ };
+ };
+
+ etm@7740000 {
+ compatible = "arm,coresight-etm4x", "arm,primecell";
+ reg = <0 0x07740000 0 0x1000>;
+
+ cpu = <&CPU7>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+ arm,coresight-loses-context-with-cpu;
+
+ out-ports {
+ port {
+ etm7_out: endpoint {
+ remote-endpoint =
+ <&apss_funnel_in7>;
+ };
+ };
+ };
+ };
+
+ funnel@7800000 {
+ compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+ reg = <0 0x07800000 0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ apss_funnel_out: endpoint {
+ remote-endpoint =
+ <&apss_merge_funnel_in>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ apss_funnel_in0: endpoint {
+ remote-endpoint =
+ <&etm0_out>;
+ };
+ };
+
+ port@1 {
+ reg = <1>;
+ apss_funnel_in1: endpoint {
+ remote-endpoint =
+ <&etm1_out>;
+ };
+ };
+
+ port@2 {
+ reg = <2>;
+ apss_funnel_in2: endpoint {
+ remote-endpoint =
+ <&etm2_out>;
+ };
+ };
+
+ port@3 {
+ reg = <3>;
+ apss_funnel_in3: endpoint {
+ remote-endpoint =
+ <&etm3_out>;
+ };
+ };
+
+ port@4 {
+ reg = <4>;
+ apss_funnel_in4: endpoint {
+ remote-endpoint =
+ <&etm4_out>;
+ };
+ };
+
+ port@5 {
+ reg = <5>;
+ apss_funnel_in5: endpoint {
+ remote-endpoint =
+ <&etm5_out>;
+ };
+ };
+
+ port@6 {
+ reg = <6>;
+ apss_funnel_in6: endpoint {
+ remote-endpoint =
+ <&etm6_out>;
+ };
+ };
+
+ port@7 {
+ reg = <7>;
+ apss_funnel_in7: endpoint {
+ remote-endpoint =
+ <&etm7_out>;
+ };
+ };
+ };
+ };
+
+ funnel@7810000 {
+ compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+ reg = <0 0x07810000 0 0x1000>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ out-ports {
+ port {
+ apss_merge_funnel_out: endpoint {
+ remote-endpoint =
+ <&funnel2_in4>;
+ };
+ };
+ };
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ port@0 {
+ reg = <0>;
+ apss_merge_funnel_in: endpoint {
+ remote-endpoint =
+ <&apss_funnel_out>;
+ };
+ };
+ };
+ };
+};
diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
index 6f6129b39c9c..0390919cc4f1 100644
--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
@@ -4853,3 +4853,5 @@
};
};
};
+
+#include "sm8250-coresight.dtsi"
--
2.17.1
Adds new coresight-tpda.yaml file describing the bindings required
to define tpda in the device trees.
Signed-off-by: Tao Zhang <[email protected]>
Signed-off-by: Mao Jinlong <[email protected]>
---
.../bindings/arm/coresight-tpda.yaml | 131 ++++++++++++++++++
MAINTAINERS | 1 +
2 files changed, 132 insertions(+)
create mode 100644 Documentation/devicetree/bindings/arm/coresight-tpda.yaml
diff --git a/Documentation/devicetree/bindings/arm/coresight-tpda.yaml b/Documentation/devicetree/bindings/arm/coresight-tpda.yaml
new file mode 100644
index 000000000000..4ce8c81a109a
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/coresight-tpda.yaml
@@ -0,0 +1,131 @@
+# SPDX-License-Identifier: GPL-2.0-only or BSD-2-Clause
+# Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/coresight-tpda.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Trace, Profiling and Diagnostics Aggregator - TPDA
+
+description: |
+ TPDAs are responsible for packetization and timestamping of data sets
+ utilizing the MIPI STPv2 packet protocol. Pulling data sets from one or
+ more attached TPDM and pushing the resultant (packetized) data out a
+ master ATB interface. Performing an arbitrated ATB interleaving (funneling)
+ task for free-flowing data from TPDM (i.e. CMB and DSB data set flows).
+
+maintainers:
+ - Tao Zhang <[email protected]>
+ - Mao Jinlong <[email protected]>
+ - Suzuki K Poulose <[email protected]>
+ - Mathieu Poirier <[email protected]>
+
+properties:
+ $nodename:
+ pattern: "^tpda(@[0-9a-f]+)$"
+ compatible:
+ items:
+ - const: qcom,coresight-tpda
+ - const: arm,primecell
+
+ reg:
+ maxItems: 1
+
+ qcom,tpda-atid:
+ $ref: /schemas/types.yaml#/definitions/uint32-array
+ maxItems: 1
+ description: |
+ Use the ATID field for trace source identification. This allows
+ multiple TPDMs to be interleaved and formatted via the Coresight
+ trace formatter framing protocol and de-formatted/parsed on a host
+ or debugger.
+
+ clocks:
+ maxItems: 1
+
+ clock-names:
+ items:
+ - const: apb_pclk
+
+ in-ports:
+ type: object
+ description: |
+ Input connections from TPDM to TPDA
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ '#address-cells':
+ const: 1
+
+ '#size-cells':
+ const: 0
+
+ patternProperties:
+ "^port@[0-9a-f]+$":
+ type: object
+ required:
+ - reg
+
+ required:
+ - '#size-cells'
+ - '#address-cells'
+
+ out-ports:
+ type: object
+ description: |
+ Output connections from the TPDA to legacy CoreSight trace bus.
+ $ref: /schemas/graph.yaml#/properties/ports
+
+ properties:
+ port:
+ description:
+ Output connection from the TPDA to legacy CoreSight Trace bus.
+ $ref: /schemas/graph.yaml#/properties/port
+
+required:
+ - compatible
+ - reg
+ - qcom,tpda-atid
+ - clocks
+ - clock-names
+ - in-ports
+ - out-ports
+
+additionalProperties: false
+
+examples:
+ # minimum tpda definition.
+ - |
+ tpda@6004000 {
+ compatible = "qcom,coresight-tpda", "arm,primecell";
+ reg = <0x6004000 0x1000>;
+
+ qcom,tpda-atid = <65>;
+
+ clocks = <&aoss_qmp>;
+ clock-names = "apb_pclk";
+
+ in-ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@0 {
+ reg = <0>;
+ tpda_qdss_0_in_tpdm_dcc: endpoint {
+ remote-endpoint =
+ <&tpdm_dcc_out_tpda_qdss_0>;
+ };
+ };
+ };
+
+ out-ports {
+ port {
+ tpda_qdss_out_funnel_in0: endpoint {
+ remote-endpoint =
+ <&funnel_in0_in_tpda_qdss>;
+ };
+ };
+ };
+ };
+
+...
diff --git a/MAINTAINERS b/MAINTAINERS
index 12e4e56a252c..d3b7ce75ba9d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -15567,6 +15567,7 @@ M: Mathieu Poirier <[email protected]>
M: Suzuki K Poulose <[email protected]>
S: Maintained
F: Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
+F: Documentation/devicetree/bindings/arm/coresight-tpda.yaml
F: Documentation/devicetree/bindings/arm/coresight-tpdm.yaml
F: drivers/hwtracing/coresight/coresight-tpda.c
F: drivers/hwtracing/coresight/coresight-tpdm.c
--
2.17.1
On 12/9/2021 10:15 PM, Mao Jinlong wrote:
> Add API usage document for sysfs API in TPDM driver.
>
> Signed-off-by: Mao Jinlong <[email protected]>
> ---
> .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 12 ++++++++++++
> MAINTAINERS | 1 +
> 2 files changed, 13 insertions(+)
> create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> new file mode 100644
> index 000000000000..fdd0bd0e1c33
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> @@ -0,0 +1,12 @@
> +What: /sys/bus/coresight/devices/<tpdm-name>/available_datasets
> +Date: December 2021
> +KernelVersion 5.16
> +Contact: Jinlong Mao or Tao Zhang
> +Description: (Read) Show available datasets for TPDM.
Sorry, forgot to remove the document of available_datasets.
Please help to review first. I will update in next version.
> +
> +What: /sys/bus/coresight/devices/<tpdm-name>/integration_test
> +Date: December 2020
> +KernelVersion 5.16
> +Contact: Jinlong Mao or Tao Zhang
> +Description: (Write) Run integration test for tpdm.
> +
> diff --git a/MAINTAINERS b/MAINTAINERS
> index d763ba684b99..7e2898f1550b 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -15566,6 +15566,7 @@ M: Jinlong Mao <[email protected]>
> M: Mathieu Poirier <[email protected]>
> M: Suzuki K Poulose <[email protected]>
> S: Maintained
> +F: Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> F: Documentation/devicetree/bindings/arm/coresight-tpdm.yaml
> F: drivers/hwtracing/coresight/coresight-tpdm.c
>
Hello Jinlong,
On 12/9/2021 6:15 AM, Mao Jinlong wrote:
> Add API usage document for sysfs API in TPDM driver.
>
> Signed-off-by: Mao Jinlong <[email protected]>
> ---
> .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 12 ++++++++++++
> MAINTAINERS | 1 +
> 2 files changed, 13 insertions(+)
> create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> new file mode 100644
> index 000000000000..fdd0bd0e1c33
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> @@ -0,0 +1,12 @@
> +What: /sys/bus/coresight/devices/<tpdm-name>/available_datasets
> +Date: December 2021
> +KernelVersion 5.16
> +Contact: Jinlong Mao or Tao Zhang
Just keep one name? I am not sure if we are adding multiple names for
other files.
> +Description: (Read) Show available datasets for TPDM.
> +
> +What: /sys/bus/coresight/devices/<tpdm-name>/integration_test
> +Date: December 2020
>
December 2021?
Hi Trilok,
Thanks for the review.
On 12/10/2021 2:34 AM, Trilok Soni wrote:
>
> Hello Jinlong,
>
> On 12/9/2021 6:15 AM, Mao Jinlong wrote:
>> Add API usage document for sysfs API in TPDM driver.
>>
>> Signed-off-by: Mao Jinlong <[email protected]>
>> ---
>> .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 12 ++++++++++++
>> MAINTAINERS | 1 +
>> 2 files changed, 13 insertions(+)
>> create mode 100644
>> Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>>
>> diff --git
>> a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>> b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>> new file mode 100644
>> index 000000000000..fdd0bd0e1c33
>> --- /dev/null
>> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>> @@ -0,0 +1,12 @@
>> +What: /sys/bus/coresight/devices/<tpdm-name>/available_datasets
>> +Date: December 2021
>> +KernelVersion 5.16
>> +Contact: Jinlong Mao or Tao Zhang
>
> Just keep one name? I am not sure if we are adding multiple names for
> other files.
Yes. available_datasets need to be removed here as there is no changes
for available_dataset.
I forgot to remove it after removing he available_dataset changes. I
will update in next version.
>
>> +Description: (Read) Show available datasets for TPDM.
>> +
>> +What: /sys/bus/coresight/devices/<tpdm-name>/integration_test
>> +Date: December 2020
>>
>
> December 2021?
I will update it.
Hi Mao,
On Thu, Dec 09, 2021 at 10:15:35PM +0800, Mao Jinlong wrote:
> Use hash length of the source's device name to map to the pointer
> of the enabled path. Using IDR will be more efficient than using
> the list. And there could be other sources except STM and CPU etms
> in the new HWs. It is better to maintain all the paths together.
>
> Signed-off-by: Mao Jinlong <[email protected]>
> ---
> drivers/hwtracing/coresight/coresight-core.c | 76 +++++++-------------
> 1 file changed, 26 insertions(+), 50 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
> index 8a18c71df37a..cc6b6cabf85f 100644
> --- a/drivers/hwtracing/coresight/coresight-core.c
> +++ b/drivers/hwtracing/coresight/coresight-core.c
> @@ -7,6 +7,7 @@
> #include <linux/init.h>
> #include <linux/types.h>
> #include <linux/device.h>
> +#include <linux/idr.h>
> #include <linux/io.h>
> #include <linux/err.h>
> #include <linux/export.h>
> @@ -26,6 +27,12 @@
> static DEFINE_MUTEX(coresight_mutex);
> static DEFINE_PER_CPU(struct coresight_device *, csdev_sink);
>
> +/*
> + * Use IDR to map the hash length of the source's device name
> + * to the pointer of path for the source
> + */
> +static DEFINE_IDR(path_idr);
> +
> /**
> * struct coresight_node - elements of a path, from source to sink
> * @csdev: Address of an element.
> @@ -36,20 +43,6 @@ struct coresight_node {
> struct list_head link;
> };
>
> -/*
> - * When operating Coresight drivers from the sysFS interface, only a single
> - * path can exist from a tracer (associated to a CPU) to a sink.
> - */
> -static DEFINE_PER_CPU(struct list_head *, tracer_path);
> -
> -/*
> - * As of this writing only a single STM can be found in CS topologies. Since
> - * there is no way to know if we'll ever see more and what kind of
> - * configuration they will enact, for the time being only define a single path
> - * for STM.
> - */
> -static struct list_head *stm_path;
> -
> /*
> * When losing synchronisation a new barrier packet needs to be inserted at the
> * beginning of the data collected in a buffer. That way the decoder knows that
> @@ -1088,10 +1081,11 @@ static int coresight_validate_source(struct coresight_device *csdev,
>
> int coresight_enable(struct coresight_device *csdev)
> {
> - int cpu, ret = 0;
> + int ret = 0;
> struct coresight_device *sink;
> struct list_head *path;
> enum coresight_dev_subtype_source subtype;
> + u32 hash;
>
> subtype = csdev->subtype.source_subtype;
>
> @@ -1133,26 +1127,14 @@ int coresight_enable(struct coresight_device *csdev)
> if (ret)
> goto err_source;
>
> - switch (subtype) {
> - case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
> - /*
> - * When working from sysFS it is important to keep track
> - * of the paths that were created so that they can be
> - * undone in 'coresight_disable()'. Since there can only
> - * be a single session per tracer (when working from sysFS)
> - * a per-cpu variable will do just fine.
> - */
> - cpu = source_ops(csdev)->cpu_id(csdev);
> - per_cpu(tracer_path, cpu) = path;
> - break;
> - case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
> - stm_path = path;
> - break;
> - default:
> - /* We can't be here */
> - break;
> - }
> -
> + /*
> + * Use the hash length of source's device name as ID
> + * and map the ID to the pointer of the path.
> + */
> + hash = hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev)));
> + ret = idr_alloc_u32(&path_idr, path, &hash, hash, GFP_KERNEL);
> + if (ret)
> + goto err_source;
> out:
> mutex_unlock(&coresight_mutex);
> return ret;
> @@ -1168,8 +1150,9 @@ EXPORT_SYMBOL_GPL(coresight_enable);
>
> void coresight_disable(struct coresight_device *csdev)
> {
> - int cpu, ret;
> + int ret;
> struct list_head *path = NULL;
> + u32 hash;
>
> mutex_lock(&coresight_mutex);
>
> @@ -1180,21 +1163,13 @@ void coresight_disable(struct coresight_device *csdev)
> if (!csdev->enable || !coresight_disable_source(csdev))
> goto out;
>
> - switch (csdev->subtype.source_subtype) {
> - case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
> - cpu = source_ops(csdev)->cpu_id(csdev);
> - path = per_cpu(tracer_path, cpu);
> - per_cpu(tracer_path, cpu) = NULL;
> - break;
> - case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
> - path = stm_path;
> - stm_path = NULL;
> - break;
> - default:
> - /* We can't be here */
> - break;
> - }
> + hash = hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev)));
> + /* Find the path by the hash length. */
> + path = idr_find(&path_idr, hash);
> + if (path == NULL)
> + return;
Please add a dev_err() here as this should really not be happening.
>
> + idr_remove(&path_idr, hash);
> coresight_disable_path(path);
> coresight_release_path(path);
>
> @@ -1779,6 +1754,7 @@ static int __init coresight_init(void)
>
> static void __exit coresight_exit(void)
> {
> + idr_destroy(&path_idr);
As far as I can tell this isn't needed.
> cscfg_exit();
> etm_perf_exit();
> bus_unregister(&coresight_bustype);
> --
> 2.17.1
>
On Thu, Dec 09, 2021 at 10:15:36PM +0800, Mao Jinlong wrote:
> Add driver to support Coresight device TPDM (Trace, Profiling and
> Diagnostics Monitor). TPDM is a monitor to collect data from
> different datasets. This change is to add probe/enable/disable
> functions for tpdm source.
>
> Signed-off-by: Tao Zhang <[email protected]>
> Signed-off-by: Mao Jinlong <[email protected]>
> ---
> MAINTAINERS | 8 +
> drivers/hwtracing/coresight/Kconfig | 13 ++
> drivers/hwtracing/coresight/Makefile | 1 +
> drivers/hwtracing/coresight/coresight-core.c | 3 +-
> drivers/hwtracing/coresight/coresight-tpdm.c | 152 +++++++++++++++++++
> drivers/hwtracing/coresight/coresight-tpdm.h | 31 ++++
> include/linux/coresight.h | 1 +
> 7 files changed, 208 insertions(+), 1 deletion(-)
> create mode 100644 drivers/hwtracing/coresight/coresight-tpdm.c
> create mode 100644 drivers/hwtracing/coresight/coresight-tpdm.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 7a2345ce8521..59f39b3194f6 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -15560,6 +15560,14 @@ L: [email protected]
> S: Supported
> F: drivers/net/ipa/
>
> +QCOM CORESIGHT COMPONENTS DRIVER
> +M: Tao Zhang <[email protected]>
> +M: Jinlong Mao <[email protected]>
> +M: Mathieu Poirier <[email protected]>
> +M: Suzuki K Poulose <[email protected]>
> +S: Maintained
> +F: drivers/hwtracing/coresight/coresight-tpdm.c
> +
There is no need for an extra entry in the MAINTAINERS file. The checkpatch.pl
script is smart enough to know when to CC you and Tao every time the TPDM/TPDA
drivers are modified. Suzuki and I will simply wait for you guys to add your RB
tags before reviewing the patches. I have explained this in the previous revision.
> QEMU MACHINE EMULATOR AND VIRTUALIZER SUPPORT
> M: Gabriel Somlo <[email protected]>
> M: "Michael S. Tsirkin" <[email protected]>
> diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
> index 514a9b8086e3..5c506a1cd08f 100644
> --- a/drivers/hwtracing/coresight/Kconfig
> +++ b/drivers/hwtracing/coresight/Kconfig
> @@ -201,4 +201,17 @@ config CORESIGHT_TRBE
>
> To compile this driver as a module, choose M here: the module will be
> called coresight-trbe.
> +
> +config CORESIGHT_TPDM
> + tristate "CoreSight Trace, Profiling & Diagnostics Monitor driver"
> + select CORESIGHT_LINKS_AND_SINKS
Is this available on 32bit HW as well? If not please make it dependent on ARM64
as it for ETMv4x devices.
> + help
> + This driver provides support for configuring monitor. Monitors are
> + primarily responsible for data set collection and support the
> + ability to collect any permutation of data set types. Monitors are
> + also responsible for interaction with system cross triggering.
> +
> + To compile this driver as a module, choose M here: the module will be
> + called coresight-tpdm.
> +
> endif
> diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
> index b6c4a48140ec..e7392a0dddeb 100644
> --- a/drivers/hwtracing/coresight/Makefile
> +++ b/drivers/hwtracing/coresight/Makefile
> @@ -25,5 +25,6 @@ obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o
> obj-$(CONFIG_CORESIGHT_CATU) += coresight-catu.o
> obj-$(CONFIG_CORESIGHT_CTI) += coresight-cti.o
> obj-$(CONFIG_CORESIGHT_TRBE) += coresight-trbe.o
> +obj-$(CONFIG_CORESIGHT_TPDM) += coresight-tpdm.o
> coresight-cti-y := coresight-cti-core.o coresight-cti-platform.o \
> coresight-cti-sysfs.o
> diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
> index cc6b6cabf85f..a7f1a6f09cfb 100644
> --- a/drivers/hwtracing/coresight/coresight-core.c
> +++ b/drivers/hwtracing/coresight/coresight-core.c
> @@ -1071,7 +1071,8 @@ static int coresight_validate_source(struct coresight_device *csdev,
> }
>
> if (subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_PROC &&
> - subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE) {
> + subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE &&
> + subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_SYS) {
> dev_err(&csdev->dev, "wrong device subtype in %s\n", function);
> return -EINVAL;
> }
> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
> new file mode 100644
> index 000000000000..f494cef4fb24
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
> @@ -0,0 +1,152 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#include <linux/amba/bus.h>
> +#include <linux/bitmap.h>
> +#include <linux/coresight.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/fs.h>
> +#include <linux/io.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/regulator/consumer.h>
> +
> +#include "coresight-priv.h"
> +#include "coresight-tpdm.h"
> +
> +DEFINE_CORESIGHT_DEVLIST(tpdm_devs, "tpdm");
> +
> +static int tpdm_enable(struct coresight_device *csdev,
> + struct perf_event *event, u32 mode)
> +{
> + struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> +
> + mutex_lock(&drvdata->lock);
> + if (drvdata->enable) {
> + mutex_unlock(&drvdata->lock);
> + return -EBUSY;
> + }
> +
> + drvdata->enable = true;
> + mutex_unlock(&drvdata->lock);
> +
> + dev_info(drvdata->dev, "TPDM tracing enabled\n");
> + return 0;
> +}
> +
> +static void tpdm_disable(struct coresight_device *csdev,
> + struct perf_event *event)
> +{
> + struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> +
> + mutex_lock(&drvdata->lock);
> + if (!drvdata->enable) {
> + mutex_unlock(&drvdata->lock);
> + return;
> + }
> +
> + drvdata->enable = false;
> + mutex_unlock(&drvdata->lock);
> +
> + dev_info(drvdata->dev, "TPDM tracing disabled\n");
> +}
> +
> +static int tpdm_trace_id(struct coresight_device *csdev)
> +{
> + struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> +
> + return drvdata->traceid;
> +}
> +
> +static const struct coresight_ops_source tpdm_source_ops = {
> + .trace_id = tpdm_trace_id,
> + .enable = tpdm_enable,
> + .disable = tpdm_disable,
> +};
> +
> +static const struct coresight_ops tpdm_cs_ops = {
> + .source_ops = &tpdm_source_ops,
> +};
> +
> +static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
> +{
> + static int traceid = TPDM_TRACE_ID_START;
> +
> + drvdata->traceid = traceid++;
> +}
I have been specific on how to properly do this in the last revision. Given the
above about the MAINTAINERS file, I am not sure that I will continue reviewing this set.
There is also no need to rush another revision as I won't have the bandwidth to
process it before the holidays.
Thanks,
Mathieu
> +
> +static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
> +{
> + struct device *dev = &adev->dev;
> + struct coresight_platform_data *pdata;
> + struct tpdm_drvdata *drvdata;
> + struct coresight_desc desc = { 0 };
> +
> + desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
> + if (!desc.name)
> + return -ENOMEM;
> + pdata = coresight_get_platform_data(dev);
> + if (IS_ERR(pdata))
> + return PTR_ERR(pdata);
> + adev->dev.platform_data = pdata;
> +
> + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> + if (!drvdata)
> + return -ENOMEM;
> + drvdata->dev = &adev->dev;
> + dev_set_drvdata(dev, drvdata);
> +
> + drvdata->base = devm_ioremap_resource(dev, &adev->res);
> + if (!drvdata->base)
> + return -ENOMEM;
> +
> + mutex_init(&drvdata->lock);
> +
> + desc.type = CORESIGHT_DEV_TYPE_SOURCE;
> + desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
> + desc.ops = &tpdm_cs_ops;
> + desc.pdata = adev->dev.platform_data;
> + desc.dev = &adev->dev;
> + drvdata->csdev = coresight_register(&desc);
> + if (IS_ERR(drvdata->csdev))
> + return PTR_ERR(drvdata->csdev);
> +
> + tpdm_init_default_data(drvdata);
> + pm_runtime_put(&adev->dev);
> +
> + return 0;
> +}
> +
> +static void __exit tpdm_remove(struct amba_device *adev)
> +{
> + struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
> +
> + coresight_unregister(drvdata->csdev);
> +}
> +
> +static struct amba_id tpdm_ids[] = {
> + {
> + .id = 0x000f0e00,
> + .mask = 0x000fff00,
> + },
> + { 0, 0},
> +};
> +
> +static struct amba_driver tpdm_driver = {
> + .drv = {
> + .name = "coresight-tpdm",
> + .owner = THIS_MODULE,
> + .suppress_bind_attrs = true,
> + },
> + .probe = tpdm_probe,
> + .id_table = tpdm_ids,
> +};
> +
> +module_amba_driver(tpdm_driver);
> +
> +MODULE_LICENSE("GPL v2");
> +MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
> new file mode 100644
> index 000000000000..980ae90ff1c8
> --- /dev/null
> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
> @@ -0,0 +1,31 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
> + */
> +
> +#ifndef _CORESIGHT_CORESIGHT_TPDM_H
> +#define _CORESIGHT_CORESIGHT_TPDM_H
> +
> +/* Default value of the traceid */
> +#define TPDM_TRACE_ID_START 128
> +
> +/**
> + * struct tpdm_drvdata - specifics associated to an TPDM component
> + * @base: memory mapped base address for this component.
> + * @dev: The device entity associated to this component.
> + * @csdev: component vitals needed by the framework.
> + * @lock: lock for the enable value.
> + * @enable: enable status of the component.
> + * @traceid: value of the current ID for this component.
> + */
> +
> +struct tpdm_drvdata {
> + void __iomem *base;
> + struct device *dev;
> + struct coresight_device *csdev;
> + struct mutex lock;
> + bool enable;
> + int traceid;
> +};
> +
> +#endif /* _CORESIGHT_CORESIGHT_TPDM_H */
> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> index 93a2922b7653..e48d463be63b 100644
> --- a/include/linux/coresight.h
> +++ b/include/linux/coresight.h
> @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
> CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
> CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
> CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
> + CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
> };
>
> enum coresight_dev_subtype_helper {
> --
> 2.17.1
>
Hi Mathieu,
Thanks for the review.
On 12/15/2021 2:30 AM, Mathieu Poirier wrote:
> Hi Mao,
>
> On Thu, Dec 09, 2021 at 10:15:35PM +0800, Mao Jinlong wrote:
>> Use hash length of the source's device name to map to the pointer
>> of the enabled path. Using IDR will be more efficient than using
>> the list. And there could be other sources except STM and CPU etms
>> in the new HWs. It is better to maintain all the paths together.
>>
>> Signed-off-by: Mao Jinlong <[email protected]>
>> ---
>> drivers/hwtracing/coresight/coresight-core.c | 76 +++++++-------------
>> 1 file changed, 26 insertions(+), 50 deletions(-)
>>
>> diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
>> index 8a18c71df37a..cc6b6cabf85f 100644
>> --- a/drivers/hwtracing/coresight/coresight-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-core.c
>> @@ -7,6 +7,7 @@
>> #include <linux/init.h>
>> #include <linux/types.h>
>> #include <linux/device.h>
>> +#include <linux/idr.h>
>> #include <linux/io.h>
>> #include <linux/err.h>
>> #include <linux/export.h>
>> @@ -26,6 +27,12 @@
>> static DEFINE_MUTEX(coresight_mutex);
>> static DEFINE_PER_CPU(struct coresight_device *, csdev_sink);
>>
>> +/*
>> + * Use IDR to map the hash length of the source's device name
>> + * to the pointer of path for the source
>> + */
>> +static DEFINE_IDR(path_idr);
>> +
>> /**
>> * struct coresight_node - elements of a path, from source to sink
>> * @csdev: Address of an element.
>> @@ -36,20 +43,6 @@ struct coresight_node {
>> struct list_head link;
>> };
>>
>> -/*
>> - * When operating Coresight drivers from the sysFS interface, only a single
>> - * path can exist from a tracer (associated to a CPU) to a sink.
>> - */
>> -static DEFINE_PER_CPU(struct list_head *, tracer_path);
>> -
>> -/*
>> - * As of this writing only a single STM can be found in CS topologies. Since
>> - * there is no way to know if we'll ever see more and what kind of
>> - * configuration they will enact, for the time being only define a single path
>> - * for STM.
>> - */
>> -static struct list_head *stm_path;
>> -
>> /*
>> * When losing synchronisation a new barrier packet needs to be inserted at the
>> * beginning of the data collected in a buffer. That way the decoder knows that
>> @@ -1088,10 +1081,11 @@ static int coresight_validate_source(struct coresight_device *csdev,
>>
>> int coresight_enable(struct coresight_device *csdev)
>> {
>> - int cpu, ret = 0;
>> + int ret = 0;
>> struct coresight_device *sink;
>> struct list_head *path;
>> enum coresight_dev_subtype_source subtype;
>> + u32 hash;
>>
>> subtype = csdev->subtype.source_subtype;
>>
>> @@ -1133,26 +1127,14 @@ int coresight_enable(struct coresight_device *csdev)
>> if (ret)
>> goto err_source;
>>
>> - switch (subtype) {
>> - case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
>> - /*
>> - * When working from sysFS it is important to keep track
>> - * of the paths that were created so that they can be
>> - * undone in 'coresight_disable()'. Since there can only
>> - * be a single session per tracer (when working from sysFS)
>> - * a per-cpu variable will do just fine.
>> - */
>> - cpu = source_ops(csdev)->cpu_id(csdev);
>> - per_cpu(tracer_path, cpu) = path;
>> - break;
>> - case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
>> - stm_path = path;
>> - break;
>> - default:
>> - /* We can't be here */
>> - break;
>> - }
>> -
>> + /*
>> + * Use the hash length of source's device name as ID
>> + * and map the ID to the pointer of the path.
>> + */
>> + hash = hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev)));
>> + ret = idr_alloc_u32(&path_idr, path, &hash, hash, GFP_KERNEL);
>> + if (ret)
>> + goto err_source;
>> out:
>> mutex_unlock(&coresight_mutex);
>> return ret;
>> @@ -1168,8 +1150,9 @@ EXPORT_SYMBOL_GPL(coresight_enable);
>>
>> void coresight_disable(struct coresight_device *csdev)
>> {
>> - int cpu, ret;
>> + int ret;
>> struct list_head *path = NULL;
>> + u32 hash;
>>
>> mutex_lock(&coresight_mutex);
>>
>> @@ -1180,21 +1163,13 @@ void coresight_disable(struct coresight_device *csdev)
>> if (!csdev->enable || !coresight_disable_source(csdev))
>> goto out;
>>
>> - switch (csdev->subtype.source_subtype) {
>> - case CORESIGHT_DEV_SUBTYPE_SOURCE_PROC:
>> - cpu = source_ops(csdev)->cpu_id(csdev);
>> - path = per_cpu(tracer_path, cpu);
>> - per_cpu(tracer_path, cpu) = NULL;
>> - break;
>> - case CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE:
>> - path = stm_path;
>> - stm_path = NULL;
>> - break;
>> - default:
>> - /* We can't be here */
>> - break;
>> - }
>> + hash = hashlen_hash(hashlen_string(NULL, dev_name(&csdev->dev)));
>> + /* Find the path by the hash length. */
>> + path = idr_find(&path_idr, hash);
>> + if (path == NULL)
>> + return;
> Please add a dev_err() here as this should really not be happening.
I will add the dev_err().
>
>>
>> + idr_remove(&path_idr, hash);
>> coresight_disable_path(path);
>> coresight_release_path(path);
>>
>> @@ -1779,6 +1754,7 @@ static int __init coresight_init(void)
>>
>> static void __exit coresight_exit(void)
>> {
>> + idr_destroy(&path_idr);
> As far as I can tell this isn't needed.
I will remove this.
>
>> cscfg_exit();
>> etm_perf_exit();
>> bus_unregister(&coresight_bustype);
>> --
>> 2.17.1
>>
Hi Mathieu,
On 12/15/2021 2:57 AM, Mathieu Poirier wrote:
> On Thu, Dec 09, 2021 at 10:15:36PM +0800, Mao Jinlong wrote:
>> Add driver to support Coresight device TPDM (Trace, Profiling and
>> Diagnostics Monitor). TPDM is a monitor to collect data from
>> different datasets. This change is to add probe/enable/disable
>> functions for tpdm source.
>>
>> Signed-off-by: Tao Zhang <[email protected]>
>> Signed-off-by: Mao Jinlong <[email protected]>
>> ---
>> MAINTAINERS | 8 +
>> drivers/hwtracing/coresight/Kconfig | 13 ++
>> drivers/hwtracing/coresight/Makefile | 1 +
>> drivers/hwtracing/coresight/coresight-core.c | 3 +-
>> drivers/hwtracing/coresight/coresight-tpdm.c | 152 +++++++++++++++++++
>> drivers/hwtracing/coresight/coresight-tpdm.h | 31 ++++
>> include/linux/coresight.h | 1 +
>> 7 files changed, 208 insertions(+), 1 deletion(-)
>> create mode 100644 drivers/hwtracing/coresight/coresight-tpdm.c
>> create mode 100644 drivers/hwtracing/coresight/coresight-tpdm.h
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 7a2345ce8521..59f39b3194f6 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -15560,6 +15560,14 @@ L: [email protected]
>> S: Supported
>> F: drivers/net/ipa/
>>
>> +QCOM CORESIGHT COMPONENTS DRIVER
>> +M: Tao Zhang <[email protected]>
>> +M: Jinlong Mao <[email protected]>
>> +M: Mathieu Poirier <[email protected]>
>> +M: Suzuki K Poulose <[email protected]>
>> +S: Maintained
>> +F: drivers/hwtracing/coresight/coresight-tpdm.c
>> +
> There is no need for an extra entry in the MAINTAINERS file. The checkpatch.pl
> script is smart enough to know when to CC you and Tao every time the TPDM/TPDA
> drivers are modified. Suzuki and I will simply wait for you guys to add your RB
> tags before reviewing the patches. I have explained this in the previous revision.
Hi Mathieu,
I will remove this entry.
>> QEMU MACHINE EMULATOR AND VIRTUALIZER SUPPORT
>> M: Gabriel Somlo <[email protected]>
>> M: "Michael S. Tsirkin" <[email protected]>
>> diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
>> index 514a9b8086e3..5c506a1cd08f 100644
>> --- a/drivers/hwtracing/coresight/Kconfig
>> +++ b/drivers/hwtracing/coresight/Kconfig
>> @@ -201,4 +201,17 @@ config CORESIGHT_TRBE
>>
>> To compile this driver as a module, choose M here: the module will be
>> called coresight-trbe.
>> +
>> +config CORESIGHT_TPDM
>> + tristate "CoreSight Trace, Profiling & Diagnostics Monitor driver"
>> + select CORESIGHT_LINKS_AND_SINKS
> Is this available on 32bit HW as well? If not please make it dependent on ARM64
> as it for ETMv4x devices.
This is available on 32bit HW as well.
>> + help
>> + This driver provides support for configuring monitor. Monitors are
>> + primarily responsible for data set collection and support the
>> + ability to collect any permutation of data set types. Monitors are
>> + also responsible for interaction with system cross triggering.
>> +
>> + To compile this driver as a module, choose M here: the module will be
>> + called coresight-tpdm.
>> +
>> endif
>> diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
>> index b6c4a48140ec..e7392a0dddeb 100644
>> --- a/drivers/hwtracing/coresight/Makefile
>> +++ b/drivers/hwtracing/coresight/Makefile
>> @@ -25,5 +25,6 @@ obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o
>> obj-$(CONFIG_CORESIGHT_CATU) += coresight-catu.o
>> obj-$(CONFIG_CORESIGHT_CTI) += coresight-cti.o
>> obj-$(CONFIG_CORESIGHT_TRBE) += coresight-trbe.o
>> +obj-$(CONFIG_CORESIGHT_TPDM) += coresight-tpdm.o
>> coresight-cti-y := coresight-cti-core.o coresight-cti-platform.o \
>> coresight-cti-sysfs.o
>> diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
>> index cc6b6cabf85f..a7f1a6f09cfb 100644
>> --- a/drivers/hwtracing/coresight/coresight-core.c
>> +++ b/drivers/hwtracing/coresight/coresight-core.c
>> @@ -1071,7 +1071,8 @@ static int coresight_validate_source(struct coresight_device *csdev,
>> }
>>
>> if (subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_PROC &&
>> - subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE) {
>> + subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE &&
>> + subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_SYS) {
>> dev_err(&csdev->dev, "wrong device subtype in %s\n", function);
>> return -EINVAL;
>> }
>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
>> new file mode 100644
>> index 000000000000..f494cef4fb24
>> --- /dev/null
>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
>> @@ -0,0 +1,152 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
>> + */
>> +
>> +#include <linux/amba/bus.h>
>> +#include <linux/bitmap.h>
>> +#include <linux/coresight.h>
>> +#include <linux/device.h>
>> +#include <linux/err.h>
>> +#include <linux/fs.h>
>> +#include <linux/io.h>
>> +#include <linux/kernel.h>
>> +#include <linux/module.h>
>> +#include <linux/of.h>
>> +#include <linux/regulator/consumer.h>
>> +
>> +#include "coresight-priv.h"
>> +#include "coresight-tpdm.h"
>> +
>> +DEFINE_CORESIGHT_DEVLIST(tpdm_devs, "tpdm");
>> +
>> +static int tpdm_enable(struct coresight_device *csdev,
>> + struct perf_event *event, u32 mode)
>> +{
>> + struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> +
>> + mutex_lock(&drvdata->lock);
>> + if (drvdata->enable) {
>> + mutex_unlock(&drvdata->lock);
>> + return -EBUSY;
>> + }
>> +
>> + drvdata->enable = true;
>> + mutex_unlock(&drvdata->lock);
>> +
>> + dev_info(drvdata->dev, "TPDM tracing enabled\n");
>> + return 0;
>> +}
>> +
>> +static void tpdm_disable(struct coresight_device *csdev,
>> + struct perf_event *event)
>> +{
>> + struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> +
>> + mutex_lock(&drvdata->lock);
>> + if (!drvdata->enable) {
>> + mutex_unlock(&drvdata->lock);
>> + return;
>> + }
>> +
>> + drvdata->enable = false;
>> + mutex_unlock(&drvdata->lock);
>> +
>> + dev_info(drvdata->dev, "TPDM tracing disabled\n");
>> +}
>> +
>> +static int tpdm_trace_id(struct coresight_device *csdev)
>> +{
>> + struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
>> +
>> + return drvdata->traceid;
>> +}
>> +
>> +static const struct coresight_ops_source tpdm_source_ops = {
>> + .trace_id = tpdm_trace_id,
>> + .enable = tpdm_enable,
>> + .disable = tpdm_disable,
>> +};
>> +
>> +static const struct coresight_ops tpdm_cs_ops = {
>> + .source_ops = &tpdm_source_ops,
>> +};
>> +
>> +static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
>> +{
>> + static int traceid = TPDM_TRACE_ID_START;
>> +
>> + drvdata->traceid = traceid++;
>> +}
> I have been specific on how to properly do this in the last revision. Given the
> above about the MAINTAINERS file, I am not sure that I will continue reviewing this set.
>
> There is also no need to rush another revision as I won't have the bandwidth to
> process it before the holidays.
>
> Thanks,
> Mathieu
Hi Mathieu,
Sorry, not addressed your previous comments here.
For the trace id, each coresight component has 7 bits to store the trace
id. So the trace id should be from 1 to 127 as 0 is invalid.
Apart from TPDMs/STM/ETMs, we also have other coresight components in
our internal device. About 80 ids are already used.
Some components have fixed trace id in HW. If we use functions below to
count the trace id, there will be conflict to other components.
Can we use 1-15 for etm trace ids and 16 - 127 for other coresight
components ? And handle trace ids in its' own driver ?
static inline int coresight_get_system_trace_id(int id)
{
/* Start system IDs above the highest per CPU trace ID. */
return coresigth_get_trace_id(cpumask_last(cpu_possible_mask) + 1);
}
static inline int coresight_get_trace_id(int cpu)
{
/*
* A trace ID of value 0 is invalid, so let's start at some
* random value that fits in 7 bits and go from there. Since
* the common convention is to have data trace IDs be I(N) + 1,
* set instruction trace IDs as a function of the CPU number.
*/
return (CORESIGHT_ETM_PMU_SEED + (cpu * 2));
}
Thanks
Jinlong Mao
>> +
>> +static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
>> +{
>> + struct device *dev = &adev->dev;
>> + struct coresight_platform_data *pdata;
>> + struct tpdm_drvdata *drvdata;
>> + struct coresight_desc desc = { 0 };
>> +
>> + desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
>> + if (!desc.name)
>> + return -ENOMEM;
>> + pdata = coresight_get_platform_data(dev);
>> + if (IS_ERR(pdata))
>> + return PTR_ERR(pdata);
>> + adev->dev.platform_data = pdata;
>> +
>> + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
>> + if (!drvdata)
>> + return -ENOMEM;
>> + drvdata->dev = &adev->dev;
>> + dev_set_drvdata(dev, drvdata);
>> +
>> + drvdata->base = devm_ioremap_resource(dev, &adev->res);
>> + if (!drvdata->base)
>> + return -ENOMEM;
>> +
>> + mutex_init(&drvdata->lock);
>> +
>> + desc.type = CORESIGHT_DEV_TYPE_SOURCE;
>> + desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
>> + desc.ops = &tpdm_cs_ops;
>> + desc.pdata = adev->dev.platform_data;
>> + desc.dev = &adev->dev;
>> + drvdata->csdev = coresight_register(&desc);
>> + if (IS_ERR(drvdata->csdev))
>> + return PTR_ERR(drvdata->csdev);
>> +
>> + tpdm_init_default_data(drvdata);
>> + pm_runtime_put(&adev->dev);
>> +
>> + return 0;
>> +}
>> +
>> +static void __exit tpdm_remove(struct amba_device *adev)
>> +{
>> + struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
>> +
>> + coresight_unregister(drvdata->csdev);
>> +}
>> +
>> +static struct amba_id tpdm_ids[] = {
>> + {
>> + .id = 0x000f0e00,
>> + .mask = 0x000fff00,
>> + },
>> + { 0, 0},
>> +};
>> +
>> +static struct amba_driver tpdm_driver = {
>> + .drv = {
>> + .name = "coresight-tpdm",
>> + .owner = THIS_MODULE,
>> + .suppress_bind_attrs = true,
>> + },
>> + .probe = tpdm_probe,
>> + .id_table = tpdm_ids,
>> +};
>> +
>> +module_amba_driver(tpdm_driver);
>> +
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
>> new file mode 100644
>> index 000000000000..980ae90ff1c8
>> --- /dev/null
>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>> @@ -0,0 +1,31 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
>> + */
>> +
>> +#ifndef _CORESIGHT_CORESIGHT_TPDM_H
>> +#define _CORESIGHT_CORESIGHT_TPDM_H
>> +
>> +/* Default value of the traceid */
>> +#define TPDM_TRACE_ID_START 128
>> +
>> +/**
>> + * struct tpdm_drvdata - specifics associated to an TPDM component
>> + * @base: memory mapped base address for this component.
>> + * @dev: The device entity associated to this component.
>> + * @csdev: component vitals needed by the framework.
>> + * @lock: lock for the enable value.
>> + * @enable: enable status of the component.
>> + * @traceid: value of the current ID for this component.
>> + */
>> +
>> +struct tpdm_drvdata {
>> + void __iomem *base;
>> + struct device *dev;
>> + struct coresight_device *csdev;
>> + struct mutex lock;
>> + bool enable;
>> + int traceid;
>> +};
>> +
>> +#endif /* _CORESIGHT_CORESIGHT_TPDM_H */
>> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
>> index 93a2922b7653..e48d463be63b 100644
>> --- a/include/linux/coresight.h
>> +++ b/include/linux/coresight.h
>> @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
>> CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
>> CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
>> CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
>> + CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
>> };
>>
>> enum coresight_dev_subtype_helper {
>> --
>> 2.17.1
>>
Hi,
I have a couple of comments relating to Coresight trace IDs
On Wed, 15 Dec 2021 at 16:10, Jinlong Mao <[email protected]> wrote:
>
> Hi Mathieu,
>
> On 12/15/2021 2:57 AM, Mathieu Poirier wrote:
> > On Thu, Dec 09, 2021 at 10:15:36PM +0800, Mao Jinlong wrote:
> >> Add driver to support Coresight device TPDM (Trace, Profiling and
> >> Diagnostics Monitor). TPDM is a monitor to collect data from
> >> different datasets. This change is to add probe/enable/disable
> >> functions for tpdm source.
> >>
> >> Signed-off-by: Tao Zhang <[email protected]>
> >> Signed-off-by: Mao Jinlong <[email protected]>
> >> ---
> >> MAINTAINERS | 8 +
> >> drivers/hwtracing/coresight/Kconfig | 13 ++
> >> drivers/hwtracing/coresight/Makefile | 1 +
> >> drivers/hwtracing/coresight/coresight-core.c | 3 +-
> >> drivers/hwtracing/coresight/coresight-tpdm.c | 152 +++++++++++++++++++
> >> drivers/hwtracing/coresight/coresight-tpdm.h | 31 ++++
> >> include/linux/coresight.h | 1 +
> >> 7 files changed, 208 insertions(+), 1 deletion(-)
> >> create mode 100644 drivers/hwtracing/coresight/coresight-tpdm.c
> >> create mode 100644 drivers/hwtracing/coresight/coresight-tpdm.h
> >>
> >> diff --git a/MAINTAINERS b/MAINTAINERS
> >> index 7a2345ce8521..59f39b3194f6 100644
> >> --- a/MAINTAINERS
> >> +++ b/MAINTAINERS
> >> @@ -15560,6 +15560,14 @@ L: [email protected]
> >> S: Supported
> >> F: drivers/net/ipa/
> >>
> >> +QCOM CORESIGHT COMPONENTS DRIVER
> >> +M: Tao Zhang <[email protected]>
> >> +M: Jinlong Mao <[email protected]>
> >> +M: Mathieu Poirier <[email protected]>
> >> +M: Suzuki K Poulose <[email protected]>
> >> +S: Maintained
> >> +F: drivers/hwtracing/coresight/coresight-tpdm.c
> >> +
> > There is no need for an extra entry in the MAINTAINERS file. The checkpatch.pl
> > script is smart enough to know when to CC you and Tao every time the TPDM/TPDA
> > drivers are modified. Suzuki and I will simply wait for you guys to add your RB
> > tags before reviewing the patches. I have explained this in the previous revision.
>
> Hi Mathieu,
>
> I will remove this entry.
>
> >> QEMU MACHINE EMULATOR AND VIRTUALIZER SUPPORT
> >> M: Gabriel Somlo <[email protected]>
> >> M: "Michael S. Tsirkin" <[email protected]>
> >> diff --git a/drivers/hwtracing/coresight/Kconfig b/drivers/hwtracing/coresight/Kconfig
> >> index 514a9b8086e3..5c506a1cd08f 100644
> >> --- a/drivers/hwtracing/coresight/Kconfig
> >> +++ b/drivers/hwtracing/coresight/Kconfig
> >> @@ -201,4 +201,17 @@ config CORESIGHT_TRBE
> >>
> >> To compile this driver as a module, choose M here: the module will be
> >> called coresight-trbe.
> >> +
> >> +config CORESIGHT_TPDM
> >> + tristate "CoreSight Trace, Profiling & Diagnostics Monitor driver"
> >> + select CORESIGHT_LINKS_AND_SINKS
> > Is this available on 32bit HW as well? If not please make it dependent on ARM64
> > as it for ETMv4x devices.
> This is available on 32bit HW as well.
> >> + help
> >> + This driver provides support for configuring monitor. Monitors are
> >> + primarily responsible for data set collection and support the
> >> + ability to collect any permutation of data set types. Monitors are
> >> + also responsible for interaction with system cross triggering.
> >> +
> >> + To compile this driver as a module, choose M here: the module will be
> >> + called coresight-tpdm.
> >> +
> >> endif
> >> diff --git a/drivers/hwtracing/coresight/Makefile b/drivers/hwtracing/coresight/Makefile
> >> index b6c4a48140ec..e7392a0dddeb 100644
> >> --- a/drivers/hwtracing/coresight/Makefile
> >> +++ b/drivers/hwtracing/coresight/Makefile
> >> @@ -25,5 +25,6 @@ obj-$(CONFIG_CORESIGHT_CPU_DEBUG) += coresight-cpu-debug.o
> >> obj-$(CONFIG_CORESIGHT_CATU) += coresight-catu.o
> >> obj-$(CONFIG_CORESIGHT_CTI) += coresight-cti.o
> >> obj-$(CONFIG_CORESIGHT_TRBE) += coresight-trbe.o
> >> +obj-$(CONFIG_CORESIGHT_TPDM) += coresight-tpdm.o
> >> coresight-cti-y := coresight-cti-core.o coresight-cti-platform.o \
> >> coresight-cti-sysfs.o
> >> diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
> >> index cc6b6cabf85f..a7f1a6f09cfb 100644
> >> --- a/drivers/hwtracing/coresight/coresight-core.c
> >> +++ b/drivers/hwtracing/coresight/coresight-core.c
> >> @@ -1071,7 +1071,8 @@ static int coresight_validate_source(struct coresight_device *csdev,
> >> }
> >>
> >> if (subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_PROC &&
> >> - subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE) {
> >> + subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE &&
> >> + subtype != CORESIGHT_DEV_SUBTYPE_SOURCE_SYS) {
> >> dev_err(&csdev->dev, "wrong device subtype in %s\n", function);
> >> return -EINVAL;
> >> }
> >> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
> >> new file mode 100644
> >> index 000000000000..f494cef4fb24
> >> --- /dev/null
> >> +++ b/drivers/hwtracing/coresight/coresight-tpdm.c
> >> @@ -0,0 +1,152 @@
> >> +// SPDX-License-Identifier: GPL-2.0
> >> +/*
> >> + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
> >> + */
> >> +
> >> +#include <linux/amba/bus.h>
> >> +#include <linux/bitmap.h>
> >> +#include <linux/coresight.h>
> >> +#include <linux/device.h>
> >> +#include <linux/err.h>
> >> +#include <linux/fs.h>
> >> +#include <linux/io.h>
> >> +#include <linux/kernel.h>
> >> +#include <linux/module.h>
> >> +#include <linux/of.h>
> >> +#include <linux/regulator/consumer.h>
> >> +
> >> +#include "coresight-priv.h"
> >> +#include "coresight-tpdm.h"
> >> +
> >> +DEFINE_CORESIGHT_DEVLIST(tpdm_devs, "tpdm");
> >> +
> >> +static int tpdm_enable(struct coresight_device *csdev,
> >> + struct perf_event *event, u32 mode)
> >> +{
> >> + struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> >> +
> >> + mutex_lock(&drvdata->lock);
> >> + if (drvdata->enable) {
> >> + mutex_unlock(&drvdata->lock);
> >> + return -EBUSY;
> >> + }
> >> +
> >> + drvdata->enable = true;
> >> + mutex_unlock(&drvdata->lock);
> >> +
> >> + dev_info(drvdata->dev, "TPDM tracing enabled\n");
> >> + return 0;
> >> +}
> >> +
> >> +static void tpdm_disable(struct coresight_device *csdev,
> >> + struct perf_event *event)
> >> +{
> >> + struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> >> +
> >> + mutex_lock(&drvdata->lock);
> >> + if (!drvdata->enable) {
> >> + mutex_unlock(&drvdata->lock);
> >> + return;
> >> + }
> >> +
> >> + drvdata->enable = false;
> >> + mutex_unlock(&drvdata->lock);
> >> +
> >> + dev_info(drvdata->dev, "TPDM tracing disabled\n");
> >> +}
> >> +
> >> +static int tpdm_trace_id(struct coresight_device *csdev)
> >> +{
> >> + struct tpdm_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
> >> +
> >> + return drvdata->traceid;
> >> +}
> >> +
> >> +static const struct coresight_ops_source tpdm_source_ops = {
> >> + .trace_id = tpdm_trace_id,
> >> + .enable = tpdm_enable,
> >> + .disable = tpdm_disable,
> >> +};
> >> +
> >> +static const struct coresight_ops tpdm_cs_ops = {
> >> + .source_ops = &tpdm_source_ops,
> >> +};
> >> +
> >> +static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
> >> +{
> >> + static int traceid = TPDM_TRACE_ID_START;
> >> +
> >> + drvdata->traceid = traceid++;
> >> +}
> > I have been specific on how to properly do this in the last revision. Given the
> > above about the MAINTAINERS file, I am not sure that I will continue reviewing this set.
> >
> > There is also no need to rush another revision as I won't have the bandwidth to
> > process it before the holidays.
> >
> > Thanks,
> > Mathieu
>
> Hi Mathieu,
>
> Sorry, not addressed your previous comments here.
>
> For the trace id, each coresight component has 7 bits to store the trace
> id. So the trace id should be from 1 to 127 as 0 is invalid.
IDs 0x70 - 0x7F (`112 - 127 ) are reserved - see the ARM Coresight
Architecture specification v3.0
>
> Apart from TPDMs/STM/ETMs, we also have other coresight components in
> our internal device. About 80 ids are already used.
>
> Some components have fixed trace id in HW. If we use functions below to
> count the trace id, there will be conflict to other components.
>
> Can we use 1-15 for etm trace ids and 16 - 127 for other coresight
> components ? And handle trace ids in its' own driver ?
>
This will limit systems to 15 cores - some have more!
>
> static inline int coresight_get_system_trace_id(int id)
> {
> /* Start system IDs above the highest per CPU trace ID. */
> return coresigth_get_trace_id(cpumask_last(cpu_possible_mask) + 1);
> }
>
> static inline int coresight_get_trace_id(int cpu)
> {
> /*
> * A trace ID of value 0 is invalid, so let's start at some
> * random value that fits in 7 bits and go from there. Since
> * the common convention is to have data trace IDs be I(N) + 1,
> * set instruction trace IDs as a function of the CPU number.
> */
> return (CORESIGHT_ETM_PMU_SEED + (cpu * 2));
> }
>
This fixed relationship between cpu and trace ID is used in the perf
tooling to populate the elements in the perf.data file to correctly
allow association between CPU and trace data, and thus allow correct
trace decode.
It should be possible to create another more dynamic mapping scheme -
but this must include a way to support the perf requirements too.
Regards
Mike
> Thanks
>
> Jinlong Mao
>
> >> +
> >> +static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
> >> +{
> >> + struct device *dev = &adev->dev;
> >> + struct coresight_platform_data *pdata;
> >> + struct tpdm_drvdata *drvdata;
> >> + struct coresight_desc desc = { 0 };
> >> +
> >> + desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
> >> + if (!desc.name)
> >> + return -ENOMEM;
> >> + pdata = coresight_get_platform_data(dev);
> >> + if (IS_ERR(pdata))
> >> + return PTR_ERR(pdata);
> >> + adev->dev.platform_data = pdata;
> >> +
> >> + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> >> + if (!drvdata)
> >> + return -ENOMEM;
> >> + drvdata->dev = &adev->dev;
> >> + dev_set_drvdata(dev, drvdata);
> >> +
> >> + drvdata->base = devm_ioremap_resource(dev, &adev->res);
> >> + if (!drvdata->base)
> >> + return -ENOMEM;
> >> +
> >> + mutex_init(&drvdata->lock);
> >> +
> >> + desc.type = CORESIGHT_DEV_TYPE_SOURCE;
> >> + desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
> >> + desc.ops = &tpdm_cs_ops;
> >> + desc.pdata = adev->dev.platform_data;
> >> + desc.dev = &adev->dev;
> >> + drvdata->csdev = coresight_register(&desc);
> >> + if (IS_ERR(drvdata->csdev))
> >> + return PTR_ERR(drvdata->csdev);
> >> +
> >> + tpdm_init_default_data(drvdata);
> >> + pm_runtime_put(&adev->dev);
> >> +
> >> + return 0;
> >> +}
> >> +
> >> +static void __exit tpdm_remove(struct amba_device *adev)
> >> +{
> >> + struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
> >> +
> >> + coresight_unregister(drvdata->csdev);
> >> +}
> >> +
> >> +static struct amba_id tpdm_ids[] = {
> >> + {
> >> + .id = 0x000f0e00,
> >> + .mask = 0x000fff00,
> >> + },
> >> + { 0, 0},
> >> +};
> >> +
> >> +static struct amba_driver tpdm_driver = {
> >> + .drv = {
> >> + .name = "coresight-tpdm",
> >> + .owner = THIS_MODULE,
> >> + .suppress_bind_attrs = true,
> >> + },
> >> + .probe = tpdm_probe,
> >> + .id_table = tpdm_ids,
> >> +};
> >> +
> >> +module_amba_driver(tpdm_driver);
> >> +
> >> +MODULE_LICENSE("GPL v2");
> >> +MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
> >> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
> >> new file mode 100644
> >> index 000000000000..980ae90ff1c8
> >> --- /dev/null
> >> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
> >> @@ -0,0 +1,31 @@
> >> +/* SPDX-License-Identifier: GPL-2.0 */
> >> +/*
> >> + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
> >> + */
> >> +
> >> +#ifndef _CORESIGHT_CORESIGHT_TPDM_H
> >> +#define _CORESIGHT_CORESIGHT_TPDM_H
> >> +
> >> +/* Default value of the traceid */
> >> +#define TPDM_TRACE_ID_START 128
> >> +
> >> +/**
> >> + * struct tpdm_drvdata - specifics associated to an TPDM component
> >> + * @base: memory mapped base address for this component.
> >> + * @dev: The device entity associated to this component.
> >> + * @csdev: component vitals needed by the framework.
> >> + * @lock: lock for the enable value.
> >> + * @enable: enable status of the component.
> >> + * @traceid: value of the current ID for this component.
> >> + */
> >> +
> >> +struct tpdm_drvdata {
> >> + void __iomem *base;
> >> + struct device *dev;
> >> + struct coresight_device *csdev;
> >> + struct mutex lock;
> >> + bool enable;
> >> + int traceid;
> >> +};
> >> +
> >> +#endif /* _CORESIGHT_CORESIGHT_TPDM_H */
> >> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> >> index 93a2922b7653..e48d463be63b 100644
> >> --- a/include/linux/coresight.h
> >> +++ b/include/linux/coresight.h
> >> @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
> >> CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
> >> CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
> >> CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
> >> + CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
> >> };
> >>
> >> enum coresight_dev_subtype_helper {
> >> --
> >> 2.17.1
> >>
--
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK
[...]
> > >> +
> > >> +static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
> > >> +{
> > >> + static int traceid = TPDM_TRACE_ID_START;
> > >> +
> > >> + drvdata->traceid = traceid++;
> > >> +}
> > > I have been specific on how to properly do this in the last revision. Given the
> > > above about the MAINTAINERS file, I am not sure that I will continue reviewing this set.
> > >
> > > There is also no need to rush another revision as I won't have the bandwidth to
> > > process it before the holidays.
> > >
> > > Thanks,
> > > Mathieu
> >
> > Hi Mathieu,
> >
> > Sorry, not addressed your previous comments here.
> >
> > For the trace id, each coresight component has 7 bits to store the trace
> > id. So the trace id should be from 1 to 127 as 0 is invalid.
>
> IDs 0x70 - 0x7F (`112 - 127 ) are reserved - see the ARM Coresight
> Architecture specification v3.0
>
Correct
> >
> > Apart from TPDMs/STM/ETMs, we also have other coresight components in
> > our internal device. About 80 ids are already used.
> >
> > Some components have fixed trace id in HW. If we use functions below to
> > count the trace id, there will be conflict to other components.
> >
> > Can we use 1-15 for etm trace ids and 16 - 127 for other coresight
> > components ? And handle trace ids in its' own driver ?
> >
>
> This will limit systems to 15 cores - some have more!
>
Correct
>
> >
> > static inline int coresight_get_system_trace_id(int id)
> > {
> > /* Start system IDs above the highest per CPU trace ID. */
> > return coresigth_get_trace_id(cpumask_last(cpu_possible_mask) + 1);
> > }
Looking at my own suggestion again this won't work since it returns the same traceID
when called multiple times.
For this patchset and _without_ taking into account internal devices that have
their traceID set in HW:
1. Define a bitmask that is 7 bit wide.
2. By default, set bits under 0x10 and between 0x70 - 0x7F.
3. In coresight_get_system_trace_id(), drop the @id parameter and allocate the
first available bit after cpumask_last(cpu_possible_mask) + 1.
4. Define a new function called coresight_put_system_trace_id(int id) that
clears the bit in the mask corresponding to @id.
For now that should work.
> >
> > static inline int coresight_get_trace_id(int cpu)
> > {
> > /*
> > * A trace ID of value 0 is invalid, so let's start at some
> > * random value that fits in 7 bits and go from there. Since
> > * the common convention is to have data trace IDs be I(N) + 1,
> > * set instruction trace IDs as a function of the CPU number.
> > */
> > return (CORESIGHT_ETM_PMU_SEED + (cpu * 2));
> > }
> >
>
> This fixed relationship between cpu and trace ID is used in the perf
> tooling to populate the elements in the perf.data file to correctly
> allow association between CPU and trace data, and thus allow correct
> trace decode.
TraceIDs associated to CPUs are communicated to the perf tooling by way of the
perf header - theoretically we should be able to change the allocation scheme
without impacting the decoding process.
>
> It should be possible to create another more dynamic mapping scheme -
> but this must include a way to support the perf requirements too.
>
TraceIDs have been a lurking problem for as long as the subsystem has existed.
For now what I have suggested above should be sufficient to provide an
in-between solution that doesn't hold back this patchset.
That being said, we need to start thinking about the best way to do this. I
will put a patchset together in the new year that aims in that direction.
> Regards
>
> Mike
>
> > Thanks
> >
> > Jinlong Mao
> >
> > >> +
> > >> +static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
> > >> +{
> > >> + struct device *dev = &adev->dev;
> > >> + struct coresight_platform_data *pdata;
> > >> + struct tpdm_drvdata *drvdata;
> > >> + struct coresight_desc desc = { 0 };
> > >> +
> > >> + desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
> > >> + if (!desc.name)
> > >> + return -ENOMEM;
> > >> + pdata = coresight_get_platform_data(dev);
> > >> + if (IS_ERR(pdata))
> > >> + return PTR_ERR(pdata);
> > >> + adev->dev.platform_data = pdata;
> > >> +
> > >> + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> > >> + if (!drvdata)
> > >> + return -ENOMEM;
> > >> + drvdata->dev = &adev->dev;
> > >> + dev_set_drvdata(dev, drvdata);
> > >> +
> > >> + drvdata->base = devm_ioremap_resource(dev, &adev->res);
> > >> + if (!drvdata->base)
> > >> + return -ENOMEM;
> > >> +
> > >> + mutex_init(&drvdata->lock);
> > >> +
> > >> + desc.type = CORESIGHT_DEV_TYPE_SOURCE;
> > >> + desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
> > >> + desc.ops = &tpdm_cs_ops;
> > >> + desc.pdata = adev->dev.platform_data;
> > >> + desc.dev = &adev->dev;
> > >> + drvdata->csdev = coresight_register(&desc);
> > >> + if (IS_ERR(drvdata->csdev))
> > >> + return PTR_ERR(drvdata->csdev);
> > >> +
> > >> + tpdm_init_default_data(drvdata);
> > >> + pm_runtime_put(&adev->dev);
> > >> +
> > >> + return 0;
> > >> +}
> > >> +
> > >> +static void __exit tpdm_remove(struct amba_device *adev)
> > >> +{
> > >> + struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
> > >> +
> > >> + coresight_unregister(drvdata->csdev);
> > >> +}
> > >> +
> > >> +static struct amba_id tpdm_ids[] = {
> > >> + {
> > >> + .id = 0x000f0e00,
> > >> + .mask = 0x000fff00,
> > >> + },
> > >> + { 0, 0},
> > >> +};
> > >> +
> > >> +static struct amba_driver tpdm_driver = {
> > >> + .drv = {
> > >> + .name = "coresight-tpdm",
> > >> + .owner = THIS_MODULE,
> > >> + .suppress_bind_attrs = true,
> > >> + },
> > >> + .probe = tpdm_probe,
> > >> + .id_table = tpdm_ids,
> > >> +};
> > >> +
> > >> +module_amba_driver(tpdm_driver);
> > >> +
> > >> +MODULE_LICENSE("GPL v2");
> > >> +MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
> > >> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
> > >> new file mode 100644
> > >> index 000000000000..980ae90ff1c8
> > >> --- /dev/null
> > >> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
> > >> @@ -0,0 +1,31 @@
> > >> +/* SPDX-License-Identifier: GPL-2.0 */
> > >> +/*
> > >> + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
> > >> + */
> > >> +
> > >> +#ifndef _CORESIGHT_CORESIGHT_TPDM_H
> > >> +#define _CORESIGHT_CORESIGHT_TPDM_H
> > >> +
> > >> +/* Default value of the traceid */
> > >> +#define TPDM_TRACE_ID_START 128
> > >> +
> > >> +/**
> > >> + * struct tpdm_drvdata - specifics associated to an TPDM component
> > >> + * @base: memory mapped base address for this component.
> > >> + * @dev: The device entity associated to this component.
> > >> + * @csdev: component vitals needed by the framework.
> > >> + * @lock: lock for the enable value.
> > >> + * @enable: enable status of the component.
> > >> + * @traceid: value of the current ID for this component.
> > >> + */
> > >> +
> > >> +struct tpdm_drvdata {
> > >> + void __iomem *base;
> > >> + struct device *dev;
> > >> + struct coresight_device *csdev;
> > >> + struct mutex lock;
> > >> + bool enable;
> > >> + int traceid;
> > >> +};
> > >> +
> > >> +#endif /* _CORESIGHT_CORESIGHT_TPDM_H */
> > >> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> > >> index 93a2922b7653..e48d463be63b 100644
> > >> --- a/include/linux/coresight.h
> > >> +++ b/include/linux/coresight.h
> > >> @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
> > >> CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
> > >> CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
> > >> CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
> > >> + CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
> > >> };
> > >>
> > >> enum coresight_dev_subtype_helper {
> > >> --
> > >> 2.17.1
> > >>
>
>
>
> --
> Mike Leach
> Principal Engineer, ARM Ltd.
> Manchester Design Centre. UK
On Thu, Dec 09, 2021 at 10:15:40PM +0800, Mao Jinlong wrote:
> Add API usage document for sysfs API in TPDM driver.
>
> Signed-off-by: Mao Jinlong <[email protected]>
> ---
> .../ABI/testing/sysfs-bus-coresight-devices-tpdm | 12 ++++++++++++
> MAINTAINERS | 1 +
> 2 files changed, 13 insertions(+)
> create mode 100644 Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
>
> diff --git a/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> new file mode 100644
> index 000000000000..fdd0bd0e1c33
> --- /dev/null
> +++ b/Documentation/ABI/testing/sysfs-bus-coresight-devices-tpdm
> @@ -0,0 +1,12 @@
> +What: /sys/bus/coresight/devices/<tpdm-name>/available_datasets
> +Date: December 2021
> +KernelVersion 5.16
5.16 already has all of the new features, so this will not make it into
that release.
thanks,
greg k-h
Hi Mathieu,
Good Day.
On 12/17/2021 3:02 AM, Mathieu Poirier wrote:
> [...]
>
>>>>> +
>>>>> +static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
>>>>> +{
>>>>> + static int traceid = TPDM_TRACE_ID_START;
>>>>> +
>>>>> + drvdata->traceid = traceid++;
>>>>> +}
>>>> I have been specific on how to properly do this in the last revision. Given the
>>>> above about the MAINTAINERS file, I am not sure that I will continue reviewing this set.
>>>>
>>>> There is also no need to rush another revision as I won't have the bandwidth to
>>>> process it before the holidays.
>>>>
>>>> Thanks,
>>>> Mathieu
>>> Hi Mathieu,
>>>
>>> Sorry, not addressed your previous comments here.
>>>
>>> For the trace id, each coresight component has 7 bits to store the trace
>>> id. So the trace id should be from 1 to 127 as 0 is invalid.
>> IDs 0x70 - 0x7F (`112 - 127 ) are reserved - see the ARM Coresight
>> Architecture specification v3.0
>>
> Correct
>
>>> Apart from TPDMs/STM/ETMs, we also have other coresight components in
>>> our internal device. About 80 ids are already used.
>>>
>>> Some components have fixed trace id in HW. If we use functions below to
>>> count the trace id, there will be conflict to other components.
>>>
>>> Can we use 1-15 for etm trace ids and 16 - 127 for other coresight
>>> components ? And handle trace ids in its' own driver ?
>>>
>> This will limit systems to 15 cores - some have more!
>>
> Correct
>
>>> static inline int coresight_get_system_trace_id(int id)
>>> {
>>> /* Start system IDs above the highest per CPU trace ID. */
>>> return coresigth_get_trace_id(cpumask_last(cpu_possible_mask) + 1);
>>> }
> Looking at my own suggestion again this won't work since it returns the same traceID
> when called multiple times.
>
> For this patchset and _without_ taking into account internal devices that have
> their traceID set in HW:
>
> 1. Define a bitmask that is 7 bit wide.
Should it be a 128 bit wide bitmask (0--127)?
> 2. By default, set bits under 0x10 and between 0x70 - 0x7F.
> 3. In coresight_get_system_trace_id(), drop the @id parameter and allocate the
> first available bit after cpumask_last(cpu_possible_mask) + 1.
Should it allocate the first available bit after (cpumask_last(cpu_possible_mask) *2 ) + 0x10 ?
Return the first zero bit position as the trace id and set the bit.
> 4. Define a new function called coresight_put_system_trace_id(int id) that
> clears the bit in the mask corresponding to @id.
>
> For now that should work.
>
>>> static inline int coresight_get_trace_id(int cpu)
>>> {
>>> /*
>>> * A trace ID of value 0 is invalid, so let's start at some
>>> * random value that fits in 7 bits and go from there. Since
>>> * the common convention is to have data trace IDs be I(N) + 1,
>>> * set instruction trace IDs as a function of the CPU number.
>>> */
>>> return (CORESIGHT_ETM_PMU_SEED + (cpu * 2));
>>> }
>>>
>> This fixed relationship between cpu and trace ID is used in the perf
>> tooling to populate the elements in the perf.data file to correctly
>> allow association between CPU and trace data, and thus allow correct
>> trace decode.
> TraceIDs associated to CPUs are communicated to the perf tooling by way of the
> perf header - theoretically we should be able to change the allocation scheme
> without impacting the decoding process.
>
>> It should be possible to create another more dynamic mapping scheme -
>> but this must include a way to support the perf requirements too.
>>
> TraceIDs have been a lurking problem for as long as the subsystem has existed.
> For now what I have suggested above should be sufficient to provide an
> in-between solution that doesn't hold back this patchset.
>
> That being said, we need to start thinking about the best way to do this. I
> will put a patchset together in the new year that aims in that direction.
>
>> Regards
>>
>> Mike
>>
>>> Thanks
>>>
>>> Jinlong Mao
>>>
>>>>> +
>>>>> +static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
>>>>> +{
>>>>> + struct device *dev = &adev->dev;
>>>>> + struct coresight_platform_data *pdata;
>>>>> + struct tpdm_drvdata *drvdata;
>>>>> + struct coresight_desc desc = { 0 };
>>>>> +
>>>>> + desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
>>>>> + if (!desc.name)
>>>>> + return -ENOMEM;
>>>>> + pdata = coresight_get_platform_data(dev);
>>>>> + if (IS_ERR(pdata))
>>>>> + return PTR_ERR(pdata);
>>>>> + adev->dev.platform_data = pdata;
>>>>> +
>>>>> + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
>>>>> + if (!drvdata)
>>>>> + return -ENOMEM;
>>>>> + drvdata->dev = &adev->dev;
>>>>> + dev_set_drvdata(dev, drvdata);
>>>>> +
>>>>> + drvdata->base = devm_ioremap_resource(dev, &adev->res);
>>>>> + if (!drvdata->base)
>>>>> + return -ENOMEM;
>>>>> +
>>>>> + mutex_init(&drvdata->lock);
>>>>> +
>>>>> + desc.type = CORESIGHT_DEV_TYPE_SOURCE;
>>>>> + desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
>>>>> + desc.ops = &tpdm_cs_ops;
>>>>> + desc.pdata = adev->dev.platform_data;
>>>>> + desc.dev = &adev->dev;
>>>>> + drvdata->csdev = coresight_register(&desc);
>>>>> + if (IS_ERR(drvdata->csdev))
>>>>> + return PTR_ERR(drvdata->csdev);
>>>>> +
>>>>> + tpdm_init_default_data(drvdata);
>>>>> + pm_runtime_put(&adev->dev);
>>>>> +
>>>>> + return 0;
>>>>> +}
>>>>> +
>>>>> +static void __exit tpdm_remove(struct amba_device *adev)
>>>>> +{
>>>>> + struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
>>>>> +
>>>>> + coresight_unregister(drvdata->csdev);
>>>>> +}
>>>>> +
>>>>> +static struct amba_id tpdm_ids[] = {
>>>>> + {
>>>>> + .id = 0x000f0e00,
>>>>> + .mask = 0x000fff00,
>>>>> + },
>>>>> + { 0, 0},
>>>>> +};
>>>>> +
>>>>> +static struct amba_driver tpdm_driver = {
>>>>> + .drv = {
>>>>> + .name = "coresight-tpdm",
>>>>> + .owner = THIS_MODULE,
>>>>> + .suppress_bind_attrs = true,
>>>>> + },
>>>>> + .probe = tpdm_probe,
>>>>> + .id_table = tpdm_ids,
>>>>> +};
>>>>> +
>>>>> +module_amba_driver(tpdm_driver);
>>>>> +
>>>>> +MODULE_LICENSE("GPL v2");
>>>>> +MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>> new file mode 100644
>>>>> index 000000000000..980ae90ff1c8
>>>>> --- /dev/null
>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>> @@ -0,0 +1,31 @@
>>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>>> +/*
>>>>> + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
>>>>> + */
>>>>> +
>>>>> +#ifndef _CORESIGHT_CORESIGHT_TPDM_H
>>>>> +#define _CORESIGHT_CORESIGHT_TPDM_H
>>>>> +
>>>>> +/* Default value of the traceid */
>>>>> +#define TPDM_TRACE_ID_START 128
>>>>> +
>>>>> +/**
>>>>> + * struct tpdm_drvdata - specifics associated to an TPDM component
>>>>> + * @base: memory mapped base address for this component.
>>>>> + * @dev: The device entity associated to this component.
>>>>> + * @csdev: component vitals needed by the framework.
>>>>> + * @lock: lock for the enable value.
>>>>> + * @enable: enable status of the component.
>>>>> + * @traceid: value of the current ID for this component.
>>>>> + */
>>>>> +
>>>>> +struct tpdm_drvdata {
>>>>> + void __iomem *base;
>>>>> + struct device *dev;
>>>>> + struct coresight_device *csdev;
>>>>> + struct mutex lock;
>>>>> + bool enable;
>>>>> + int traceid;
>>>>> +};
>>>>> +
>>>>> +#endif /* _CORESIGHT_CORESIGHT_TPDM_H */
>>>>> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
>>>>> index 93a2922b7653..e48d463be63b 100644
>>>>> --- a/include/linux/coresight.h
>>>>> +++ b/include/linux/coresight.h
>>>>> @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
>>>>> CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
>>>>> CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
>>>>> CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
>>>>> + CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
>>>>> };
>>>>>
>>>>> enum coresight_dev_subtype_helper {
>>>>> --
>>>>> 2.17.1
>>>>>
>>
>>
>> --
>> Mike Leach
>> Principal Engineer, ARM Ltd.
>> Manchester Design Centre. UK
Hey Jinlong,
On Fri, Jan 21, 2022 at 10:01:47PM +0800, Jinlong Mao wrote:
> Hi Mathieu,
>
> Good Day.
>
> On 12/17/2021 3:02 AM, Mathieu Poirier wrote:
> > [...]
> >
> > > > > > +
> > > > > > +static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
> > > > > > +{
> > > > > > + static int traceid = TPDM_TRACE_ID_START;
> > > > > > +
> > > > > > + drvdata->traceid = traceid++;
> > > > > > +}
> > > > > I have been specific on how to properly do this in the last revision. Given the
> > > > > above about the MAINTAINERS file, I am not sure that I will continue reviewing this set.
> > > > >
> > > > > There is also no need to rush another revision as I won't have the bandwidth to
> > > > > process it before the holidays.
> > > > >
> > > > > Thanks,
> > > > > Mathieu
> > > > Hi Mathieu,
> > > >
> > > > Sorry, not addressed your previous comments here.
> > > >
> > > > For the trace id, each coresight component has 7 bits to store the trace
> > > > id. So the trace id should be from 1 to 127 as 0 is invalid.
> > > IDs 0x70 - 0x7F (`112 - 127 ) are reserved - see the ARM Coresight
> > > Architecture specification v3.0
> > >
> > Correct
> >
> > > > Apart from TPDMs/STM/ETMs, we also have other coresight components in
> > > > our internal device. About 80 ids are already used.
> > > >
> > > > Some components have fixed trace id in HW. If we use functions below to
> > > > count the trace id, there will be conflict to other components.
> > > >
> > > > Can we use 1-15 for etm trace ids and 16 - 127 for other coresight
> > > > components ? And handle trace ids in its' own driver ?
> > > >
> > > This will limit systems to 15 cores - some have more!
> > >
> > Correct
> >
> > > > static inline int coresight_get_system_trace_id(int id)
> > > > {
> > > > /* Start system IDs above the highest per CPU trace ID. */
> > > > return coresigth_get_trace_id(cpumask_last(cpu_possible_mask) + 1);
> > > > }
> > Looking at my own suggestion again this won't work since it returns the same traceID
> > when called multiple times.
> >
> > For this patchset and _without_ taking into account internal devices that have
> > their traceID set in HW:
> >
> > 1. Define a bitmask that is 7 bit wide.
> Should it be a 128 bit wide bitmask? (0--127)?
Yes, you are correct.
> > 2. By default, set bits under 0x10 and between 0x70 - 0x7F.
> > 3. In coresight_get_system_trace_id(), drop the @id parameter and allocate the
> > first available bit after cpumask_last(cpu_possible_mask) + 1.
>
> Should it allocate the first available bit after (cpumask_last(cpu_possible_mask) *2 ) + 0x10 ?
> Return the first zero bit position as the trace id and set the bit.
I need to clarify something with Mike on this - I will get back to you on
Monday.
>
> > 4. Define a new function called coresight_put_system_trace_id(int id) that
> > clears the bit in the mask corresponding to @id.
> >
> > For now that should work.
> >
> > > > static inline int coresight_get_trace_id(int cpu)
> > > > {
> > > > /*
> > > > * A trace ID of value 0 is invalid, so let's start at some
> > > > * random value that fits in 7 bits and go from there. Since
> > > > * the common convention is to have data trace IDs be I(N) + 1,
> > > > * set instruction trace IDs as a function of the CPU number.
> > > > */
> > > > return (CORESIGHT_ETM_PMU_SEED + (cpu * 2));
> > > > }
> > > >
> > > This fixed relationship between cpu and trace ID is used in the perf
> > > tooling to populate the elements in the perf.data file to correctly
> > > allow association between CPU and trace data, and thus allow correct
> > > trace decode.
> > TraceIDs associated to CPUs are communicated to the perf tooling by way of the
> > perf header - theoretically we should be able to change the allocation scheme
> > without impacting the decoding process.
> >
> > > It should be possible to create another more dynamic mapping scheme -
> > > but this must include a way to support the perf requirements too.
> > >
> > TraceIDs have been a lurking problem for as long as the subsystem has existed.
> > For now what I have suggested above should be sufficient to provide an
> > in-between solution that doesn't hold back this patchset.
> >
> > That being said, we need to start thinking about the best way to do this. I
> > will put a patchset together in the new year that aims in that direction.
> >
> > > Regards
> > >
> > > Mike
> > >
> > > > Thanks
> > > >
> > > > Jinlong Mao
> > > >
> > > > > > +
> > > > > > +static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
> > > > > > +{
> > > > > > + struct device *dev = &adev->dev;
> > > > > > + struct coresight_platform_data *pdata;
> > > > > > + struct tpdm_drvdata *drvdata;
> > > > > > + struct coresight_desc desc = { 0 };
> > > > > > +
> > > > > > + desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
> > > > > > + if (!desc.name)
> > > > > > + return -ENOMEM;
> > > > > > + pdata = coresight_get_platform_data(dev);
> > > > > > + if (IS_ERR(pdata))
> > > > > > + return PTR_ERR(pdata);
> > > > > > + adev->dev.platform_data = pdata;
> > > > > > +
> > > > > > + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> > > > > > + if (!drvdata)
> > > > > > + return -ENOMEM;
> > > > > > + drvdata->dev = &adev->dev;
> > > > > > + dev_set_drvdata(dev, drvdata);
> > > > > > +
> > > > > > + drvdata->base = devm_ioremap_resource(dev, &adev->res);
> > > > > > + if (!drvdata->base)
> > > > > > + return -ENOMEM;
> > > > > > +
> > > > > > + mutex_init(&drvdata->lock);
> > > > > > +
> > > > > > + desc.type = CORESIGHT_DEV_TYPE_SOURCE;
> > > > > > + desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
> > > > > > + desc.ops = &tpdm_cs_ops;
> > > > > > + desc.pdata = adev->dev.platform_data;
> > > > > > + desc.dev = &adev->dev;
> > > > > > + drvdata->csdev = coresight_register(&desc);
> > > > > > + if (IS_ERR(drvdata->csdev))
> > > > > > + return PTR_ERR(drvdata->csdev);
> > > > > > +
> > > > > > + tpdm_init_default_data(drvdata);
> > > > > > + pm_runtime_put(&adev->dev);
> > > > > > +
> > > > > > + return 0;
> > > > > > +}
> > > > > > +
> > > > > > +static void __exit tpdm_remove(struct amba_device *adev)
> > > > > > +{
> > > > > > + struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
> > > > > > +
> > > > > > + coresight_unregister(drvdata->csdev);
> > > > > > +}
> > > > > > +
> > > > > > +static struct amba_id tpdm_ids[] = {
> > > > > > + {
> > > > > > + .id = 0x000f0e00,
> > > > > > + .mask = 0x000fff00,
> > > > > > + },
> > > > > > + { 0, 0},
> > > > > > +};
> > > > > > +
> > > > > > +static struct amba_driver tpdm_driver = {
> > > > > > + .drv = {
> > > > > > + .name = "coresight-tpdm",
> > > > > > + .owner = THIS_MODULE,
> > > > > > + .suppress_bind_attrs = true,
> > > > > > + },
> > > > > > + .probe = tpdm_probe,
> > > > > > + .id_table = tpdm_ids,
> > > > > > +};
> > > > > > +
> > > > > > +module_amba_driver(tpdm_driver);
> > > > > > +
> > > > > > +MODULE_LICENSE("GPL v2");
> > > > > > +MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
> > > > > > diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
> > > > > > new file mode 100644
> > > > > > index 000000000000..980ae90ff1c8
> > > > > > --- /dev/null
> > > > > > +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
> > > > > > @@ -0,0 +1,31 @@
> > > > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > > > +/*
> > > > > > + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
> > > > > > + */
> > > > > > +
> > > > > > +#ifndef _CORESIGHT_CORESIGHT_TPDM_H
> > > > > > +#define _CORESIGHT_CORESIGHT_TPDM_H
> > > > > > +
> > > > > > +/* Default value of the traceid */
> > > > > > +#define TPDM_TRACE_ID_START 128
> > > > > > +
> > > > > > +/**
> > > > > > + * struct tpdm_drvdata - specifics associated to an TPDM component
> > > > > > + * @base: memory mapped base address for this component.
> > > > > > + * @dev: The device entity associated to this component.
> > > > > > + * @csdev: component vitals needed by the framework.
> > > > > > + * @lock: lock for the enable value.
> > > > > > + * @enable: enable status of the component.
> > > > > > + * @traceid: value of the current ID for this component.
> > > > > > + */
> > > > > > +
> > > > > > +struct tpdm_drvdata {
> > > > > > + void __iomem *base;
> > > > > > + struct device *dev;
> > > > > > + struct coresight_device *csdev;
> > > > > > + struct mutex lock;
> > > > > > + bool enable;
> > > > > > + int traceid;
> > > > > > +};
> > > > > > +
> > > > > > +#endif /* _CORESIGHT_CORESIGHT_TPDM_H */
> > > > > > diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> > > > > > index 93a2922b7653..e48d463be63b 100644
> > > > > > --- a/include/linux/coresight.h
> > > > > > +++ b/include/linux/coresight.h
> > > > > > @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
> > > > > > CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
> > > > > > CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
> > > > > > CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
> > > > > > + CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
> > > > > > };
> > > > > >
> > > > > > enum coresight_dev_subtype_helper {
> > > > > > --
> > > > > > 2.17.1
> > > > > >
> > >
> > >
> > > --
> > > Mike Leach
> > > Principal Engineer, ARM Ltd.
> > > Manchester Design Centre. UK
Hi Mathieu,
Good afternoon.
On 1/22/2022 1:15 AM, Mathieu Poirier wrote:
> Hey Jinlong,
>
> On Fri, Jan 21, 2022 at 10:01:47PM +0800, Jinlong Mao wrote:
>> Hi Mathieu,
>>
>> Good Day.
>>
>> On 12/17/2021 3:02 AM, Mathieu Poirier wrote:
>>> [...]
>>>
>>>>>>> +
>>>>>>> +static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
>>>>>>> +{
>>>>>>> + static int traceid = TPDM_TRACE_ID_START;
>>>>>>> +
>>>>>>> + drvdata->traceid = traceid++;
>>>>>>> +}
>>>>>> I have been specific on how to properly do this in the last revision. Given the
>>>>>> above about the MAINTAINERS file, I am not sure that I will continue reviewing this set.
>>>>>>
>>>>>> There is also no need to rush another revision as I won't have the bandwidth to
>>>>>> process it before the holidays.
>>>>>>
>>>>>> Thanks,
>>>>>> Mathieu
>>>>> Hi Mathieu,
>>>>>
>>>>> Sorry, not addressed your previous comments here.
>>>>>
>>>>> For the trace id, each coresight component has 7 bits to store the trace
>>>>> id. So the trace id should be from 1 to 127 as 0 is invalid.
>>>> IDs 0x70 - 0x7F (`112 - 127 ) are reserved - see the ARM Coresight
>>>> Architecture specification v3.0
>>>>
>>> Correct
>>>
>>>>> Apart from TPDMs/STM/ETMs, we also have other coresight components in
>>>>> our internal device. About 80 ids are already used.
>>>>>
>>>>> Some components have fixed trace id in HW. If we use functions below to
>>>>> count the trace id, there will be conflict to other components.
>>>>>
>>>>> Can we use 1-15 for etm trace ids and 16 - 127 for other coresight
>>>>> components ? And handle trace ids in its' own driver ?
>>>>>
>>>> This will limit systems to 15 cores - some have more!
>>>>
>>> Correct
>>>
>>>>> static inline int coresight_get_system_trace_id(int id)
>>>>> {
>>>>> /* Start system IDs above the highest per CPU trace ID. */
>>>>> return coresigth_get_trace_id(cpumask_last(cpu_possible_mask) + 1);
>>>>> }
>>> Looking at my own suggestion again this won't work since it returns the same traceID
>>> when called multiple times.
>>>
>>> For this patchset and _without_ taking into account internal devices that have
>>> their traceID set in HW:
>>>
>>> 1. Define a bitmask that is 7 bit wide.
>> Should it be a 128 bit wide bitmask (0--127)?
> Yes, you are correct.
>
>>> 2. By default, set bits under 0x10 and between 0x70 - 0x7F.
>>> 3. In coresight_get_system_trace_id(), drop the @id parameter and allocate the
>>> first available bit after cpumask_last(cpu_possible_mask) + 1.
>> Should it allocate the first available bit after (cpumask_last(cpu_possible_mask) *2 ) + 0x10 ?
>> Return the first zero bit position as the trace id and set the bit.
> I need to clarify something with Mike on this - I will get back to you on
> Monday.
Do you have more comments on this ?
>
>>> 4. Define a new function called coresight_put_system_trace_id(int id) that
>>> clears the bit in the mask corresponding to @id.
>>>
>>> For now that should work.
>>>
>>>>> static inline int coresight_get_trace_id(int cpu)
>>>>> {
>>>>> /*
>>>>> * A trace ID of value 0 is invalid, so let's start at some
>>>>> * random value that fits in 7 bits and go from there. Since
>>>>> * the common convention is to have data trace IDs be I(N) + 1,
>>>>> * set instruction trace IDs as a function of the CPU number.
>>>>> */
>>>>> return (CORESIGHT_ETM_PMU_SEED + (cpu * 2));
>>>>> }
>>>>>
>>>> This fixed relationship between cpu and trace ID is used in the perf
>>>> tooling to populate the elements in the perf.data file to correctly
>>>> allow association between CPU and trace data, and thus allow correct
>>>> trace decode.
>>> TraceIDs associated to CPUs are communicated to the perf tooling by way of the
>>> perf header - theoretically we should be able to change the allocation scheme
>>> without impacting the decoding process.
>>>
>>>> It should be possible to create another more dynamic mapping scheme -
>>>> but this must include a way to support the perf requirements too.
>>>>
>>> TraceIDs have been a lurking problem for as long as the subsystem has existed.
>>> For now what I have suggested above should be sufficient to provide an
>>> in-between solution that doesn't hold back this patchset.
>>>
>>> That being said, we need to start thinking about the best way to do this. I
>>> will put a patchset together in the new year that aims in that direction.
>>>
>>>> Regards
>>>>
>>>> Mike
>>>>
>>>>> Thanks
>>>>>
>>>>> Jinlong Mao
>>>>>
>>>>>>> +
>>>>>>> +static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
>>>>>>> +{
>>>>>>> + struct device *dev = &adev->dev;
>>>>>>> + struct coresight_platform_data *pdata;
>>>>>>> + struct tpdm_drvdata *drvdata;
>>>>>>> + struct coresight_desc desc = { 0 };
>>>>>>> +
>>>>>>> + desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
>>>>>>> + if (!desc.name)
>>>>>>> + return -ENOMEM;
>>>>>>> + pdata = coresight_get_platform_data(dev);
>>>>>>> + if (IS_ERR(pdata))
>>>>>>> + return PTR_ERR(pdata);
>>>>>>> + adev->dev.platform_data = pdata;
>>>>>>> +
>>>>>>> + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
>>>>>>> + if (!drvdata)
>>>>>>> + return -ENOMEM;
>>>>>>> + drvdata->dev = &adev->dev;
>>>>>>> + dev_set_drvdata(dev, drvdata);
>>>>>>> +
>>>>>>> + drvdata->base = devm_ioremap_resource(dev, &adev->res);
>>>>>>> + if (!drvdata->base)
>>>>>>> + return -ENOMEM;
>>>>>>> +
>>>>>>> + mutex_init(&drvdata->lock);
>>>>>>> +
>>>>>>> + desc.type = CORESIGHT_DEV_TYPE_SOURCE;
>>>>>>> + desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
>>>>>>> + desc.ops = &tpdm_cs_ops;
>>>>>>> + desc.pdata = adev->dev.platform_data;
>>>>>>> + desc.dev = &adev->dev;
>>>>>>> + drvdata->csdev = coresight_register(&desc);
>>>>>>> + if (IS_ERR(drvdata->csdev))
>>>>>>> + return PTR_ERR(drvdata->csdev);
>>>>>>> +
>>>>>>> + tpdm_init_default_data(drvdata);
>>>>>>> + pm_runtime_put(&adev->dev);
>>>>>>> +
>>>>>>> + return 0;
>>>>>>> +}
>>>>>>> +
>>>>>>> +static void __exit tpdm_remove(struct amba_device *adev)
>>>>>>> +{
>>>>>>> + struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
>>>>>>> +
>>>>>>> + coresight_unregister(drvdata->csdev);
>>>>>>> +}
>>>>>>> +
>>>>>>> +static struct amba_id tpdm_ids[] = {
>>>>>>> + {
>>>>>>> + .id = 0x000f0e00,
>>>>>>> + .mask = 0x000fff00,
>>>>>>> + },
>>>>>>> + { 0, 0},
>>>>>>> +};
>>>>>>> +
>>>>>>> +static struct amba_driver tpdm_driver = {
>>>>>>> + .drv = {
>>>>>>> + .name = "coresight-tpdm",
>>>>>>> + .owner = THIS_MODULE,
>>>>>>> + .suppress_bind_attrs = true,
>>>>>>> + },
>>>>>>> + .probe = tpdm_probe,
>>>>>>> + .id_table = tpdm_ids,
>>>>>>> +};
>>>>>>> +
>>>>>>> +module_amba_driver(tpdm_driver);
>>>>>>> +
>>>>>>> +MODULE_LICENSE("GPL v2");
>>>>>>> +MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
>>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>>> new file mode 100644
>>>>>>> index 000000000000..980ae90ff1c8
>>>>>>> --- /dev/null
>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>>> @@ -0,0 +1,31 @@
>>>>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>>>>> +/*
>>>>>>> + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
>>>>>>> + */
>>>>>>> +
>>>>>>> +#ifndef _CORESIGHT_CORESIGHT_TPDM_H
>>>>>>> +#define _CORESIGHT_CORESIGHT_TPDM_H
>>>>>>> +
>>>>>>> +/* Default value of the traceid */
>>>>>>> +#define TPDM_TRACE_ID_START 128
>>>>>>> +
>>>>>>> +/**
>>>>>>> + * struct tpdm_drvdata - specifics associated to an TPDM component
>>>>>>> + * @base: memory mapped base address for this component.
>>>>>>> + * @dev: The device entity associated to this component.
>>>>>>> + * @csdev: component vitals needed by the framework.
>>>>>>> + * @lock: lock for the enable value.
>>>>>>> + * @enable: enable status of the component.
>>>>>>> + * @traceid: value of the current ID for this component.
>>>>>>> + */
>>>>>>> +
>>>>>>> +struct tpdm_drvdata {
>>>>>>> + void __iomem *base;
>>>>>>> + struct device *dev;
>>>>>>> + struct coresight_device *csdev;
>>>>>>> + struct mutex lock;
>>>>>>> + bool enable;
>>>>>>> + int traceid;
>>>>>>> +};
>>>>>>> +
>>>>>>> +#endif /* _CORESIGHT_CORESIGHT_TPDM_H */
>>>>>>> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
>>>>>>> index 93a2922b7653..e48d463be63b 100644
>>>>>>> --- a/include/linux/coresight.h
>>>>>>> +++ b/include/linux/coresight.h
>>>>>>> @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
>>>>>>> CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
>>>>>>> CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
>>>>>>> CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
>>>>>>> + CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
>>>>>>> };
>>>>>>>
>>>>>>> enum coresight_dev_subtype_helper {
>>>>>>> --
>>>>>>> 2.17.1
>>>>>>>
>>>>
>>>> --
>>>> Mike Leach
>>>> Principal Engineer, ARM Ltd.
>>>> Manchester Design Centre. UK
On Wed, Jan 26, 2022 at 03:07:38PM +0800, Jinlong Mao wrote:
> Hi Mathieu,
>
> Good afternoon.
>
> On 1/22/2022 1:15 AM, Mathieu Poirier wrote:
> > Hey Jinlong,
> >
> > On Fri, Jan 21, 2022 at 10:01:47PM +0800, Jinlong Mao wrote:
> > > Hi Mathieu,
> > >
> > > Good Day.
> > >
> > > On 12/17/2021 3:02 AM, Mathieu Poirier wrote:
> > > > [...]
> > > >
> > > > > > > > +
> > > > > > > > +static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
> > > > > > > > +{
> > > > > > > > + static int traceid = TPDM_TRACE_ID_START;
> > > > > > > > +
> > > > > > > > + drvdata->traceid = traceid++;
> > > > > > > > +}
> > > > > > > I have been specific on how to properly do this in the last revision. Given the
> > > > > > > above about the MAINTAINERS file, I am not sure that I will continue reviewing this set.
> > > > > > >
> > > > > > > There is also no need to rush another revision as I won't have the bandwidth to
> > > > > > > process it before the holidays.
> > > > > > >
> > > > > > > Thanks,
> > > > > > > Mathieu
> > > > > > Hi Mathieu,
> > > > > >
> > > > > > Sorry, not addressed your previous comments here.
> > > > > >
> > > > > > For the trace id, each coresight component has 7 bits to store the trace
> > > > > > id. So the trace id should be from 1 to 127 as 0 is invalid.
> > > > > IDs 0x70 - 0x7F (`112 - 127 ) are reserved - see the ARM Coresight
> > > > > Architecture specification v3.0
> > > > >
> > > > Correct
> > > >
> > > > > > Apart from TPDMs/STM/ETMs, we also have other coresight components in
> > > > > > our internal device. About 80 ids are already used.
> > > > > >
> > > > > > Some components have fixed trace id in HW. If we use functions below to
> > > > > > count the trace id, there will be conflict to other components.
> > > > > >
> > > > > > Can we use 1-15 for etm trace ids and 16 - 127 for other coresight
> > > > > > components ? And handle trace ids in its' own driver ?
> > > > > >
> > > > > This will limit systems to 15 cores - some have more!
> > > > >
> > > > Correct
> > > >
> > > > > > static inline int coresight_get_system_trace_id(int id)
> > > > > > {
> > > > > > /* Start system IDs above the highest per CPU trace ID. */
> > > > > > return coresigth_get_trace_id(cpumask_last(cpu_possible_mask) + 1);
> > > > > > }
> > > > Looking at my own suggestion again this won't work since it returns the same traceID
> > > > when called multiple times.
> > > >
> > > > For this patchset and _without_ taking into account internal devices that have
> > > > their traceID set in HW:
> > > >
> > > > 1. Define a bitmask that is 7 bit wide.
> > > Should it be a 128 bit wide bitmask? (0--127)?
> > Yes, you are correct.
> >
> > > > 2. By default, set bits under 0x10 and between 0x70 - 0x7F.
> > > > 3. In coresight_get_system_trace_id(), drop the @id parameter and allocate the
> > > > first available bit after cpumask_last(cpu_possible_mask) + 1.
> > > Should it allocate the first available bit after (cpumask_last(cpu_possible_mask) *2 ) + 0x10 ?
> > > Return the first zero bit position as the trace id and set the bit.
> > I need to clarify something with Mike on this - I will get back to you on
> > Monday.
> Do you have more comments on this ?
I just received clarifications on this - there is no need to continue enacting
the current scheme and as such reserving bits following the above formula will
not be needed either. Simply assigning free traceIDs based on request will
work just fine.
That of course is taking into account that 0x0, 0x1 and 0x70 - 0x7f are
reserved. 0x1 is currently used for STM and should eventually be fixed to
simply request a traceID the same way any other component do. You can fix it as
part of this set but it is not mandatory.
Let me know if there are things I haven't been clear on.
Thanks,
Mathieu
> >
> > > > 4. Define a new function called coresight_put_system_trace_id(int id) that
> > > > clears the bit in the mask corresponding to @id.
> > > >
> > > > For now that should work.
> > > >
> > > > > > static inline int coresight_get_trace_id(int cpu)
> > > > > > {
> > > > > > /*
> > > > > > * A trace ID of value 0 is invalid, so let's start at some
> > > > > > * random value that fits in 7 bits and go from there. Since
> > > > > > * the common convention is to have data trace IDs be I(N) + 1,
> > > > > > * set instruction trace IDs as a function of the CPU number.
> > > > > > */
> > > > > > return (CORESIGHT_ETM_PMU_SEED + (cpu * 2));
> > > > > > }
> > > > > >
> > > > > This fixed relationship between cpu and trace ID is used in the perf
> > > > > tooling to populate the elements in the perf.data file to correctly
> > > > > allow association between CPU and trace data, and thus allow correct
> > > > > trace decode.
> > > > TraceIDs associated to CPUs are communicated to the perf tooling by way of the
> > > > perf header - theoretically we should be able to change the allocation scheme
> > > > without impacting the decoding process.
> > > >
> > > > > It should be possible to create another more dynamic mapping scheme -
> > > > > but this must include a way to support the perf requirements too.
> > > > >
> > > > TraceIDs have been a lurking problem for as long as the subsystem has existed.
> > > > For now what I have suggested above should be sufficient to provide an
> > > > in-between solution that doesn't hold back this patchset.
> > > >
> > > > That being said, we need to start thinking about the best way to do this. I
> > > > will put a patchset together in the new year that aims in that direction.
> > > >
> > > > > Regards
> > > > >
> > > > > Mike
> > > > >
> > > > > > Thanks
> > > > > >
> > > > > > Jinlong Mao
> > > > > >
> > > > > > > > +
> > > > > > > > +static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
> > > > > > > > +{
> > > > > > > > + struct device *dev = &adev->dev;
> > > > > > > > + struct coresight_platform_data *pdata;
> > > > > > > > + struct tpdm_drvdata *drvdata;
> > > > > > > > + struct coresight_desc desc = { 0 };
> > > > > > > > +
> > > > > > > > + desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
> > > > > > > > + if (!desc.name)
> > > > > > > > + return -ENOMEM;
> > > > > > > > + pdata = coresight_get_platform_data(dev);
> > > > > > > > + if (IS_ERR(pdata))
> > > > > > > > + return PTR_ERR(pdata);
> > > > > > > > + adev->dev.platform_data = pdata;
> > > > > > > > +
> > > > > > > > + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> > > > > > > > + if (!drvdata)
> > > > > > > > + return -ENOMEM;
> > > > > > > > + drvdata->dev = &adev->dev;
> > > > > > > > + dev_set_drvdata(dev, drvdata);
> > > > > > > > +
> > > > > > > > + drvdata->base = devm_ioremap_resource(dev, &adev->res);
> > > > > > > > + if (!drvdata->base)
> > > > > > > > + return -ENOMEM;
> > > > > > > > +
> > > > > > > > + mutex_init(&drvdata->lock);
> > > > > > > > +
> > > > > > > > + desc.type = CORESIGHT_DEV_TYPE_SOURCE;
> > > > > > > > + desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
> > > > > > > > + desc.ops = &tpdm_cs_ops;
> > > > > > > > + desc.pdata = adev->dev.platform_data;
> > > > > > > > + desc.dev = &adev->dev;
> > > > > > > > + drvdata->csdev = coresight_register(&desc);
> > > > > > > > + if (IS_ERR(drvdata->csdev))
> > > > > > > > + return PTR_ERR(drvdata->csdev);
> > > > > > > > +
> > > > > > > > + tpdm_init_default_data(drvdata);
> > > > > > > > + pm_runtime_put(&adev->dev);
> > > > > > > > +
> > > > > > > > + return 0;
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > +static void __exit tpdm_remove(struct amba_device *adev)
> > > > > > > > +{
> > > > > > > > + struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
> > > > > > > > +
> > > > > > > > + coresight_unregister(drvdata->csdev);
> > > > > > > > +}
> > > > > > > > +
> > > > > > > > +static struct amba_id tpdm_ids[] = {
> > > > > > > > + {
> > > > > > > > + .id = 0x000f0e00,
> > > > > > > > + .mask = 0x000fff00,
> > > > > > > > + },
> > > > > > > > + { 0, 0},
> > > > > > > > +};
> > > > > > > > +
> > > > > > > > +static struct amba_driver tpdm_driver = {
> > > > > > > > + .drv = {
> > > > > > > > + .name = "coresight-tpdm",
> > > > > > > > + .owner = THIS_MODULE,
> > > > > > > > + .suppress_bind_attrs = true,
> > > > > > > > + },
> > > > > > > > + .probe = tpdm_probe,
> > > > > > > > + .id_table = tpdm_ids,
> > > > > > > > +};
> > > > > > > > +
> > > > > > > > +module_amba_driver(tpdm_driver);
> > > > > > > > +
> > > > > > > > +MODULE_LICENSE("GPL v2");
> > > > > > > > +MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
> > > > > > > > diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
> > > > > > > > new file mode 100644
> > > > > > > > index 000000000000..980ae90ff1c8
> > > > > > > > --- /dev/null
> > > > > > > > +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
> > > > > > > > @@ -0,0 +1,31 @@
> > > > > > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > > > > > +/*
> > > > > > > > + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
> > > > > > > > + */
> > > > > > > > +
> > > > > > > > +#ifndef _CORESIGHT_CORESIGHT_TPDM_H
> > > > > > > > +#define _CORESIGHT_CORESIGHT_TPDM_H
> > > > > > > > +
> > > > > > > > +/* Default value of the traceid */
> > > > > > > > +#define TPDM_TRACE_ID_START 128
> > > > > > > > +
> > > > > > > > +/**
> > > > > > > > + * struct tpdm_drvdata - specifics associated to an TPDM component
> > > > > > > > + * @base: memory mapped base address for this component.
> > > > > > > > + * @dev: The device entity associated to this component.
> > > > > > > > + * @csdev: component vitals needed by the framework.
> > > > > > > > + * @lock: lock for the enable value.
> > > > > > > > + * @enable: enable status of the component.
> > > > > > > > + * @traceid: value of the current ID for this component.
> > > > > > > > + */
> > > > > > > > +
> > > > > > > > +struct tpdm_drvdata {
> > > > > > > > + void __iomem *base;
> > > > > > > > + struct device *dev;
> > > > > > > > + struct coresight_device *csdev;
> > > > > > > > + struct mutex lock;
> > > > > > > > + bool enable;
> > > > > > > > + int traceid;
> > > > > > > > +};
> > > > > > > > +
> > > > > > > > +#endif /* _CORESIGHT_CORESIGHT_TPDM_H */
> > > > > > > > diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> > > > > > > > index 93a2922b7653..e48d463be63b 100644
> > > > > > > > --- a/include/linux/coresight.h
> > > > > > > > +++ b/include/linux/coresight.h
> > > > > > > > @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
> > > > > > > > CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
> > > > > > > > CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
> > > > > > > > CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
> > > > > > > > + CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
> > > > > > > > };
> > > > > > > >
> > > > > > > > enum coresight_dev_subtype_helper {
> > > > > > > > --
> > > > > > > > 2.17.1
> > > > > > > >
> > > > >
> > > > > --
> > > > > Mike Leach
> > > > > Principal Engineer, ARM Ltd.
> > > > > Manchester Design Centre. UK
On 1/26/2022 11:34 PM, Mathieu Poirier wrote:
> On Wed, Jan 26, 2022 at 03:07:38PM +0800, Jinlong Mao wrote:
>> Hi Mathieu,
>>
>> Good afternoon.
>>
>> On 1/22/2022 1:15 AM, Mathieu Poirier wrote:
>>> Hey Jinlong,
>>>
>>> On Fri, Jan 21, 2022 at 10:01:47PM +0800, Jinlong Mao wrote:
>>>> Hi Mathieu,
>>>>
>>>> Good Day.
>>>>
>>>> On 12/17/2021 3:02 AM, Mathieu Poirier wrote:
>>>>> [...]
>>>>>
>>>>>>>>> +
>>>>>>>>> +static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
>>>>>>>>> +{
>>>>>>>>> + static int traceid = TPDM_TRACE_ID_START;
>>>>>>>>> +
>>>>>>>>> + drvdata->traceid = traceid++;
>>>>>>>>> +}
>>>>>>>> I have been specific on how to properly do this in the last revision. Given the
>>>>>>>> above about the MAINTAINERS file, I am not sure that I will continue reviewing this set.
>>>>>>>>
>>>>>>>> There is also no need to rush another revision as I won't have the bandwidth to
>>>>>>>> process it before the holidays.
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Mathieu
>>>>>>> Hi Mathieu,
>>>>>>>
>>>>>>> Sorry, not addressed your previous comments here.
>>>>>>>
>>>>>>> For the trace id, each coresight component has 7 bits to store the trace
>>>>>>> id. So the trace id should be from 1 to 127 as 0 is invalid.
>>>>>> IDs 0x70 - 0x7F (`112 - 127 ) are reserved - see the ARM Coresight
>>>>>> Architecture specification v3.0
>>>>>>
>>>>> Correct
>>>>>
>>>>>>> Apart from TPDMs/STM/ETMs, we also have other coresight components in
>>>>>>> our internal device. About 80 ids are already used.
>>>>>>>
>>>>>>> Some components have fixed trace id in HW. If we use functions below to
>>>>>>> count the trace id, there will be conflict to other components.
>>>>>>>
>>>>>>> Can we use 1-15 for etm trace ids and 16 - 127 for other coresight
>>>>>>> components ? And handle trace ids in its' own driver ?
>>>>>>>
>>>>>> This will limit systems to 15 cores - some have more!
>>>>>>
>>>>> Correct
>>>>>
>>>>>>> static inline int coresight_get_system_trace_id(int id)
>>>>>>> {
>>>>>>> /* Start system IDs above the highest per CPU trace ID. */
>>>>>>> return coresigth_get_trace_id(cpumask_last(cpu_possible_mask) + 1);
>>>>>>> }
>>>>> Looking at my own suggestion again this won't work since it returns the same traceID
>>>>> when called multiple times.
>>>>>
>>>>> For this patchset and _without_ taking into account internal devices that have
>>>>> their traceID set in HW:
>>>>>
>>>>> 1. Define a bitmask that is 7 bit wide.
>>>> Should it be a 128 bit wide bitmask (0--127)?
>>> Yes, you are correct.
>>>
>>>>> 2. By default, set bits under 0x10 and between 0x70 - 0x7F.
>>>>> 3. In coresight_get_system_trace_id(), drop the @id parameter and allocate the
>>>>> first available bit after cpumask_last(cpu_possible_mask) + 1.
>>>> Should it allocate the first available bit after (cpumask_last(cpu_possible_mask) *2 ) + 0x10 ?
>>>> Return the first zero bit position as the trace id and set the bit.
>>> I need to clarify something with Mike on this - I will get back to you on
>>> Monday.
>> Do you have more comments on this ?
> I just received clarifications on this - there is no need to continue enacting
> the current scheme and as such reserving bits following the above formula will
> not be needed either. Simply assigning free traceIDs based on request will
> work just fine.
>
> That of course is taking into account that 0x0, 0x1 and 0x70 - 0x7f are
> reserved. 0x1 is currently used for STM and should eventually be fixed to
> simply request a traceID the same way any other component do. You can fix it as
> part of this set but it is not mandatory.
>
> Let me know if there are things I haven't been clear on.
>
> Thanks,
> Mathieu
Hi Mathieu,
Do you mean ETM sources and other sources can share the same
"coresight_get_trace_id" function ?
int trace_id = 1;
int coresight_get_trace_id ()
{
trace_id += 1;
if (trace_id > 1 && trace_id < 0x70)
return trace_id;
else
return -EINVAL;
}
or do we still need a different function for other sources like use
"coresight_get_system_trace_id" ?
Return the id from 1 and skip the ids which equeals to
CORESIGHT_ETM_PMU_SEED + (cpu * 2).
Thanks
Jinlong Mao
>>>>> 4. Define a new function called coresight_put_system_trace_id(int id) that
>>>>> clears the bit in the mask corresponding to @id.
>>>>>
>>>>> For now that should work.
>>>>>
>>>>>>> static inline int coresight_get_trace_id(int cpu)
>>>>>>> {
>>>>>>> /*
>>>>>>> * A trace ID of value 0 is invalid, so let's start at some
>>>>>>> * random value that fits in 7 bits and go from there. Since
>>>>>>> * the common convention is to have data trace IDs be I(N) + 1,
>>>>>>> * set instruction trace IDs as a function of the CPU number.
>>>>>>> */
>>>>>>> return (CORESIGHT_ETM_PMU_SEED + (cpu * 2));
>>>>>>> }
>>>>>>>
>>>>>> This fixed relationship between cpu and trace ID is used in the perf
>>>>>> tooling to populate the elements in the perf.data file to correctly
>>>>>> allow association between CPU and trace data, and thus allow correct
>>>>>> trace decode.
>>>>> TraceIDs associated to CPUs are communicated to the perf tooling by way of the
>>>>> perf header - theoretically we should be able to change the allocation scheme
>>>>> without impacting the decoding process.
>>>>>
>>>>>> It should be possible to create another more dynamic mapping scheme -
>>>>>> but this must include a way to support the perf requirements too.
>>>>>>
>>>>> TraceIDs have been a lurking problem for as long as the subsystem has existed.
>>>>> For now what I have suggested above should be sufficient to provide an
>>>>> in-between solution that doesn't hold back this patchset.
>>>>>
>>>>> That being said, we need to start thinking about the best way to do this. I
>>>>> will put a patchset together in the new year that aims in that direction.
>>>>>
>>>>>> Regards
>>>>>>
>>>>>> Mike
>>>>>>
>>>>>>> Thanks
>>>>>>>
>>>>>>> Jinlong Mao
>>>>>>>
>>>>>>>>> +
>>>>>>>>> +static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
>>>>>>>>> +{
>>>>>>>>> + struct device *dev = &adev->dev;
>>>>>>>>> + struct coresight_platform_data *pdata;
>>>>>>>>> + struct tpdm_drvdata *drvdata;
>>>>>>>>> + struct coresight_desc desc = { 0 };
>>>>>>>>> +
>>>>>>>>> + desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
>>>>>>>>> + if (!desc.name)
>>>>>>>>> + return -ENOMEM;
>>>>>>>>> + pdata = coresight_get_platform_data(dev);
>>>>>>>>> + if (IS_ERR(pdata))
>>>>>>>>> + return PTR_ERR(pdata);
>>>>>>>>> + adev->dev.platform_data = pdata;
>>>>>>>>> +
>>>>>>>>> + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
>>>>>>>>> + if (!drvdata)
>>>>>>>>> + return -ENOMEM;
>>>>>>>>> + drvdata->dev = &adev->dev;
>>>>>>>>> + dev_set_drvdata(dev, drvdata);
>>>>>>>>> +
>>>>>>>>> + drvdata->base = devm_ioremap_resource(dev, &adev->res);
>>>>>>>>> + if (!drvdata->base)
>>>>>>>>> + return -ENOMEM;
>>>>>>>>> +
>>>>>>>>> + mutex_init(&drvdata->lock);
>>>>>>>>> +
>>>>>>>>> + desc.type = CORESIGHT_DEV_TYPE_SOURCE;
>>>>>>>>> + desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
>>>>>>>>> + desc.ops = &tpdm_cs_ops;
>>>>>>>>> + desc.pdata = adev->dev.platform_data;
>>>>>>>>> + desc.dev = &adev->dev;
>>>>>>>>> + drvdata->csdev = coresight_register(&desc);
>>>>>>>>> + if (IS_ERR(drvdata->csdev))
>>>>>>>>> + return PTR_ERR(drvdata->csdev);
>>>>>>>>> +
>>>>>>>>> + tpdm_init_default_data(drvdata);
>>>>>>>>> + pm_runtime_put(&adev->dev);
>>>>>>>>> +
>>>>>>>>> + return 0;
>>>>>>>>> +}
>>>>>>>>> +
>>>>>>>>> +static void __exit tpdm_remove(struct amba_device *adev)
>>>>>>>>> +{
>>>>>>>>> + struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
>>>>>>>>> +
>>>>>>>>> + coresight_unregister(drvdata->csdev);
>>>>>>>>> +}
>>>>>>>>> +
>>>>>>>>> +static struct amba_id tpdm_ids[] = {
>>>>>>>>> + {
>>>>>>>>> + .id = 0x000f0e00,
>>>>>>>>> + .mask = 0x000fff00,
>>>>>>>>> + },
>>>>>>>>> + { 0, 0},
>>>>>>>>> +};
>>>>>>>>> +
>>>>>>>>> +static struct amba_driver tpdm_driver = {
>>>>>>>>> + .drv = {
>>>>>>>>> + .name = "coresight-tpdm",
>>>>>>>>> + .owner = THIS_MODULE,
>>>>>>>>> + .suppress_bind_attrs = true,
>>>>>>>>> + },
>>>>>>>>> + .probe = tpdm_probe,
>>>>>>>>> + .id_table = tpdm_ids,
>>>>>>>>> +};
>>>>>>>>> +
>>>>>>>>> +module_amba_driver(tpdm_driver);
>>>>>>>>> +
>>>>>>>>> +MODULE_LICENSE("GPL v2");
>>>>>>>>> +MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
>>>>>>>>> diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>>>>> new file mode 100644
>>>>>>>>> index 000000000000..980ae90ff1c8
>>>>>>>>> --- /dev/null
>>>>>>>>> +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
>>>>>>>>> @@ -0,0 +1,31 @@
>>>>>>>>> +/* SPDX-License-Identifier: GPL-2.0 */
>>>>>>>>> +/*
>>>>>>>>> + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
>>>>>>>>> + */
>>>>>>>>> +
>>>>>>>>> +#ifndef _CORESIGHT_CORESIGHT_TPDM_H
>>>>>>>>> +#define _CORESIGHT_CORESIGHT_TPDM_H
>>>>>>>>> +
>>>>>>>>> +/* Default value of the traceid */
>>>>>>>>> +#define TPDM_TRACE_ID_START 128
>>>>>>>>> +
>>>>>>>>> +/**
>>>>>>>>> + * struct tpdm_drvdata - specifics associated to an TPDM component
>>>>>>>>> + * @base: memory mapped base address for this component.
>>>>>>>>> + * @dev: The device entity associated to this component.
>>>>>>>>> + * @csdev: component vitals needed by the framework.
>>>>>>>>> + * @lock: lock for the enable value.
>>>>>>>>> + * @enable: enable status of the component.
>>>>>>>>> + * @traceid: value of the current ID for this component.
>>>>>>>>> + */
>>>>>>>>> +
>>>>>>>>> +struct tpdm_drvdata {
>>>>>>>>> + void __iomem *base;
>>>>>>>>> + struct device *dev;
>>>>>>>>> + struct coresight_device *csdev;
>>>>>>>>> + struct mutex lock;
>>>>>>>>> + bool enable;
>>>>>>>>> + int traceid;
>>>>>>>>> +};
>>>>>>>>> +
>>>>>>>>> +#endif /* _CORESIGHT_CORESIGHT_TPDM_H */
>>>>>>>>> diff --git a/include/linux/coresight.h b/include/linux/coresight.h
>>>>>>>>> index 93a2922b7653..e48d463be63b 100644
>>>>>>>>> --- a/include/linux/coresight.h
>>>>>>>>> +++ b/include/linux/coresight.h
>>>>>>>>> @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
>>>>>>>>> CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
>>>>>>>>> CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
>>>>>>>>> CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
>>>>>>>>> + CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
>>>>>>>>> };
>>>>>>>>>
>>>>>>>>> enum coresight_dev_subtype_helper {
>>>>>>>>> --
>>>>>>>>> 2.17.1
>>>>>>>>>
>>>>>> --
>>>>>> Mike Leach
>>>>>> Principal Engineer, ARM Ltd.
>>>>>> Manchester Design Centre. UK
Hi Jinlong,
On Fri, Jan 21, 2022 at 10:01:47PM +0800, Jinlong Mao wrote:
> Hi Mathieu,
>
> Good Day.
>
> On 12/17/2021 3:02 AM, Mathieu Poirier wrote:
> > [...]
> >
> > > > > > +
> > > > > > +static void tpdm_init_default_data(struct tpdm_drvdata *drvdata)
> > > > > > +{
> > > > > > + static int traceid = TPDM_TRACE_ID_START;
> > > > > > +
> > > > > > + drvdata->traceid = traceid++;
> > > > > > +}
> > > > > I have been specific on how to properly do this in the last revision. Given the
> > > > > above about the MAINTAINERS file, I am not sure that I will continue reviewing this set.
> > > > >
> > > > > There is also no need to rush another revision as I won't have the bandwidth to
> > > > > process it before the holidays.
> > > > >
> > > > > Thanks,
> > > > > Mathieu
> > > > Hi Mathieu,
> > > >
> > > > Sorry, not addressed your previous comments here.
> > > >
> > > > For the trace id, each coresight component has 7 bits to store the trace
> > > > id. So the trace id should be from 1 to 127 as 0 is invalid.
> > > IDs 0x70 - 0x7F (`112 - 127 ) are reserved - see the ARM Coresight
> > > Architecture specification v3.0
> > >
> > Correct
> >
> > > > Apart from TPDMs/STM/ETMs, we also have other coresight components in
> > > > our internal device. About 80 ids are already used.
> > > >
> > > > Some components have fixed trace id in HW. If we use functions below to
> > > > count the trace id, there will be conflict to other components.
> > > >
> > > > Can we use 1-15 for etm trace ids and 16 - 127 for other coresight
> > > > components ? And handle trace ids in its' own driver ?
> > > >
> > > This will limit systems to 15 cores - some have more!
> > >
> > Correct
> >
> > > > static inline int coresight_get_system_trace_id(int id)
> > > > {
> > > > /* Start system IDs above the highest per CPU trace ID. */
> > > > return coresigth_get_trace_id(cpumask_last(cpu_possible_mask) + 1);
> > > > }
> > Looking at my own suggestion again this won't work since it returns the same traceID
> > when called multiple times.
> >
> > For this patchset and _without_ taking into account internal devices that have
> > their traceID set in HW:
> >
> > 1. Define a bitmask that is 7 bit wide.
> Should it be a 128 bit wide bitmask? (0--127)?
> > 2. By default, set bits under 0x10 and between 0x70 - 0x7F.
> > 3. In coresight_get_system_trace_id(), drop the @id parameter and allocate the
> > first available bit after cpumask_last(cpu_possible_mask) + 1.
>
> Should it allocate the first available bit after (cpumask_last(cpu_possible_mask) *2 ) + 0x10 ?
> Return the first zero bit position as the trace id and set the bit.
Please ignore my email from January 26th and proceed exactly as you stated
above.
I had conversations with Suzuki and Mike and providing an appropriate fix for this
issue needs more investigation.
Aplogies for the flip-flopping, as I said earlier this is a complex problem
we've been restling with for quite some time now.
Thanks,
Mathieu
>
> > 4. Define a new function called coresight_put_system_trace_id(int id) that
> > clears the bit in the mask corresponding to @id.
> >
> > For now that should work.
> >
> > > > static inline int coresight_get_trace_id(int cpu)
> > > > {
> > > > /*
> > > > * A trace ID of value 0 is invalid, so let's start at some
> > > > * random value that fits in 7 bits and go from there. Since
> > > > * the common convention is to have data trace IDs be I(N) + 1,
> > > > * set instruction trace IDs as a function of the CPU number.
> > > > */
> > > > return (CORESIGHT_ETM_PMU_SEED + (cpu * 2));
> > > > }
> > > >
> > > This fixed relationship between cpu and trace ID is used in the perf
> > > tooling to populate the elements in the perf.data file to correctly
> > > allow association between CPU and trace data, and thus allow correct
> > > trace decode.
> > TraceIDs associated to CPUs are communicated to the perf tooling by way of the
> > perf header - theoretically we should be able to change the allocation scheme
> > without impacting the decoding process.
> >
> > > It should be possible to create another more dynamic mapping scheme -
> > > but this must include a way to support the perf requirements too.
> > >
> > TraceIDs have been a lurking problem for as long as the subsystem has existed.
> > For now what I have suggested above should be sufficient to provide an
> > in-between solution that doesn't hold back this patchset.
> >
> > That being said, we need to start thinking about the best way to do this. I
> > will put a patchset together in the new year that aims in that direction.
> >
> > > Regards
> > >
> > > Mike
> > >
> > > > Thanks
> > > >
> > > > Jinlong Mao
> > > >
> > > > > > +
> > > > > > +static int tpdm_probe(struct amba_device *adev, const struct amba_id *id)
> > > > > > +{
> > > > > > + struct device *dev = &adev->dev;
> > > > > > + struct coresight_platform_data *pdata;
> > > > > > + struct tpdm_drvdata *drvdata;
> > > > > > + struct coresight_desc desc = { 0 };
> > > > > > +
> > > > > > + desc.name = coresight_alloc_device_name(&tpdm_devs, dev);
> > > > > > + if (!desc.name)
> > > > > > + return -ENOMEM;
> > > > > > + pdata = coresight_get_platform_data(dev);
> > > > > > + if (IS_ERR(pdata))
> > > > > > + return PTR_ERR(pdata);
> > > > > > + adev->dev.platform_data = pdata;
> > > > > > +
> > > > > > + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
> > > > > > + if (!drvdata)
> > > > > > + return -ENOMEM;
> > > > > > + drvdata->dev = &adev->dev;
> > > > > > + dev_set_drvdata(dev, drvdata);
> > > > > > +
> > > > > > + drvdata->base = devm_ioremap_resource(dev, &adev->res);
> > > > > > + if (!drvdata->base)
> > > > > > + return -ENOMEM;
> > > > > > +
> > > > > > + mutex_init(&drvdata->lock);
> > > > > > +
> > > > > > + desc.type = CORESIGHT_DEV_TYPE_SOURCE;
> > > > > > + desc.subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_SYS;
> > > > > > + desc.ops = &tpdm_cs_ops;
> > > > > > + desc.pdata = adev->dev.platform_data;
> > > > > > + desc.dev = &adev->dev;
> > > > > > + drvdata->csdev = coresight_register(&desc);
> > > > > > + if (IS_ERR(drvdata->csdev))
> > > > > > + return PTR_ERR(drvdata->csdev);
> > > > > > +
> > > > > > + tpdm_init_default_data(drvdata);
> > > > > > + pm_runtime_put(&adev->dev);
> > > > > > +
> > > > > > + return 0;
> > > > > > +}
> > > > > > +
> > > > > > +static void __exit tpdm_remove(struct amba_device *adev)
> > > > > > +{
> > > > > > + struct tpdm_drvdata *drvdata = dev_get_drvdata(&adev->dev);
> > > > > > +
> > > > > > + coresight_unregister(drvdata->csdev);
> > > > > > +}
> > > > > > +
> > > > > > +static struct amba_id tpdm_ids[] = {
> > > > > > + {
> > > > > > + .id = 0x000f0e00,
> > > > > > + .mask = 0x000fff00,
> > > > > > + },
> > > > > > + { 0, 0},
> > > > > > +};
> > > > > > +
> > > > > > +static struct amba_driver tpdm_driver = {
> > > > > > + .drv = {
> > > > > > + .name = "coresight-tpdm",
> > > > > > + .owner = THIS_MODULE,
> > > > > > + .suppress_bind_attrs = true,
> > > > > > + },
> > > > > > + .probe = tpdm_probe,
> > > > > > + .id_table = tpdm_ids,
> > > > > > +};
> > > > > > +
> > > > > > +module_amba_driver(tpdm_driver);
> > > > > > +
> > > > > > +MODULE_LICENSE("GPL v2");
> > > > > > +MODULE_DESCRIPTION("Trace, Profiling & Diagnostic Monitor driver");
> > > > > > diff --git a/drivers/hwtracing/coresight/coresight-tpdm.h b/drivers/hwtracing/coresight/coresight-tpdm.h
> > > > > > new file mode 100644
> > > > > > index 000000000000..980ae90ff1c8
> > > > > > --- /dev/null
> > > > > > +++ b/drivers/hwtracing/coresight/coresight-tpdm.h
> > > > > > @@ -0,0 +1,31 @@
> > > > > > +/* SPDX-License-Identifier: GPL-2.0 */
> > > > > > +/*
> > > > > > + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
> > > > > > + */
> > > > > > +
> > > > > > +#ifndef _CORESIGHT_CORESIGHT_TPDM_H
> > > > > > +#define _CORESIGHT_CORESIGHT_TPDM_H
> > > > > > +
> > > > > > +/* Default value of the traceid */
> > > > > > +#define TPDM_TRACE_ID_START 128
> > > > > > +
> > > > > > +/**
> > > > > > + * struct tpdm_drvdata - specifics associated to an TPDM component
> > > > > > + * @base: memory mapped base address for this component.
> > > > > > + * @dev: The device entity associated to this component.
> > > > > > + * @csdev: component vitals needed by the framework.
> > > > > > + * @lock: lock for the enable value.
> > > > > > + * @enable: enable status of the component.
> > > > > > + * @traceid: value of the current ID for this component.
> > > > > > + */
> > > > > > +
> > > > > > +struct tpdm_drvdata {
> > > > > > + void __iomem *base;
> > > > > > + struct device *dev;
> > > > > > + struct coresight_device *csdev;
> > > > > > + struct mutex lock;
> > > > > > + bool enable;
> > > > > > + int traceid;
> > > > > > +};
> > > > > > +
> > > > > > +#endif /* _CORESIGHT_CORESIGHT_TPDM_H */
> > > > > > diff --git a/include/linux/coresight.h b/include/linux/coresight.h
> > > > > > index 93a2922b7653..e48d463be63b 100644
> > > > > > --- a/include/linux/coresight.h
> > > > > > +++ b/include/linux/coresight.h
> > > > > > @@ -65,6 +65,7 @@ enum coresight_dev_subtype_source {
> > > > > > CORESIGHT_DEV_SUBTYPE_SOURCE_PROC,
> > > > > > CORESIGHT_DEV_SUBTYPE_SOURCE_BUS,
> > > > > > CORESIGHT_DEV_SUBTYPE_SOURCE_SOFTWARE,
> > > > > > + CORESIGHT_DEV_SUBTYPE_SOURCE_SYS,
> > > > > > };
> > > > > >
> > > > > > enum coresight_dev_subtype_helper {
> > > > > > --
> > > > > > 2.17.1
> > > > > >
> > >
> > >
> > > --
> > > Mike Leach
> > > Principal Engineer, ARM Ltd.
> > > Manchester Design Centre. UK