mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH RFC 0/3] Support the Nord CCI CCU output mux
@ 2026-11-05 11:10 Wenmeng Liu
  2026-11-05 11:10 ` [PATCH RFC 1/3] dt-bindings: mfd: syscon: Add Qualcomm Nord Titan CAM_TOP Wenmeng Liu
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Wenmeng Liu @ 2026-11-05 11:10 UTC (permalink / raw)
  To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Loic Poulain, Robert Foss, Andi Shyti
  Cc: mfd, devicetree, linux-kernel, linux-arm-msm, linux-i2c,
	vikram.sharma, nihal.gupta, vtumati, bryan.odonoghue,
	Wenmeng Liu

On Nord, the CCI controllers are wrapped by a CCU. After reset, the
CCI I2C ports are routed to the CCU, and the CCU output mux must select
the CCI before it can be used.

The mux register is part of CAM_TOP, a register block shared by
multiple camera components and outside the CCI and CAMSS register
ranges. Accessing the block requires the camera subsystem top power
domain and AHB clock, and its state is lost when the power domain is
turned off.

This RFC describes CAM_TOP as a syscon and lets each CCI reference its
mux configuration through a phandle, register offset and mask. The CCI
driver selects the CCI at probe and runtime resume, right after enabling
the CCI clocks and before the CCI is reset or configured.

	titan_cam_top: syscon@<addr> {
		compatible = "qcom,nord-titan-cam-top", "syscon";
		reg = <...>;
	};

	cci2: cci@<addr> {
		compatible = "qcom,nord-cci", "qcom,msm8996-cci";
		...
		qcom,ccu-mux-sel = <&titan_cam_top OFFSET MASK>;
	};

The CAM_TOP syscon does not describe its clock or power domain. A clock
attached to a syscon is kept prepared for the lifetime of the regmap,
which would keep the camera clock controller runtime active even when
the camera is idle. Instead, the CCI, as the consumer, writes the mux
with its own power domain and clocks, which include the AHB clock,
enabled.

An alternative is to introduce a dedicated CAM_TOP driver which owns
the clock and power domain, provides the regmap through
of_syscon_register_regmap() and handles runtime PM in its accessors.
This describes the hardware resources more completely and avoids the
debugfs issue, but adds a driver for a block currently used only by
the CCI.

We would like feedback on whether using a plain syscon with power and
clock management left to its consumer is acceptable, or whether CAM_TOP
should instead have a dedicated binding and driver.

---
Wenmeng Liu (3):
      dt-bindings: mfd: syscon: Add Qualcomm Nord Titan CAM_TOP
      dt-bindings: i2c: qcom-cci: Document Nord compatible
      i2c: qcom-cci: Support the CCU output mux

 .../devicetree/bindings/i2c/qcom,i2c-cci.yaml      | 41 +++++++++++++++++++++
 Documentation/devicetree/bindings/mfd/syscon.yaml  |  1 +
 drivers/i2c/busses/Kconfig                         |  1 +
 drivers/i2c/busses/i2c-qcom-cci.c                  | 42 ++++++++++++++++++++++
 4 files changed, 85 insertions(+)
---
base-commit: 8b7179210b22f8e48a82c5ceacb9d56a9c4cfec4
change-id: 20261105-ccu-99785a56dcd0

Best regards,
-- 
Wenmeng Liu <wenmeng.liu@oss.qualcomm.com>


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

* [PATCH RFC 1/3] dt-bindings: mfd: syscon: Add Qualcomm Nord Titan CAM_TOP
  2026-11-05 11:10 [PATCH RFC 0/3] Support the Nord CCI CCU output mux Wenmeng Liu
@ 2026-11-05 11:10 ` Wenmeng Liu
  2026-11-05 11:11 ` [PATCH RFC 2/3] dt-bindings: i2c: qcom-cci: Document Nord compatible Wenmeng Liu
  2026-11-05 11:11 ` [PATCH RFC 3/3] i2c: qcom-cci: Support the CCU output mux Wenmeng Liu
  2 siblings, 0 replies; 4+ messages in thread
From: Wenmeng Liu @ 2026-11-05 11:10 UTC (permalink / raw)
  To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Loic Poulain, Robert Foss, Andi Shyti
  Cc: mfd, devicetree, linux-kernel, linux-arm-msm, linux-i2c,
	vikram.sharma, nihal.gupta, vtumati, bryan.odonoghue,
	Wenmeng Liu

The CAM_TOP block in the Nord Titan camera subsystem contains
registers shared by several camera blocks, including the CCU output
mux used to route the CCI I2C ports.

The block is outside of the CCI and CAMSS register ranges, so describe
it as a syscon for its users to reference.

Signed-off-by: Wenmeng Liu <wenmeng.liu@oss.qualcomm.com>
---
 Documentation/devicetree/bindings/mfd/syscon.yaml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml
index 80ff0e1caca224d8dc7d8a0243acc49c253cccea..077c4037fa0ce4f1b93927579c2c326e7bed73d4 100644
--- a/Documentation/devicetree/bindings/mfd/syscon.yaml
+++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -109,6 +109,7 @@ properties:
               - qcom,apq8064-mmss-sfpb
               - qcom,apq8064-sps-sic
               - qcom,msm8960-sps-sic
+              - qcom,nord-titan-cam-top
               - rockchip,px30-qos
               - rockchip,rk3036-qos
               - rockchip,rk3066-qos

-- 
2.34.1


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

* [PATCH RFC 2/3] dt-bindings: i2c: qcom-cci: Document Nord compatible
  2026-11-05 11:10 [PATCH RFC 0/3] Support the Nord CCI CCU output mux Wenmeng Liu
  2026-11-05 11:10 ` [PATCH RFC 1/3] dt-bindings: mfd: syscon: Add Qualcomm Nord Titan CAM_TOP Wenmeng Liu
@ 2026-11-05 11:11 ` Wenmeng Liu
  2026-11-05 11:11 ` [PATCH RFC 3/3] i2c: qcom-cci: Support the CCU output mux Wenmeng Liu
  2 siblings, 0 replies; 4+ messages in thread
From: Wenmeng Liu @ 2026-11-05 11:11 UTC (permalink / raw)
  To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Loic Poulain, Robert Foss, Andi Shyti
  Cc: mfd, devicetree, linux-kernel, linux-arm-msm, linux-i2c,
	vikram.sharma, nihal.gupta, vtumati, bryan.odonoghue,
	Wenmeng Liu

Add the Nord CCI compatible. The CCI is based on the CCI v2 core, but
is wrapped by a CCU. After reset, the I2C ports are routed to the CCU
and the CCU output mux must select the CCI before any transfer can
take place.

Add the qcom,ccu-mux-sel property to describe the syscon register and
bits controlling the CCU output mux.

In addition to its core clock, the CCI requires the CCU AHB clock and
the camera subsystem top AHB and fast AHB clocks. The top AHB clock is
required to access the CCI registers and the CCU output mux.

Signed-off-by: Wenmeng Liu <wenmeng.liu@oss.qualcomm.com>
---
 .../devicetree/bindings/i2c/qcom,i2c-cci.yaml      | 41 ++++++++++++++++++++++
 1 file changed, 41 insertions(+)

diff --git a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml
index 1e8def25ec0ec1ef6b34859709d10a2a36fe36f5..5a25ebe0e61f686b86306a1dc94911e302d9b440 100644
--- a/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml
+++ b/Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml
@@ -29,6 +29,7 @@ properties:
               - qcom,glymur-cci
               - qcom,kaanapali-cci
               - qcom,milos-cci
+              - qcom,nord-cci
               - qcom,qcm2290-cci
               - qcom,qcs8300-cci
               - qcom,sa8775p-cci
@@ -70,6 +71,20 @@ properties:
   reg:
     maxItems: 1
 
+  qcom,ccu-mux-sel:
+    $ref: /schemas/types.yaml#/definitions/phandle-array
+    description:
+      On SoCs where the CCI sits in a CCU wrapper, the CCI I2C ports are
+      routed to the CCU after reset and the CCU output mux has to select the
+      CCI before any transfer.
+    items:
+      - items:
+          - description: phandle to the Titan CAM_TOP syscon
+          - description: byte offset of the CCU output mux register in the
+              syscon
+          - description: mask of the mux bits of this CCI, set to 1 to route
+              the I2C ports to this CCI
+
 patternProperties:
   "^i2c-bus@[01]$":
     $ref: /schemas/i2c/i2c-controller.yaml#
@@ -131,6 +146,32 @@ allOf:
             - const: cci_ahb
             - const: cci
 
+  - if:
+      properties:
+        compatible:
+          contains:
+            const: qcom,nord-cci
+    then:
+      properties:
+        clocks:
+          items:
+            - description: Camera subsystem top AHB clock, needed by the CCI
+                register interface and to access the CCU output mux
+            - description: CCI core clock
+            - description: AHB clock of the CCU wrapper the CCI sits in
+            - description: Camera subsystem top fast AHB clock
+        clock-names:
+          items:
+            - const: ahb
+            - const: cci
+            - const: ccu_ahb
+            - const: fast_ahb
+      required:
+        - qcom,ccu-mux-sel
+    else:
+      properties:
+        qcom,ccu-mux-sel: false
+
   - if:
       properties:
         compatible:

-- 
2.34.1


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

* [PATCH RFC 3/3] i2c: qcom-cci: Support the CCU output mux
  2026-11-05 11:10 [PATCH RFC 0/3] Support the Nord CCI CCU output mux Wenmeng Liu
  2026-11-05 11:10 ` [PATCH RFC 1/3] dt-bindings: mfd: syscon: Add Qualcomm Nord Titan CAM_TOP Wenmeng Liu
  2026-11-05 11:11 ` [PATCH RFC 2/3] dt-bindings: i2c: qcom-cci: Document Nord compatible Wenmeng Liu
@ 2026-11-05 11:11 ` Wenmeng Liu
  2 siblings, 0 replies; 4+ messages in thread
From: Wenmeng Liu @ 2026-11-05 11:11 UTC (permalink / raw)
  To: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Loic Poulain, Robert Foss, Andi Shyti
  Cc: mfd, devicetree, linux-kernel, linux-arm-msm, linux-i2c,
	vikram.sharma, nihal.gupta, vtumati, bryan.odonoghue,
	Wenmeng Liu

On SoCs such as Nord, the CCIs are wrapped by a CCU. After reset, the
CCI I2C ports are routed to the CCU, and the CCU output mux must select
the CCI before any transfer can take place.

Get the mux register and bits from the optional qcom,ccu-mux-sel syscon
reference and select the CCI at probe and runtime resume, right after
enabling the CCI clocks and before the CCI is reset or configured, as
the mux register is not retained across power collapse.

The mux register is accessible only with the camera subsystem top power
domain and AHB clock enabled, both of which are CCI resources. The
syscon regmap serializes the accesses from multiple CCI instances.

Signed-off-by: Wenmeng Liu <wenmeng.liu@oss.qualcomm.com>
---
 drivers/i2c/busses/Kconfig        |  1 +
 drivers/i2c/busses/i2c-qcom-cci.c | 42 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 275aaa7f35833f0b07ae13e88def21c3fbc6c787..63ba7314ee7c7cc57115e267a006cd058fe3e305 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -1061,6 +1061,7 @@ config I2C_PXA_SLAVE
 config I2C_QCOM_CCI
 	tristate "Qualcomm Camera Control Interface"
 	depends on ARCH_QCOM || COMPILE_TEST
+	select MFD_SYSCON
 	select PM_OPP
 	help
 	  If you say yes to this option, support will be included for the
diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c
index 76a5dedf659fb8396ca5df188143469977526505..0e2190cf3300b7da727fc798a1440f30fa73e28d 100644
--- a/drivers/i2c/busses/i2c-qcom-cci.c
+++ b/drivers/i2c/busses/i2c-qcom-cci.c
@@ -7,11 +7,13 @@
 #include <linux/i2c.h>
 #include <linux/io.h>
 #include <linux/interrupt.h>
+#include <linux/mfd/syscon.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_opp.h>
+#include <linux/regmap.h>
 
 #define CCI_HW_VERSION				0x0
 #define CCI_RESET_CMD				0x004
@@ -137,9 +139,26 @@ struct cci {
 	struct clk_bulk_data *clocks;
 	int nclocks;
 	struct clk *cci_clk;
+	/* Optional CCU output mux, routing the I2C ports to the CCI */
+	struct regmap *ccu_mux;
+	u32 ccu_mux_reg;
+	u32 ccu_mux_mask;
 	struct cci_master master[NUM_MASTERS];
 };
 
+/*
+ * Hand the I2C ports over to the CCI. This has to be done with the CCI
+ * clocks enabled, which the mux register access needs, and before the CCI
+ * is reset or configured.
+ */
+static int cci_ccu_mux_select(struct cci *cci)
+{
+	if (!cci->ccu_mux)
+		return 0;
+
+	return regmap_set_bits(cci->ccu_mux, cci->ccu_mux_reg, cci->ccu_mux_mask);
+}
+
 static irqreturn_t cci_isr(int irq, void *dev)
 {
 	struct cci *cci = dev;
@@ -651,6 +670,12 @@ static int __maybe_unused cci_resume_runtime(struct device *dev)
 	if (ret)
 		return ret;
 
+	ret = cci_ccu_mux_select(cci);
+	if (ret) {
+		cci_disable_clocks(cci);
+		return ret;
+	}
+
 	return cci_init(cci);
 }
 
@@ -668,6 +693,7 @@ static int cci_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct resource *r;
+	u32 mux_args[2];
 	struct cci *cci;
 	int ret, i;
 	u32 val;
@@ -730,6 +756,18 @@ static int cci_probe(struct platform_device *pdev)
 	if (IS_ERR(cci->base))
 		return PTR_ERR(cci->base);
 
+	cci->ccu_mux = syscon_regmap_lookup_by_phandle_args(dev->of_node, "qcom,ccu-mux-sel",
+							    2, mux_args);
+	if (IS_ERR(cci->ccu_mux)) {
+		ret = PTR_ERR(cci->ccu_mux);
+		if (ret != -ENOENT)
+			return dev_err_probe(dev, ret, "failed to get CCU mux\n");
+		cci->ccu_mux = NULL;
+	} else {
+		cci->ccu_mux_reg = mux_args[0];
+		cci->ccu_mux_mask = mux_args[1];
+	}
+
 	/* Clocks */
 
 	ret = devm_clk_bulk_get_all(dev, &cci->clocks);
@@ -761,6 +799,10 @@ static int cci_probe(struct platform_device *pdev)
 	if (ret < 0)
 		return ret;
 
+	ret = cci_ccu_mux_select(cci);
+	if (ret)
+		goto disable_clocks;
+
 	/* Interrupt */
 
 	ret = platform_get_irq(pdev, 0);

-- 
2.34.1


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

end of thread, other threads:[~2026-11-05 11:11 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-05 11:10 [PATCH RFC 0/3] Support the Nord CCI CCU output mux Wenmeng Liu
2026-11-05 11:10 ` [PATCH RFC 1/3] dt-bindings: mfd: syscon: Add Qualcomm Nord Titan CAM_TOP Wenmeng Liu
2026-11-05 11:11 ` [PATCH RFC 2/3] dt-bindings: i2c: qcom-cci: Document Nord compatible Wenmeng Liu
2026-11-05 11:11 ` [PATCH RFC 3/3] i2c: qcom-cci: Support the CCU output mux Wenmeng Liu

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

all inboxes | Powered by JetHome®