Support for MIPI YCbCr 4:2:2 Camera Input on QCS6490 (V4L2 vs CAMX)

Hi~,
We are planning to validate a product that can receive a MIPI camera input in YCbCr 4:2:2 format using the Rubik Pi platform.

Could you advise whether this can be supported using the QCS6490’s V4L2 framework, or if it is also feasible through Qualcomm’s CAMX camera stack?

Any guidance, references, or examples related to this use case would be greatly appreciated.

Thank you in advance.

May I confirm which operating system you are currently using—Linux, Ubuntu, or Android?
Is ISP processing required?
Is it mandatory to open via V4L2/CAMX?
Is YCbCr 4:2:2 the definitive required format, or would 4:2:0 satisfy your requirements?

We are considering Linux and Ubuntu. ISP processing is not required, and it would be preferable to use V4L2.
Since the image sensor supports only 4:2:2, YCbCr 4:2:2 is mandatory.

The “libcamera camss” bypasses the ISP, but you need to switch the device tree and drivers. You can also write the appropriate sensor driver yourself, and this solution supports V4L2. For more information, please refer to the following Qualcomm documentation.

Thank you for your explanation.

To clarify one point, could you please confirm whether the libcamera camss (ISP bypass) solution supports YCbCr 4:2:2 output via V4L2 when the image sensor provides only 4:2:2?

Our sensor does not support 4:2:0, so native 4:2:2 support is mandatory for our use case.
Please let us know if this is supported by the CAMSS hardware and drivers, or if additional driver customization is required.

Thank you in advance.

CAMX supports YCbCr 4:2:2 format. As for libcamera camss, we have not conducted practical tests yet.

Have you tested any practical camera sensor with libcamera camss yet??

We have adapted the RAW-MIPI-AR0234M sensor for our customer on Linux and Ubuntu versions.
Could the issue you are currently facing be as follows:
“the sensor is detected, the device tree is OK but on stream-on, no frames are received”

Does the RAW MIPI sensor was using qcom-camss to receive the RAW frames out ? Did the sensor manage to stream?

Yes, the RAW MIPI sensor was using qcom-camss to receive the RAW frames, and the sensor managed to stream.

Good to know! I am trying to adapt IMX219 to stream, it gets detected and configured. However, on stream-on, it is unable to stream. Would you mind sharing a device tree for the sensor integration?

You may refer to our working IMX412 implementation and make modifications accordingly for your sensor.

imx412 :

diff --git a/arch/arm64/boot/dts/qcom/qcm6490-camera-sensor-rubikpi3.dtsi b/arch/arm64/boot/dts/qcom/qcm6490-camera-sensor-rubikpi3.dtsi
index cd4758f7a..e6f59c096 100644
--- a/arch/arm64/boot/dts/qcom/qcm6490-camera-sensor-rubikpi3.dtsi
+++ b/arch/arm64/boot/dts/qcom/qcm6490-camera-sensor-rubikpi3.dtsi
@@ -25,7 +25,7 @@ camera2_vio_ldo: gpio-regulator@1 {
 		regulator-enable-ramp-delay = <233>;
 		enable-active-high;
 		gpio = <&tlmm 19 0>;
-		status = "ok";
+		status = "disabled";
 	};

 	qcom,cam-res-mgr {
@@ -209,6 +209,7 @@ config {

 &soc {
 	qcom,cci0 {
+		status = "disabled";
 		qcom,actuator0 {
 			status = "disabled";
 		};
@@ -252,7 +253,7 @@ qcom,cam-sensor1 {
 			gpio-req-tbl-flags = <1 0>;
 			gpio-req-tbl-label = "CAMIF_MCLK2", "CAM_RESET2";
 			cci-master = <0>;
-			status = "ok";
+			status = "disabled";
 			clocks = <&camcc CAM_CC_MCLK2_CLK>;
 			clock-names = "cam_clk";
 			clock-cntl-level = "nominal";
@@ -304,11 +305,70 @@ qcom,cam-sensor0 {
 			gpio-req-tbl-flags = <1 0>;
 			gpio-req-tbl-label = "CAMIF_MCLK0", "CAM_RESET4";
 			cci-master = <0>;
-			status = "ok";
+			status = "disabled";
 			clocks = <&camcc CAM_CC_MCLK0_CLK>;
 			clock-names = "cam_clk";
 			clock-cntl-level = "nominal";
 			clock-rates = <24000000>;
 		};
 	};
-};
\ No newline at end of file
+};
+
+
+&cci1 {
+    status = "okay";
+    assigned-clocks = <&camcc CAM_CC_CCI_1_CLK_SRC>;
+    assigned-clock-rates = <37500000>;
+};
+
+&cci1_i2c0 {
+    clock-frequency = <400000>;
+    //camera1
+	camera@3B {
+		compatible = "veye,mvcam";
+		reg = <0x3B>;
+		status = "ok";
+
+		reset-gpios = <&tlmm 57 0>;
+		pinctrl-names = "default", "suspend";
+		pinctrl-0 = <&cam_sensor_active_rst4>;
+		pinctrl-1 = <&cam_sensor_suspend_rst4>;
+
+		clocks = <&camcc CAM_CC_MCLK0_CLK>;
+		assigned-clocks = <&camcc CAM_CC_MCLK0_CLK>;
+		assigned-clock-rates = <24000000>;
+		rotation = <0>;
+		orientation = <2>;
+
+		VANA-supply  = <&camera1_vio_ldo>;
+
+		port {
+			veye_ep: endpoint {
+				clock-lanes = <7>;
+				link-frequencies = /bits/ 64 <600000000>;
+				clock-noncontinuous;
+				data-lanes = <0 1>;
+				remote-endpoint = <&csiphy1_ep>;
+			};
+		};
+	};
+};
+
+
+&camss {
+	status = "ok";
+	ports {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/* The port index denotes CSIPHY id i.e. csiphy1 */
+		port@1 {
+			reg = <1>;
+			csiphy1_ep: endpoint {
+				clock-lanes = <7>;
+				data-lanes = <0 1>;
+				remote-endpoint = <&veye_ep>;
+			};
+		};
+	};
+};
diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi
index f8346a59a..3df490f18 100644
--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi
+++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi
@@ -6155,7 +6155,7 @@ camss: camss@acaf000 {
 					<&camcc CAM_CC_IFE_2_GDSC>,
 					<&camcc CAM_CC_TITAN_TOP_GDSC>;

-			power-domains-names = "ife0", "ife1", "ife2", "top";
+			power-domain-names = "ife0", "ife1", "ife2", "top";

 			reg = <0x0 0x0acb3000 0x0 0x1000>,
 			      <0x0 0x0acba000 0x0 0x1000>,
1 Like