Device Tree for CSI MIPI

Hi,

I am doing an LT6911UXC (HDMI to MIPI/CSI) chip based board with the Xavier NX Dev Kit.

I am trying to connect the LT6911UXC board and the Xavier NX Dev Kit via J1 connector which using CSI0 2 lanes.

However, before connecting, there is a problem.

Even though the Xavier NX Dev Kit and the LT6911uxc are not physically connected, it is detected on the Xavier NX Dev Kit. When I executed the command ‘/dev/video/’, it detected the device as below.

Is it normal for this situation?

I think there are problems in the device tree file. Can you check my device tree?

These are the processes that I have done so far. I didn’t modify any other things but this.
(And I used the LT6911uxc device driver from the L4T BSP sources, 32.6.1)

  1. 'tegra194-p3668-all-p3509-0000.dts’
    It is placed in this directory, ‘…/public/hardware/nvidia/platform/t19x/jakku/kernel-dts/’

image

  1. As you can see it includes two dtsi files.
    A) ‘tegra194-p3688-common.dtsi’
    It is placed in this directory, ‘…/public/hardware/nvidia/platform/t19x/jakku/kernel-dts/common’

image

B) ‘tegra194-p3688-0000-a00.dtsi’
It is placed in this directory, ‘…/public/hardware/nvidia/platform/t19x/jakku/kernel-dts/common’
In this file I created “tegra194-camera-jakku-rbpcv2-lt6911uxc.dtsi” file and included in it.
This file, “tegra194-camera-jakku-rbpcv2-lt6911uxc.dtsi”, is located in here, ‘…/public/hardware/nvidia/platform/t19x/jakku/kernel-dts/common’.

image

  1. I made this device tree,“tegra194-camera-jakku-rbpcv2-lt6911uxc.dtsi”, like below.

Here is the Device tree code.

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

#define CAM0_PWDN TEGRA194_MAIN_GPIO(P, 4)
#define CAM1_PWDN TEGRA194_MAIN_GPIO(P, 5)
#define CAM_I2C_MUX TEGRA194_AON_GPIO(CC, 3)

/ {
host1x {
vi@15c10000 {
num-channels = <1>;
ports {
#address-cells = <1>;
#size-cells = <0>;
vi_port0: port@0 {
reg = <0>;
rbpcv2_lt6911uxc_vi_in0: endpoint {
status = “okay”;
port-index = <0>;
bus-width = <2>;
remote-endpoint = <&rbpcv2_lt6911uxc_csi_out0>;
};
};
};
};

	nvcsi@15a00000 {
		num-channels = <1>;								
		#address-cells = <1>;
		#size-cells = <0>;
		csi_chan0: channel@0 {
			reg = <0>;
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				csi_chan0_port0: port@0 {
					reg = <0>;
					rbpcv2_lt6911uxc_csi_in0: endpoint@0 {
						status = "okay";
						port-index = <0>;
						bus-width = <2>;
						remote-endpoint = <&rbpcv2_lt6911uxc_out0>;
					};
				};
				csi_chan0_port1: port@1 {
					reg = <1>;
					rbpcv2_lt6911uxc_csi_out0: endpoint@1 {
						status = "okay";
						remote-endpoint = <&rbpcv2_lt6911uxc_vi_in0>;
					};
				};
			};
		};
	};
};

cam_i2cmux{
	compatible = "i2c-mux-gpio";
	#address-cells = <1>;
	#size-cells = <0>;
	i2c-parent = <&cam_i2c>;			
	mux-gpios = <&tegra_aon_gpio CAM_I2C_MUX GPIO_ACTIVE_HIGH>;
	i2c@0 {
		reg = <0>;
		#address-cells = <1>;
		#size-cells = <0>;
		rbpcv2_lt6911uxc_a@2b {
			compatible = "nvidia,lt6911uxc";
			reg = <0x2b>;
			devnode = "video0";
			physical_w = "3.674";
			physical_h = "2.738";
			sensor_model = "lt6911uxc";
			use_sensor_mode_id = "true";
			status = "okay";
			reset-gpios = <&tegra_main_gpio CAM0_PWDN GPIO_ACTIVE_HIGH>;
			mode0 { // E2832_1920x1080_60Fps
				mclk_khz = "24000";
				num_lanes = "4";
				tegra_sinterface = "serial_a";
				phy_mode = "DPHY";
				discontinuous_clk = "yes";
				dpcm_enable = "false";
				cil_settletime = "0";

				active_w = "1920";
				active_h = "1080";
				mode_type = "rgb";
				pixel_phase = "rgb888";
				csi_pixel_bit_depth = "24";
				readout_orientation = "0";
				line_length = "1920";
				inherent_gain = "1";
				mclk_multiplier = "24";
				pix_clk_hz = "576000000";

				gain_factor = "16";
				framerate_factor = "1000000";
				exposure_factor = "1000000";
				min_gain_val = "16"; /* 1.00x */
				max_gain_val = "170"; /* 10.66x */
				step_gain_val = "1";
				default_gain = "16"; /* 1.00x */
				min_hdr_ratio = "1";
				max_hdr_ratio = "1";
				min_framerate = "2000000"; /* 2.0 fps */
				max_framerate = "60000000"; /* 60.0 fps */
				step_framerate = "1";
				default_framerate = "60000000"; /* 60.0 fps */
				min_exp_time = "13"; /* us */
				max_exp_time = "683709"; /* us */
				step_exp_time = "1";
				default_exp_time = "16667"; /* us  */
			};
			
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				port@0 {
					reg = <0>;
					rbpcv2_lt6911uxc_out0: endpoint {
						status = "okay";
						port-index = <0>;
						bus-width = <2>;
						remote-endpoint = <&rbpcv2_lt6911uxc_csi_in0>;
					};
				};
			};				
		};
	};
	
};

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

};

/{
tegra-camera-platform {
compatible = “nvidia, tegra-camera-platform”;

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

	
	modules {
		cam_module0: module0 {
			status = "okay";
			badge = "jakku_front_LT6911UXC";
			position = "front"; 	//position = "bottom";
			orientation = "1";
			cam_module0_drivernode0: drivernode0 {
				pcl_id = "v4l2_sensor";
				devname = "lt6911uxc 9-002b";	// I2C Bus num and Addr num
				proc-device-tree = "/proc/device-tree/cam_i2cmux/i2c@0/rbpcv2_lt6911uxc_a@2b";
			};
		};
	};
};

};

Can you check that my device tree wrote correctly?

Thanks

The num_lanes should be 2 due to it’s two lanes connection.

Hi,

I modified mode0 function as below but still get the same situation.

/ {
host1x {
vi@15c10000 {
num-channels = <1>; // ?
ports {
#address-cells = <1>;
#size-cells = <0>;
vi_port0: port@0 { // Specifies the media pad port connection.
reg = <0>;
rbpcv2_lt6911uxc_vi_in0: endpoint {
status = “okay”;
port-index = <0>; // Defines the sensor port connection.
bus-width = <2>; // Number of CSI lanes connected to sensor
remote-endpoint = <&rbpcv2_lt6911uxc_csi_out0>;
};
};
};
};

	nvcsi@15a00000 {
		num-channels = <1>;								// ?
		#address-cells = <1>;
		#size-cells = <0>;
		csi_chan0: channel@0 {
			reg = <0>;
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				csi_chan0_port0: port@0 {
					reg = <0>;
					rbpcv2_lt6911uxc_csi_in0: endpoint@0 {
						status = "okay";
						port-index = <0>;
						bus-width = <2>;
						remote-endpoint = <&rbpcv2_lt6911uxc_out0>;
					};
				};
				csi_chan0_port1: port@1 {
					reg = <1>;
					rbpcv2_lt6911uxc_csi_out0: endpoint@1 {
						status = "okay";
						remote-endpoint = <&rbpcv2_lt6911uxc_vi_in0>;
					};
				};
			};
		};
	};
};

cam_i2cmux{
	compatible = "i2c-mux-gpio";
	#address-cells = <1>;
	#size-cells = <0>;
	i2c-parent = <&cam_i2c>;			// ?
	mux-gpios = <&tegra_aon_gpio CAM_I2C_MUX GPIO_ACTIVE_HIGH>;
	i2c@0 {
		reg = <0>;
		#address-cells = <1>;
		#size-cells = <0>;
		rbpcv2_lt6911uxc_a@2b {
			compatible = "nvidia,lt6911uxc";
			reg = <0x2b>;
			devnode = "video0";
			physical_w = "3.674";
			physical_h = "2.738";
			sensor_model = "lt6911uxc";
			use_sensor_mode_id = "true";
			status = "okay";
			reset-gpios = <&tegra_main_gpio CAM0_PWDN GPIO_ACTIVE_HIGH>;
			mode0 { // E2832_1920x1080_60Fps
				mclk_khz = "335996";
				num_lanes = "2";
				tegra_sinterface = "serial_a";
				phy_mode = "DPHY";
				discontinuous_clk = "yes";
				dpcm_enable = "false";
				cil_settletime = "0";

				active_w = "1920";
				active_h = "1080";
				mode_type = "rgb";
				pixel_phase = "rgb888";
				csi_pixel_bit_depth = "24";
				readout_orientation = "0";
				line_length = "1920";
				inherent_gain = "1";
				mclk_multiplier = "24";
				pix_clk_hz = "148500000";

				gain_factor = "16";
				framerate_factor = "1000000";
				exposure_factor = "1000000";
				min_gain_val = "16"; /* 1.00x */
				max_gain_val = "170"; /* 10.66x */
				step_gain_val = "1";
				default_gain = "16"; /* 1.00x */
				min_hdr_ratio = "1";
				max_hdr_ratio = "1";
				min_framerate = "2000000"; /* 2.0 fps */
				max_framerate = "60000000"; /* 60.0 fps */
				step_framerate = "1";
				default_framerate = "60000000"; /* 60.0 fps */
				min_exp_time = "13"; /* us */
				max_exp_time = "683709"; /* us */
				step_exp_time = "1";
				default_exp_time = "16667"; /* us  */
			};
			
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				port@0 {
					reg = <0>;
					rbpcv2_lt6911uxc_out0: endpoint {
						status = "okay";
						port-index = <0>;
						bus-width = <2>;
						remote-endpoint = <&rbpcv2_lt6911uxc_csi_in0>;
					};
				};
			};				
		};
	};
	
};

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

};

/ {
tegra-camera-platform {
compatible = “nvidia, tegra-camera-platform”;
num_csi_lanes = <2>;
max_lane_speed = <1500000>;
min_bits_per_pixel = <10>;
vi_peak_byte_per_pixel = <2>;
vi_bw_margin_pct = <25>;
max_pixel_rate = <750000>;
isp_peak_byte_per_pixel = <5>;
isp_bw_margin_pct = <25>;

	modules {
		cam_module0: module0 {
			status = "okay";
			badge = "jakku_front_LT6911UXC";
			position = "front"; 	//position = "bottom";
			orientation = "1";
			cam_module0_drivernode0: drivernode0 {
				pcl_id = "v4l2_sensor";
				devname = "lt6911uxc 9-002b";	// I2C Bus num and Addr num
				proc-device-tree = "/proc/device-tree/cam_i2cmux/i2c@0/rbpcv2_lt6911uxc_a@2b";
			};
		};
	};
};

};

Is it normal that even though the Xavier NX Dev Kit and the LT6911uxc are not physically connected, it is detected on the Xavier NX Dev Kit?

It’s normal. The driver will be loaded when device tree is define.
Normally the sensor driver have access itself REG to check if device is present or not and break to generate the video node. Suppose the LT6911uxc driver didn’t handle this in the probe() function. So no matter what the video node was generated depend on device tree configure.

so. then do you mean there would be problem on LT6911 device driver file?
Especially, in the probe() function?

Yes, the probe() function need to detect is device present or not.

Thanks.

Could you check the device tree that I developed?

Do all port numbers and channel numbers look fine?

I used the J1 connector on the Xavier NX Dev KIT which uses CSI0 line.

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

#define CAM0_PWDN TEGRA194_MAIN_GPIO(P, 4)
#define CAM1_PWDN TEGRA194_MAIN_GPIO(P, 5)
#define CAM_I2C_MUX TEGRA194_AON_GPIO(CC, 3)

/ {

     host1x {

	vi@15c10000  {

		ports {

			vi_port0: port@0 {							

			};
		};
	};

	nvcsi@15a00000 {

		csi_chan0: channel@0 {

			ports {

				csi_chan0_port0: port@0 {

				};
				csi_chan0_port1: port@1 {

				};
			};
		};
	};
};

cam_i2cmux{
	i2c@0 {
		rbpcv2_lt6911uxc_a@2b {
			ports {
				port@0 {
					rbpcv2_lt6911uxc_out0: endpoint {
						remote-endpoint = <&rbpcv2_lt6911uxc_csi_in0>;
					};
				};
			};				
		};
	};
	
};

};

/ {

tegra-camera-platform {
	compatible = "nvidia, tegra-camera-platform";
	modules {
		cam_module0: module0 {
			status = "okay";
			badge = "jakku_front_LT6911UXC";
			position = "front"; 	//position = "bottom";
			orientation = "1";
			cam_module0_drivernode0: drivernode0 {
				pcl_id = "v4l2_sensor";
				devname = "lt6911uxc 9-002b";	// I2C Bus num and Addr num
				proc-device-tree = "/proc/device-tree/cam_i2cmux/i2c@0/rbpcv2_lt6911uxc_a@2b";
			};
		};
	};
};

};

Looks good. However, the key point is the “port-index” and “bus-width”

Yes I have set those arguments like this below.
Does this look fine?
I am using 2 lane on CSI 0.

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

#define CAM0_PWDN TEGRA194_MAIN_GPIO(P, 4)
#define CAM1_PWDN TEGRA194_MAIN_GPIO(P, 5)
#define CAM_I2C_MUX TEGRA194_AON_GPIO(CC, 3)

/ {
host1x {
vi@15c10000 {
num-channels = <1>; // ?
ports {
#address-cells = <1>;
#size-cells = <0>;
vi_port0: port@0 {
reg = <0>;
rbpcv2_lt6911uxc_vi_in0: endpoint {
status = “okay”;
port-index = <0>;
bus-width = <2>;
remote-endpoint = <&rbpcv2_lt6911uxc_csi_out0>;
};
};
};
};

	nvcsi@15a00000 {
		num-channels = <1>;								
		#address-cells = <1>;
		#size-cells = <0>;
		csi_chan0: channel@0 {
			reg = <0>;
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				csi_chan0_port0: port@0 {
					reg = <0>;
					rbpcv2_lt6911uxc_csi_in0: endpoint@0 {
						status = "okay";
						port-index = <0>;
						bus-width = <2>;
						remote-endpoint = <&rbpcv2_lt6911uxc_out0>;
					};
				};
				csi_chan0_port1: port@1 {
					reg = <1>;
					rbpcv2_lt6911uxc_csi_out0: endpoint@1 {
						status = "okay";
						remote-endpoint = <&rbpcv2_lt6911uxc_vi_in0>;
					};
				};
			};
		};
	};
};

cam_i2cmux{
	compatible = "i2c-mux-gpio";
	#address-cells = <1>;
	#size-cells = <0>;
	i2c-parent = <&cam_i2c>;			// ?
	mux-gpios = <&tegra_aon_gpio CAM_I2C_MUX GPIO_ACTIVE_HIGH>;
	i2c@0 {
		reg = <0>;
		#address-cells = <1>;
		#size-cells = <0>;
		rbpcv2_lt6911uxc_a@2b {
			compatible = "nvidia,lt6911uxc";
			reg = <0x2b>;
			devnode = "video0";
			physical_w = "3.674";
			physical_h = "2.738";
			sensor_model = "lt6911uxc";
			use_sensor_mode_id = "true";
			status = "okay";
			reset-gpios = <&tegra_main_gpio CAM0_PWDN GPIO_ACTIVE_HIGH>;
			mode0 { // E2832_1920x1080_60Fps
				mclk_khz = "335996";
				num_lanes = "4";
				tegra_sinterface = "serial_a";
				phy_mode = "DPHY";
				discontinuous_clk = "yes";
				dpcm_enable = "false";
				cil_settletime = "0";

				active_w = "1920";
				active_h = "1080";
				mode_type = "rgb";
				pixel_phase = "rgb888";
				csi_pixel_bit_depth = "24";
				readout_orientation = "0";
				line_length = "1920";
				inherent_gain = "1";
				mclk_multiplier = "24";
				pix_clk_hz = "148500000";

				gain_factor = "16";
				framerate_factor = "1000000";
				exposure_factor = "1000000";
				min_gain_val = "16"; /* 1.00x */
				max_gain_val = "170"; /* 10.66x */
				step_gain_val = "1";
				default_gain = "16"; /* 1.00x */
				min_hdr_ratio = "1";
				max_hdr_ratio = "1";
				min_framerate = "2000000"; /* 2.0 fps */
				max_framerate = "60000000"; /* 60.0 fps */
				step_framerate = "1";
				default_framerate = "60000000"; /* 60.0 fps */
				min_exp_time = "13"; /* us */
				max_exp_time = "683709"; /* us */
				step_exp_time = "1";
				default_exp_time = "16667"; /* us  */
			};
			
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				port@0 {
					reg = <0>;
					rbpcv2_lt6911uxc_out0: endpoint {
						status = "okay";
						port-index = <0>;
						bus-width = <2>;
						remote-endpoint = <&rbpcv2_lt6911uxc_csi_in0>;
					};
				};
			};				
		};
	};
	
};

};

/ {
tegra-camera-platform {
compatible = “nvidia, tegra-camera-platform”;

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

	modules {
		cam_module0: module0 {
			status = "okay";
			badge = "jakku_front_LT6911UXC";
			position = "front"; 	//position = "bottom";
			orientation = "1";
			cam_module0_drivernode0: drivernode0 {
				pcl_id = "v4l2_sensor";
				devname = "lt6911uxc 9-002b";	// I2C Bus num and Addr num
				proc-device-tree = "/proc/device-tree/cam_i2cmux/i2c@0/rbpcv2_lt6911uxc_a@2b";
			};
		};
	};
};

};

Looks fine to me.

One more question.

In the device tree, may I know what this function works for?

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

It’s define the GPIO for the camera power down pin control

Thank you for your guidance.

About the code below,

{

port-index = <0>;
bus-width = <2>;

port-index = <2>;
bus-width = <2>;

}
Can you tell me what the numbers mean?

I thought that ‘bus-width = <2>’ stands for CSI 2 lanes, am I right?

Also, what is the difference between’port-index = <0>’ and ‘port-index = <2>’?

port-index is used to specify which stream the camera uses. Please see detail here.

so if I write ’port-index = <0>’ , does it mean the stream 0 is used?

Xavier NX Dev Kit carrier board J1? Yes port-index = <0>.

Then if I use Xavier NX Dev Kit carrier board J9. is it port-index = <2>?

That is correct. I also like this guide.

Thank you.