> br_clksrc=osc
That only works on an i.MX35 board, and not on an i.MX53.
The driver happily assumes it is running on an i.MX35, and selects either the 66.5MHz bus clock or the 24.576MHz oscillator. Good luck trying to divide 24.576 down to any normal CAN baud rate with the required fractional-percent baud rate accuracy though.
On an i.MX53, the clock is - tricky. In the Reference Manual, bit FLEXCANx_CTRL[13] is called "-", marked "Reserved", but confusingly says it selects the 66.5 or 24.576 MHz clocks. It doesn't. That section was pasted in out of the i.MX35 manual and not properly edited. The Flexcan baud rate clock selection is handled in the i.MX53 by CCM_CSCMR2[CAN_CLK_SEL].
That, as you found, is set up by getting the platform to select the 24MHz "lp_apm" clock.
There are plenty of other problems with the documentation and the driver.
The "mx53_linux.pdf" document states:
bitrate configures the bitrate. Currenlty, [sic] this parameter only shows the bitrate that is supported.
To ensure bitrate exactly, set the individual parameters:
The driver in drivers/net/can/flexcan/dev.c has the comment:
static void flexcan_set_bitrate(struct flexcan_device *flexcan, int bitrate)
{
/* TODO:: implement in future
* based on the bitrate to get the timing of
* presdiv, pseg1, pseg2, propseg
*/
The following commit added all the code to set the bit rate, but then left the above comment in the code!
Author: William Lai <b04597@freescale.com> 2010-04-21 12:20:44
Committer: William Lai <b04597@freescale.com> 2010-04-22 17:10:20
Parent: e783aee7a0b858727595a1416e901dee08e96bc2 (ENGR00122399-2 MX53 CAN: MBM word access only)
Branches: remotes/origin/remote/freescale/imx_2.6.31, remotes/origin/remote/freescale/imx_2.6.31_10.05.02,
remotes/origin/remote/freescale/imx_2.6.31_10.07.11, remotes/origin/remote/freescale/imx_2.6.31_10.08.01
Follows: rel_imx_2.6.31_10.03.00
Precedes: rel-imx-2.6.31-10.08.00, rel_imx_2.6.31_10.05.02, rel_imx_2.6.31_10.07.11
ENGR00122723 CAN: Enable the adaptive bitrate setting
Enable the adaptive bitrate setting, according to the clock rate.
And the bitrate can be changed by the proc file.
The above change was made in 2.6.31, earlier and 5 months before "mx53_linux.pdf" stated that 2.6.35.3 didn't support setting the bitrate when it does.
There's a bug in the driver in its reporting of the RJW as well. Here's the setting and reporting code. Spot the difference:
static ssize_t flexcan_set_attr(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
{
...
case FLEXCAN_ATTR_BR_RJW:
flexcan->br_rjw = tmp - 1;
case FLEXCAN_ATTR_BR_PROPSEG:
flexcan->br_propseg = tmp - 1;
case FLEXCAN_ATTR_BR_PSEG1:
flexcan->br_pseg1 = tmp - 1;
case FLEXCAN_ATTR_BR_PSEG2:
flexcan->br_pseg2 = tmp - 1;
static ssize_t flexcan_show_attr(struct device *dev,
struct device_attribute *attr, char *buf)
{
...
case FLEXCAN_ATTR_BR_PRESDIV:
return sprintf(buf, "%d\n", flexcan->br_presdiv + 1);
case FLEXCAN_ATTR_BR_RJW:
return sprintf(buf, "%d\n", flexcan->br_rjw);
case FLEXCAN_ATTR_BR_PROPSEG:
return sprintf(buf, "%d\n", flexcan->br_propseg + 1);
case FLEXCAN_ATTR_BR_PSEG1:
return sprintf(buf, "%d\n", flexcan->br_pseg1 + 1);
case FLEXCAN_ATTR_BR_PSEG2:
return sprintf(buf, "%d\n", flexcan->br_pseg2 + 1);
It sets the RJW properly, but forgets to add one to the field when printing it.
Tom