diff options
author | Marek Vasut <marex@denx.de> | 2016-09-19 15:34:01 -0400 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2016-09-21 04:32:24 -0400 |
commit | 8d58790b832e13d6006d842037732304af357c3c (patch) | |
tree | 959472dcb010b91b1c72accdfdfbe7ace34fb379 | |
parent | b5036cd4ed3173ab8cdbc85e2ba74acf46bafb51 (diff) |
net: can: ifi: Configure transmitter delay
Configure the transmitter delay register at +0x1c to correctly handle
the CAN FD bitrate switch (BRS). This moves the SSP (secondary sample
point) to a proper offset, so that the TDC mechanism works and won't
generate error frames on the CAN link.
Signed-off-by: Marek Vasut <marex@denx.de>
Cc: Marc Kleine-Budde <mkl@pengutronix.de>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Oliver Hartkopp <socketcan@hartkopp.net>
Cc: Wolfgang Grandegger <wg@grandegger.com>
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
-rw-r--r-- | drivers/net/can/ifi_canfd/ifi_canfd.c | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/net/can/ifi_canfd/ifi_canfd.c b/drivers/net/can/ifi_canfd/ifi_canfd.c index 2d1d22eec750..368bb0710d8f 100644 --- a/drivers/net/can/ifi_canfd/ifi_canfd.c +++ b/drivers/net/can/ifi_canfd/ifi_canfd.c | |||
@@ -81,6 +81,10 @@ | |||
81 | #define IFI_CANFD_TIME_SET_TIMEA_4_12_6_6 BIT(15) | 81 | #define IFI_CANFD_TIME_SET_TIMEA_4_12_6_6 BIT(15) |
82 | 82 | ||
83 | #define IFI_CANFD_TDELAY 0x1c | 83 | #define IFI_CANFD_TDELAY 0x1c |
84 | #define IFI_CANFD_TDELAY_DEFAULT 0xb | ||
85 | #define IFI_CANFD_TDELAY_MASK 0x3fff | ||
86 | #define IFI_CANFD_TDELAY_ABS BIT(14) | ||
87 | #define IFI_CANFD_TDELAY_EN BIT(15) | ||
84 | 88 | ||
85 | #define IFI_CANFD_ERROR 0x20 | 89 | #define IFI_CANFD_ERROR 0x20 |
86 | #define IFI_CANFD_ERROR_TX_OFFSET 0 | 90 | #define IFI_CANFD_ERROR_TX_OFFSET 0 |
@@ -641,7 +645,7 @@ static void ifi_canfd_set_bittiming(struct net_device *ndev) | |||
641 | struct ifi_canfd_priv *priv = netdev_priv(ndev); | 645 | struct ifi_canfd_priv *priv = netdev_priv(ndev); |
642 | const struct can_bittiming *bt = &priv->can.bittiming; | 646 | const struct can_bittiming *bt = &priv->can.bittiming; |
643 | const struct can_bittiming *dbt = &priv->can.data_bittiming; | 647 | const struct can_bittiming *dbt = &priv->can.data_bittiming; |
644 | u16 brp, sjw, tseg1, tseg2; | 648 | u16 brp, sjw, tseg1, tseg2, tdc; |
645 | 649 | ||
646 | /* Configure bit timing */ | 650 | /* Configure bit timing */ |
647 | brp = bt->brp - 2; | 651 | brp = bt->brp - 2; |
@@ -664,6 +668,11 @@ static void ifi_canfd_set_bittiming(struct net_device *ndev) | |||
664 | (brp << IFI_CANFD_TIME_PRESCALE_OFF) | | 668 | (brp << IFI_CANFD_TIME_PRESCALE_OFF) | |
665 | (sjw << IFI_CANFD_TIME_SJW_OFF_7_9_8_8), | 669 | (sjw << IFI_CANFD_TIME_SJW_OFF_7_9_8_8), |
666 | priv->base + IFI_CANFD_FTIME); | 670 | priv->base + IFI_CANFD_FTIME); |
671 | |||
672 | /* Configure transmitter delay */ | ||
673 | tdc = (dbt->brp * (dbt->phase_seg1 + 1)) & IFI_CANFD_TDELAY_MASK; | ||
674 | writel(IFI_CANFD_TDELAY_EN | IFI_CANFD_TDELAY_ABS | tdc, | ||
675 | priv->base + IFI_CANFD_TDELAY); | ||
667 | } | 676 | } |
668 | 677 | ||
669 | static void ifi_canfd_set_filter(struct net_device *ndev, const u32 id, | 678 | static void ifi_canfd_set_filter(struct net_device *ndev, const u32 id, |