AnsweredAssumed Answered

Increasing CAN clock frequency of i.MX6 on kernel 3.10

Question asked by Isaac Nickaein on May 5, 2015
Latest reply on Jan 11, 2016 by Isaac Nickaein

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:

 

clk_set_rate(&can_clk_root, 60000000);

 

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.

Outcomes