Closed flixr closed 8 months ago
We managed to get frames from OrinNano with 2 * IMX568 cameras. After a bunch of tries we could get frames from 2 csi ports at the same time(csi port 0 and 1) in Orin Nano with that 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 2 // 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 = "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 = 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";
};
};
};
There are similar changes compare to updated branch. Setting VC_MIPI_LANES
to 2 for all ports, port-index
to <1>
and tegra_sinterface
to serial_b
for CAM0. CAM1 can be 4 lanes but the cameras cannot be same fps in that situation. So setting the lanes same for 2 ports will set cameras as equal. I don't know if there is any settings to set 2 csi ports as 4 lanes but I don't think so. Because Orin Nano supports CAM0 port as 2 lane and CAM1 as 2-4 lane as datasheet's says in 3.2 Camera Connector.
Also there is another issue with driver and device tree. When we checked the table for GStreamer Properties active_w and active_h is 2464x2048 for device tree. But it has adjusted to 2464x2064 in the driver.
Fix device tree for cam0 on Orin NX/Nano on Auvidea JNX42.
Tested on Orin NX with two IMX296.