基于RV1126 Video分析-----驱动各模块总览

发布时间 2023-07-05 17:14:08作者: 阿风小子
一 通用理论
硬件链接:
一般情况下,Camera和SOC有两个接口进行连接,分为为MIPI接口和I2C接口,其中MIPI接口用来传输图像的数据,数据传输路径为从Sensor传输到SOC。另一个接口为I2C接口,主要是用来SOC对Sensor初始化配置寄存器和摄像头参数的配置,比如要进行图像数据捕获的时候就需要通过i2c对Sensor的寄存器进行配置。
 
图像数据流:
光线经过Sensor之后,Sensor芯片经过ADC转换生成原始图像数据(raw),然后Sensor生成的原始图像数据(raw)经过MIPI总线进入SOC,进入SOC之后经过图像处理芯片(如ISP)进行图像处理。所以由此可以可以看出,Camera驱动V4L2一定有这3部分组成:
 
第一部分与Sensor相关的,比如控制Sensor的寄存器进行配置,这一部分是有Sensor厂家提供。
 
第二部分和MIPI相关的,需要MIPI进行图像传输,所以驱动应该就有这一部分的驱动,这部分一般是由SOC厂家提供。
 
第三部分就是ISP部分,有些SOC有ISP图像处理模块,经过MIPI传输的图像进入SOC之后需要在传入SOC的ISP模块对图像进一步进行加工,所以一定是有一部分驱动是描述ISP模块的。
 
(光) -------> [sensor] ----->(raw图像数据) ----->[mipi总线] ----->[图像处理芯片(如ISP)] -----> (NV16/NV12等格式图像数据)
 
raw格式sensor的输出格式,是sensor将光信号转换为电信号时的电平高低的原始记录,没有经过处理的原始数据
 
 
二 从DTS 中找到这三部分
我们已经知道Camera有3部分的驱动,分别是描述Sensor、MIPI相关、图像处理芯片相关的,所以在dts中也有描述这3部分的。
 
第一部分
sensor 相关dts
 
&i2c1 {                                          
                                                                                   
tp2855_1: tp2855_1@44 {  
 
compatible = "techpoint,tp2855";                        
reg = <0x44>;  //i2c地址                     
...
port {                                        
ucam_out0: endpoint {                       
remote-endpoint = <&csi_dphy0_input>; //Sensor连接到mipi
data-lanes = <1 2 3 4>;                   
};                                          
};   
}; 
 
tp2855_2: tp2855_2@45 {
compatible = "techpoint,tp2855";
reg = <0x45>; //i2c地址         
...
 
port {
ucam_out1: endpoint {
remote-endpoint = <&csi_dphy1_input>; //Sensor连接到mipi    csi_dphy1_input
data-lanes = <1 2 3 4>; 
};
};
};
};    
 
第二部分
mipi 物理总线相关
 
对于RV1126和RV1106平台而言,支持两个DPHY硬件,存在两个独立而完备的标准物理mipi csi2 dphy,对应于dts上的csi_dphy0和csi_dphy1(参见rv1126.dtsi),特性如下:
 
data lane最大4 lanes;
最大速率2.5Gbps/lane;
1
2
sensor----mipi dphy
 
//连接 0x44 前四通道 摄像头
&csi_dphy0 {                                     
status = "okay";                 
 
  //mipi有两端一段连接Sensor,另一端连接 mipi_csi2_input
ports {                                         
#address-cells = <1>;                         
#size-cells = <0>;                            
          //连接到Sensor                                        
port@0 {                                      
reg = <0>;                                  
#address-cells = <1>;                       
#size-cells = <0>;                          
                                                 
csi_dphy0_input: endpoint@1 {               
reg = <1>;                                
remote-endpoint = <&ucam_out0>;    // 连接到Sensor : ucam_out0       
data-lanes = <1 2 3 4>;                   
};                                          
};                                            
         //连接到 mipi_csi2_input                             
port@1 {                                      
reg = <1>;                                  
#address-cells = <1>;                       
#size-cells = <0>;                          
                                                 
csi_dphy0_output: endpoint@0 {              
reg = <0>;                                
remote-endpoint = <&mipi_csi2_input>;     // 连接到 mipi_csi2_input
data-lanes = <1 2 3 4>;                   
};                                          
};                                            
};                                             
};                                             
 
//连接 0x45 后四通道摄像头             
&csi_dphy1 {                                     
status = "okay";
 
//连接到Sensor      
ports {
#address-cells = <1>;
#size-cells = <0>;
 
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
 
csi_dphy1_input: endpoint@1 {
reg = <1>;
remote-endpoint = <&ucam_out1>;// 连接到Sensor : ucam_out1 
data-lanes = <1 2 3 4>;
};
};
 
//连接到ISP   
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
 
csi_dphy1_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&isp_in>; // 连接到ISP : isp_in
data-lanes = <1 2 3 4>;
};
};
};     
};     
 
第三部分
mipi 协议解析相关 (MIPI Host)
每个mipi phy都需要一个csi2模块来解析mipi协议
sensor----mipi dphy ---- mipi_csi2
 
&mipi_csi2 {                                     
status = "okay";                                
    
ports {                                         
#address-cells = <1>;                         
#size-cells = <0>;                            
                                                 
port@0 {                                      
reg = <0>;                                  
#address-cells = <1>;                       
#size-cells = <0>;                          
                                                 
mipi_csi2_input: endpoint@1 {               
reg = <1>;                                
remote-endpoint = <&csi_dphy0_output>;    
data-lanes = <1 2 3 4>;                   
};                                          
};                                            
                                                                                     
port@1 {                                      
reg = <1>;                                  
#address-cells = <1>;                       
#size-cells = <0>;                          
                                                 
mipi_csi2_output: endpoint@0 {              
reg = <0>;                                
remote-endpoint = <&cif_mipi_in>;         
data-lanes = <1 2 3 4>;                   
};                                          
};                                            
};                                            
};    
 
第四部分
图像处理芯片(vicap)相关
 
sensor----mipi dphy ---- mipi_csi2-----vicap
 
rkcif_mipi_lvds: rkcif_mipi_lvds {
compatible = "rockchip,rkcif-mipi-lvds";
rockchip,hw = <&rkcif>;
// iommus = <&rkcif_mmu>;
memory-region = <&isp_reserved>;
status = "disabled";
};
 
&rkcif_mipi_lvds {                               
status = "okay";                                
     rockchip,cif-monitor = <3 2 25 1000 5>;
port {                                          
/* MIPI CSI-2 endpoint */                     
cif_mipi_in: endpoint {                       
remote-endpoint = <&mipi_csi2_output>;      
data-lanes = <1 2 3 4>;                     
};                                            
};                                            
};     
 
图像处理芯片(isp)相关
 
&rkisp_vir0 {                                    
status = "okay";
ports {
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
 
isp_in: endpoint@0 {
reg = <0>;
remote-endpoint = <&csi_dphy1_output>;//连接到 mipi : csi_dphy1_output
};
};
};                         
}; 
 
0x44 前四通道 连接关系
图像处理走vicap
 
ucam_out0 - csi_dphy0_input - csi_dphy0_output - mipi_csi2_input <-> mipi_csi2_output
 
 
  tp2855_1@44    csi_dphy0                                 mipi_csi2                        rkcif_mipi_lvds
   ucam_out0 ---> csi_dphy0_input -- csi_dphy0_output   -->   mipi_csi2_input -- mipi_csi2_output   <--->    cif_mipi_in
 
前四通道 驱动拆分:
 
1 关于 sensor模块分析: sensor.c
kernel\drivers\media\i2c\techpoint\techpoint_v4l2.c
 
2 关于 mipi 物理层 (csi dphy)模块 (csi_dphy0 / csi_dphy1)分析 : mipi_csi_dphy.c
kernel\drivers\phy\rockchip\phy-rockchip-mipi-rx.c
 
3 关于 mipi解析模块( mipi csi)(MIPI Host)模块分析:mipi_csi.c
kernel\drivers\media\platform\rockchip\cif\mipi-csi2.c
 
   
4 关于 图像处理vicap 模块分析:rkcif_mipi.c
kernel\drivers\media\platform\rockchip\cif\dev.c
 
0x45 后四通道 连接关系
图像处理走isp
 
ucam_out1 - csi_dphy1_input - csi_dphy1_output <-> isp_in
 
tp2855_2@45          csi_dphy1 rkisp_vir0
ucam_out1  -->  csi_dphy1_input -- csi_dphy1_output   <---> isp_in
 
由上面分析我们可以知道在Camera的框架中在不同板子或者说不同平台,有3部分是需要实现的。
 
第一部分Sensor相关即不同板子摄像头选型肯定是不一样的,这部分的驱动就是要实现Sensor的初始化,寄存器的配置等,比如启动图像捕获的时候,需要配置寄存器,从应用层会使用一个ioctl一步
一步的调用下来到驱动中,所以这部分是Sensor相关的,需要Sensor提供相应的驱动。
 
第二部分MIPI相关,比如我们常用的SOC和Sensor连接就是使用MIPI接口,所以就需要实现MIPI相关部分的驱动,这部分一般来说是由SOC厂商进行提供。
 
第三部分图像处理芯片(如ISP)部分,如果我们的SOC平台如果有ISP模块那么就有ISP模块部分的驱动代码,这部分也是SOC厂商提供的。
 
从dts的配置中我们可以看到,驱动的绑定路径为,从Sensor连接到MIPI然后MIPI连接到ISP,所以说Sensor捕获到的数据通过MIPI传入ISP,然后通过ISP处理后传动应用层进行处理,整个Camera的驱动框
架大概就是这个流程。