Commit | Line | Data |
---|---|---|
875347fe MKB |
1 | /* SPDX-License-Identifier: GPL-2.0 |
2 | * | |
eb79a267 | 3 | * mcp251xfd - Microchip MCP251xFD Family CAN controller driver |
875347fe | 4 | * |
e793c724 | 5 | * Copyright (c) 2019, 2020, 2021, 2023 Pengutronix, |
2a68dd86 | 6 | * Marc Kleine-Budde <kernel@pengutronix.de> |
875347fe MKB |
7 | * Copyright (c) 2019 Martin Sperl <kernel@martin.sperl.org> |
8 | */ | |
9 | ||
eb79a267 MKB |
10 | #ifndef _MCP251XFD_H |
11 | #define _MCP251XFD_H | |
875347fe | 12 | |
1e846c7a | 13 | #include <linux/bitfield.h> |
875347fe MKB |
14 | #include <linux/can/core.h> |
15 | #include <linux/can/dev.h> | |
16 | #include <linux/can/rx-offload.h> | |
17 | #include <linux/gpio/consumer.h> | |
18 | #include <linux/kernel.h> | |
ae2e9940 | 19 | #include <linux/netdevice.h> |
875347fe MKB |
20 | #include <linux/regmap.h> |
21 | #include <linux/regulator/consumer.h> | |
22 | #include <linux/spi/spi.h> | |
efd8d98d MKB |
23 | #include <linux/timecounter.h> |
24 | #include <linux/workqueue.h> | |
875347fe | 25 | |
eb79a267 | 26 | /* MPC251x registers */ |
875347fe MKB |
27 | |
28 | /* CAN FD Controller Module SFR */ | |
eb79a267 MKB |
29 | #define MCP251XFD_REG_CON 0x00 |
30 | #define MCP251XFD_REG_CON_TXBWS_MASK GENMASK(31, 28) | |
31 | #define MCP251XFD_REG_CON_ABAT BIT(27) | |
32 | #define MCP251XFD_REG_CON_REQOP_MASK GENMASK(26, 24) | |
33 | #define MCP251XFD_REG_CON_MODE_MIXED 0 | |
34 | #define MCP251XFD_REG_CON_MODE_SLEEP 1 | |
35 | #define MCP251XFD_REG_CON_MODE_INT_LOOPBACK 2 | |
36 | #define MCP251XFD_REG_CON_MODE_LISTENONLY 3 | |
37 | #define MCP251XFD_REG_CON_MODE_CONFIG 4 | |
38 | #define MCP251XFD_REG_CON_MODE_EXT_LOOPBACK 5 | |
39 | #define MCP251XFD_REG_CON_MODE_CAN2_0 6 | |
40 | #define MCP251XFD_REG_CON_MODE_RESTRICTED 7 | |
41 | #define MCP251XFD_REG_CON_OPMOD_MASK GENMASK(23, 21) | |
42 | #define MCP251XFD_REG_CON_TXQEN BIT(20) | |
43 | #define MCP251XFD_REG_CON_STEF BIT(19) | |
44 | #define MCP251XFD_REG_CON_SERR2LOM BIT(18) | |
45 | #define MCP251XFD_REG_CON_ESIGM BIT(17) | |
46 | #define MCP251XFD_REG_CON_RTXAT BIT(16) | |
47 | #define MCP251XFD_REG_CON_BRSDIS BIT(12) | |
48 | #define MCP251XFD_REG_CON_BUSY BIT(11) | |
49 | #define MCP251XFD_REG_CON_WFT_MASK GENMASK(10, 9) | |
50 | #define MCP251XFD_REG_CON_WFT_T00FILTER 0x0 | |
51 | #define MCP251XFD_REG_CON_WFT_T01FILTER 0x1 | |
52 | #define MCP251XFD_REG_CON_WFT_T10FILTER 0x2 | |
53 | #define MCP251XFD_REG_CON_WFT_T11FILTER 0x3 | |
54 | #define MCP251XFD_REG_CON_WAKFIL BIT(8) | |
55 | #define MCP251XFD_REG_CON_PXEDIS BIT(6) | |
56 | #define MCP251XFD_REG_CON_ISOCRCEN BIT(5) | |
57 | #define MCP251XFD_REG_CON_DNCNT_MASK GENMASK(4, 0) | |
58 | ||
59 | #define MCP251XFD_REG_NBTCFG 0x04 | |
60 | #define MCP251XFD_REG_NBTCFG_BRP_MASK GENMASK(31, 24) | |
61 | #define MCP251XFD_REG_NBTCFG_TSEG1_MASK GENMASK(23, 16) | |
62 | #define MCP251XFD_REG_NBTCFG_TSEG2_MASK GENMASK(14, 8) | |
63 | #define MCP251XFD_REG_NBTCFG_SJW_MASK GENMASK(6, 0) | |
64 | ||
65 | #define MCP251XFD_REG_DBTCFG 0x08 | |
66 | #define MCP251XFD_REG_DBTCFG_BRP_MASK GENMASK(31, 24) | |
67 | #define MCP251XFD_REG_DBTCFG_TSEG1_MASK GENMASK(20, 16) | |
68 | #define MCP251XFD_REG_DBTCFG_TSEG2_MASK GENMASK(11, 8) | |
69 | #define MCP251XFD_REG_DBTCFG_SJW_MASK GENMASK(3, 0) | |
70 | ||
71 | #define MCP251XFD_REG_TDC 0x0c | |
72 | #define MCP251XFD_REG_TDC_EDGFLTEN BIT(25) | |
73 | #define MCP251XFD_REG_TDC_SID11EN BIT(24) | |
74 | #define MCP251XFD_REG_TDC_TDCMOD_MASK GENMASK(17, 16) | |
75 | #define MCP251XFD_REG_TDC_TDCMOD_AUTO 2 | |
76 | #define MCP251XFD_REG_TDC_TDCMOD_MANUAL 1 | |
77 | #define MCP251XFD_REG_TDC_TDCMOD_DISABLED 0 | |
78 | #define MCP251XFD_REG_TDC_TDCO_MASK GENMASK(14, 8) | |
79 | #define MCP251XFD_REG_TDC_TDCV_MASK GENMASK(5, 0) | |
80 | ||
81 | #define MCP251XFD_REG_TBC 0x10 | |
82 | ||
83 | #define MCP251XFD_REG_TSCON 0x14 | |
84 | #define MCP251XFD_REG_TSCON_TSRES BIT(18) | |
85 | #define MCP251XFD_REG_TSCON_TSEOF BIT(17) | |
86 | #define MCP251XFD_REG_TSCON_TBCEN BIT(16) | |
87 | #define MCP251XFD_REG_TSCON_TBCPRE_MASK GENMASK(9, 0) | |
88 | ||
89 | #define MCP251XFD_REG_VEC 0x18 | |
90 | #define MCP251XFD_REG_VEC_RXCODE_MASK GENMASK(30, 24) | |
91 | #define MCP251XFD_REG_VEC_TXCODE_MASK GENMASK(22, 16) | |
92 | #define MCP251XFD_REG_VEC_FILHIT_MASK GENMASK(12, 8) | |
93 | #define MCP251XFD_REG_VEC_ICODE_MASK GENMASK(6, 0) | |
94 | ||
95 | #define MCP251XFD_REG_INT 0x1c | |
96 | #define MCP251XFD_REG_INT_IF_MASK GENMASK(15, 0) | |
97 | #define MCP251XFD_REG_INT_IE_MASK GENMASK(31, 16) | |
98 | #define MCP251XFD_REG_INT_IVMIE BIT(31) | |
99 | #define MCP251XFD_REG_INT_WAKIE BIT(30) | |
100 | #define MCP251XFD_REG_INT_CERRIE BIT(29) | |
101 | #define MCP251XFD_REG_INT_SERRIE BIT(28) | |
102 | #define MCP251XFD_REG_INT_RXOVIE BIT(27) | |
103 | #define MCP251XFD_REG_INT_TXATIE BIT(26) | |
104 | #define MCP251XFD_REG_INT_SPICRCIE BIT(25) | |
105 | #define MCP251XFD_REG_INT_ECCIE BIT(24) | |
106 | #define MCP251XFD_REG_INT_TEFIE BIT(20) | |
107 | #define MCP251XFD_REG_INT_MODIE BIT(19) | |
108 | #define MCP251XFD_REG_INT_TBCIE BIT(18) | |
109 | #define MCP251XFD_REG_INT_RXIE BIT(17) | |
110 | #define MCP251XFD_REG_INT_TXIE BIT(16) | |
111 | #define MCP251XFD_REG_INT_IVMIF BIT(15) | |
112 | #define MCP251XFD_REG_INT_WAKIF BIT(14) | |
113 | #define MCP251XFD_REG_INT_CERRIF BIT(13) | |
114 | #define MCP251XFD_REG_INT_SERRIF BIT(12) | |
115 | #define MCP251XFD_REG_INT_RXOVIF BIT(11) | |
116 | #define MCP251XFD_REG_INT_TXATIF BIT(10) | |
117 | #define MCP251XFD_REG_INT_SPICRCIF BIT(9) | |
118 | #define MCP251XFD_REG_INT_ECCIF BIT(8) | |
119 | #define MCP251XFD_REG_INT_TEFIF BIT(4) | |
120 | #define MCP251XFD_REG_INT_MODIF BIT(3) | |
121 | #define MCP251XFD_REG_INT_TBCIF BIT(2) | |
122 | #define MCP251XFD_REG_INT_RXIF BIT(1) | |
123 | #define MCP251XFD_REG_INT_TXIF BIT(0) | |
875347fe | 124 | /* These IRQ flags must be cleared by SW in the CAN_INT register */ |
eb79a267 MKB |
125 | #define MCP251XFD_REG_INT_IF_CLEARABLE_MASK \ |
126 | (MCP251XFD_REG_INT_IVMIF | MCP251XFD_REG_INT_WAKIF | \ | |
127 | MCP251XFD_REG_INT_CERRIF | MCP251XFD_REG_INT_SERRIF | \ | |
128 | MCP251XFD_REG_INT_MODIF) | |
129 | ||
130 | #define MCP251XFD_REG_RXIF 0x20 | |
131 | #define MCP251XFD_REG_TXIF 0x24 | |
132 | #define MCP251XFD_REG_RXOVIF 0x28 | |
133 | #define MCP251XFD_REG_TXATIF 0x2c | |
134 | #define MCP251XFD_REG_TXREQ 0x30 | |
135 | ||
136 | #define MCP251XFD_REG_TREC 0x34 | |
137 | #define MCP251XFD_REG_TREC_TXBO BIT(21) | |
138 | #define MCP251XFD_REG_TREC_TXBP BIT(20) | |
139 | #define MCP251XFD_REG_TREC_RXBP BIT(19) | |
140 | #define MCP251XFD_REG_TREC_TXWARN BIT(18) | |
141 | #define MCP251XFD_REG_TREC_RXWARN BIT(17) | |
142 | #define MCP251XFD_REG_TREC_EWARN BIT(16) | |
143 | #define MCP251XFD_REG_TREC_TEC_MASK GENMASK(15, 8) | |
144 | #define MCP251XFD_REG_TREC_REC_MASK GENMASK(7, 0) | |
145 | ||
146 | #define MCP251XFD_REG_BDIAG0 0x38 | |
147 | #define MCP251XFD_REG_BDIAG0_DTERRCNT_MASK GENMASK(31, 24) | |
148 | #define MCP251XFD_REG_BDIAG0_DRERRCNT_MASK GENMASK(23, 16) | |
149 | #define MCP251XFD_REG_BDIAG0_NTERRCNT_MASK GENMASK(15, 8) | |
150 | #define MCP251XFD_REG_BDIAG0_NRERRCNT_MASK GENMASK(7, 0) | |
151 | ||
152 | #define MCP251XFD_REG_BDIAG1 0x3c | |
153 | #define MCP251XFD_REG_BDIAG1_DLCMM BIT(31) | |
154 | #define MCP251XFD_REG_BDIAG1_ESI BIT(30) | |
155 | #define MCP251XFD_REG_BDIAG1_DCRCERR BIT(29) | |
156 | #define MCP251XFD_REG_BDIAG1_DSTUFERR BIT(28) | |
157 | #define MCP251XFD_REG_BDIAG1_DFORMERR BIT(27) | |
158 | #define MCP251XFD_REG_BDIAG1_DBIT1ERR BIT(25) | |
159 | #define MCP251XFD_REG_BDIAG1_DBIT0ERR BIT(24) | |
160 | #define MCP251XFD_REG_BDIAG1_TXBOERR BIT(23) | |
161 | #define MCP251XFD_REG_BDIAG1_NCRCERR BIT(21) | |
162 | #define MCP251XFD_REG_BDIAG1_NSTUFERR BIT(20) | |
163 | #define MCP251XFD_REG_BDIAG1_NFORMERR BIT(19) | |
164 | #define MCP251XFD_REG_BDIAG1_NACKERR BIT(18) | |
165 | #define MCP251XFD_REG_BDIAG1_NBIT1ERR BIT(17) | |
166 | #define MCP251XFD_REG_BDIAG1_NBIT0ERR BIT(16) | |
167 | #define MCP251XFD_REG_BDIAG1_BERR_MASK \ | |
168 | (MCP251XFD_REG_BDIAG1_DLCMM | MCP251XFD_REG_BDIAG1_ESI | \ | |
169 | MCP251XFD_REG_BDIAG1_DCRCERR | MCP251XFD_REG_BDIAG1_DSTUFERR | \ | |
170 | MCP251XFD_REG_BDIAG1_DFORMERR | MCP251XFD_REG_BDIAG1_DBIT1ERR | \ | |
171 | MCP251XFD_REG_BDIAG1_DBIT0ERR | MCP251XFD_REG_BDIAG1_TXBOERR | \ | |
172 | MCP251XFD_REG_BDIAG1_NCRCERR | MCP251XFD_REG_BDIAG1_NSTUFERR | \ | |
173 | MCP251XFD_REG_BDIAG1_NFORMERR | MCP251XFD_REG_BDIAG1_NACKERR | \ | |
174 | MCP251XFD_REG_BDIAG1_NBIT1ERR | MCP251XFD_REG_BDIAG1_NBIT0ERR) | |
175 | #define MCP251XFD_REG_BDIAG1_EFMSGCNT_MASK GENMASK(15, 0) | |
176 | ||
177 | #define MCP251XFD_REG_TEFCON 0x40 | |
178 | #define MCP251XFD_REG_TEFCON_FSIZE_MASK GENMASK(28, 24) | |
179 | #define MCP251XFD_REG_TEFCON_FRESET BIT(10) | |
180 | #define MCP251XFD_REG_TEFCON_UINC BIT(8) | |
181 | #define MCP251XFD_REG_TEFCON_TEFTSEN BIT(5) | |
182 | #define MCP251XFD_REG_TEFCON_TEFOVIE BIT(3) | |
183 | #define MCP251XFD_REG_TEFCON_TEFFIE BIT(2) | |
184 | #define MCP251XFD_REG_TEFCON_TEFHIE BIT(1) | |
185 | #define MCP251XFD_REG_TEFCON_TEFNEIE BIT(0) | |
186 | ||
187 | #define MCP251XFD_REG_TEFSTA 0x44 | |
188 | #define MCP251XFD_REG_TEFSTA_TEFOVIF BIT(3) | |
189 | #define MCP251XFD_REG_TEFSTA_TEFFIF BIT(2) | |
190 | #define MCP251XFD_REG_TEFSTA_TEFHIF BIT(1) | |
191 | #define MCP251XFD_REG_TEFSTA_TEFNEIF BIT(0) | |
192 | ||
193 | #define MCP251XFD_REG_TEFUA 0x48 | |
194 | ||
195 | #define MCP251XFD_REG_TXQCON 0x50 | |
196 | #define MCP251XFD_REG_TXQCON_PLSIZE_MASK GENMASK(31, 29) | |
197 | #define MCP251XFD_REG_TXQCON_PLSIZE_8 0 | |
198 | #define MCP251XFD_REG_TXQCON_PLSIZE_12 1 | |
199 | #define MCP251XFD_REG_TXQCON_PLSIZE_16 2 | |
200 | #define MCP251XFD_REG_TXQCON_PLSIZE_20 3 | |
201 | #define MCP251XFD_REG_TXQCON_PLSIZE_24 4 | |
202 | #define MCP251XFD_REG_TXQCON_PLSIZE_32 5 | |
203 | #define MCP251XFD_REG_TXQCON_PLSIZE_48 6 | |
204 | #define MCP251XFD_REG_TXQCON_PLSIZE_64 7 | |
205 | #define MCP251XFD_REG_TXQCON_FSIZE_MASK GENMASK(28, 24) | |
206 | #define MCP251XFD_REG_TXQCON_TXAT_UNLIMITED 3 | |
207 | #define MCP251XFD_REG_TXQCON_TXAT_THREE_SHOT 1 | |
208 | #define MCP251XFD_REG_TXQCON_TXAT_ONE_SHOT 0 | |
209 | #define MCP251XFD_REG_TXQCON_TXAT_MASK GENMASK(22, 21) | |
210 | #define MCP251XFD_REG_TXQCON_TXPRI_MASK GENMASK(20, 16) | |
211 | #define MCP251XFD_REG_TXQCON_FRESET BIT(10) | |
212 | #define MCP251XFD_REG_TXQCON_TXREQ BIT(9) | |
213 | #define MCP251XFD_REG_TXQCON_UINC BIT(8) | |
214 | #define MCP251XFD_REG_TXQCON_TXEN BIT(7) | |
215 | #define MCP251XFD_REG_TXQCON_TXATIE BIT(4) | |
216 | #define MCP251XFD_REG_TXQCON_TXQEIE BIT(2) | |
217 | #define MCP251XFD_REG_TXQCON_TXQNIE BIT(0) | |
218 | ||
219 | #define MCP251XFD_REG_TXQSTA 0x54 | |
220 | #define MCP251XFD_REG_TXQSTA_TXQCI_MASK GENMASK(12, 8) | |
221 | #define MCP251XFD_REG_TXQSTA_TXABT BIT(7) | |
222 | #define MCP251XFD_REG_TXQSTA_TXLARB BIT(6) | |
223 | #define MCP251XFD_REG_TXQSTA_TXERR BIT(5) | |
224 | #define MCP251XFD_REG_TXQSTA_TXATIF BIT(4) | |
225 | #define MCP251XFD_REG_TXQSTA_TXQEIF BIT(2) | |
226 | #define MCP251XFD_REG_TXQSTA_TXQNIF BIT(0) | |
227 | ||
228 | #define MCP251XFD_REG_TXQUA 0x58 | |
229 | ||
230 | #define MCP251XFD_REG_FIFOCON(x) (0x50 + 0xc * (x)) | |
231 | #define MCP251XFD_REG_FIFOCON_PLSIZE_MASK GENMASK(31, 29) | |
232 | #define MCP251XFD_REG_FIFOCON_PLSIZE_8 0 | |
233 | #define MCP251XFD_REG_FIFOCON_PLSIZE_12 1 | |
234 | #define MCP251XFD_REG_FIFOCON_PLSIZE_16 2 | |
235 | #define MCP251XFD_REG_FIFOCON_PLSIZE_20 3 | |
236 | #define MCP251XFD_REG_FIFOCON_PLSIZE_24 4 | |
237 | #define MCP251XFD_REG_FIFOCON_PLSIZE_32 5 | |
238 | #define MCP251XFD_REG_FIFOCON_PLSIZE_48 6 | |
239 | #define MCP251XFD_REG_FIFOCON_PLSIZE_64 7 | |
240 | #define MCP251XFD_REG_FIFOCON_FSIZE_MASK GENMASK(28, 24) | |
241 | #define MCP251XFD_REG_FIFOCON_TXAT_MASK GENMASK(22, 21) | |
242 | #define MCP251XFD_REG_FIFOCON_TXAT_ONE_SHOT 0 | |
243 | #define MCP251XFD_REG_FIFOCON_TXAT_THREE_SHOT 1 | |
244 | #define MCP251XFD_REG_FIFOCON_TXAT_UNLIMITED 3 | |
245 | #define MCP251XFD_REG_FIFOCON_TXPRI_MASK GENMASK(20, 16) | |
246 | #define MCP251XFD_REG_FIFOCON_FRESET BIT(10) | |
247 | #define MCP251XFD_REG_FIFOCON_TXREQ BIT(9) | |
248 | #define MCP251XFD_REG_FIFOCON_UINC BIT(8) | |
249 | #define MCP251XFD_REG_FIFOCON_TXEN BIT(7) | |
250 | #define MCP251XFD_REG_FIFOCON_RTREN BIT(6) | |
251 | #define MCP251XFD_REG_FIFOCON_RXTSEN BIT(5) | |
252 | #define MCP251XFD_REG_FIFOCON_TXATIE BIT(4) | |
253 | #define MCP251XFD_REG_FIFOCON_RXOVIE BIT(3) | |
254 | #define MCP251XFD_REG_FIFOCON_TFERFFIE BIT(2) | |
255 | #define MCP251XFD_REG_FIFOCON_TFHRFHIE BIT(1) | |
256 | #define MCP251XFD_REG_FIFOCON_TFNRFNIE BIT(0) | |
257 | ||
258 | #define MCP251XFD_REG_FIFOSTA(x) (0x54 + 0xc * (x)) | |
259 | #define MCP251XFD_REG_FIFOSTA_FIFOCI_MASK GENMASK(12, 8) | |
260 | #define MCP251XFD_REG_FIFOSTA_TXABT BIT(7) | |
261 | #define MCP251XFD_REG_FIFOSTA_TXLARB BIT(6) | |
262 | #define MCP251XFD_REG_FIFOSTA_TXERR BIT(5) | |
263 | #define MCP251XFD_REG_FIFOSTA_TXATIF BIT(4) | |
264 | #define MCP251XFD_REG_FIFOSTA_RXOVIF BIT(3) | |
265 | #define MCP251XFD_REG_FIFOSTA_TFERFFIF BIT(2) | |
266 | #define MCP251XFD_REG_FIFOSTA_TFHRFHIF BIT(1) | |
267 | #define MCP251XFD_REG_FIFOSTA_TFNRFNIF BIT(0) | |
268 | ||
269 | #define MCP251XFD_REG_FIFOUA(x) (0x58 + 0xc * (x)) | |
270 | ||
271 | #define MCP251XFD_REG_FLTCON(x) (0x1d0 + 0x4 * (x)) | |
272 | #define MCP251XFD_REG_FLTCON_FLTEN3 BIT(31) | |
273 | #define MCP251XFD_REG_FLTCON_F3BP_MASK GENMASK(28, 24) | |
274 | #define MCP251XFD_REG_FLTCON_FLTEN2 BIT(23) | |
275 | #define MCP251XFD_REG_FLTCON_F2BP_MASK GENMASK(20, 16) | |
276 | #define MCP251XFD_REG_FLTCON_FLTEN1 BIT(15) | |
277 | #define MCP251XFD_REG_FLTCON_F1BP_MASK GENMASK(12, 8) | |
278 | #define MCP251XFD_REG_FLTCON_FLTEN0 BIT(7) | |
279 | #define MCP251XFD_REG_FLTCON_F0BP_MASK GENMASK(4, 0) | |
280 | #define MCP251XFD_REG_FLTCON_FLTEN(x) (BIT(7) << 8 * ((x) & 0x3)) | |
281 | #define MCP251XFD_REG_FLTCON_FLT_MASK(x) (GENMASK(7, 0) << (8 * ((x) & 0x3))) | |
282 | #define MCP251XFD_REG_FLTCON_FBP(x, fifo) ((fifo) << 8 * ((x) & 0x3)) | |
283 | ||
284 | #define MCP251XFD_REG_FLTOBJ(x) (0x1f0 + 0x8 * (x)) | |
285 | #define MCP251XFD_REG_FLTOBJ_EXIDE BIT(30) | |
286 | #define MCP251XFD_REG_FLTOBJ_SID11 BIT(29) | |
287 | #define MCP251XFD_REG_FLTOBJ_EID_MASK GENMASK(28, 11) | |
288 | #define MCP251XFD_REG_FLTOBJ_SID_MASK GENMASK(10, 0) | |
289 | ||
290 | #define MCP251XFD_REG_FLTMASK(x) (0x1f4 + 0x8 * (x)) | |
291 | #define MCP251XFD_REG_MASK_MIDE BIT(30) | |
292 | #define MCP251XFD_REG_MASK_MSID11 BIT(29) | |
293 | #define MCP251XFD_REG_MASK_MEID_MASK GENMASK(28, 11) | |
294 | #define MCP251XFD_REG_MASK_MSID_MASK GENMASK(10, 0) | |
875347fe MKB |
295 | |
296 | /* RAM */ | |
eb79a267 MKB |
297 | #define MCP251XFD_RAM_START 0x400 |
298 | #define MCP251XFD_RAM_SIZE SZ_2K | |
875347fe MKB |
299 | |
300 | /* Message Object */ | |
eb79a267 MKB |
301 | #define MCP251XFD_OBJ_ID_SID11 BIT(29) |
302 | #define MCP251XFD_OBJ_ID_EID_MASK GENMASK(28, 11) | |
303 | #define MCP251XFD_OBJ_ID_SID_MASK GENMASK(10, 0) | |
304 | #define MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK GENMASK(31, 9) | |
305 | #define MCP251XFD_OBJ_FLAGS_SEQ_MCP2517FD_MASK GENMASK(15, 9) | |
306 | #define MCP251XFD_OBJ_FLAGS_SEQ_MASK MCP251XFD_OBJ_FLAGS_SEQ_MCP2518FD_MASK | |
307 | #define MCP251XFD_OBJ_FLAGS_ESI BIT(8) | |
308 | #define MCP251XFD_OBJ_FLAGS_FDF BIT(7) | |
309 | #define MCP251XFD_OBJ_FLAGS_BRS BIT(6) | |
310 | #define MCP251XFD_OBJ_FLAGS_RTR BIT(5) | |
311 | #define MCP251XFD_OBJ_FLAGS_IDE BIT(4) | |
49ffacbc | 312 | #define MCP251XFD_OBJ_FLAGS_DLC_MASK GENMASK(3, 0) |
eb79a267 MKB |
313 | |
314 | #define MCP251XFD_REG_FRAME_EFF_SID_MASK GENMASK(28, 18) | |
315 | #define MCP251XFD_REG_FRAME_EFF_EID_MASK GENMASK(17, 0) | |
875347fe MKB |
316 | |
317 | /* MCP2517/18FD SFR */ | |
eb79a267 MKB |
318 | #define MCP251XFD_REG_OSC 0xe00 |
319 | #define MCP251XFD_REG_OSC_SCLKRDY BIT(12) | |
320 | #define MCP251XFD_REG_OSC_OSCRDY BIT(10) | |
321 | #define MCP251XFD_REG_OSC_PLLRDY BIT(8) | |
322 | #define MCP251XFD_REG_OSC_CLKODIV_10 3 | |
323 | #define MCP251XFD_REG_OSC_CLKODIV_4 2 | |
324 | #define MCP251XFD_REG_OSC_CLKODIV_2 1 | |
325 | #define MCP251XFD_REG_OSC_CLKODIV_1 0 | |
326 | #define MCP251XFD_REG_OSC_CLKODIV_MASK GENMASK(6, 5) | |
327 | #define MCP251XFD_REG_OSC_SCLKDIV BIT(4) | |
328 | #define MCP251XFD_REG_OSC_LPMEN BIT(3) /* MCP2518FD only */ | |
329 | #define MCP251XFD_REG_OSC_OSCDIS BIT(2) | |
330 | #define MCP251XFD_REG_OSC_PLLEN BIT(0) | |
331 | ||
332 | #define MCP251XFD_REG_IOCON 0xe04 | |
333 | #define MCP251XFD_REG_IOCON_INTOD BIT(30) | |
334 | #define MCP251XFD_REG_IOCON_SOF BIT(29) | |
335 | #define MCP251XFD_REG_IOCON_TXCANOD BIT(28) | |
336 | #define MCP251XFD_REG_IOCON_PM1 BIT(25) | |
337 | #define MCP251XFD_REG_IOCON_PM0 BIT(24) | |
338 | #define MCP251XFD_REG_IOCON_GPIO1 BIT(17) | |
339 | #define MCP251XFD_REG_IOCON_GPIO0 BIT(16) | |
340 | #define MCP251XFD_REG_IOCON_LAT1 BIT(9) | |
341 | #define MCP251XFD_REG_IOCON_LAT0 BIT(8) | |
342 | #define MCP251XFD_REG_IOCON_XSTBYEN BIT(6) | |
343 | #define MCP251XFD_REG_IOCON_TRIS1 BIT(1) | |
344 | #define MCP251XFD_REG_IOCON_TRIS0 BIT(0) | |
345 | ||
346 | #define MCP251XFD_REG_CRC 0xe08 | |
347 | #define MCP251XFD_REG_CRC_FERRIE BIT(25) | |
348 | #define MCP251XFD_REG_CRC_CRCERRIE BIT(24) | |
349 | #define MCP251XFD_REG_CRC_FERRIF BIT(17) | |
350 | #define MCP251XFD_REG_CRC_CRCERRIF BIT(16) | |
351 | #define MCP251XFD_REG_CRC_IF_MASK GENMASK(17, 16) | |
352 | #define MCP251XFD_REG_CRC_MASK GENMASK(15, 0) | |
353 | ||
354 | #define MCP251XFD_REG_ECCCON 0xe0c | |
355 | #define MCP251XFD_REG_ECCCON_PARITY_MASK GENMASK(14, 8) | |
356 | #define MCP251XFD_REG_ECCCON_DEDIE BIT(2) | |
357 | #define MCP251XFD_REG_ECCCON_SECIE BIT(1) | |
358 | #define MCP251XFD_REG_ECCCON_ECCEN BIT(0) | |
359 | ||
360 | #define MCP251XFD_REG_ECCSTAT 0xe10 | |
361 | #define MCP251XFD_REG_ECCSTAT_ERRADDR_MASK GENMASK(27, 16) | |
362 | #define MCP251XFD_REG_ECCSTAT_IF_MASK GENMASK(2, 1) | |
363 | #define MCP251XFD_REG_ECCSTAT_DEDIF BIT(2) | |
364 | #define MCP251XFD_REG_ECCSTAT_SECIF BIT(1) | |
365 | ||
366 | #define MCP251XFD_REG_DEVID 0xe14 /* MCP2518FD only */ | |
367 | #define MCP251XFD_REG_DEVID_ID_MASK GENMASK(7, 4) | |
368 | #define MCP251XFD_REG_DEVID_REV_MASK GENMASK(3, 0) | |
875347fe | 369 | |
875347fe | 370 | /* SPI commands */ |
eb79a267 MKB |
371 | #define MCP251XFD_SPI_INSTRUCTION_RESET 0x0000 |
372 | #define MCP251XFD_SPI_INSTRUCTION_WRITE 0x2000 | |
373 | #define MCP251XFD_SPI_INSTRUCTION_READ 0x3000 | |
374 | #define MCP251XFD_SPI_INSTRUCTION_WRITE_CRC 0xa000 | |
375 | #define MCP251XFD_SPI_INSTRUCTION_READ_CRC 0xb000 | |
376 | #define MCP251XFD_SPI_INSTRUCTION_WRITE_CRC_SAFE 0xc000 | |
377 | #define MCP251XFD_SPI_ADDRESS_MASK GENMASK(11, 0) | |
378 | ||
379 | #define MCP251XFD_SYSCLOCK_HZ_MAX 40000000 | |
380 | #define MCP251XFD_SYSCLOCK_HZ_MIN 1000000 | |
381 | #define MCP251XFD_SPICLOCK_HZ_MAX 20000000 | |
efd8d98d MKB |
382 | #define MCP251XFD_TIMESTAMP_WORK_DELAY_SEC 45 |
383 | static_assert(MCP251XFD_TIMESTAMP_WORK_DELAY_SEC < | |
384 | CYCLECOUNTER_MASK(32) / MCP251XFD_SYSCLOCK_HZ_MAX / 2); | |
eb79a267 MKB |
385 | #define MCP251XFD_OSC_PLL_MULTIPLIER 10 |
386 | #define MCP251XFD_OSC_STAB_SLEEP_US (3 * USEC_PER_MSEC) | |
387 | #define MCP251XFD_OSC_STAB_TIMEOUT_US (10 * MCP251XFD_OSC_STAB_SLEEP_US) | |
388 | #define MCP251XFD_POLL_SLEEP_US (10) | |
389 | #define MCP251XFD_POLL_TIMEOUT_US (USEC_PER_MSEC) | |
9efa1a54 | 390 | #define MCP251XFD_FRAME_LEN_MAX_BITS (736) |
c9e6b80d MKB |
391 | |
392 | /* Misc */ | |
393 | #define MCP251XFD_NAPI_WEIGHT 32 | |
eb79a267 MKB |
394 | #define MCP251XFD_SOFTRESET_RETRIES_MAX 3 |
395 | #define MCP251XFD_READ_CRC_RETRIES_MAX 3 | |
396 | #define MCP251XFD_ECC_CNT_MAX 2 | |
397 | #define MCP251XFD_SANITIZE_SPI 1 | |
398 | #define MCP251XFD_SANITIZE_CAN 1 | |
875347fe | 399 | |
aada7422 MKB |
400 | /* FIFO and Ring */ |
401 | #define MCP251XFD_FIFO_TEF_NUM 1U | |
aa66ae9b | 402 | #define MCP251XFD_FIFO_RX_NUM 3U |
aada7422 MKB |
403 | #define MCP251XFD_FIFO_TX_NUM 1U |
404 | ||
0a1f2e65 MKB |
405 | #define MCP251XFD_FIFO_DEPTH 32U |
406 | ||
c9e6b80d MKB |
407 | #define MCP251XFD_RX_OBJ_NUM_MIN 16U |
408 | #define MCP251XFD_RX_OBJ_NUM_MAX (MCP251XFD_FIFO_RX_NUM * MCP251XFD_FIFO_DEPTH) | |
409 | #define MCP251XFD_RX_FIFO_DEPTH_MIN 4U | |
846990e0 | 410 | #define MCP251XFD_RX_FIFO_DEPTH_COALESCE_MIN 8U |
c9e6b80d MKB |
411 | |
412 | #define MCP251XFD_TX_OBJ_NUM_MIN 2U | |
aa66ae9b | 413 | #define MCP251XFD_TX_OBJ_NUM_MAX 16U |
c9e6b80d MKB |
414 | #define MCP251XFD_TX_OBJ_NUM_CAN_DEFAULT 8U |
415 | #define MCP251XFD_TX_OBJ_NUM_CANFD_DEFAULT 4U | |
416 | #define MCP251XFD_TX_FIFO_DEPTH_MIN 2U | |
656fc12d | 417 | #define MCP251XFD_TX_FIFO_DEPTH_COALESCE_MIN 2U |
c9e6b80d | 418 | |
aada7422 MKB |
419 | static_assert(MCP251XFD_FIFO_TEF_NUM == 1U); |
420 | static_assert(MCP251XFD_FIFO_TEF_NUM == MCP251XFD_FIFO_TX_NUM); | |
c9e6b80d | 421 | static_assert(MCP251XFD_FIFO_RX_NUM <= 4U); |
aada7422 | 422 | |
875347fe | 423 | /* Silence TX MAB overflow warnings */ |
eb79a267 | 424 | #define MCP251XFD_QUIRK_MAB_NO_WARN BIT(0) |
875347fe | 425 | /* Use CRC to access registers */ |
eb79a267 | 426 | #define MCP251XFD_QUIRK_CRC_REG BIT(1) |
875347fe | 427 | /* Use CRC to access RX/TEF-RAM */ |
eb79a267 | 428 | #define MCP251XFD_QUIRK_CRC_RX BIT(2) |
875347fe | 429 | /* Use CRC to access TX-RAM */ |
eb79a267 | 430 | #define MCP251XFD_QUIRK_CRC_TX BIT(3) |
875347fe | 431 | /* Enable ECC for RAM */ |
eb79a267 | 432 | #define MCP251XFD_QUIRK_ECC BIT(4) |
875347fe | 433 | /* Use Half Duplex SPI transfers */ |
eb79a267 | 434 | #define MCP251XFD_QUIRK_HALF_DUPLEX BIT(5) |
875347fe | 435 | |
eb79a267 | 436 | struct mcp251xfd_hw_tef_obj { |
875347fe MKB |
437 | u32 id; |
438 | u32 flags; | |
439 | u32 ts; | |
440 | }; | |
441 | ||
442 | /* The tx_obj_raw version is used in spi async, i.e. without | |
443 | * regmap. We have to take care of endianness ourselves. | |
444 | */ | |
1a6dd999 | 445 | struct __packed mcp251xfd_hw_tx_obj_raw { |
875347fe MKB |
446 | __le32 id; |
447 | __le32 flags; | |
448 | u8 data[sizeof_field(struct canfd_frame, data)]; | |
449 | }; | |
450 | ||
eb79a267 | 451 | struct mcp251xfd_hw_tx_obj_can { |
875347fe MKB |
452 | u32 id; |
453 | u32 flags; | |
454 | u8 data[sizeof_field(struct can_frame, data)]; | |
455 | }; | |
456 | ||
eb79a267 | 457 | struct mcp251xfd_hw_tx_obj_canfd { |
875347fe MKB |
458 | u32 id; |
459 | u32 flags; | |
460 | u8 data[sizeof_field(struct canfd_frame, data)]; | |
461 | }; | |
462 | ||
eb79a267 | 463 | struct mcp251xfd_hw_rx_obj_can { |
875347fe MKB |
464 | u32 id; |
465 | u32 flags; | |
466 | u32 ts; | |
467 | u8 data[sizeof_field(struct can_frame, data)]; | |
468 | }; | |
469 | ||
eb79a267 | 470 | struct mcp251xfd_hw_rx_obj_canfd { |
875347fe MKB |
471 | u32 id; |
472 | u32 flags; | |
473 | u32 ts; | |
474 | u8 data[sizeof_field(struct canfd_frame, data)]; | |
475 | }; | |
476 | ||
eb79a267 | 477 | struct __packed mcp251xfd_buf_cmd { |
875347fe MKB |
478 | __be16 cmd; |
479 | }; | |
480 | ||
eb79a267 | 481 | struct __packed mcp251xfd_buf_cmd_crc { |
875347fe MKB |
482 | __be16 cmd; |
483 | u8 len; | |
484 | }; | |
485 | ||
eb79a267 | 486 | union mcp251xfd_tx_obj_load_buf { |
875347fe | 487 | struct __packed { |
eb79a267 MKB |
488 | struct mcp251xfd_buf_cmd cmd; |
489 | struct mcp251xfd_hw_tx_obj_raw hw_tx_obj; | |
875347fe MKB |
490 | } nocrc; |
491 | struct __packed { | |
eb79a267 MKB |
492 | struct mcp251xfd_buf_cmd_crc cmd; |
493 | struct mcp251xfd_hw_tx_obj_raw hw_tx_obj; | |
875347fe MKB |
494 | __be16 crc; |
495 | } crc; | |
496 | } ____cacheline_aligned; | |
497 | ||
eb79a267 | 498 | union mcp251xfd_write_reg_buf { |
875347fe | 499 | struct __packed { |
eb79a267 | 500 | struct mcp251xfd_buf_cmd cmd; |
875347fe MKB |
501 | u8 data[4]; |
502 | } nocrc; | |
503 | struct __packed { | |
eb79a267 | 504 | struct mcp251xfd_buf_cmd_crc cmd; |
875347fe MKB |
505 | u8 data[4]; |
506 | __be16 crc; | |
507 | } crc; | |
2e8ca20b TK |
508 | struct __packed { |
509 | struct mcp251xfd_buf_cmd cmd; | |
510 | u8 data[1]; | |
511 | __be16 crc; | |
512 | } safe; | |
875347fe MKB |
513 | } ____cacheline_aligned; |
514 | ||
eb79a267 | 515 | struct mcp251xfd_tx_obj { |
875347fe MKB |
516 | struct spi_message msg; |
517 | struct spi_transfer xfer[2]; | |
eb79a267 | 518 | union mcp251xfd_tx_obj_load_buf buf; |
875347fe MKB |
519 | }; |
520 | ||
63e70488 MKB |
521 | struct mcp251xfd_tef_ring { |
522 | unsigned int head; | |
523 | unsigned int tail; | |
524 | ||
525 | /* u8 obj_num equals tx_ring->obj_num */ | |
526 | /* u8 obj_size equals sizeof(struct mcp251xfd_hw_tef_obj) */ | |
b8e0ddd3 | 527 | /* u8 obj_num_shift_to_u8 equals tx_ring->obj_num_shift_to_u8 */ |
68c0c1c7 | 528 | |
169d00a2 MKB |
529 | union mcp251xfd_write_reg_buf irq_enable_buf; |
530 | struct spi_transfer irq_enable_xfer; | |
531 | struct spi_message irq_enable_msg; | |
532 | ||
68c0c1c7 | 533 | union mcp251xfd_write_reg_buf uinc_buf; |
169d00a2 | 534 | union mcp251xfd_write_reg_buf uinc_irq_disable_buf; |
68c0c1c7 | 535 | struct spi_transfer uinc_xfer[MCP251XFD_TX_OBJ_NUM_MAX]; |
63e70488 MKB |
536 | }; |
537 | ||
eb79a267 | 538 | struct mcp251xfd_tx_ring { |
875347fe MKB |
539 | unsigned int head; |
540 | unsigned int tail; | |
541 | ||
542 | u16 base; | |
c912f19e MKB |
543 | u8 nr; |
544 | u8 fifo_nr; | |
875347fe | 545 | u8 obj_num; |
b8e0ddd3 | 546 | u8 obj_num_shift_to_u8; |
875347fe MKB |
547 | u8 obj_size; |
548 | ||
eb79a267 MKB |
549 | struct mcp251xfd_tx_obj obj[MCP251XFD_TX_OBJ_NUM_MAX]; |
550 | union mcp251xfd_write_reg_buf rts_buf; | |
875347fe MKB |
551 | }; |
552 | ||
eb79a267 | 553 | struct mcp251xfd_rx_ring { |
875347fe MKB |
554 | unsigned int head; |
555 | unsigned int tail; | |
556 | ||
24436be5 MKB |
557 | /* timestamp of the last valid received CAN frame */ |
558 | u64 last_valid; | |
559 | ||
875347fe MKB |
560 | u16 base; |
561 | u8 nr; | |
562 | u8 fifo_nr; | |
563 | u8 obj_num; | |
85505e58 | 564 | u8 obj_num_shift_to_u8; |
875347fe MKB |
565 | u8 obj_size; |
566 | ||
60a848c5 MKB |
567 | union mcp251xfd_write_reg_buf irq_enable_buf; |
568 | struct spi_transfer irq_enable_xfer; | |
569 | struct spi_message irq_enable_msg; | |
570 | ||
1f652bb6 | 571 | union mcp251xfd_write_reg_buf uinc_buf; |
60a848c5 | 572 | union mcp251xfd_write_reg_buf uinc_irq_disable_buf; |
c9e6b80d | 573 | struct spi_transfer uinc_xfer[MCP251XFD_FIFO_DEPTH]; |
eb79a267 | 574 | struct mcp251xfd_hw_rx_obj_canfd obj[]; |
875347fe MKB |
575 | }; |
576 | ||
eb79a267 MKB |
577 | struct __packed mcp251xfd_map_buf_nocrc { |
578 | struct mcp251xfd_buf_cmd cmd; | |
875347fe MKB |
579 | u8 data[256]; |
580 | } ____cacheline_aligned; | |
581 | ||
eb79a267 MKB |
582 | struct __packed mcp251xfd_map_buf_crc { |
583 | struct mcp251xfd_buf_cmd_crc cmd; | |
875347fe MKB |
584 | u8 data[256 - 4]; |
585 | __be16 crc; | |
586 | } ____cacheline_aligned; | |
587 | ||
eb79a267 | 588 | struct mcp251xfd_ecc { |
875347fe MKB |
589 | u32 ecc_stat; |
590 | int cnt; | |
591 | }; | |
592 | ||
eb79a267 | 593 | struct mcp251xfd_regs_status { |
875347fe | 594 | u32 intf; |
887e359d | 595 | u32 rxif; |
875347fe MKB |
596 | }; |
597 | ||
eb79a267 MKB |
598 | enum mcp251xfd_model { |
599 | MCP251XFD_MODEL_MCP2517FD = 0x2517, | |
600 | MCP251XFD_MODEL_MCP2518FD = 0x2518, | |
c6f2a617 MKB |
601 | MCP251XFD_MODEL_MCP251863 = 0x251863, |
602 | MCP251XFD_MODEL_MCP251XFD = 0xffffffff, /* autodetect model */ | |
875347fe MKB |
603 | }; |
604 | ||
eb79a267 MKB |
605 | struct mcp251xfd_devtype_data { |
606 | enum mcp251xfd_model model; | |
875347fe MKB |
607 | u32 quirks; |
608 | }; | |
609 | ||
9263c2e9 | 610 | enum mcp251xfd_flags { |
60a848c5 | 611 | MCP251XFD_FLAGS_DOWN, |
9263c2e9 MKB |
612 | MCP251XFD_FLAGS_FD_MODE, |
613 | ||
614 | __MCP251XFD_FLAGS_SIZE__ | |
615 | }; | |
616 | ||
eb79a267 | 617 | struct mcp251xfd_priv { |
875347fe MKB |
618 | struct can_priv can; |
619 | struct can_rx_offload offload; | |
620 | struct net_device *ndev; | |
621 | ||
622 | struct regmap *map_reg; /* register access */ | |
623 | struct regmap *map_rx; /* RX/TEF RAM access */ | |
624 | ||
625 | struct regmap *map_nocrc; | |
eb79a267 MKB |
626 | struct mcp251xfd_map_buf_nocrc *map_buf_nocrc_rx; |
627 | struct mcp251xfd_map_buf_nocrc *map_buf_nocrc_tx; | |
875347fe MKB |
628 | |
629 | struct regmap *map_crc; | |
eb79a267 MKB |
630 | struct mcp251xfd_map_buf_crc *map_buf_crc_rx; |
631 | struct mcp251xfd_map_buf_crc *map_buf_crc_tx; | |
875347fe MKB |
632 | |
633 | struct spi_device *spi; | |
634 | u32 spi_max_speed_hz_orig; | |
2a68dd86 MKB |
635 | u32 spi_max_speed_hz_fast; |
636 | u32 spi_max_speed_hz_slow; | |
875347fe | 637 | |
aada7422 | 638 | struct mcp251xfd_tef_ring tef[MCP251XFD_FIFO_TEF_NUM]; |
c9e6b80d | 639 | struct mcp251xfd_rx_ring *rx[MCP251XFD_FIFO_RX_NUM]; |
aada7422 | 640 | struct mcp251xfd_tx_ring tx[MCP251XFD_FIFO_TX_NUM]; |
875347fe | 641 | |
d8fb63e4 VS |
642 | struct workqueue_struct *wq; |
643 | struct work_struct tx_work; | |
644 | struct mcp251xfd_tx_obj *tx_work_obj; | |
645 | ||
9263c2e9 MKB |
646 | DECLARE_BITMAP(flags, __MCP251XFD_FLAGS_SIZE__); |
647 | ||
875347fe | 648 | u8 rx_ring_num; |
d86ba8db | 649 | u8 rx_obj_num; |
60a848c5 | 650 | u8 rx_obj_num_coalesce_irq; |
169d00a2 | 651 | u8 tx_obj_num_coalesce_irq; |
60a848c5 MKB |
652 | |
653 | u32 rx_coalesce_usecs_irq; | |
169d00a2 | 654 | u32 tx_coalesce_usecs_irq; |
60a848c5 | 655 | struct hrtimer rx_irq_timer; |
169d00a2 | 656 | struct hrtimer tx_irq_timer; |
875347fe | 657 | |
eb79a267 MKB |
658 | struct mcp251xfd_ecc ecc; |
659 | struct mcp251xfd_regs_status regs_status; | |
875347fe | 660 | |
efd8d98d MKB |
661 | struct cyclecounter cc; |
662 | struct timecounter tc; | |
663 | struct delayed_work timestamp; | |
664 | ||
875347fe MKB |
665 | struct gpio_desc *rx_int; |
666 | struct clk *clk; | |
2a68dd86 | 667 | bool pll_enable; |
875347fe MKB |
668 | struct regulator *reg_vdd; |
669 | struct regulator *reg_xceiver; | |
670 | ||
eb79a267 | 671 | struct mcp251xfd_devtype_data devtype_data; |
875347fe MKB |
672 | struct can_berr_counter bec; |
673 | }; | |
674 | ||
eb79a267 | 675 | #define MCP251XFD_IS(_model) \ |
875347fe | 676 | static inline bool \ |
eb79a267 | 677 | mcp251xfd_is_##_model(const struct mcp251xfd_priv *priv) \ |
875347fe | 678 | { \ |
c6f2a617 | 679 | return priv->devtype_data.model == MCP251XFD_MODEL_MCP##_model; \ |
875347fe MKB |
680 | } |
681 | ||
c6f2a617 MKB |
682 | MCP251XFD_IS(2517FD); |
683 | MCP251XFD_IS(2518FD); | |
684 | MCP251XFD_IS(251863); | |
685 | MCP251XFD_IS(251XFD); | |
875347fe | 686 | |
3044a4f2 MKB |
687 | static inline bool mcp251xfd_is_fd_mode(const struct mcp251xfd_priv *priv) |
688 | { | |
689 | /* listen-only mode works like FD mode */ | |
690 | return priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_FD); | |
691 | } | |
692 | ||
eb79a267 | 693 | static inline u8 mcp251xfd_first_byte_set(u32 mask) |
875347fe MKB |
694 | { |
695 | return (mask & 0x0000ffff) ? | |
696 | ((mask & 0x000000ff) ? 0 : 1) : | |
697 | ((mask & 0x00ff0000) ? 2 : 3); | |
698 | } | |
699 | ||
eb79a267 | 700 | static inline u8 mcp251xfd_last_byte_set(u32 mask) |
875347fe MKB |
701 | { |
702 | return (mask & 0xffff0000) ? | |
703 | ((mask & 0xff000000) ? 3 : 2) : | |
704 | ((mask & 0x0000ff00) ? 1 : 0); | |
705 | } | |
706 | ||
eb79a267 | 707 | static inline __be16 mcp251xfd_cmd_reset(void) |
875347fe | 708 | { |
eb79a267 | 709 | return cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_RESET); |
875347fe MKB |
710 | } |
711 | ||
712 | static inline void | |
eb79a267 | 713 | mcp251xfd_spi_cmd_read_nocrc(struct mcp251xfd_buf_cmd *cmd, u16 addr) |
875347fe | 714 | { |
eb79a267 | 715 | cmd->cmd = cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_READ | addr); |
875347fe MKB |
716 | } |
717 | ||
718 | static inline void | |
eb79a267 | 719 | mcp251xfd_spi_cmd_write_nocrc(struct mcp251xfd_buf_cmd *cmd, u16 addr) |
875347fe | 720 | { |
eb79a267 | 721 | cmd->cmd = cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_WRITE | addr); |
875347fe MKB |
722 | } |
723 | ||
eb79a267 | 724 | static inline bool mcp251xfd_reg_in_ram(unsigned int reg) |
875347fe MKB |
725 | { |
726 | static const struct regmap_range range = | |
eb79a267 MKB |
727 | regmap_reg_range(MCP251XFD_RAM_START, |
728 | MCP251XFD_RAM_START + MCP251XFD_RAM_SIZE - 4); | |
875347fe MKB |
729 | |
730 | return regmap_reg_in_range(reg, &range); | |
731 | } | |
732 | ||
733 | static inline void | |
eb79a267 | 734 | __mcp251xfd_spi_cmd_crc_set_len(struct mcp251xfd_buf_cmd_crc *cmd, |
875347fe MKB |
735 | u16 len, bool in_ram) |
736 | { | |
737 | /* Number of u32 for RAM access, number of u8 otherwise. */ | |
738 | if (in_ram) | |
739 | cmd->len = len >> 2; | |
740 | else | |
741 | cmd->len = len; | |
742 | } | |
743 | ||
744 | static inline void | |
eb79a267 | 745 | mcp251xfd_spi_cmd_crc_set_len_in_ram(struct mcp251xfd_buf_cmd_crc *cmd, u16 len) |
875347fe | 746 | { |
eb79a267 | 747 | __mcp251xfd_spi_cmd_crc_set_len(cmd, len, true); |
875347fe MKB |
748 | } |
749 | ||
750 | static inline void | |
eb79a267 | 751 | mcp251xfd_spi_cmd_crc_set_len_in_reg(struct mcp251xfd_buf_cmd_crc *cmd, u16 len) |
875347fe | 752 | { |
eb79a267 | 753 | __mcp251xfd_spi_cmd_crc_set_len(cmd, len, false); |
875347fe MKB |
754 | } |
755 | ||
756 | static inline void | |
eb79a267 | 757 | mcp251xfd_spi_cmd_read_crc_set_addr(struct mcp251xfd_buf_cmd_crc *cmd, u16 addr) |
875347fe | 758 | { |
eb79a267 | 759 | cmd->cmd = cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_READ_CRC | addr); |
875347fe MKB |
760 | } |
761 | ||
762 | static inline void | |
eb79a267 | 763 | mcp251xfd_spi_cmd_read_crc(struct mcp251xfd_buf_cmd_crc *cmd, |
875347fe MKB |
764 | u16 addr, u16 len) |
765 | { | |
eb79a267 MKB |
766 | mcp251xfd_spi_cmd_read_crc_set_addr(cmd, addr); |
767 | __mcp251xfd_spi_cmd_crc_set_len(cmd, len, mcp251xfd_reg_in_ram(addr)); | |
875347fe MKB |
768 | } |
769 | ||
770 | static inline void | |
eb79a267 | 771 | mcp251xfd_spi_cmd_write_crc_set_addr(struct mcp251xfd_buf_cmd_crc *cmd, |
875347fe MKB |
772 | u16 addr) |
773 | { | |
eb79a267 | 774 | cmd->cmd = cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_WRITE_CRC | addr); |
875347fe MKB |
775 | } |
776 | ||
2e8ca20b TK |
777 | static inline void |
778 | mcp251xfd_spi_cmd_write_safe_set_addr(struct mcp251xfd_buf_cmd *cmd, | |
779 | u16 addr) | |
780 | { | |
781 | cmd->cmd = cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_WRITE_CRC_SAFE | addr); | |
782 | } | |
783 | ||
875347fe | 784 | static inline void |
eb79a267 | 785 | mcp251xfd_spi_cmd_write_crc(struct mcp251xfd_buf_cmd_crc *cmd, |
875347fe MKB |
786 | u16 addr, u16 len) |
787 | { | |
eb79a267 MKB |
788 | mcp251xfd_spi_cmd_write_crc_set_addr(cmd, addr); |
789 | __mcp251xfd_spi_cmd_crc_set_len(cmd, len, mcp251xfd_reg_in_ram(addr)); | |
875347fe MKB |
790 | } |
791 | ||
792 | static inline u8 * | |
eb79a267 MKB |
793 | mcp251xfd_spi_cmd_write(const struct mcp251xfd_priv *priv, |
794 | union mcp251xfd_write_reg_buf *write_reg_buf, | |
2e8ca20b | 795 | u16 addr, u8 len) |
875347fe MKB |
796 | { |
797 | u8 *data; | |
798 | ||
eb79a267 | 799 | if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) { |
2e8ca20b TK |
800 | if (len == 1) { |
801 | mcp251xfd_spi_cmd_write_safe_set_addr(&write_reg_buf->safe.cmd, | |
802 | addr); | |
803 | data = write_reg_buf->safe.data; | |
804 | } else { | |
805 | mcp251xfd_spi_cmd_write_crc_set_addr(&write_reg_buf->crc.cmd, | |
806 | addr); | |
807 | data = write_reg_buf->crc.data; | |
808 | } | |
875347fe | 809 | } else { |
eb79a267 | 810 | mcp251xfd_spi_cmd_write_nocrc(&write_reg_buf->nocrc.cmd, |
875347fe MKB |
811 | addr); |
812 | data = write_reg_buf->nocrc.data; | |
813 | } | |
814 | ||
815 | return data; | |
816 | } | |
817 | ||
e793c724 MKB |
818 | static inline int mcp251xfd_get_timestamp_raw(const struct mcp251xfd_priv *priv, |
819 | u32 *ts_raw) | |
dc09e7e3 | 820 | { |
e793c724 MKB |
821 | return regmap_read(priv->map_reg, MCP251XFD_REG_TBC, ts_raw); |
822 | } | |
823 | ||
824 | static inline void mcp251xfd_skb_set_timestamp(struct sk_buff *skb, u64 ns) | |
825 | { | |
826 | struct skb_shared_hwtstamps *hwtstamps = skb_hwtstamps(skb); | |
827 | ||
828 | hwtstamps->hwtstamp = ns_to_ktime(ns); | |
829 | } | |
830 | ||
831 | static inline | |
832 | void mcp251xfd_skb_set_timestamp_raw(const struct mcp251xfd_priv *priv, | |
833 | struct sk_buff *skb, u32 ts_raw) | |
834 | { | |
835 | u64 ns; | |
836 | ||
837 | ns = timecounter_cyc2time(&priv->tc, ts_raw); | |
838 | mcp251xfd_skb_set_timestamp(skb, ns); | |
dc09e7e3 MKB |
839 | } |
840 | ||
eb79a267 | 841 | static inline u16 mcp251xfd_get_tef_obj_addr(u8 n) |
875347fe | 842 | { |
eb79a267 MKB |
843 | return MCP251XFD_RAM_START + |
844 | sizeof(struct mcp251xfd_hw_tef_obj) * n; | |
875347fe MKB |
845 | } |
846 | ||
847 | static inline u16 | |
eb79a267 | 848 | mcp251xfd_get_tx_obj_addr(const struct mcp251xfd_tx_ring *ring, u8 n) |
875347fe MKB |
849 | { |
850 | return ring->base + ring->obj_size * n; | |
851 | } | |
852 | ||
853 | static inline u16 | |
eb79a267 | 854 | mcp251xfd_get_rx_obj_addr(const struct mcp251xfd_rx_ring *ring, u8 n) |
875347fe MKB |
855 | { |
856 | return ring->base + ring->obj_size * n; | |
857 | } | |
858 | ||
1e846c7a MKB |
859 | static inline int |
860 | mcp251xfd_tx_tail_get_from_chip(const struct mcp251xfd_priv *priv, | |
861 | u8 *tx_tail) | |
862 | { | |
863 | u32 fifo_sta; | |
864 | int err; | |
865 | ||
866 | err = regmap_read(priv->map_reg, | |
c912f19e | 867 | MCP251XFD_REG_FIFOSTA(priv->tx->fifo_nr), |
1e846c7a MKB |
868 | &fifo_sta); |
869 | if (err) | |
870 | return err; | |
871 | ||
872 | *tx_tail = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta); | |
873 | ||
874 | return 0; | |
875 | } | |
876 | ||
eb79a267 | 877 | static inline u8 mcp251xfd_get_tef_head(const struct mcp251xfd_priv *priv) |
875347fe | 878 | { |
dada6a6c | 879 | return priv->tef->head & (priv->tx->obj_num - 1); |
875347fe MKB |
880 | } |
881 | ||
eb79a267 | 882 | static inline u8 mcp251xfd_get_tef_tail(const struct mcp251xfd_priv *priv) |
875347fe | 883 | { |
dada6a6c | 884 | return priv->tef->tail & (priv->tx->obj_num - 1); |
875347fe MKB |
885 | } |
886 | ||
b8e0ddd3 | 887 | static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv, u8 len) |
875347fe | 888 | { |
eb79a267 | 889 | return min_t(u8, len, priv->tx->obj_num - mcp251xfd_get_tef_tail(priv)); |
875347fe MKB |
890 | } |
891 | ||
eb79a267 | 892 | static inline u8 mcp251xfd_get_tx_head(const struct mcp251xfd_tx_ring *ring) |
875347fe MKB |
893 | { |
894 | return ring->head & (ring->obj_num - 1); | |
895 | } | |
896 | ||
eb79a267 | 897 | static inline u8 mcp251xfd_get_tx_tail(const struct mcp251xfd_tx_ring *ring) |
875347fe MKB |
898 | { |
899 | return ring->tail & (ring->obj_num - 1); | |
900 | } | |
901 | ||
eb79a267 | 902 | static inline u8 mcp251xfd_get_tx_free(const struct mcp251xfd_tx_ring *ring) |
875347fe MKB |
903 | { |
904 | return ring->obj_num - (ring->head - ring->tail); | |
905 | } | |
906 | ||
907 | static inline int | |
eb79a267 | 908 | mcp251xfd_get_tx_nr_by_addr(const struct mcp251xfd_tx_ring *tx_ring, u8 *nr, |
875347fe MKB |
909 | u16 addr) |
910 | { | |
eb79a267 MKB |
911 | if (addr < mcp251xfd_get_tx_obj_addr(tx_ring, 0) || |
912 | addr >= mcp251xfd_get_tx_obj_addr(tx_ring, tx_ring->obj_num)) | |
875347fe MKB |
913 | return -ENOENT; |
914 | ||
eb79a267 | 915 | *nr = (addr - mcp251xfd_get_tx_obj_addr(tx_ring, 0)) / |
875347fe MKB |
916 | tx_ring->obj_size; |
917 | ||
918 | return 0; | |
919 | } | |
920 | ||
eb79a267 | 921 | static inline u8 mcp251xfd_get_rx_head(const struct mcp251xfd_rx_ring *ring) |
875347fe MKB |
922 | { |
923 | return ring->head & (ring->obj_num - 1); | |
924 | } | |
925 | ||
eb79a267 | 926 | static inline u8 mcp251xfd_get_rx_tail(const struct mcp251xfd_rx_ring *ring) |
875347fe MKB |
927 | { |
928 | return ring->tail & (ring->obj_num - 1); | |
929 | } | |
930 | ||
875347fe | 931 | static inline u8 |
85505e58 | 932 | mcp251xfd_get_rx_linear_len(const struct mcp251xfd_rx_ring *ring, u8 len) |
875347fe | 933 | { |
eb79a267 | 934 | return min_t(u8, len, ring->obj_num - mcp251xfd_get_rx_tail(ring)); |
875347fe MKB |
935 | } |
936 | ||
eb79a267 | 937 | #define mcp251xfd_for_each_tx_obj(ring, _obj, n) \ |
875347fe MKB |
938 | for ((n) = 0, (_obj) = &(ring)->obj[(n)]; \ |
939 | (n) < (ring)->obj_num; \ | |
940 | (n)++, (_obj) = &(ring)->obj[(n)]) | |
941 | ||
eb79a267 | 942 | #define mcp251xfd_for_each_rx_ring(priv, ring, n) \ |
875347fe MKB |
943 | for ((n) = 0, (ring) = *((priv)->rx + (n)); \ |
944 | (n) < (priv)->rx_ring_num; \ | |
945 | (n)++, (ring) = *((priv)->rx + (n))) | |
946 | ||
335c818c | 947 | int mcp251xfd_chip_fifo_init(const struct mcp251xfd_priv *priv); |
eb79a267 | 948 | u16 mcp251xfd_crc16_compute2(const void *cmd, size_t cmd_size, |
875347fe | 949 | const void *data, size_t data_size); |
eb79a267 | 950 | u16 mcp251xfd_crc16_compute(const void *data, size_t data_size); |
d86ba8db | 951 | void mcp251xfd_ethtool_init(struct mcp251xfd_priv *priv); |
cae9071b | 952 | int mcp251xfd_regmap_init(struct mcp251xfd_priv *priv); |
9263c2e9 | 953 | extern const struct can_ram_config mcp251xfd_ram_config; |
fa0b68df | 954 | int mcp251xfd_ring_init(struct mcp251xfd_priv *priv); |
55bc37c8 MKB |
955 | void mcp251xfd_ring_free(struct mcp251xfd_priv *priv); |
956 | int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv); | |
319fdbc9 | 957 | int mcp251xfd_handle_rxif(struct mcp251xfd_priv *priv); |
1e846c7a | 958 | int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv); |
efd8d98d | 959 | void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv); |
a7801540 | 960 | void mcp251xfd_timestamp_start(struct mcp251xfd_priv *priv); |
efd8d98d | 961 | void mcp251xfd_timestamp_stop(struct mcp251xfd_priv *priv); |
875347fe | 962 | |
d8fb63e4 | 963 | void mcp251xfd_tx_obj_write_sync(struct work_struct *work); |
09b0eb92 MKB |
964 | netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb, |
965 | struct net_device *ndev); | |
966 | ||
e0ab3dd5 MKB |
967 | #if IS_ENABLED(CONFIG_DEV_COREDUMP) |
968 | void mcp251xfd_dump(const struct mcp251xfd_priv *priv); | |
969 | #else | |
970 | static inline void mcp251xfd_dump(const struct mcp251xfd_priv *priv) | |
971 | { | |
972 | } | |
973 | #endif | |
974 | ||
875347fe | 975 | #endif |