点击左上方蓝色“一口Linux”,选择“设为星标”
瑞芯微 | 摄像头ov13850移植笔记
VICAP特性:
(相关资料图)
支持BT601YCbCr4228bit、RAW8/10/12bit输入支持BT656YCbCr4228bit输入支持BT1120YCbCr4228bit输入,单/双边取样支持2/4mixedBT656/BT1120YCbCr4228bitinput支持YUYV序列的配置支持thepolarityofpixel_clk,hsyncandvsyncconfigurable支持接收CSI2协议的数据(最多4个IDs)支持接收DSI协议的数据(Videomode/Commandmode)支持窗口裁剪支持virtualstridewhenwritetoDDR支持输出NV16/NV12格式的YUV数据支持compact/non-compactoutputforRAWdata支持MMU
ISP是一个完整的视频和静止图像输入设备。这个模块支持集成YCbCr处理图像传感器和简单CMOS传感器 ,提交没有任何综合图像处理Bayer RGB模式图像。
rk3568采用的是ISP21版本。
ISP21 包含了一系列的图像处理算法模块,主要包括:暗电流矫正、坏点矫正、3A、HDR、镜头阴影矫正、镜头畸变矫正、3DLUT、去噪(包括RAW域去噪,多帧降噪,颜色去噪等)、锐化等。
ISP21包括硬件算法实现及软件逻辑控制部分,RkAiq即为软件逻辑控制部分的实现。
RkAiq不断从ISP HW获取统计数据,并经过3A等算法生成新的参数反馈给各硬件模块。
RkAiq软件模块主要实现的功能为:从ISP驱动获取图像统计,结合IQ Tuning参数,使用一系列算法计算出新的ISP、Sensor等硬件参数,不断迭代该过程,最终达到最优的图像效果。
《Rockchip RK3568 TRM Part1 V1.1-20210301.pdf》
在rk3568中主要包含4个设备:
下面我看下瑞芯微MIPI-CSI是如何用设备树描述的。
瑞芯微MIPI-CSI设备树节点属性说明参考内核说明文档:
[kernel\Documentation\devicetree\bindings\media]video-interfaces.txt关于sensor节点属性的说明,接口类型,rockchip-isp1.txtisp模块属性说明rockchip-mipi-dphy.txtdphy模块的说明kernel\Documentation\devicetree\bindings\media\i2c\ovxxxxxx.txtov系列的摄像设备树说明
rk3568的MIPI-CSI用到的所有的设备树节点:
rkisp_vir0:rkisp-vir0{compatible="rockchip,rkisp-vir";rockchip,hw=<&rkisp>;status="disabled";};
该设备树信息对应的初始化函数
[kernel\drivers\media\platform\rockchip\isp\dev.c]structplatform_driverrkisp_plat_drv={.driver={.name=DRIVER_NAME,.of_match_table=of_match_ptr(rkisp_plat_of_match),.pm=&rkisp_plat_pm_ops,},.probe=rkisp_plat_probe,.remove=rkisp_plat_remove,};
该节点用于初始化isp相关的组件,
驱动程序会创建拓扑图中的 rkisp-isp-subdev、rkisp-csi-subdev、rkisp_mainpath、rkisp_selfpath、rkisp_rawwr0、rkisp_rawwr2、rkisp_rawwr3、rkisp_rawrd0_m、rkisp_rawrd2_s、rkisp-statistics、、rkisp-input-params 组件
isp硬件相关的信息在父节点**rockchip,hw = <&rkisp>;**中描述。
rkisp:rkisp@fdff0000{compatible="rockchip,rk3568-rkisp";reg=<0x00xfdff00000x00x10000>;interrupts=,,;//中断使用的gpio,触发方式高电平触发interrupt-names="mipi_irq","mi_irq","isp_irq";//中断名称clocks=<&cruACLK_ISP>,<&cruHCLK_ISP>,<&cruCLK_ISP>;//时钟clock-names="aclk_isp","hclk_isp","clk_isp";//时钟名称resets=<&cruSRST_ISP>,<&cruSRST_H_ISP>;reset-names="isp","isp-h";rockchip,grf=<&grf>;power-domains=<&powerRK3568_PD_VI>;//ispvicap电源和时钟iommus=<&rkisp_mmu>;//mmu属性rockchip,iq-feature=/bits/64<0x3FBFFFE67FF>;status="disabled";};rkisp_mmu:iommu@fdff1a00{compatible="rockchip,iommu-v2";reg=<0x00xfdff1a000x00x100>;interrupts=;interrupt-names="isp_mmu";clocks=<&cruACLK_ISP>,<&cruHCLK_ISP>;clock-names="aclk","iface";power-domains=<&powerRK3568_PD_VI>;#iommu-cells=<0>;rockchip,disable-mmu-reset;status="disabled";};pmu:power-management@fdd90000{pd_vi@RK3568_PD_VI{reg=;clocks=<&cruHCLK_VI>,<&cruPCLK_VI>;pm_qos=<&qos_isp>,<&qos_vicap0>,<&qos_vicap1>;};};
该设备树节点用于描述ISP硬件信息:基地址0xfdff0000 、中断源、时钟、reset引脚、iommus等。
驱动提取对应的硬件信息,填充到struct rkisp_hw_dev结构体变量中。
对应驱动入口:
[kernel\drivers\media\platform\rockchip\isp\hw.c]staticstructplatform_driverrkisp_hw_drv={.driver={.name="rkisp_hw",.of_match_table=of_match_ptr(rkisp_hw_of_match),.pm=&rkisp_hw_pm_ops,},.probe=rkisp_hw_probe,.remove=rkisp_hw_remove,.shutdown=rkisp_hw_shutdown,};
以下是描述csi2_dphy0拓扑信息,实际摄像头信息需要用户自己填写:
[rk3568-evb1-ddr4-v10.dtsi]&csi2_dphy0{status="okay";ports{#address-cells=<1>;#size-cells=<0>;port@0{reg=<0>;#address-cells=<1>;#size-cells=<0>;mipi_in_ucam0:endpoint@1{reg=<1>;remote-endpoint=<&0v13850_out>;data-lanes=<1234>;};};port@1{reg=<1>;#address-cells=<1>;#size-cells=<0>;csidphy_out:endpoint@0{reg=<0>;remote-endpoint=<&isp0_in>;};};};};
该节点描述内容:
-父节点csi2_dphy0-port@n:表示pad号为n-mipi_in_ucam0:SinkPad(in表示进入该entity,上游连接的设备由remote-endpoint给出,即摄像头0v13850_out)- data-lanes : mipi通道数量:4-csidphy_out:SourcePad,下游连接的设备由remote-endpoint给出,即isp0_in
以下是csi2_dphy控制器相关硬件信息,位于瑞芯微3568平台设备树文件rk3568.dtsi中
[rk3568.dtsi]aliases{csi2dphy0=&csi2_dphy0;……}csi2_dphy0:csi2-dphy0{compatible="rockchip,rk3568-csi2-dphy";rockchip,hw=<&csi2_dphy_hw>;status="disabled";};csi2_dphy_hw:csi2-dphy-hw@fe870000{compatible="rockchip,rk3568-csi2-dphy-hw";reg=<0x00xfe8700000x00x1000>;clocks=<&cruPCLK_MIPICSIPHY>;clock-names="pclk";rockchip,grf=<&grf>;status="disabled";};
csi2dphy0 对应的驱动入口为:
[kernel\drivers\phy\rockchip\phy-rockchip-csi2-dphy-hw.c]staticstructplatform_driverrockchip_csi2_dphy_hw_driver={.probe=rockchip_csi2_dphy_hw_probe,.remove=rockchip_csi2_dphy_hw_remove,.driver={.name="rockchip-csi2-dphy-hw",.of_match_table=rockchip_csi2_dphy_hw_match_id,},};
在函数rockchip_csi2_dphy_hw_probe()中还会注册结构体变量 rockchip_csi2_dphy_driver
630platform_driver_register(&rockchip_csi2_dphy_driver);
rockchip_csi2_dphy_driver定义如下:
[kernel\drivers\phy\rockchip\phy-rockchip-csi2-dphy-hw.c]structplatform_driverrockchip_csi2_dphy_driver={.probe=rockchip_csi2_dphy_probe,.remove=rockchip_csi2_dphy_remove,.driver={.name="rockchip-csi2-dphy",.pm=&rockchip_csi2_dphy_pm_ops,.of_match_table=rockchip_csi2_dphy_match_id,},};
分析驱动就要从这些入口函数probe开始分析。
kernel├──arch/arm64/boot/dts/rockchipDTS配置文件├──drivers/phy/rockchip/├──phy-rockchip-csi2-dphy.c└──phy-rockchip-csi2-dphy-hw.cmipidphy驱动├──drivers/media|├──platform/rockchip/isprkispisp驱动│├──capture_v21.c包含mp/sp的配置及vb2,帧中断处理│├──dev.c包含probe、异步注册、clock、pipeline、iommu及media/v4l2framework│├──isp_params_v21.c3A相关参数设置│├──isp_stats_v21.c3A相关统计│├──regs.c寄存器相关的读写操作│└──rkisp.c对应isp_sdentity节点,│包含从mipi接收数据,并有crop功能├──v4l2-corev4l2核心代码└──i2c/└──ov13850.cCIS(cmosimagesensor)驱动
注:3568的isp版本是v21,只需要看v21结尾的文件
该函数主要用于申请设备号:
主设备号 :81设备名 :video4linux申请class:video4linux
#defineVIDEO_MAJOR81#defineVIDEO_NUM_DEVICES256#defineVIDEO_NAME"video4linux"staticstructclassvideo_class={.name=VIDEO_NAME,.dev_groups=video_device_groups,};staticint__initvideodev_init(void){dev_tdev=MKDEV(VIDEO_MAJOR,0);ret=register_chrdev_region(dev,VIDEO_NUM_DEVICES,VIDEO_NAME);ret=class_register(&video_class);}staticvoid__exitvideodev_exit(void){dev_tdev=MKDEV(VIDEO_MAJOR,0);class_unregister(&video_class);unregister_chrdev_region(dev,VIDEO_NUM_DEVICES);}
注意为简化起见,所有代码只把最重要的部分列举出来,后同。
该函数是最重要的一个初始化函数,除了rkisp_csi2_dphy(entity67)外,其他的功能部件都在该函数中初始化。
注册rkisp-vir0父设备、isp-dubdev子设备、csi2-dev子设备等,由于rk3568支持多路sensor输入,即isp支持多路处理,因此会虚拟多通道isp-virx。
该函数主要工作:
中注册。
该函数主要初始化isp驱动
staticconststructof_device_idrkisp_hw_of_match[]={……{.compatible="rockchip,rk3568-rkisp",.data=&rk3568_isp_match_data,},{},};640staticintrkisp_hw_probe(structplatform_device*pdev)641{646structrkisp_hw_dev*hw_dev;……/*匹配设备树compatible属性*/651match=of_match_node(rkisp_hw_of_match,node);654/*为hw_dev分配内存*/655hw_dev=devm_kzalloc(dev,sizeof(*hw_dev),GFP_KERNEL);659dev_set_drvdata(dev,hw_dev);//dev->driver_data660hw_dev->dev=dev;661hw_dev->is_thunderboot=IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);662dev_info(dev,"is_thunderboot:%d\n",hw_dev->is_thunderboot);663hw_dev->max_in.w=0;664hw_dev->max_in.h=0;665hw_dev->max_in.fps=0;//获得grf句柄*/669hw_dev->grf=syscon_regmap_lookup_by_phandle(node,"rockchip,grf");672/*获取控制器物理地址673res=platform_get_resource(pdev,IORESOURCE_MEM,0);/*将物理地址映射为基地址*/679hw_dev->base_addr=devm_ioremap_resource(dev,res);694match_data=match->data;695hw_dev->mipi_irq=-1;696697hw_dev->pdev=pdev;698hw_dev->match_data=match_data;699if(!hw_dev->is_thunderboot)700rkisp_register_irq(hw_dev);//注册中断701/*从设备树中提取时钟*/702for(i=0;inum_clks;i++){703structclk*clk=devm_clk_get(dev,match_data->clks[i]);704707hw_dev->clks[i]=clk;708}709hw_dev->num_clks=match_data->num_clks;710hw_dev->clk_rate_tbl=match_data->clk_rate_tbl;711hw_dev->num_clk_rate_tbl=match_data->num_clk_rate_tbl;712/*提取reset属性*/713hw_dev->reset=devm_reset_control_array_get(dev,false,false);718719ret=of_property_read_u64(node,"rockchip,iq-feature",&hw_dev->iq_feature);720if(!ret)721hw_dev->is_feature_on=true;722else723hw_dev->is_feature_on=false;724/*初始化其他的一些变量*/725hw_dev->dev_num=0;…………743hw_dev->is_shutdown=false;744hw_dev->is_mmu=is_iommu_enable(dev);745ret=of_reserved_mem_device_init(dev);…………770}
文中各种mipi技术文档,后台回复关键字:mipi
后面还会继续更新几篇Camera文章,
建议大家订阅本专题!
也可以后台留言,加一口君好友yikoupeng,
拉你进高质量技术交流群。
精彩文章合集
文章推荐
Copyright © 2015-2022 华东数据网版权所有 备案号:京ICP备2022016840号-41 联系邮箱:2 913 236 @qq.com