目前正在rk3588 linux平台调试,kernel5.10,记录并总结下调试过程,防止忘记
1. dts配置
// SPDX-License-Identifier: (GPL-2.0+ OR MIT) /* * Copyright (c) 2022 Rockchip Electronics Co., Ltd. * */ / { cam_ircut0: cam_ircut { status = "okay"; compatible = "rockchip,ircut"; ircut-open-gpios = <&gpio4 RK_PA0 GPIO_ACTIVE_HIGH>; ircut-close-gpios = <&gpio4 RK_PA1 GPIO_ACTIVE_HIGH>; rockchip,camera-module-index = <0>; rockchip,camera-module-facing = "back"; }; }; &csi2_dcphy0 { status = "okay"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; #address-cells = <1>; #size-cells = <0>; mipidcphy0_in: endpoint@1 { reg = <1>; remote-endpoint = <&serdes_out0>; data-lanes = <1 2>; }; }; port@1 { reg = <1>; #address-cells = <1>; #size-cells = <0>; csidcphy0_out: endpoint@0 { reg = <0>; remote-endpoint = <&mipi0_csi2_input>; }; }; }; }; &csi2_dphy0_hw { status = "okay"; }; &i2c3 { status = "okay"; gmsl-deserializer@2c { compatible = "maxim,max9286"; reg = <0x2c>; enable-gpios = <&tca6408 2 GPIO_ACTIVE_HIGH>; framesync-gpio = <&gpio2 RK_PC4 GPIO_ACTIVE_HIGH>; num-si-slots = <0x4>; num-mi-slots = <0x1>; cam-config = <0x6>; mipi-lanes = <0x2>; pixel-freq = <996>; serializer_adapter_default = <&max96705_serdes_0>; serializer_adapter_brdcast = <&max96705_serdes_5>; sensor_adapter_brdcast = <&ar0231_4>; rockchip,camera-module-index = <0>; rockchip,camera-module-facing = "back"; rockchip,camera-module-name = "CMK-OT2022-PX1"; rockchip,camera-module-lens-name = "IR0147-50IRC-8M-F20"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; enable = <1>; video-format = <12>; video-width = <8>; cfa-pattern = "rggb"; serializer_adapter_link0 = <&max96705_serdes_1>; sensor_adapter_0 = <&ar0231_0>; serdes_in0: endpoint { remote-endpoint = <&sensor_out0>; }; }; port@1 { reg = <1>; enable = <1>; video-format = <12>; video-width = <8>; cfa-pattern = "rggb"; serializer_adapter_link1 = <&max96705_serdes_2>; sensor_adapter_1 = <&ar0231_1>; serdes_in1: endpoint { remote-endpoint = <&sensor_out1>; }; }; port@2 { reg = <2>; enable = <1>; video-format = <12>; video-width = <8>; cfa-pattern = "rggb"; serializer_adapter_link2 = <&max96705_serdes_3>; sensor_adapter_2 = <&ar0231_2>; serdes_in2: endpoint { remote-endpoint = <&sensor_out2>; }; }; port@3 { reg = <3>; enable = <1>; video-format = <12>; video-width = <8>; cfa-pattern = "rggb"; serializer_adapter_link3 = <&max96705_serdes_4>; sensor_adapter_3 = <&ar0231_3>; serdes_in3: endpoint { remote-endpoint = <&sensor_out3>; }; }; port@4 { reg = <4>; enable = <1>; video-format = <12>; video-width = <8>; cfa-pattern = "rggb"; serdes_out0: endpoint { remote-endpoint = <&mipidcphy0_in>; data-lanes = <1 2>; }; }; }; }; max96705_serdes_0:serdes@40 { compatible = "max96705-serdes"; reg = <0x40>; }; max96705_serdes_1:serdes@41 { compatible = "max96705-serdes"; reg = <0x41>; }; max96705_serdes_2:serdes@42 { compatible = "max96705-serdes"; reg = <0x42>; }; max96705_serdes_3:serdes@43 { compatible = "max96705-serdes"; reg = <0x43>; }; max96705_serdes_4:serdes@44 { compatible = "max96705-serdes"; reg = <0x44>; }; max96705_serdes_5:serdes@45 { compatible = "max96705-serdes"; reg = <0x45>; }; ar0231_0:sensor@10 { compatible = "ar0231"; reg = <0x10>; #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; sensor_out0: endpoint { remote-endpoint = <&serdes_in0>; }; }; }; ar0231_1:sensor@11 { compatible = "ar0231"; reg = <0x11>; #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; sensor_out1: endpoint { remote-endpoint = <&serdes_in1>; }; }; }; ar0231_2:sensor@12 { compatible = "ar0231"; reg = <0x12>; #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; sensor_out2: endpoint { remote-endpoint = <&serdes_in2>; }; }; }; ar0231_3:sensor@13 { compatible = "ar0231"; reg = <0x13>; #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; sensor_out3: endpoint { remote-endpoint = <&serdes_in3>; }; }; }; ar0231_4:sensor@14 { compatible = "ar0231-i2c"; reg = <0x14>; #address-cells = <1>; #size-cells = <0>; }; }; &mipi0_csi2 { status = "okay"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; #address-cells = <1>; #size-cells = <0>; mipi0_csi2_input: endpoint@1 { reg = <1>; remote-endpoint = <&csidcphy0_out>; }; }; port@1 { reg = <1>; #address-cells = <1>; #size-cells = <0>; mipi0_csi2_output: endpoint@0 { reg = <0>; remote-endpoint = <&cif_mipi0_in0>; }; }; }; }; &pinctrl { cam { mipidphy0_pwr: mipidphy0-pwr { rockchip,pins = /* camera power en */ <1 RK_PB2 RK_FUNC_GPIO &pcfg_pull_none>; }; }; }; &rkcif { status = "okay"; }; &rkcif_mipi_lvds { status = "okay"; port { cif_mipi0_in0: endpoint { remote-endpoint = <&mipi0_csi2_output>; }; }; }; &rkcif_mipi_lvds_sditf { status = "disabled"; port { mipi_lvds_sditf: endpoint { remote-endpoint = <&isp0_vir0>; }; }; }; &rkcif_mmu { status = "okay"; }; &rkisp0 { status = "okay"; }; &isp0_mmu { status = "okay"; }; &rkisp0_vir0 { status = "disabled"; port { #address-cells = <1>; #size-cells = <0>; isp0_vir0: endpoint@0 { reg = <0>; remote-endpoint = <&mipi_lvds_sditf>; }; }; };
2. rk平台max9286驱动代码
相关代码我是通过rk平台相关camera的代码修改的,详情可以查询我的上传
3. 调试过程
3.1 硬件原理图参考
建议通过正规的渠道购买max9286以便获得美信相关FAE的支持,不然从硬件角度和软件角度都没有支持,项目会很难进行,我现在的状况就是这样

3.2 驱动代码
我在调试前在外网收集了一些代码,当然kernel中自带的就max9286代码,只不过不符合rk的软件框架,相对来说要修改很多,所以我还是根据rk已有的相关代码修改的,节省很多时间
3.3 调试经验文档
相关调试比较好的调试经验可以参考以下文章:
另外可以查看max9286 programming guide,还有其他板卡的max9286的调试介绍vision-user-manual.pdf
3.4 调试问题以及调试过程
我将根据调试过程来列举我遇到的问题
1. i2c问题
在整理好驱动后,进probe函数后会读取sensor id,i2c地址不对,下面是量到的波形

图中红圈所标识的是奇怪的点,
1.起始信号后只有8个周期,没看到ack位
2.data上有奇怪的上拉然后立即下拉的过程,虽说在clock为低时不影响实际传输的值
后面有了解到i2c clock stretching时钟延展:通过将 SCL 线保持在低电平来暂停传输。在 SCL 再次拉高之前,传输无法进行。从机通过将 SCL 线拉低,强制主机进入等待状态
同时询问Rockchip 3588是否支持i2c clock stretching
实际的上的i2c clock stretching在max9286中的描述是在访问remote sensor时可能由于同轴电缆或者双绞线太长导致remote sensor回应慢,而现在的状况时加上这个调试max9286的子板就会出现这种i2c 波形,应该是硬件设计问题,i2c通信没发现什么问题,这个问题就没有深究
2. serializer i2c无法读取寄存器
在用v4l2-ctl 抓图的过程中会调用驱动中的start streaming函数,在这个函数中设置max9286的相关寄存器,设置完成后会读取max96705的link状态,遇到的状况就是始终无法读取
检查硬件状态,查看硬件配置BWS,CX/TP,I2CSEL,HIM ,MS
可参考max9286+max96705摄像头调试–基于imx8qm问题5
我检查下来的状态是BWS=0(open),HIM =1 (high),DRS = 0(high data rate mode),DBL = 1,这些个状态max9286和max96705一定要一致,用万用表两道HIM为高后,将寄存器0x1c设置为0xf4,可以读取max96705寄存器
3. v4l2-ctl不能抓取图像
v4l2-ctl --verbose -d /dev/video0 --stream-mmap=4 --stream-to=/data/1.yuv --stream-count=1 --stream-poll无法dump出数据,显示timeout,量max9286端mipi data有波形输出
排查步骤可以参考rockchip相关文档《Camera_Exteranl_FAQ_v2.1.pdf》
camera 正常传输图像像素数据是工作在高速传输模式下。建议查看 MIPI DPHY Status 寄存器,可以提示 DPHY 是否进入正常高速(Hs)状态采集高速(Hs)数据

root@RK3588:/# io -4 0xfdd10014
fdd10014: 000006f0
可以看到bit11为0,max9286 mipi只能工作在continue mode,而bit11 Clk lane continue 模式时,该状态固定为 1,目前的max9286已处于streaming状态,建议检查 Clk lane 至主控端的硬件连接是否正常,之前软件上配置的是max9286连接的是rk3588端的Dphy0,硬件原理图上的命名有问题,查看连接网络,实际上连接到核心板上的是DCPHY0,问题又来了,rockchip最新的硬件设计参考指出DCPHY建议使用2lane

官方解释:硬件逻辑设计的原因,导致dcphy对HS->LP11的时序要求很高,skew calibration会影响到结束的位置,所以不能开。目前推荐都是用2lane的。4lane的要使用,要求tx端的mipi时序有比较大的调整空间,目前看除了一些fpga输出的mipi能比较方便的调整时序,市面上大部分的tx端都很难调整到这部分特殊时序,光靠rx端的内部调整不能保证一定可以。
dts和驱动代码g_mbus函数中以及max9286配置都换成2lane后用v4l2-ctl抓图,由于平台问题,只能设置为NV12或NV6格式来抓图,设置为UYVY和YUYV主图报错,后面打上0001-media-rockchip-vicap-fixes-error-of-output-format-to.patch后能正常抓UYVY图像
上面的过程都是在基于硬件正常的情况下,如果还抓不到图,就需要查查硬件,在max9286寄存器配置完成后,用示波器测量max9286端和soc接收端的mipi clk和data,看波形、帧率等是否正常,任何一端mipi data没有信号或者有问题都不行,我这边就碰到过,由于转接板问题导致的soc mipi data0p和data0n短路的情况,还有就是max9286不正常,不能出mipi信号
另外,还可能碰到配置max9286寄存器过程中在访问remote sensor(max96705 7bit地址0x40)时出现错误,导致i2c错误,我这是信号经过的转接板太多,在设置max96712之前多加些延时,还有可能是POC供电有问题,还要测量coax同轴电缆是否有信号,板卡上电感是否坏了
4. 图像不正常
抓出的图像不正常

调整camera ar0231固件为UYVY,同时调整max96705 crossbar 大小端,
0x03, SER_I2C_LK0, 0x20, 0x07,
0x03, SER_I2C_LK0, 0x21, 0x06,
0x03, SER_I2C_LK0, 0x22, 0x05,
0x03, SER_I2C_LK0, 0x23, 0x04,
0x03, SER_I2C_LK0, 0x24, 0x03,
0x03, SER_I2C_LK0, 0x25, 0x02,
0x03, SER_I2C_LK0, 0x26, 0x01,
0x03, SER_I2C_LK0, 0x27, 0x00,
0x03, SER_I2C_LK0, 0x30, 0x17,
0x03, SER_I2C_LK0, 0x31, 0x16,
0x03, SER_I2C_LK0, 0x32, 0x15,
0x03, SER_I2C_LK0, 0x33, 0x14,
0x03, SER_I2C_LK0, 0x34, 0x13,
0x03, SER_I2C_LK0, 0x35, 0x12,
0x03, SER_I2C_LK0, 0x36, 0x11,
0x03, SER_I2C_LK0, 0x37, 0x10,
能正常一路camera出图像
5. 4路camera出图问题
同步可参考[max9286+max96705摄像头调试–基于imx8qm]
目前设置为内同步,手动模式,需要设置同步时钟则需设置0x06~0x08寄存器
0x03, DSR_I2C_DEF, 0x06, 0xa8,
0x03, DSR_I2C_DEF, 0x07, 0x14,
0x03, DSR_I2C_DEF, 0x08, 0x45,
0x03, DSR_I2C_DEF, 0x01, 0x00,
四路同步需要检查寄存器

max9286配置为4路camera有严格的时序问题,我们再之前的配置,虽然所有寄存器的状态全部正确,但单独切换到link1~4,可以发现并没有mipi波形,我们在开机后用i2ctransfer手动给max9286配置寄存器,发现在配置完第一路link和第二路link配置后再切回第一路,发现第一路已经停了(示波器一直连着mipi data0),像这样连续试很久才配置出一种4路camera均能输出的情况,注意再同步后,切换到link2~4,需要设置0x0B link order寄存器,选择当前link为first csi output order,不然在示波器上只能看到sync信号,没有完整的mipi data 波形
在所有link通道都有输出后,在soc端需要配置dphy接收的mipi clock,可以用示波器从max9286端量出,单个camera 2lane为200M,4个camera为800M,完成后就应该能用v4l2-ctrl抓图,当然可能会出现很多mipi ERR1、ERR2,根据相应情况排查
6. 只能从VC0拿到数据
按照以往的经验,多路camera应该试按排列给与特定的virtual channel,在通过video0~3来达到特定的数据,但目前只能达到vc0中的数据,由于没有美信原厂的支持,我们一致在排查这个问题,

io -4 -l 0x1000 0xfdce0000 查看vc收发,vc0是19c
在max9286一直输出的情况下,查看soc端vc0~3接收的情况,可以看到只有vc0异能接收到帧头帧尾,而因为没有美信的支持,所以一直卡在这个阶段,max9286出来的数据也没法保证正确与否,只能量信号确认
试过0x15设置成0x1b即设置成(4 x W)x H

可以用video0抓到vc0的图像,用video1–3抓不到vc1–3的图像,报timeout错误,查看soc端vc接收寄存器19c,发现vc1~3错误
0x15配置成0x9b即设置成W x (4 x H)

四路camera能用以下命令出图
v4l2-ctl -d /dev/video0 --set-fmt-video=width=1280,height=720,pixelformat=NV16 --stream-mmap=4
但用NV16或NV12或者UYVY抓出来的图像不正常,图像始终蒙了一层绿色

后面发现所有的数据都只有低4位,高位为0,通过把 低位移到高位可以发现图像变亮,绿色的蒙板没了
后面咨询了美信的代理商,发现max9286只出一路vc0,0x15设置为0x1b模式出的超级帧包含了4路camera的数据,只需要在驱动中设置width为1280*4,抓的图为4路camera的组合帧
937

被折叠的 条评论
为什么被折叠?



