Failed tegra camera driver registration on JetPack4.2

We are porting IMX378 sensor from JetPack3.3 to JetPack4.2.

However, the following error occurs:

nvidia@nvidia-desktop:~$ dmesg | grep imx378
[    0.184620] DTS File Name: arch/arm64/boot/dts/../../../../../../hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-imx378.dts
[    0.441643] DTS File Name: arch/arm64/boot/dts/../../../../../../hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-imx378.dts
[    3.694327] imx378 30-001a: Failed to find port index
[    3.694331] imx378 30-001a: Failed to find port info.
[    3.694334] imx378 30-001a: Failed to initialize imx378
[    3.694337] imx378 30-001a: tegra camera driver registration failed
[    3.694518] imx378: probe of 30-001a failed with error -22

The same phenomenon occurs even if imx378.c source code is ported to imx219.c or imx185.c.

Is there a problem with the following device tree?

File1: /usr/src/hardware/nvidia/platform/t18x/quill/kernel-dts/tegra186-quill-p3310-1000-c03-00-imx378.dts

#include "tegra186-quill-p3310-1000-c03-00-base.dts"
#include "quill-platforms/tegra186-quill-camera-imx378-c03.dtsi"

/ {
	nvidia,dtsfilename = __FILE__;

	/* GPIO */
	gpio@2200000 {
		camera-control-input {
			status = "disabled";
		};
		camera-control-output-low {
			status = "disabled";
		};
		camera-control-output-high {
			gpio-hog;
			gpios = <CAM0_RST_L 0 CAM0_PWDN 0>;
			label = "cam0-rst cam0-pwdn";
			output-high;
			status = "okay";
		};
	};

	host1x {
		vi_base: vi@15700000 {
			ports {
				imx378_vi_port0: port@0 {
					status = "okay";
					imx378_vi_in0: endpoint {
						status = "okay";
					};
				};
			};
		};
		csi_base: nvcsi@150c0000 {
			csi_chan0: channel@0 {
				status = "okay";
				ports {
					csi_chan0_port0: port@0 {
						status = "okay";
						imx378_csi_in0: endpoint@0 {
							status = "okay";
						};
					};
					csi_chan0_port1: port@1 {
						status = "okay";
						imx378_csi_out0: endpoint@1 {
							status = "okay";
						};
					};
				};
			};
		};
	};
};

File2: /usr/src/hardware/nvidia/platform/t18x/quill/kernel-dts/quill-platforms/tegra186-quill-camera-imx378-c03.dtsi

#include <quill-modules/tegra186-camera-imx378-c03.dtsi>
#include "dt-bindings/clock/tegra186-clock.h"

#define CAM0_RST_L	TEGRA_MAIN_GPIO(R, 5)
#define CAM0_PWDN	TEGRA_MAIN_GPIO(R, 0)
#define CAM1_RST_L	TEGRA_MAIN_GPIO(R, 1)
#define CAM1_PWDN	TEGRA_MAIN_GPIO(L, 6)

/* camera control gpio definitions */

/ {
	i2c@3180000 {
		tca9548@70 {
			compatible = "nxp,pca9548";
			reg = <0x70>;
			#address-cells = <1>;
			#size-cells = <0>;
			skip_mux_detect = "yes";
			#vif-supply = <&en_vdd_cam>;
			vcc-supply = <&en_vdd_cam>;
			#vcc_lp = "vif";
			status = "okay";
			force_bus_start = <CAMERA_I2C_MUX_BUS(0)>;
			i2c@0 {
				reg = <0>;
				i2c-mux,deselect-on-exit;
				#address-cells = <1>;
				#size-cells = <0>;
				imx378_a@1a {
					/* Define any required hw resources needed by driver */
					/* ie. clocks, io pins, power sources */
					clocks = <&tegra_car TEGRA186_CLK_EXTPERIPH1>,
							 <&tegra_car TEGRA186_CLK_PLLP_OUT0>;
					clock-names = "extperiph1", "pllp_grtba";
					mclk = "extperiph1";
					reset-gpios = <&tegra_main_gpio CAM0_RST_L GPIO_ACTIVE_HIGH>;
					vana-supply = <&en_vdd_cam_hv_2v8>;
					vif-supply = <&en_vdd_cam>;
					vdig-supply = <&en_vdd_cam_1v2>;
					status = "okay";
				};
			};
		};
	};
};

File3: /usr/src/hardware/nvidia/platform/t18x/quill/kernel-dts/quill-modules/tegra186-camera-imx378-c03.dtsi

/ {
	host1x {
		vi@15700000 {
			num-channels = <1>;
			ports {
				#address-cells = <1>;
				#size-cells = <0>;
				port@0 {
					reg = <0>;
					vi_in0: endpoint {
						csi-port = <0>;
						bus-width = <2>;
						remote-endpoint = <&csi_out0>;
					};
				};
			};
		};

		nvcsi@150c0000 {
			num-channels = <1>;
			channel@0 {
				reg = <0>;
				ports {
					#address-cells = <1>;
					#size-cells = <0>;
					port@0 {
						reg = <0>;
						csi_in0: endpoint@0 {
							csi-port = <0>;
							bus-width = <2>;
							remote-endpoint = <&imx378_out0>;
						};
					};
					port@1 {
						reg = <1>;
						csi_out0: endpoint@1 {
							remote-endpoint = <&vi_in0>;
						};
					};
				};
			};
		};
	};

	i2c@3180000 {
		tca9548@70 {
			i2c@0 {
				imx378_a@1a {
					devnode = "video0";
					compatible = "nvidia,imx378";
					reg = <0x1a>;

					physical_w = "7.564";
					physical_h = "5.476";

					sensor_model ="imx378";
					dovdd-supply = <&en_vdd_cam>;
					avdd-reg = "vana";
					dvdd-reg = "vdig";
					iovdd-reg = "dovdd";

					mode0 { // IMX378_MODE_4056X3040
						mclk_khz = "6000";
						num_lanes = "2";
						tegra_sinterface = "serial_a";
						phy_mode = "DPHY";
						discontinuous_clk = "yes";
						cil_settletime = "0";

						active_w = "4056";
						active_h = "3040";
						mode_type = "bayer";
						pixel_phase = "rggb";
						readout_orientation = "90";
						line_length = "4350";
						inherent_gain = "1";
						mclk_multiplier = "348";
						pix_clk_hz = "417600000";

						gain_factor = "1000000";
						min_gain_val = "1000000";
						max_gain_val = "22000000";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						framerate_factor = "1000000";
						min_framerate = "1000000";
						max_framerate = "30000000";
						min_exp_time = "1";
						max_exp_time = "65515";
						default_exp_time = "3180";/* us */
						embedded_metadata_height = "0";
					};
					mode1 { // IMX378_MODE_3840X2160
						mclk_khz = "6000";
						num_lanes = "2";
						tegra_sinterface = "serial_a";
						phy_mode = "DPHY";
						discontinuous_clk = "yes";
						cil_settletime = "0";

						active_w = "3840";
						active_h = "2160";
						mode_type = "bayer";
						pixel_phase = "rggb";
						readout_orientation = "90";
						line_length = "4250";
						inherent_gain = "1";
						mclk_multiplier = "238";
						pix_clk_hz = "285600000";

						gain_factor = "1000000";
						min_gain_val = "1000000";
						max_gain_val = "22000000";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						framerate_factor = "1000000";
						min_framerate = "1000000";
						max_framerate = "30000000";
						min_exp_time = "1";
						max_exp_time = "65515";
						default_exp_time = "2220";/* us */
						embedded_metadata_height = "0";
					};
					mode2 { // IMX378_MODE_1920X1080
						mclk_khz = "6000";
						num_lanes = "2";
						tegra_sinterface = "serial_a";
						phy_mode = "DPHY";
						discontinuous_clk = "yes";
						cil_settletime = "0";

						active_w = "1920";
						active_h = "1080";
						mode_type = "bayer";
						pixel_phase = "rggb";
						readout_orientation = "90";
						line_length = "2240";
						inherent_gain = "1";
						mclk_multiplier = "126";
						pix_clk_hz = "151200000";

						gain_factor = "1000000";
						min_gain_val = "1000000";
						max_gain_val = "22000000";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						framerate_factor = "1000000";
						min_framerate = "1000000";
						max_framerate = "60000000";
						min_exp_time = "1";
						max_exp_time = "65515";
						default_exp_time = "1105";/* us */
						embedded_metadata_height = "0";
					};
					mode3 { // IMX378_MODE_640X480
						mclk_khz = "6000";
						num_lanes = "2";
						tegra_sinterface = "serial_a";
						phy_mode = "DPHY";
						discontinuous_clk = "yes";
						cil_settletime = "0";

						active_w = "640";
						active_h = "480";
						mode_type = "bayer";
						pixel_phase = "rggb";
						readout_orientation = "90";
						line_length = "1600";
						inherent_gain = "1";
						mclk_multiplier = "84";
						pix_clk_hz = "100800000";

						gain_factor = "1000000";
						min_gain_val = "1000000";
						max_gain_val = "22000000";
						min_hdr_ratio = "1";
						max_hdr_ratio = "64";
						framerate_factor = "1000000";
						min_framerate = "1000000";
						max_framerate = "120000000";
						min_exp_time = "1";
						max_exp_time = "65515";
						default_exp_time = "505";/* us */
						embedded_metadata_height = "0";
					};
					ports {
						#address-cells = <1>;
						#size-cells = <0>;
						port@0 {
							reg = <0>;
							imx378_out0: endpoint {
								csi-port = <0>;
								bus-width = <2>;
								remote-endpoint = <&csi_in0>;
							};
						};
					};
				};
			};
		};
	};

	lens_imx378_a@3e {
		min_focus_distance = "0.0";
		hyper_focal = "0.0";
		focal_length = "4.52";
		f_number = "2.0";
		aperture = "2.0";
	};

	tegra-camera-platform {
		compatible = "nvidia, tegra-camera-platform";
		/**
		* Physical settings to calculate max ISO BW
		*
		* num_csi_lanes = <>;
		* Total number of CSI lanes when all cameras are active
		*
		* max_lane_speed = <>;
		* Max lane speed in Kbit/s
		*
		* min_bits_per_pixel = <>;
		* Min bits per pixel
		*
		* vi_peak_byte_per_pixel = <>;
		* Max byte per pixel for the VI ISO case
		*
		* vi_bw_margin_pct = <>;
		* Vi bandwidth margin in percentage
		*
		* max_pixel_rate = <>;
		* Max pixel rate in Kpixel/s for the ISP ISO case
		*
		* isp_peak_byte_per_pixel = <>;
		* Max byte per pixel for the ISP ISO case
		*
		* isp_bw_margin_pct = <>;
		* Isp bandwidth margin in percentage
		*/
		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>;

		/**
		 * The general guideline for naming badge_info contains 3 parts, and is as follows,
		 * The first part is the camera_board_id for the module; if the module is in a FFD
		 * platform, then use the platform name for this part.
		 * The second part contains the position of the module, ex. "rear" or "front".
		 * The third part contains the last 6 characters of a part number which is found
		 * in the module's specsheet from the vender.
		 */
		modules {
			module0 {
				status = "okay";
				badge = "imx378_CH1_396CP";
				position = "0";
				orientation = "1";
				drivernode0 {
					status = "okay";
					/* Declare PCL support driver (classically known as guid)  */
					pcl_id = "v4l2_sensor";
					/* Driver v4l2 device name */
					devname = "imx378 30-001a";
					/* Declare the device-tree hierarchy to driver instance */
					proc-device-tree = "/proc/device-tree/i2c@3180000/tca9548@70/i2c@0/imx378_a@1a";
				};
				drivernode1 {
					/* Declare PCL support driver (classically known as guid)  */
					pcl_id = "v4l2_lens";
					proc-device-tree = "/proc/device-tree/lens_imx378_a@3e/";
				};
			};
		};
	};
};

hello yasuo-tanaka,

suggest you check the documentation, [Sensor Software Driver Programming Guide],
and you should refer to Port Index session for the port index mapping diagram.

you may also disassembler the dtb file into txt file for quick checking,
for example,

$ dtc -I dtb -O dts -o results.txt $OUT/kernel/dtb/tegra186-quill-p3310-1000-c03-00-base.dtb

hello JerryChang,

Thank you for your reply.
I understand that I need to change some parameters like “port-index” in the device tree.
I will check the guidance and try it.

hello JerryChang,

Thank you very much.
This problem was solved with the parameter names in the device tree.

Hello CenturyArks-Support

Which’s params of device tree you changed?

Hello hoanganhv1svm,

It is published on our GitHub.

Hello bro,

Thanks for your sharing. Did you porting adv72xx to nano.
i’m stuck with adv7280 from few a week before :(

I having similar Issues porting a Leopard RAA462113 camera from 3.3 to 4.3. leopard wont help to keep its product up to date.