1 /* SPDX-License-Identifier: GPL-2.0
2 * flexcan.c - FLEXCAN CAN controller driver
4 * Copyright (c) 2005-2006 Varma Electronics Oy
5 * Copyright (c) 2009 Sascha Hauer, Pengutronix
6 * Copyright (c) 2010-2017 Pengutronix, Marc Kleine-Budde <kernel@pengutronix.de>
7 * Copyright (c) 2014 David Jander, Protonic Holland
8 * Copyright (C) 2022 Amarula Solutions, Dario Binacchi <dario.binacchi@amarulasolutions.com>
10 * Based on code originally by Andrey Volkov <avolkov@varma-el.com>
17 #include <linux/can/rx-offload.h>
19 /* FLEXCAN hardware feature flags
21 * Below is some version info we got:
22 * SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR rece- FD Mode MB
23 * Filter? connected? Passive detection ption in MB Supported?
24 * MCF5441X FlexCAN2 ? no yes no no no no 16
25 * MX25 FlexCAN2 03.00.00.00 no no no no no no 64
26 * MX28 FlexCAN2 03.00.04.00 yes yes no no no no 64
27 * MX35 FlexCAN2 03.00.00.00 no no no no no no 64
28 * MX53 FlexCAN2 03.00.00.00 yes no no no no no 64
29 * MX6s FlexCAN3 10.00.12.00 yes yes no no yes no 64
30 * MX8QM FlexCAN3 03.00.23.00 yes yes no no yes yes 64
31 * MX8MP FlexCAN3 03.00.17.01 yes yes no yes yes yes 64
32 * VF610 FlexCAN3 ? no yes no yes yes? no 64
33 * LS1021A FlexCAN2 03.00.04.00 no yes no no yes no 64
34 * LX2160A FlexCAN3 03.00.23.00 no yes no yes yes yes 64
36 * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
39 /* [TR]WRN_INT not connected */
40 #define FLEXCAN_QUIRK_BROKEN_WERR_STATE BIT(1)
41 /* Disable RX FIFO Global mask */
42 #define FLEXCAN_QUIRK_DISABLE_RXFG BIT(2)
43 /* Enable EACEN and RRS bit in ctrl2 */
44 #define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3)
45 /* Disable non-correctable errors interrupt and freeze mode */
46 #define FLEXCAN_QUIRK_DISABLE_MECR BIT(4)
47 /* Use mailboxes (not FIFO) for RX path */
48 #define FLEXCAN_QUIRK_USE_RX_MAILBOX BIT(5)
49 /* No interrupt for error passive */
50 #define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6)
51 /* default to BE register access */
52 #define FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN BIT(7)
53 /* Setup stop mode with GPR to support wakeup */
54 #define FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR BIT(8)
55 /* Support CAN-FD mode */
56 #define FLEXCAN_QUIRK_SUPPORT_FD BIT(9)
57 /* support memory detection and correction */
58 #define FLEXCAN_QUIRK_SUPPORT_ECC BIT(10)
59 /* Setup stop mode with SCU firmware to support wakeup */
60 #define FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW BIT(11)
61 /* Setup 3 separate interrupts, main, boff and err */
62 #define FLEXCAN_QUIRK_NR_IRQ_3 BIT(12)
63 /* Setup 16 mailboxes */
64 #define FLEXCAN_QUIRK_NR_MB_16 BIT(13)
65 /* Device supports RX via mailboxes */
66 #define FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX BIT(14)
67 /* Device supports RTR reception via mailboxes */
68 #define FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR BIT(15)
69 /* Device supports RX via FIFO */
70 #define FLEXCAN_QUIRK_SUPPORT_RX_FIFO BIT(16)
72 struct flexcan_devtype_data {
73 u32 quirks; /* quirks needed for different IP cores */
76 struct flexcan_stop_mode {
84 struct can_rx_offload offload;
87 struct flexcan_regs __iomem *regs;
88 struct flexcan_mb __iomem *tx_mb;
89 struct flexcan_mb __iomem *tx_mb_reserved;
93 u8 clk_src; /* clock source of CAN Protocol Engine */
102 struct flexcan_devtype_data devtype_data;
103 struct regulator *reg_xceiver;
104 struct flexcan_stop_mode stm;
109 /* IPC handle when setup stop mode by System Controller firmware(scfw) */
110 struct imx_sc_ipc *sc_ipc_handle;
112 /* Read and Write APIs */
113 u32 (*read)(void __iomem *addr);
114 void (*write)(u32 val, void __iomem *addr);
117 extern const struct ethtool_ops flexcan_ethtool_ops;
120 flexcan_supports_rx_mailbox(const struct flexcan_priv *priv)
122 const u32 quirks = priv->devtype_data.quirks;
124 return quirks & FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX;
128 flexcan_supports_rx_mailbox_rtr(const struct flexcan_priv *priv)
130 const u32 quirks = priv->devtype_data.quirks;
132 return (quirks & (FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX |
133 FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR)) ==
134 (FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX |
135 FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR);
139 flexcan_supports_rx_fifo(const struct flexcan_priv *priv)
141 const u32 quirks = priv->devtype_data.quirks;
143 return quirks & FLEXCAN_QUIRK_SUPPORT_RX_FIFO;
147 flexcan_active_rx_rtr(const struct flexcan_priv *priv)
149 const u32 quirks = priv->devtype_data.quirks;
151 if (quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) {
152 if (quirks & FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR)
155 /* RX-FIFO is always RTR capable */
163 #endif /* _FLEXCAN_H */