Hi KevinFFF,
I haven’t yet done the loop back test, but I do think it is becoming clear that we are struggling to load a device tree overlay to our AGX Orin 64 GB Dev Kits. In your link above you seem to be suggesting that we should modify the full device tree and reflash. To date we have been trying to apply an overlay to the existing tree.
We tried to add support for both MCP2515s with the following overlay (mcp2515-dual-spi1-overlay.dts):
/dts-v1/;
/plugin/;
/ {
compatible = “nvidia,jetson-agx-orin”;
fragment@0 {
target-path = "/spi@3210000"; // SPI1 on header
__overlay__ {
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
can2: mcp2515@0 {
compatible = "microchip,mcp2515";
reg = <0>; // chip select 0
spi-max-frequency = <2000000>;
oscillator-frequency = <10000000>; // 10 MHz clock input
interrupt-parent = <&tegra_main_gpio>;
interrupts = <8 8>;
nvidia,enable-hw-based-cs;
controller-data {
nvidia,enable-hw-based-cs;
nvidia,rx-clk-tap-delay = <0x10>;
};
};
can3: mcp2515@1 {
compatible = "microchip,mcp2515";
reg = <1>; // chip select 1
spi-max-frequency = <2000000>;
oscillator-frequency = <10000000>; // 10 MHz clock input
interrupt-parent = <&tegra_main_gpio>;
interrupts = <499 8>;
nvidia,enable-hw-based-cs;
controller-data {
nvidia,enable-hw-based-cs;
nvidia,rx-clk-tap-delay = <0x10>;
};
};
};
};
};
Then we enabled SPI1 via Jetson IO. This created a DTBO file named jetson-io-hdr40-user-custom.dtbo located in /boot. We gained access to this overlay via decompilation with this command: dtc -I dtb -O dts -o jetson-io-hdr40-user-custom.dts /boot/jetson-io-hdr40-user-custom.dtbo
This is the decompiled file:
/dts-v1/;
/ {
jetson-header-name = “Jetson 40pin Header”;
overlay-name = “User Custom [2025-05-29-141127]”;
compatible = “nvidia,p3737-0000+p3701-0000\0nvidia,p3737-0000+p3701-0004\0nvidia,p3737-0000+p3701-0005\0nvidia,p3737-0000+p3701-0008”;
p3737-0000_p3701-0000-hdr40@0 {
target = <0xffffffff>;
__overlay__ {
pinctrl-names = "default";
pinctrl-0 = <0x01>;
exp-header-pinmux {
phandle = <0x01>;
hdr40-pin19 {
nvidia,pins = "spi1_mosi_pz5";
nvidia,function = "spi1";
nvidia,tristate = <0x00>;
nvidia,enable-input = <0x01>;
};
hdr40-pin21 {
nvidia,pins = "spi1_miso_pz4";
nvidia,function = "spi1";
nvidia,tristate = <0x00>;
nvidia,enable-input = <0x01>;
};
hdr40-pin23 {
nvidia,pins = "spi1_sck_pz3";
nvidia,function = "spi1";
nvidia,tristate = <0x00>;
nvidia,enable-input = <0x01>;
};
hdr40-pin24 {
nvidia,pins = "spi1_cs0_pz6";
nvidia,function = "spi1";
nvidia,tristate = <0x00>;
nvidia,enable-input = <0x01>;
};
hdr40-pin26 {
nvidia,pins = "spi1_cs1_pz7";
nvidia,function = "spi1";
nvidia,tristate = <0x00>;
nvidia,enable-input = <0x01>;
};
};
};
};
fragment@1 {
target = <0xffffffff>;
__overlay__ {
pinctrl-names = "default";
pinctrl-0 = <0x02>;
exp-header-pinmux {
phandle = <0x02>;
hdr40-pin29 {
nvidia,pins = "can0_din_paa1";
nvidia,function = "can0";
nvidia,tristate = <0x01>;
nvidia,enable-input = <0x01>;
};
hdr40-pin31 {
nvidia,pins = "can0_dout_paa0";
nvidia,function = "can0";
nvidia,tristate = <0x00>;
nvidia,enable-input = <0x00>;
};
hdr40-pin33 {
nvidia,pins = "can1_dout_paa2";
nvidia,function = "can1";
nvidia,tristate = <0x00>;
nvidia,enable-input = <0x00>;
};
hdr40-pin37 {
nvidia,pins = "can1_din_paa3";
nvidia,function = "can1";
nvidia,tristate = <0x01>;
nvidia,enable-input = <0x01>;
};
};
};
};
__symbols__ {
jetson_io_pinmux = "/p3737-0000_p3701-0000-hdr40@0/__overlay__/exp-header-pinmux";
jetson_io_pinmux_aon = "/fragment@1/__overlay__/exp-header-pinmux";
};
__fixups__ {
pinmux = "/p3737-0000_p3701-0000-hdr40@0:target:0";
pinmux_aon = "/fragment@1:target:0";
};
__local_fixups__ {
p3737-0000_p3701-0000-hdr40@0 {
__overlay__ {
pinctrl-0 = <0x00>;
};
};
fragment@1 {
__overlay__ {
pinctrl-0 = <0x00>;
};
};
};
};
The initial extlinux.conf file looks like this :
GNU nano 6.2 ./extlinux.conf *
TIMEOUT 30
DEFAULT JetsonIO
MENU TITLE L4T boot options
LABEL primary
MENU LABEL primary kernel
LINUX /boot/Image
INITRD /boot/initrd
APPEND ${cbootargs} root=/dev/nvme0n1p1 rw rootwait rootfstype=ext4 mminit_loglevel=4 console=ttyTCU0,115200 console=ttyAMA0,115200 firmware_class.path=/etc/firmware fbcon=map:0 net.ifnames=0 nospectre_bhb video=efifb:off console=tty0 nv-auto-config
LABEL JetsonIO
MENU LABEL Custom Header Config: <HDR40 User Custom [2025-05-29-141127]>
LINUX /boot/Image
FDT /boot/dtb/kernel_tegra234-p3737-0000+p3701-0005-nv.dtb
INITRD /boot/initrd
APPEND ${cbootargs} root=/dev/nvme0n1p1 rw rootwait rootfstype=ext4 mminit_loglevel=4 console=ttyTCU0,115200 console=ttyAMA0,115200 firmware_class.path=/etc/firmware fbcon=map:0 net.ifnames=0 nospectre_bhb video=efifb:off console=tty0 nv-auto-config
OVERLAYS /boot/jetson-io-hdr40-user-custom.dtbo
we then modified the OVERLAYS line to look like this:
OVERLAYS /boot/jetson-io-hdr40-user-custom.dtbo,/boot/mcp2515-dual-spi1-overlay.dtbo and placed mcp2515-dual-spi1-overlay.dtbo in /boot.
When we make this change neither overlay functions. Our modifications in JETSONIO to add the SPI headers don’t persist, if we open JETSONIO they have reverted. If I return the OVERLAYS line to : OVERLAYS /boot/jetson-io-hdr40-user-custom.dtbo the JETSON IO changes show up again in JETSON IO.
I also experimented with combining mcp2515-dual-spi1-overlay.dts and /boot/jetson-io-hdr40-user-custom.dts into a single file and this is what results:
/dts-v1/;
/plugin/;
/ {
jetson-header-name = “Jetson 40pin Header”;
overlay-name = “User Custom with MCP2515”;
compatible = “nvidia,p3737-0000+p3701-0000\0nvidia,p3737-0000+p3701-0004\0nvidia,p3737-0000+p3701-0005\0nvidia,p3737-0000+p3701-0008”;
p3737-0000_p3701-0000-hdr40@0 {
target = <0xffffffff>;
__overlay__ {
pinctrl-names = "default";
pinctrl-0 = <0x01>;
exp-header-pinmux {
phandle = <0x01>;
hdr40-pin19 {
nvidia,pins = "spi1_mosi_pz5";
nvidia,function = "spi1";
nvidia,tristate = <0x00>;
nvidia,enable-input = <0x01>;
};
hdr40-pin21 {
nvidia,pins = "spi1_miso_pz4";
nvidia,function = "spi1";
nvidia,tristate = <0x00>;
nvidia,enable-input = <0x01>;
};
hdr40-pin23 {
nvidia,pins = "spi1_sck_pz3";
nvidia,function = "spi1";
nvidia,tristate = <0x00>;
nvidia,enable-input = <0x01>;
};
hdr40-pin24 {
nvidia,pins = "spi1_cs0_pz6";
nvidia,function = "spi1";
nvidia,tristate = <0x00>;
nvidia,enable-input = <0x01>;
};
hdr40-pin26 {
nvidia,pins = "spi1_cs1_pz7";
nvidia,function = "spi1";
nvidia,tristate = <0x00>;
nvidia,enable-input = <0x01>;
};
};
};
};
fragment@1 {
target = <0xffffffff>;
__overlay__ {
pinctrl-names = "default";
pinctrl-0 = <0x02>;
exp-header-pinmux {
phandle = <0x02>;
hdr40-pin29 {
nvidia,pins = "can0_din_paa1";
nvidia,function = "can0";
nvidia,tristate = <0x01>;
nvidia,enable-input = <0x01>;
};
hdr40-pin31 {
nvidia,pins = "can0_dout_paa0";
nvidia,function = "can0";
nvidia,tristate = <0x00>;
nvidia,enable-input = <0x00>;
};
hdr40-pin33 {
nvidia,pins = "can1_dout_paa2";
nvidia,function = "can1";
nvidia,tristate = <0x00>;
nvidia,enable-input = <0x00>;
};
hdr40-pin37 {
nvidia,pins = "can1_din_paa3";
nvidia,function = "can1";
nvidia,tristate = <0x01>;
nvidia,enable-input = <0x01>;
};
};
};
};
fragment@2 {
target-path = "/spi@3210000";
__overlay__ {
status = "okay";
#address-cells = <1>;
#size-cells = <0>;
can2: mcp2515@0 {
compatible = "microchip,mcp2515";
reg = <0>;
spi-max-frequency = <2000000>;
oscillator-frequency = <10000000>;
interrupt-parent = <&tegra_main_gpio>;
interrupts = <8 8>;
controller-data {
nvidia,enable-hw-based-cs;
nvidia,rx-clk-tap-delay = <0x10>;
};
};
can3: mcp2515@1 {
compatible = "microchip,mcp2515";
reg = <1>;
spi-max-frequency = <2000000>;
oscillator-frequency = <10000000>;
interrupt-parent = <&tegra_main_gpio>;
interrupts = <499 8>;
controller-data {
nvidia,enable-hw-based-cs;
nvidia,rx-clk-tap-delay = <0x10>;
};
};
};
};
__symbols__ {
jetson_io_pinmux = "/p3737-0000_p3701-0000-hdr40@0/__overlay__/exp-header-pinmux";
jetson_io_pinmux_aon = "/fragment@1/__overlay__/exp-header-pinmux";
};
__fixups__ {
pinmux = "/p3737-0000_p3701-0000-hdr40@0:target:0";
pinmux_aon = "/fragment@1:target:0";
};
__local_fixups__ {
p3737-0000_p3701-0000-hdr40@0 {
__overlay__ {
pinctrl-0 = <0x00>;
};
};
fragment@1 {
__overlay__ {
pinctrl-0 = <0x00>;
};
};
};
};
combined-mcp2515-jetsonio.dts then gets compiled via:
sudo dtc -I dts -O dtb -@ -o /boot/combined-mcp2515-jetsonio.dtbo combined-mcp2515-jetsonio.dts
extlinux.conf OVERLAYS becomes :
OVERLAYS /boot/combined-mcp2515-jetsonio.dtbo but results are similar. We lose the functionality of the JETSON IO overlay and lose the functionality associated with my MCP overlays.
Any ideas on what we’re doing wrong here? In parallel I will work on trying to see if we recompile the full device tree and flash if that resolves the issues.
Thanks very much for your help,
Mike