Skip to content

Commit e54a52a

Browse files
Yuanfang ZhangSuzuki K Poulose
authored andcommitted
coresight: add coresight Trace Network On Chip driver
Add a driver to support Coresight device Trace Network On Chip (TNOC), which is an integration hierarchy integrating functionalities of TPDA and funnels. It aggregates the trace and transports to coresight trace bus. Compared to current configuration, it has the following advantages: 1. Reduce wires between subsystems. 2. Continue cleaning the infrastructure. 3. Reduce Data overhead by transporting raw data from source to target. +------------------------+ +-------------------------+ | Video Subsystem | |Video Subsystem | | +-------------+ | | +------------+ | | | Video TPDM | | | | Video TPDM | | | +-------------+ | | +------------+ | | | | | | | | v | | v | | +---------------+ | | +-----------+ | | | Video funnel | | | |Video TNOC | | | +---------------+ | | +-----------+ | +------------|-----------+ +------------|------------+ | | v-----+ | +--------------------|---------+ | | Multimedia v | | | Subsystem +--------+ | | | | TPDA | | v | +----|---+ | +---------------------+ | | | | Aggregator TNOC | | | | +----------|----------+ | +-- | | | | | | | | | | | +------v-----+ | | | | Funnel | | | | +------------+ | | +----------------|-------------+ | | | v v +--------------------+ +------------------+ | Coresight Sink | | Coresight Sink | +--------------------+ +------------------+ Current Configuration TNOC Reviewed-by: Leo Yan <leo.yan@arm.com> Signed-off-by: Yuanfang Zhang <quic_yuanfang@quicinc.com> Reviewed-by: Mike Leach <mike.leach@linaro.com> Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/r/20250710-trace-noc-v11-2-f849075c40b8@quicinc.com
1 parent 931c931 commit e54a52a

3 files changed

Lines changed: 255 additions & 0 deletions

File tree

drivers/hwtracing/coresight/Kconfig

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,4 +268,16 @@ config CORESIGHT_KUNIT_TESTS
268268
Enable Coresight unit tests. Only useful for development and not
269269
intended for production.
270270

271+
config CORESIGHT_TNOC
272+
tristate "Coresight Trace Network On Chip driver"
273+
help
274+
This driver provides support for Trace Network On Chip (TNOC) component.
275+
TNOC is an interconnect used to collect traces from various subsystems
276+
and transport to a coresight trace sink. It sits in the different
277+
tiles of SOC and aggregates the trace local to the tile and transports
278+
it another tile or to coresight trace sink eventually.
279+
280+
To compile this driver as a module, choose M here: the module will be
281+
called coresight-tnoc.
282+
271283
endif

drivers/hwtracing/coresight/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ obj-$(CONFIG_CORESIGHT_SINK_TPIU) += coresight-tpiu.o
3636
obj-$(CONFIG_CORESIGHT_SINK_ETBV10) += coresight-etb10.o
3737
obj-$(CONFIG_CORESIGHT_LINKS_AND_SINKS) += coresight-funnel.o \
3838
coresight-replicator.o
39+
obj-$(CONFIG_CORESIGHT_TNOC) += coresight-tnoc.o
3940
obj-$(CONFIG_CORESIGHT_SOURCE_ETM3X) += coresight-etm3x.o
4041
coresight-etm3x-y := coresight-etm3x-core.o coresight-etm-cp14.o \
4142
coresight-etm3x-sysfs.o
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
// SPDX-License-Identifier: GPL-2.0-only
2+
/*
3+
* Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved.
4+
*/
5+
6+
#include <linux/amba/bus.h>
7+
#include <linux/coresight.h>
8+
#include <linux/device.h>
9+
#include <linux/io.h>
10+
#include <linux/kernel.h>
11+
#include <linux/module.h>
12+
#include <linux/of.h>
13+
#include <linux/platform_device.h>
14+
15+
#include "coresight-priv.h"
16+
#include "coresight-trace-id.h"
17+
18+
#define TRACE_NOC_CTRL 0x008
19+
#define TRACE_NOC_XLD 0x010
20+
#define TRACE_NOC_FREQVAL 0x018
21+
#define TRACE_NOC_SYNCR 0x020
22+
23+
/* Enable generation of output ATB traffic.*/
24+
#define TRACE_NOC_CTRL_PORTEN BIT(0)
25+
/* Sets the type of issued ATB FLAG packets.*/
26+
#define TRACE_NOC_CTRL_FLAGTYPE BIT(7)
27+
/* Sets the type of issued ATB FREQ packet*/
28+
#define TRACE_NOC_CTRL_FREQTYPE BIT(8)
29+
30+
#define TRACE_NOC_SYNC_INTERVAL 0xFFFF
31+
32+
/*
33+
* struct trace_noc_drvdata - specifics associated to a trace noc component
34+
* @base: memory mapped base address for this component.
35+
* @dev: device node for trace_noc_drvdata.
36+
* @csdev: component vitals needed by the framework.
37+
* @spinlock: serialize enable/disable operation.
38+
* @atid: id for the trace packet.
39+
*/
40+
struct trace_noc_drvdata {
41+
void __iomem *base;
42+
struct device *dev;
43+
struct coresight_device *csdev;
44+
spinlock_t spinlock;
45+
u32 atid;
46+
};
47+
48+
DEFINE_CORESIGHT_DEVLIST(trace_noc_devs, "traceNoc");
49+
50+
static void trace_noc_enable_hw(struct trace_noc_drvdata *drvdata)
51+
{
52+
u32 val;
53+
54+
/* Set ATID */
55+
writel_relaxed(drvdata->atid, drvdata->base + TRACE_NOC_XLD);
56+
57+
/* Set the data word count between 'SYNC' packets */
58+
writel_relaxed(TRACE_NOC_SYNC_INTERVAL, drvdata->base + TRACE_NOC_SYNCR);
59+
60+
/* Set the Control register:
61+
* - Set the FLAG packets to 'FLAG' packets
62+
* - Set the FREQ packets to 'FREQ_TS' packets
63+
* - Enable generation of output ATB traffic
64+
*/
65+
66+
val = readl_relaxed(drvdata->base + TRACE_NOC_CTRL);
67+
68+
val &= ~TRACE_NOC_CTRL_FLAGTYPE;
69+
val |= TRACE_NOC_CTRL_FREQTYPE;
70+
val |= TRACE_NOC_CTRL_PORTEN;
71+
72+
writel(val, drvdata->base + TRACE_NOC_CTRL);
73+
}
74+
75+
static int trace_noc_enable(struct coresight_device *csdev, struct coresight_connection *inport,
76+
struct coresight_connection *outport)
77+
{
78+
struct trace_noc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
79+
80+
scoped_guard(spinlock, &drvdata->spinlock) {
81+
if (csdev->refcnt == 0)
82+
trace_noc_enable_hw(drvdata);
83+
84+
csdev->refcnt++;
85+
}
86+
87+
dev_dbg(drvdata->dev, "Trace NOC is enabled\n");
88+
return 0;
89+
}
90+
91+
static void trace_noc_disable(struct coresight_device *csdev, struct coresight_connection *inport,
92+
struct coresight_connection *outport)
93+
{
94+
struct trace_noc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
95+
96+
scoped_guard(spinlock, &drvdata->spinlock) {
97+
if (--csdev->refcnt == 0)
98+
writel(0x0, drvdata->base + TRACE_NOC_CTRL);
99+
}
100+
dev_dbg(drvdata->dev, "Trace NOC is disabled\n");
101+
}
102+
103+
static int trace_noc_id(struct coresight_device *csdev, __maybe_unused enum cs_mode mode,
104+
__maybe_unused struct coresight_device *sink)
105+
{
106+
struct trace_noc_drvdata *drvdata;
107+
108+
drvdata = dev_get_drvdata(csdev->dev.parent);
109+
110+
return drvdata->atid;
111+
}
112+
113+
static const struct coresight_ops_link trace_noc_link_ops = {
114+
.enable = trace_noc_enable,
115+
.disable = trace_noc_disable,
116+
};
117+
118+
static const struct coresight_ops trace_noc_cs_ops = {
119+
.trace_id = trace_noc_id,
120+
.link_ops = &trace_noc_link_ops,
121+
};
122+
123+
static int trace_noc_init_default_data(struct trace_noc_drvdata *drvdata)
124+
{
125+
int atid;
126+
127+
atid = coresight_trace_id_get_system_id();
128+
if (atid < 0)
129+
return atid;
130+
131+
drvdata->atid = atid;
132+
133+
return 0;
134+
}
135+
136+
static ssize_t traceid_show(struct device *dev,
137+
struct device_attribute *attr, char *buf)
138+
{
139+
unsigned long val;
140+
struct trace_noc_drvdata *drvdata = dev_get_drvdata(dev->parent);
141+
142+
val = drvdata->atid;
143+
return sprintf(buf, "%#lx\n", val);
144+
}
145+
static DEVICE_ATTR_RO(traceid);
146+
147+
static struct attribute *coresight_tnoc_attrs[] = {
148+
&dev_attr_traceid.attr,
149+
NULL,
150+
};
151+
152+
static const struct attribute_group coresight_tnoc_group = {
153+
.attrs = coresight_tnoc_attrs,
154+
};
155+
156+
static const struct attribute_group *coresight_tnoc_groups[] = {
157+
&coresight_tnoc_group,
158+
NULL,
159+
};
160+
161+
static int trace_noc_probe(struct amba_device *adev, const struct amba_id *id)
162+
{
163+
struct device *dev = &adev->dev;
164+
struct coresight_platform_data *pdata;
165+
struct trace_noc_drvdata *drvdata;
166+
struct coresight_desc desc = { 0 };
167+
int ret;
168+
169+
desc.name = coresight_alloc_device_name(&trace_noc_devs, dev);
170+
if (!desc.name)
171+
return -ENOMEM;
172+
173+
pdata = coresight_get_platform_data(dev);
174+
if (IS_ERR(pdata))
175+
return PTR_ERR(pdata);
176+
adev->dev.platform_data = pdata;
177+
178+
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
179+
if (!drvdata)
180+
return -ENOMEM;
181+
182+
drvdata->dev = &adev->dev;
183+
dev_set_drvdata(dev, drvdata);
184+
185+
drvdata->base = devm_ioremap_resource(dev, &adev->res);
186+
if (!drvdata->base)
187+
return -ENOMEM;
188+
189+
spin_lock_init(&drvdata->spinlock);
190+
191+
ret = trace_noc_init_default_data(drvdata);
192+
if (ret)
193+
return ret;
194+
195+
desc.ops = &trace_noc_cs_ops;
196+
desc.type = CORESIGHT_DEV_TYPE_LINK;
197+
desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_MERG;
198+
desc.pdata = adev->dev.platform_data;
199+
desc.dev = &adev->dev;
200+
desc.access = CSDEV_ACCESS_IOMEM(drvdata->base);
201+
desc.groups = coresight_tnoc_groups;
202+
drvdata->csdev = coresight_register(&desc);
203+
if (IS_ERR(drvdata->csdev)) {
204+
coresight_trace_id_put_system_id(drvdata->atid);
205+
return PTR_ERR(drvdata->csdev);
206+
}
207+
pm_runtime_put(&adev->dev);
208+
209+
return 0;
210+
}
211+
212+
static void trace_noc_remove(struct amba_device *adev)
213+
{
214+
struct trace_noc_drvdata *drvdata = dev_get_drvdata(&adev->dev);
215+
216+
coresight_unregister(drvdata->csdev);
217+
coresight_trace_id_put_system_id(drvdata->atid);
218+
}
219+
220+
static struct amba_id trace_noc_ids[] = {
221+
{
222+
.id = 0x000f0c00,
223+
.mask = 0x00ffff00,
224+
},
225+
{},
226+
};
227+
MODULE_DEVICE_TABLE(amba, trace_noc_ids);
228+
229+
static struct amba_driver trace_noc_driver = {
230+
.drv = {
231+
.name = "coresight-trace-noc",
232+
.suppress_bind_attrs = true,
233+
},
234+
.probe = trace_noc_probe,
235+
.remove = trace_noc_remove,
236+
.id_table = trace_noc_ids,
237+
};
238+
239+
module_amba_driver(trace_noc_driver);
240+
241+
MODULE_LICENSE("GPL");
242+
MODULE_DESCRIPTION("Trace NOC driver");

0 commit comments

Comments
 (0)