Devicetree
 help / color / mirror / Atom feed
* [PATCH v1 0/3] Add Qualcomm CAMNOC ICC provider
@ 2026-08-07 11:49 Atanas Filipov
  2026-08-07 11:49 ` [PATCH v1 1/3] dt-bindings: interconnect: Add Qualcomm CAMNOC ICC binding Atanas Filipov
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Atanas Filipov @ 2026-08-07 11:49 UTC (permalink / raw)
  To: djakov, andersson, konradybcio, robh, krzk+dt, conor+dt
  Cc: dmitry.baryshkov, krzysztof.kozlowski, odelu.kukatla,
	raviteja.laggyshetty, vivek.aknurwar, quic_afilipov, loic.poulain,
	linux-arm-msm, linux-pm, devicetree, linux-kernel, atanas.filipov

This series adds a device tree binding and driver for a Qualcomm Camera
Network-on-Chip (CAMNOC) interconnect provider.

CAMNOC is the internal AXI interconnect within the camera subsystem
that arbitrates bandwidth between camera sub-devices (IFE, JPEG, BPS,
etc.) and the external memory interconnect. On current SoCs, each
sub-device that shares the CAMNOC AXI clock calls clk_set_rate()
directly on it. This is a last-writer-wins race: whichever consumer
sets the rate last wins, regardless of what other active consumers
actually require.

This series introduces a lightweight ICC provider for CAMNOC that solves
this by leveraging the existing ICC aggregation framework. Each consumer
obtains an ICC path to the CAMNOC AXI slave node and votes for bandwidth
via icc_set_bw(). The ICC core aggregates all active votes (max of
peak_bw across consumers) and the provider's set() callback translates
the aggregated result into a single clk_set_rate() call.

Consumers encode the required clock frequency directly as peak_bw in
kBps (e.g. 400000 for 400 MHz); the provider converts this back to Hz.
This keeps the provider itself free of per-consumer bandwidth tables,
while still allowing a consumer's operating-points-v2 table to select
its CAMNOC bandwidth vote from the same OPP entry that selects its core
clock rate and RPMh performance state, as shown in the binding example.

Supported compatibles:
- qcom,sm8250-cam-virt

Scope of this series:
- dt-bindings: interconnect provider binding, with a generic consumer
  example illustrating the interconnects/interconnect-names wiring and
  the optional OPP-driven bandwidth vote
- driver: CAMNOC ICC provider (drivers/interconnect/qcom)
- DTS: CAMNOC provider node for SM8250

This series intentionally adds the provider only, with no consumer
wiring in this round. Existing camera sub-device drivers on this SoC
will be migrated to vote through this provider in a follow-up series,
once it has settled through review; that migration is what will let
those drivers stop calling clk_set_rate() directly and avoid the shared
clock race described above.

Patch order follows binding -> driver -> DTS so that each patch is
independently bisectable.

Atanas Filipov (3):
  dt-bindings: interconnect: Add Qualcomm CAMNOC ICC binding
  interconnect: qcom: Add CAMNOC interconnect provider driver
  arm64: dts: qcom: sm8250: Add CAMNOC ICC provider node

 .../bindings/interconnect/qcom,camnoc.yaml    |  98 ++++++++++
 arch/arm64/boot/dts/qcom/sm8250.dtsi          |   8 +
 drivers/interconnect/qcom/Kconfig             |  10 +
 drivers/interconnect/qcom/Makefile            |   2 +
 drivers/interconnect/qcom/qcom-camnoc.c       | 184 ++++++++++++++++++
 .../dt-bindings/interconnect/qcom,camnoc.h    |  12 ++
 6 files changed, 314 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,camnoc.yaml
 create mode 100644 drivers/interconnect/qcom/qcom-camnoc.c
 create mode 100644 include/dt-bindings/interconnect/qcom,camnoc.h


base-commit: f9a2394a23482bfd330911e9c8295b71724feacd
-- 
2.34.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v1 1/3] dt-bindings: interconnect: Add Qualcomm CAMNOC ICC binding
  2026-08-07 11:49 [PATCH v1 0/3] Add Qualcomm CAMNOC ICC provider Atanas Filipov
@ 2026-08-07 11:49 ` Atanas Filipov
  2026-08-07 21:12   ` Dmitry Baryshkov
  2026-08-07 11:49 ` [PATCH v1 2/3] interconnect: qcom: Add CAMNOC interconnect provider driver Atanas Filipov
  2026-08-07 11:49 ` [PATCH v1 3/3] arm64: dts: qcom: sm8250: Add CAMNOC ICC provider node Atanas Filipov
  2 siblings, 1 reply; 6+ messages in thread
From: Atanas Filipov @ 2026-08-07 11:49 UTC (permalink / raw)
  To: djakov, andersson, konradybcio, robh, krzk+dt, conor+dt
  Cc: dmitry.baryshkov, krzysztof.kozlowski, odelu.kukatla,
	raviteja.laggyshetty, vivek.aknurwar, quic_afilipov, loic.poulain,
	linux-arm-msm, linux-pm, devicetree, linux-kernel, atanas.filipov

Add a device tree binding for the Qualcomm Camera Network-on-Chip
(CAMNOC) interconnect provider. CAMNOC is the internal AXI
interconnect within the camera subsystem that arbitrates bandwidth
between camera sub-devices and the external memory interconnect.

The CAMNOC ICC provider aggregates bandwidth requests from multiple
independent consumers and scales the CAMNOC AXI clock accordingly,
avoiding the race conditions that arise when each consumer calls
clk_set_rate() directly on the shared clock.

Signed-off-by: Atanas Filipov <atanas.filipov@oss.qualcomm.com>
---
 .../bindings/interconnect/qcom,camnoc.yaml    | 98 +++++++++++++++++++
 .../dt-bindings/interconnect/qcom,camnoc.h    | 12 +++
 2 files changed, 110 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,camnoc.yaml
 create mode 100644 include/dt-bindings/interconnect/qcom,camnoc.h

diff --git a/Documentation/devicetree/bindings/interconnect/qcom,camnoc.yaml b/Documentation/devicetree/bindings/interconnect/qcom,camnoc.yaml
new file mode 100644
index 000000000000..b2f5c140ff80
--- /dev/null
+++ b/Documentation/devicetree/bindings/interconnect/qcom,camnoc.yaml
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/interconnect/qcom,camnoc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Camera NOC (CAMNOC) Interconnect Provider
+
+maintainers:
+  - Aleksandar Filipov <quic_afilipov@quicinc.com>
+
+description:
+  The Camera Network-on-Chip (CAMNOC) is the internal AXI interconnect
+  within the Qualcomm camera subsystem. It arbitrates AXI bandwidth
+  between camera sub-devices (IFE, JPEG, BPS, etc.) and the external
+  memory interconnect. Multiple consumers may independently request
+  bandwidth; the CAMNOC ICC provider aggregates these requests and
+  scales CAM_CC_CAMNOC_AXI_CLK accordingly.
+
+properties:
+  compatible:
+    enum:
+      - qcom,sm8250-cam-virt
+
+  clocks:
+    items:
+      - description: CAMNOC AXI clock
+
+  clock-names:
+    items:
+      - const: camnoc_axi
+
+  '#interconnect-cells':
+    const: 1
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - '#interconnect-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,camcc-sm8250.h>
+    #include <dt-bindings/interconnect/qcom,camnoc.h>
+
+    camnoc_icc: interconnect {
+        compatible = "qcom,sm8250-cam-virt";
+        clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>;
+        clock-names = "camnoc_axi";
+        #interconnect-cells = <1>;
+    };
+
+    /* Example camera sub-device consuming the CAMNOC provider above */
+    camera-subsystem@ac53000 {
+        reg = <0x0ac53000 0x1000>;
+
+        interconnects = <&camnoc_icc MASTER_CAMNOC_JPEG
+                         &camnoc_icc SLAVE_CAMNOC_AXI>;
+        interconnect-names = "camnoc";
+
+        /*
+         * Optional: an operating-points-v2 table lets the consumer
+         * drive its CAMNOC bandwidth vote from the same OPP that
+         * selects its core clock rate and RPMh performance state.
+         */
+        operating-points-v2 = <&camera_opp_table>;
+
+        camera_opp_table: opp-table {
+            compatible = "operating-points-v2";
+
+            opp-100000000 {
+                opp-hz = /bits/ 64 <100000000>;
+                opp-peak-kBps = <22246>;
+                required-opps = <&rpmhpd_opp_min_svs>;
+            };
+
+            opp-200000000 {
+                opp-hz = /bits/ 64 <200000000>;
+                opp-peak-kBps = <44492>;
+                required-opps = <&rpmhpd_opp_low_svs>;
+            };
+
+            opp-400000000 {
+                opp-hz = /bits/ 64 <400000000>;
+                opp-peak-kBps = <88983>;
+                required-opps = <&rpmhpd_opp_svs>;
+            };
+
+            opp-480000000 {
+                opp-hz = /bits/ 64 <480000000>;
+                opp-peak-kBps = <106780>;
+                required-opps = <&rpmhpd_opp_svs_l1>;
+            };
+        };
+    };
diff --git a/include/dt-bindings/interconnect/qcom,camnoc.h b/include/dt-bindings/interconnect/qcom,camnoc.h
new file mode 100644
index 000000000000..a03f5e3f6446
--- /dev/null
+++ b/include/dt-bindings/interconnect/qcom,camnoc.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+
+#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_CAMNOC_H
+#define __DT_BINDINGS_INTERCONNECT_QCOM_CAMNOC_H
+
+#define MASTER_CAMNOC_JPEG	0
+#define SLAVE_CAMNOC_AXI	1
+
+#endif /* __DT_BINDINGS_INTERCONNECT_QCOM_CAMNOC_H */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v1 2/3] interconnect: qcom: Add CAMNOC interconnect provider driver
  2026-08-07 11:49 [PATCH v1 0/3] Add Qualcomm CAMNOC ICC provider Atanas Filipov
  2026-08-07 11:49 ` [PATCH v1 1/3] dt-bindings: interconnect: Add Qualcomm CAMNOC ICC binding Atanas Filipov
@ 2026-08-07 11:49 ` Atanas Filipov
  2026-08-07 12:03   ` sashiko-bot
  2026-08-07 11:49 ` [PATCH v1 3/3] arm64: dts: qcom: sm8250: Add CAMNOC ICC provider node Atanas Filipov
  2 siblings, 1 reply; 6+ messages in thread
From: Atanas Filipov @ 2026-08-07 11:49 UTC (permalink / raw)
  To: djakov, andersson, konradybcio, robh, krzk+dt, conor+dt
  Cc: dmitry.baryshkov, krzysztof.kozlowski, odelu.kukatla,
	raviteja.laggyshetty, vivek.aknurwar, quic_afilipov, loic.poulain,
	linux-arm-msm, linux-pm, devicetree, linux-kernel, atanas.filipov

The Camera Network-on-Chip (CAMNOC) is the internal AXI interconnect
within the camera subsystem. Multiple camera sub-devices share the
CAMNOC AXI clock. When each sub-device calls clk_set_rate() directly
on this shared clock, a last-writer-wins race condition arises: the
final caller sets the rate regardless of what other active consumers
require.

Introduce a lightweight ICC provider for CAMNOC that solves this by
leveraging the ICC aggregation framework. Each consumer obtains an
ICC path to SLAVE_CAMNOC_AXI and votes for bandwidth via icc_set_bw().
The ICC core aggregates all votes (max of peak_bw across consumers)
and the provider's set() callback translates the result into a single
clk_set_rate() call on the CAMNOC AXI clock.

Consumers encode the required clock frequency directly as peak_bw in
kBps (e.g. 400000 for 400 MHz). The conversion is:
  rate_hz = peak_bw_kBps * 1000

Implement get_bw() returning 0 for both avg and peak to prevent the
ICC core from defaulting to INT_MAX before any consumer has voted.

Signed-off-by: Atanas Filipov <atanas.filipov@oss.qualcomm.com>
---
 drivers/interconnect/qcom/Kconfig       |  10 ++
 drivers/interconnect/qcom/Makefile      |   2 +
 drivers/interconnect/qcom/qcom-camnoc.c | 184 ++++++++++++++++++++++++
 3 files changed, 196 insertions(+)
 create mode 100644 drivers/interconnect/qcom/qcom-camnoc.c

diff --git a/drivers/interconnect/qcom/Kconfig b/drivers/interconnect/qcom/Kconfig
index 5b8a094ca4ed..9d9d238019a0 100644
--- a/drivers/interconnect/qcom/Kconfig
+++ b/drivers/interconnect/qcom/Kconfig
@@ -135,6 +135,16 @@ config INTERCONNECT_QCOM_NORD
 	  the RPMh hardware and communicates via Bus Clock Manager (BCM)
 	  through the Resource State Coordinator (RSC).
 
+config INTERCONNECT_QCOM_CAMNOC
+	tristate "Qualcomm CAMNOC interconnect driver"
+	depends on INTERCONNECT_QCOM || COMPILE_TEST
+	depends on ARM64 || COMPILE_TEST
+	help
+	  Say y here to support the Camera Network-on-Chip (CAMNOC)
+	  interconnect driver for Qualcomm SoCs. It aggregates bandwidth
+	  requests from camera sub-devices (IFE, JPEG, BPS, etc.) and
+	  scales CAM_CC_CAMNOC_AXI_CLK accordingly.
+
 config INTERCONNECT_QCOM_OSM_L3
 	tristate "Qualcomm OSM L3 interconnect driver"
 	depends on INTERCONNECT_QCOM || COMPILE_TEST
diff --git a/drivers/interconnect/qcom/Makefile b/drivers/interconnect/qcom/Makefile
index 1c7d410b40cc..52a5998ae6a8 100644
--- a/drivers/interconnect/qcom/Makefile
+++ b/drivers/interconnect/qcom/Makefile
@@ -18,6 +18,7 @@ qnoc-msm8974-objs			:= msm8974.o
 qnoc-msm8976-objs			:= msm8976.o
 qnoc-msm8996-objs			:= msm8996.o
 qnoc-nord-objs				:= nord.o
+icc-camnoc-objs				:= qcom-camnoc.o
 icc-osm-l3-objs				:= osm-l3.o
 qnoc-qcm2290-objs			:= qcm2290.o
 qnoc-qcs404-objs			:= qcs404.o
@@ -66,6 +67,7 @@ obj-$(CONFIG_INTERCONNECT_QCOM_MSM8974) += qnoc-msm8974.o
 obj-$(CONFIG_INTERCONNECT_QCOM_MSM8976) += qnoc-msm8976.o
 obj-$(CONFIG_INTERCONNECT_QCOM_MSM8996) += qnoc-msm8996.o
 obj-$(CONFIG_INTERCONNECT_QCOM_NORD) += qnoc-nord.o
+obj-$(CONFIG_INTERCONNECT_QCOM_CAMNOC) += icc-camnoc.o
 obj-$(CONFIG_INTERCONNECT_QCOM_OSM_L3) += icc-osm-l3.o
 obj-$(CONFIG_INTERCONNECT_QCOM_QCM2290) += qnoc-qcm2290.o
 obj-$(CONFIG_INTERCONNECT_QCOM_QCS404) += qnoc-qcs404.o
diff --git a/drivers/interconnect/qcom/qcom-camnoc.c b/drivers/interconnect/qcom/qcom-camnoc.c
new file mode 100644
index 000000000000..a5a484491515
--- /dev/null
+++ b/drivers/interconnect/qcom/qcom-camnoc.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ *
+ * Qualcomm Camera NOC (CAMNOC) interconnect provider.
+ *
+ * CAMNOC is the internal AXI interconnect within the Qualcomm camera
+ * subsystem. Multiple camera sub-devices (IFE, JPEG, BPS, etc.) share
+ * CAM_CC_CAMNOC_AXI_CLK. This driver acts as an ICC provider so that
+ * each sub-device can independently vote for bandwidth; the ICC core
+ * aggregates the votes (max of peak_bw across all consumers) and this
+ * driver translates the result into a clk_set_rate() call, avoiding
+ * the last-writer-wins race that occurs with direct clk_set_rate().
+ *
+ * Consumers express their required clock rate directly as peak_bw in
+ * kBps (e.g. 400000 for 400 MHz).  The driver converts kBps → Hz:
+ *   rate_hz = peak_bw_kBps * 1000
+ */
+
+#include <linux/clk.h>
+#include <linux/interconnect-provider.h>
+#include <linux/interconnect.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+
+#include <dt-bindings/interconnect/qcom,camnoc.h>
+
+#define to_camnoc_provider(_p) \
+	container_of(_p, struct qcom_camnoc_icc_provider, provider)
+
+struct qcom_camnoc_icc_provider {
+	struct clk *clk;
+	struct icc_provider provider;
+};
+
+struct qcom_camnoc_node {
+	const char *name;
+	u16 buswidth;
+};
+
+static const struct qcom_camnoc_node camnoc_master_jpeg = {
+	.name = "master-camnoc-jpeg",
+	.buswidth = 16,
+};
+
+static const struct qcom_camnoc_node camnoc_slave_axi = {
+	.name = "slave-camnoc-axi",
+	.buswidth = 16,
+};
+
+static const struct qcom_camnoc_node * const camnoc_nodes[] = {
+	[MASTER_CAMNOC_JPEG] = &camnoc_master_jpeg,
+	[SLAVE_CAMNOC_AXI]   = &camnoc_slave_axi,
+};
+
+#define CAMNOC_NUM_NODES	ARRAY_SIZE(camnoc_nodes)
+
+static int qcom_camnoc_get_bw(struct icc_node *node, u32 *avg, u32 *peak)
+{
+	*avg = 0;
+	*peak = 0;
+
+	return 0;
+}
+
+static int qcom_camnoc_set(struct icc_node *src, struct icc_node *dst)
+{
+	struct qcom_camnoc_icc_provider *cp =
+		to_camnoc_provider(src->provider);
+	unsigned long rate;
+
+	/*
+	 * peak_bw is the aggregated max across all consumers (kBps).
+	 * Consumers encode the required clock frequency directly as kBps,
+	 * so the conversion is simply: rate_hz = peak_bw * 1000.
+	 * A vote of 0 means no requirement; leave the clock at its minimum.
+	 */
+	rate = icc_units_to_bps(dst->peak_bw);
+
+	dev_dbg(src->provider->dev,
+		"CAMNOC set: aggregated peak_bw=%u kBps -> rate=%lu Hz\n",
+		dst->peak_bw, rate);
+
+	return clk_set_rate(cp->clk, rate);
+}
+
+static void qcom_camnoc_remove(struct platform_device *pdev)
+{
+	struct qcom_camnoc_icc_provider *cp = platform_get_drvdata(pdev);
+
+	icc_provider_deregister(&cp->provider);
+	icc_nodes_remove(&cp->provider);
+}
+
+static int qcom_camnoc_probe(struct platform_device *pdev)
+{
+	struct qcom_camnoc_icc_provider *cp;
+	struct icc_onecell_data *data;
+	struct icc_provider *provider;
+	struct icc_node *node;
+	unsigned int i;
+	int ret;
+
+	cp = devm_kzalloc(&pdev->dev, sizeof(*cp), GFP_KERNEL);
+	if (!cp)
+		return -ENOMEM;
+
+	cp->clk = devm_clk_get(&pdev->dev, "camnoc_axi");
+	if (IS_ERR(cp->clk))
+		return dev_err_probe(&pdev->dev, PTR_ERR(cp->clk),
+				     "failed to get camnoc_axi clock\n");
+
+	data = devm_kzalloc(&pdev->dev,
+			    struct_size(data, nodes, CAMNOC_NUM_NODES),
+			    GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->num_nodes = CAMNOC_NUM_NODES;
+
+	provider = &cp->provider;
+	provider->dev = &pdev->dev;
+	provider->get_bw = qcom_camnoc_get_bw;
+	provider->set = qcom_camnoc_set;
+	provider->aggregate = icc_std_aggregate;
+	provider->xlate = of_icc_xlate_onecell;
+	provider->data = data;
+
+	icc_provider_init(provider);
+
+	for (i = 0; i < CAMNOC_NUM_NODES; i++) {
+		node = icc_node_create_dyn();
+		if (IS_ERR(node)) {
+			ret = PTR_ERR(node);
+			goto err_remove;
+		}
+
+		ret = icc_node_set_name(node, provider, camnoc_nodes[i]->name);
+		if (ret) {
+			icc_node_destroy(node->id);
+			goto err_remove;
+		}
+
+		node->data = (void *)camnoc_nodes[i];
+		icc_node_add(node, provider);
+		data->nodes[i] = node;
+	}
+
+	icc_link_nodes(data->nodes[MASTER_CAMNOC_JPEG],
+		       &data->nodes[SLAVE_CAMNOC_AXI]);
+
+	ret = icc_provider_register(provider);
+	if (ret)
+		goto err_remove;
+
+	platform_set_drvdata(pdev, cp);
+
+	return 0;
+
+err_remove:
+	icc_nodes_remove(provider);
+	return ret;
+}
+
+static const struct of_device_id qcom_camnoc_of_match[] = {
+	{ .compatible = "qcom,sm8250-cam-virt" },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, qcom_camnoc_of_match);
+
+static struct platform_driver qcom_camnoc_driver = {
+	.probe  = qcom_camnoc_probe,
+	.remove = qcom_camnoc_remove,
+	.driver = {
+		.name           = "qcom-camnoc-icc",
+		.of_match_table = qcom_camnoc_of_match,
+		.sync_state     = icc_sync_state,
+	},
+};
+module_platform_driver(qcom_camnoc_driver);
+
+MODULE_DESCRIPTION("Qualcomm CAMNOC interconnect driver");
+MODULE_LICENSE("GPL");
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v1 3/3] arm64: dts: qcom: sm8250: Add CAMNOC ICC provider node
  2026-08-07 11:49 [PATCH v1 0/3] Add Qualcomm CAMNOC ICC provider Atanas Filipov
  2026-08-07 11:49 ` [PATCH v1 1/3] dt-bindings: interconnect: Add Qualcomm CAMNOC ICC binding Atanas Filipov
  2026-08-07 11:49 ` [PATCH v1 2/3] interconnect: qcom: Add CAMNOC interconnect provider driver Atanas Filipov
@ 2026-08-07 11:49 ` Atanas Filipov
  2 siblings, 0 replies; 6+ messages in thread
From: Atanas Filipov @ 2026-08-07 11:49 UTC (permalink / raw)
  To: djakov, andersson, konradybcio, robh, krzk+dt, conor+dt
  Cc: dmitry.baryshkov, krzysztof.kozlowski, odelu.kukatla,
	raviteja.laggyshetty, vivek.aknurwar, quic_afilipov, loic.poulain,
	linux-arm-msm, linux-pm, devicetree, linux-kernel, atanas.filipov

Add the cam_virt CAMNOC interconnect provider node to the sm8250 SoC
DTSI. The node uses the CAMNOC AXI clock to aggregate bandwidth votes
from camera sub-devices via the ICC framework.

The node is placed alongside the other virtual interconnect nodes,
after mmss_noc.

Signed-off-by: Atanas Filipov <atanas.filipov@oss.qualcomm.com>
---
 arch/arm64/boot/dts/qcom/sm8250.dtsi | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi
index 7076720413ab..33535c83a4d9 100644
--- a/arch/arm64/boot/dts/qcom/sm8250.dtsi
+++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
@@ -11,6 +11,7 @@
 #include <dt-bindings/clock/qcom,rpmh.h>
 #include <dt-bindings/dma/qcom-gpi.h>
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/interconnect/qcom,camnoc.h>
 #include <dt-bindings/interconnect/qcom,osm-l3.h>
 #include <dt-bindings/interconnect/qcom,sm8250.h>
 #include <dt-bindings/mailbox/qcom-ipcc.h>
@@ -377,6 +378,13 @@ qup_virt: interconnect-qup-virt {
 		qcom,bcm-voters = <&apps_bcm_voter>;
 	};
 
+	cam_virt: interconnect-cam-virt {
+		compatible = "qcom,sm8250-cam-virt";
+		clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>;
+		clock-names = "camnoc_axi";
+		#interconnect-cells = <1>;
+	};
+
 	cpu0_opp_table: opp-table-cpu0 {
 		compatible = "operating-points-v2";
 		opp-shared;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v1 2/3] interconnect: qcom: Add CAMNOC interconnect provider driver
  2026-08-07 11:49 ` [PATCH v1 2/3] interconnect: qcom: Add CAMNOC interconnect provider driver Atanas Filipov
@ 2026-08-07 12:03   ` sashiko-bot
  0 siblings, 0 replies; 6+ messages in thread
From: sashiko-bot @ 2026-08-07 12:03 UTC (permalink / raw)
  To: Atanas Filipov; +Cc: robh, conor+dt, devicetree

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Missing return value check for `icc_link_nodes()`.
--

--- Patch [2]: [PATCH v1 2/3] interconnect: qcom: Add CAMNOC interconnect provider driver ---
commit 210368acb417d0d403f4fd95176e70d2684711b8
Author: Atanas Filipov <atanas.filipov@oss.qualcomm.com>
interconnect: qcom: Add CAMNOC interconnect provider driver

This commit introduces a new interconnect provider driver for the Qualcomm
Camera NOC (CAMNOC). It aggregates bandwidth requests from camera
sub-devices and adjusts the CAMNOC AXI clock rate to prevent a
last-writer-wins race condition.

> diff --git a/drivers/interconnect/qcom/qcom-camnoc.c b/drivers/interconnect/qcom/qcom-camnoc.c
> new file mode 100644
> index 0000000000000..a5a4844915153
> --- /dev/null
> +++ b/drivers/interconnect/qcom/qcom-camnoc.c

[ ... ]

> +static int qcom_camnoc_probe(struct platform_device *pdev)
> +{

[ ... ]

> +	for (i = 0; i < CAMNOC_NUM_NODES; i++) {
> +		node = icc_node_create_dyn();
> +		if (IS_ERR(node)) {
> +			ret = PTR_ERR(node);
> +			goto err_remove;
> +		}
> +
> +		ret = icc_node_set_name(node, provider, camnoc_nodes[i]->name);
> +		if (ret) {
> +			icc_node_destroy(node->id);
> +			goto err_remove;
> +		}
> +
> +		node->data = (void *)camnoc_nodes[i];
> +		icc_node_add(node, provider);
> +		data->nodes[i] = node;
> +	}
> +
> +	icc_link_nodes(data->nodes[MASTER_CAMNOC_JPEG],
> +		       &data->nodes[SLAVE_CAMNOC_AXI]);
> +
> +	ret = icc_provider_register(provider);

[Severity: High]
Does this code need to check the return value of icc_link_nodes?

If the internal memory allocation in icc_link_nodes fails, it returns an
error code (such as -ENOMEM) and the interconnect link is not created.

Because the error is ignored, the driver will continue and register the
provider successfully despite being broken. Later, when consumers request a
path through this interconnect, the path lookup will fail with -ENOENT,
potentially causing consumer drivers to malfunction or fail to probe.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260807114951.4164439-1-atanas.filipov@oss.qualcomm.com?part=2

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v1 1/3] dt-bindings: interconnect: Add Qualcomm CAMNOC ICC binding
  2026-08-07 11:49 ` [PATCH v1 1/3] dt-bindings: interconnect: Add Qualcomm CAMNOC ICC binding Atanas Filipov
@ 2026-08-07 21:12   ` Dmitry Baryshkov
  0 siblings, 0 replies; 6+ messages in thread
From: Dmitry Baryshkov @ 2026-08-07 21:12 UTC (permalink / raw)
  To: Atanas Filipov
  Cc: djakov, andersson, konradybcio, robh, krzk+dt, conor+dt,
	krzysztof.kozlowski, odelu.kukatla, raviteja.laggyshetty,
	vivek.aknurwar, quic_afilipov, loic.poulain, linux-arm-msm,
	linux-pm, devicetree, linux-kernel

On Fri, Aug 07, 2026 at 02:49:49PM +0300, Atanas Filipov wrote:
> Add a device tree binding for the Qualcomm Camera Network-on-Chip
> (CAMNOC) interconnect provider. CAMNOC is the internal AXI
> interconnect within the camera subsystem that arbitrates bandwidth
> between camera sub-devices and the external memory interconnect.
> 
> The CAMNOC ICC provider aggregates bandwidth requests from multiple
> independent consumers and scales the CAMNOC AXI clock accordingly,
> avoiding the race conditions that arise when each consumer calls
> clk_set_rate() directly on the shared clock.
> 
> Signed-off-by: Atanas Filipov <atanas.filipov@oss.qualcomm.com>
> ---
>  .../bindings/interconnect/qcom,camnoc.yaml    | 98 +++++++++++++++++++
>  .../dt-bindings/interconnect/qcom,camnoc.h    | 12 +++
>  2 files changed, 110 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/interconnect/qcom,camnoc.yaml
>  create mode 100644 include/dt-bindings/interconnect/qcom,camnoc.h
> 
> diff --git a/Documentation/devicetree/bindings/interconnect/qcom,camnoc.yaml b/Documentation/devicetree/bindings/interconnect/qcom,camnoc.yaml
> new file mode 100644
> index 000000000000..b2f5c140ff80
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/interconnect/qcom,camnoc.yaml
> @@ -0,0 +1,98 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/interconnect/qcom,camnoc.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm Camera NOC (CAMNOC) Interconnect Provider
> +
> +maintainers:
> +  - Aleksandar Filipov <quic_afilipov@quicinc.com>
> +
> +description:
> +  The Camera Network-on-Chip (CAMNOC) is the internal AXI interconnect
> +  within the Qualcomm camera subsystem. It arbitrates AXI bandwidth
> +  between camera sub-devices (IFE, JPEG, BPS, etc.) and the external
> +  memory interconnect. Multiple consumers may independently request
> +  bandwidth; the CAMNOC ICC provider aggregates these requests and
> +  scales CAM_CC_CAMNOC_AXI_CLK accordingly.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - qcom,sm8250-cam-virt
> +
> +  clocks:
> +    items:
> +      - description: CAMNOC AXI clock
> +
> +  clock-names:
> +    items:
> +      - const: camnoc_axi
> +
> +  '#interconnect-cells':
> +    const: 1
> +
> +required:
> +  - compatible
> +  - clocks
> +  - clock-names
> +  - '#interconnect-cells'
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/qcom,camcc-sm8250.h>
> +    #include <dt-bindings/interconnect/qcom,camnoc.h>
> +
> +    camnoc_icc: interconnect {
> +        compatible = "qcom,sm8250-cam-virt";
> +        clocks = <&camcc CAM_CC_CAMNOC_AXI_CLK>;
> +        clock-names = "camnoc_axi";
> +        #interconnect-cells = <1>;
> +    };
> +
> +    /* Example camera sub-device consuming the CAMNOC provider above */
> +    camera-subsystem@ac53000 {
> +        reg = <0x0ac53000 0x1000>;
> +
> +        interconnects = <&camnoc_icc MASTER_CAMNOC_JPEG
> +                         &camnoc_icc SLAVE_CAMNOC_AXI>;
> +        interconnect-names = "camnoc";
> +
> +        /*
> +         * Optional: an operating-points-v2 table lets the consumer
> +         * drive its CAMNOC bandwidth vote from the same OPP that
> +         * selects its core clock rate and RPMh performance state.

Is this a table for the camera-subsystem or for the CAMNOC_AXI_CLK? In
the latter case, the OPP table should be a part of the camnoc device.

> +         */
> +        operating-points-v2 = <&camera_opp_table>;
> +
> +        camera_opp_table: opp-table {
> +            compatible = "operating-points-v2";
> +
> +            opp-100000000 {
> +                opp-hz = /bits/ 64 <100000000>;
> +                opp-peak-kBps = <22246>;
> +                required-opps = <&rpmhpd_opp_min_svs>;
> +            };
> +
> +            opp-200000000 {
> +                opp-hz = /bits/ 64 <200000000>;
> +                opp-peak-kBps = <44492>;
> +                required-opps = <&rpmhpd_opp_low_svs>;
> +            };
> +
> +            opp-400000000 {
> +                opp-hz = /bits/ 64 <400000000>;
> +                opp-peak-kBps = <88983>;
> +                required-opps = <&rpmhpd_opp_svs>;
> +            };
> +
> +            opp-480000000 {
> +                opp-hz = /bits/ 64 <480000000>;
> +                opp-peak-kBps = <106780>;
> +                required-opps = <&rpmhpd_opp_svs_l1>;
> +            };
> +        };
> +    };
> diff --git a/include/dt-bindings/interconnect/qcom,camnoc.h b/include/dt-bindings/interconnect/qcom,camnoc.h
> new file mode 100644
> index 000000000000..a03f5e3f6446
> --- /dev/null
> +++ b/include/dt-bindings/interconnect/qcom,camnoc.h
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */
> +/*
> + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
> + */
> +
> +#ifndef __DT_BINDINGS_INTERCONNECT_QCOM_CAMNOC_H
> +#define __DT_BINDINGS_INTERCONNECT_QCOM_CAMNOC_H
> +
> +#define MASTER_CAMNOC_JPEG	0

I guess, there are other connection ports. Please describe them.

> +#define SLAVE_CAMNOC_AXI	1
> +
> +#endif /* __DT_BINDINGS_INTERCONNECT_QCOM_CAMNOC_H */
> -- 
> 2.34.1
> 

-- 
With best wishes
Dmitry

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-08-07 21:13 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-07 11:49 [PATCH v1 0/3] Add Qualcomm CAMNOC ICC provider Atanas Filipov
2026-08-07 11:49 ` [PATCH v1 1/3] dt-bindings: interconnect: Add Qualcomm CAMNOC ICC binding Atanas Filipov
2026-08-07 21:12   ` Dmitry Baryshkov
2026-08-07 11:49 ` [PATCH v1 2/3] interconnect: qcom: Add CAMNOC interconnect provider driver Atanas Filipov
2026-08-07 12:03   ` sashiko-bot
2026-08-07 11:49 ` [PATCH v1 3/3] arm64: dts: qcom: sm8250: Add CAMNOC ICC provider node Atanas Filipov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox