I am trying to configure CAN interface of i.MX6 to work at the bitrate of 800Kb/s in Kernel 3.10.53. The default clock frequency of CAN driver is 30Mhz which causes bitrate error of 1.3%:
#canconfig can1 bitrate 800000
can1 bitrate: 789473, sample-point: 0.789
flexcan 2094000.flexcan can1: bitrate error 1.3%
More details on this issue and what I have tried comes in the following:
To solve this issue, I have to increase the clock frequency of CAN to be a multiple of 800Khz (I guess?). It seems the clock setup for i.MX6 is done in arch/arm/mach-imx/clk-imx6q.c. The lines related to CAN clock are:
clk[can_root] = imx_clk_divider("can_root", "pll3_60m", base + 0x20, 2, 6);
clk[can1_ipg] = imx_clk_gate2("can1_ipg", "ipg", base + 0x68, 14);
clk[can1_serial] = imx_clk_gate2("can1_serial", "can_root", base + 0x68, 16);
clk[can2_ipg] = imx_clk_gate2("can2_ipg", "ipg", base + 0x68, 18);
clk[can2_serial] = imx_clk_gate2("can2_serial", "can_root", base + 0x68, 20);
One solution I came up with was to change the settings for can_root clock from pll3_60m to pll3_120m. With this change, the canconfig will report the correct bitrate (800Kb instead of ~789Kb) and there is no warning about bitrate error. HOWEVER, the i.MX6 still cannot receive any can packets and goes to BUS-OFF mode.
This result is very similar to what I got in kernel 3.0.35 before, when I did the similar thing in arch/arm/clock.c file. I guess I am missing some architectural limitation in i.MX6 clocking that causes this solution to fail.
What we ended up in kernel 3.0.35 was to set the clock rate explicitly during initialization by:
This hack solved the issue and i.MX6 could send and receive CAN packets on 800Kb/s successfully.
I am looking for the right approach to increase CAN clock frequency to support 800Kb/s on Kernel 3.10, or a similar hack for this kernel.