summaryrefslogtreecommitdiff
path: root/drivers/net/can/spi/mcp25xxfd
diff options
context:
space:
mode:
authorRafael Beims <rafael.beims@toradex.com>2022-01-18 13:12:09 -0300
committerRafael Beims <rafael.beims@toradex.com>2022-01-26 09:53:11 -0300
commit655f52684c76b08915d1c6a361328b76888262a0 (patch)
treec4c7aa9ded05de05ceef8cd3f04d1be7d403f5cd /drivers/net/can/spi/mcp25xxfd
parentc890f227a02983865d985211e5498791287d7d8d (diff)
can: mcp25xxfd: Fix failure to probe driver when bus occupation is high
The mcp2518fd chip needs to detect a bus idle condition before changing modes. In conditions where the bus load is high (> 50%), the mode switch can fail. If this happens during initialization, the driver fails to probe. The problem is that the default bit timing configurations are done for 500kbps bus rate with a SYSCLK of 40MHz. If the bus that the device is connected to is configured at a higher bitrate and is loaded, it can be that we are not able to detect a sufficiently large number of "1" bits in order to say that the bus is idle. This commit changes the bit timing before changing modes so that the mcp2518fd is prepared to detect a bus idle condition even at the highest bus rate that would be allowed. Co-authored-by: Edward Karpicz <e.karpic@ekspla.com> Signed-off-by: Edward Karpicz <e.karpic@ekspla.com> Signed-off-by: Rafael Beims <rafael.beims@toradex.com>
Diffstat (limited to 'drivers/net/can/spi/mcp25xxfd')
-rw-r--r--drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can.c b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can.c
index e8b0fe79309d..5029775009af 100644
--- a/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can.c
+++ b/drivers/net/can/spi/mcp25xxfd/mcp25xxfd_can.c
@@ -351,8 +351,25 @@ int mcp25xxfd_can_probe(struct mcp25xxfd_priv *priv)
/* so if we are in config mode then everything is fine
* and we check that a mode switch works propperly
*/
- if (mode == MCP25XXFD_CAN_CON_MODE_CONFIG)
+ if (mode == MCP25XXFD_CAN_CON_MODE_CONFIG) {
+ /* all mode switches require bus idle condition. Power on default bit rate setting is about
+ * 500kbps @ 40MHz. This is OK for all real bus speeds up to 500kbps and SYSCLK=40MHz. But
+ * probe may fail when real bus speed is 1Mbps and bus load is high (>50%). As well
+ * probe may fail with SYSCLK=20MHz and high bus load on 500kbps bus.
+ * Switching to >=1Mbps bitrate @ 20MHz to avoid this issue for SYSCLK>=20MHz and
+ * all standard arbitration bitrates */
+ ret = mcp25xxfd_cmd_write(spi, MCP25XXFD_CAN_NBTCFG, (0 << MCP25XXFD_CAN_NBTCFG_BRP_SHIFT) |
+ (13 << MCP25XXFD_CAN_NBTCFG_TSEG1_SHIFT) |
+ (4 << MCP25XXFD_CAN_NBTCFG_TSEG2_SHIFT) |
+ (1 << MCP25XXFD_CAN_NBTCFG_SJW_SHIFT));
+
+ if (ret)
+ return ret;
+
return mcp25xxfd_can_probe_modeswitch(priv);
+ } else {
+ dev_warn(&spi->dev, "Not in CONFIG mode.\n");
+ }
/* if the bitfield is 0 then there is something is wrong */
if (!mode_data) {