Configuring Xavier NX DP1_HPD as DP hotplug detection

On a custom carrier-board, I have two type-c connectors, wired to DP0 and DP1.

DP0 works fine, but debugging a problem related to DP1 has raised a question:

  • How the DP1_HPD (GPIO M.1) pin is configured as DP hotplug input?
  • Is the configuration done only by kernel device tree or does it include something the drivers or bootloader do?
    The intention is to configure both outputs as similar DP outputs.

The kernel device tree changes that I have tried are included at the end of this message.

According to Xavier NX pinmux excel-sheet, the inputs DP0_HPD and DP1_HPD equal GPIOs M0 and M1.
State of those GPIOs can be read from/sys/kernel/debug/tegra_gpio:

Port:Pin:ENB DBC IN OUT_CTRL OUT_VAL INT_CLR
...
M:0 0x0 0x0 0x0 0x1 0x0 0x0
M:1 0x1 0x0 0x0 0x0 0x0 0x0

I can see the IN value of DP1_HPD (GPIO M.1) changing when cable is plugged or removed to DP1, as expected (when the pin is in GPIO mode).

The DP0_HPD (GPIO M.0) input state does not seem to change when plugging the cable, but maybe it’s because the pin is configure to something else than GPIO?

I noticed that the M.1 (DP1_HPD) ENB value changed from 0x4d to 0x1 after I made the attached changes in the device tree. I have no idea how to get similar change in M.0. Changing the head0 and head1 configurations to match does not change the M.0 gpio values.

Device tree changes

I have made the following changes to the device tree:
nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-p3509-disp.dtsi
(only modified entries are shown here, others are as defaults)

&head0 {
        status = "okay";
        nvidia,fb-bpp = <32>;
        nvidia,fbmem-size = <265420800>; /* 8K (7680*4320) 32bpp double buffered */
        nvidia,fb-flags = <TEGRA_FB_FLIP_ON_PROBE>;
        win-mask = <0x7>;
        nvidia,fb-win = <0>;
        nvidia,dc-connector = <&sor1>;
        nvidia,dc-flags = <TEGRA_DC_FLAG_ENABLED>;
        avdd_hdmi-supply = <&p3668_spmic_sd0>; /* 1v0 */
        avdd_hdmi_pll-supply = <&p3668_spmic_sd1>; /* 1v8 */
        vdd_hdmi_5v0-supply = <&p3509_vdd_hdmi_5v0>; /* 5v0 */

        //Added the following 2 lines to match the configuration with head1 (that works)
        avdd-dp-pll-supply = <&p3668_spmic_sd1>;
        vdd-edp-sec-mode-supply = <&battery_reg>;
};
&sor0 {
        status = "okay";
        nvidia,active-panel = <&sor0_dp_display>;
};
&sor0_dp_display {
        status = "okay";
        nvidia,is_ext_dp_panel = <1>;
};
&sor1 {
        status = "okay";
        //Changed active-panel to point dp display instead of hdmi and added the similar sor1_dp_display:
        nvidia,active-panel = <&sor1_dp_display>;
};
&sor1_dp_display {
        status = "okay";
        nvidia,is_ext_dp_panel = <1>;
};

Also noticed that heads are “cross linked” head0->sor1 and head1->sor0 by default. Is there a specific reason for this?

Hi,

That is probably because the default setting was DP0 → dp port, DP1 → hdmi port on devkit and now you want to use DP1 as dp port too.

Thus, besides the DTS change, you also need to check the pinmux setting.
Please read the register and see if these two give different result.

0x02440030 → for DP0_hpd (M.0)
0x02440038 → for DP1 hpd (M.1)

If you said M.1 gives correct result, then you may need to modify M.0 to be same as M.1 setting through pinmux spreadsheet or directly modify the pinmux file under Linux_for_Tegra/bootloader/t186ref/BCT

By default, those pins are configured identically in the pinmux cfg.
This config was active in the earlier exaple.

tegra19x-mb1-pinmux-p3668-a01.cfg:

pinmux.0x02440030 = 0x00000450; # dp_aux_ch0_hpd_pm0: dp, tristate-enable, input-enable, io_high_voltage-disable, lpdr-disable
pinmux.0x02440038 = 0x00000450; # dp_aux_ch1_hpd_pm1: dp, tristate-enable, input-enable, io_high_voltage-disable, lpdr-disable

Hi,

Is the value read after system boots up is still 0x450 on both too?

No, in runnig system the other one has changed to 0x150:

Bank: 0 Reg: 0x02440030 Val: 0x00000450 -> dp_aux_ch0_hpd_pm0
Bank: 0 Reg: 0x02440038 Val: 0x00000150 -> dp_aux_ch1_hpd_pm1

(read from /sys/kernel/debug/tegra_pinctrl_reg)

Could you share your full dts here? Looks like something is overwriting the pinmux.

Please also make sure that your pinmux cfg file is really that one which has 2 x 0x450.

Meanwhile, I downloaded the new L4T 32.5.

I unpacked a fresh copy of L4T 32.5 and configured flashed it according to the installation manual.
I read the contents of a few debug interfaces before and after patching the kernel device tree that is included in the end of this message.
The patched device tree does change the display type from HDMI to DP, but the mentioned HPD pins remain different.

Flashed the initial image with the command:

 sudo ./flash.sh jetson-xavier-nx-devkit-emmc mmcblk0p1

Flashed the modified device tree with the command:

 sudo ./flash.sh -r -k kernel-dtb jetson-xavier-nx-devkit-emmc mmcblk0p1

The tegra19x-mb1-pinmux-p3668-a01.cfg contains this config by default:

pinmux.0x02440030 = 0x00000450; # dp_aux_ch0_hpd_pm0: dp, tristate-enable, input-enable, io_high_voltage-disable, lpdr-disable
pinmux.0x02440038 = 0x00000450; # dp_aux_ch1_hpd_pm1: dp, tristate-enable, input-enable, io_high_voltage-disable, lpdr-disable

/sys/kernel/debug/tegra_pinctrl_reg

Default:

Bank: 0 Reg: 0x02440030 Val: 0x00000450 -> dp_aux_ch0_hpd_pm0
Bank: 0 Reg: 0x02440038 Val: 0x00000150 -> dp_aux_ch1_hpd_pm1

Patched: (no change in outcome)

Bank: 0 Reg: 0x02440030 Val: 0x00000450 -> dp_aux_ch0_hpd_pm0
Bank: 0 Reg: 0x02440038 Val: 0x00000150 -> dp_aux_ch1_hpd_pm1

/sys/kernel/debug/tegra_gpio

Default:

M:0 0x0 0x0 0x0 0x1 0x0 0x0
M:1 0x4d 0x0 0x0 0x0 0x0 0x0

Patched: (M.1 config changed from 0x4d to 0x1)

M:0 0x0 0x0 0x0 0x1 0x0 0x0
M:1 0x1 0x0 0x1 0x0 0x0 0x0

/sys/kernel/debug/tegradc.*/out_type
Default:

        DC OUTPUT:      TEGRA_DC_OUT_HDMI (1)
        DC OUTPUT:      TEGRA_DC_OUT_DP (3)

Patched: (display type changed to DP as expected)

        DC OUTPUT:      TEGRA_DC_OUT_DP (3)
        DC OUTPUT:      TEGRA_DC_OUT_DP (3)

Modified device tree file
Linux_for_Tegra/sources/hardware/nvidia/platform/t19x/jakku/kernel-dts/common/tegra194-p3509-disp.dtsi

#include <dt-bindings/display/tegra-dc.h>
#include <dt-bindings/display/tegra-panel.h>
#include <t19x-common-platforms/tegra194-hdmi.dtsi>
#include <t19x-common-platforms/tegra194-dp.dtsi>
#include "tegra194-fixed-regulator-p3509-0000-a00.dtsi"
#include "tegra194-spmic-p3668.dtsi"

&head0 {
        status = "okay";
        nvidia,fb-bpp = <32>;
        nvidia,fbmem-size = <265420800>; /* 8K (7680*4320) 32bpp double buffered */
        nvidia,fb-flags = <TEGRA_FB_FLIP_ON_PROBE>;
        win-mask = <0x7>;
        nvidia,fb-win = <0>;
        nvidia,dc-connector = <&sor1>;
        nvidia,dc-flags = <TEGRA_DC_FLAG_ENABLED>;

        vdd-dp-pwr-supply = <&p3668_spmic_sd0>;
        avdd-dp-pll-supply = <&p3668_spmic_sd1>;
        vdd-edp-sec-mode-supply = <&battery_reg>;
        vdd-dp-pad-supply = <&battery_reg>;
        vdd_hdmi_5v0-supply = <&p3509_vdd_hdmi_5v0>;
};
&head1 {
        status = "okay";
        nvidia,fb-bpp = <32>;
        nvidia,fbmem-size = <265420800>; /* 8K (7680*4320) 32bpp double buffered */
        nvidia,fb-flags = <TEGRA_FB_FLIP_ON_PROBE>;
        win-mask = <0x38>;
        nvidia,fb-win = <3>;
        nvidia,dc-connector = <&sor0>;
        nvidia,dc-flags = <TEGRA_DC_FLAG_ENABLED>;

        vdd-dp-pwr-supply = <&p3668_spmic_sd0>;
        avdd-dp-pll-supply = <&p3668_spmic_sd1>;
        vdd-edp-sec-mode-supply = <&battery_reg>;
        vdd-dp-pad-supply = <&battery_reg>;
        vdd_hdmi_5v0-supply = <&p3509_vdd_hdmi_5v0>;
};
&sor0 {
        status = "okay";
        nvidia,active-panel = <&sor0_dp_display>;
};
&sor1 {
        status = "okay";
        nvidia,active-panel = <&sor1_dp_display>;
};
&sor0_dp_display {
        status = "okay";
        nvidia,is_ext_dp_panel = <1>;
};
&sor1_dp_display {
        status = "okay";
        nvidia,is_ext_dp_panel = <1>;
};
&dpaux0 {
        status = "okay";
};
&dpaux1 {
        status = "okay";
};
&tegra_cec {
        status = "okay";
};

Update: Got it working.

The problem was that it is not enough to update the kernel device-tree; must update the whole system and run oem-config.