Hello everyone,
I'm continuing my evaluation of the GX-MIPI-IMX662 cameras as potential replacements for the VEYE-MIPI-IMX462. First, thank you for uploading the kernel 6.1 drivers, it saved significant porting effort.
I've built a system image based on linux-rockchip 6.1 with the provided drivers and adapted the device tree overlays for my dev board. I used my existing working overlay for the VEYE-MIPI-IMX462 on CSI0 and the provided GX camera examples for Firefly and Orange Pi boards on github.
However, I've encountered a problem during testing. My board has two identical 31-pin 0.3mm CSI connectors: CSI0 and CSI1. When a GX camera is connected to CSI0, the video stream fails to start and the kernel log is spammed with MIPI_CSI2 ERR1/ERR2 errors. The camera is correctly detected via I2C judging by correct output of gx_probe.sh. When connected to CSI1, frames are received at the expected 60 FPS, but the kernel log still has some errors (though much fewer).
Some additional context:
The cameras are always connected via the same adapter pcb (camera 22-pin to board 31-pin, 4-lane MIPI-CSI) that handles pinout and i2c levels. The adapter has a hardware limitation and both gpio pins (5 and 6) on camera side are pulled high (3.3V).
The VEYE series cameras work without any issues on CSI0 using the same adapter and 15-pin to 22-pin stock cable. The GX cameras have external 5VDC connected (5.05V measured while running the test command) using stock dupont wires.
I have tried updating the GX camera firmware but found it was already at the latest version referenced in the GX camera firmware update manual on wiki. I've also tried replacing the GX camera module with another one (I have two of them).
Testing:
GX-MIPI-IMX662 connected to CSI0 (fails)
The camera probe is successful, but the v4l2-ctl command hangs.
source rk35xx_veye_bsp/gx_i2c_tools/gx_probe.sh 3
Found veye_gxcam camera on i2c-3.
Setenv I2C_BUS = 3
Setenv CAMERAMODEL = GX-MIPI-IMX662
Setenv FPS = 60
Setenv WIDTH = 1920
Setenv HEIGHT = 1080
v4l2-ctl --set-fmt-video=width=$WIDTH,height=$HEIGHT,pixelformat=UYVY --stream-mmap --stream-count=-1 --stream-to=/dev/null
^C
The dmesg output for this test shows a good amount of various MIPI CSI-2 errors (ecc, crc, frame sync):
[ 75.870155] (0xfdd30000)MIPI_CSI2 ERR1:0x10000000 (ecc2)
[ 75.870764] (0xfdd30000)MIPI_CSI2 ERR1:0x10000000 (ecc2)
[ 75.871912] (0xfdd30000)MIPI_CSI2 ERR2:0x100 (ecc,vc: 0)
[ 75.871924] (0xfdd30000)MIPI_CSI2 ERR1:0x10 (fs/fe mis,vc: 0)
[ 75.874969] (0xfdd30000)MIPI_CSI2 ERR2:0x8800 (ecc,vc: 3) (err id,vc: 3)
[ 75.875197] (0xfdd30000)MIPI_CSI2 ERR1:0x8000000 (crc,vc: 3)
... (many similar lines) ...
[ 75.989465] rockchip-mipi-csi2 mipi2-csi2: stream off, src_sd: 00000000833c3caa, sd_name:rockchip-csi2-dphy0
[ 75.989477] rockchip-mipi-csi2 mipi2-csi2: stream OFF
GX-MIPI-IMX662 connected to CSI1 (works with errors)
The camera probe is successful, and frames are streamed at ~60 FPS.
source rk35xx_veye_bsp/gx_i2c_tools/gx_probe.sh 4
Found veye_gxcam camera on i2c-4.
Setenv I2C_BUS = 4
Setenv CAMERAMODEL = GX-MIPI-IMX662
Setenv FPS = 60
Setenv WIDTH = 1920
Setenv HEIGHT = 1080
v4l2-ctl --set-fmt-video=width=$WIDTH,height=$HEIGHT,pixelformat=UYVY --stream-mmap --stream-count=-1 --stream-to=/dev/null
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 61.62 fps
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 60.94 fps
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 60.63 fps
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 60.46 fps
^C
However, dmesg still reports some crc and data errors:
[ 53.285363] rkcif-mipi-lvds4: stream[0] start streaming
...
[ 53.288967] rockchip-csi2-dphy3: dphy3, data_rate_mbps 1188
[ 53.711971] (0xfdd50000)MIPI_CSI2 ERR1:0x1000000 (crc,vc: 0)
[ 53.713534] (0xfdd50000)MIPI_CSI2 ERR1:0x1000000 (crc,vc: 0)
[ 53.715025] (0xfdd50000)MIPI_CSI2 ERR1:0x1000 (err_data,vc: 0)
... (error lines continue throughout stream) ...
[ 65.103234] rockchip-mipi-csi2 mipi4-csi2: stream off, src_sd: 00000000d08c0081, sd_name:rockchip-csi2-dphy3
Device tree overlays used
GX Camera on CSI0: rk3588-camera-gxcam-csi0.dts
/dts-v1/;
/plugin/;
#include <dt-bindings/clock/rk3588-cru.h>
#include <dt-bindings/power/rk3588-power.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/rockchip.h>
/ {
fragment@0 {
target = <&i2c3>;
__overlay__ {
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&i2c3m0_xfer>;
gxcam: gxcam@3b{
status = "okay";
compatible = "veye,gxcam";
reg = <0x3b>;
clocks = <&cru CLK_MIPI_CAMARAOUT_M3>;
clock-names = "xvclk";
pinctrl-names = "default";
pinctrl-0 = <&mipim0_camera3_clk>;
power-domains = <&power RK3588_PD_VI>;
rockchip,grf = <&sys_grf>;
pwdn-gpios = <&gpio1 RK_PB0 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_HIGH>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "NC";
rockchip,camera-module-lens-name = "NC";
port {
gxcam_out0: endpoint {
remote-endpoint = <&mipidphy0_in_ucam0>;
data-lanes = <1 2>;
};
};
};
};
};
fragment@1 {
target = <&csi2_dphy0_hw>;
__overlay__ {
status = "okay";
};
};
fragment@2 {
target = <&csi2_dphy0>;
__overlay__ {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipidphy0_in_ucam0: endpoint@1 {
reg = <1>;
remote-endpoint = <&gxcam_out0>;
data-lanes = <1 2>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
csidphy0_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi2_csi2_input>;
};
};
};
};
};
fragment@3 {
target = <&mipi2_csi2>;
__overlay__ {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi2_csi2_input: endpoint@1 {
reg = <1>;
remote-endpoint = <&csidphy0_out>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
mipi2_csi2_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&cif_mipi2_in0>;
};
};
};
};
};
fragment@4 {
target = <&rkcif>;
__overlay__ {
status = "okay";
};
};
fragment@5 {
target = <&rkcif_mipi_lvds2>;
__overlay__ {
status = "okay";
port {
cif_mipi2_in0: endpoint {
remote-endpoint = <&mipi2_csi2_output>;
};
};
};
};
fragment@6 {
target = <&rkcif_mipi_lvds2_sditf>;
__overlay__ {
status = "disabled";
port {
mipi_lvds2_sditf: endpoint {
remote-endpoint = <&isp0_vir2>;
};
};
};
};
fragment@7 {
target = <&rkcif_mmu>;
__overlay__ {
status = "okay";
};
};
fragment@8 {
target = <&rkisp0>;
__overlay__ {
status = "disabled";
};
};
fragment@9 {
target = <&isp0_mmu>;
__overlay__ {
status = "disabled";
};
};
fragment@10 {
target = <&rkisp0_vir2>;
__overlay__ {
status = "disabled";
port {
#address-cells = <1>;
#size-cells = <0>;
isp0_vir2: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi_lvds2_sditf>;
};
};
};
};
};
GX Camera on CSI1: rk3588-camera-gxcam-csi1.dts
/dts-v1/;
/plugin/;
#include <dt-bindings/clock/rk3588-cru.h>
#include <dt-bindings/power/rk3588-power.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/rockchip.h>
/ {
fragment@0 {
target = <&i2c4>;
__overlay__ {
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&i2c4m1_xfer>;
gxcam_1: gxcam_1@3b {
status = "okay";
compatible = "veye,gxcam";
reg = <0x3b>;
clocks = <&cru CLK_MIPI_CAMARAOUT_M2>;
clock-names = "xvclk";
pinctrl-names = "default";
pinctrl-0 = <&mipim0_camera2_clk>;
power-domains = <&power RK3588_PD_VI>;
rockchip,grf = <&sys_grf>;
pwdn-gpios = <&gpio3 RK_PA2 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio3 RK_PA0 GPIO_ACTIVE_HIGH>;
rockchip,camera-module-index = <1>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "NC";
rockchip,camera-module-lens-name = "NC";
port {
gxcam_out1: endpoint {
remote-endpoint = <&mipidphy3_in_ucam3>;
data-lanes = <1 2>;
};
};
};
};
};
fragment@1 {
target = <&csi2_dphy1_hw>;
__overlay__ {
status = "okay";
};
};
fragment@2 {
target = <&csi2_dphy3>;
__overlay__ {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipidphy3_in_ucam3: endpoint@1 {
reg = <1>;
remote-endpoint = <&gxcam_out1>;
data-lanes = <1 2>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
csidphy3_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi4_csi2_input>;
};
};
};
};
};
fragment@3 {
target = <&mipi4_csi2>;
__overlay__ {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi4_csi2_input: endpoint@1 {
reg = <1>;
remote-endpoint = <&csidphy3_out>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
mipi4_csi2_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&cif_mipi_in4>;
};
};
};
};
};
fragment@4 {
target = <&rkcif>;
__overlay__ {
status = "okay";
};
};
fragment@5 {
target = <&rkcif_mipi_lvds4>;
__overlay__ {
status = "okay";
port {
cif_mipi_in4: endpoint {
remote-endpoint = <&mipi4_csi2_output>;
};
};
};
};
fragment@6 {
target = <&rkcif_mipi_lvds4_sditf>;
__overlay__ {
status = "disabled";
port {
mipi4_lvds_sditf: endpoint {
remote-endpoint = <&isp1_vir1>;
};
};
};
};
fragment@7 {
target = <&rkcif_mmu>;
__overlay__ {
status = "okay";
};
};
fragment@8 {
target = <&rkisp1>;
__overlay__ {
status = "disabled";
};
};
fragment@9 {
target = <&isp1_mmu>;
__overlay__ {
status = "disabled";
};
};
fragment@10 {
target = <&rkisp1_vir1>;
__overlay__ {
status = "disabled";
port {
#address-cells = <1>;
#size-cells = <0>;
isp1_vir1: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi4_lvds_sditf>;
};
};
};
};
};
Working VEYE camera on CSI0: rk3588-camera-veyecam2m-csi0.dts
/dts-v1/;
/plugin/;
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/rockchip.h>
#include <dt-bindings/power/rk3588-power.h>
/ {
compatible = "rockchip,rk3588";
fragment@0 {
target = <&i2c3>;
__overlay__ {
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&i2c3m0_xfer>;
veyecam2m_0: veyecam2m@3b{
status = "okay";
compatible = "veye,veyecam2m";
reg = <0x3b>;
pinctrl-names = "default";
pinctrl-0 = <&mipim0_camera3_clk>;
power-domains = <&power RK3588_PD_VI>;
pwdn-gpios = <&gpio1 RK_PB0 GPIO_ACTIVE_HIGH>;
reset-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_LOW>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "NC";
rockchip,camera-module-lens-name = "NC";
port {
veyecam2m_0_out: endpoint {
remote-endpoint = <&mipidphy0_in_ucam0>;
data-lanes = <1 2>;
};
};
};
};
};
fragment@1 {
target = <&csi2_dphy0_hw>;
__overlay__ {
status = "okay";
};
};
fragment@2 {
target = <&csi2_dphy0>;
__overlay__ {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipidphy0_in_ucam0: endpoint@1 {
reg = <1>;
remote-endpoint = <&veyecam2m_0_out>;
data-lanes = <1 2>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
csidphy0_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi2_csi2_input>;
};
};
};
};
};
fragment@3 {
target = <&mipi2_csi2>;
__overlay__ {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi2_csi2_input: endpoint@1 {
reg = <1>;
remote-endpoint = <&csidphy0_out>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
mipi2_csi2_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&cif_mipi2_in0>;
};
};
};
};
};
fragment@4 {
target = <&rkcif>;
__overlay__ {
status = "okay";
};
};
fragment@5 {
target = <&rkcif_mmu>;
__overlay__ {
status = "okay";
};
};
fragment@6 {
target = <&rkcif_mipi_lvds2>;
__overlay__ {
status = "okay";
port {
cif_mipi2_in0: endpoint {
remote-endpoint = <&mipi2_csi2_output>;
};
};
};
};
fragment@7 {
target = <&rkcif_mipi_lvds2_sditf>;
__overlay__ {
status = "disabled";
port {
mipi_lvds2_sditf: endpoint {
remote-endpoint = <&isp0_vir0>;
};
};
};
};
fragment@8 {
target = <&rkisp0>;
__overlay__ {
status = "disabled";
};
};
fragment@9 {
target = <&isp0_mmu>;
__overlay__ {
status = "disabled";
};
};
fragment@10 {
target = <&rkisp0_vir0>;
__overlay__ {
status = "disabled";
port {
#address-cells = <1>;
#size-cells = <0>;
isp0_vir0: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi_lvds2_sditf>;
};
};
};
};
};
I'm still trying to figure out the issue. The most obvious difference is the GX camera's higher data rate. Any help or debugging steps would be greatly appreciated. I'm happy to run any tests or provide more details about my setup if it helps.