Commit | Line | Data |
---|---|---|
875347fe MKB |
1 | /* SPDX-License-Identifier: GPL-2.0 |
2 | * | |
eb79a267 | 3 | * mcp251xfd - Microchip MCP251xFD Family CAN controller driver |
875347fe | 4 | * |
aada7422 | 5 | * Copyright (c) 2019, 2020, 2021 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) | |
c9e6b80d MKB |
390 | |
391 | /* Misc */ | |
392 | #define MCP251XFD_NAPI_WEIGHT 32 | |
eb79a267 MKB |
393 | #define MCP251XFD_SOFTRESET_RETRIES_MAX 3 |
394 | #define MCP251XFD_READ_CRC_RETRIES_MAX 3 | |
395 | #define MCP251XFD_ECC_CNT_MAX 2 | |
396 | #define MCP251XFD_SANITIZE_SPI 1 | |
397 | #define MCP251XFD_SANITIZE_CAN 1 | |
875347fe | 398 | |
aada7422 MKB |
399 | /* FIFO and Ring */ |
400 | #define MCP251XFD_FIFO_TEF_NUM 1U | |
c9e6b80d | 401 | #define MCP251XFD_FIFO_RX_NUM 1U |
aada7422 MKB |
402 | #define MCP251XFD_FIFO_TX_NUM 1U |
403 | ||
0a1f2e65 MKB |
404 | #define MCP251XFD_FIFO_DEPTH 32U |
405 | ||
c9e6b80d MKB |
406 | #define MCP251XFD_RX_OBJ_NUM_MIN 16U |
407 | #define MCP251XFD_RX_OBJ_NUM_MAX (MCP251XFD_FIFO_RX_NUM * MCP251XFD_FIFO_DEPTH) | |
408 | #define MCP251XFD_RX_FIFO_DEPTH_MIN 4U | |
409 | ||
410 | #define MCP251XFD_TX_OBJ_NUM_MIN 2U | |
411 | #define MCP251XFD_TX_OBJ_NUM_MAX 8U | |
412 | #define MCP251XFD_TX_OBJ_NUM_CAN_DEFAULT 8U | |
413 | #define MCP251XFD_TX_OBJ_NUM_CANFD_DEFAULT 4U | |
414 | #define MCP251XFD_TX_FIFO_DEPTH_MIN 2U | |
415 | ||
aada7422 MKB |
416 | static_assert(MCP251XFD_FIFO_TEF_NUM == 1U); |
417 | static_assert(MCP251XFD_FIFO_TEF_NUM == MCP251XFD_FIFO_TX_NUM); | |
c9e6b80d | 418 | static_assert(MCP251XFD_FIFO_RX_NUM <= 4U); |
aada7422 | 419 | |
875347fe | 420 | /* Silence TX MAB overflow warnings */ |
eb79a267 | 421 | #define MCP251XFD_QUIRK_MAB_NO_WARN BIT(0) |
875347fe | 422 | /* Use CRC to access registers */ |
eb79a267 | 423 | #define MCP251XFD_QUIRK_CRC_REG BIT(1) |
875347fe | 424 | /* Use CRC to access RX/TEF-RAM */ |
eb79a267 | 425 | #define MCP251XFD_QUIRK_CRC_RX BIT(2) |
875347fe | 426 | /* Use CRC to access TX-RAM */ |
eb79a267 | 427 | #define MCP251XFD_QUIRK_CRC_TX BIT(3) |
875347fe | 428 | /* Enable ECC for RAM */ |
eb79a267 | 429 | #define MCP251XFD_QUIRK_ECC BIT(4) |
875347fe | 430 | /* Use Half Duplex SPI transfers */ |
eb79a267 | 431 | #define MCP251XFD_QUIRK_HALF_DUPLEX BIT(5) |
875347fe | 432 | |
eb79a267 | 433 | struct mcp251xfd_hw_tef_obj { |
875347fe MKB |
434 | u32 id; |
435 | u32 flags; | |
436 | u32 ts; | |
437 | }; | |
438 | ||
439 | /* The tx_obj_raw version is used in spi async, i.e. without | |
440 | * regmap. We have to take care of endianness ourselves. | |
441 | */ | |
eb79a267 | 442 | struct mcp251xfd_hw_tx_obj_raw { |
875347fe MKB |
443 | __le32 id; |
444 | __le32 flags; | |
445 | u8 data[sizeof_field(struct canfd_frame, data)]; | |
446 | }; | |
447 | ||
eb79a267 | 448 | struct mcp251xfd_hw_tx_obj_can { |
875347fe MKB |
449 | u32 id; |
450 | u32 flags; | |
451 | u8 data[sizeof_field(struct can_frame, data)]; | |
452 | }; | |
453 | ||
eb79a267 | 454 | struct mcp251xfd_hw_tx_obj_canfd { |
875347fe MKB |
455 | u32 id; |
456 | u32 flags; | |
457 | u8 data[sizeof_field(struct canfd_frame, data)]; | |
458 | }; | |
459 | ||
eb79a267 | 460 | struct mcp251xfd_hw_rx_obj_can { |
875347fe MKB |
461 | u32 id; |
462 | u32 flags; | |
463 | u32 ts; | |
464 | u8 data[sizeof_field(struct can_frame, data)]; | |
465 | }; | |
466 | ||
eb79a267 | 467 | struct mcp251xfd_hw_rx_obj_canfd { |
875347fe MKB |
468 | u32 id; |
469 | u32 flags; | |
470 | u32 ts; | |
471 | u8 data[sizeof_field(struct canfd_frame, data)]; | |
472 | }; | |
473 | ||
eb79a267 | 474 | struct __packed mcp251xfd_buf_cmd { |
875347fe MKB |
475 | __be16 cmd; |
476 | }; | |
477 | ||
eb79a267 | 478 | struct __packed mcp251xfd_buf_cmd_crc { |
875347fe MKB |
479 | __be16 cmd; |
480 | u8 len; | |
481 | }; | |
482 | ||
eb79a267 | 483 | union mcp251xfd_tx_obj_load_buf { |
875347fe | 484 | struct __packed { |
eb79a267 MKB |
485 | struct mcp251xfd_buf_cmd cmd; |
486 | struct mcp251xfd_hw_tx_obj_raw hw_tx_obj; | |
875347fe MKB |
487 | } nocrc; |
488 | struct __packed { | |
eb79a267 MKB |
489 | struct mcp251xfd_buf_cmd_crc cmd; |
490 | struct mcp251xfd_hw_tx_obj_raw hw_tx_obj; | |
875347fe MKB |
491 | __be16 crc; |
492 | } crc; | |
493 | } ____cacheline_aligned; | |
494 | ||
eb79a267 | 495 | union mcp251xfd_write_reg_buf { |
875347fe | 496 | struct __packed { |
eb79a267 | 497 | struct mcp251xfd_buf_cmd cmd; |
875347fe MKB |
498 | u8 data[4]; |
499 | } nocrc; | |
500 | struct __packed { | |
eb79a267 | 501 | struct mcp251xfd_buf_cmd_crc cmd; |
875347fe MKB |
502 | u8 data[4]; |
503 | __be16 crc; | |
504 | } crc; | |
505 | } ____cacheline_aligned; | |
506 | ||
eb79a267 | 507 | struct mcp251xfd_tx_obj { |
875347fe MKB |
508 | struct spi_message msg; |
509 | struct spi_transfer xfer[2]; | |
eb79a267 | 510 | union mcp251xfd_tx_obj_load_buf buf; |
875347fe MKB |
511 | }; |
512 | ||
63e70488 MKB |
513 | struct mcp251xfd_tef_ring { |
514 | unsigned int head; | |
515 | unsigned int tail; | |
516 | ||
517 | /* u8 obj_num equals tx_ring->obj_num */ | |
518 | /* u8 obj_size equals sizeof(struct mcp251xfd_hw_tef_obj) */ | |
68c0c1c7 MKB |
519 | |
520 | union mcp251xfd_write_reg_buf uinc_buf; | |
521 | struct spi_transfer uinc_xfer[MCP251XFD_TX_OBJ_NUM_MAX]; | |
63e70488 MKB |
522 | }; |
523 | ||
eb79a267 | 524 | struct mcp251xfd_tx_ring { |
875347fe MKB |
525 | unsigned int head; |
526 | unsigned int tail; | |
527 | ||
528 | u16 base; | |
c912f19e MKB |
529 | u8 nr; |
530 | u8 fifo_nr; | |
875347fe MKB |
531 | u8 obj_num; |
532 | u8 obj_size; | |
533 | ||
eb79a267 MKB |
534 | struct mcp251xfd_tx_obj obj[MCP251XFD_TX_OBJ_NUM_MAX]; |
535 | union mcp251xfd_write_reg_buf rts_buf; | |
875347fe MKB |
536 | }; |
537 | ||
eb79a267 | 538 | struct mcp251xfd_rx_ring { |
875347fe MKB |
539 | unsigned int head; |
540 | unsigned int tail; | |
541 | ||
542 | u16 base; | |
543 | u8 nr; | |
544 | u8 fifo_nr; | |
545 | u8 obj_num; | |
546 | u8 obj_size; | |
547 | ||
60a848c5 MKB |
548 | union mcp251xfd_write_reg_buf irq_enable_buf; |
549 | struct spi_transfer irq_enable_xfer; | |
550 | struct spi_message irq_enable_msg; | |
551 | ||
1f652bb6 | 552 | union mcp251xfd_write_reg_buf uinc_buf; |
60a848c5 | 553 | union mcp251xfd_write_reg_buf uinc_irq_disable_buf; |
c9e6b80d | 554 | struct spi_transfer uinc_xfer[MCP251XFD_FIFO_DEPTH]; |
eb79a267 | 555 | struct mcp251xfd_hw_rx_obj_canfd obj[]; |
875347fe MKB |
556 | }; |
557 | ||
eb79a267 MKB |
558 | struct __packed mcp251xfd_map_buf_nocrc { |
559 | struct mcp251xfd_buf_cmd cmd; | |
875347fe MKB |
560 | u8 data[256]; |
561 | } ____cacheline_aligned; | |
562 | ||
eb79a267 MKB |
563 | struct __packed mcp251xfd_map_buf_crc { |
564 | struct mcp251xfd_buf_cmd_crc cmd; | |
875347fe MKB |
565 | u8 data[256 - 4]; |
566 | __be16 crc; | |
567 | } ____cacheline_aligned; | |
568 | ||
eb79a267 | 569 | struct mcp251xfd_ecc { |
875347fe MKB |
570 | u32 ecc_stat; |
571 | int cnt; | |
572 | }; | |
573 | ||
eb79a267 | 574 | struct mcp251xfd_regs_status { |
875347fe | 575 | u32 intf; |
887e359d | 576 | u32 rxif; |
875347fe MKB |
577 | }; |
578 | ||
eb79a267 MKB |
579 | enum mcp251xfd_model { |
580 | MCP251XFD_MODEL_MCP2517FD = 0x2517, | |
581 | MCP251XFD_MODEL_MCP2518FD = 0x2518, | |
582 | MCP251XFD_MODEL_MCP251XFD = 0xffff, /* autodetect model */ | |
875347fe MKB |
583 | }; |
584 | ||
eb79a267 MKB |
585 | struct mcp251xfd_devtype_data { |
586 | enum mcp251xfd_model model; | |
875347fe MKB |
587 | u32 quirks; |
588 | }; | |
589 | ||
9263c2e9 | 590 | enum mcp251xfd_flags { |
60a848c5 | 591 | MCP251XFD_FLAGS_DOWN, |
9263c2e9 MKB |
592 | MCP251XFD_FLAGS_FD_MODE, |
593 | ||
594 | __MCP251XFD_FLAGS_SIZE__ | |
595 | }; | |
596 | ||
eb79a267 | 597 | struct mcp251xfd_priv { |
875347fe MKB |
598 | struct can_priv can; |
599 | struct can_rx_offload offload; | |
600 | struct net_device *ndev; | |
601 | ||
602 | struct regmap *map_reg; /* register access */ | |
603 | struct regmap *map_rx; /* RX/TEF RAM access */ | |
604 | ||
605 | struct regmap *map_nocrc; | |
eb79a267 MKB |
606 | struct mcp251xfd_map_buf_nocrc *map_buf_nocrc_rx; |
607 | struct mcp251xfd_map_buf_nocrc *map_buf_nocrc_tx; | |
875347fe MKB |
608 | |
609 | struct regmap *map_crc; | |
eb79a267 MKB |
610 | struct mcp251xfd_map_buf_crc *map_buf_crc_rx; |
611 | struct mcp251xfd_map_buf_crc *map_buf_crc_tx; | |
875347fe MKB |
612 | |
613 | struct spi_device *spi; | |
614 | u32 spi_max_speed_hz_orig; | |
2a68dd86 MKB |
615 | u32 spi_max_speed_hz_fast; |
616 | u32 spi_max_speed_hz_slow; | |
875347fe | 617 | |
aada7422 | 618 | struct mcp251xfd_tef_ring tef[MCP251XFD_FIFO_TEF_NUM]; |
c9e6b80d | 619 | struct mcp251xfd_rx_ring *rx[MCP251XFD_FIFO_RX_NUM]; |
aada7422 | 620 | struct mcp251xfd_tx_ring tx[MCP251XFD_FIFO_TX_NUM]; |
875347fe | 621 | |
9263c2e9 MKB |
622 | DECLARE_BITMAP(flags, __MCP251XFD_FLAGS_SIZE__); |
623 | ||
875347fe | 624 | u8 rx_ring_num; |
d86ba8db | 625 | u8 rx_obj_num; |
60a848c5 MKB |
626 | u8 rx_obj_num_coalesce_irq; |
627 | ||
628 | u32 rx_coalesce_usecs_irq; | |
629 | struct hrtimer rx_irq_timer; | |
875347fe | 630 | |
eb79a267 MKB |
631 | struct mcp251xfd_ecc ecc; |
632 | struct mcp251xfd_regs_status regs_status; | |
875347fe | 633 | |
efd8d98d MKB |
634 | struct cyclecounter cc; |
635 | struct timecounter tc; | |
636 | struct delayed_work timestamp; | |
637 | ||
875347fe MKB |
638 | struct gpio_desc *rx_int; |
639 | struct clk *clk; | |
2a68dd86 | 640 | bool pll_enable; |
875347fe MKB |
641 | struct regulator *reg_vdd; |
642 | struct regulator *reg_xceiver; | |
643 | ||
eb79a267 | 644 | struct mcp251xfd_devtype_data devtype_data; |
875347fe MKB |
645 | struct can_berr_counter bec; |
646 | }; | |
647 | ||
eb79a267 | 648 | #define MCP251XFD_IS(_model) \ |
875347fe | 649 | static inline bool \ |
eb79a267 | 650 | mcp251xfd_is_##_model(const struct mcp251xfd_priv *priv) \ |
875347fe | 651 | { \ |
eb79a267 | 652 | return priv->devtype_data.model == MCP251XFD_MODEL_MCP##_model##FD; \ |
875347fe MKB |
653 | } |
654 | ||
eb79a267 MKB |
655 | MCP251XFD_IS(2517); |
656 | MCP251XFD_IS(2518); | |
657 | MCP251XFD_IS(251X); | |
875347fe | 658 | |
3044a4f2 MKB |
659 | static inline bool mcp251xfd_is_fd_mode(const struct mcp251xfd_priv *priv) |
660 | { | |
661 | /* listen-only mode works like FD mode */ | |
662 | return priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY | CAN_CTRLMODE_FD); | |
663 | } | |
664 | ||
eb79a267 | 665 | static inline u8 mcp251xfd_first_byte_set(u32 mask) |
875347fe MKB |
666 | { |
667 | return (mask & 0x0000ffff) ? | |
668 | ((mask & 0x000000ff) ? 0 : 1) : | |
669 | ((mask & 0x00ff0000) ? 2 : 3); | |
670 | } | |
671 | ||
eb79a267 | 672 | static inline u8 mcp251xfd_last_byte_set(u32 mask) |
875347fe MKB |
673 | { |
674 | return (mask & 0xffff0000) ? | |
675 | ((mask & 0xff000000) ? 3 : 2) : | |
676 | ((mask & 0x0000ff00) ? 1 : 0); | |
677 | } | |
678 | ||
eb79a267 | 679 | static inline __be16 mcp251xfd_cmd_reset(void) |
875347fe | 680 | { |
eb79a267 | 681 | return cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_RESET); |
875347fe MKB |
682 | } |
683 | ||
684 | static inline void | |
eb79a267 | 685 | mcp251xfd_spi_cmd_read_nocrc(struct mcp251xfd_buf_cmd *cmd, u16 addr) |
875347fe | 686 | { |
eb79a267 | 687 | cmd->cmd = cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_READ | addr); |
875347fe MKB |
688 | } |
689 | ||
690 | static inline void | |
eb79a267 | 691 | mcp251xfd_spi_cmd_write_nocrc(struct mcp251xfd_buf_cmd *cmd, u16 addr) |
875347fe | 692 | { |
eb79a267 | 693 | cmd->cmd = cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_WRITE | addr); |
875347fe MKB |
694 | } |
695 | ||
eb79a267 | 696 | static inline bool mcp251xfd_reg_in_ram(unsigned int reg) |
875347fe MKB |
697 | { |
698 | static const struct regmap_range range = | |
eb79a267 MKB |
699 | regmap_reg_range(MCP251XFD_RAM_START, |
700 | MCP251XFD_RAM_START + MCP251XFD_RAM_SIZE - 4); | |
875347fe MKB |
701 | |
702 | return regmap_reg_in_range(reg, &range); | |
703 | } | |
704 | ||
705 | static inline void | |
eb79a267 | 706 | __mcp251xfd_spi_cmd_crc_set_len(struct mcp251xfd_buf_cmd_crc *cmd, |
875347fe MKB |
707 | u16 len, bool in_ram) |
708 | { | |
709 | /* Number of u32 for RAM access, number of u8 otherwise. */ | |
710 | if (in_ram) | |
711 | cmd->len = len >> 2; | |
712 | else | |
713 | cmd->len = len; | |
714 | } | |
715 | ||
716 | static inline void | |
eb79a267 | 717 | mcp251xfd_spi_cmd_crc_set_len_in_ram(struct mcp251xfd_buf_cmd_crc *cmd, u16 len) |
875347fe | 718 | { |
eb79a267 | 719 | __mcp251xfd_spi_cmd_crc_set_len(cmd, len, true); |
875347fe MKB |
720 | } |
721 | ||
722 | static inline void | |
eb79a267 | 723 | mcp251xfd_spi_cmd_crc_set_len_in_reg(struct mcp251xfd_buf_cmd_crc *cmd, u16 len) |
875347fe | 724 | { |
eb79a267 | 725 | __mcp251xfd_spi_cmd_crc_set_len(cmd, len, false); |
875347fe MKB |
726 | } |
727 | ||
728 | static inline void | |
eb79a267 | 729 | mcp251xfd_spi_cmd_read_crc_set_addr(struct mcp251xfd_buf_cmd_crc *cmd, u16 addr) |
875347fe | 730 | { |
eb79a267 | 731 | cmd->cmd = cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_READ_CRC | addr); |
875347fe MKB |
732 | } |
733 | ||
734 | static inline void | |
eb79a267 | 735 | mcp251xfd_spi_cmd_read_crc(struct mcp251xfd_buf_cmd_crc *cmd, |
875347fe MKB |
736 | u16 addr, u16 len) |
737 | { | |
eb79a267 MKB |
738 | mcp251xfd_spi_cmd_read_crc_set_addr(cmd, addr); |
739 | __mcp251xfd_spi_cmd_crc_set_len(cmd, len, mcp251xfd_reg_in_ram(addr)); | |
875347fe MKB |
740 | } |
741 | ||
742 | static inline void | |
eb79a267 | 743 | mcp251xfd_spi_cmd_write_crc_set_addr(struct mcp251xfd_buf_cmd_crc *cmd, |
875347fe MKB |
744 | u16 addr) |
745 | { | |
eb79a267 | 746 | cmd->cmd = cpu_to_be16(MCP251XFD_SPI_INSTRUCTION_WRITE_CRC | addr); |
875347fe MKB |
747 | } |
748 | ||
749 | static inline void | |
eb79a267 | 750 | mcp251xfd_spi_cmd_write_crc(struct mcp251xfd_buf_cmd_crc *cmd, |
875347fe MKB |
751 | u16 addr, u16 len) |
752 | { | |
eb79a267 MKB |
753 | mcp251xfd_spi_cmd_write_crc_set_addr(cmd, addr); |
754 | __mcp251xfd_spi_cmd_crc_set_len(cmd, len, mcp251xfd_reg_in_ram(addr)); | |
875347fe MKB |
755 | } |
756 | ||
757 | static inline u8 * | |
eb79a267 MKB |
758 | mcp251xfd_spi_cmd_write(const struct mcp251xfd_priv *priv, |
759 | union mcp251xfd_write_reg_buf *write_reg_buf, | |
875347fe MKB |
760 | u16 addr) |
761 | { | |
762 | u8 *data; | |
763 | ||
eb79a267 MKB |
764 | if (priv->devtype_data.quirks & MCP251XFD_QUIRK_CRC_REG) { |
765 | mcp251xfd_spi_cmd_write_crc_set_addr(&write_reg_buf->crc.cmd, | |
875347fe MKB |
766 | addr); |
767 | data = write_reg_buf->crc.data; | |
768 | } else { | |
eb79a267 | 769 | mcp251xfd_spi_cmd_write_nocrc(&write_reg_buf->nocrc.cmd, |
875347fe MKB |
770 | addr); |
771 | data = write_reg_buf->nocrc.data; | |
772 | } | |
773 | ||
774 | return data; | |
775 | } | |
776 | ||
dc09e7e3 MKB |
777 | static inline int mcp251xfd_get_timestamp(const struct mcp251xfd_priv *priv, |
778 | u32 *timestamp) | |
779 | { | |
780 | return regmap_read(priv->map_reg, MCP251XFD_REG_TBC, timestamp); | |
781 | } | |
782 | ||
eb79a267 | 783 | static inline u16 mcp251xfd_get_tef_obj_addr(u8 n) |
875347fe | 784 | { |
eb79a267 MKB |
785 | return MCP251XFD_RAM_START + |
786 | sizeof(struct mcp251xfd_hw_tef_obj) * n; | |
875347fe MKB |
787 | } |
788 | ||
789 | static inline u16 | |
eb79a267 | 790 | mcp251xfd_get_tx_obj_addr(const struct mcp251xfd_tx_ring *ring, u8 n) |
875347fe MKB |
791 | { |
792 | return ring->base + ring->obj_size * n; | |
793 | } | |
794 | ||
795 | static inline u16 | |
eb79a267 | 796 | mcp251xfd_get_rx_obj_addr(const struct mcp251xfd_rx_ring *ring, u8 n) |
875347fe MKB |
797 | { |
798 | return ring->base + ring->obj_size * n; | |
799 | } | |
800 | ||
1e846c7a MKB |
801 | static inline int |
802 | mcp251xfd_tx_tail_get_from_chip(const struct mcp251xfd_priv *priv, | |
803 | u8 *tx_tail) | |
804 | { | |
805 | u32 fifo_sta; | |
806 | int err; | |
807 | ||
808 | err = regmap_read(priv->map_reg, | |
c912f19e | 809 | MCP251XFD_REG_FIFOSTA(priv->tx->fifo_nr), |
1e846c7a MKB |
810 | &fifo_sta); |
811 | if (err) | |
812 | return err; | |
813 | ||
814 | *tx_tail = FIELD_GET(MCP251XFD_REG_FIFOSTA_FIFOCI_MASK, fifo_sta); | |
815 | ||
816 | return 0; | |
817 | } | |
818 | ||
eb79a267 | 819 | static inline u8 mcp251xfd_get_tef_head(const struct mcp251xfd_priv *priv) |
875347fe | 820 | { |
dada6a6c | 821 | return priv->tef->head & (priv->tx->obj_num - 1); |
875347fe MKB |
822 | } |
823 | ||
eb79a267 | 824 | static inline u8 mcp251xfd_get_tef_tail(const struct mcp251xfd_priv *priv) |
875347fe | 825 | { |
dada6a6c | 826 | return priv->tef->tail & (priv->tx->obj_num - 1); |
875347fe MKB |
827 | } |
828 | ||
eb79a267 | 829 | static inline u8 mcp251xfd_get_tef_len(const struct mcp251xfd_priv *priv) |
875347fe | 830 | { |
dada6a6c | 831 | return priv->tef->head - priv->tef->tail; |
875347fe MKB |
832 | } |
833 | ||
eb79a267 | 834 | static inline u8 mcp251xfd_get_tef_linear_len(const struct mcp251xfd_priv *priv) |
875347fe MKB |
835 | { |
836 | u8 len; | |
837 | ||
eb79a267 | 838 | len = mcp251xfd_get_tef_len(priv); |
875347fe | 839 | |
eb79a267 | 840 | return min_t(u8, len, priv->tx->obj_num - mcp251xfd_get_tef_tail(priv)); |
875347fe MKB |
841 | } |
842 | ||
eb79a267 | 843 | static inline u8 mcp251xfd_get_tx_head(const struct mcp251xfd_tx_ring *ring) |
875347fe MKB |
844 | { |
845 | return ring->head & (ring->obj_num - 1); | |
846 | } | |
847 | ||
eb79a267 | 848 | static inline u8 mcp251xfd_get_tx_tail(const struct mcp251xfd_tx_ring *ring) |
875347fe MKB |
849 | { |
850 | return ring->tail & (ring->obj_num - 1); | |
851 | } | |
852 | ||
eb79a267 | 853 | static inline u8 mcp251xfd_get_tx_free(const struct mcp251xfd_tx_ring *ring) |
875347fe MKB |
854 | { |
855 | return ring->obj_num - (ring->head - ring->tail); | |
856 | } | |
857 | ||
858 | static inline int | |
eb79a267 | 859 | mcp251xfd_get_tx_nr_by_addr(const struct mcp251xfd_tx_ring *tx_ring, u8 *nr, |
875347fe MKB |
860 | u16 addr) |
861 | { | |
eb79a267 MKB |
862 | if (addr < mcp251xfd_get_tx_obj_addr(tx_ring, 0) || |
863 | addr >= mcp251xfd_get_tx_obj_addr(tx_ring, tx_ring->obj_num)) | |
875347fe MKB |
864 | return -ENOENT; |
865 | ||
eb79a267 | 866 | *nr = (addr - mcp251xfd_get_tx_obj_addr(tx_ring, 0)) / |
875347fe MKB |
867 | tx_ring->obj_size; |
868 | ||
869 | return 0; | |
870 | } | |
871 | ||
eb79a267 | 872 | static inline u8 mcp251xfd_get_rx_head(const struct mcp251xfd_rx_ring *ring) |
875347fe MKB |
873 | { |
874 | return ring->head & (ring->obj_num - 1); | |
875 | } | |
876 | ||
eb79a267 | 877 | static inline u8 mcp251xfd_get_rx_tail(const struct mcp251xfd_rx_ring *ring) |
875347fe MKB |
878 | { |
879 | return ring->tail & (ring->obj_num - 1); | |
880 | } | |
881 | ||
eb79a267 | 882 | static inline u8 mcp251xfd_get_rx_len(const struct mcp251xfd_rx_ring *ring) |
875347fe MKB |
883 | { |
884 | return ring->head - ring->tail; | |
885 | } | |
886 | ||
887 | static inline u8 | |
eb79a267 | 888 | mcp251xfd_get_rx_linear_len(const struct mcp251xfd_rx_ring *ring) |
875347fe MKB |
889 | { |
890 | u8 len; | |
891 | ||
eb79a267 | 892 | len = mcp251xfd_get_rx_len(ring); |
875347fe | 893 | |
eb79a267 | 894 | return min_t(u8, len, ring->obj_num - mcp251xfd_get_rx_tail(ring)); |
875347fe MKB |
895 | } |
896 | ||
eb79a267 | 897 | #define mcp251xfd_for_each_tx_obj(ring, _obj, n) \ |
875347fe MKB |
898 | for ((n) = 0, (_obj) = &(ring)->obj[(n)]; \ |
899 | (n) < (ring)->obj_num; \ | |
900 | (n)++, (_obj) = &(ring)->obj[(n)]) | |
901 | ||
eb79a267 | 902 | #define mcp251xfd_for_each_rx_ring(priv, ring, n) \ |
875347fe MKB |
903 | for ((n) = 0, (ring) = *((priv)->rx + (n)); \ |
904 | (n) < (priv)->rx_ring_num; \ | |
905 | (n)++, (ring) = *((priv)->rx + (n))) | |
906 | ||
335c818c | 907 | int mcp251xfd_chip_fifo_init(const struct mcp251xfd_priv *priv); |
eb79a267 | 908 | u16 mcp251xfd_crc16_compute2(const void *cmd, size_t cmd_size, |
875347fe | 909 | const void *data, size_t data_size); |
eb79a267 | 910 | u16 mcp251xfd_crc16_compute(const void *data, size_t data_size); |
d86ba8db | 911 | void mcp251xfd_ethtool_init(struct mcp251xfd_priv *priv); |
cae9071b | 912 | int mcp251xfd_regmap_init(struct mcp251xfd_priv *priv); |
9263c2e9 | 913 | extern const struct can_ram_config mcp251xfd_ram_config; |
fa0b68df | 914 | int mcp251xfd_ring_init(struct mcp251xfd_priv *priv); |
55bc37c8 MKB |
915 | void mcp251xfd_ring_free(struct mcp251xfd_priv *priv); |
916 | int mcp251xfd_ring_alloc(struct mcp251xfd_priv *priv); | |
319fdbc9 | 917 | int mcp251xfd_handle_rxif(struct mcp251xfd_priv *priv); |
1e846c7a | 918 | int mcp251xfd_handle_tefif(struct mcp251xfd_priv *priv); |
b2fcc707 | 919 | void mcp251xfd_skb_set_timestamp(const struct mcp251xfd_priv *priv, |
efd8d98d MKB |
920 | struct sk_buff *skb, u32 timestamp); |
921 | void mcp251xfd_timestamp_init(struct mcp251xfd_priv *priv); | |
922 | void mcp251xfd_timestamp_stop(struct mcp251xfd_priv *priv); | |
875347fe | 923 | |
09b0eb92 MKB |
924 | netdev_tx_t mcp251xfd_start_xmit(struct sk_buff *skb, |
925 | struct net_device *ndev); | |
926 | ||
e0ab3dd5 MKB |
927 | #if IS_ENABLED(CONFIG_DEV_COREDUMP) |
928 | void mcp251xfd_dump(const struct mcp251xfd_priv *priv); | |
929 | #else | |
930 | static inline void mcp251xfd_dump(const struct mcp251xfd_priv *priv) | |
931 | { | |
932 | } | |
933 | #endif | |
934 | ||
875347fe | 935 | #endif |