DP HPD not working with production module with custom carrier

I’m having an issue that HPD on the eDP port does not seem to work. This is the third revision of a custom carrier and the same HPD level shifting circuit worked on the older revision.
The only difference is that I use the production module now instead of the older A01 revision.

Schematics and full boot log can be downloaded below

In the log it says
[ 15.051518] tegradc tegradc.1: No hpd-gpio in DT
[ 15.056160] tegradc tegradc.1: DT parsed successfully
[ 15.061236] tegradc tegradc.1: Display dc.ffffff800d5c0000 registered with id=1
[ 15.069308] tegradc tegradc.1: dpd enable lookup fail:-19

which sounds really odd though I’m not sure if dc.1 is not actually HDMI?
Still I feel this might have to do with the software.
DLT_rev3.zip (94.8 KB)

I verified that DP0_HPD is at 1.8V when the cable is plugged in and at 0V when unplugged.

Hi,

For display issue, please disable the second head(hdmi) in dts for debug. Also, please try hotplug and see if dmesg prints out more logs.

Hi,
I have the “Jetson_Nano_Module_Pinmux_Config_Template” spreadsheet but I don’t know what to do with the generated .dtsi. My guess is that it has to be compiled somehow and then flashed.
I could not find any guide on how to proceed with the dtsi file. My experience with device tree is very limited unfortunately.

Meanwhile I attached a log where I hot plugged the DP cable a few times, HDMI still enabled though.
bootlog_w_hotplugging.log (85.3 KB)

Just to verify, I flashed the Jetson Module with the P3448-0020 option. Assuming that this is the option for the eMMC based module with rev. B01 as opposed to the old A01 SDcard based revision found in the current dev kit. Is this correct?

Yes, if you are using a production module, then you need to flash with p3448-0020.

I don’t think you need to change the pinmux setting if you just follow original design as devkit and also no need to change dts or driver.

Ok how do I best disable HDMI then if not over the pinmux table?
Did you get anything useful from the kernel log with hotplugs?

Hi timonske,

You could disable it in the device tree. (tegradc.0 is your hdmi /1 is your dp).

But I think there is hardware design issue on your side because even your HDMI is not able to work fine.

The i2c error spew looks more like from your hdmi port but not DP. DP does not give out anything now…

[ 14.100540] hpd: state 1 (Check Plug), hpd 0, pending_hpd_evt 0
[ 14.106499] hpd: switching from state 1 (Check Plug) to state 3 (Disabled)

hpd does not detect anything from your dp port.

The exact same HPD circuit worked with the prev. revision which was using a A001 revision board.
I attached the schematics in my first post though.

The fact that DP does not show any reaction but HDMI reacted to me unplugging the DisplayPort and plugging it back in would support my suspicion that the pinmux is not correct.

The naming is also odd then, the design documents call DP0 DP/ePD and the DP1 port DP/HDMI but in DT it is the reverse?

HDMI was not plugged in at any point. The HDMI HPD pin was held HIGH through the pull up resistor.

You engineers already looked at the older revision and could not find any issues schematic wise.

I also noticed that USB isn’t working either, although absolutely nothing changed hardware wise on the carrier side.
Now I found this entry in one of the device tree includes. I’m not sure if that the #ifdef triggers but it does look like it completely disables USB?

#if TEGRA_XUSB_PADCONTROL_VERSION >= DT_VERSION_2
	xusb_padctl: xusb_padctl@7009f000 {
		compatible = "nvidia,tegra210b01-xusb-padctl";
		reg =   <0x0 0x7009f000 0x0 0x1000>;
		reg-names = "padctl";
		resets = <&tegra_car 142>;
		reset-names = "padctl";
		status = "disabled";

		pads {
			usb2 {
				clocks = <&tegra_car TEGRA210_CLK_USB2_TRK>;
				clock-names = "trk";
				status = "disabled";

				lanes {
					usb2-0 {
						status = "disabled";
						#phy-cells = <0>;
					};
					usb2-1 {
						status = "disabled";
						#phy-cells = <0>;
					};
					usb2-2 {
						status = "disabled";
						#phy-cells = <0>;
					};
					usb2-3 {
						status = "disabled";
						#phy-cells = <0>;
					};
				};
			};

			pcie {
				clocks = <&tegra_car TEGRA210_CLK_PLL_E>,
				<&tegra_car TEGRA210_CLK_PLL_P_UPHY_OUT>;
				clock-names = "pll", "uphy_mgmt";
				resets = <&tegra_car 205>;
				reset-names = "phy";
				status = "disabled";

				lanes {
					pcie-0 {
						status = "disabled";
						#phy-cells = <0>;
					};
					pcie-1 {
						status = "disabled";
						#phy-cells = <0>;
					};
					pcie-2 {
						status = "disabled";
						#phy-cells = <0>;
					};
					pcie-3 {
						status = "disabled";
						#phy-cells = <0>;
					};
					pcie-4 {
						status = "disabled";
						#phy-cells = <0>;
					};
					pcie-5 {
						status = "disabled";
						#phy-cells = <0>;
					};
					pcie-6 {
						status = "disabled";
						#phy-cells = <0>;
					};
				};
			};
		};

		ports {
			usb2-0 {
				status = "disabled";
			};
			usb2-1 {
				status = "disabled";
			};
			usb2-2 {
				status = "disabled";
			};
			usb2-3 {
				status = "disabled";
			};
			usb3-0 {
				status = "disabled";
			};
			usb3-1 {
				status = "disabled";
			};
			usb3-2 {
				status = "disabled";
			};
			usb3-3 {
				status = "disabled";
			};
		};
	};
#endif

Is there any guide on the Device Tree setup? The structure is incredible nested and its hard to decipher what is actually used by the Nano and for what revision.

Thanks
Timon

In the bringup guide the following is mentioned at the beginning:
“Before you use a P3448 SOM with a carrier board other than P3449, change the kernel device tree, bootloader configuration, ODM data, and flashing configuration to configure for the new carrier board instead of P3449. An EEPROM ID for your custom board is not required.”

Is this only the case when I make more drastic changes to the dev kit design and require different peripheral behaviour than the devkit offers?
If I don’t have to make changes to the device tree in this case, why does the dev kit include this eeprom?

Hi timonske,

Sorry for late reply. I am confused by your comment here.

  1. In below, it seems the carrier board you are using are applied to A01 and production module. Is it correct?

This is the third revision of a custom carrier and the same HPD level shifting circuit worked on the older revision.
The only difference is that I use the production module now instead of the older A01 revision

  1. If (1) is correct, may I know how did you get the hardware design guide for A01 revision? Is it approved by someone from nv? Actually, we don’t have any carrier board that can run A01 and production module simultaneously.

Hi Wayne,
sorry for the confusion. I got access to the prelimenary design docs earlier this year. Up to rev. 2 of my carrier I used A002 from the devkit. Now with rev.3 I switched to the production module and new pinout. The rev.3 carrier only works with B01.
Maybe any software changes that I missed that I have to take care of with B01?

Ok I got it.

Please note that I only work on software drivers. If you need any hardware check, I can help find some other engineers to check. You could refer to OEM design guide first.

There are some issues here:

  1. Your hdmi/dp seems have a reversed connection in prevous. Which means none of your monitor should work now. If your design matches the OEM design guide, then it should not happen. You could also check the device tree you are using (search dp_hpd0 keyword for your DP port)

  2. Please don’t depend on only one dtsi file to decide your device tree. You should check the runtime device tree by reading the node /proc/device-tree on your jetson nano and see what is the exact status of each node.

Also, if you need our help to check usb case, please file separate topic. This title is related to display hotplug but not usb.

I’m a bit confused now. While yes it feels like it is reversed, I followed the exact pinout from the design guide and the naming from the design guide which suggests that DP0 and DP1/HDMI got reversed pinout wise from rev. A01 to B01.

So far I have not touched anything in the device tree, I’m running the stock image that is being flashed through the SDK Manager.
My assumption is that this would give me the same behaviour from the new devkit design that is included in the public design docs. No need to set anything up, even if I don’t have an EEPROM on my carrier.

timonske,

Then I think you could try to check the runtime device tree by reading the related nodes under /proc/device-tree.

Please note that “sor” is the one that maps to hardware pin like dp0 and dp1. tegradc.0/1 are just software controller and map to arbitrary sor.

Default setting from official device tree is:

tegradc.1 -> sor0 -> dp
tegradc.0 -> sor1 -> hdmi

Please re-check the device tree and the kernel log behavior for each port.

Hi Wayne,
I’m not really sure where to look in /proc/device-tree and what values are interesting to debug this issue? I could not find anything related to dc, sor or dp

So do I understand correctly that you can theoretically map between the 2 ports in software?

Hi timonske,

I am not sure if you know the device tree of tegra well. The whole device tree is under /proc/device-tree/

For example, you could find sor0 and sor1 nodes. You could check whether their status is enabled or disabled.

Also, you could check the node under tegradc.0/tegradc.1 to know what is the sor they are mapping to.

This step is to make sure the run-time dt matches your desired result.

So do I understand correctly that you can theoretically map between the 2 ports in software?
Yes, sor0 and sor1 map to hw pin dp0 and dp1 respectively. The higher level is tegradc (display controller) which can be arbitrarily map to sor0 or sor1.

What you need to do now is to make sure

  1. what is the correct mapping you want.

  2. Disable one head and focus on the remaining one. For example, disable hdmi head and only try dp.

  3. Hotplug the cable and see if dmesg prints out correct driver log.
    If you unplug dp cable but the dmesg prints out hdmi driver log, then it is definitely wrong.

  4. One thing that might be missing for many users… nvgpu driver is a loadable module. You could check it by using command “lsmod”. If it is missing, then display is not able to render either.

Hi Wayne,
I looked at this with a few other Embedded Software Engineers. In /proc/device-tree there does not appear to be a tegradc entry. Looking at the device tree source we found a few hints and it seems to use the mapping that you mentioned before.

However there is not really any info on the HPD pin mapping. Given that this pinout differs from rev. A02 to B01 we would expect that there would something specific to that in the dtsi specific to the revision but they pull in the same definitions.

We suspect that the EEPROM is important to have in order to get the same behaviour (e.g. load the correct device tree) as the to be released dev kit. Has this been tested by Nvidia so far with real hardware? There are tons of errors in the pre linux env. about failed eeprom reads.

Hi timonske,

>>I looked at this with a few other Embedded Software Engineers. In /proc/device-tree there does not appear to be a tegradc entry. Looking at the device tree source we found a few hints and it seems to use the mapping that you mentioned before

Sorry that the exact name of tegradc should be dc@54200000 and dc@54240000 which are mapping to tegradc.0 and tegradc.1. If you looked into the dts already, then you should find out.

>>However there is not really any info on the HPD pin mapping. Given that this pinout differs from rev. A02 to B01 we would expect that there would something specific to that in the dtsi specific to the revision but they pull in the same definitions.

You cannot find it because we don’t have “HPD pin mapping” at all. The only thing for HPD pin is the pinmux setting and you could check it by referring to adaptation guide and Pinmux spreadsheet from our download center.

Please note that what so-called pinmux setting here is just configured this hpd pin as dp pin or GPIO. There is nothing like mapping hpd1 to dc0 and hpd0 to dc1. No such mechanism.

If you use the same hardware connection as devkit, then you don’t need to change the hpd pin setting.
What I meant here is that if devkit uses sor0 as DP and sor1 as HDMI and you use the same, then you should not need to change it.

We suspect that the EEPROM is important to have in order to get the same behaviour (e.g. load the correct device tree) as the to be released dev kit. Has this been tested by Nvidia so far with real hardware? There are tons of errors in the pre linux env. about failed eeprom reads.

There are two eeprom if using devkit.

  1. eeprom on module
  2. eeprom on carrier board.

Our driver and device tree loading only cares about the eeprom on module. It means if you only change the carrier board, though it does not have eeprom, it should not affect anything.

You could compare your current behavior (dmesg) on devkit with your carrier board and see if any difference.