Update the device-tree for CAN-BUS, PLLAON Clock

Hello, I’m having trouble flashing the modified device-tree in order to make the CAN-BUS work, I guess there is something that I missed. I have read the documentation How to enable the pll_aon clock

I have modified the “tegra194-a02-bpmp-p2888-a04.dtb” file in the “bootloader” folder on my desktop computer using “dtc”. But when I want to upload the file with the command “sudo ./flash.sh -k kernel-dtb jetson-agx-xavier-devkit mmcblk0p1” its get systematically overwritten during the flashing process, and the device-tree on the Jetson AGX Xavier has not changed. I tried to put the file in the “kernel/dtb” folder but it seems that the file is just ignored.

However what I manged to do so far is to download and compile the kernel and the device-tree source files. I have edited “sources/hardware/nvidia/plateform/t19x/galen/kernel-dts/common/tegra194-p2888-0001-p2822-0000-common.dtsi” to fit the changes demanded in the documentation cited earlier How to enable the pll_aon clock

         clocks-init {
		compatible = "nvidia,clocks-config";
		status = "okay";
		disable {
			clocks = <&bpmp_clks TEGRA194_CLK_CAN1>,
				<&bpmp_clks TEGRA194_CLK_CAN2>;
		};
	};

and this in “sources/hardware/plateform/t19x/common/kernel-dts/t19x-common-platforms/tegra194-no-pll-aon-clock.dtsi”

        mttcan@c310000 {
		pll_source = "pllaon";
                clocks = <&bpmp_clks TEGRA194_CLK_CAN1_CORE>,
                        <&bpmp_clks TEGRA194_CLK_CAN1_HOST>,
                        <&bpmp_clks TEGRA194_CLK_CAN1>,
                        <&bpmp_clks TEGRA194_CLK_PLLAON>;
		 clock-names = "can_core", "can_host","can", "pllaon";
        };

        mttcan@c320000 {
		pll_source = "pllaon";
                clocks = <&bpmp_clks TEGRA194_CLK_CAN2_CORE>,
                        <&bpmp_clks TEGRA194_CLK_CAN2_HOST>,
                        <&bpmp_clks TEGRA194_CLK_CAN2>,
                        <&bpmp_clks TEGRA194_CLK_PLLAON>;
		 clock-names = "can_core", "can_host","can", "pllaon";
        };

This seems to work kind of, as when I type “cat /proc/device-tree/mttcan@c310000/pll_source” I get “pllaon”.
But this command “cat /sys/kernel/debug/bpmp/debug/clk/can1/parent” gives me “pll_c”
This one “cat /sys/kernel/debug/bpmp/debug/clk/can1/possible_parents” “clk_32k osc pll_c”
And this one “xxd /proc/device-tree/mttcan@c310000/clocks”

00000000: 0000 0004 0000 011c 0000 0004 0000 000a …
00000010: 0000 0004 0000 0009 0000 0004 0000 005e …^

When I type modprobe mttcan I get the error in dmesg saying:

mttcan c310000.mttcan: unable to set CAN_CLK parent
mttcan c310000.mttcan: probe failed
mttcan c320000.mttcan: unable to set CAN_CLK parent
mttcan c320000.mttcan: probe failed

Thank you for your help.

Have a done some “progress”, in the sens that, I have found that I should have put the “tegra194-a02-bpmp-p2888-a04.dtb” in the folder “bootloader/t186ref” in order to be flashed on the device and not just the “bootloader” folder.

I have change my strategy, I have given up compiling the kernel, what I’m doing now:

Delete everything
Download a fresh copy of JetPack 4.6 using sdkmanager
De-compiling the two dts files “tegra194-a02-bpmp-p2888-a04.dtb” and “tegra194-p2888-0001-p2822-0000.dtb” using the “dtc” command:

dtc -I dtb -O dts tegra194-p2888-0001-p2822-0000.dtb -o tegra194-p2888-0001-p2822-0000.dts
dtc -I dtb -O dts tegra194-a02-bpmp-p2888-a04.dtb -o tegra194-a02-bpmp-p2888-a04.dts

Changing the following things in tegra194-a02-bpmp-p2888-a04.dts

clock@can1 {
	allow_fractional_divider = <0x1>;
	allowed-parents = <0x121 0x5b 0x13a 0x5e>;
	clk-id = <0x9>;
};

clock@can2 {
	allow_fractional_divider = <0x1>;
	allowed-parents = <0x121 0x5b 0x13a 0x5e>;
	clk-id = <0xb>;
};

And in tegra194-p2888-0001-p2822-0000.dts

mttcan@c310000 {
	compatible = "nvidia,tegra194-mttcan";
	reg = <0x0 0xc310000 0x0 0x400 0x0 0xc311000 0x0 0x32 0x0 0xc312000 0x0 0x1000>;
	reg-names = "can-regs", "glue-regs", "msg-ram";
	interrupts = <0x0 0x28 0x4>;
	pll_source = "pllaon";
	clocks = <0x4 0x11c 0x4 0xa 0x4 0x9 0x4 0x5e>;
	clock-names = "can_core", "can_host", "can", "pllaon";
	resets = <0x5 0x4>;
	reset-names = "can";
	mram-params = <0x0 0x10 0x10 0x20 0x0 0x0 0x10 0x10 0x10>;
	tx-config = <0x0 0x10 0x0 0x40>;
	rx-config = <0x40 0x40 0x40>;
	status = "okay";
	linux,phandle = <0x187>;
	phandle = <0x187>;
};

mttcan@c320000 {
	compatible = "nvidia,tegra194-mttcan";
	reg = <0x0 0xc320000 0x0 0x400 0x0 0xc321000 0x0 0x32 0x0 0xc322000 0x0 0x1000>;
	reg-names = "can-regs", "glue-regs", "msg-ram";
	interrupts = <0x0 0x2a 0x4>;
	pll_source = "pllaon";
	clocks = <0x4 0x11d 0x4 0xc 0x4 0xb 0x4 0x5e>;
	clock-names = "can_core", "can_host", "can", "pllaon";
	resets = <0x5 0x5>;
	reset-names = "can";
	mram-params = <0x0 0x10 0x10 0x20 0x0 0x0 0x10 0x10 0x10>;
	tx-config = <0x0 0x10 0x0 0x40>;
	rx-config = <0x40 0x40 0x40>;
	status = "okay";
	linux,phandle = <0x188>;
	phandle = <0x188>;
};

...

clocks-init {
	compatible = "nvidia,clocks-config";
	status = "okay";
	disable {
		clocks = <0x14f 0x9 0x4 0xb>;
	};
};

Then recompile them into dtb

dtc -I dts -O dtb tegra194-p2888-0001-p2822-0000.dts -o tegra194-p2888-0001-p2822-0000.dtb
dtc -I dts -O dtb tegra194-a02-bpmp-p2888-a04.dts -o tegra194-a02-bpmp-p2888-a04.dtb

Then replace the existing file “tegra194-p2888-0001-p2822-0000.dtb” in the “kernel/dtb” folder and “tegra194-a02-bpmp-p2888-a04.dtb” in the “bootloader/t186ref”

Then flash the jetson with the command:
sudo ./flash.sh jetson-agx-xavier-devkit mmcblk0p1

Once it is done, setup the ubuntu (language, keyboard etc…)

Then login and type:
sudo modprobe mttcan

And everything freeze. Then the device reboot itself after ~2 minutes.

Thank you for you help.

Ok, after a new attempt it works on JetPack 4.6. The clock is set to pllaon when I activate the mttcan with modprobe.

The last thing I did was indeed the good strategy but I must have mess-up one of my dts file, hence causing the freeze of the kernel. (maybe I took one from an other version of JetPack accidentally due to a bad copy paste)

For those who have issue using the can on the Jetson Xavier AGX, JetPack 4.6 here is my solution.

Download with the sdkmanager the JetPack 4.6 but flash the device yet.
Then as I said in my previous post, copy into a workspace folder the files “bootloader/t186ref/tegra194-a02-bpmp-p2888-a04.dtb” and “kernel/dtb/tegra194-p2888-0001-p2822-0000.dtb”

Then use the “dtc” (device-tree compiler) command to de-compile the files: (or download the edited .dtb further down in my post)

dtc -I dtb -O dts tegra194-p2888-0001-p2822-0000.dtb -o tegra194-p2888-0001-p2822-0000.dts
dtc -I dtb -O dts tegra194-a02-bpmp-p2888-a04.dtb -o tegra194-a02-bpmp-p2888-a04.dts

edit the file “tegra194-a02-bpmp-p2888-a04.dts” to allow the “pllaon” (0x5e) clock to be a parent of the two CAN

...
clock@can1 {
	allow_fractional_divider = <0x1>;
	allowed-parents = <0x121 0x5b 0x13a 0x5e>; // changed
	clk-id = <0x9>;
};

clock@can2 {
	allow_fractional_divider = <0x1>;
	allowed-parents = <0x121 0x5b 0x13a 0x5e>; // changed
	clk-id = <0xb>;
};
...

And the “tegra194-p2888-0001-p2822-0000.dts” file to change the “pll_source”, and the “pllaon” to the field “clocks” and “clock-names” of the two “mttcan”. Also remove the “pllaon” clock from the disabled clocks.

...
mttcan@c310000 {
	compatible = "nvidia,tegra194-mttcan";
	reg = <0x0 0xc310000 0x0 0x400 0x0 0xc311000 0x0 0x32 0x0 0xc312000 0x0 0x1000>;
	reg-names = "can-regs", "glue-regs", "msg-ram";
	interrupts = <0x0 0x28 0x4>;
	pll_source = "pllaon"; // changed
	clocks = <0x4 0x11c 0x4 0xa 0x4 0x9 0x4 0x5e>; // changed
	clock-names = "can_core", "can_host", "can", "pllaon"; // changed
	resets = <0x5 0x4>;
	reset-names = "can";
	mram-params = <0x0 0x10 0x10 0x20 0x0 0x0 0x10 0x10 0x10>;
	tx-config = <0x0 0x10 0x0 0x40>;
	rx-config = <0x40 0x40 0x40>;
	status = "okay";
	linux,phandle = <0x187>;
	phandle = <0x187>;
};

mttcan@c320000 {
	compatible = "nvidia,tegra194-mttcan";
	reg = <0x0 0xc320000 0x0 0x400 0x0 0xc321000 0x0 0x32 0x0 0xc322000 0x0 0x1000>;
	reg-names = "can-regs", "glue-regs", "msg-ram";
	interrupts = <0x0 0x2a 0x4>;
	pll_source = "pllaon"; // changed
	clocks = <0x4 0x11d 0x4 0xc 0x4 0xb 0x4 0x5e>; // changed
	clock-names = "can_core", "can_host", "can", "pllaon"; // changed
	resets = <0x5 0x5>;
	reset-names = "can";
	mram-params = <0x0 0x10 0x10 0x20 0x0 0x0 0x10 0x10 0x10>;
	tx-config = <0x0 0x10 0x0 0x40>;
	rx-config = <0x40 0x40 0x40>;
	status = "okay";
	linux,phandle = <0x188>;
	phandle = <0x188>;
};
...
clocks-init {
	compatible = "nvidia,clocks-config";
	status = "okay";
	disable {
		clocks = <0x4 0x9 0x4 0xb>; // changed
	};
};
...

Remove the “.dtb” files and recompile them from the sources with:

dtc -I dts -O dtb tegra194-p2888-0001-p2822-0000.dts -o tegra194-p2888-0001-p2822-0000.dtb
dtc -I dts -O dtb tegra194-a02-bpmp-p2888-a04.dts -o tegra194-a02-bpmp-p2888-a04.dtb

I have uploaded my dtb files here: working_dtb_mttcan_pllaon_4.6.zip (225.3 KB)

Then replace the existing file “tegra194-p2888-0001-p2822-0000.dtb” in the “kernel/dtb” folder and “tegra194-a02-bpmp-p2888-a04.dtb” in the “bootloader/t186ref”

Then flash the jetson with the command:
sudo ./flash.sh jetson-agx-xavier-devkit mmcblk0p1

Once it is done, setup the ubuntu (language, keyboard etc…)

Then to use the CAN, type as root using sudo:

busybox devmem 0x0c303000 32 0x0000c400
busybox devmem 0x0c303008 32 0x0000c458
busybox devmem 0x0c303010 32 0x0000c400
busybox devmem 0x0c303018 32 0x0000c458

modprobe can
modprobe can_raw
modprobe mttcan

ip link set can0 type can bitrate 500000 dbitrate 2000000 berr-reporting on fd on 
ip link set can1 type can bitrate 500000 dbitrate 2000000 berr-reporting on fd on 
ip link set up can0
ip link set up can1

And then once you connected the CAN transceiver to the correct pins, it works.

I hope it can help someone.

Glad to know you resolved the problem, thanks for the update!