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 __nocache_noinit __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 can_driver_data common;
1065 	struct k_mutex lock;
1066 	struct k_sem tx_sem;
1067 	struct k_mutex tx_mtx;
1068 	void *custom;
1069 } __aligned(4);
1070 
1071 /**
1072  * @brief Bosch M_CAN driver front-end callback for reading a register value
1073  *
1074  * @param dev Pointer to the device structure for the driver instance.
1075  * @param reg Register offset
1076  * @param[out] val Register value
1077  *
1078  * @retval 0 If successful.
1079  * @retval -ENOTSUP Register not supported.
1080  * @retval -EIO General input/output error.
1081  */
1082 typedef int (*can_mcan_read_reg_t)(const struct device *dev, uint16_t reg, uint32_t *val);
1083 
1084 /**
1085  * @brief Bosch M_CAN driver front-end callback for writing a register value
1086  *
1087  * @param dev Pointer to the device structure for the driver instance.
1088  * @param reg Register offset
1089  * @param val Register value
1090  *
1091  * @retval 0 If successful.
1092  * @retval -ENOTSUP Register not supported.
1093  * @retval -EIO General input/output error.
1094  */
1095 typedef int (*can_mcan_write_reg_t)(const struct device *dev, uint16_t reg, uint32_t val);
1096 
1097 /**
1098  * @brief Bosch M_CAN driver front-end callback for reading from Message RAM
1099  *
1100  * @param dev Pointer to the device structure for the driver instance.
1101  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1102  *        offset must be 32-bit aligned.
1103  * @param[out] dst Destination for the data read. The destination address must be 32-bit aligned.
1104  * @param len Number of bytes to read. Must be a multiple of 4.
1105  *
1106  * @retval 0 If successful.
1107  * @retval -EIO General input/output error.
1108  */
1109 typedef int (*can_mcan_read_mram_t)(const struct device *dev, uint16_t offset, void *dst,
1110 				    size_t len);
1111 
1112 /**
1113  * @brief Bosch M_CAN driver front-end callback for writing to Message RAM
1114  *
1115  * @param dev Pointer to the device structure for the driver instance.
1116  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1117  *        offset must be 32-bit aligned.
1118  * @param src Source for the data to be written. The source address must be 32-bit aligned.
1119  * @param len Number of bytes to write. Must be a multiple of 4.
1120  *
1121  * @retval 0 If successful.
1122  * @retval -EIO General input/output error.
1123  */
1124 typedef int (*can_mcan_write_mram_t)(const struct device *dev, uint16_t offset, const void *src,
1125 				     size_t len);
1126 
1127 /**
1128  * @brief Bosch M_CAN driver front-end callback for clearing Message RAM
1129  *
1130  * Clear Message RAM by writing 0 to all words.
1131  *
1132  * @param dev Pointer to the device structure for the driver instance.
1133  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1134  *        offset must be 32-bit aligned.
1135  * @param len Number of bytes to clear. Must be a multiple of 4.
1136  *
1137  * @retval 0 If successful.
1138  * @retval -EIO General input/output error.
1139  */
1140 typedef int (*can_mcan_clear_mram_t)(const struct device *dev, uint16_t offset, size_t len);
1141 
1142 /**
1143  * @brief Bosch M_CAN driver front-end operations.
1144  */
1145 struct can_mcan_ops {
1146 	can_mcan_read_reg_t read_reg;
1147 	can_mcan_write_reg_t write_reg;
1148 	can_mcan_read_mram_t read_mram;
1149 	can_mcan_write_mram_t write_mram;
1150 	can_mcan_clear_mram_t clear_mram;
1151 };
1152 
1153 /**
1154  * @brief Bosch M_CAN driver internal Tx callback structure.
1155  */
1156 struct can_mcan_tx_callback {
1157 	can_tx_callback_t function;
1158 	void *user_data;
1159 };
1160 
1161 /**
1162  * @brief Bosch M_CAN driver internal Rx callback structure.
1163  */
1164 struct can_mcan_rx_callback {
1165 	can_rx_callback_t function;
1166 	void *user_data;
1167 };
1168 
1169 /**
1170  * @brief Bosch M_CAN driver internal Tx + Rx callbacks structure.
1171  */
1172 struct can_mcan_callbacks {
1173 	struct can_mcan_tx_callback *tx;
1174 	struct can_mcan_rx_callback *std;
1175 	struct can_mcan_rx_callback *ext;
1176 	uint8_t num_tx;
1177 	uint8_t num_std;
1178 	uint8_t num_ext;
1179 };
1180 
1181 /**
1182  * @brief Define Bosch M_CAN TX and RX callbacks
1183  *
1184  * This macro allows a Bosch M_CAN driver frontend using a fixed Message RAM configuration to limit
1185  * the required software resources (e.g. limit the number of the standard (11-bit) or extended
1186  * (29-bit) filters in use).
1187  *
1188  * Frontend drivers supporting dynamic Message RAM configuration should use @ref
1189  * CAN_MCAN_DT_CALLBACKS_DEFINE() or @ref CAN_MCAN_DT_INST_CALLBACKS_DEFINE() instead.
1190  *
1191  * @param _name callbacks variable name
1192  * @param _tx Number of Tx callbacks
1193  * @param _std Number of standard (11-bit) filter callbacks
1194  * @param _ext Number of extended (29-bit) filter callbacks
1195  * @see CAN_MCAN_DT_CALLBACKS_DEFINE()
1196  */
1197 #define CAN_MCAN_CALLBACKS_DEFINE(_name, _tx, _std, _ext)                                          \
1198 	static struct can_mcan_tx_callback _name##_tx_cbs[_tx];                                    \
1199 	static struct can_mcan_rx_callback _name##_std_cbs[_std];                                  \
1200 	static struct can_mcan_rx_callback _name##_ext_cbs[_ext];                                  \
1201 	static const struct can_mcan_callbacks _name = {                                           \
1202 		.tx = _name##_tx_cbs,                                                              \
1203 		.std = _name##_std_cbs,                                                            \
1204 		.ext = _name##_ext_cbs,                                                            \
1205 		.num_tx = _tx,                                                                     \
1206 		.num_std = _std,                                                                   \
1207 		.num_ext = _ext,                                                                   \
1208 	}
1209 
1210 /**
1211  * @brief Define Bosch M_CAN TX and RX callbacks
1212  * @param node_id node identifier
1213  * @param _name callbacks variable name
1214  * @see CAN_MCAN_CALLBACKS_DEFINE()
1215  */
1216 #define CAN_MCAN_DT_CALLBACKS_DEFINE(node_id, _name)                                               \
1217 	CAN_MCAN_CALLBACKS_DEFINE(_name, CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id),             \
1218 				  CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id),                   \
1219 				  CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id))
1220 
1221 /**
1222  * @brief Equivalent to CAN_MCAN_DT_CALLBACKS_DEFINE(DT_DRV_INST(inst))
1223  * @param inst DT_DRV_COMPAT instance number
1224  * @param _name callbacks variable name
1225  * @see CAN_MCAN_DT_CALLBACKS_DEFINE()
1226  */
1227 #define CAN_MCAN_DT_INST_CALLBACKS_DEFINE(inst, _name)                                             \
1228 	CAN_MCAN_DT_CALLBACKS_DEFINE(DT_DRV_INST(inst), _name)
1229 
1230 /**
1231  * @brief Bosch M_CAN driver internal configuration structure.
1232  */
1233 struct can_mcan_config {
1234 	const struct can_driver_config common;
1235 	const struct can_mcan_ops *ops;
1236 	const struct can_mcan_callbacks *callbacks;
1237 	uint16_t mram_elements[CAN_MCAN_MRAM_CFG_NUM_CELLS];
1238 	uint16_t mram_offsets[CAN_MCAN_MRAM_CFG_NUM_CELLS];
1239 	size_t mram_size;
1240 	const void *custom;
1241 };
1242 
1243 /**
1244  * @brief Get an array containing the number of elements in Bosch M_CAN Message RAM
1245  *
1246  * The order of the array entries is given by the @ref CAN_MCAN_MRAM_CFG definitions.
1247  *
1248  * @param node_id node identifier
1249  * @return array of number of elements
1250  */
1251 #define CAN_MCAN_DT_MRAM_ELEMENTS_GET(node_id)                                                     \
1252 	{                                                                                          \
1253 		0, /* offset cell */                                                               \
1254 			CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id),                             \
1255 			CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id),                             \
1256 			CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(node_id),                               \
1257 			CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(node_id),                               \
1258 			CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(node_id),                              \
1259 			CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(node_id),                          \
1260 			CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id)                               \
1261 	}
1262 
1263 /**
1264  * @brief Get an array containing the base offsets for element 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 base offsets for elements
1270  */
1271 #define CAN_MCAN_DT_MRAM_OFFSETS_GET(node_id)                                                      \
1272 	{                                                                                          \
1273 		0, /* offset cell */                                                               \
1274 			CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET(node_id),                               \
1275 			CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET(node_id),                               \
1276 			CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET(node_id),                                 \
1277 			CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET(node_id),                                 \
1278 			CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET(node_id),                                \
1279 			CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET(node_id),                            \
1280 			CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET(node_id)                                 \
1281 	}
1282 
1283 /**
1284  * @brief Static initializer for @p can_mcan_config struct
1285  *
1286  * @param node_id Devicetree node identifier
1287  * @param _custom Pointer to custom driver frontend configuration structure
1288  * @param _ops Pointer to front-end @a can_mcan_ops
1289  * @param _cbs Pointer to front-end @a can_mcan_callbacks
1290  */
1291 #ifdef CONFIG_CAN_FD_MODE
1292 #define CAN_MCAN_DT_CONFIG_GET(node_id, _custom, _ops, _cbs)                                       \
1293 	{                                                                                          \
1294 		.common = CAN_DT_DRIVER_CONFIG_GET(node_id, 0, 8000000),                           \
1295 		.ops = _ops,                                                                       \
1296 		.callbacks = _cbs,                                                                 \
1297 		.mram_elements = CAN_MCAN_DT_MRAM_ELEMENTS_GET(node_id),                           \
1298 		.mram_offsets = CAN_MCAN_DT_MRAM_OFFSETS_GET(node_id),                             \
1299 		.mram_size = CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(node_id),                              \
1300 		.custom = _custom,                                                                 \
1301 	}
1302 #else /* CONFIG_CAN_FD_MODE */
1303 #define CAN_MCAN_DT_CONFIG_GET(node_id, _custom, _ops, _cbs)                                       \
1304 	{                                                                                          \
1305 		.common = CAN_DT_DRIVER_CONFIG_GET(node_id, 0, 1000000),                           \
1306 		.ops = _ops,                                                                       \
1307 		.callbacks = _cbs,                                                                 \
1308 		.mram_elements = CAN_MCAN_DT_MRAM_ELEMENTS_GET(node_id),                           \
1309 		.mram_offsets = CAN_MCAN_DT_MRAM_OFFSETS_GET(node_id),                             \
1310 		.mram_size = CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(node_id),                              \
1311 		.custom = _custom,                                                                 \
1312 	}
1313 #endif /* !CONFIG_CAN_FD_MODE */
1314 
1315 /**
1316  * @brief Static initializer for @p can_mcan_config struct from DT_DRV_COMPAT instance
1317  *
1318  * @param inst DT_DRV_COMPAT instance number
1319  * @param _custom Pointer to custom driver frontend configuration structure
1320  * @param _ops Pointer to front-end @a can_mcan_ops
1321  * @param _cbs Pointer to front-end @a can_mcan_callbacks
1322  * @see CAN_MCAN_DT_CONFIG_GET()
1323  */
1324 #define CAN_MCAN_DT_CONFIG_INST_GET(inst, _custom, _ops, _cbs)                                     \
1325 	CAN_MCAN_DT_CONFIG_GET(DT_DRV_INST(inst), _custom, _ops, _cbs)
1326 
1327 /**
1328  * @brief Initializer for a @a can_mcan_data struct
1329  * @param _custom Pointer to custom driver frontend data structure
1330  */
1331 #define CAN_MCAN_DATA_INITIALIZER(_custom)                                                         \
1332 	{                                                                                          \
1333 		.custom = _custom,                                                                 \
1334 	}
1335 
1336 /**
1337  * @brief Bosch M_CAN driver front-end callback helper for reading a memory mapped register
1338  *
1339  * @param base Register base address
1340  * @param reg Register offset
1341  * @param[out] val Register value
1342  *
1343  * @retval 0 Memory mapped register read always succeeds.
1344  */
can_mcan_sys_read_reg(mm_reg_t base,uint16_t reg,uint32_t * val)1345 static inline int can_mcan_sys_read_reg(mm_reg_t base, uint16_t reg, uint32_t *val)
1346 {
1347 	*val = sys_read32(base + reg);
1348 
1349 	return 0;
1350 }
1351 
1352 /**
1353  * @brief Bosch M_CAN driver front-end callback helper for writing a memory mapped register
1354  *
1355  * @param base Register base address
1356  * @param reg Register offset
1357  * @param val Register value
1358  *
1359  * @retval 0 Memory mapped register write always succeeds.
1360  */
can_mcan_sys_write_reg(mm_reg_t base,uint16_t reg,uint32_t val)1361 static inline int can_mcan_sys_write_reg(mm_reg_t base, uint16_t reg, uint32_t val)
1362 {
1363 	sys_write32(val, base + reg);
1364 
1365 	return 0;
1366 }
1367 
1368 /**
1369  * @brief Bosch M_CAN driver front-end callback helper for reading from memory mapped Message RAM
1370  *
1371  * @param base Base address of the Message RAM for the given Bosch M_CAN instance. The base address
1372  *        must be 32-bit aligned.
1373  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1374  *        offset must be 32-bit aligned.
1375  * @param[out] dst Destination for the data read. The destination address must be 32-bit aligned.
1376  * @param len Number of bytes to read. Must be a multiple of 4.
1377  *
1378  * @retval 0 If successful.
1379  * @retval -EIO General input/output error.
1380  */
can_mcan_sys_read_mram(mem_addr_t base,uint16_t offset,void * dst,size_t len)1381 static inline int can_mcan_sys_read_mram(mem_addr_t base, uint16_t offset, void *dst, size_t len)
1382 {
1383 	volatile uint32_t *src32 = (volatile uint32_t *)(base + offset);
1384 	uint32_t *dst32 = (uint32_t *)dst;
1385 	size_t len32 = len / sizeof(uint32_t);
1386 
1387 	__ASSERT(base % 4U == 0U, "base must be a multiple of 4");
1388 	__ASSERT(offset % 4U == 0U, "offset must be a multiple of 4");
1389 	__ASSERT(POINTER_TO_UINT(dst) % 4U == 0U, "dst must be 32-bit aligned");
1390 	__ASSERT(len % 4U == 0U, "len must be a multiple of 4");
1391 
1392 #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
1393 	int err;
1394 
1395 	err = sys_cache_data_invd_range((void *)(base + offset), len);
1396 	if (err != 0) {
1397 		return err;
1398 	}
1399 #endif /* !defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE) */
1400 
1401 	while (len32-- > 0) {
1402 		*dst32++ = *src32++;
1403 	}
1404 
1405 	return 0;
1406 }
1407 
1408 /**
1409  * @brief Bosch M_CAN driver front-end callback helper for writing to memory mapped Message RAM
1410  *
1411  * @param base Base address of the Message RAM for the given Bosch M_CAN instance. The base address
1412  *        must be 32-bit aligned.
1413  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1414  *        offset must be 32-bit aligned.
1415  * @param src Source for the data to be written. The source address must be 32-bit aligned.
1416  * @param len Number of bytes to write. Must be a multiple of 4.
1417  *
1418  * @retval 0 If successful.
1419  * @retval -EIO General input/output error.
1420  */
can_mcan_sys_write_mram(mem_addr_t base,uint16_t offset,const void * src,size_t len)1421 static inline int can_mcan_sys_write_mram(mem_addr_t base, uint16_t offset, const void *src,
1422 					  size_t len)
1423 {
1424 	volatile uint32_t *dst32 = (volatile uint32_t *)(base + offset);
1425 	const uint32_t *src32 = (const uint32_t *)src;
1426 	size_t len32 = len / sizeof(uint32_t);
1427 
1428 	__ASSERT(base % 4U == 0U, "base must be a multiple of 4");
1429 	__ASSERT(offset % 4U == 0U, "offset must be a multiple of 4");
1430 	__ASSERT(POINTER_TO_UINT(src) % 4U == 0U, "src must be 32-bit aligned");
1431 	__ASSERT(len % 4U == 0U, "len must be a multiple of 4");
1432 
1433 	while (len32-- > 0) {
1434 		*dst32++ = *src32++;
1435 	}
1436 
1437 #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
1438 	return sys_cache_data_flush_range((void *)(base + offset), len);
1439 #else /* defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE) */
1440 	return 0;
1441 #endif /* !defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE) */
1442 }
1443 
1444 /**
1445  * @brief Bosch M_CAN driver front-end callback helper for clearing memory mapped Message RAM
1446  *
1447  * Clear Message RAM by writing 0 to all words.
1448  *
1449  * @param base Base address of the Message RAM for the given Bosch M_CAN instance. The base address
1450  *        must be 32-bit aligned.
1451  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1452  *        offset must be 32-bit aligned.
1453  * @param len Number of bytes to clear. Must be a multiple of 4.
1454  *
1455  * @retval 0 If successful.
1456  * @retval -EIO General input/output error.
1457  */
can_mcan_sys_clear_mram(mem_addr_t base,uint16_t offset,size_t len)1458 static inline int can_mcan_sys_clear_mram(mem_addr_t base, uint16_t offset, size_t len)
1459 {
1460 	volatile uint32_t *dst32 = (volatile uint32_t *)(base + offset);
1461 	size_t len32 = len / sizeof(uint32_t);
1462 
1463 	__ASSERT(base % 4U == 0U, "base must be a multiple of 4");
1464 	__ASSERT(offset % 4U == 0U, "offset must be a multiple of 4");
1465 	__ASSERT(len % 4U == 0U, "len must be a multiple of 4");
1466 
1467 	while (len32-- > 0) {
1468 		*dst32++ = 0U;
1469 	}
1470 
1471 #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
1472 	return sys_cache_data_flush_range((void *)(base + offset), len);
1473 #else /* defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE) */
1474 	return 0;
1475 #endif /* !defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE) */
1476 }
1477 
1478 /**
1479  * @brief Read a Bosch M_CAN register
1480  *
1481  * @param dev Pointer to the device structure for the driver instance.
1482  * @param reg Register offset
1483  * @param[out] val Register value
1484  *
1485  * @retval 0 If successful.
1486  * @retval -ENOTSUP Register not supported.
1487  * @retval -EIO General input/output error.
1488  */
1489 int can_mcan_read_reg(const struct device *dev, uint16_t reg, uint32_t *val);
1490 
1491 /**
1492  * @brief Write a Bosch M_CAN register
1493  *
1494  * @param dev Pointer to the device structure for the driver instance.
1495  * @param reg Register offset
1496  * @param val Register value
1497  *
1498  * @retval 0 If successful.
1499  * @retval -ENOTSUP Register not supported.
1500  * @retval -EIO General input/output error.
1501  */
1502 int can_mcan_write_reg(const struct device *dev, uint16_t reg, uint32_t val);
1503 
1504 /**
1505  * @brief Read from Bosch M_CAN Message RAM
1506  *
1507  * @param dev Pointer to the device structure for the driver instance.
1508  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1509  *        offset must be 32-bit aligned.
1510  * @param[out] dst Destination for the data read.
1511  * @param len Number of bytes to read. Must be a multiple of 4.
1512  *
1513  * @retval 0 If successful.
1514  * @retval -EIO General input/output error.
1515  */
can_mcan_read_mram(const struct device * dev,uint16_t offset,void * dst,size_t len)1516 static inline int can_mcan_read_mram(const struct device *dev, uint16_t offset, void *dst,
1517 				     size_t len)
1518 {
1519 	const struct can_mcan_config *config = dev->config;
1520 
1521 	return config->ops->read_mram(dev, offset, dst, len);
1522 }
1523 
1524 /**
1525  * @brief Write to Bosch M_CAN Message RAM
1526  *
1527  * @param dev Pointer to the device structure for the driver instance.
1528  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1529  *        offset must be 32-bit aligned.
1530  * @param src Source for the data to be written
1531  * @param len Number of bytes to write. Must be a multiple of 4.
1532  *
1533  * @retval 0 If successful.
1534  * @retval -EIO General input/output error.
1535  */
can_mcan_write_mram(const struct device * dev,uint16_t offset,const void * src,size_t len)1536 static inline int can_mcan_write_mram(const struct device *dev, uint16_t offset, const void *src,
1537 				      size_t len)
1538 {
1539 	const struct can_mcan_config *config = dev->config;
1540 
1541 	return config->ops->write_mram(dev, offset, src, len);
1542 }
1543 
1544 /**
1545  * @brief Clear Bosch M_CAN Message RAM
1546  *
1547  * Clear Message RAM by writing 0 to all words.
1548  *
1549  * @param dev Pointer to the device structure for the driver instance.
1550  * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1551  *        offset must be 32-bit aligned.
1552  * @param len Number of bytes to clear. Must be a multiple of 4.
1553  *
1554  * @retval 0 If successful.
1555  * @retval -EIO General input/output error.
1556  */
can_mcan_clear_mram(const struct device * dev,uint16_t offset,size_t len)1557 static inline int can_mcan_clear_mram(const struct device *dev, uint16_t offset, size_t len)
1558 {
1559 	const struct can_mcan_config *config = dev->config;
1560 
1561 	return config->ops->clear_mram(dev, offset, len);
1562 }
1563 
1564 /**
1565  * @brief Configure Bosch M_MCAN Message RAM start addresses.
1566  *
1567  * Bosch M_CAN driver front-end callback helper function for configuring the start addresses of the
1568  * Bosch M_CAN Rx FIFO0 (RXFOC), Rx FIFO1 (RXF1C), Rx Buffer (RXBCC), Tx Buffer (TXBC), and Tx Event
1569  * FIFO (TXEFC) in Message RAM.
1570  *
1571  * The start addresses (containing bits 15:2 since Bosch M_CAN message RAM is accessed as 32 bit
1572  * words) are calculated relative to the provided Message RAM Base Address (mrba).
1573  *
1574  * Some Bosch M_CAN implementations use a fixed Message RAM configuration, other use a fixed memory
1575  * area and relative addressing, others again have custom registers for configuring the Message
1576  * RAM. It is the responsibility of the front-end driver to call this function during driver
1577  * initialization as needed.
1578  *
1579  * @param dev Pointer to the device structure for the driver instance.
1580  * @param mrba Message RAM Base Address.
1581  * @param mram Message RAM Address.
1582  *
1583  * @retval 0 If successful.
1584  * @retval -EIO General input/output error.
1585  */
1586 int can_mcan_configure_mram(const struct device *dev, uintptr_t mrba, uintptr_t mram);
1587 
1588 /**
1589  * @brief Bosch M_CAN driver initialization callback.
1590  *
1591  * @param dev Pointer to the device structure for the driver instance.
1592  */
1593 int can_mcan_init(const struct device *dev);
1594 
1595 /**
1596  * @brief Bosch M_CAN driver m_can_int0 IRQ handler.
1597  *
1598  * @param dev Pointer to the device structure for the driver instance.
1599  */
1600 void can_mcan_line_0_isr(const struct device *dev);
1601 
1602 /**
1603  * @brief Bosch M_CAN driver m_can_int1 IRQ handler.
1604  *
1605  * @param dev Pointer to the device structure for the driver instance.
1606  */
1607 void can_mcan_line_1_isr(const struct device *dev);
1608 
1609 /**
1610  * @brief Enable Bosch M_CAN configuration change.
1611  *
1612  * @param dev Pointer to the device structure for the driver instance.
1613  */
1614 void can_mcan_enable_configuration_change(const struct device *dev);
1615 
1616 /**
1617  * @brief Bosch M_CAN driver callback API upon getting CAN controller capabilities
1618  * See @a can_get_capabilities() for argument description
1619  */
1620 int can_mcan_get_capabilities(const struct device *dev, can_mode_t *cap);
1621 
1622 /**
1623  * @brief Bosch M_CAN driver callback API upon starting CAN controller
1624  * See @a can_start() for argument description
1625  */
1626 int can_mcan_start(const struct device *dev);
1627 
1628 /**
1629  * @brief Bosch M_CAN driver callback API upon stopping CAN controller
1630  * See @a can_stop() for argument description
1631  */
1632 int can_mcan_stop(const struct device *dev);
1633 
1634 /**
1635  * @brief Bosch M_CAN driver callback API upon setting CAN controller mode
1636  * See @a can_set_mode() for argument description
1637  */
1638 int can_mcan_set_mode(const struct device *dev, can_mode_t mode);
1639 
1640 /**
1641  * @brief Bosch M_CAN driver callback API upon setting CAN bus timing
1642  * See @a can_set_timing() for argument description
1643  */
1644 int can_mcan_set_timing(const struct device *dev, const struct can_timing *timing);
1645 
1646 /**
1647  * @brief Bosch M_CAN driver callback API upon setting CAN bus data phase timing
1648  * See @a can_set_timing_data() for argument description
1649  */
1650 int can_mcan_set_timing_data(const struct device *dev, const struct can_timing *timing_data);
1651 
1652 #ifdef CONFIG_CAN_MANUAL_RECOVERY_MODE
1653 /**
1654  * @brief Bosch M_CAN driver callback API upon recovering the CAN bus
1655  * See @a can_recover() for argument description
1656  */
1657 int can_mcan_recover(const struct device *dev, k_timeout_t timeout);
1658 #endif /* CONFIG_CAN_MANUAL_RECOVERY_MODE */
1659 
1660 int can_mcan_send(const struct device *dev, const struct can_frame *frame, k_timeout_t timeout,
1661 		  can_tx_callback_t callback, void *user_data);
1662 
1663 int can_mcan_get_max_filters(const struct device *dev, bool ide);
1664 
1665 /**
1666  * @brief Bosch M_CAN driver callback API upon adding an RX filter
1667  * See @a can_add_rx_callback() for argument description
1668  */
1669 int can_mcan_add_rx_filter(const struct device *dev, can_rx_callback_t callback, void *user_data,
1670 			   const struct can_filter *filter);
1671 
1672 /**
1673  * @brief Bosch M_CAN driver callback API upon removing an RX filter
1674  * See @a can_remove_rx_filter() for argument description
1675  */
1676 void can_mcan_remove_rx_filter(const struct device *dev, int filter_id);
1677 
1678 /**
1679  * @brief Bosch M_CAN driver callback API upon getting the CAN controller state
1680  * See @a can_get_state() for argument description
1681  */
1682 int can_mcan_get_state(const struct device *dev, enum can_state *state,
1683 		       struct can_bus_err_cnt *err_cnt);
1684 
1685 /**
1686  * @brief Bosch M_CAN driver callback API upon setting a state change callback
1687  * See @a can_set_state_change_callback() for argument description
1688  */
1689 void can_mcan_set_state_change_callback(const struct device *dev,
1690 					can_state_change_callback_t callback, void *user_data);
1691 
1692 #endif /* ZEPHYR_INCLUDE_DRIVERS_CAN_CAN_MCAN_H_ */
1693