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