1 /*
2  * Copyright (c) 2023 Vestas Wind Systems A/S
3  * Copyright (c) 2020 Alexander Wachter
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  */
8 
9 #ifndef ZEPHYR_INCLUDE_DRIVERS_CAN_CAN_MCAN_H_
10 #define ZEPHYR_INCLUDE_DRIVERS_CAN_CAN_MCAN_H_
11 
12 #include <zephyr/cache.h>
13 #include <zephyr/devicetree.h>
14 #include <zephyr/drivers/can.h>
15 #include <zephyr/kernel.h>
16 #include <zephyr/sys/sys_io.h>
17 #include <zephyr/sys/util.h>
18 
19 /*
20  * The Bosch M_CAN register definitions correspond to those found in the Bosch M_CAN Controller Area
21  * Network User's Manual, Revision 3.3.0.
22  */
23 
24 /* Core Release register */
25 #define CAN_MCAN_CREL         0x000
26 #define CAN_MCAN_CREL_REL     GENMASK(31, 28)
27 #define CAN_MCAN_CREL_STEP    GENMASK(27, 24)
28 #define CAN_MCAN_CREL_SUBSTEP GENMASK(23, 20)
29 #define CAN_MCAN_CREL_YEAR    GENMASK(19, 16)
30 #define CAN_MCAN_CREL_MON     GENMASK(15, 8)
31 #define CAN_MCAN_CREL_DAY     GENMASK(7, 0)
32 
33 /* Endian register */
34 #define CAN_MCAN_ENDN     0x004
35 #define CAN_MCAN_ENDN_ETV GENMASK(31, 0)
36 
37 /* Customer register */
38 #define CAN_MCAN_CUST      0x008
39 #define CAN_MCAN_CUST_CUST GENMASK(31, 0)
40 
41 /* Data Bit Timing & Prescaler register */
42 #define CAN_MCAN_DBTP        0x00C
43 #define CAN_MCAN_DBTP_TDC    BIT(23)
44 #define CAN_MCAN_DBTP_DBRP   GENMASK(20, 16)
45 #define CAN_MCAN_DBTP_DTSEG1 GENMASK(12, 8)
46 #define CAN_MCAN_DBTP_DTSEG2 GENMASK(7, 4)
47 #define CAN_MCAN_DBTP_DSJW   GENMASK(3, 0)
48 
49 /* Test register */
50 #define CAN_MCAN_TEST       0x010
51 #define CAN_MCAN_TEST_SVAL  BIT(21)
52 #define CAN_MCAN_TEST_TXBNS GENMASK(20, 16)
53 #define CAN_MCAN_TEST_PVAL  BIT(13)
54 #define CAN_MCAN_TEST_TXBNP GENMASK(12, 8)
55 #define CAN_MCAN_TEST_RX    BIT(7)
56 #define CAN_MCAN_TEST_TX    GENMASK(6, 5)
57 #define CAN_MCAN_TEST_LBCK  BIT(4)
58 
59 /* RAM Watchdog register */
60 #define CAN_MCAN_RWD     0x014
61 #define CAN_MCAN_RWD_WDV GENMASK(15, 8)
62 #define CAN_MCAN_RWD_WDC GENMASK(7, 0)
63 
64 /* CC Control register */
65 #define CAN_MCAN_CCCR      0x018
66 #define CAN_MCAN_CCCR_NISO BIT(15)
67 #define CAN_MCAN_CCCR_TXP  BIT(14)
68 #define CAN_MCAN_CCCR_EFBI BIT(13)
69 #define CAN_MCAN_CCCR_PXHD BIT(12)
70 #define CAN_MCAN_CCCR_WMM  BIT(11)
71 #define CAN_MCAN_CCCR_UTSU BIT(10)
72 #define CAN_MCAN_CCCR_BRSE BIT(9)
73 #define CAN_MCAN_CCCR_FDOE BIT(8)
74 #define CAN_MCAN_CCCR_TEST BIT(7)
75 #define CAN_MCAN_CCCR_DAR  BIT(6)
76 #define CAN_MCAN_CCCR_MON  BIT(5)
77 #define CAN_MCAN_CCCR_CSR  BIT(4)
78 #define CAN_MCAN_CCCR_CSA  BIT(3)
79 #define CAN_MCAN_CCCR_ASM  BIT(2)
80 #define CAN_MCAN_CCCR_CCE  BIT(1)
81 #define CAN_MCAN_CCCR_INIT BIT(0)
82 
83 /* Nominal Bit Timing & Prescaler register */
84 #define CAN_MCAN_NBTP        0x01C
85 #define CAN_MCAN_NBTP_NSJW   GENMASK(31, 25)
86 #define CAN_MCAN_NBTP_NBRP   GENMASK(24, 16)
87 #define CAN_MCAN_NBTP_NTSEG1 GENMASK(15, 8)
88 #define CAN_MCAN_NBTP_NTSEG2 GENMASK(6, 0)
89 
90 /* Timestamp Counter Configuration register */
91 #define CAN_MCAN_TSCC     0x020
92 #define CAN_MCAN_TSCC_TCP GENMASK(19, 16)
93 #define CAN_MCAN_TSCC_TSS GENMASK(1, 0)
94 
95 /* Timestamp Counter Value register */
96 #define CAN_MCAN_TSCV     0x024
97 #define CAN_MCAN_TSCV_TSC GENMASK(15, 0)
98 
99 /* Timeout Counter Configuration register */
100 #define CAN_MCAN_TOCC      0x028
101 #define CAN_MCAN_TOCC_TOP  GENMASK(31, 16)
102 #define CAN_MCAN_TOCC_TOS  GENMASK(2, 1)
103 #define CAN_MCAN_TOCC_ETOC BIT(1)
104 
105 /* Timeout Counter Value register */
106 #define CAN_MCAN_TOCV     0x02C
107 #define CAN_MCAN_TOCV_TOC GENMASK(15, 0)
108 
109 /* Error Counter register */
110 #define CAN_MCAN_ECR     0x040
111 #define CAN_MCAN_ECR_CEL GENMASK(23, 16)
112 #define CAN_MCAN_ECR_RP  BIT(15)
113 #define CAN_MCAN_ECR_REC GENMASK(14, 8)
114 #define CAN_MCAN_ECR_TEC GENMASK(7, 0)
115 
116 /* Protocol Status register */
117 #define CAN_MCAN_PSR      0x044
118 #define CAN_MCAN_PSR_TDCV GENMASK(22, 16)
119 #define CAN_MCAN_PSR_PXE  BIT(14)
120 #define CAN_MCAN_PSR_RFDF BIT(13)
121 #define CAN_MCAN_PSR_RBRS BIT(12)
122 #define CAN_MCAN_PSR_RESI BIT(11)
123 #define CAN_MCAN_PSR_DLEC GENMASK(10, 8)
124 #define CAN_MCAN_PSR_BO   BIT(7)
125 #define CAN_MCAN_PSR_EW   BIT(6)
126 #define CAN_MCAN_PSR_EP   BIT(5)
127 #define CAN_MCAN_PSR_ACT  GENMASK(4, 3)
128 #define CAN_MCAN_PSR_LEC  GENMASK(2, 0)
129 
130 enum can_mcan_psr_lec {
131 	CAN_MCAN_PSR_LEC_NO_ERROR    = 0,
132 	CAN_MCAN_PSR_LEC_STUFF_ERROR = 1,
133 	CAN_MCAN_PSR_LEC_FORM_ERROR  = 2,
134 	CAN_MCAN_PSR_LEC_ACK_ERROR   = 3,
135 	CAN_MCAN_PSR_LEC_BIT1_ERROR  = 4,
136 	CAN_MCAN_PSR_LEC_BIT0_ERROR  = 5,
137 	CAN_MCAN_PSR_LEC_CRC_ERROR   = 6,
138 	CAN_MCAN_PSR_LEC_NO_CHANGE   = 7
139 };
140 
141 /* Transmitter Delay Compensation register */
142 #define CAN_MCAN_TDCR      0x048
143 #define CAN_MCAN_TDCR_TDCO GENMASK(14, 8)
144 #define CAN_MCAN_TDCR_TDCF GENMASK(6, 0)
145 
146 /* Interrupt register */
147 #define CAN_MCAN_IR      0x050
148 #define CAN_MCAN_IR_ARA  BIT(29)
149 #define CAN_MCAN_IR_PED  BIT(28)
150 #define CAN_MCAN_IR_PEA  BIT(27)
151 #define CAN_MCAN_IR_WDI  BIT(26)
152 #define CAN_MCAN_IR_BO   BIT(25)
153 #define CAN_MCAN_IR_EW   BIT(24)
154 #define CAN_MCAN_IR_EP   BIT(23)
155 #define CAN_MCAN_IR_ELO  BIT(22)
156 #define CAN_MCAN_IR_BEU  BIT(21)
157 #define CAN_MCAN_IR_BEC  BIT(20)
158 #define CAN_MCAN_IR_DRX  BIT(19)
159 #define CAN_MCAN_IR_TOO  BIT(18)
160 #define CAN_MCAN_IR_MRAF BIT(17)
161 #define CAN_MCAN_IR_TSW  BIT(16)
162 #define CAN_MCAN_IR_TEFL BIT(15)
163 #define CAN_MCAN_IR_TEFF BIT(14)
164 #define CAN_MCAN_IR_TEFW BIT(13)
165 #define CAN_MCAN_IR_TEFN BIT(12)
166 #define CAN_MCAN_IR_TFE  BIT(11)
167 #define CAN_MCAN_IR_TCF  BIT(10)
168 #define CAN_MCAN_IR_TC   BIT(9)
169 #define CAN_MCAN_IR_HPM  BIT(8)
170 #define CAN_MCAN_IR_RF1L BIT(7)
171 #define CAN_MCAN_IR_RF1F BIT(6)
172 #define CAN_MCAN_IR_RF1W BIT(5)
173 #define CAN_MCAN_IR_RF1N BIT(4)
174 #define CAN_MCAN_IR_RF0L BIT(3)
175 #define CAN_MCAN_IR_RF0F BIT(2)
176 #define CAN_MCAN_IR_RF0W BIT(1)
177 #define CAN_MCAN_IR_RF0N BIT(0)
178 
179 /* Interrupt Enable register */
180 #define CAN_MCAN_IE       0x054
181 #define CAN_MCAN_IE_ARAE  BIT(29)
182 #define CAN_MCAN_IE_PEDE  BIT(28)
183 #define CAN_MCAN_IE_PEAE  BIT(27)
184 #define CAN_MCAN_IE_WDIE  BIT(26)
185 #define CAN_MCAN_IE_BOE   BIT(25)
186 #define CAN_MCAN_IE_EWE   BIT(24)
187 #define CAN_MCAN_IE_EPE   BIT(23)
188 #define CAN_MCAN_IE_ELOE  BIT(22)
189 #define CAN_MCAN_IE_BEUE  BIT(21)
190 #define CAN_MCAN_IE_BECE  BIT(20)
191 #define CAN_MCAN_IE_DRXE  BIT(19)
192 #define CAN_MCAN_IE_TOOE  BIT(18)
193 #define CAN_MCAN_IE_MRAFE BIT(17)
194 #define CAN_MCAN_IE_TSWE  BIT(16)
195 #define CAN_MCAN_IE_TEFLE BIT(15)
196 #define CAN_MCAN_IE_TEFFE BIT(14)
197 #define CAN_MCAN_IE_TEFWE BIT(13)
198 #define CAN_MCAN_IE_TEFNE BIT(12)
199 #define CAN_MCAN_IE_TFEE  BIT(11)
200 #define CAN_MCAN_IE_TCFE  BIT(10)
201 #define CAN_MCAN_IE_TCE   BIT(9)
202 #define CAN_MCAN_IE_HPME  BIT(8)
203 #define CAN_MCAN_IE_RF1LE BIT(7)
204 #define CAN_MCAN_IE_RF1FE BIT(6)
205 #define CAN_MCAN_IE_RF1WE BIT(5)
206 #define CAN_MCAN_IE_RF1NE BIT(4)
207 #define CAN_MCAN_IE_RF0LE BIT(3)
208 #define CAN_MCAN_IE_RF0FE BIT(2)
209 #define CAN_MCAN_IE_RF0WE BIT(1)
210 #define CAN_MCAN_IE_RF0NE BIT(0)
211 
212 /* Interrupt Line Select register */
213 #define CAN_MCAN_ILS       0x058
214 #define CAN_MCAN_ILS_ARAL  BIT(29)
215 #define CAN_MCAN_ILS_PEDL  BIT(28)
216 #define CAN_MCAN_ILS_PEAL  BIT(27)
217 #define CAN_MCAN_ILS_WDIL  BIT(26)
218 #define CAN_MCAN_ILS_BOL   BIT(25)
219 #define CAN_MCAN_ILS_EWL   BIT(24)
220 #define CAN_MCAN_ILS_EPL   BIT(23)
221 #define CAN_MCAN_ILS_ELOL  BIT(22)
222 #define CAN_MCAN_ILS_BEUL  BIT(21)
223 #define CAN_MCAN_ILS_BECL  BIT(20)
224 #define CAN_MCAN_ILS_DRXL  BIT(19)
225 #define CAN_MCAN_ILS_TOOL  BIT(18)
226 #define CAN_MCAN_ILS_MRAFL BIT(17)
227 #define CAN_MCAN_ILS_TSWL  BIT(16)
228 #define CAN_MCAN_ILS_TEFLL BIT(15)
229 #define CAN_MCAN_ILS_TEFFL BIT(14)
230 #define CAN_MCAN_ILS_TEFWL BIT(13)
231 #define CAN_MCAN_ILS_TEFNL BIT(12)
232 #define CAN_MCAN_ILS_TFEL  BIT(11)
233 #define CAN_MCAN_ILS_TCFL  BIT(10)
234 #define CAN_MCAN_ILS_TCL   BIT(9)
235 #define CAN_MCAN_ILS_HPML  BIT(8)
236 #define CAN_MCAN_ILS_RF1LL BIT(7)
237 #define CAN_MCAN_ILS_RF1FL BIT(6)
238 #define CAN_MCAN_ILS_RF1WL BIT(5)
239 #define CAN_MCAN_ILS_RF1NL BIT(4)
240 #define CAN_MCAN_ILS_RF0LL BIT(3)
241 #define CAN_MCAN_ILS_RF0FL BIT(2)
242 #define CAN_MCAN_ILS_RF0WL BIT(1)
243 #define CAN_MCAN_ILS_RF0NL BIT(0)
244 
245 /* Interrupt Line Enable register */
246 #define CAN_MCAN_ILE       0x05C
247 #define CAN_MCAN_ILE_EINT1 BIT(1)
248 #define CAN_MCAN_ILE_EINT0 BIT(0)
249 
250 /* Global filter configuration register */
251 #define CAN_MCAN_GFC      0x080
252 #define CAN_MCAN_GFC_ANFS GENMASK(5, 4)
253 #define CAN_MCAN_GFC_ANFE GENMASK(3, 2)
254 #define CAN_MCAN_GFC_RRFS BIT(1)
255 #define CAN_MCAN_GFC_RRFE BIT(0)
256 
257 /* Standard ID Filter Configuration register */
258 #define CAN_MCAN_SIDFC       0x084
259 #define CAN_MCAN_SIDFC_LSS   GENMASK(23, 16)
260 #define CAN_MCAN_SIDFC_FLSSA GENMASK(15, 2)
261 
262 /* Extended ID Filter Configuration register */
263 #define CAN_MCAN_XIDFC       0x088
264 #define CAN_MCAN_XIDFC_LSS   GENMASK(22, 16)
265 #define CAN_MCAN_XIDFC_FLESA GENMASK(15, 2)
266 
267 /* Extended ID AND Mask register */
268 #define CAN_MCAN_XIDAM      0x090
269 #define CAN_MCAN_XIDAM_EIDM GENMASK(28, 0)
270 
271 /* High Priority Message Status register */
272 #define CAN_MCAN_HPMS      0x094
273 #define CAN_MCAN_HPMS_FLST BIT(15)
274 #define CAN_MCAN_HPMS_FIDX GENMASK(14, 8)
275 #define CAN_MCAN_HPMS_MSI  GENMASK(7, 6)
276 #define CAN_MCAN_HPMS_BIDX GENMASK(5, 0)
277 
278 /* New Data 1 register */
279 #define CAN_MCAN_NDAT1    0x098
280 #define CAN_MCAN_NDAT1_ND GENMASK(31, 0)
281 
282 /* New Data 2 register */
283 #define CAN_MCAN_NDAT2    0x09C
284 #define CAN_MCAN_NDAT2_ND GENMASK(31, 0)
285 
286 /* Rx FIFO 0 Configuration register */
287 #define CAN_MCAN_RXF0C      0x0A0
288 #define CAN_MCAN_RXF0C_F0OM BIT(31)
289 #define CAN_MCAN_RXF0C_F0WM GENMASK(30, 24)
290 #define CAN_MCAN_RXF0C_F0S  GENMASK(22, 16)
291 #define CAN_MCAN_RXF0C_F0SA GENMASK(15, 2)
292 
293 /* Rx FIFO 0 Status register */
294 #define CAN_MCAN_RXF0S      0x0A4
295 #define CAN_MCAN_RXF0S_RF0L BIT(25)
296 #define CAN_MCAN_RXF0S_F0F  BIT(24)
297 #define CAN_MCAN_RXF0S_F0PI GENMASK(21, 16)
298 #define CAN_MCAN_RXF0S_F0GI GENMASK(13, 8)
299 #define CAN_MCAN_RXF0S_F0FL GENMASK(6, 0)
300 
301 /* Rx FIFO 0 Acknowledge register */
302 #define CAN_MCAN_RXF0A      0x0A8
303 #define CAN_MCAN_RXF0A_F0AI GENMASK(5, 0)
304 
305 /* Rx Buffer Configuration register */
306 #define CAN_MCAN_RXBC      0x0AC
307 #define CAN_MCAN_RXBC_RBSA GENMASK(15, 2)
308 
309 /* Rx FIFO 1 Configuration register */
310 #define CAN_MCAN_RXF1C      0x0B0
311 #define CAN_MCAN_RXF1C_F1OM BIT(31)
312 #define CAN_MCAN_RXF1C_F1WM GENMASK(30, 24)
313 #define CAN_MCAN_RXF1C_F1S  GENMASK(22, 16)
314 #define CAN_MCAN_RXF1C_F1SA GENMASK(15, 2)
315 
316 /* Rx FIFO 1 Status register */
317 #define CAN_MCAN_RXF1S      0x0B4
318 #define CAN_MCAN_RXF1S_RF1L BIT(25)
319 #define CAN_MCAN_RXF1S_F1F  BIT(24)
320 #define CAN_MCAN_RXF1S_F1PI GENMASK(21, 16)
321 #define CAN_MCAN_RXF1S_F1GI GENMASK(13, 8)
322 #define CAN_MCAN_RXF1S_F1FL GENMASK(6, 0)
323 
324 /* Rx FIFO 1 Acknowledge register */
325 #define CAN_MCAN_RXF1A      0x0B8
326 #define CAN_MCAN_RXF1A_F1AI GENMASK(5, 0)
327 
328 /* Rx Buffer/FIFO Element Size Configuration register */
329 #define CAN_MCAN_RXESC      0x0BC
330 #define CAN_MCAN_RXESC_RBDS GENMASK(10, 8)
331 #define CAN_MCAN_RXESC_F1DS GENMASK(6, 4)
332 #define CAN_MCAN_RXESC_F0DS GENMASK(2, 0)
333 
334 /* Tx Buffer Configuration register */
335 #define CAN_MCAN_TXBC      0x0C0
336 #define CAN_MCAN_TXBC_TFQM BIT(30)
337 #define CAN_MCAN_TXBC_TFQS GENMASK(29, 24)
338 #define CAN_MCAN_TXBC_NDTB GENMASK(21, 16)
339 #define CAN_MCAN_TXBC_TBSA GENMASK(15, 2)
340 
341 /* Tx FIFO/Queue Status register */
342 #define CAN_MCAN_TXFQS       0x0C4
343 #define CAN_MCAN_TXFQS_TFQF  BIT(21)
344 #define CAN_MCAN_TXFQS_TFQPI GENMASK(20, 16)
345 #define CAN_MCAN_TXFQS_TFGI  GENMASK(12, 8)
346 #define CAN_MCAN_TXFQS_TFFL  GENMASK(5, 0)
347 
348 /* Tx Buffer Element Size Configuration register */
349 #define CAN_MCAN_TXESC      0x0C8
350 #define CAN_MCAN_TXESC_TBDS GENMASK(2, 0)
351 
352 /* Tx Buffer Request Pending register */
353 #define CAN_MCAN_TXBRP     0x0CC
354 #define CAN_MCAN_TXBRP_TRP GENMASK(31, 0)
355 
356 /* Tx Buffer Add Request register */
357 #define CAN_MCAN_TXBAR    0x0D0
358 #define CAN_MCAN_TXBAR_AR GENMASK(31, 0)
359 
360 /* Tx Buffer Cancellation Request register */
361 #define CAN_MCAN_TXBCR    0x0D4
362 #define CAN_MCAN_TXBCR_CR GENMASK(31, 0)
363 
364 /* Tx Buffer Transmission Occurred register */
365 #define CAN_MCAN_TXBTO    0x0D8
366 #define CAN_MCAN_TXBTO_TO GENMASK(31, 0)
367 
368 /* Tx Buffer Cancellation Finished register */
369 #define CAN_MCAN_TXBCF    0x0DC
370 #define CAN_MCAN_TXBCF_CF GENMASK(31, 0)
371 
372 /* Tx Buffer Transmission Interrupt Enable register */
373 #define CAN_MCAN_TXBTIE     0x0E0
374 #define CAN_MCAN_TXBTIE_TIE GENMASK(31, 0)
375 
376 /* Tx Buffer Cancellation Finished Interrupt Enable register */
377 #define CAN_MCAN_TXBCIE      0x0E4
378 #define CAN_MCAN_TXBCIE_CFIE GENMASK(31, 0)
379 
380 /* Tx Event FIFO Configuration register */
381 #define CAN_MCAN_TXEFC      0x0F0
382 #define CAN_MCAN_TXEFC_EFWM GENMASK(29, 24)
383 #define CAN_MCAN_TXEFC_EFS  GENMASK(21, 16)
384 #define CAN_MCAN_TXEFC_EFSA GENMASK(15, 2)
385 
386 /* Tx Event FIFO Status register */
387 #define CAN_MCAN_TXEFS      0x0F4
388 #define CAN_MCAN_TXEFS_TEFL BIT(25)
389 #define CAN_MCAN_TXEFS_EFF  BIT(24)
390 #define CAN_MCAN_TXEFS_EFPI GENMASK(20, 16)
391 #define CAN_MCAN_TXEFS_EFGI GENMASK(12, 8)
392 #define CAN_MCAN_TXEFS_EFFL GENMASK(5, 0)
393 
394 /* Tx Event FIFO Acknowledge register */
395 #define CAN_MCAN_TXEFA      0x0F8
396 #define CAN_MCAN_TXEFA_EFAI GENMASK(4, 0)
397 
398 /**
399  * @name Indexes for the cells in the devicetree bosch,mram-cfg property
400  * @anchor CAN_MCAN_MRAM_CFG
401 
402  * These match the description of the cells in the bosch,m_can-base devicetree binding.
403  *
404  * @{
405  */
406 /** offset cell index */
407 #define CAN_MCAN_MRAM_CFG_OFFSET        0
408 /** std-filter-elements cell index */
409 #define CAN_MCAN_MRAM_CFG_STD_FILTER    1
410 /** ext-filter-elements cell index */
411 #define CAN_MCAN_MRAM_CFG_EXT_FILTER    2
412 /** rx-fifo0-elements cell index */
413 #define CAN_MCAN_MRAM_CFG_RX_FIFO0      3
414 /** rx-fifo1-elements cell index */
415 #define CAN_MCAN_MRAM_CFG_RX_FIFO1      4
416 /** rx-buffer-elements cell index */
417 #define CAN_MCAN_MRAM_CFG_RX_BUFFER     5
418 /** tx-event-fifo-elements cell index */
419 #define CAN_MCAN_MRAM_CFG_TX_EVENT_FIFO 6
420 /** tx-buffer-elements cell index */
421 #define CAN_MCAN_MRAM_CFG_TX_BUFFER     7
422 /** Total number of cells in bosch,mram-cfg property */
423 #define CAN_MCAN_MRAM_CFG_NUM_CELLS     8
424 
425 /** @} */
426 
427 /**
428  * @brief Get the Bosch M_CAN Message RAM offset
429  *
430  * @param node_id node identifier
431  * @return the Message RAM offset in bytes
432  */
433 #define CAN_MCAN_DT_MRAM_OFFSET(node_id)                                                           \
434 	DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_OFFSET)
435 
436 /**
437  * @brief Get the number of standard (11-bit) filter elements in Bosch M_CAN Message RAM
438  *
439  * @param node_id node identifier
440  * @return the number of standard (11-bit) filter elements
441  */
442 #define CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id)                                              \
443 	DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_STD_FILTER)
444 
445 /**
446  * @brief Get the number of extended (29-bit) filter elements in Bosch M_CAN Message RAM
447  *
448  * @param node_id node identifier
449  * @return the number of extended (29-bit) filter elements
450  */
451 #define CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id)                                              \
452 	DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_EXT_FILTER)
453 
454 /**
455  * @brief Get the number of Rx FIFO 0 elements in Bosch M_CAN Message RAM
456  *
457  * @param node_id node identifier
458  * @return the number of Rx FIFO 0 elements
459  */
460 #define CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(node_id)                                                \
461 	DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_RX_FIFO0)
462 
463 /**
464  * @brief Get the number of Rx FIFO 1 elements in Bosch M_CAN Message RAM
465  *
466  * @param node_id node identifier
467  * @return the number of Rx FIFO 1 elements
468  */
469 #define CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(node_id)                                                \
470 	DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_RX_FIFO1)
471 
472 /**
473  * @brief Get the number of Rx Buffer elements in Bosch M_CAN Message RAM
474  *
475  * @param node_id node identifier
476  * @return the number of Rx Buffer elements
477  */
478 #define CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(node_id)                                               \
479 	DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_RX_BUFFER)
480 
481 /**
482  * @brief Get the number of Tx Event FIFO elements in Bosch M_CAN Message RAM
483  *
484  * @param node_id node identifier
485  * @return the number of Tx Event FIFO elements
486  */
487 #define CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(node_id)                                           \
488 	DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_TX_EVENT_FIFO)
489 
490 /**
491  * @brief Get the number of Tx Buffer elements in Bosch M_CAN Message RAM
492  *
493  * @param node_id node identifier
494  * @return the number of Tx Buffer elements
495  */
496 #define CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id)                                               \
497 	DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_TX_BUFFER)
498 
499 /**
500  * @brief Get the base offset of standard (11-bit) filter elements in Bosch M_CAN Message RAM
501  *
502  * @param node_id node identifier
503  * @return the base offset of standard (11-bit) filter elements in bytes
504  */
505 #define CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET(node_id) (0U)
506 
507 /**
508  * @brief Get the base offset of extended (29-bit) filter elements in Bosch M_CAN Message RAM
509  *
510  * @param node_id node identifier
511  * @return the base offset of extended (29-bit) filter elements in bytes
512  */
513 #define CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET(node_id)                                                \
514 	(CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET(node_id) +                                             \
515 	 CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id) * sizeof(struct can_mcan_std_filter))
516 
517 /**
518  * @brief Get the base offset of Rx FIFO 0 elements in Bosch M_CAN Message RAM
519  *
520  * @param node_id node identifier
521  * @return the base offset of Rx FIFO 0 elements in bytes
522  */
523 #define CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET(node_id)                                                  \
524 	(CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET(node_id) +                                             \
525 	 CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id) * sizeof(struct can_mcan_ext_filter))
526 
527 /**
528  * @brief Get the base offset of Rx FIFO 1 elements in Bosch M_CAN Message RAM
529  *
530  * @param node_id node identifier
531  * @return the base offset of Rx FIFO 1 elements in bytes
532  */
533 #define CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET(node_id)                                                  \
534 	(CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET(node_id) +                                               \
535 	 CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(node_id) * sizeof(struct can_mcan_rx_fifo))
536 
537 /**
538  * @brief Get the base offset of Rx Buffer elements in Bosch M_CAN Message RAM
539  *
540  * @param node_id node identifier
541  * @return the base offset of Rx Buffer elements in bytes
542  */
543 #define CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET(node_id)                                                 \
544 	(CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET(node_id) +                                               \
545 	 CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(node_id) * sizeof(struct can_mcan_rx_fifo))
546 
547 /**
548  * @brief Get the base offset of Tx Event FIFO elements in Bosch M_CAN Message RAM
549  *
550  * @param node_id node identifier
551  * @return the base offset of Tx Event FIFO elements in bytes
552  */
553 #define CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET(node_id)                                             \
554 	(CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET(node_id) +                                              \
555 	 CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(node_id) * sizeof(struct can_mcan_rx_fifo))
556 
557 /**
558  * @brief Get the base offset of Tx Buffer elements in Bosch M_CAN Message RAM
559  *
560  * @param node_id node identifier
561  * @return the base offset of Tx Buffer elements in bytes
562  */
563 #define CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET(node_id)                                                 \
564 	(CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET(node_id) +                                          \
565 	 CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(node_id) * sizeof(struct can_mcan_tx_event_fifo))
566 
567 /**
568  * @brief Get the Bosch M_CAN register base address
569  *
570  * For devicetree nodes with just one register block, this macro returns the base address of that
571  * register block.
572  *
573  * If a devicetree node has more than one register block, this macros returns the base address of
574  * the register block named "m_can".
575  *
576  * @param node_id node identifier
577  * @return the Bosch M_CAN register base address
578  */
579 #define CAN_MCAN_DT_MCAN_ADDR(node_id)                                                             \
580 	COND_CODE_1(DT_NUM_REGS(node_id), ((mm_reg_t)DT_REG_ADDR(node_id)),                        \
581 		    ((mm_reg_t)DT_REG_ADDR_BY_NAME(node_id, m_can)))
582 
583 /**
584  * @brief Get the Bosch M_CAN Message RAM base address
585  *
586  * For devicetree nodes with dedicated Message RAM area defined via devicetree, this macro returns
587  * the base address of the Message RAM.
588  *
589  * @param node_id node identifier
590  * @return the Bosch M_CAN Message RAM base address (MRBA)
591  */
592 #define CAN_MCAN_DT_MRBA(node_id)                                                                  \
593 	(mem_addr_t)DT_REG_ADDR_BY_NAME(node_id, message_ram)
594 
595 /**
596  * @brief Get the Bosch M_CAN Message RAM address
597  *
598  * For devicetree nodes with dedicated Message RAM area defined via devicetree, this macro returns
599  * the address of the Message RAM, taking in the Message RAM offset into account.
600  *
601  * @param node_id node identifier
602  * @return the Bosch M_CAN Message RAM address
603  */
604 #define CAN_MCAN_DT_MRAM_ADDR(node_id)                                                             \
605 	(mem_addr_t)(CAN_MCAN_DT_MRBA(node_id) + CAN_MCAN_DT_MRAM_OFFSET(node_id))
606 
607 /**
608  * @brief Get the Bosch M_CAN Message RAM size
609  *
610  * For devicetree nodes with dedicated Message RAM area defined via devicetree, this macro returns
611  * the size of the Message RAM, taking in the Message RAM offset into account.
612  *
613  * @param node_id node identifier
614  * @return the Bosch M_CAN Message RAM base address
615  * @see CAN_MCAN_DT_MRAM_ELEMENTS_SIZE()
616  */
617 #define CAN_MCAN_DT_MRAM_SIZE(node_id)                                                             \
618 	(mem_addr_t)(DT_REG_SIZE_BY_NAME(node_id, message_ram) - CAN_MCAN_DT_MRAM_OFFSET(node_id))
619 
620 /**
621  * @brief Get the total size of all Bosch M_CAN Message RAM elements
622  *
623  * @param node_id node identifier
624  * @return the total size of all Message RAM elements in bytes
625  * @see CAN_MCAN_DT_MRAM_SIZE()
626  */
627 #define CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(node_id)                                                    \
628 	(CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET(node_id) +                                              \
629 	 CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id) * sizeof(struct can_mcan_tx_buffer))
630 
631 /**
632  * @brief Define a RAM buffer for Bosch M_CAN Message RAM
633  *
634  * For devicetree nodes without dedicated Message RAM area, this macro defines a suitable RAM buffer
635  * to hold the Message RAM elements. Since this buffer cannot be shared between multiple Bosch M_CAN
636  * instances, the Message RAM offset must be set to 0x0.
637  *
638  * @param node_id node identifier
639  * @param _name buffer variable name
640  */
641 #define CAN_MCAN_DT_MRAM_DEFINE(node_id, _name)                                                    \
642 	BUILD_ASSERT(CAN_MCAN_DT_MRAM_OFFSET(node_id) == 0, "offset must be 0");                   \
643 	static char __noinit __nocache __aligned(4) _name[CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(node_id)];
644 
645 /**
646  * @brief Assert that the Message RAM configuration meets the Bosch M_CAN IP core restrictions
647  *
648  * @param node_id node identifier
649  */
650 #define CAN_MCAN_DT_BUILD_ASSERT_MRAM_CFG(node_id)                                                 \
651 	BUILD_ASSERT(CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id) <= 128,                         \
652 		     "Maximum Standard filter elements exceeded");                                 \
653 	BUILD_ASSERT(CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id) <= 64,                          \
654 		     "Maximum Extended filter elements exceeded");                                 \
655 	BUILD_ASSERT(CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(node_id) <= 64,                            \
656 		     "Maximum Rx FIFO 0 elements exceeded");                                       \
657 	BUILD_ASSERT(CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(node_id) <= 64,                            \
658 		     "Maximum Rx FIFO 1 elements exceeded");                                       \
659 	BUILD_ASSERT(CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(node_id) <= 64,                           \
660 		     "Maximum Rx Buffer elements exceeded");                                       \
661 	BUILD_ASSERT(CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(node_id) <= 32,                       \
662 		     "Maximum Tx Buffer elements exceeded");                                       \
663 	BUILD_ASSERT(CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id) <= 32,                           \
664 		     "Maximum Tx Buffer elements exceeded");
665 
666 /**
667  * @brief Equivalent to CAN_MCAN_DT_MRAM_OFFSET(DT_DRV_INST(inst))
668  * @param inst DT_DRV_COMPAT instance number
669  * @return the Message RAM offset in bytes
670  * @see CAN_MCAN_DT_MRAM_OFFSET()
671  */
672 #define CAN_MCAN_DT_INST_MRAM_OFFSET(inst) CAN_MCAN_DT_MRAM_OFFSET(DT_DRV_INST(inst))
673 
674 /**
675  * @brief Equivalent to CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(DT_DRV_INST(inst))
676  * @param inst DT_DRV_COMPAT instance number
677  * @return the number of standard (11-bit) elements
678  * @see CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS()
679  */
680 #define CAN_MCAN_DT_INST_MRAM_STD_FILTER_ELEMENTS(inst)                                            \
681 	CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(DT_DRV_INST(inst))
682 
683 /**
684  * @brief Equivalent to CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(DT_DRV_INST(inst))
685  * @param inst DT_DRV_COMPAT instance number
686  * @return the number of extended (29-bit) elements
687  * @see CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS()
688  */
689 #define CAN_MCAN_DT_INST_MRAM_EXT_FILTER_ELEMENTS(inst)                                            \
690 	CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(DT_DRV_INST(inst))
691 
692 /**
693  * @brief Equivalent to CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(DT_DRV_INST(inst))
694  * @param inst DT_DRV_COMPAT instance number
695  * @return the number of Rx FIFO 0 elements
696  * @see CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS()
697  */
698 #define CAN_MCAN_DT_INST_MRAM_RX_FIFO0_ELEMENTS(inst)                                              \
699 	CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(DT_DRV_INST(inst))
700 
701 /**
702  * @brief Equivalent to CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(DT_DRV_INST(inst))
703  * @param inst DT_DRV_COMPAT instance number
704  * @return the number of Rx FIFO 1 elements
705  * @see CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS()
706  */
707 #define CAN_MCAN_DT_INST_MRAM_RX_FIFO1_ELEMENTS(inst)                                              \
708 	CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(DT_DRV_INST(inst))
709 
710 /**
711  * @brief Equivalent to CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(DT_DRV_INST(inst))
712  * @param inst DT_DRV_COMPAT instance number
713  * @return the number of Rx Buffer elements
714  * @see CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS()
715  */
716 #define CAN_MCAN_DT_INST_MRAM_RX_BUFFER_ELEMENTS(inst)                                             \
717 	CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(DT_DRV_INST(inst))
718 
719 /**
720  * @brief Equivalent to CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(DT_DRV_INST(inst))
721  * @param inst DT_DRV_COMPAT instance number
722  * @return the number of Tx Event FIFO elements
723  * @see CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS()
724  */
725 #define CAN_MCAN_DT_INST_MRAM_TX_EVENT_FIFO_ELEMENTS(inst)                                         \
726 	CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(DT_DRV_INST(inst))
727 
728 /**
729  * @brief Equivalent to CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(DT_DRV_INST(inst))
730  * @param inst DT_DRV_COMPAT instance number
731  * @return the number of Tx Buffer elements
732  * @see CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS()
733  */
734 #define CAN_MCAN_DT_INST_MRAM_TX_BUFFER_ELEMENTS(inst)                                             \
735 	CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(DT_DRV_INST(inst))
736 
737 /**
738  * @brief Equivalent to CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET(DT_DRV_INST(inst))
739  * @param inst DT_DRV_COMPAT instance number
740  * @return the base offset of standard (11-bit) filter elements in bytes
741  * @see CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET()
742  */
743 #define CAN_MCAN_DT_INST_MRAM_STD_FILTER_OFFSET(inst)                                              \
744 	CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET(DT_DRV_INST(inst))
745 
746 /**
747  * @brief Equivalent to CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET(DT_DRV_INST(inst))
748  * @param inst DT_DRV_COMPAT instance number
749  * @return the base offset of extended (29-bit) filter elements in bytes
750  * @see CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET()
751  */
752 #define CAN_MCAN_DT_INST_MRAM_EXT_FILTER_OFFSET(inst)                                              \
753 	CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET(DT_DRV_INST(inst))
754 
755 /**
756  * @brief Equivalent to CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET(DT_DRV_INST(inst))
757  * @param inst DT_DRV_COMPAT instance number
758  * @return the base offset of Rx FIFO 0 elements in bytes
759  * @see CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET()
760  */
761 #define CAN_MCAN_DT_INST_MRAM_RX_FIFO0_OFFSET(inst)                                                \
762 	CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET(DT_DRV_INST(inst))
763 
764 /**
765  * @brief Equivalent to CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET(DT_DRV_INST(inst))
766  * @param inst DT_DRV_COMPAT instance number
767  * @return the base offset of Rx FIFO 1 elements in bytes
768  * @see CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET()
769  */
770 #define CAN_MCAN_DT_INST_MRAM_RX_FIFO1_OFFSET(inst)                                                \
771 	CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET(DT_DRV_INST(inst))
772 
773 /**
774  * @brief Equivalent to CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET(DT_DRV_INST(inst))
775  * @param inst DT_DRV_COMPAT instance number
776  * @return the base offset of Rx Buffer elements in bytes
777  * @see CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET()
778  */
779 #define CAN_MCAN_DT_INST_MRAM_RX_BUFFER_OFFSET(inst)                                               \
780 	CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET(DT_DRV_INST(inst))
781 
782 /**
783  * @brief Equivalent to CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET(DT_DRV_INST(inst))
784  * @param inst DT_DRV_COMPAT instance number
785  * @return the base offset of Tx Event FIFO elements in bytes
786  * @see CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET()
787  */
788 #define CAN_MCAN_DT_INST_MRAM_TX_EVENT_FIFO_OFFSET(inst)                                           \
789 	CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET(DT_DRV_INST(inst))
790 
791 /**
792  * @brief Equivalent to CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET(DT_DRV_INST(inst))
793  * @param inst DT_DRV_COMPAT instance number
794  * @return the base offset of Tx Buffer elements in bytes
795  * @see CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET()
796  */
797 #define CAN_MCAN_DT_INST_MRAM_TX_BUFFER_OFFSET(inst)                                               \
798 	CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET(DT_DRV_INST(inst))
799 
800 /**
801  * @brief Equivalent to CAN_MCAN_DT_MCAN_ADDR(DT_DRV_INST(inst))
802  * @param inst DT_DRV_COMPAT instance number
803  * @return the Bosch M_CAN register base address
804  * @see CAN_MCAN_DT_MRAM_ADDR()
805  */
806 #define CAN_MCAN_DT_INST_MCAN_ADDR(inst) CAN_MCAN_DT_MCAN_ADDR(DT_DRV_INST(inst))
807 
808 /**
809  * @brief Equivalent to CAN_MCAN_DT_MRBA(DT_DRV_INST(inst))
810  * @param inst DT_DRV_COMPAT instance number
811  * @return the Bosch M_CAN Message RAM Base Address (MRBA)
812  * @see CAN_MCAN_DT_MRBA()
813  */
814 #define CAN_MCAN_DT_INST_MRBA(inst) CAN_MCAN_DT_MRBA(DT_DRV_INST(inst))
815 
816 /**
817  * @brief Equivalent to CAN_MCAN_DT_MRAM_ADDR(DT_DRV_INST(inst))
818  * @param inst DT_DRV_COMPAT instance number
819  * @return the Bosch M_CAN Message RAM address
820  * @see CAN_MCAN_DT_MRAM_ADDR()
821  */
822 #define CAN_MCAN_DT_INST_MRAM_ADDR(inst) CAN_MCAN_DT_MRAM_ADDR(DT_DRV_INST(inst))
823 
824 /**
825  * @brief Equivalent to CAN_MCAN_DT_MRAM_SIZE(DT_DRV_INST(inst))
826  * @param inst DT_DRV_COMPAT instance number
827  * @return the Bosch M_CAN Message RAM size in bytes
828  * @see CAN_MCAN_DT_MRAM_SIZE()
829  */
830 #define CAN_MCAN_DT_INST_MRAM_SIZE(inst) CAN_MCAN_DT_MRAM_SIZE(DT_DRV_INST(inst))
831 
832 /**
833  * @brief Equivalent to CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(DT_DRV_INST(inst))
834  * @param inst DT_DRV_COMPAT instance number
835  * @return the total size of all Message RAM elements in bytes
836  * @see CAN_MCAN_DT_MRAM_ELEMENTS_SIZE()
837  */
838 #define CAN_MCAN_DT_INST_MRAM_ELEMENTS_SIZE(inst) CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(DT_DRV_INST(inst))
839 
840 /**
841  * @brief Equivalent to CAN_MCAN_DT_MRAM_DEFINE(DT_DRV_INST(inst))
842  * @param inst DT_DRV_COMPAT instance number
843  * @param _name buffer variable name
844  * @see CAN_MCAN_DT_MRAM_DEFINE()
845  */
846 #define CAN_MCAN_DT_INST_MRAM_DEFINE(inst, _name) CAN_MCAN_DT_MRAM_DEFINE(DT_DRV_INST(inst), _name)
847 
848 /**
849  * @brief Bosch M_CAN specific static initializer for a minimum nominal @p can_timing struct
850  */
851 #define CAN_MCAN_TIMING_MIN_INITIALIZER                                                            \
852 	{                                                                                          \
853 		.sjw = 1,                                                                          \
854 		.prop_seg = 0,                                                                     \
855 		.phase_seg1 = 2,                                                                   \
856 		.phase_seg2 = 2,                                                                   \
857 		.prescaler = 1                                                                     \
858 	}
859 
860 /**
861  * @brief Bosch M_CAN specific static initializer for a maximum nominal @p can_timing struct
862  */
863 #define CAN_MCAN_TIMING_MAX_INITIALIZER                                                            \
864 	{                                                                                          \
865 		.sjw = 128,                                                                        \
866 		.prop_seg = 0,                                                                     \
867 		.phase_seg1 = 256,                                                                 \
868 		.phase_seg2 = 128,                                                                 \
869 		.prescaler = 512                                                                   \
870 	}
871 
872 /**
873  * @brief Bosch M_CAN specific static initializer for a minimum data phase @p can_timing struct
874  */
875 #define CAN_MCAN_TIMING_DATA_MIN_INITIALIZER                                                       \
876 	{                                                                                          \
877 		.sjw = 1,                                                                          \
878 		.prop_seg = 0,                                                                     \
879 		.phase_seg1 = 1,                                                                   \
880 		.phase_seg2 = 1,                                                                   \
881 		.prescaler = 1                                                                     \
882 	}
883 
884 /**
885  * @brief Bosch M_CAN specific static initializer for a maximum data phase @p can_timing struct
886  */
887 #define CAN_MCAN_TIMING_DATA_MAX_INITIALIZER                                                       \
888 	{                                                                                          \
889 		.sjw = 16,                                                                         \
890 		.prop_seg = 0,                                                                     \
891 		.phase_seg1 = 32,                                                                  \
892 		.phase_seg2 = 16,                                                                  \
893 		.prescaler = 32                                                                    \
894 	}
895 
896 /**
897  * @brief Equivalent to CAN_MCAN_DT_BUILD_ASSERT_MRAM_CFG(DT_DRV_INST(inst))
898  * @param inst DT_DRV_COMPAT instance number
899  * @see CAN_MCAN_DT_BUILD_ASSERT_MRAM_CFG()
900  */
901 #define CAN_MCAN_DT_INST_BUILD_ASSERT_MRAM_CFG(inst)                                               \
902 	CAN_MCAN_DT_BUILD_ASSERT_MRAM_CFG(DT_DRV_INST(inst))
903 
904 /**
905  * @brief Bosch M_CAN Rx Buffer and FIFO Element header
906  *
907  * See Bosch M_CAN Users Manual section 2.4.2 for details.
908  */
909 struct can_mcan_rx_fifo_hdr {
910 	union {
911 		struct {
912 			uint32_t ext_id: 29;
913 			uint32_t rtr: 1;
914 			uint32_t xtd: 1;
915 			uint32_t esi: 1;
916 		};
917 		struct {
918 			uint32_t pad1: 18;
919 			uint32_t std_id: 11;
920 			uint32_t pad2: 3;
921 		};
922 	};
923 	uint32_t rxts: 16;
924 	uint32_t dlc: 4;
925 	uint32_t brs: 1;
926 	uint32_t fdf: 1;
927 	uint32_t res: 2;
928 	uint32_t fidx: 7;
929 	uint32_t anmf: 1;
930 } __packed __aligned(4);
931 
932 /**
933  * @brief Bosch M_CAN Rx Buffer and FIFO Element
934  *
935  * See Bosch M_CAN Users Manual section 2.4.2 for details.
936  */
937 struct can_mcan_rx_fifo {
938 	struct can_mcan_rx_fifo_hdr hdr;
939 	union {
940 		uint8_t data[64];
941 		uint32_t data_32[16];
942 	};
943 } __packed __aligned(4);
944 
945 /**
946  * @brief Bosch M_CAN Tx Buffer Element header
947  *
948  * See Bosch M_CAN Users Manual section 2.4.3 for details.
949  */
950 struct can_mcan_tx_buffer_hdr {
951 	union {
952 		struct {
953 			uint32_t ext_id: 29;
954 			uint32_t rtr: 1;
955 			uint32_t xtd: 1;
956 			uint32_t esi: 1;
957 		};
958 		struct {
959 			uint32_t pad1: 18;
960 			uint32_t std_id: 11;
961 			uint32_t pad2: 3;
962 		};
963 	};
964 	uint16_t res1;
965 	uint8_t dlc: 4;
966 	uint8_t brs: 1;
967 	uint8_t fdf: 1;
968 	uint8_t tsce: 1;
969 	uint8_t efc: 1;
970 	uint8_t mm;
971 } __packed __aligned(4);
972 
973 /**
974  * @brief Bosch M_CAN Tx Buffer Element
975  *
976  * See Bosch M_CAN Users Manual section 2.4.3 for details.
977  */
978 struct can_mcan_tx_buffer {
979 	struct can_mcan_tx_buffer_hdr hdr;
980 	union {
981 		uint8_t data[64];
982 		uint32_t data_32[16];
983 	};
984 } __packed __aligned(4);
985 
986 /**
987  * @brief Bosch M_CAN Tx Event FIFO Element
988  *
989  * See Bosch M_CAN Users Manual section 2.4.4 for details.
990  */
991 struct can_mcan_tx_event_fifo {
992 	union {
993 		struct {
994 			uint32_t ext_id: 29;
995 			uint32_t rtr: 1;
996 			uint32_t xtd: 1;
997 			uint32_t esi: 1;
998 		};
999 		struct {
1000 			uint32_t pad1: 18;
1001 			uint32_t std_id: 11;
1002 			uint32_t pad2: 3;
1003 		};
1004 	};
1005 	uint16_t txts;
1006 	uint8_t dlc: 4;
1007 	uint8_t brs: 1;
1008 	uint8_t fdf: 1;
1009 	uint8_t et: 2;
1010 	uint8_t mm;
1011 } __packed __aligned(4);
1012 
1013 /* Bosch M_CAN Standard/Extended Filter Element Configuration (SFEC/EFEC) */
1014 #define CAN_MCAN_XFEC_DISABLE    0x0
1015 #define CAN_MCAN_XFEC_FIFO0      0x1
1016 #define CAN_MCAN_XFEC_FIFO1      0x2
1017 #define CAN_MCAN_XFEC_REJECT     0x3
1018 #define CAN_MCAN_XFEC_PRIO       0x4
1019 #define CAN_MCAN_XFEC_PRIO_FIFO0 0x5
1020 #define CAN_MCAN_XFEC_PRIO_FIFO1 0x7
1021 
1022 /* Bosch M_CAN Standard Filter Type (SFT) */
1023 #define CAN_MCAN_SFT_RANGE    0x0
1024 #define CAN_MCAN_SFT_DUAL     0x1
1025 #define CAN_MCAN_SFT_CLASSIC  0x2
1026 #define CAN_MCAN_SFT_DISABLED 0x3
1027 
1028 /**
1029  * @brief Bosch M_CAN Standard Message ID Filter Element
1030  *
1031  * See Bosch M_CAN Users Manual section 2.4.5 for details.
1032  */
1033 struct can_mcan_std_filter {
1034 	uint32_t sfid2: 11;
1035 	uint32_t res: 5;
1036 	uint32_t sfid1: 11;
1037 	uint32_t sfec: 3;
1038 	uint32_t sft: 2;
1039 } __packed __aligned(4);
1040 
1041 /* Bosch M_CAN Extended Filter Type (EFT) */
1042 #define CAN_MCAN_EFT_RANGE_XIDAM 0x0
1043 #define CAN_MCAN_EFT_DUAL        0x1
1044 #define CAN_MCAN_EFT_CLASSIC     0x2
1045 #define CAN_MCAN_EFT_RANGE       0x3
1046 
1047 /**
1048  * @brief Bosch M_CAN Extended Message ID Filter Element
1049  *
1050  * See Bosch M_CAN Users Manual section 2.4.6 for details.
1051  */
1052 struct can_mcan_ext_filter {
1053 	uint32_t efid1: 29;
1054 	uint32_t efec: 3;
1055 	uint32_t efid2: 29;
1056 	uint32_t esync: 1;
1057 	uint32_t eft: 2;
1058 } __packed __aligned(4);
1059 
1060 /**
1061  * @brief Bosch M_CAN driver internal data structure.
1062  */
1063 struct can_mcan_data {
1064 	struct k_mutex lock;
1065 	struct k_sem tx_sem;
1066 	struct k_mutex tx_mtx;
1067 	can_state_change_callback_t state_change_cb;
1068 	void *state_change_cb_data;
1069 	bool started;
1070 #ifdef CONFIG_CAN_FD_MODE
1071 	bool fd;
1072 #endif /* CONFIG_CAN_FD_MODE */
1073 	void *custom;
1074 } __aligned(4);
1075 
1076 /**
1077  * @brief Bosch M_CAN driver front-end callback for reading a register value
1078  *
1079  * @param dev Pointer to the device structure for the driver instance.
1080  * @param reg Register offset
1081  * @param[out] val Register value
1082  *
1083  * @retval 0 If successful.
1084  * @retval -ENOTSUP Register not supported.
1085  * @retval -EIO General input/output error.
1086  */
1087 typedef int (*can_mcan_read_reg_t)(const struct device *dev, uint16_t reg, uint32_t *val);
1088 
1089 /**
1090  * @brief Bosch M_CAN driver front-end callback for writing a register value
1091  *
1092  * @param dev Pointer to the device structure for the driver instance.
1093  * @param reg Register offset
1094  * @param val Register value
1095  *
1096  * @retval 0 If successful.
1097  * @retval -ENOTSUP Register not supported.
1098  * @retval -EIO General input/output error.
1099  */
1100 typedef int (*can_mcan_write_reg_t)(const struct device *dev, uint16_t reg, uint32_t val);
1101 
1102 /**
1103  * @brief Bosch M_CAN driver front-end callback for reading from Message RAM
1104  *
1105  * @param dev Pointer to the device structure for the driver instance.
1106  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1107  *        offset must be 32-bit aligned.
1108  * @param[out] dst Destination for the data read. The destination address must be 32-bit aligned.
1109  * @param len Number of bytes to read. Must be a multiple of 4.
1110  *
1111  * @retval 0 If successful.
1112  * @retval -EIO General input/output error.
1113  */
1114 typedef int (*can_mcan_read_mram_t)(const struct device *dev, uint16_t offset, void *dst,
1115 				    size_t len);
1116 
1117 /**
1118  * @brief Bosch M_CAN driver front-end callback for writing to Message RAM
1119  *
1120  * @param dev Pointer to the device structure for the driver instance.
1121  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1122  *        offset must be 32-bit aligned.
1123  * @param src Source for the data to be written. The source address must be 32-bit aligned.
1124  * @param len Number of bytes to write. Must be a multiple of 4.
1125  *
1126  * @retval 0 If successful.
1127  * @retval -EIO General input/output error.
1128  */
1129 typedef int (*can_mcan_write_mram_t)(const struct device *dev, uint16_t offset, const void *src,
1130 				     size_t len);
1131 
1132 /**
1133  * @brief Bosch M_CAN driver front-end callback for clearing Message RAM
1134  *
1135  * Clear Message RAM by writing 0 to all words.
1136  *
1137  * @param dev Pointer to the device structure for the driver instance.
1138  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1139  *        offset must be 32-bit aligned.
1140  * @param len Number of bytes to clear. Must be a multiple of 4.
1141  *
1142  * @retval 0 If successful.
1143  * @retval -EIO General input/output error.
1144  */
1145 typedef int (*can_mcan_clear_mram_t)(const struct device *dev, uint16_t offset, size_t len);
1146 
1147 /**
1148  * @brief Bosch M_CAN driver front-end operations.
1149  */
1150 struct can_mcan_ops {
1151 	can_mcan_read_reg_t read_reg;
1152 	can_mcan_write_reg_t write_reg;
1153 	can_mcan_read_mram_t read_mram;
1154 	can_mcan_write_mram_t write_mram;
1155 	can_mcan_clear_mram_t clear_mram;
1156 };
1157 
1158 /**
1159  * @brief Bosch M_CAN driver internal Tx callback structure.
1160  */
1161 struct can_mcan_tx_callback {
1162 	can_tx_callback_t function;
1163 	void *user_data;
1164 };
1165 
1166 /**
1167  * @brief Bosch M_CAN driver internal Rx callback structure.
1168  */
1169 struct can_mcan_rx_callback {
1170 	can_rx_callback_t function;
1171 	void *user_data;
1172 	uint8_t flags;
1173 };
1174 
1175 /**
1176  * @brief Bosch M_CAN driver internal Tx + Rx callbacks structure.
1177  */
1178 struct can_mcan_callbacks {
1179 	struct can_mcan_tx_callback *tx;
1180 	struct can_mcan_rx_callback *std;
1181 	struct can_mcan_rx_callback *ext;
1182 	uint8_t num_tx;
1183 	uint8_t num_std;
1184 	uint8_t num_ext;
1185 };
1186 
1187 /**
1188  * @brief Define Bosch M_CAN TX and RX callbacks
1189  *
1190  * This macro allows a Bosch M_CAN driver frontend using a fixed Message RAM configuration to limit
1191  * the required software resources (e.g. limit the number of the standard (11-bit) or extended
1192  * (29-bit) filters in use).
1193  *
1194  * Frontend drivers supporting dynamic Message RAM configuration should use @ref
1195  * CAN_MCAN_DT_CALLBACKS_DEFINE() or @ref CAN_MCAN_DT_INST_CALLBACKS_DEFINE() instead.
1196  *
1197  * @param _name callbacks variable name
1198  * @param _tx Number of Tx callbacks
1199  * @param _std Number of standard (11-bit) filter callbacks
1200  * @param _ext Number of extended (29-bit) filter callbacks
1201  * @see CAN_MCAN_DT_CALLBACKS_DEFINE()
1202  */
1203 #define CAN_MCAN_CALLBACKS_DEFINE(_name, _tx, _std, _ext)                                          \
1204 	static struct can_mcan_tx_callback _name##_tx_cbs[_tx];                                    \
1205 	static struct can_mcan_rx_callback _name##_std_cbs[_std];                                  \
1206 	static struct can_mcan_rx_callback _name##_ext_cbs[_ext];                                  \
1207 	static const struct can_mcan_callbacks _name = {                                           \
1208 		.tx = _name##_tx_cbs,                                                              \
1209 		.std = _name##_std_cbs,                                                            \
1210 		.ext = _name##_ext_cbs,                                                            \
1211 		.num_tx = _tx,                                                                     \
1212 		.num_std = _std,                                                                   \
1213 		.num_ext = _ext,                                                                   \
1214 	}
1215 
1216 /**
1217  * @brief Define Bosch M_CAN TX and RX callbacks
1218  * @param node_id node identifier
1219  * @param _name callbacks variable name
1220  * @see CAN_MCAN_CALLBACKS_DEFINE()
1221  */
1222 #define CAN_MCAN_DT_CALLBACKS_DEFINE(node_id, _name)                                               \
1223 	CAN_MCAN_CALLBACKS_DEFINE(_name, CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id),             \
1224 				  CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id),                   \
1225 				  CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id))
1226 
1227 /**
1228  * @brief Equivalent to CAN_MCAN_DT_CALLBACKS_DEFINE(DT_DRV_INST(inst))
1229  * @param inst DT_DRV_COMPAT instance number
1230  * @param _name callbacks variable name
1231  * @see CAN_MCAN_DT_CALLBACKS_DEFINE()
1232  */
1233 #define CAN_MCAN_DT_INST_CALLBACKS_DEFINE(inst, _name)                                             \
1234 	CAN_MCAN_DT_CALLBACKS_DEFINE(DT_DRV_INST(inst), _name)
1235 
1236 /**
1237  * @brief Bosch M_CAN driver internal configuration structure.
1238  */
1239 struct can_mcan_config {
1240 	const struct can_mcan_ops *ops;
1241 	const struct can_mcan_callbacks *callbacks;
1242 	uint16_t mram_elements[CAN_MCAN_MRAM_CFG_NUM_CELLS];
1243 	uint16_t mram_offsets[CAN_MCAN_MRAM_CFG_NUM_CELLS];
1244 	size_t mram_size;
1245 	uint32_t bus_speed;
1246 	uint16_t sjw;
1247 	uint16_t sample_point;
1248 	uint16_t prop_ts1;
1249 	uint16_t ts2;
1250 #ifdef CONFIG_CAN_FD_MODE
1251 	uint32_t bus_speed_data;
1252 	uint16_t sample_point_data;
1253 	uint8_t sjw_data;
1254 	uint8_t prop_ts1_data;
1255 	uint8_t ts2_data;
1256 	uint8_t tx_delay_comp_offset;
1257 #endif
1258 	const struct device *phy;
1259 	uint32_t max_bitrate;
1260 	const void *custom;
1261 };
1262 
1263 /**
1264  * @brief Get an array containing the number of elements in Bosch M_CAN Message RAM
1265  *
1266  * The order of the array entries is given by the @ref CAN_MCAN_MRAM_CFG definitions.
1267  *
1268  * @param node_id node identifier
1269  * @return array of number of elements
1270  */
1271 #define CAN_MCAN_DT_MRAM_ELEMENTS_GET(node_id)                                                     \
1272 	{                                                                                          \
1273 		0, /* offset cell */                                                               \
1274 			CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id),                             \
1275 			CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id),                             \
1276 			CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(node_id),                               \
1277 			CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(node_id),                               \
1278 			CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(node_id),                              \
1279 			CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(node_id),                          \
1280 			CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id)                               \
1281 	}
1282 
1283 /**
1284  * @brief Get an array containing the base offsets for element in Bosch M_CAN Message RAM
1285  *
1286  * The order of the array entries is given by the @ref CAN_MCAN_MRAM_CFG definitions.
1287  *
1288  * @param node_id node identifier
1289  * @return array of base offsets for elements
1290  */
1291 #define CAN_MCAN_DT_MRAM_OFFSETS_GET(node_id)                                                      \
1292 	{                                                                                          \
1293 		0, /* offset cell */                                                               \
1294 			CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET(node_id),                               \
1295 			CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET(node_id),                               \
1296 			CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET(node_id),                                 \
1297 			CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET(node_id),                                 \
1298 			CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET(node_id),                                \
1299 			CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET(node_id),                            \
1300 			CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET(node_id)                                 \
1301 	}
1302 
1303 /**
1304  * @brief Static initializer for @p can_mcan_config struct
1305  *
1306  * @param node_id Devicetree node identifier
1307  * @param _custom Pointer to custom driver frontend configuration structure
1308  * @param _ops Pointer to front-end @a can_mcan_ops
1309  * @param _cbs Pointer to front-end @a can_mcan_callbacks
1310  */
1311 #ifdef CONFIG_CAN_FD_MODE
1312 #define CAN_MCAN_DT_CONFIG_GET(node_id, _custom, _ops, _cbs)                                       \
1313 	{                                                                                          \
1314 		.ops = _ops,                                                                       \
1315 		.callbacks = _cbs,                                                                 \
1316 		.mram_elements = CAN_MCAN_DT_MRAM_ELEMENTS_GET(node_id),                           \
1317 		.mram_offsets = CAN_MCAN_DT_MRAM_OFFSETS_GET(node_id),                             \
1318 		.mram_size = CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(node_id),                              \
1319 		.bus_speed = DT_PROP(node_id, bus_speed),                                          \
1320 		.sjw = DT_PROP(node_id, sjw),                                                      \
1321 		.sample_point = DT_PROP_OR(node_id, sample_point, 0),                              \
1322 		.prop_ts1 = DT_PROP_OR(node_id, prop_seg, 0) + DT_PROP_OR(node_id, phase_seg1, 0), \
1323 		.ts2 = DT_PROP_OR(node_id, phase_seg2, 0),                                         \
1324 		.bus_speed_data = DT_PROP(node_id, bus_speed_data),                                \
1325 		.sjw_data = DT_PROP(node_id, sjw_data),                                            \
1326 		.sample_point_data = DT_PROP_OR(node_id, sample_point_data, 0),                    \
1327 		.prop_ts1_data = DT_PROP_OR(node_id, prop_seg_data, 0) +                           \
1328 				 DT_PROP_OR(node_id, phase_seg1_data, 0),                          \
1329 		.ts2_data = DT_PROP_OR(node_id, phase_seg2_data, 0),                               \
1330 		.tx_delay_comp_offset = DT_PROP(node_id, tx_delay_comp_offset),                    \
1331 		.phy = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(node_id, phys)),                           \
1332 		.max_bitrate = DT_CAN_TRANSCEIVER_MAX_BITRATE(node_id, 8000000),                   \
1333 		.custom = _custom,                                                                 \
1334 	}
1335 #else /* CONFIG_CAN_FD_MODE */
1336 #define CAN_MCAN_DT_CONFIG_GET(node_id, _custom, _ops, _cbs)                                       \
1337 	{                                                                                          \
1338 		.ops = _ops,                                                                       \
1339 		.callbacks = _cbs,                                                                 \
1340 		.mram_elements = CAN_MCAN_DT_MRAM_ELEMENTS_GET(node_id),                           \
1341 		.mram_offsets = CAN_MCAN_DT_MRAM_OFFSETS_GET(node_id),                             \
1342 		.mram_size = CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(node_id),                              \
1343 		.bus_speed = DT_PROP(node_id, bus_speed),                                          \
1344 		.sjw = DT_PROP(node_id, sjw),                                                      \
1345 		.sample_point = DT_PROP_OR(node_id, sample_point, 0),                              \
1346 		.prop_ts1 = DT_PROP_OR(node_id, prop_seg, 0) + DT_PROP_OR(node_id, phase_seg1, 0), \
1347 		.ts2 = DT_PROP_OR(node_id, phase_seg2, 0),                                         \
1348 		.phy = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(node_id, phys)),                           \
1349 		.max_bitrate = DT_CAN_TRANSCEIVER_MAX_BITRATE(node_id, 1000000),                   \
1350 		.custom = _custom,                                                                 \
1351 	}
1352 #endif /* !CONFIG_CAN_FD_MODE */
1353 
1354 /**
1355  * @brief Static initializer for @p can_mcan_config struct from DT_DRV_COMPAT instance
1356  *
1357  * @param inst DT_DRV_COMPAT instance number
1358  * @param _custom Pointer to custom driver frontend configuration structure
1359  * @param _ops Pointer to front-end @a can_mcan_ops
1360  * @param _cbs Pointer to front-end @a can_mcan_callbacks
1361  * @see CAN_MCAN_DT_CONFIG_GET()
1362  */
1363 #define CAN_MCAN_DT_CONFIG_INST_GET(inst, _custom, _ops, _cbs)                                     \
1364 	CAN_MCAN_DT_CONFIG_GET(DT_DRV_INST(inst), _custom, _ops, _cbs)
1365 
1366 /**
1367  * @brief Initializer for a @a can_mcan_data struct
1368  * @param _custom Pointer to custom driver frontend data structure
1369  */
1370 #define CAN_MCAN_DATA_INITIALIZER(_custom)                                                         \
1371 	{                                                                                          \
1372 		.custom = _custom,                                                                 \
1373 	}
1374 
1375 /**
1376  * @brief Bosch M_CAN driver front-end callback helper for reading a memory mapped register
1377  *
1378  * @param base Register base address
1379  * @param reg Register offset
1380  * @param[out] val Register value
1381  *
1382  * @retval 0 Memory mapped register read always succeeds.
1383  */
can_mcan_sys_read_reg(mm_reg_t base,uint16_t reg,uint32_t * val)1384 static inline int can_mcan_sys_read_reg(mm_reg_t base, uint16_t reg, uint32_t *val)
1385 {
1386 	*val = sys_read32(base + reg);
1387 
1388 	return 0;
1389 }
1390 
1391 /**
1392  * @brief Bosch M_CAN driver front-end callback helper for writing a memory mapped register
1393  *
1394  * @param base Register base address
1395  * @param reg Register offset
1396  * @param val Register value
1397  *
1398  * @retval 0 Memory mapped register write always succeeds.
1399  */
can_mcan_sys_write_reg(mm_reg_t base,uint16_t reg,uint32_t val)1400 static inline int can_mcan_sys_write_reg(mm_reg_t base, uint16_t reg, uint32_t val)
1401 {
1402 	sys_write32(val, base + reg);
1403 
1404 	return 0;
1405 }
1406 
1407 /**
1408  * @brief Bosch M_CAN driver front-end callback helper for reading from memory mapped Message RAM
1409  *
1410  * @param base Base address of the Message RAM for the given Bosch M_CAN instance. The base address
1411  *        must be 32-bit aligned.
1412  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1413  *        offset must be 32-bit aligned.
1414  * @param[out] dst Destination for the data read. The destination address must be 32-bit aligned.
1415  * @param len Number of bytes to read. Must be a multiple of 4.
1416  *
1417  * @retval 0 If successful.
1418  * @retval -EIO General input/output error.
1419  */
can_mcan_sys_read_mram(mem_addr_t base,uint16_t offset,void * dst,size_t len)1420 static inline int can_mcan_sys_read_mram(mem_addr_t base, uint16_t offset, void *dst, size_t len)
1421 {
1422 	volatile uint32_t *src32 = (volatile uint32_t *)(base + offset);
1423 	uint32_t *dst32 = (uint32_t *)dst;
1424 	size_t len32 = len / sizeof(uint32_t);
1425 
1426 	__ASSERT(base % 4U == 0U, "base must be a multiple of 4");
1427 	__ASSERT(offset % 4U == 0U, "offset must be a multiple of 4");
1428 	__ASSERT(POINTER_TO_UINT(dst) % 4U == 0U, "dst must be 32-bit aligned");
1429 	__ASSERT(len % 4U == 0U, "len must be a multiple of 4");
1430 
1431 #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
1432 	int err;
1433 
1434 	err = sys_cache_data_invd_range((void *)(base + offset), len);
1435 	if (err != 0) {
1436 		return err;
1437 	}
1438 #endif /* !defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE) */
1439 
1440 	while (len32-- > 0) {
1441 		*dst32++ = *src32++;
1442 	}
1443 
1444 	return 0;
1445 }
1446 
1447 /**
1448  * @brief Bosch M_CAN driver front-end callback helper for writing to memory mapped Message RAM
1449  *
1450  * @param base Base address of the Message RAM for the given Bosch M_CAN instance. The base address
1451  *        must be 32-bit aligned.
1452  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1453  *        offset must be 32-bit aligned.
1454  * @param src Source for the data to be written. The source address must be 32-bit aligned.
1455  * @param len Number of bytes to write. Must be a multiple of 4.
1456  *
1457  * @retval 0 If successful.
1458  * @retval -EIO General input/output error.
1459  */
can_mcan_sys_write_mram(mem_addr_t base,uint16_t offset,const void * src,size_t len)1460 static inline int can_mcan_sys_write_mram(mem_addr_t base, uint16_t offset, const void *src,
1461 					  size_t len)
1462 {
1463 	volatile uint32_t *dst32 = (volatile uint32_t *)(base + offset);
1464 	const uint32_t *src32 = (const uint32_t *)src;
1465 	size_t len32 = len / sizeof(uint32_t);
1466 
1467 	__ASSERT(base % 4U == 0U, "base must be a multiple of 4");
1468 	__ASSERT(offset % 4U == 0U, "offset must be a multiple of 4");
1469 	__ASSERT(POINTER_TO_UINT(src) % 4U == 0U, "src must be 32-bit aligned");
1470 	__ASSERT(len % 4U == 0U, "len must be a multiple of 4");
1471 
1472 	while (len32-- > 0) {
1473 		*dst32++ = *src32++;
1474 	}
1475 
1476 #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
1477 	return sys_cache_data_flush_range((void *)(base + offset), len);
1478 #else /* defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE) */
1479 	return 0;
1480 #endif /* !defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE) */
1481 }
1482 
1483 /**
1484  * @brief Bosch M_CAN driver front-end callback helper for clearing memory mapped Message RAM
1485  *
1486  * Clear Message RAM by writing 0 to all words.
1487  *
1488  * @param base Base address of the Message RAM for the given Bosch M_CAN instance. The base address
1489  *        must be 32-bit aligned.
1490  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1491  *        offset must be 32-bit aligned.
1492  * @param len Number of bytes to clear. Must be a multiple of 4.
1493  *
1494  * @retval 0 If successful.
1495  * @retval -EIO General input/output error.
1496  */
can_mcan_sys_clear_mram(mem_addr_t base,uint16_t offset,size_t len)1497 static inline int can_mcan_sys_clear_mram(mem_addr_t base, uint16_t offset, size_t len)
1498 {
1499 	volatile uint32_t *dst32 = (volatile uint32_t *)(base + offset);
1500 	size_t len32 = len / sizeof(uint32_t);
1501 
1502 	__ASSERT(base % 4U == 0U, "base must be a multiple of 4");
1503 	__ASSERT(offset % 4U == 0U, "offset must be a multiple of 4");
1504 	__ASSERT(len % 4U == 0U, "len must be a multiple of 4");
1505 
1506 	while (len32-- > 0) {
1507 		*dst32++ = 0U;
1508 	}
1509 
1510 #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
1511 	return sys_cache_data_flush_range((void *)(base + offset), len);
1512 #else /* defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE) */
1513 	return 0;
1514 #endif /* !defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE) */
1515 }
1516 
1517 /**
1518  * @brief Read a Bosch M_CAN register
1519  *
1520  * @param dev Pointer to the device structure for the driver instance.
1521  * @param reg Register offset
1522  * @param[out] val Register value
1523  *
1524  * @retval 0 If successful.
1525  * @retval -ENOTSUP Register not supported.
1526  * @retval -EIO General input/output error.
1527  */
1528 int can_mcan_read_reg(const struct device *dev, uint16_t reg, uint32_t *val);
1529 
1530 /**
1531  * @brief Write a Bosch M_CAN register
1532  *
1533  * @param dev Pointer to the device structure for the driver instance.
1534  * @param reg Register offset
1535  * @param val Register value
1536  *
1537  * @retval 0 If successful.
1538  * @retval -ENOTSUP Register not supported.
1539  * @retval -EIO General input/output error.
1540  */
1541 int can_mcan_write_reg(const struct device *dev, uint16_t reg, uint32_t val);
1542 
1543 /**
1544  * @brief Read from Bosch M_CAN Message RAM
1545  *
1546  * @param dev Pointer to the device structure for the driver instance.
1547  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1548  *        offset must be 32-bit aligned.
1549  * @param[out] dst Destination for the data read.
1550  * @param len Number of bytes to read. Must be a multiple of 4.
1551  *
1552  * @retval 0 If successful.
1553  * @retval -EIO General input/output error.
1554  */
can_mcan_read_mram(const struct device * dev,uint16_t offset,void * dst,size_t len)1555 static inline int can_mcan_read_mram(const struct device *dev, uint16_t offset, void *dst,
1556 				     size_t len)
1557 {
1558 	const struct can_mcan_config *config = dev->config;
1559 
1560 	return config->ops->read_mram(dev, offset, dst, len);
1561 }
1562 
1563 /**
1564  * @brief Write to Bosch M_CAN Message RAM
1565  *
1566  * @param dev Pointer to the device structure for the driver instance.
1567  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1568  *        offset must be 32-bit aligned.
1569  * @param src Source for the data to be written
1570  * @param len Number of bytes to write. Must be a multiple of 4.
1571  *
1572  * @retval 0 If successful.
1573  * @retval -EIO General input/output error.
1574  */
can_mcan_write_mram(const struct device * dev,uint16_t offset,const void * src,size_t len)1575 static inline int can_mcan_write_mram(const struct device *dev, uint16_t offset, const void *src,
1576 				      size_t len)
1577 {
1578 	const struct can_mcan_config *config = dev->config;
1579 
1580 	return config->ops->write_mram(dev, offset, src, len);
1581 }
1582 
1583 /**
1584  * @brief Clear Bosch M_CAN Message RAM
1585  *
1586  * Clear Message RAM by writing 0 to all words.
1587  *
1588  * @param dev Pointer to the device structure for the driver instance.
1589  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1590  *        offset must be 32-bit aligned.
1591  * @param len Number of bytes to clear. Must be a multiple of 4.
1592  *
1593  * @retval 0 If successful.
1594  * @retval -EIO General input/output error.
1595  */
can_mcan_clear_mram(const struct device * dev,uint16_t offset,size_t len)1596 static inline int can_mcan_clear_mram(const struct device *dev, uint16_t offset, size_t len)
1597 {
1598 	const struct can_mcan_config *config = dev->config;
1599 
1600 	return config->ops->clear_mram(dev, offset, len);
1601 }
1602 
1603 /**
1604  * @brief Configure Bosch M_MCAN Message RAM start addresses.
1605  *
1606  * Bosch M_CAN driver front-end callback helper function for configuring the start addresses of the
1607  * Bosch M_CAN Rx FIFO0 (RXFOC), Rx FIFO1 (RXF1C), Rx Buffer (RXBCC), Tx Buffer (TXBC), and Tx Event
1608  * FIFO (TXEFC) in Message RAM.
1609  *
1610  * The start addresses (containing bits 15:2 since Bosch M_CAN message RAM is accessed as 32 bit
1611  * words) are calculated relative to the provided Message RAM Base Address (mrba).
1612  *
1613  * Some Bosch M_CAN implementations use a fixed Message RAM configuration, other use a fixed memory
1614  * area and relative addressing, others again have custom registers for configuring the Message
1615  * RAM. It is the responsibility of the front-end driver to call this function during driver
1616  * initialization as needed.
1617  *
1618  * @param dev Pointer to the device structure for the driver instance.
1619  * @param mrba Message RAM Base Address.
1620  * @param mram Message RAM Address.
1621  *
1622  * @retval 0 If successful.
1623  * @retval -EIO General input/output error.
1624  */
1625 int can_mcan_configure_mram(const struct device *dev, uintptr_t mrba, uintptr_t mram);
1626 
1627 /**
1628  * @brief Bosch M_CAN driver initialization callback.
1629  *
1630  * @param dev Pointer to the device structure for the driver instance.
1631  */
1632 int can_mcan_init(const struct device *dev);
1633 
1634 /**
1635  * @brief Bosch M_CAN driver m_can_int0 IRQ handler.
1636  *
1637  * @param dev Pointer to the device structure for the driver instance.
1638  */
1639 void can_mcan_line_0_isr(const struct device *dev);
1640 
1641 /**
1642  * @brief Bosch M_CAN driver m_can_int1 IRQ handler.
1643  *
1644  * @param dev Pointer to the device structure for the driver instance.
1645  */
1646 void can_mcan_line_1_isr(const struct device *dev);
1647 
1648 /**
1649  * @brief Enable Bosch M_CAN configuration change.
1650  *
1651  * @param dev Pointer to the device structure for the driver instance.
1652  */
1653 void can_mcan_enable_configuration_change(const struct device *dev);
1654 
1655 /**
1656  * @brief Bosch M_CAN driver callback API upon getting CAN controller capabilities
1657  * See @a can_get_capabilities() for argument description
1658  */
1659 int can_mcan_get_capabilities(const struct device *dev, can_mode_t *cap);
1660 
1661 /**
1662  * @brief Bosch M_CAN driver callback API upon starting CAN controller
1663  * See @a can_start() for argument description
1664  */
1665 int can_mcan_start(const struct device *dev);
1666 
1667 /**
1668  * @brief Bosch M_CAN driver callback API upon stopping CAN controller
1669  * See @a can_stop() for argument description
1670  */
1671 int can_mcan_stop(const struct device *dev);
1672 
1673 /**
1674  * @brief Bosch M_CAN driver callback API upon setting CAN controller mode
1675  * See @a can_set_mode() for argument description
1676  */
1677 int can_mcan_set_mode(const struct device *dev, can_mode_t mode);
1678 
1679 /**
1680  * @brief Bosch M_CAN driver callback API upon setting CAN bus timing
1681  * See @a can_set_timing() for argument description
1682  */
1683 int can_mcan_set_timing(const struct device *dev, const struct can_timing *timing);
1684 
1685 /**
1686  * @brief Bosch M_CAN driver callback API upon setting CAN bus data phase timing
1687  * See @a can_set_timing_data() for argument description
1688  */
1689 int can_mcan_set_timing_data(const struct device *dev, const struct can_timing *timing_data);
1690 
1691 #ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
1692 /**
1693  * @brief Bosch M_CAN driver callback API upon recovering the CAN bus
1694  * See @a can_recover() for argument description
1695  */
1696 int can_mcan_recover(const struct device *dev, k_timeout_t timeout);
1697 #endif /* !CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */
1698 
1699 int can_mcan_send(const struct device *dev, const struct can_frame *frame, k_timeout_t timeout,
1700 		  can_tx_callback_t callback, void *user_data);
1701 
1702 int can_mcan_get_max_filters(const struct device *dev, bool ide);
1703 
1704 /**
1705  * @brief Bosch M_CAN driver callback API upon adding an RX filter
1706  * See @a can_add_rx_callback() for argument description
1707  */
1708 int can_mcan_add_rx_filter(const struct device *dev, can_rx_callback_t callback, void *user_data,
1709 			   const struct can_filter *filter);
1710 
1711 /**
1712  * @brief Bosch M_CAN driver callback API upon removing an RX filter
1713  * See @a can_remove_rx_filter() for argument description
1714  */
1715 void can_mcan_remove_rx_filter(const struct device *dev, int filter_id);
1716 
1717 /**
1718  * @brief Bosch M_CAN driver callback API upon getting the CAN controller state
1719  * See @a can_get_state() for argument description
1720  */
1721 int can_mcan_get_state(const struct device *dev, enum can_state *state,
1722 		       struct can_bus_err_cnt *err_cnt);
1723 
1724 /**
1725  * @brief Bosch M_CAN driver callback API upon setting a state change callback
1726  * See @a can_set_state_change_callback() for argument description
1727  */
1728 void can_mcan_set_state_change_callback(const struct device *dev,
1729 					can_state_change_callback_t callback, void *user_data);
1730 
1731 /**
1732  * @brief Bosch M_CAN driver callback API upon getting the maximum supported bitrate
1733  * See @a can_get_max_bitrate() for argument description
1734  */
1735 int can_mcan_get_max_bitrate(const struct device *dev, uint32_t *max_bitrate);
1736 
1737 #endif /* ZEPHYR_INCLUDE_DRIVERS_CAN_CAN_MCAN_H_ */
1738