1 | /* SPDX-License-Identifier: GPL-2.0 |
2 | * flexcan.c - FLEXCAN CAN controller driver |
3 | * |
4 | * Copyright (c) 2005-2006 Varma Electronics Oy |
5 | * Copyright (c) 2009 Sascha Hauer, Pengutronix |
6 | * Copyright (c) 2010-2017 Pengutronix, Marc Kleine-Budde <kernel@pengutronix.de> |
7 | * Copyright (c) 2014 David Jander, Protonic Holland |
8 | * Copyright (C) 2022 Amarula Solutions, Dario Binacchi <dario.binacchi@amarulasolutions.com> |
9 | * |
10 | * Based on code originally by Andrey Volkov <avolkov@varma-el.com> |
11 | * |
12 | */ |
13 | |
14 | #ifndef _FLEXCAN_H |
15 | #define _FLEXCAN_H |
16 | |
17 | #include <linux/can/rx-offload.h> |
18 | |
19 | /* FLEXCAN hardware feature flags |
20 | * |
21 | * Below is some version info we got: |
22 | * SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR rece- FD Mode MB |
23 | * Filter? connected? Passive detection ption in MB Supported? |
24 | * MCF5441X FlexCAN2 ? no yes no no no no 16 |
25 | * MX25 FlexCAN2 03.00.00.00 no no no no no no 64 |
26 | * MX28 FlexCAN2 03.00.04.00 yes yes no no no no 64 |
27 | * MX35 FlexCAN2 03.00.00.00 no no no no no no 64 |
28 | * MX53 FlexCAN2 03.00.00.00 yes no no no no no 64 |
29 | * MX6s FlexCAN3 10.00.12.00 yes yes no no yes no 64 |
30 | * MX8QM FlexCAN3 03.00.23.00 yes yes no no yes yes 64 |
31 | * MX8MP FlexCAN3 03.00.17.01 yes yes no yes yes yes 64 |
32 | * VF610 FlexCAN3 ? no yes no yes yes? no 64 |
33 | * LS1021A FlexCAN2 03.00.04.00 no yes no no yes no 64 |
34 | * LX2160A FlexCAN3 03.00.23.00 no yes no yes yes yes 64 |
35 | * |
36 | * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. |
37 | */ |
38 | |
39 | /* [TR]WRN_INT not connected */ |
40 | #define FLEXCAN_QUIRK_BROKEN_WERR_STATE BIT(1) |
41 | /* Disable RX FIFO Global mask */ |
42 | #define FLEXCAN_QUIRK_DISABLE_RXFG BIT(2) |
43 | /* Enable EACEN and RRS bit in ctrl2 */ |
44 | #define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) |
45 | /* Disable non-correctable errors interrupt and freeze mode */ |
46 | #define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) |
47 | /* Use mailboxes (not FIFO) for RX path */ |
48 | #define FLEXCAN_QUIRK_USE_RX_MAILBOX BIT(5) |
49 | /* No interrupt for error passive */ |
50 | #define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) |
51 | /* default to BE register access */ |
52 | #define FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN BIT(7) |
53 | /* Setup stop mode with GPR to support wakeup */ |
54 | #define FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR BIT(8) |
55 | /* Support CAN-FD mode */ |
56 | #define FLEXCAN_QUIRK_SUPPORT_FD BIT(9) |
57 | /* support memory detection and correction */ |
58 | #define FLEXCAN_QUIRK_SUPPORT_ECC BIT(10) |
59 | /* Setup stop mode with SCU firmware to support wakeup */ |
60 | #define FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW BIT(11) |
61 | /* Setup 3 separate interrupts, main, boff and err */ |
62 | #define FLEXCAN_QUIRK_NR_IRQ_3 BIT(12) |
63 | /* Setup 16 mailboxes */ |
64 | #define FLEXCAN_QUIRK_NR_MB_16 BIT(13) |
65 | /* Device supports RX via mailboxes */ |
66 | #define FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX BIT(14) |
67 | /* Device supports RTR reception via mailboxes */ |
68 | #define FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR BIT(15) |
69 | /* Device supports RX via FIFO */ |
70 | #define FLEXCAN_QUIRK_SUPPORT_RX_FIFO BIT(16) |
71 | |
72 | struct flexcan_devtype_data { |
73 | u32 quirks; /* quirks needed for different IP cores */ |
74 | }; |
75 | |
76 | struct flexcan_stop_mode { |
77 | struct regmap *gpr; |
78 | u8 req_gpr; |
79 | u8 req_bit; |
80 | }; |
81 | |
82 | struct flexcan_priv { |
83 | struct can_priv can; |
84 | struct can_rx_offload offload; |
85 | struct device *dev; |
86 | |
87 | struct flexcan_regs __iomem *regs; |
88 | struct flexcan_mb __iomem *tx_mb; |
89 | struct flexcan_mb __iomem *tx_mb_reserved; |
90 | u8 tx_mb_idx; |
91 | u8 mb_count; |
92 | u8 mb_size; |
93 | u8 clk_src; /* clock source of CAN Protocol Engine */ |
94 | u8 scu_idx; |
95 | |
96 | u64 rx_mask; |
97 | u64 tx_mask; |
98 | u32 reg_ctrl_default; |
99 | |
100 | struct clk *clk_ipg; |
101 | struct clk *clk_per; |
102 | struct flexcan_devtype_data devtype_data; |
103 | struct regulator *reg_xceiver; |
104 | struct flexcan_stop_mode stm; |
105 | |
106 | int irq_boff; |
107 | int irq_err; |
108 | |
109 | /* IPC handle when setup stop mode by System Controller firmware(scfw) */ |
110 | struct imx_sc_ipc *sc_ipc_handle; |
111 | |
112 | /* Read and Write APIs */ |
113 | u32 (*read)(void __iomem *addr); |
114 | void (*write)(u32 val, void __iomem *addr); |
115 | }; |
116 | |
117 | extern const struct ethtool_ops flexcan_ethtool_ops; |
118 | |
119 | static inline bool |
120 | flexcan_supports_rx_mailbox(const struct flexcan_priv *priv) |
121 | { |
122 | const u32 quirks = priv->devtype_data.quirks; |
123 | |
124 | return quirks & FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX; |
125 | } |
126 | |
127 | static inline bool |
128 | flexcan_supports_rx_mailbox_rtr(const struct flexcan_priv *priv) |
129 | { |
130 | const u32 quirks = priv->devtype_data.quirks; |
131 | |
132 | return (quirks & (FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX | |
133 | FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR)) == |
134 | (FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX | |
135 | FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR); |
136 | } |
137 | |
138 | static inline bool |
139 | flexcan_supports_rx_fifo(const struct flexcan_priv *priv) |
140 | { |
141 | const u32 quirks = priv->devtype_data.quirks; |
142 | |
143 | return quirks & FLEXCAN_QUIRK_SUPPORT_RX_FIFO; |
144 | } |
145 | |
146 | static inline bool |
147 | flexcan_active_rx_rtr(const struct flexcan_priv *priv) |
148 | { |
149 | const u32 quirks = priv->devtype_data.quirks; |
150 | |
151 | if (quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) { |
152 | if (quirks & FLEXCAN_QUIRK_SUPPORT_RX_MAILBOX_RTR) |
153 | return true; |
154 | } else { |
155 | /* RX-FIFO is always RTR capable */ |
156 | return true; |
157 | } |
158 | |
159 | return false; |
160 | } |
161 | |
162 | |
163 | #endif /* _FLEXCAN_H */ |
164 | |