xref: /linux/drivers/net/can/flexcan/flexcan.h (revision 1a9239bb4253f9076b5b4b2a1a4e8d7defd77a95)
1 /* SPDX-License-Identifier: GPL-2.0
2  * flexcan.c - FLEXCAN CAN controller driver
3  *
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>
9  *
10  * Based on code originally by Andrey Volkov <avolkov@varma-el.com>
11  *
12  */
13 
14 #ifndef _FLEXCAN_H
15 #define _FLEXCAN_H
16 
17 #include <linux/can/rx-offload.h>
18 
19 /* FLEXCAN hardware feature flags
20  *
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
35  *
36  * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
37  */
38 
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)
71 /* Setup stop mode with ATF SCMI protocol to support wakeup */
72 #define FLEXCAN_QUIRK_SETUP_STOP_MODE_SCMI BIT(17)
73 /* Device has two separate interrupt lines for two mailbox ranges, which
74  * both need to have an interrupt handler registered.
75  */
76 #define FLEXCAN_QUIRK_SECONDARY_MB_IRQ	BIT(18)
77 
78 struct flexcan_devtype_data {
79 	u32 quirks;		/* quirks needed for different IP cores */
80 };
81 
82 struct flexcan_stop_mode {
83 	struct regmap *gpr;
84 	u8 req_gpr;
85 	u8 req_bit;
86 };
87 
88 struct flexcan_priv {
89 	struct can_priv can;
90 	struct can_rx_offload offload;
91 	struct device *dev;
92 
93 	struct flexcan_regs __iomem *regs;
94 	struct flexcan_mb __iomem *tx_mb;
95 	struct flexcan_mb __iomem *tx_mb_reserved;
96 	u8 tx_mb_idx;
97 	u8 mb_count;
98 	u8 mb_size;
99 	u8 clk_src;	/* clock source of CAN Protocol Engine */
100 	u8 scu_idx;
101 
102 	u64 rx_mask;
103 	u64 tx_mask;
104 	u32 reg_ctrl_default;
105 
106 	struct clk *clk_ipg;
107 	struct clk *clk_per;
108 	struct flexcan_devtype_data devtype_data;
109 	struct regulator *reg_xceiver;
110 	struct phy *transceiver;
111 	struct flexcan_stop_mode stm;
112 
113 	int irq_boff;
114 	int irq_err;
115 	int irq_secondary_mb;
116 
117 	/* IPC handle when setup stop mode by System Controller firmware(scfw) */
118 	struct imx_sc_ipc *sc_ipc_handle;
119 
120 	/* Read and Write APIs */
121 	u32 (*read)(void __iomem *addr);
122 	void (*write)(u32 val, void __iomem *addr);
123 };
124 
125 extern const struct ethtool_ops flexcan_ethtool_ops;
126 
127 static inline bool
flexcan_supports_rx_mailbox(const struct flexcan_priv * priv)128 flexcan_supports_rx_mailbox(const struct flexcan_priv *priv)
129 {
130 	const u32 quirks = priv->devtype_data.quirks;
131 
132 	return quirks & FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX;
133 }
134 
135 static inline bool
flexcan_supports_rx_mailbox_rtr(const struct flexcan_priv * priv)136 flexcan_supports_rx_mailbox_rtr(const struct flexcan_priv *priv)
137 {
138 	const u32 quirks = priv->devtype_data.quirks;
139 
140 	return (quirks & (FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX |
141 			  FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR)) ==
142 		(FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX |
143 		 FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR);
144 }
145 
146 static inline bool
flexcan_supports_rx_fifo(const struct flexcan_priv * priv)147 flexcan_supports_rx_fifo(const struct flexcan_priv *priv)
148 {
149 	const u32 quirks = priv->devtype_data.quirks;
150 
151 	return quirks & FLEXCAN_QUIRK_SUPPORT_RX_FIFO;
152 }
153 
154 static inline bool
flexcan_active_rx_rtr(const struct flexcan_priv * priv)155 flexcan_active_rx_rtr(const struct flexcan_priv *priv)
156 {
157 	const u32 quirks = priv->devtype_data.quirks;
158 
159 	if (quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) {
160 		if (quirks & FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR)
161 			return true;
162 	} else {
163 		/*  RX-FIFO is always RTR capable */
164 		return true;
165 	}
166 
167 	return false;
168 }
169 
170 
171 #endif /* _FLEXCAN_H */
172