VC-MIPI-modules / vc_mipi_nvidia

Vision Components MIPI CSI-2 driver for NVIDIA Jetson Nano, Xavier NX, AGX Xavier, TX2 and Orin Nano, Orin NX
69 stars 31 forks source link

With the Orin Nano and 2 IMX568 cameras, there is tearing in the image. #67

Open burak-ayd opened 4 months ago

burak-ayd commented 4 months ago

We managed to take images with Orin Nano and 2 IMX568 cameras, but there are tearing in the video. We do not have this problem with JNX30D and Xavier NX.

Device Tree

/*
 * Copyright (c) 2023, Vision Components GmbH.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <dt-bindings/media/camera.h>

// ------------------------------------------------------------------------------------------------
//  Driver Configuration for NVIDIA Jetson Orin Nano on NVIDIA Jetson Orin Nano Developer Kit
// ------------------------------------------------------------------------------------------------
#define VC_MIPI_CAM_1       1   // 1: Enabled, 0: Disabled  (serial_a => CSI Port 0 => VI Stream 0)
#define VC_MIPI_CAM_0       1   // 1: Enabled, 0: Disabled  (serial_c => CSI Port 2 => VI Stream 2)
// ------------------------------------------------------------------------------------------------
//  Supported number of lanes
// -----+------------------------------------------------------------------------------------------
//  1   | OV7251, IMX296, IMX297
//  2   | OV9281, IMX264, IMX265
//  2,4 | IMX178, IMX183, IMX226, IMX250, IMX252, IMX273, IMX290, IMX327, IMX335, IMX392, 
//      | IMX412, IMX415, IMX568
// -----+------------------------------------------------------------------------------------------
#define VC_MIPI_LANES       4   // 1, 2, 4 Lanes
// ------------------------------------------------------------------------------------------------
//  Embedded Metadata Height
// -----+------------------------------------------------------------------------------------------
//  0   | IMX178, IMX183, IMX226, IMX250, IMX252, IMX264, IMX265, IMX273, IMX392, OV7251, OV9281
//  1   | IMX290, IMX327, IMX335, IMX415, IMX462
//  2   | IMX296, IMX297, IMX412
//  4   | IMX565, IMX566, IMX567, IMX568
// -----+------------------------------------------------------------------------------------------
#define VC_MIPI_METADATA_H  "4" // "0", "1", "2", "4" Lines of meta data
// ------------------------------------------------------------------------------------------------
//   Sensor Manufacturer
// -----+------------------------------------------------------------------------------------------
//   1  | Sony Sensor (IMX)
//   2  | Omni Vision Sensor (OV)
// -----+------------------------------------------------------------------------------------------
#define VC_MIPI_MANUFACTURER 1
// ------------------------------------------------------------------------------------------------
//  GStreamer Support
// ------------------------------------------------------------------------------------------------
//  If you want to use GStreamer with nvarguscamerasrc you have to adjust this settings in the 
//  device tree below. The sections which have to be modified are marked by a comment. 
//  To find the correct parameter values please follow the instruction in the main README.md of 
//  this repository https://github.com/VC-MIPI-modules/vc_mipi_nvidia#gstreamer-support
// ------------------------------------------------------------------------------------------------

#if VC_MIPI_LANES == 1
    #define BUS_WIDTH 1
    #define NUM_LANES "1" 
    #define NUM_CSI_LANES 2
    #define PIX_CLK_HZ "150000000"
#endif
#if VC_MIPI_LANES == 2
    #define BUS_WIDTH 2
    #define NUM_LANES "2" 
    #define NUM_CSI_LANES 4
    #define PIX_CLK_HZ "300000000"
#endif
#if VC_MIPI_LANES == 4
    #define BUS_WIDTH 4
    #define NUM_LANES "4" 
    #define NUM_CSI_LANES 8
    #define PIX_CLK_HZ "600000000"
#endif

#if VC_MIPI_CAM_1 == 1 && VC_MIPI_CAM_0 == 1
    #define VC_MIPI_CAMERAS 2
#else
    #define VC_MIPI_CAMERAS 1
#endif

/ {
    tegra-capture-vi  {
        num-channels = <VC_MIPI_CAMERAS>;
        ports {
            #address-cells = <1>;
            #size-cells = <0>;
#if VC_MIPI_CAM_1 == 1
            vc_vi_port0: port@0 {
                reg = <0>;
                vc_vi_in0: endpoint {
                    port-index = <1>;
                    bus-width = <2>;
                    remote-endpoint = <&vc_csi_out0>;
                };
            };
#endif
#if VC_MIPI_CAM_0 == 1
            vc_vi_port1: port@1 {
                reg = <1>;
                vc_vi_in1: endpoint {
                    port-index = <2>;
                    bus-width = <BUS_WIDTH>;
                    remote-endpoint = <&vc_csi_out1>;
                };
            };
#endif
        }; // ports
    };

    host1x@13e00000 {
        nvcsi@15a00000 {
            num-channels = <VC_MIPI_CAMERAS>;
            #address-cells = <1>;
            #size-cells = <0>;
#if VC_MIPI_CAM_1 == 1
            vc_csi_chan0: channel@0 {
                reg = <0>;
                ports {
                    #address-cells = <1>;
                    #size-cells = <0>;
                    vc_csi_chan0_port0: port@0 {
                        reg = <0>;
                        vc_csi_in0: endpoint@0 {
                            port-index = <1>;
                            bus-width = <2>;
                            remote-endpoint = <&vc_mipi_out0>;
                        };
                    };
                    vc_csi_chan0_port1: port@1 {
                        reg = <1>;
                        vc_csi_out0: endpoint@1 {
                            remote-endpoint = <&vc_vi_in0>;
                        };
                    };
                };
            };
#endif
#if VC_MIPI_CAM_0 == 1
            vc_csi_chan1: channel@1 {
                reg = <1>;
                ports {
                    #address-cells = <1>;
                    #size-cells = <0>;
                    vc_csi_chan1_port0: port@0 {
                        reg = <0>;
                        vc_csi_in1: endpoint@2 {
                            port-index = <2>;
                            bus-width = <BUS_WIDTH>;
                            remote-endpoint = <&vc_mipi_out1>;
                        };
                    };
                    vc_csi_chan1_port1: port@1 {
                        reg = <1>;
                        vc_csi_out1: endpoint@3 {
                            remote-endpoint = <&vc_vi_in1>;
                        };
                    };
                };
            };
#endif
        };
    };

    cam_i2cmux {
#if VC_MIPI_CAM_1 == 1
        i2c@0 {
#if VC_MIPI_MANUFACTURER == 1
            vc_mipi_cam0: vc_mipi@1a {
                reg                     = <0x1a>;
#else
            vc_mipi_cam0: vc_mipi@60 {
                reg                     = <0x60>;
#endif
                compatible              = "nvidia,vc_mipi";
                devnode                 = "video0";
                use_sensor_mode_id      = "false";
                sensor_model            = "vc_mipi";

                num_lanes               = "2";
                trigger_mode            = "1";
                io_mode                 = "0";

                // ----------------------------------------------------
                // If you want to use GStreamer with nvarguscamerasrc
                // you have to adjust this settings
                physical_w              = "6.752";
                physical_h              = "5.612";
                // ----------------------------------------------------

                // This node is needed by the Tegra framework.
                // You don't have to change any settings if just want 
                // to use the V4L API.
                mode0 {
                    num_lanes                = "2";
                    tegra_sinterface         = "serial_b";
                    embedded_metadata_height = VC_MIPI_METADATA_H;
                    readout_orientation      = "0";
                    lane_polarity            = "4";

                    // ----------------------------------------------------
                    // If you want to use GStreamer with nvarguscamerasrc
                    // you have to adjust this settings. 
                    active_l                 = "0";
                    active_t                 = "0";
                    active_w                 = "2464";
                    active_h                 = "2048";
                    mode_type                = "bayer";
                    pixel_phase              = "rggb";
                    csi_pixel_bit_depth      = "10";

                    min_gain_val             = "0";         // mdB
                    max_gain_val             = "48000";     // mdB
                    step_gain_val            = "100";       // mdB
                    default_gain             = "0";         // mdB

                    min_exp_time             = "1";         // us
                    max_exp_time             = "1000000";   // us
                    step_exp_time            = "1";         // us
                    default_exp_time         = "10000";     // us

                    // For applications like argus_camera, there should 
                    // be a minimal frame rate greater than zero!
                    min_framerate            = "100";       // mHz
                    max_framerate            = "41300";     // mHz
                    step_framerate           = "100";       // mHz
                    default_framerate        = "41300";     // mHz
                    // ----------------------------------------------------

                    gain_factor              = "1000";
                    exposure_factor          = "1000000";
                    framerate_factor         = "1000";
                    inherent_gain            = "1";
                    min_hdr_ratio            = "1";
                    max_hdr_ratio            = "1";

                    line_length              = "0";
                    phy_mode                 = "DPHY";
                    discontinuous_clk        = "no";
                    mclk_khz                 = "24000";
                    pix_clk_hz               = "300000000";
                    mclk_multiplier          = "0.0";       // deprecated
                    cil_settletime           = "0";
                    dpcm_enable              = "false";
                };

                ports {
                    #address-cells = <1>;
                    #size-cells = <0>;
                    port@0 {
                        reg = <0>;
                        vc_mipi_out0: endpoint {
                            port-index = <1>;
                            bus-width = <2>;
                            remote-endpoint = <&vc_csi_in0>;
                        };
                    };
                };
            };
        };
#endif // VC_MIPI_CAM_1

#if VC_MIPI_CAM_0 == 1
        i2c@1 {
#if VC_MIPI_MANUFACTURER == 1
            vc_mipi_cam1: vc_mipi@1a {
                reg                     = <0x1a>;
#else
            vc_mipi_cam1: vc_mipi@60 {
                reg                     = <0x60>;
#endif
                compatible              = "nvidia,vc_mipi";
                devnode                 = "video1";
                use_sensor_mode_id      = "false";
                sensor_model            = "vc_mipi";

                num_lanes               = NUM_LANES;
                trigger_mode            = "1";
                io_mode                 = "0";

                // ----------------------------------------------------
                // If you want to use GStreamer with nvarguscamerasrc
                // you have to adjust this settings
                physical_w              = "6.752";
                physical_h              = "5.612";
                // ----------------------------------------------------

                // This node is needed by the Tegra framework.
                // You don't have to change any settings if just want 
                // to use the V4L API.
                mode0 {
                    num_lanes                = NUM_LANES;
                    tegra_sinterface         = "serial_c";
                    embedded_metadata_height = VC_MIPI_METADATA_H;
                    readout_orientation      = "0";
                    lane_polarity            = "0";

                    // ----------------------------------------------------
                    // If you want to use GStreamer with nvarguscamerasrc
                    // you have to adjust this settings. 
                    active_l                 = "0";
                    active_t                 = "0";
                    active_w                 = "2464";
                    active_h                 = "2048";
                    mode_type                = "bayer";
                    pixel_phase              = "rggb";
                    csi_pixel_bit_depth      = "10";

                    min_gain_val             = "0";         // mdB
                    max_gain_val             = "48000";     // mdB
                    step_gain_val            = "100";       // mdB
                    default_gain             = "0";         // mdB

                    min_exp_time             = "1";         // us
                    max_exp_time             = "1000000";   // us
                    step_exp_time            = "1";         // us
                    default_exp_time         = "10000";     // us

                    // For applications like argus_camera, there should 
                    // be a minimal frame rate greater than zero!
                    min_framerate            = "100";       // mHz
                    max_framerate            = "78800";     // mHz
                    step_framerate           = "100";       // mHz
                    default_framerate        = "78800";     // mHz
                    // ----------------------------------------------------

                    gain_factor              = "1000";
                    exposure_factor          = "1000000";
                    framerate_factor         = "1000";
                    inherent_gain            = "1";
                    min_hdr_ratio            = "1";
                    max_hdr_ratio            = "1";

                    line_length              = "0";
                    phy_mode                 = "DPHY";
                    discontinuous_clk        = "no";
                    mclk_khz                 = "24000";
                    pix_clk_hz               = PIX_CLK_HZ;
                    mclk_multiplier          = "0.0";       // deprecated
                    cil_settletime           = "0";
                    dpcm_enable              = "false";
                };

                ports {
                    #address-cells = <1>;
                    #size-cells = <0>;
                    port@0 {
                        reg = <0>;
                        vc_mipi_out1: endpoint {
                            port-index = <2>;
                            bus-width = <BUS_WIDTH>;
                            remote-endpoint = <&vc_csi_in1>;
                        };
                    };
                };
            };
        };
#endif // VC_MIPI_CAM_0
    };

    lens@vc_mipi {
        min_focus_distance  = "0.0";
        hyper_focal         = "0.0";
        focal_length        = "6.0";
        f_number            = "2.0";
        aperture            = "0.0";
    };
};

/ {
    tcp: tegra-camera-platform {
        compatible = "nvidia, tegra-camera-platform";

        num_csi_lanes = <NUM_CSI_LANES>;
        max_lane_speed = <1500000>;
        min_bits_per_pixel = <10>;
        vi_peak_byte_per_pixel = <2>;
        vi_bw_margin_pct = <25>;
        max_pixel_rate = <240000>;
        isp_peak_byte_per_pixel = <5>;
        isp_bw_margin_pct = <25>;

        modules {
#if VC_MIPI_CAM_1 == 1
            cam_module0: module0 {
                badge = "jakku_front_vc_mipi";
                position = "front";
                orientation = "1";
                cam_module0_drivernode0: drivernode0 {
                    pcl_id = "v4l2_sensor";
#if VC_MIPI_MANUFACTURER == 1
                    devname = "vc_mipi 9-001a";
                    proc-device-tree = "/proc/device-tree/cam_i2cmux/i2c@0/vc_mipi@1a";
#else
                    devname = "vc_mipi 9-0060";
                    proc-device-tree = "/proc/device-tree/cam_i2cmux/i2c@0/vc_mipi@60";
#endif
                };
                cam_module0_drivernode1: drivernode1 {
                    pcl_id = "v4l2_lens";
                    proc-device-tree = "/proc/device-tree/lens@vc_mipi/";
                };
            };
#endif // VC_MIPI_CAM_1

#if VC_MIPI_CAM_0 == 1
            cam_module1: module1 {
                badge = "jakku_rear_vc_mipi";
                position = "rear";
                orientation = "1";
                cam_module1_drivernode0: drivernode0 {
                    pcl_id = "v4l2_sensor";
#if VC_MIPI_MANUFACTURER == 1
                    devname = "vc_mipi 10-001a";
                    proc-device-tree = "/proc/device-tree/cam_i2cmux/i2c@1/vc_mipi@1a";
#else
                    devname = "vc_mipi 10-0060";
                    proc-device-tree = "/proc/device-tree/cam_i2cmux/i2c@1/vc_mipi@60";
#endif  
                };
                cam_module1_drivernode1: drivernode1 {
                    pcl_id = "v4l2_lens";
                    proc-device-tree = "/proc/device-tree/lens@vc_mipi/";
                };
            };
#endif // VC_MIPI_CAM_0
        };
    };
};

#define CAM0_PWDN   TEGRA234_MAIN_GPIO(H, 6)
#define CAM1_PWDN   TEGRA234_MAIN_GPIO(AC, 0)
#define CAM_I2C_MUX     TEGRA234_AON_GPIO(CC, 3)

/ {
    cam_i2cmux {
        status = "okay";
        compatible = "i2c-mux-gpio";
        #address-cells = <1>;
        #size-cells = <0>;
        mux-gpios = <&tegra_aon_gpio CAM_I2C_MUX GPIO_ACTIVE_HIGH>;
        i2c-parent = <&cam_i2c>;
#if VC_MIPI_CAM_1 == 1
        i2c@0 {
            status = "okay";
            reg = <0>;
            #address-cells = <1>;
            #size-cells = <0>;
#if VC_MIPI_MANUFACTURER == 1
            vc_mipi@1a {
#else
            vc_mipi@60 {
#endif
                reset-gpios = <&tegra_main_gpio CAM0_PWDN GPIO_ACTIVE_HIGH>;
            };
        };
#endif
#if VC_MIPI_CAM_0 == 1
        i2c@1 {
            status = "okay";
            reg = <1>;
            #address-cells = <1>;
            #size-cells = <0>;
#if VC_MIPI_MANUFACTURER == 1
            vc_mipi@1a {
#else
                    vc_mipi@60 {
#endif
                reset-gpios = <&tegra_main_gpio CAM1_PWDN GPIO_ACTIVE_HIGH>;
            };
        };
#endif
    };

    gpio@2200000 {
        camera-control-output-low {
            gpio-hog;
            output-low;
            gpios = <CAM0_PWDN 0 CAM1_PWDN 0>;
            label = "cam0-pwdn","cam1-pwdn";
        };
    };
};

Video

https://github.com/VC-MIPI-modules/vc_mipi_nvidia/assets/26469177/ced9f1cc-45e2-46a9-94e9-348a5ecd7047

bazo80 commented 4 months ago

Hello @burak-ayd

ok, you have adjusted cam0 to 2 lanes (pixel clock, num lanes, frame rate), the cam1 is running on 4 lanes. I didn't test this combination. But it is on my agenda. The next thoughts are wild guesses: The "tegra-camera-platform {" node has the num_csi_lanes = ; entry. In that case it has the value 8. I don't know whether the value should be set to 6, when the first lane pair is not used. The lane_polarity could be 4, theoretically. But I would set it back to 6, not sure if this thing has an effect, when the first pair is not used.

Is the effect also present, when both cameras are running with 2 lanes?

noob502 commented 1 month ago

@burak-ayd How did you build the image for Orin Nano with VC_MIPI ?