LXR | KVM | PM | Time | Interrupt | Systems Performance | Bootup Optimization

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_fopsrkisp_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_fopsrkisp_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_fopsrkisp_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_fopsrkisp_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。

posted on 2024-04-13 23:59  ArnoldLu  阅读(994)  评论(0编辑  收藏  举报

导航