master
h 131 lines 4.71 KB
Raw
1 /*
2 * QEMU model of the NXP FLEXCAN device.
3 *
4 * Copyright (c) 2025 Matyas Bobek <matyas.bobek@gmail.com>
5 *
6 * Based on CTU CAN FD emulation implemented by Jan Charvat.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #ifndef HW_CAN_FLEXCAN_H
12 #define HW_CAN_FLEXCAN_H
13
14 #include "net/can_emu.h"
15 #include "qom/object.h"
16 #include "hw/misc/imx_ccm.h"
17
18 #define FLEXCAN_FIFO_DEPTH 6
19 #define FLEXCAN_MAILBOX_COUNT 64
20
21 /**
22 * Definitions of structs FlexcanRegs and FlexcanRegsMessageBuffer were
23 * originally written for the Linux kernel by:
24 * Andrey Volkov <andrey@volkov.fr>
25 * Sascha Hauer <s.hauer@pengutronix.de>
26 * Marc Kleine-Budde <mkl@pengutronix.de>
27 * David Jander <david@protonic.nl>
28 * and they have agreed to license them under GPL-2.0-or-later.
29 */
30
31 /* view of single message buffer registers */
32 typedef struct FlexcanRegsMessageBuffer {
33 uint32_t can_ctrl;
34 uint32_t can_id;
35 uint32_t data[2];
36 } FlexcanRegsMessageBuffer;
37
38 /* FlexCAN register in hw layout */
39 typedef struct FlexcanRegs {
40 uint32_t mcr; /* 0x00 */
41 uint32_t ctrl; /* 0x04 - not affected by soft reset */
42 uint32_t timer; /* 0x08 */
43 uint32_t tcr; /* 0x0C */
44 uint32_t rxmgmask; /* 0x10 - not affected by soft reset */
45 uint32_t rx14mask; /* 0x14 - not affected by soft reset */
46 uint32_t rx15mask; /* 0x18 - not affected by soft reset */
47 uint32_t ecr; /* 0x1C */
48 uint32_t esr; /* 0x20 */
49 uint32_t imask2; /* 0x24 */
50 uint32_t imask1; /* 0x28 */
51 uint32_t iflag2; /* 0x2C */
52 uint32_t iflag1; /* 0x30 */
53 union { /* 0x34 */
54 uint32_t gfwr_mx28; /* MX28, MX53 */
55 uint32_t ctrl2; /* MX6, VF610 - not affected by soft reset */
56 };
57 uint32_t esr2; /* 0x38 */
58 uint32_t imeur; /* 0x3C, unused */
59 uint32_t lrfr; /* 0x40, unused */
60 uint32_t crcr; /* 0x44 */
61 uint32_t rxfgmask; /* 0x48 */
62 uint32_t rxfir; /* 0x4C - not affected by soft reset */
63 uint32_t cbt; /* 0x50, unused - not affected by soft reset */
64 uint32_t _reserved2; /* 0x54 */
65 uint32_t dbg1; /* 0x58, unused */
66 uint32_t dbg2; /* 0x5C, unused */
67 uint32_t _reserved3[8]; /* 0x60 */
68 /* 0x80 - not affected by soft reset */
69 FlexcanRegsMessageBuffer mbs[FLEXCAN_MAILBOX_COUNT];
70 uint32_t _reserved4[256]; /* 0x480 */
71 uint32_t rximr[64]; /* 0x880 - not affected by soft reset */
72 uint32_t _reserved5[24]; /* 0x980 */
73 uint32_t gfwr_mx6; /* 0x9E0 - MX6 */
74
75 /* the rest is unused except for SMB */
76 uint32_t _reserved6[39]; /* 0x9E4 */
77 uint32_t _rxfir[6]; /* 0xA80 */
78 uint32_t _reserved8[2]; /* 0xA98 */
79 uint32_t _rxmgmask; /* 0xAA0 */
80 uint32_t _rxfgmask; /* 0xAA4 */
81 uint32_t _rx14mask; /* 0xAA8 */
82 uint32_t _rx15mask; /* 0xAAC */
83 uint32_t tx_smb[4]; /* 0xAB0 */
84 FlexcanRegsMessageBuffer rx_smb0; /* 0xAC0, used for SMB emulation */
85 uint32_t rx_smb1[4]; /* 0xAD0 */
86 uint32_t mecr; /* 0xAE0 */
87 uint32_t erriar; /* 0xAE4 */
88 uint32_t erridpr; /* 0xAE8 */
89 uint32_t errippr; /* 0xAEC */
90 uint32_t rerrar; /* 0xAF0 */
91 uint32_t rerrdr; /* 0xAF4 */
92 uint32_t rerrsynr; /* 0xAF8 */
93 uint32_t errsr; /* 0xAFC */
94 uint32_t _reserved7[64]; /* 0xB00 */
95 uint32_t fdctrl; /* 0xC00 - not affected by soft reset */
96 uint32_t fdcbt; /* 0xC04 - not affected by soft reset */
97 uint32_t fdcrc; /* 0xC08 */
98 uint32_t _reserved9[199]; /* 0xC0C */
99 uint32_t tx_smb_fd[18]; /* 0xF28 */
100 uint32_t rx_smb0_fd[18]; /* 0xF70 */
101 uint32_t rx_smb1_fd[18]; /* 0xFB8 */
102 } FlexcanRegs;
103
104 typedef struct FlexcanState {
105 SysBusDevice parent_obj;
106
107 MemoryRegion iomem;
108 IMXCCMState *ccm;
109 qemu_irq irq;
110
111 CanBusState *canbus;
112 CanBusClientState bus_client;
113
114 union {
115 FlexcanRegs regs;
116 uint32_t regs_raw[sizeof(FlexcanRegs) / 4];
117 };
118 int64_t timer_start;
119 uint64_t last_rx_timer_cycles;
120 int32_t locked_mbidx;
121 int32_t smb_target_mbidx;
122 uint32_t timer_freq;
123 } FlexcanState;
124
125 #define TYPE_CAN_FLEXCAN "flexcan"
126 OBJECT_DECLARE_SIMPLE_TYPE(FlexcanState, CAN_FLEXCAN);
127
128 #define TYPE_CAN_FLEXCAN2 "flexcan2"
129 #define TYPE_CAN_FLEXCAN3 "flexcan3"
130
131 #endif