This patch series adds support for the Qualcomm CoreSight Interconnect TNOC (Trace Network On Chip) block, which acts as a CoreSight graph link forwarding trace data from subsystems to the Aggregator TNOC. Unlike the Aggregator TNOC, this block does not support aggregation or ATID assignment.
Signed-off-by: Yuanfang Zhang yuanfang.zhang@oss.qualcomm.com --- Changes in v4: - Fix unintended blank line removals in trace_noc_enable_hw. - Link to v3: https://lore.kernel.org/r/20250828-itnoc-v3-0-f1b55dea7a27@oss.qualcomm.com
Changes in v3: - Add detail for changes in V2. - Remove '#address-cells' and '#size-cells' properties from in-ports field. - Fix comment indentation for packet description. - Link to v2: https://lore.kernel.org/r/20250819-itnoc-v2-0-2d0e6be44e2f@oss.qualcomm.com
Changes in v2: - Removed the trailing '|' after the description in qcom,coresight-itnoc.yaml. - Dropped the 'select' section from the YAML file. - Updated node name to use a more generic naming convention. - Removed the 'items' property from the compatible field. - Deleted the description for the reg property. - Dropped clock-names and adjusted the order of clock-names and clocks. - Moved additionalProperties to follow the $ref of out-ports. - Change "atid" type from u32 to int, set it as "-EOPNOTSUPP" for non-AMBA device. - Link to v1: https://lore.kernel.org/r/20250815-itnoc-v1-0-62c8e4f7ad32@oss.qualcomm.com
--- Yuanfang Zhang (3): dt-bindings: arm: qcom: Add Coresight Interconnect TNOC coresight-tnoc: add platform driver to support Interconnect TNOC coresight-tnoc: Add runtime PM support for Interconnect TNOC
.../bindings/arm/qcom,coresight-itnoc.yaml | 90 ++++++++++++++ drivers/hwtracing/coresight/coresight-tnoc.c | 136 +++++++++++++++++++-- 2 files changed, 215 insertions(+), 11 deletions(-) --- base-commit: 2b52cf338d39d684a1c6af298e8204902c026aca change-id: 20250815-itnoc-460273d1b80c
Best regards,
Add device tree binding for Qualcomm Coresight Interconnect Trace Network On Chip (ITNOC). This TNOC acts as a CoreSight graph link that forwards trace data from a subsystem to the Aggregator TNOC, without aggregation or ATID functionality.
Signed-off-by: Yuanfang Zhang yuanfang.zhang@oss.qualcomm.com Reviewed-by: Rob Herring (Arm) robh@kernel.org --- .../bindings/arm/qcom,coresight-itnoc.yaml | 90 ++++++++++++++++++++++ 1 file changed, 90 insertions(+)
diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-itnoc.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-itnoc.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8936bb7c3e8ea267ca66e0cc3fc4dac33ba6de30 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-itnoc.yaml @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/qcom,coresight-itnoc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Interconnect Trace Network On Chip - ITNOC + +maintainers: + - Yuanfang Zhang yuanfang.zhang@oss.qualcomm.com + +description: + The Interconnect TNOC is a CoreSight graph link that forwards trace data + from a subsystem to the Aggregator TNOC. Compared to Aggregator TNOC, it + does not have aggregation and ATID functionality. + +properties: + $nodename: + pattern: "^itnoc(@[0-9a-f]+)?$" + + compatible: + const: qcom,coresight-itnoc + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + items: + - const: apb + + in-ports: + $ref: /schemas/graph.yaml#/properties/ports + + patternProperties: + '^port(@[0-9a-f]{1,2})?$': + description: Input connections from CoreSight Trace Bus + $ref: /schemas/graph.yaml#/properties/port + + out-ports: + $ref: /schemas/graph.yaml#/properties/ports + additionalProperties: false + + properties: + port: + description: out connections to aggregator TNOC + $ref: /schemas/graph.yaml#/properties/port + +required: + - compatible + - reg + - clocks + - clock-names + - in-ports + - out-ports + +additionalProperties: false + +examples: + - | + itnoc@109ac000 { + compatible = "qcom,coresight-itnoc"; + reg = <0x109ac000 0x1000>; + + clocks = <&aoss_qmp>; + clock-names = "apb"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + tn_ic_in_tpdm_dcc: endpoint { + remote-endpoint = <&tpdm_dcc_out_tn_ic>; + }; + }; + }; + + out-ports { + port { + tn_ic_out_tnoc_aggr: endpoint { + /* to Aggregator TNOC input */ + remote-endpoint = <&tn_ag_in_tn_ic>; + }; + }; + }; + }; +...
This patch adds platform driver support for the CoreSight Interconnect TNOC, Interconnect TNOC is a CoreSight link that forwards trace data from a subsystem to the Aggregator TNOC. Compared to Aggregator TNOC, it does not have aggregation and ATID functionality.
Key changes: - Add platform driver `coresight-itnoc` with device tree match support. - Refactor probe logic into a common `_tnoc_probe()` function. - Conditionally initialize ATID only for AMBA-based TNOC blocks.
Signed-off-by: Yuanfang Zhang yuanfang.zhang@oss.qualcomm.com Reviewed-by: Leo Yan leo.yan@arm.com --- drivers/hwtracing/coresight/coresight-tnoc.c | 113 ++++++++++++++++++++++++--- 1 file changed, 102 insertions(+), 11 deletions(-)
diff --git a/drivers/hwtracing/coresight/coresight-tnoc.c b/drivers/hwtracing/coresight/coresight-tnoc.c index d542df46ea39314605290311f683010337bfd4bd..5be882300d79bc0173aa6a19d7da1d48c4aaca9c 100644 --- a/drivers/hwtracing/coresight/coresight-tnoc.c +++ b/drivers/hwtracing/coresight/coresight-tnoc.c @@ -34,6 +34,7 @@ * @base: memory mapped base address for this component. * @dev: device node for trace_noc_drvdata. * @csdev: component vitals needed by the framework. + * @pclk: APB clock if present, otherwise NULL * @spinlock: serialize enable/disable operation. * @atid: id for the trace packet. */ @@ -41,8 +42,9 @@ struct trace_noc_drvdata { void __iomem *base; struct device *dev; struct coresight_device *csdev; + struct clk *pclk; spinlock_t spinlock; - u32 atid; + int atid; };
DEFINE_CORESIGHT_DEVLIST(trace_noc_devs, "traceNoc"); @@ -51,6 +53,12 @@ static void trace_noc_enable_hw(struct trace_noc_drvdata *drvdata) { u32 val;
+ /* No valid ATID, simply enable the unit */ + if (drvdata->atid == -EOPNOTSUPP) { + writel(TRACE_NOC_CTRL_PORTEN, drvdata->base + TRACE_NOC_CTRL); + return; + } + /* Set ATID */ writel_relaxed(drvdata->atid, drvdata->base + TRACE_NOC_XLD);
@@ -124,6 +132,11 @@ static int trace_noc_init_default_data(struct trace_noc_drvdata *drvdata) { int atid;
+ if (!dev_is_amba(drvdata->dev)) { + drvdata->atid = -EOPNOTSUPP; + return 0; + } + atid = coresight_trace_id_get_system_id(); if (atid < 0) return atid; @@ -149,8 +162,21 @@ static struct attribute *coresight_tnoc_attrs[] = { NULL, };
+static umode_t trace_id_is_visible(struct kobject *kobj, + struct attribute *attr, int idx) +{ + struct device *dev = kobj_to_dev(kobj); + struct trace_noc_drvdata *drvdata = dev_get_drvdata(dev->parent); + + if (attr == &dev_attr_traceid.attr && drvdata->atid < 0) + return 0; + + return attr->mode; +} + static const struct attribute_group coresight_tnoc_group = { .attrs = coresight_tnoc_attrs, + .is_visible = trace_id_is_visible, };
static const struct attribute_group *coresight_tnoc_groups[] = { @@ -158,9 +184,8 @@ static const struct attribute_group *coresight_tnoc_groups[] = { NULL, };
-static int trace_noc_probe(struct amba_device *adev, const struct amba_id *id) +static int _tnoc_probe(struct device *dev, struct resource *res) { - struct device *dev = &adev->dev; struct coresight_platform_data *pdata; struct trace_noc_drvdata *drvdata; struct coresight_desc desc = { 0 }; @@ -173,16 +198,20 @@ static int trace_noc_probe(struct amba_device *adev, const struct amba_id *id) pdata = coresight_get_platform_data(dev); if (IS_ERR(pdata)) return PTR_ERR(pdata); - adev->dev.platform_data = pdata; + dev->platform_data = pdata;
drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM;
- drvdata->dev = &adev->dev; + drvdata->dev = dev; dev_set_drvdata(dev, drvdata);
- drvdata->base = devm_ioremap_resource(dev, &adev->res); + ret = coresight_get_enable_clocks(dev, &drvdata->pclk, NULL); + if (ret) + return ret; + + drvdata->base = devm_ioremap_resource(dev, res); if (IS_ERR(drvdata->base)) return PTR_ERR(drvdata->base);
@@ -195,20 +224,31 @@ static int trace_noc_probe(struct amba_device *adev, const struct amba_id *id) desc.ops = &trace_noc_cs_ops; desc.type = CORESIGHT_DEV_TYPE_LINK; desc.subtype.link_subtype = CORESIGHT_DEV_SUBTYPE_LINK_MERG; - desc.pdata = adev->dev.platform_data; - desc.dev = &adev->dev; + desc.pdata = pdata; + desc.dev = dev; desc.access = CSDEV_ACCESS_IOMEM(drvdata->base); desc.groups = coresight_tnoc_groups; drvdata->csdev = coresight_register(&desc); if (IS_ERR(drvdata->csdev)) { - coresight_trace_id_put_system_id(drvdata->atid); + if (drvdata->atid > 0) + coresight_trace_id_put_system_id(drvdata->atid); return PTR_ERR(drvdata->csdev); } - pm_runtime_put(&adev->dev);
return 0; }
+static int trace_noc_probe(struct amba_device *adev, const struct amba_id *id) +{ + int ret; + + ret = _tnoc_probe(&adev->dev, &adev->res); + if (!ret) + pm_runtime_put(&adev->dev); + + return ret; +} + static void trace_noc_remove(struct amba_device *adev) { struct trace_noc_drvdata *drvdata = dev_get_drvdata(&adev->dev); @@ -236,7 +276,58 @@ static struct amba_driver trace_noc_driver = { .id_table = trace_noc_ids, };
-module_amba_driver(trace_noc_driver); +static int itnoc_probe(struct platform_device *pdev) +{ + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + int ret; + + pm_runtime_get_noresume(&pdev->dev); + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + ret = _tnoc_probe(&pdev->dev, res); + pm_runtime_put(&pdev->dev); + if (ret) + pm_runtime_disable(&pdev->dev); + + return ret; +} + +static void itnoc_remove(struct platform_device *pdev) +{ + struct trace_noc_drvdata *drvdata = platform_get_drvdata(pdev); + + coresight_unregister(drvdata->csdev); + pm_runtime_disable(&pdev->dev); +} + +static const struct of_device_id itnoc_of_match[] = { + { .compatible = "qcom,coresight-itnoc" }, + {} +}; +MODULE_DEVICE_TABLE(of, itnoc_of_match); + +static struct platform_driver itnoc_driver = { + .probe = itnoc_probe, + .remove = itnoc_remove, + .driver = { + .name = "coresight-itnoc", + .of_match_table = itnoc_of_match, + .suppress_bind_attrs = true, + }, +}; + +static int __init tnoc_init(void) +{ + return coresight_init_driver("tnoc", &trace_noc_driver, &itnoc_driver, THIS_MODULE); +} + +static void __exit tnoc_exit(void) +{ + coresight_remove_driver(&trace_noc_driver, &itnoc_driver); +} +module_init(tnoc_init); +module_exit(tnoc_exit);
MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Trace NOC driver");
This patch adds runtime power management support for platform-based CoreSight Interconnect TNOC (ITNOC) devices. It introduces suspend and resume callbacks to manage the APB clock (`pclk`) during device runtime transitions.
Signed-off-by: Yuanfang Zhang yuanfang.zhang@oss.qualcomm.com --- drivers/hwtracing/coresight/coresight-tnoc.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-tnoc.c b/drivers/hwtracing/coresight/coresight-tnoc.c index 5be882300d79bc0173aa6a19d7da1d48c4aaca9c..2c5370497076536bfa868f0d80db775ef242968b 100644 --- a/drivers/hwtracing/coresight/coresight-tnoc.c +++ b/drivers/hwtracing/coresight/coresight-tnoc.c @@ -301,6 +301,28 @@ static void itnoc_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); }
+#ifdef CONFIG_PM +static int itnoc_runtime_suspend(struct device *dev) +{ + struct trace_noc_drvdata *drvdata = dev_get_drvdata(dev); + + clk_disable_unprepare(drvdata->pclk); + + return 0; +} + +static int itnoc_runtime_resume(struct device *dev) +{ + struct trace_noc_drvdata *drvdata = dev_get_drvdata(dev); + + return clk_prepare_enable(drvdata->pclk); +} +#endif + +static const struct dev_pm_ops itnoc_dev_pm_ops = { + SET_RUNTIME_PM_OPS(itnoc_runtime_suspend, itnoc_runtime_resume, NULL) +}; + static const struct of_device_id itnoc_of_match[] = { { .compatible = "qcom,coresight-itnoc" }, {} @@ -314,6 +336,7 @@ static struct platform_driver itnoc_driver = { .name = "coresight-itnoc", .of_match_table = itnoc_of_match, .suppress_bind_attrs = true, + .pm = &itnoc_dev_pm_ops, }, };
On 9/1/2025 2:58 PM, Yuanfang Zhang wrote:
This patch adds runtime power management support for platform-based CoreSight Interconnect TNOC (ITNOC) devices. It introduces suspend and resume callbacks to manage the APB clock (`pclk`) during device runtime transitions.
Signed-off-by: Yuanfang Zhang yuanfang.zhang@oss.qualcomm.com
drivers/hwtracing/coresight/coresight-tnoc.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-tnoc.c b/drivers/hwtracing/coresight/coresight-tnoc.c index 5be882300d79bc0173aa6a19d7da1d48c4aaca9c..2c5370497076536bfa868f0d80db775ef242968b 100644 --- a/drivers/hwtracing/coresight/coresight-tnoc.c +++ b/drivers/hwtracing/coresight/coresight-tnoc.c @@ -301,6 +301,28 @@ static void itnoc_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } +#ifdef CONFIG_PM +static int itnoc_runtime_suspend(struct device *dev) +{
- struct trace_noc_drvdata *drvdata = dev_get_drvdata(dev);
- clk_disable_unprepare(drvdata->pclk);
- return 0;
+}
+static int itnoc_runtime_resume(struct device *dev) +{
- struct trace_noc_drvdata *drvdata = dev_get_drvdata(dev);
- return clk_prepare_enable(drvdata->pclk);
+} +#endif
+static const struct dev_pm_ops itnoc_dev_pm_ops = {
- SET_RUNTIME_PM_OPS(itnoc_runtime_suspend, itnoc_runtime_resume, NULL)
+};
static const struct of_device_id itnoc_of_match[] = { { .compatible = "qcom,coresight-itnoc" }, {} @@ -314,6 +336,7 @@ static struct platform_driver itnoc_driver = { .name = "coresight-itnoc", .of_match_table = itnoc_of_match, .suppress_bind_attrs = true,
},.pm = &itnoc_dev_pm_ops,
};
missed Reviewed-by: Leo Yan leo.yan@arm.com tag.
thanks, yuanfang.
Dear all,
Apologies — I mistakenly included an unintended attachment in my previous reply regarding the patch submission.
Please disregard the attachment; it is not relevant to the discussion.
Thank you for your understanding.
Best regards, Yuanfang Zhang
On 9/1/2025 4:30 PM, yuanfang zhang wrote:
On 9/1/2025 2:58 PM, Yuanfang Zhang wrote:
This patch adds runtime power management support for platform-based CoreSight Interconnect TNOC (ITNOC) devices. It introduces suspend and resume callbacks to manage the APB clock (`pclk`) during device runtime transitions.
Signed-off-by: Yuanfang Zhang yuanfang.zhang@oss.qualcomm.com
drivers/hwtracing/coresight/coresight-tnoc.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
diff --git a/drivers/hwtracing/coresight/coresight-tnoc.c b/drivers/hwtracing/coresight/coresight-tnoc.c index 5be882300d79bc0173aa6a19d7da1d48c4aaca9c..2c5370497076536bfa868f0d80db775ef242968b 100644 --- a/drivers/hwtracing/coresight/coresight-tnoc.c +++ b/drivers/hwtracing/coresight/coresight-tnoc.c @@ -301,6 +301,28 @@ static void itnoc_remove(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } +#ifdef CONFIG_PM +static int itnoc_runtime_suspend(struct device *dev) +{
- struct trace_noc_drvdata *drvdata = dev_get_drvdata(dev);
- clk_disable_unprepare(drvdata->pclk);
- return 0;
+}
+static int itnoc_runtime_resume(struct device *dev) +{
- struct trace_noc_drvdata *drvdata = dev_get_drvdata(dev);
- return clk_prepare_enable(drvdata->pclk);
+} +#endif
+static const struct dev_pm_ops itnoc_dev_pm_ops = {
- SET_RUNTIME_PM_OPS(itnoc_runtime_suspend, itnoc_runtime_resume, NULL)
+};
static const struct of_device_id itnoc_of_match[] = { { .compatible = "qcom,coresight-itnoc" }, {} @@ -314,6 +336,7 @@ static struct platform_driver itnoc_driver = { .name = "coresight-itnoc", .of_match_table = itnoc_of_match, .suppress_bind_attrs = true,
},.pm = &itnoc_dev_pm_ops,
};
missed Reviewed-by: Leo Yan leo.yan@arm.com tag.
thanks, yuanfang.