Orin NX - Enable 2x USB3.2 for custom carrier board USB

Hello,

I’m currently working on a custom carrier board for a Jetson Orin NX 16GB module and I feel like I’m missing something regarding the USB 3.1 capability.

My target, for the moment, is to enable two USB3.2 Type-C ports attached to USB1-USBSS1 and USB2-USBSS2 signals through a typical Type-C connector mux (HD3SS3220IRNHR). I’m able to detect devices at USB2.0 speed through both connectors. However, if any 3.0 or 3.1 device is connected, it is also recognized only as a USB 2.0 device.

Regarding the device tree, I’ve tried several changes without success:

xusb_padctl: xusb_padctl@3520000 {
	status = "okay";
	pads {
		usb2 {
			lanes {
				usb2-0 {
					nvidia,function = "xusb";
					status = "okay";
				};
				usb2-1 {
					nvidia,function = "xusb";
					status = "okay";
				};
				usb2-2 {
					nvidia,function = "xusb";
					status = "okay";
				};
			};
		};
		usb3 {
			lanes {
				usb3-0 {
					nvidia,function = "xusb";
					status = "okay";
				};
				usb3-1 {
					nvidia,function = "xusb";
					status = "okay";
				};
				usb3-2 {
					nvidia,function = "xusb";
					status = "okay";
				};
			};
		};
	};

	ports {
		usb2-0 {/* Goes to recovery port */
			mode = "otg";
			status = "okay";
			vbus-supply = <&p3768_vdd_5v_sys>;
			usb-role-switch;
			port {
				typec_p0: endpoint {
					remote-endpoint = <&fusb_p0>;
				};
			};
		};
		usb2-1 {/* Goes to hub */
			mode = "host";
			vbus-supply = <&p3768_vdd_av10_hub>;
			status = "okay";
		};
		usb2-2 {/* Goes to M2.E */
			mode = "host";
			vbus-supply = <&p3768_vdd_5v_sys>;
			status = "okay";
		};
		usb3-0 {/* Goes to hub */
			nvidia,usb2-companion = <1>;
			status = "okay";
		};
		usb3-1 {/* Goes to J5 */
			nvidia,usb2-companion = <0>;
			status = "okay";
		};
		usb3-2 {
			nvidia,usb2-companion = <2>;
			status = "okay";
		};
	};
};

tegra_xudc: xudc@3550000 {
	status = "okay";
	phys = <&{/xusb_padctl@3520000/pads/usb2/lanes/usb2-0}>,
		<&{/xusb_padctl@3520000/pads/usb3/lanes/usb3-1}>;
	phy-names = "usb2-0", "usb3-1";
	nvidia,xusb-padctl = <&xusb_padctl>;
};

tegra_xhci: xhci@3610000 {
	status = "okay";
	phys = <&{/xusb_padctl@3520000/pads/usb2/lanes/usb2-0}>,
		<&{/xusb_padctl@3520000/pads/usb2/lanes/usb2-1}>,
		<&{/xusb_padctl@3520000/pads/usb2/lanes/usb2-2}>,
		<&{/xusb_padctl@3520000/pads/usb3/lanes/usb3-0}>,
		<&{/xusb_padctl@3520000/pads/usb3/lanes/usb3-1}>,
		<&{/xusb_padctl@3520000/pads/usb3/lanes/usb3-2}>;
	phy-names = "usb2-0", "usb2-1", "usb2-2", "usb3-0", "usb3-1", "usb3-2";
	nvidia,xusb-padctl = <&xusb_padctl>;
};

I’m not sure if it’s right because I’ve not been able to figure out what pins are linked to a usb port. For example, USBSS2 pins are 51, 53, 57 and 59. I can imagine usb3-2 in the DT refers to those pins but i cannot be sure of it. I tried several combitations of the nvidia,usb2-companion parameter but no option seemed to work.

Pinmux files were also updated as specified in the Bring-up Guide.

Am I missing something? Thank you in advance for your help.

Regards,
José Luis.

Hi,

Just to clarify. The devkit design only uses one type C which is fusb301 controller.

Since your port seems totally different, you have to enable your own type C controller first. And then Do similar work in device tree as our example. That is why you can see there is “typec_p0: endpoint” “remote-endpoint = <&fusb_p0>;” in the DT.

Hi Wayne,

Thanks for your answer. Firstly, sorry if I make some obvious mistakes as I currently starting to work on these products.

I see your point. In my case, instead of using a FUSB301 that controls a USBSS mux, i’ve an unique integrated IC whose configuration is defined by HW components (although you can overwrite this configuration though an I2C driver like fusb301.c).

So, as far as my IC should be ready to transmit just after start-up (I’ve checked the IC status - DFP role and device attached), does the OS needs to know something to enable USBSS? Must I enable a custom type C controller although it actually does nothing?

Hi,

You still need to provide similar thing as remote-endpoint = <&fusb_p0> to our driver. Otherwise our driver cannot tell when to switch the data role (host/device).

The rest of things are mentioned in the developer guide document.
https://docs.nvidia.com/jetson/archives/r35.3.1/DeveloperGuide/text/HR/JetsonModuleAdaptationAndBringUp/JetsonAgxOrinSeries.html?highlight=universal#porting-the-universal-serial-bus

Hi Wayne,

Our target is to use USBSS0 and USBSS1 to transmit data at a 3.0 speed to downstream devices. This means the data role will always be host.

Is the remote-endpoint still needed given this circumstance?

Thank you.

Hi,

What you are talking about does not matter. But your exact schematic connection matters…

Please share the whole usb part schematic included the connector side, type C controller side and then the jetson module side…

The problem here is you make your port as type C port but you only want it to be a type A function.

Hi,

You’re right. I chose a type-C connector for weight/size reasons which are critial but, as soon as the selected USB-C controller is configured by HW, I assume it will act as a type-A.

Here you are the schematic connections:

These schematics are duplicated for the USB2/USBSS2:

Thanks.

Hi,

For the type C port which only acts as host mode.

The DT should be similar to type A case. Which means you need to set mode = “host”;

Also, xhci should have those pins and xudc should not have those pins because xudc is for device mode to use.
remote-endpoint is not needed and could be removed.

And you have to remove all unused pins otherwise the driver would probe error too.

Hi Wayne,

Thank you for the answer. I’ve just tested the following DT, but it’s still working only at a 2.0 speed through USB1 and USB2.


xusb_padctl: xusb_padctl@3520000 {
		status = "okay";
		pads {
			usb2 {
				lanes {
					usb2-0 {
						nvidia,function = "xusb";
						status = "okay";
					};
					usb2-1 {
						nvidia,function = "xusb";
						status = "okay";
					};
					usb2-2 {
						nvidia,function = "xusb";
						status = "okay";
					};
				};
			};
			usb3 {
				lanes {
					usb3-0 {
						nvidia,function = "xusb";
						status = "okay";
					};
					usb3-1 {
						nvidia,function = "xusb";
						status = "okay";
					};
					usb3-2 {
						nvidia,function = "xusb";
						status = "okay";
					};
				};
			};
	   	};
		ports {
			usb2-0 {/* Goes to recovery port */
				mode = "otg";
				status = "okay";
				vbus-supply = <&p3768_vdd_5v_sys>;
				usb-role-switch;
				port {
					typec_p0: endpoint {
						remote-endpoint = <&fusb_p0>;
					};
				};
			};
			usb2-1 {/* Goes to USB1 conn */
				mode = "host";
				vbus-supply = <&p3768_vdd_av10_hub>;
				status = "okay";
			};
			usb2-2 {/* Goes to USB2 Conn*/
				mode = "host";
				vbus-supply = <&p3768_vdd_5v_sys>;
				status = "okay";
			};
			usb3-0 {/* Goes to USB0 -REC */
				nvidia,usb2-companion = <0>;
				status = "okay";
			};
			usb3-1 {/* Goes to USB1 Conn */
				nvidia,usb2-companion = <1>;
				status = "okay";
			};
			usb3-2 {/* Goes to USB2 Conn*/
				nvidia,usb2-companion = <2>;
				status = "okay";
			};
		};
	};

	tegra_xudc: xudc@3550000 {
		status = "okay";
		phys = <&{/xusb_padctl@3520000/pads/usb2/lanes/usb2-0}>,
			<&{/xusb_padctl@3520000/pads/usb3/lanes/usb3-0}>;
		phy-names = "usb2-0", "usb3-0";
		nvidia,xusb-padctl = <&xusb_padctl>;
	};

	tegra_xhci: xhci@3610000 {
		status = "okay";
		phys = <&{/xusb_padctl@3520000/pads/usb2/lanes/usb2-0}>,
			<&{/xusb_padctl@3520000/pads/usb2/lanes/usb2-1}>,
			<&{/xusb_padctl@3520000/pads/usb2/lanes/usb2-2}>,
			<&{/xusb_padctl@3520000/pads/usb3/lanes/usb3-0}>,
			<&{/xusb_padctl@3520000/pads/usb3/lanes/usb3-1}>,
			<&{/xusb_padctl@3520000/pads/usb3/lanes/usb3-2}>;
		phy-names = "usb2-0", "usb2-1", "usb2-2", "usb3-0", "usb3-1", "usb3-2";
		nvidia,xusb-padctl = <&xusb_padctl>;
	};

Is there anything I may be missing?

Check if the vbus-supply really matches your hardware design too

vbus-supply = <&p3768_vdd_5v_sys>;
vbus-supply = <&p3768_vdd_av10_hub>;

And you need to at least share a full dmesg.

Full dmesg:
dmesg (71.4 KB)

Regarding the vbus-supply parameter, I’ve noticed it’s a reference con the subnodes in tegra234-p3768-0000-a0-fixed-regulator.dtsi. I configured both to p3768_vdd_5v_sys as it is automatically enabled with DC_IN but no change was noticed.

However, I do not fully understand what’s the fuction of these nodes as those supplies are not enabled by the Jetson module and they are not necessarily monitored by it. In my case, Vbus is provided by the vdd_5v_sys net through a overcurrent detection IC enabled by Vdd_3v3_sys_PG signal. The USB 3.0 requirement of a low VBus level during device attachment is met as my devices will always be atteched before power-up.

If it is a always-on power that has no GPIO to control, then you can use “battery_reg” as a dummy regulator to the device tree.

Hi Wayne,

I receive some errors when compiling the kernel adding battery_reg.

DT:

xusb_padctl: xusb_padctl@3520000 {
		status = "okay";
		pads {
			usb2 {
				lanes {
					usb2-0 {
						nvidia,function = "xusb";
						status = "okay";
					};
					usb2-1 {
						nvidia,function = "xusb";
						status = "okay";
					};
					usb2-2 {
						nvidia,function = "xusb";
						status = "okay";
					};
				};
			};
			usb3 {
				lanes {
					usb3-0 {
						nvidia,function = "xusb";
						status = "okay";
					};
					usb3-1 {
						nvidia,function = "xusb";
						status = "okay";
					};
					usb3-2 {
						nvidia,function = "xusb";
						status = "okay";
					};
				};
			};
		};

		ports {
			usb2-0 {/* Goes to recovery port */
				mode = "otg";
				status = "okay";
				vbus-supply = <&battery_reg>;
				usb-role-switch;
				port {
					typec_p0: endpoint {
						remote-endpoint = <&fusb_p0>;
					};
				};
			};
			usb2-1 {/* Goes to USB1 conn */
				mode = "host";
				vbus-supply = <&battery_reg>;
				status = "okay";
			};
			usb2-2 {/* Goes to USB2 Conn*/
				mode = "host";
				vbus-supply = <&battery_reg>;
				status = "okay";
			};
			usb3-0 {/* Goes to USB0 -REC */
				nvidia,usb2-companion = <0>;
				status = "okay";
			};
			usb3-1 {/* Goes to USB1 Conn */
				nvidia,usb2-companion = <1>;
				status = "okay";
			};
			usb3-2 {/* Goes to USB2 Conn*/
				nvidia,usb2-companion = <2>;
				status = "okay";
			};
		};
	};

Compilation output errors:

ERROR (phandle_references): /xusb_padctl@3520000/ports/usb2-0: Reference to non-existent node or label "battery_reg"
  also defined at /media/joseluis/LinuxData/Orin_HSCB-v01-r0/Jetson_Linux_R35.3.1_aarch64/Linux_for_Tegra/source/public/kernel/kernel-5.10/arch/arm64/boot/dts/../../../../../../hardware/nvidia/platform/t23x/p3768/kernel-dts/cvb/tegra234-hscb-v01-r0.dtsi:99.11-109.6

/media/joseluis/LinuxData/Orin_HSCB-v01-r0/Jetson_Linux_R35.3.1_aarch64/Linux_for_Tegra/source/public/kernel/kernel-5.10/../../hardware/nvidia/soc/t23x/kernel-dts/tegra234-soc/tegra234-soc-base.dtsi:598.11-600.6: 
ERROR (phandle_references): /xusb_padctl@3520000/ports/usb2-1: Reference to non-existent node or label "battery_reg"
  also defined at /media/joseluis/LinuxData/Orin_HSCB-v01-r0/Jetson_Linux_R35.3.1_aarch64/Linux_for_Tegra/source/public/kernel/kernel-5.10/arch/arm64/boot/dts/../../../../../../hardware/nvidia/platform/t23x/p3768/kernel-dts/cvb/tegra234-hscb-v01-r0.dtsi:110.11-114.6

/media/joseluis/LinuxData/Orin_HSCB-v01-r0/Jetson_Linux_R35.3.1_aarch64/Linux_for_Tegra/source/public/kernel/kernel-5.10/../../hardware/nvidia/soc/t23x/kernel-dts/tegra234-soc/tegra234-soc-base.dtsi:601.11-603.6: 
ERROR (phandle_references): /xusb_padctl@3520000/ports/usb2-2: Reference to non-existent node or label "battery_reg"
also defined at /media/joseluis/LinuxData/Orin_HSCB-v01-r0/Jetson_Linux_R35.3.1_aarch64/Linux_for_Tegra/source/public/kernel/kernel-5.10/arch/arm64/boot/dts/../../../../../../hardware/nvidia/platform/t23x/p3768/kernel-dts/cvb/tegra234-hscb-v01-r0.dtsi:115.11-119.6
ERROR: Input tree has errors, aborting (use -f to force output

Hi Wayne,

Finally, I figured out what happened. There was a hardware design mistake on our carrier board (The SSRX signals from the typeC connector to the USBSS mux were traced to the wrong orientation).

I managed to route the SSRX signal to the right connector pin in the cleanest way possible and now devices are detected as 3.0.

The final DT was the stated above:

xusb_padctl: xusb_padctl@3520000 {
		status = "okay";
		pads {
			usb2 {
				lanes {
					usb2-0 {
						nvidia,function = "xusb";
						status = "okay";
					};
					usb2-1 {
						nvidia,function = "xusb";
						status = "okay";
					};
					usb2-2 {
						nvidia,function = "xusb";
						status = "okay";
					};
				};
			};
			usb3 {
				lanes {
					usb3-0 {
						nvidia,function = "xusb";
						status = "okay";
					};
					usb3-1 {
						nvidia,function = "xusb";
						status = "okay";
					};
					usb3-2 {
						nvidia,function = "xusb";
						status = "okay";
					};
				};
			};
	   	};
		ports {
			usb2-0 {/* Goes to recovery port */
				mode = "otg";
				status = "okay";
				vbus-supply = <&p3768_vdd_5v_sys>;
				usb-role-switch;
				port {
					typec_p0: endpoint {
						remote-endpoint = <&fusb_p0>;
					};
				};
			};
			usb2-1 {/* Goes to USB1 conn */
				mode = "host";
				vbus-supply = <&p3768_vdd_av10_hub>;
				status = "okay";
			};
			usb2-2 {/* Goes to USB2 Conn*/
				mode = "host";
				vbus-supply = <&p3768_vdd_5v_sys>;
				status = "okay";
			};
			usb3-0 {/* Goes to USB0 -REC */
				nvidia,usb2-companion = <0>;
				status = "okay";
			};
			usb3-1 {/* Goes to USB1 Conn */
				nvidia,usb2-companion = <1>;
				status = "okay";
			};
			usb3-2 {/* Goes to USB2 Conn*/
				nvidia,usb2-companion = <2>;
				status = "okay";
			};
		};
	};

	tegra_xudc: xudc@3550000 {
		status = "okay";
		phys = <&{/xusb_padctl@3520000/pads/usb2/lanes/usb2-0}>,
			<&{/xusb_padctl@3520000/pads/usb3/lanes/usb3-0}>;
		phy-names = "usb2-0", "usb3-0";
		nvidia,xusb-padctl = <&xusb_padctl>;
	};

	tegra_xhci: xhci@3610000 {
		status = "okay";
		phys = <&{/xusb_padctl@3520000/pads/usb2/lanes/usb2-0}>,
			<&{/xusb_padctl@3520000/pads/usb2/lanes/usb2-1}>,
			<&{/xusb_padctl@3520000/pads/usb2/lanes/usb2-2}>,
			<&{/xusb_padctl@3520000/pads/usb3/lanes/usb3-0}>,
			<&{/xusb_padctl@3520000/pads/usb3/lanes/usb3-1}>,
			<&{/xusb_padctl@3520000/pads/usb3/lanes/usb3-2}>;
		phy-names = "usb2-0", "usb2-1", "usb2-2", "usb3-0", "usb3-1", "usb3-2";
		nvidia,xusb-padctl = <&xusb_padctl>;
	};

Thanks for your help.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.