背景描述:需要在板卡上实现两路4lane的MIPI CSI2接口。官方设备树默认提供的是4路2lane的MIPI CSI2接口。
参考官方资料:Common/ISP/ISP32-lite/Rockchip_Driver_Guide_VI_CN_v1.1.4.pdf
RKVICAP
驱动的设备拓扑结构:
多
sensor
支持
框图说明:


从上述官方文档描述可知设备树应参考如下链路进行配置。

但是实测发现按照上述配置只有一个摄像头能正常使用4lane模式。需调整csi2_dphy1链路的rkcif_mipi_lvds2改为rkcif_mipi_lvds1;csi2_dphy4链路的rkcif_mipi_lvds4该为rkcif_mipi_lvds3对于的下一环节分别修改为rkcif_mipi_lvds1_sditf、&rkcif_mipi_lvds3_sditf。
具体设备树配置如下:
&i2c1 {
status = "okay";
vm149c_2: vm149c@c {
compatible = "silicon touch,vm149c";
status = "okay";
reg = <0x0c>;
rockchip,camera-module-index = <1>;
rockchip,camera-module-facing = "back";
};
ov13850_2: ov13850@36 {
compatible = "ovti,ov13850";
status = "okay";
reg = <0x36>;
clocks = <&cru CLK_MIPI_CAMERAOUT_M1>;
clock-names = "xvclk";
pwdn-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_HIGH>;
power-domains = <&power RK3576_PD_VI>;
rockchip,camera-module-index = <1>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "RK-CMK-8M-2-v1";
rockchip,camera-module-lens-name = "CK8401";
lens-focus = <&vm149c_2>;
port {
camera2_out: endpoint {
remote-endpoint = <&mipi_dphy3_in_tl13850>;
data-lanes = <1 2 3 4>;
};
};
};
};
&i2c6 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c6m0_xfer>;
vm149c_1: vm149c@c {
compatible = "silicon touch,vm149c";
status = "okay";
reg = <0x0c>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
};
ov13850_1: ov13850@36 {
compatible = "ovti,ov13850";
status = "okay";
reg = <0x36>;
clocks = <&cru CLK_MIPI_CAMERAOUT_M1>;
clock-names = "xvclk";
pwdn-gpios = <&gpio1 RK_PB3 GPIO_ACTIVE_HIGH>;
power-domains = <&power RK3576_PD_VI>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "RK-CMK-8M-2-v1";
rockchip,camera-module-lens-name = "CK8401";
lens-focus = <&vm149c_1>;
port {
camera1_out: endpoint {
remote-endpoint = <&mipi_dphy0_in_tl13850>;
data-lanes = <1 2 3 4>;
};
};
};
};
&csi2_dphy0 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi_dphy0_in_tl13850: endpoint@1 {
reg = <1>;
remote-endpoint = <&camera1_out>;
data-lanes = <1 2 3 4>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
csidphy0_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi2_csi2_input>;
};
};
};
};
&csi2_dphy3 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi_dphy3_in_tl13850: endpoint@1 {
reg = <1>;
remote-endpoint = <&camera2_out>;
data-lanes = <1 2 3 4>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
csidphy3_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi4_csi2_input>;
};
};
};
};
&mipi2_csi2 {
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_mipi_in1>;
};
};
};
};
&mipi4_csi2 {
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_in3>;
};
};
};
};
&rkcif_mipi_lvds1 {
status = "okay";
port {
cif_mipi_in1: endpoint {
remote-endpoint = <&mipi2_csi2_output>;
};
};
};
&rkcif_mipi_lvds3 {
status = "okay";
port {
cif_mipi_in3: endpoint {
remote-endpoint = <&mipi4_csi2_output>;
};
};
};
&rkcif_mipi_lvds1_sditf {
status = "okay";
port {
mipi_lvds1_sditf: endpoint {
remote-endpoint = <&isp_vir2_in0>;
};
};
};
&rkcif_mipi_lvds3_sditf {
status = "okay";
port {
mipi_lvds3_sditf: endpoint {
remote-endpoint = <&isp_vir1_in0>;
};
};
};
&rkisp_vir1 {
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
isp_vir1_in0: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi_lvds3_sditf>;
};
};
};
&rkisp_vir2 {
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
isp_vir2_in0: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi_lvds1_sditf>;
};
};
};
&rkcif {
status = "okay";
};
&csi2_dphy0_hw {
status = "okay";
};
&csi2_dphy1_hw {
status = "okay";
};
&rkcif_mmu {
status = "okay";
};
&rkisp {
status = "okay";
};
&rkisp_mmu {
status = "okay";
};
&rkvpss {
status = "okay";
};
&rkvpss_mmu {
status = "okay";
};
&rkvpss_vir0 {
status = "okay";
};
&rkisp_vir0_sditf {
status = "okay";
};
&rkvpss_vir1 {
status = "okay";
};
&rkvpss_vir2 {
status = "okay";
};
修改完后重新编译内核镜像测试即可。
抓图可使用如下命令
v4l2-ctl -d /dev/
video-camera0
--set-fmt-video=width=1920,height=1080,pixelformat='UYVY'
--stream-mmap=4 --stream-count=1 --stream-to=/tmp/cap.raw --stream-skip=2
参数说明:
-d
:指定设备名称
--set-fmt-video
:设置分辨率,需和
sensor
输出分辨率一致,
sensor
当前分辨率可通过
media-ctl -p -d
/dev/mediaX
查看。
pixelformat
:输出数据格式
--stream-mmap
:
mmap buffer
数量。
--stream-count
:抓取的帧数,多帧也是存在同一文件。
--stream-to
:指定存储路径。
--stream-skip
:跳掉的帧数。
实时显示到显示wayland上命令
配置
wayland显示在
HDMI为主屏
echo "output:HDMI-A-1:primary" > /tmp/.weston_drm.conf
获取视频流并显示到HDMI命令:
gst-launch-1.0 v4l2src device=/dev/video-camera0 ! video/x-raw,format=NV12,width=1920,height=1080, framerate=30/1 ! waylandsink
查看video设备节点对于的media拓扑结构命令
media-ctl -p -d /dev/media0
查看mp对应的video节点命令
media-ctl -d /dev/media1 -e "rkisp_mainpath"