Linux v4l2子系统(8):Rockchip ISP
关键词:ISP、DMA等等。
1 Rockchip ISP的dts配置和初始化
rkisp0是硬件设备节点:
rkisp0: rkisp@fdcb0000 {
compatible = "rockchip,rk3588-rkisp";
reg = <0x0 0xfdcb0000 0x0 0x7f00>;
interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
<GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "isp_irq", "mi_irq", "mipi_irq";
clocks = <&cru ACLK_ISP0>, <&cru HCLK_ISP0>,
<&cru CLK_ISP0_CORE>, <&cru CLK_ISP0_CORE_MARVIN>,
<&cru CLK_ISP0_CORE_VICAP>;
clock-names = "aclk_isp", "hclk_isp", "clk_isp_core",
"clk_isp_core_marvin", "clk_isp_core_vicap";
power-domains = <&power RK3588_PD_VI>;
iommus = <&isp0_mmu>;
status = "disabled";
};
rkisp_hw_drv_init()从dts中后去ISP硬件配置信息,并填充初始化struct rkisp_hw_dev。
rkisp_hw_drv_init
platform_driver_register--处理rockchip,rk3588-rkisp硬件信息。
rkisp_hw_drv--
rkisp_hw_probe--解析dts,填充并初始化rkisp_hw_dev作为driver_data。
rkisp_get_sram
platform_driver_register--注册rockchip,rkisp-vir虚拟设备。
rkispp_hw_drv_init--ISPP即FEC的初始化。
一个ISP硬件可以虚拟出4个虚拟设备。rkisp_vir0即是ISP硬件设备的虚拟设备:
rkisp0_vir0: rkisp0-vir0 { compatible = "rockchip,rkisp-vir"; rockchip,hw = <&rkisp0>;--对应的硬件节点。 /* * dual isp process image case * other rkisp hw and virtual nodes should disabled * rockchip,hw = <&rkisp_unite>; */ status = "disabled"; }; &rkisp0_vir0 { status = "okay"; port { #address-cells = <1>; #size-cells = <0>; isp0_vir0: endpoint@0 { reg = <0>; remote-endpoint = <&mipi_lvds2_sditf>; }; }; };
rkisp的虚拟设备初始化如下:
platform_driver_register--注册rockchip,rkisp-vir虚拟设备。 rkisp_plat_drv-- rkisp_plat_probe rkisp_attach_hw--获取子节点"rockchip,hw"的信息。 v4l2_ctrl_handler_init v4l2_device_register media_device_init media_device_register rkisp_register_platform_subdevs ->rkisp_register_isp_subdev--创建Media Entity名称为rkisp-isp-subdev的v4l2_subdev设备。
->v4l2_subdev_init--初始化subdev,函数集为rkisp_isp_sd_ops。
->media_entity_pads_init
->v4l2_device_register_subdev ->rkisp_register_csi_subdev--ISP_V30跳过此函数。
->rkisp_register_bridge_subdev--未配置ISPP,跳过此函数。 ->rkisp_register_stream_vdevs
->rkisp_register_stream_v30
->rkisp_stream_init
->rkisp_init_vb2_queue
->vb2_queue_init--初始化vb2 buffer,操作函数集为rkisp_vb2_ops。
->rkisp_register_stream_vdev--创建4个stream v4l2设备:RKISP_STREAM_MP、RKISP_STREAM_SP、RKISP_STREAM_FBC、RKISP_STREAM_VIR。
->video_register_device--注册video设备,操作函数集为rkisp_fops和rkisp_v4l2_ioctl_ops。
->media_entity_pads_init
->media_create_pad_link ->rkisp_register_dmarx_vdev--创建3个类型DMA类型v4l2设备:RKISP_STREAM_RAWRD0、RKISP_STREAM_RAWRD2、RKISP_STREAM_RAWRD1。Entity名称为rkisp_rawrd0_m、rkisp_rawrd2_s、rkisp_rawrd1_1,每个Entity包含一个SourcePad。
->dmarx_init
->rkisp_register_dmarx_video
->rkisp_init_vb2_queue
->video_register_device--创建v4l2设备rkisp-statistics,操作函数集为rkisp_fops和rkisp_dmarx_ioctl。
->media_entity_pads_init
->media_create_pad_link ->rkisp_register_stats_vdev--创建1个Statistics类型v4l2设备。Entity名称为rkisp-statistics,仅包含一个Sink Pad。
->rkisp_stats_init_vb2_queue
->rkisp_init_stats_vdev
->media_entity_pads_init
->video_register_device--操作函数集为rkisp_stats_fops和rkisp_stats_ioctl。
->media_create_pad_link ->rkisp_register_params_vdev
->rkisp_params_init_vb2_queue
->rkisp_init_params_vdev
->media_entity_pads_init
->video_register_device--创建1个v4l2设备rkisp-input-params,操作函数集为rkisp_params_fops和rkisp_params_ioctl。
->media_create_pad_link ->rkisp_register_luma_vdev ->isp_subdev_notifier
->v4l2_async_notifier_init
->v4l2_async_notifier_parse_fwnode_endpoints--解析/rkisp0-vir0/port/下的endpoint。
->v4l2_async_notifier_register ->rkisp_proc_init--创建/proc/rkisp0-vir0节点,显示时钟、中断、输入等信息。
rkisp-isp-subdev对应的操作函数集为:
static const struct v4l2_subdev_pad_ops rkisp_isp_sd_pad_ops = { .enum_mbus_code = rkisp_isp_sd_enum_mbus_code, .get_selection = rkisp_isp_sd_get_selection, .set_selection = rkisp_isp_sd_set_selection, .get_fmt = rkisp_isp_sd_get_fmt, .set_fmt = rkisp_isp_sd_set_fmt, #ifdef CONFIG_MEDIA_CONTROLLER .link_validate = rkisp_subdev_fmt_link_validate, #endif }; static const struct v4l2_subdev_video_ops rkisp_isp_sd_video_ops = { .s_stream = rkisp_isp_sd_s_stream, .s_rx_buffer = rkisp_sd_s_rx_buffer, }; static const struct v4l2_subdev_core_ops rkisp_isp_core_ops = { .subscribe_event = rkisp_isp_sd_subs_evt, .unsubscribe_event = v4l2_event_subdev_unsubscribe, .s_power = rkisp_isp_sd_s_power, .ioctl = rkisp_ioctl, #ifdef CONFIG_COMPAT .compat_ioctl32 = rkisp_compat_ioctl32, #endif }; static struct v4l2_subdev_ops rkisp_isp_sd_ops = { .core = &rkisp_isp_core_ops, .video = &rkisp_isp_sd_video_ops, .pad = &rkisp_isp_sd_pad_ops, };
ISP设备:
- Entity rkisp-isp-subdev对应/dev/v4l-subdev3设备。Entity有两个Sink Pad,分别是:输入数据通道和参数配置通道;两个Source Pad,分别是输出数据和统计数据通道。
- 3个DMA相关Entity。每个Entity一个Source Pad。
- 1个参数配置Entity,包含一个Source Pad。
- 1个统计数据Entity,包含一个Sink Pad。
- 4个输出Stream Entity,每个包含一个Sink Pad。
联系方式:arnoldlu@qq.com