• 正文
  • 推荐器件
  • 相关推荐
申请入驻 产业图谱

Camera | 7.瑞芯微rk3568平台摄像头控制器MIPI-CSI驱动架构梳理

2024/01/09
2376
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论
因为有拍照、录制视频、直播等刚需,现在手机的摄像头基本都是高清,支持高清摄像头的SoC都支持MIPI-CSI。

不同SoC的MIPI-CSI在实现上有一定差别,即使同一厂家设计生产的芯片也都不尽相同。

本文基于瑞芯微rk3568平台evb1公板为例来详细讲解MIPI-CSI/DPHY驱动。

阅读本文之前,建议大家先仔细学习前面几篇文章。

一、rk3568硬件模块部分

驱动的研究往往要先从硬件着手,下面我首先看下rk3568公板电路

1)电路图

电路图可得摄像头与SoC的MIPI-CSI接口,可以是x4lane,也可以是x2lane,data和clk都是差分信号

如果不了解,建议问下硬件工程师

控制摄像头接口是I2C接口,并且位于I2C通道4下。

2)rk3568内部MIPI相关模块图

电路图只能查看SoC的MIPI控制器与摄像头的接口关系,下面我们来看下rk3568内部与mipi相关的模块。

吐槽一下瑞芯微的文档,一言难尽,我严重怀疑厂家压根就不想让其他人真正搞懂他们的SDK,这样好收每年的技术支持费用,高通这损招是让丫彻底学明白了。

由于官方给的手册要么有错误,要么就是有些图片错误,就不截图了。

下图是根据官方手册说明,整理的内部模块图。

    Sensor输出数据流通过MIPI的lanes传输给rk3568的DPHY控制器CSI控制器从硬件中提取出图像数据VICAP从MIPI接口读取数据然后将数据传递给给ISP ,ISP 再输出经过一系列图像处理算法后得到图像。MP用于预览图像SP用于缩放 VICAP
    Video Capture通过DVP/MIPI接口从摄像头读取数据,并通过AXI总线数据传输到主存中。

VICAP特性:

支持?BT601?YCbCr?422?8bit??、?RAW?8/10/12bit?输入
支持?BT656?YCbCr?422?8bit??输入
支持?BT1120?YCbCr?422?8bit?输入?,?单/双边?取样
支持?2/4?mixed?BT656/BT1120?YCbCr?422?8bit?input
支持?YUYV?序列的配置
支持?the?polarity?of?pixel_clk,?hsync?and?vsync?configurable
支持接收?CSI2?协议的数据(最多4个IDs)
支持接收?DSI?协议的数据(Video?mode/Command?mode)
支持窗口裁剪
支持virtual?stride?when?write?to?DDR
支持输出NV16/NV12格式的YUV数据
支持compact/non-compact?output?for?RAW?data
支持MMU
    ISP(图像信号处理)

ISP是一个完整的视频和静止图像输入设备。这个模块支持集成YCbCr处理图像传感器和简单CMOS传感器 ,提交没有任何综合图像处理Bayer RGB模式图像。

rk3568采用的是ISP21版本。

ISP21 包含了一系列的图像处理算法模块,主要包括:电流矫正、坏点矫正、3A、HDR、镜头阴影矫正、镜头畸变矫正、3DLUT、去噪(包括RAW域去噪,多帧降噪,颜色去噪等)、锐化等。

ISP21包括硬件算法实现及软件逻辑控制部分,RkAiq即为软件逻辑控制部分的实现。

RkAiq不断从ISP HW获取统计数据,并经过3A等算法生成新的参数反馈给各硬件模块。

RkAiq软件模块主要实现的功能为:从ISP驱动获取图像统计,结合IQ Tuning参数,使用一系列算法计算出新的ISP、Sensor等硬件参数,不断迭代该过程,最终达到最优的图像效果。

3)CSI_RX、VICAP、ISP寄存器基地址

《Rockchip RK3568 TRM Part1 V1.1-20210301.pdf》

二、 瑞芯微MIPI-CSI设备树分析

在rk3568中主要包含4个设备:

    • isp-subdev:图像处理控制器,如3a处理,并将处理后的所得的参数反馈给sensor。csi-subdev:mipi数据解析控制器。cis2-dphy:
    • mipi数据硬件接收控制器。sensor:外接的sensor,支持mipi输出。

下面我看下瑞芯微MIPI-CSI是如何用设备树描述的。

1. 内核中相关MIPI设备树说明文档

瑞芯微MIPI-CSI设备树节点属性说明参考内核说明文档:

[kernelDocumentationdevicetreebindingsmedia]
video-interfaces.txt?????????????关于sensor节点属性的说明,接口类型,
rockchip-isp1.txt????????????????isp模块属性说明
rockchip-mipi-dphy.txt???????????dphy模块的说明
kernelDocumentationdevicetreebindingsmediai2covxxxxxx.txt??ov系列的摄像设备树说明

2. 设备树节点说明

rk3568的MIPI-CSI用到的所有的设备树节点:

a) rockchip,rkisp-vir
rkisp_vir0:?rkisp-vir0?{
????compatible?=?"rockchip,rkisp-vir";
????rockchip,hw?=?<&rkisp>;
????status?=?"disabled";
};????

该设备树信息对应的初始化函数

[kerneldriversmediaplatformrockchipispdev.c]
struct?platform_driver?rkisp_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>;**中描述。

b) rkisp
rkisp:?rkisp@fdff0000?{
????compatible?=?"rockchip,rk3568-rkisp";
????reg?=?<0x0?0xfdff0000?0x0?0x10000>;
????interrupts?=?<GIC_SPI?57?IRQ_TYPE_LEVEL_HIGH>,
?????????????<GIC_SPI?58?IRQ_TYPE_LEVEL_HIGH>,
?????????????<GIC_SPI?60?IRQ_TYPE_LEVEL_HIGH>;?//中断使用的gpio,触发方式高电平触发
????interrupt-names?=?"mipi_irq",?"mi_irq",?"isp_irq";?//中断名称
????clocks?=?<&cru?ACLK_ISP>,?<&cru?HCLK_ISP>,?<&cru?CLK_ISP>;?//时钟
????clock-names?=?"aclk_isp",?"hclk_isp",?"clk_isp";???//时钟名称
????resets?=?<&cru?SRST_ISP>,?<&cru?SRST_H_ISP>;
????reset-names?=?"isp",?"isp-h";
????rockchip,grf?=?<&grf>;???
????power-domains?=?<&power?RK3568_PD_VI>;?????//isp?vicap电源和时钟
????iommus?=?<&rkisp_mmu>;????????????????//mmu属性
????rockchip,iq-feature?=?/bits/?64?<0x3FBFFFE67FF>;
????status?=?"disabled";
};????
?rkisp_mmu:?iommu@fdff1a00?{
??compatible?=?"rockchip,iommu-v2";
??reg?=?<0x0?0xfdff1a00?0x0?0x100>;
??interrupts?=?<GIC_SPI?59?IRQ_TYPE_LEVEL_HIGH>;
??interrupt-names?=?"isp_mmu";
??clocks?=?<&cru?ACLK_ISP>,?<&cru?HCLK_ISP>;
??clock-names?=?"aclk",?"iface";
??power-domains?=?<&power?RK3568_PD_VI>;
??#iommu-cells?=?<0>;
??rockchip,disable-mmu-reset;
??status?=?"disabled";
?};
?pmu:?power-management@fdd90000?{
???pd_vi@RK3568_PD_VI?{
????reg?=?<RK3568_PD_VI>;
????clocks?=?<&cru?HCLK_VI>,
??????<&cru?PCLK_VI>;
????pm_qos?=?<&qos_isp>,
??????<&qos_vicap0>,
??????<&qos_vicap1>;
???};
};

该设备树节点用于描述ISP硬件信息:基地址0xfdff0000 、中断源、时钟、reset引脚、iommus等。

驱动提取对应的硬件信息,填充到struct rkisp_hw_dev结构体变量中。

对应驱动入口:

[kerneldriversmediaplatformrockchipisphw.c]
static?struct?platform_driver?rkisp_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,
};
c) ?CSI2协议相关设备树
    csi2驱动相关硬件信息

以下是描述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?=?<1?2?3?4>;
????????????};
????????};
????????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???:?Sink?Pad(in表示进入该entity,上游连接的设备由remote-endpoint给出,即摄像头0v13850_out)
- data-lanes ?????: mipi通道数量:4
-?csidphy_out?????:?Source?Pad,下游连接的设备由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?=?<0x0?0xfe870000?0x0?0x1000>;
????clocks?=?<&cru?PCLK_MIPICSIPHY>;
????clock-names?=?"pclk";
????rockchip,grf?=?<&grf>;
????status?=?"disabled";
};

csi2dphy0 对应的驱动入口为:

[kerneldriversphyrockchipphy-rockchip-csi2-dphy-hw.c]
static?struct?platform_driver?rockchip_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

630????platform_driver_register(&rockchip_csi2_dphy_driver);

rockchip_csi2_dphy_driver定义如下:


[kerneldriversphyrockchipphy-rockchip-csi2-dphy-hw.c]
struct?platform_driver?rockchip_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开始分析。

三、驱动初始化

1. ?驱动文件目录

kernel
???├──?arch/arm64/boot/dts/rockchip?DTS?配置文件
???├──?drivers/phy/rockchip/
???????├──?phy-rockchip-csi2-dphy.c
????└──?phy-rockchip-csi2-dphy-hw.c?mipi?dphy?驱动?????
???├──?drivers/media|
????├──?platform/rockchip/isp?rkisp?isp?驱动
???????│???????????????????├──?capture_v21.c?包含?mp/sp?的配置及?vb2,帧中断处理??
???????│???????????????????├──?dev.c?包含?probe、异步注册、?clock、?pipeline、iommu?及?
??????????????????????????????????????media/v4l2?framework
???????│???????????????????├──?isp_params_v21.c?3A?相关参数设置
???????│???????????????????├──?isp_stats_v21.c?3A?相关统计
???????│???????????????????├──?regs.c?寄存器相关的读写操作
???????│???????????????????└──??rkisp.c?对应?isp_sd?entity?节点,
???????│???????????????????????包含从?mipi?接收数据,并有?crop?功能
???????├──?v4l2-core??v4l2核心代码
???????└──?i2c/
????????????└──?ov13850.c?CIS(cmos?image?sensor)驱动

注:3568的isp版本是v21,只需要看v21结尾的文件

1. 字符设备号申请:videodev_init()

该函数主要用于申请设备号:

主设备号 :81
设备名 ? ? :video4linux
申请class:video4linux

#define?VIDEO_MAJOR?81
#define?VIDEO_NUM_DEVICES?256
#define?VIDEO_NAME??????????????"video4linux"

static?struct?class?video_class?=?{
?.name?=?VIDEO_NAME,
?.dev_groups?=?video_device_groups,
};
static?int?__init?videodev_init(void)
{
?dev_t?dev?=?MKDEV(VIDEO_MAJOR,?0);
?ret?=?register_chrdev_region(dev,?VIDEO_NUM_DEVICES,?VIDEO_NAME);
?ret?=?class_register(&video_class);
}
static?void?__exit?videodev_exit(void)
{
?dev_t?dev?=?MKDEV(VIDEO_MAJOR,?0);

?class_unregister(&video_class);
?unregister_chrdev_region(dev,?VIDEO_NUM_DEVICES);
}

注意
为简化起见,所有代码只把最重要的部分列举出来,后同。

2. isp架构初始化:rkisp_plat_probe()

该函数是最重要的一个初始化函数,除了rkisp_csi2_dphy(entity67)外,其他的功能部件都在该函数中初始化。

注册rkisp-vir0父设备、isp-dubdev子设备、csi2-dev子设备等,由于rk3568支持多路sensor输入,即isp支持多路处理,因此会虚拟多通道isp-virx。

该函数主要工作:

      1. 给isp_dev申请内存并初始化,该结构体用于camera控制器所有的信息注册v4l2_device结构体初始化media相关资源函数rkisp_register_platform_subdevs(),用于注册拓扑结构中的各个模块,对应的entity详见图entity1、7注册为sub_device
      1. 初始化struct v4l2_subdev_ops、初始化media子模块需要相关信息
      1. entity1还会设置默认的图像格式entity13、19、25、31、37、43、49、55、61注册为video_device

填充struct v4l2_file_operations(struct video_device->fops)、struct v4l2_ioctl_ops(struct video_device->ioctl_ops),struct vb2_ops(struct video_device->vb2_queue->ops)

![ ](https://img-blog.csdnimg.cn/796972bedb2046e89d3e3772fec31a9b.png

其中对于研发人员最重要的就是这些回调函数,应用层下发的各个命令最终都会通过架构调用到这些函数。

下面把重要的几个模块所注册的回调函数做了个总结:

这些回调函数在架构中关系参考下图:

其中entity67相关资源是在函数rockchip_csi2_dphy_probe()中注册。

3. isp驱动初始化:rkisp_hw_probe()

该函数主要初始化isp驱动

static?const?struct?of_device_id?rkisp_hw_of_match[]?=?{
?……
?{
??.compatible?=?"rockchip,rk3568-rkisp",
??.data?=?&rk3568_isp_match_data,
?},
?{},
};

640?static?int?rkisp_hw_probe(struct?platform_device?*pdev)
641?{????
646??struct?rkisp_hw_dev?*hw_dev;??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
??……
??/*匹配设备树compatible属性*/
651?????match?=?of_match_node(rkisp_hw_of_match,?node);
654??/*为hw_dev?分配内存*/
655?????hw_dev?=?devm_kzalloc(dev,?sizeof(*hw_dev),?GFP_KERNEL);
659?????dev_set_drvdata(dev,?hw_dev);//dev->driver_data
660?????hw_dev->dev?=?dev;
661?????hw_dev->is_thunderboot?=?IS_ENABLED(CONFIG_VIDEO_ROCKCHIP_THUNDER_BOOT_ISP);
662?????dev_info(dev,?"is_thunderboot:?%dn",?hw_dev->is_thunderboot);
663?????hw_dev->max_in.w?=?0;
664?????hw_dev->max_in.h?=?0;
665?????hw_dev->max_in.fps?=?0;
??//获得grf句柄*/
669?????hw_dev->grf?=?syscon_regmap_lookup_by_phandle(node,?"rockchip,grf");
672?????/*获取控制器物理地址
673?????res?=?platform_get_resource(pdev,?IORESOURCE_MEM,?0);
??/*将物理地址映射为基地址*/
679?????hw_dev->base_addr?=?devm_ioremap_resource(dev,?res);

694?????match_data?=?match->data;
695?????hw_dev->mipi_irq?=?-1;
696?
697?????hw_dev->pdev?=?pdev;
698?????hw_dev->match_data?=?match_data;
699?????if?(!hw_dev->is_thunderboot)
700?????????rkisp_register_irq(hw_dev);??//注册中断
701??/*从设备树中提取时钟*/
702?????for?(i?=?0;?i?<?match_data->num_clks;?i++)?{
703?????????struct?clk?*clk?=?devm_clk_get(dev,?match_data->clks[i]);
704?
707?????????hw_dev->clks[i]?=?clk;
708?????}
709?????hw_dev->num_clks?=?match_data->num_clks;
710?????hw_dev->clk_rate_tbl?=?match_data->clk_rate_tbl;
711?????hw_dev->num_clk_rate_tbl?=?match_data->num_clk_rate_tbl;
712??/*提取reset属性*/
713?????hw_dev->reset?=?devm_reset_control_array_get(dev,?false,?false);
718?
719?????ret?=?of_property_read_u64(node,?"rockchip,iq-feature",?&hw_dev->iq_feature);
720?????if?(!ret)
721?????????hw_dev->is_feature_on?=?true;
722?????else
723?????????hw_dev->is_feature_on?=?false;
724??/*初始化其他的一些变量*/
725?????hw_dev->dev_num?=?0;
??…………
743?????hw_dev->is_shutdown?=?false;
744?????hw_dev->is_mmu?=?is_iommu_enable(dev);
745?????ret?=?of_reserved_mem_device_init(dev);
?…………
770?}

4. ?mipi接口dphy驱动初始化:rockchip_csi2_dphy_probe()、rockchip_csi2_dphy_hw_probe()

文中各种mipi技术文档,后台回复关键字:mipi

后面还会继续更新几篇Camera文章,

建议大家订阅本专题!

也可以后台留言,加一口君好友yikoupeng,

拉你进高质量技术交流群。

end

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
DS2431Q+T&R 1 Maxim Integrated Products EEPROM, 1KX1, Serial, CMOS, PDSO6, 3 X 3 MM, ROHS COMPLIANT, TDFN-6
$1.6 查看
XRCGB24M000F3A00R0 1 Murata Manufacturing Co Ltd Parallel - Fundamental Quartz Crystal, 24MHz Nom, ROHS AND REACH COMPLIANT, SMALL, SMD, 4 PIN

ECAD模型

下载ECAD模型
$0.45 查看
DP83867ISRGZT 1 Texas Instruments Industrial temperature, robust gigabit Ethernet PHY transceiver with SGMII 48-VQFN -40 to 85

ECAD模型

下载ECAD模型
$7.14 查看
瑞芯微电子

瑞芯微电子

瑞芯微专注于移动互联网、数字多媒体芯片设计,是专业的个人移动信息终端SOC解决方案供应商。瑞芯微在移动互联网领域有多个较完整的自主创新的知识产权群,为中国电子业发展做出积极努力。目前产品涵盖Android平板电脑、Android电视机顶盒(智能电视)、电子书、WIFI/蓝牙音频解决方案等,目前已发展为领先的物联网(IoT)及人工智能物联网(AIoT)处理器芯片企业。

瑞芯微专注于移动互联网、数字多媒体芯片设计,是专业的个人移动信息终端SOC解决方案供应商。瑞芯微在移动互联网领域有多个较完整的自主创新的知识产权群,为中国电子业发展做出积极努力。目前产品涵盖Android平板电脑、Android电视机顶盒(智能电视)、电子书、WIFI/蓝牙音频解决方案等,目前已发展为领先的物联网(IoT)及人工智能物联网(AIoT)处理器芯片企业。收起

查看更多

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录

公众号『一口Linux』号主彭老师,拥有15年嵌入式开发经验和培训经验。曾任职ZTE,某研究所,华清远见教学总监。拥有多篇网络协议相关专利和软件著作。精通计算机网络、Linux系统编程、ARM、Linux驱动、龙芯、物联网。原创内容基本从实际项目出发,保持原理+实践风格,适合Linux驱动新手入门和技术进阶。