aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can/m_can
diff options
context:
space:
mode:
authorFranklin S Cooper Jr <fcooper@ti.com>2018-01-16 06:37:14 -0500
committerMarc Kleine-Budde <mkl@pengutronix.de>2018-01-16 09:11:33 -0500
commite759c626d826649cf393da34cd59656d08afb52d (patch)
tree84009a7311597a0a4bb6255d1ea2aa5f99bd2b87 /drivers/net/can/m_can
parentb54f9eea7667b3011e6c7e646051c7a7bfcd8165 (diff)
can: m_can: Support higher speed CAN-FD bitrates
During test transmitting using CAN-FD at high bitrates (> 2 Mbps) would fail. Scoping the signals I noticed that only a single bit was being transmitted and with a bit more investigation realized the actual MCAN IP would go back to initialization mode automatically. It appears this issue is due to the MCAN needing to use the Transmitter Delay Compensation Mode with the correct value for the transmitter delay compensation offset (tdco). What impacts the tdco value isn't 100% clear but to calculate it you use an equation defined in the MCAN User's Guide. The user guide mentions that this register needs to be set based on clock values, secondary sample point and the data bitrate. One of the key variables that can't automatically be determined is the secondary sample point (ssp). This ssp is similar to the sp but is specific to this transmitter delay compensation mode. The guidelines for configuring ssp is rather vague but via some CAN test it appears for DRA76x that putting the value same as data sampling point works. The CAN-CIA's "Bit Time Requirements for CAN FD" paper presented at the International CAN Conference 2013 indicates that this TDC mode is only needed for data bit rates above 2.5 Mbps. Therefore, only enable this mode when the data bit rate is above 2.5 Mbps. Signed-off-by: Franklin S Cooper Jr <fcooper@ti.com> Signed-off-by: Sekhar Nori <nsekhar@ti.com> Signed-off-by: Faiz Abbas <faiz_abbas@ti.com> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can/m_can')
-rw-r--r--drivers/net/can/m_can/m_can.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
index f4947a74b65f..79dd3c36ea32 100644
--- a/drivers/net/can/m_can/m_can.c
+++ b/drivers/net/can/m_can/m_can.c
@@ -126,6 +126,12 @@ enum m_can_mram_cfg {
126#define DBTP_DSJW_SHIFT 0 126#define DBTP_DSJW_SHIFT 0
127#define DBTP_DSJW_MASK (0xf << DBTP_DSJW_SHIFT) 127#define DBTP_DSJW_MASK (0xf << DBTP_DSJW_SHIFT)
128 128
129/* Transmitter Delay Compensation Register (TDCR) */
130#define TDCR_TDCO_SHIFT 8
131#define TDCR_TDCO_MASK (0x7F << TDCR_TDCO_SHIFT)
132#define TDCR_TDCF_SHIFT 0
133#define TDCR_TDCF_MASK (0x7F << TDCR_TDCF_SHIFT)
134
129/* Test Register (TEST) */ 135/* Test Register (TEST) */
130#define TEST_LBCK BIT(4) 136#define TEST_LBCK BIT(4)
131 137
@@ -987,13 +993,47 @@ static int m_can_set_bittiming(struct net_device *dev)
987 m_can_write(priv, M_CAN_NBTP, reg_btp); 993 m_can_write(priv, M_CAN_NBTP, reg_btp);
988 994
989 if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { 995 if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
996 reg_btp = 0;
990 brp = dbt->brp - 1; 997 brp = dbt->brp - 1;
991 sjw = dbt->sjw - 1; 998 sjw = dbt->sjw - 1;
992 tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1; 999 tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1;
993 tseg2 = dbt->phase_seg2 - 1; 1000 tseg2 = dbt->phase_seg2 - 1;
994 reg_btp = (brp << DBTP_DBRP_SHIFT) | (sjw << DBTP_DSJW_SHIFT) | 1001
995 (tseg1 << DBTP_DTSEG1_SHIFT) | 1002 /* TDC is only needed for bitrates beyond 2.5 MBit/s.
996 (tseg2 << DBTP_DTSEG2_SHIFT); 1003 * This is mentioned in the "Bit Time Requirements for CAN FD"
1004 * paper presented at the International CAN Conference 2013
1005 */
1006 if (dbt->bitrate > 2500000) {
1007 u32 tdco, ssp;
1008
1009 /* Use the same value of secondary sampling point
1010 * as the data sampling point
1011 */
1012 ssp = dbt->sample_point;
1013
1014 /* Equation based on Bosch's M_CAN User Manual's
1015 * Transmitter Delay Compensation Section
1016 */
1017 tdco = (priv->can.clock.freq / 1000) *
1018 ssp / dbt->bitrate;
1019
1020 /* Max valid TDCO value is 127 */
1021 if (tdco > 127) {
1022 netdev_warn(dev, "TDCO value of %u is beyond maximum. Using maximum possible value\n",
1023 tdco);
1024 tdco = 127;
1025 }
1026
1027 reg_btp |= DBTP_TDC;
1028 m_can_write(priv, M_CAN_TDCR,
1029 tdco << TDCR_TDCO_SHIFT);
1030 }
1031
1032 reg_btp |= (brp << DBTP_DBRP_SHIFT) |
1033 (sjw << DBTP_DSJW_SHIFT) |
1034 (tseg1 << DBTP_DTSEG1_SHIFT) |
1035 (tseg2 << DBTP_DTSEG2_SHIFT);
1036
997 m_can_write(priv, M_CAN_DBTP, reg_btp); 1037 m_can_write(priv, M_CAN_DBTP, reg_btp);
998 } 1038 }
999 1039