aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarek Vasut <marex@denx.de>2016-09-19 15:34:01 -0400
committerMarc Kleine-Budde <mkl@pengutronix.de>2016-09-21 04:32:24 -0400
commit8d58790b832e13d6006d842037732304af357c3c (patch)
tree959472dcb010b91b1c72accdfdfbe7ace34fb379
parentb5036cd4ed3173ab8cdbc85e2ba74acf46bafb51 (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.c11
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
669static void ifi_canfd_set_filter(struct net_device *ndev, const u32 id, 678static void ifi_canfd_set_filter(struct net_device *ndev, const u32 id,