How to change CAN clock frequency (or source) on Jetson TX2?

I want to use CAN to communicate with other device. Jetson TX2 CAN1 uses 40 MHz clock:
sudo cat /sys/kernel/debug/clk/clk_summary |grep can can2 2 2 40000000 40000000 0 0 can2_host 1 1 40000000 38400000 0 0 can1 2 2 40000000 40000000 0 0 can1_host 1 1 40000000 38400000 0 0
But device uses 42 MHz clock and specified CAN setting which can not be changed.
When clock on this device is changed to 40Mhz (only for debug) everything (whole communication) works OK, but when clock freq is changed back to 42MHz it stops working.

How to change CAN1 (or CAN0) clock freq to 42 MHZ (or any other frequency)??

I have found that freq is stored in struct in module: m_ttcan_linux.c:

static const struct tegra_mttcan_soc_info t186_mttcan_sinfo = {
	.set_can_core_clk = false,
	.can_core_clk_rate = 40000000,
	.can_clk_rate = 40000000,
	.use_external_timer = false,

but changing this gives no effect.
I also tried to change it with command:

 echo 42000000 > /sys/kernel/debug/clk/can1/clk_rate bash: echo: write error: Permission denied

CAN settings:

 ip -details link show can1
10: can1: <NOARP,UP,LOWER_UP,ECHO> mtu 16 qdisc pfifo_fast state UNKNOWN mode DEFAULT group default qlen 10
    link/can  promiscuity 0 
    can state ERROR-ACTIVE (berr-counter tx 0 rx 127) restart-ms 0 
	  bitrate 952380 sample-point 0.761 
	  tq 47 prop-seg 8 phase-seg1 7 phase-seg2 5 sjw 1
	  mttcan: tseg1 2..255 tseg2 0..127 sjw 1..127 brp 1..511 brp-inc 1
	  mttcan: dtseg1 1..31 dtseg2 0..15 dsjw 1..15 dbrp 1..15 dbrp-inc 1
	  clock 40000000numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535 

L4T R32.2.3

I think it should be changed it device tree, but for now I do not see place where to do this modification.


This is the community feedback forum, I am moving this to the Jetson TX2 forum for you.

1 Like

Yes clock needs to be changed in source code in mttcan driver as mentioned by you.
static const struct tegra_mttcan_soc_info t186_mttcan_sinfo = {
.set_can_core_clk = false,
.can_core_clk_rate = 42000000,
.can_clk_rate = 42000000,
.use_external_timer = false,
recompile the driver with the change and reboot the device. But clock will not set to 42MHz as it is not divisible by 480MHz pll_aon clock frequency so there will be drift in final CAN clock rate.

Thanks for answer shgarg,
So thats why after changing this freq in driver to 42MHz I have still seen 40MHz in CAN settings?
I have to change it to 48MHz (for example) and just replace a *.ko file, then reload module (modprob mttcan) and frequency will be 48MHz?

Can I change a clock source and use different clock which can achieve 42MHz rate?

Sorry for the late response.
Yes, if you change freq in driver to 48MHz, reload driver, it should be changed. You can change parent clock source from pll_aon to others (Ex pll_p_out0 (Freq: 408MHz)) But again, to match exact 42MHz is tricky based on parent clock frequency and divisor value.
Let me know if you need anything else.