.. | .. |
---|
9 | 9 | // |
---|
10 | 10 | // Based on code originally by Andrey Volkov <avolkov@varma-el.com> |
---|
11 | 11 | |
---|
12 | | -#include <linux/netdevice.h> |
---|
| 12 | +#include <linux/bitfield.h> |
---|
13 | 13 | #include <linux/can.h> |
---|
14 | 14 | #include <linux/can/dev.h> |
---|
15 | 15 | #include <linux/can/error.h> |
---|
.. | .. |
---|
19 | 19 | #include <linux/delay.h> |
---|
20 | 20 | #include <linux/interrupt.h> |
---|
21 | 21 | #include <linux/io.h> |
---|
| 22 | +#include <linux/mfd/syscon.h> |
---|
22 | 23 | #include <linux/module.h> |
---|
| 24 | +#include <linux/netdevice.h> |
---|
23 | 25 | #include <linux/of.h> |
---|
24 | 26 | #include <linux/of_device.h> |
---|
| 27 | +#include <linux/pinctrl/consumer.h> |
---|
25 | 28 | #include <linux/platform_device.h> |
---|
| 29 | +#include <linux/pm_runtime.h> |
---|
| 30 | +#include <linux/regmap.h> |
---|
26 | 31 | #include <linux/regulator/consumer.h> |
---|
27 | 32 | |
---|
28 | 33 | #define DRV_NAME "flexcan" |
---|
.. | .. |
---|
49 | 54 | #define FLEXCAN_MCR_IRMQ BIT(16) |
---|
50 | 55 | #define FLEXCAN_MCR_LPRIO_EN BIT(13) |
---|
51 | 56 | #define FLEXCAN_MCR_AEN BIT(12) |
---|
| 57 | +#define FLEXCAN_MCR_FDEN BIT(11) |
---|
52 | 58 | /* MCR_MAXMB: maximum used MBs is MAXMB + 1 */ |
---|
53 | 59 | #define FLEXCAN_MCR_MAXMB(x) ((x) & 0x7f) |
---|
54 | 60 | #define FLEXCAN_MCR_IDAM_A (0x0 << 8) |
---|
.. | .. |
---|
88 | 94 | #define FLEXCAN_CTRL2_MRP BIT(18) |
---|
89 | 95 | #define FLEXCAN_CTRL2_RRS BIT(17) |
---|
90 | 96 | #define FLEXCAN_CTRL2_EACEN BIT(16) |
---|
| 97 | +#define FLEXCAN_CTRL2_ISOCANFDEN BIT(12) |
---|
91 | 98 | |
---|
92 | 99 | /* FLEXCAN memory error control register (MECR) bits */ |
---|
93 | 100 | #define FLEXCAN_MECR_ECRWRDIS BIT(31) |
---|
.. | .. |
---|
133 | 140 | (FLEXCAN_ESR_TWRN_INT | FLEXCAN_ESR_RWRN_INT | \ |
---|
134 | 141 | FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT) |
---|
135 | 142 | |
---|
| 143 | +/* FLEXCAN Bit Timing register (CBT) bits */ |
---|
| 144 | +#define FLEXCAN_CBT_BTF BIT(31) |
---|
| 145 | +#define FLEXCAN_CBT_EPRESDIV_MASK GENMASK(30, 21) |
---|
| 146 | +#define FLEXCAN_CBT_ERJW_MASK GENMASK(20, 16) |
---|
| 147 | +#define FLEXCAN_CBT_EPROPSEG_MASK GENMASK(15, 10) |
---|
| 148 | +#define FLEXCAN_CBT_EPSEG1_MASK GENMASK(9, 5) |
---|
| 149 | +#define FLEXCAN_CBT_EPSEG2_MASK GENMASK(4, 0) |
---|
| 150 | + |
---|
| 151 | +/* FLEXCAN FD control register (FDCTRL) bits */ |
---|
| 152 | +#define FLEXCAN_FDCTRL_FDRATE BIT(31) |
---|
| 153 | +#define FLEXCAN_FDCTRL_MBDSR1 GENMASK(20, 19) |
---|
| 154 | +#define FLEXCAN_FDCTRL_MBDSR0 GENMASK(17, 16) |
---|
| 155 | +#define FLEXCAN_FDCTRL_MBDSR_8 0x0 |
---|
| 156 | +#define FLEXCAN_FDCTRL_MBDSR_12 0x1 |
---|
| 157 | +#define FLEXCAN_FDCTRL_MBDSR_32 0x2 |
---|
| 158 | +#define FLEXCAN_FDCTRL_MBDSR_64 0x3 |
---|
| 159 | +#define FLEXCAN_FDCTRL_TDCEN BIT(15) |
---|
| 160 | +#define FLEXCAN_FDCTRL_TDCFAIL BIT(14) |
---|
| 161 | +#define FLEXCAN_FDCTRL_TDCOFF GENMASK(12, 8) |
---|
| 162 | +#define FLEXCAN_FDCTRL_TDCVAL GENMASK(5, 0) |
---|
| 163 | + |
---|
| 164 | +/* FLEXCAN FD Bit Timing register (FDCBT) bits */ |
---|
| 165 | +#define FLEXCAN_FDCBT_FPRESDIV_MASK GENMASK(29, 20) |
---|
| 166 | +#define FLEXCAN_FDCBT_FRJW_MASK GENMASK(18, 16) |
---|
| 167 | +#define FLEXCAN_FDCBT_FPROPSEG_MASK GENMASK(14, 10) |
---|
| 168 | +#define FLEXCAN_FDCBT_FPSEG1_MASK GENMASK(7, 5) |
---|
| 169 | +#define FLEXCAN_FDCBT_FPSEG2_MASK GENMASK(2, 0) |
---|
| 170 | + |
---|
136 | 171 | /* FLEXCAN interrupt flag register (IFLAG) bits */ |
---|
137 | 172 | /* Errata ERR005829 step7: Reserve first valid MB */ |
---|
138 | 173 | #define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8 |
---|
139 | 174 | #define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0 |
---|
140 | | -#define FLEXCAN_TX_MB 63 |
---|
141 | 175 | #define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1) |
---|
142 | | -#define FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST (FLEXCAN_TX_MB - 1) |
---|
143 | | -#define FLEXCAN_IFLAG_MB(x) BIT((x) & 0x1f) |
---|
| 176 | +#define FLEXCAN_IFLAG_MB(x) BIT_ULL(x) |
---|
144 | 177 | #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) |
---|
145 | 178 | #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) |
---|
146 | 179 | #define FLEXCAN_IFLAG_RX_FIFO_AVAILABLE BIT(5) |
---|
.. | .. |
---|
159 | 192 | #define FLEXCAN_MB_CODE_TX_DATA (0xc << 24) |
---|
160 | 193 | #define FLEXCAN_MB_CODE_TX_TANSWER (0xe << 24) |
---|
161 | 194 | |
---|
| 195 | +#define FLEXCAN_MB_CNT_EDL BIT(31) |
---|
| 196 | +#define FLEXCAN_MB_CNT_BRS BIT(30) |
---|
| 197 | +#define FLEXCAN_MB_CNT_ESI BIT(29) |
---|
162 | 198 | #define FLEXCAN_MB_CNT_SRR BIT(22) |
---|
163 | 199 | #define FLEXCAN_MB_CNT_IDE BIT(21) |
---|
164 | 200 | #define FLEXCAN_MB_CNT_RTR BIT(20) |
---|
.. | .. |
---|
170 | 206 | /* FLEXCAN hardware feature flags |
---|
171 | 207 | * |
---|
172 | 208 | * Below is some version info we got: |
---|
173 | | - * SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR re- |
---|
174 | | - * Filter? connected? Passive detection ception in MB |
---|
175 | | - * MX25 FlexCAN2 03.00.00.00 no no no no no |
---|
176 | | - * MX28 FlexCAN2 03.00.04.00 yes yes no no no |
---|
177 | | - * MX35 FlexCAN2 03.00.00.00 no no no no no |
---|
178 | | - * MX53 FlexCAN2 03.00.00.00 yes no no no no |
---|
179 | | - * MX6s FlexCAN3 10.00.12.00 yes yes no no yes |
---|
180 | | - * VF610 FlexCAN3 ? no yes no yes yes? |
---|
181 | | - * LS1021A FlexCAN2 03.00.04.00 no yes no no yes |
---|
| 209 | + * SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR rece- FD Mode |
---|
| 210 | + * Filter? connected? Passive detection ption in MB Supported? |
---|
| 211 | + * MX25 FlexCAN2 03.00.00.00 no no no no no no |
---|
| 212 | + * MX28 FlexCAN2 03.00.04.00 yes yes no no no no |
---|
| 213 | + * MX35 FlexCAN2 03.00.00.00 no no no no no no |
---|
| 214 | + * MX53 FlexCAN2 03.00.00.00 yes no no no no no |
---|
| 215 | + * MX6s FlexCAN3 10.00.12.00 yes yes no no yes no |
---|
| 216 | + * MX8QM FlexCAN3 03.00.23.00 yes yes no no yes yes |
---|
| 217 | + * MX8MP FlexCAN3 03.00.17.01 yes yes no yes yes yes |
---|
| 218 | + * VF610 FlexCAN3 ? no yes no yes yes? no |
---|
| 219 | + * LS1021A FlexCAN2 03.00.04.00 no yes no no yes no |
---|
| 220 | + * LX2160A FlexCAN3 03.00.23.00 no yes no yes yes yes |
---|
182 | 221 | * |
---|
183 | 222 | * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. |
---|
184 | 223 | */ |
---|
185 | | -#define FLEXCAN_QUIRK_BROKEN_WERR_STATE BIT(1) /* [TR]WRN_INT not connected */ |
---|
186 | | -#define FLEXCAN_QUIRK_DISABLE_RXFG BIT(2) /* Disable RX FIFO Global mask */ |
---|
187 | | -#define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) /* Enable EACEN and RRS bit in ctrl2 */ |
---|
188 | | -#define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) /* Disable Memory error detection */ |
---|
189 | | -#define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) /* Use timestamp based offloading */ |
---|
190 | | -#define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) /* No interrupt for error passive */ |
---|
191 | | -#define FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN BIT(7) /* default to BE register access */ |
---|
| 224 | + |
---|
| 225 | +/* [TR]WRN_INT not connected */ |
---|
| 226 | +#define FLEXCAN_QUIRK_BROKEN_WERR_STATE BIT(1) |
---|
| 227 | + /* Disable RX FIFO Global mask */ |
---|
| 228 | +#define FLEXCAN_QUIRK_DISABLE_RXFG BIT(2) |
---|
| 229 | +/* Enable EACEN and RRS bit in ctrl2 */ |
---|
| 230 | +#define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) |
---|
| 231 | +/* Disable non-correctable errors interrupt and freeze mode */ |
---|
| 232 | +#define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) |
---|
| 233 | +/* Use timestamp based offloading */ |
---|
| 234 | +#define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) |
---|
| 235 | +/* No interrupt for error passive */ |
---|
| 236 | +#define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) |
---|
| 237 | +/* default to BE register access */ |
---|
| 238 | +#define FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN BIT(7) |
---|
| 239 | +/* Setup stop mode to support wakeup */ |
---|
| 240 | +#define FLEXCAN_QUIRK_SETUP_STOP_MODE BIT(8) |
---|
| 241 | +/* Support CAN-FD mode */ |
---|
| 242 | +#define FLEXCAN_QUIRK_SUPPORT_FD BIT(9) |
---|
| 243 | +/* support memory detection and correction */ |
---|
| 244 | +#define FLEXCAN_QUIRK_SUPPORT_ECC BIT(10) |
---|
192 | 245 | |
---|
193 | 246 | /* Structure of the message buffer */ |
---|
194 | 247 | struct flexcan_mb { |
---|
195 | 248 | u32 can_ctrl; |
---|
196 | 249 | u32 can_id; |
---|
197 | | - u32 data[2]; |
---|
| 250 | + u32 data[]; |
---|
198 | 251 | }; |
---|
199 | 252 | |
---|
200 | 253 | /* Structure of the hardware registers */ |
---|
201 | 254 | struct flexcan_regs { |
---|
202 | 255 | u32 mcr; /* 0x00 */ |
---|
203 | | - u32 ctrl; /* 0x04 */ |
---|
| 256 | + u32 ctrl; /* 0x04 - Not affected by Soft Reset */ |
---|
204 | 257 | u32 timer; /* 0x08 */ |
---|
205 | | - u32 _reserved1; /* 0x0c */ |
---|
206 | | - u32 rxgmask; /* 0x10 */ |
---|
207 | | - u32 rx14mask; /* 0x14 */ |
---|
208 | | - u32 rx15mask; /* 0x18 */ |
---|
| 258 | + u32 tcr; /* 0x0c */ |
---|
| 259 | + u32 rxgmask; /* 0x10 - Not affected by Soft Reset */ |
---|
| 260 | + u32 rx14mask; /* 0x14 - Not affected by Soft Reset */ |
---|
| 261 | + u32 rx15mask; /* 0x18 - Not affected by Soft Reset */ |
---|
209 | 262 | u32 ecr; /* 0x1c */ |
---|
210 | 263 | u32 esr; /* 0x20 */ |
---|
211 | 264 | u32 imask2; /* 0x24 */ |
---|
.. | .. |
---|
214 | 267 | u32 iflag1; /* 0x30 */ |
---|
215 | 268 | union { /* 0x34 */ |
---|
216 | 269 | u32 gfwr_mx28; /* MX28, MX53 */ |
---|
217 | | - u32 ctrl2; /* MX6, VF610 */ |
---|
| 270 | + u32 ctrl2; /* MX6, VF610 - Not affected by Soft Reset */ |
---|
218 | 271 | }; |
---|
219 | 272 | u32 esr2; /* 0x38 */ |
---|
220 | 273 | u32 imeur; /* 0x3c */ |
---|
221 | 274 | u32 lrfr; /* 0x40 */ |
---|
222 | 275 | u32 crcr; /* 0x44 */ |
---|
223 | 276 | u32 rxfgmask; /* 0x48 */ |
---|
224 | | - u32 rxfir; /* 0x4c */ |
---|
225 | | - u32 _reserved3[12]; /* 0x50 */ |
---|
226 | | - struct flexcan_mb mb[64]; /* 0x80 */ |
---|
| 277 | + u32 rxfir; /* 0x4c - Not affected by Soft Reset */ |
---|
| 278 | + u32 cbt; /* 0x50 - Not affected by Soft Reset */ |
---|
| 279 | + u32 _reserved2; /* 0x54 */ |
---|
| 280 | + u32 dbg1; /* 0x58 */ |
---|
| 281 | + u32 dbg2; /* 0x5c */ |
---|
| 282 | + u32 _reserved3[8]; /* 0x60 */ |
---|
| 283 | + u8 mb[2][512]; /* 0x80 - Not affected by Soft Reset */ |
---|
227 | 284 | /* FIFO-mode: |
---|
228 | 285 | * MB |
---|
229 | 286 | * 0x080...0x08f 0 RX message buffer |
---|
230 | | - * 0x090...0x0df 1-5 reserverd |
---|
| 287 | + * 0x090...0x0df 1-5 reserved |
---|
231 | 288 | * 0x0e0...0x0ff 6-7 8 entry ID table |
---|
232 | 289 | * (mx25, mx28, mx35, mx53) |
---|
233 | 290 | * 0x0e0...0x2df 6-7..37 8..128 entry ID table |
---|
.. | .. |
---|
235 | 292 | * (mx6, vf610) |
---|
236 | 293 | */ |
---|
237 | 294 | u32 _reserved4[256]; /* 0x480 */ |
---|
238 | | - u32 rximr[64]; /* 0x880 */ |
---|
| 295 | + u32 rximr[64]; /* 0x880 - Not affected by Soft Reset */ |
---|
239 | 296 | u32 _reserved5[24]; /* 0x980 */ |
---|
240 | 297 | u32 gfwr_mx6; /* 0x9e0 - MX6 */ |
---|
241 | | - u32 _reserved6[63]; /* 0x9e4 */ |
---|
| 298 | + u32 _reserved6[39]; /* 0x9e4 */ |
---|
| 299 | + u32 _rxfir[6]; /* 0xa80 */ |
---|
| 300 | + u32 _reserved8[2]; /* 0xa98 */ |
---|
| 301 | + u32 _rxmgmask; /* 0xaa0 */ |
---|
| 302 | + u32 _rxfgmask; /* 0xaa4 */ |
---|
| 303 | + u32 _rx14mask; /* 0xaa8 */ |
---|
| 304 | + u32 _rx15mask; /* 0xaac */ |
---|
| 305 | + u32 tx_smb[4]; /* 0xab0 */ |
---|
| 306 | + u32 rx_smb0[4]; /* 0xac0 */ |
---|
| 307 | + u32 rx_smb1[4]; /* 0xad0 */ |
---|
242 | 308 | u32 mecr; /* 0xae0 */ |
---|
243 | 309 | u32 erriar; /* 0xae4 */ |
---|
244 | 310 | u32 erridpr; /* 0xae8 */ |
---|
.. | .. |
---|
247 | 313 | u32 rerrdr; /* 0xaf4 */ |
---|
248 | 314 | u32 rerrsynr; /* 0xaf8 */ |
---|
249 | 315 | u32 errsr; /* 0xafc */ |
---|
| 316 | + u32 _reserved7[64]; /* 0xb00 */ |
---|
| 317 | + u32 fdctrl; /* 0xc00 - Not affected by Soft Reset */ |
---|
| 318 | + u32 fdcbt; /* 0xc04 - Not affected by Soft Reset */ |
---|
| 319 | + u32 fdcrc; /* 0xc08 */ |
---|
| 320 | + u32 _reserved9[199]; /* 0xc0c */ |
---|
| 321 | + u32 tx_smb_fd[18]; /* 0xf28 */ |
---|
| 322 | + u32 rx_smb0_fd[18]; /* 0xf70 */ |
---|
| 323 | + u32 rx_smb1_fd[18]; /* 0xfb8 */ |
---|
250 | 324 | }; |
---|
| 325 | + |
---|
| 326 | +static_assert(sizeof(struct flexcan_regs) == 0x4 * 18 + 0xfb8); |
---|
251 | 327 | |
---|
252 | 328 | struct flexcan_devtype_data { |
---|
253 | 329 | u32 quirks; /* quirks needed for different IP cores */ |
---|
254 | 330 | }; |
---|
255 | 331 | |
---|
| 332 | +struct flexcan_stop_mode { |
---|
| 333 | + struct regmap *gpr; |
---|
| 334 | + u8 req_gpr; |
---|
| 335 | + u8 req_bit; |
---|
| 336 | +}; |
---|
| 337 | + |
---|
256 | 338 | struct flexcan_priv { |
---|
257 | 339 | struct can_priv can; |
---|
258 | 340 | struct can_rx_offload offload; |
---|
| 341 | + struct device *dev; |
---|
259 | 342 | |
---|
260 | 343 | struct flexcan_regs __iomem *regs; |
---|
| 344 | + struct flexcan_mb __iomem *tx_mb; |
---|
261 | 345 | struct flexcan_mb __iomem *tx_mb_reserved; |
---|
| 346 | + u8 tx_mb_idx; |
---|
| 347 | + u8 mb_count; |
---|
| 348 | + u8 mb_size; |
---|
| 349 | + u8 clk_src; /* clock source of CAN Protocol Engine */ |
---|
| 350 | + |
---|
| 351 | + u64 rx_mask; |
---|
| 352 | + u64 tx_mask; |
---|
262 | 353 | u32 reg_ctrl_default; |
---|
263 | | - u32 reg_imask1_default; |
---|
264 | | - u32 reg_imask2_default; |
---|
265 | 354 | |
---|
266 | 355 | struct clk *clk_ipg; |
---|
267 | 356 | struct clk *clk_per; |
---|
268 | 357 | const struct flexcan_devtype_data *devtype_data; |
---|
269 | 358 | struct regulator *reg_xceiver; |
---|
| 359 | + struct flexcan_stop_mode stm; |
---|
270 | 360 | |
---|
271 | 361 | /* Read and Write APIs */ |
---|
272 | 362 | u32 (*read)(void __iomem *addr); |
---|
.. | .. |
---|
290 | 380 | |
---|
291 | 381 | static const struct flexcan_devtype_data fsl_imx6q_devtype_data = { |
---|
292 | 382 | .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
---|
293 | | - FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE, |
---|
| 383 | + FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE | |
---|
| 384 | + FLEXCAN_QUIRK_SETUP_STOP_MODE, |
---|
| 385 | +}; |
---|
| 386 | + |
---|
| 387 | +static const struct flexcan_devtype_data fsl_imx8qm_devtype_data = { |
---|
| 388 | + .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
---|
| 389 | + FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE | |
---|
| 390 | + FLEXCAN_QUIRK_SUPPORT_FD, |
---|
| 391 | +}; |
---|
| 392 | + |
---|
| 393 | +static struct flexcan_devtype_data fsl_imx8mp_devtype_data = { |
---|
| 394 | + .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
---|
| 395 | + FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | |
---|
| 396 | + FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SETUP_STOP_MODE | |
---|
| 397 | + FLEXCAN_QUIRK_SUPPORT_FD | FLEXCAN_QUIRK_SUPPORT_ECC, |
---|
294 | 398 | }; |
---|
295 | 399 | |
---|
296 | 400 | static const struct flexcan_devtype_data fsl_vf610_devtype_data = { |
---|
297 | 401 | .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
---|
298 | 402 | FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | |
---|
299 | | - FLEXCAN_QUIRK_BROKEN_PERR_STATE, |
---|
| 403 | + FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SUPPORT_ECC, |
---|
300 | 404 | }; |
---|
301 | 405 | |
---|
302 | 406 | static const struct flexcan_devtype_data fsl_ls1021a_r2_devtype_data = { |
---|
303 | 407 | .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
---|
304 | 408 | FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP, |
---|
| 409 | +}; |
---|
| 410 | + |
---|
| 411 | +static const struct flexcan_devtype_data fsl_lx2160a_r1_devtype_data = { |
---|
| 412 | + .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
---|
| 413 | + FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_BROKEN_PERR_STATE | |
---|
| 414 | + FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_SUPPORT_FD | |
---|
| 415 | + FLEXCAN_QUIRK_SUPPORT_ECC, |
---|
305 | 416 | }; |
---|
306 | 417 | |
---|
307 | 418 | static const struct can_bittiming_const flexcan_bittiming_const = { |
---|
.. | .. |
---|
313 | 424 | .sjw_max = 4, |
---|
314 | 425 | .brp_min = 1, |
---|
315 | 426 | .brp_max = 256, |
---|
| 427 | + .brp_inc = 1, |
---|
| 428 | +}; |
---|
| 429 | + |
---|
| 430 | +static const struct can_bittiming_const flexcan_fd_bittiming_const = { |
---|
| 431 | + .name = DRV_NAME, |
---|
| 432 | + .tseg1_min = 2, |
---|
| 433 | + .tseg1_max = 96, |
---|
| 434 | + .tseg2_min = 2, |
---|
| 435 | + .tseg2_max = 32, |
---|
| 436 | + .sjw_max = 16, |
---|
| 437 | + .brp_min = 1, |
---|
| 438 | + .brp_max = 1024, |
---|
| 439 | + .brp_inc = 1, |
---|
| 440 | +}; |
---|
| 441 | + |
---|
| 442 | +static const struct can_bittiming_const flexcan_fd_data_bittiming_const = { |
---|
| 443 | + .name = DRV_NAME, |
---|
| 444 | + .tseg1_min = 2, |
---|
| 445 | + .tseg1_max = 39, |
---|
| 446 | + .tseg2_min = 2, |
---|
| 447 | + .tseg2_max = 8, |
---|
| 448 | + .sjw_max = 4, |
---|
| 449 | + .brp_min = 1, |
---|
| 450 | + .brp_max = 1024, |
---|
316 | 451 | .brp_inc = 1, |
---|
317 | 452 | }; |
---|
318 | 453 | |
---|
.. | .. |
---|
349 | 484 | iowrite32(val, addr); |
---|
350 | 485 | } |
---|
351 | 486 | |
---|
| 487 | +static struct flexcan_mb __iomem *flexcan_get_mb(const struct flexcan_priv *priv, |
---|
| 488 | + u8 mb_index) |
---|
| 489 | +{ |
---|
| 490 | + u8 bank_size; |
---|
| 491 | + bool bank; |
---|
| 492 | + |
---|
| 493 | + if (WARN_ON(mb_index >= priv->mb_count)) |
---|
| 494 | + return NULL; |
---|
| 495 | + |
---|
| 496 | + bank_size = sizeof(priv->regs->mb[0]) / priv->mb_size; |
---|
| 497 | + |
---|
| 498 | + bank = mb_index >= bank_size; |
---|
| 499 | + if (bank) |
---|
| 500 | + mb_index -= bank_size; |
---|
| 501 | + |
---|
| 502 | + return (struct flexcan_mb __iomem *) |
---|
| 503 | + (&priv->regs->mb[bank][priv->mb_size * mb_index]); |
---|
| 504 | +} |
---|
| 505 | + |
---|
| 506 | +static int flexcan_low_power_enter_ack(struct flexcan_priv *priv) |
---|
| 507 | +{ |
---|
| 508 | + struct flexcan_regs __iomem *regs = priv->regs; |
---|
| 509 | + unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; |
---|
| 510 | + |
---|
| 511 | + while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
---|
| 512 | + udelay(10); |
---|
| 513 | + |
---|
| 514 | + if (!(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
---|
| 515 | + return -ETIMEDOUT; |
---|
| 516 | + |
---|
| 517 | + return 0; |
---|
| 518 | +} |
---|
| 519 | + |
---|
| 520 | +static int flexcan_low_power_exit_ack(struct flexcan_priv *priv) |
---|
| 521 | +{ |
---|
| 522 | + struct flexcan_regs __iomem *regs = priv->regs; |
---|
| 523 | + unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; |
---|
| 524 | + |
---|
| 525 | + while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
---|
| 526 | + udelay(10); |
---|
| 527 | + |
---|
| 528 | + if (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK) |
---|
| 529 | + return -ETIMEDOUT; |
---|
| 530 | + |
---|
| 531 | + return 0; |
---|
| 532 | +} |
---|
| 533 | + |
---|
| 534 | +static void flexcan_enable_wakeup_irq(struct flexcan_priv *priv, bool enable) |
---|
| 535 | +{ |
---|
| 536 | + struct flexcan_regs __iomem *regs = priv->regs; |
---|
| 537 | + u32 reg_mcr; |
---|
| 538 | + |
---|
| 539 | + reg_mcr = priv->read(®s->mcr); |
---|
| 540 | + |
---|
| 541 | + if (enable) |
---|
| 542 | + reg_mcr |= FLEXCAN_MCR_WAK_MSK; |
---|
| 543 | + else |
---|
| 544 | + reg_mcr &= ~FLEXCAN_MCR_WAK_MSK; |
---|
| 545 | + |
---|
| 546 | + priv->write(reg_mcr, ®s->mcr); |
---|
| 547 | +} |
---|
| 548 | + |
---|
| 549 | +static inline int flexcan_enter_stop_mode(struct flexcan_priv *priv) |
---|
| 550 | +{ |
---|
| 551 | + struct flexcan_regs __iomem *regs = priv->regs; |
---|
| 552 | + u32 reg_mcr; |
---|
| 553 | + |
---|
| 554 | + reg_mcr = priv->read(®s->mcr); |
---|
| 555 | + reg_mcr |= FLEXCAN_MCR_SLF_WAK; |
---|
| 556 | + priv->write(reg_mcr, ®s->mcr); |
---|
| 557 | + |
---|
| 558 | + /* enable stop request */ |
---|
| 559 | + regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, |
---|
| 560 | + 1 << priv->stm.req_bit, 1 << priv->stm.req_bit); |
---|
| 561 | + |
---|
| 562 | + return flexcan_low_power_enter_ack(priv); |
---|
| 563 | +} |
---|
| 564 | + |
---|
| 565 | +static inline int flexcan_exit_stop_mode(struct flexcan_priv *priv) |
---|
| 566 | +{ |
---|
| 567 | + struct flexcan_regs __iomem *regs = priv->regs; |
---|
| 568 | + u32 reg_mcr; |
---|
| 569 | + |
---|
| 570 | + /* remove stop request */ |
---|
| 571 | + regmap_update_bits(priv->stm.gpr, priv->stm.req_gpr, |
---|
| 572 | + 1 << priv->stm.req_bit, 0); |
---|
| 573 | + |
---|
| 574 | + reg_mcr = priv->read(®s->mcr); |
---|
| 575 | + reg_mcr &= ~FLEXCAN_MCR_SLF_WAK; |
---|
| 576 | + priv->write(reg_mcr, ®s->mcr); |
---|
| 577 | + |
---|
| 578 | + return flexcan_low_power_exit_ack(priv); |
---|
| 579 | +} |
---|
| 580 | + |
---|
352 | 581 | static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv) |
---|
353 | 582 | { |
---|
354 | 583 | struct flexcan_regs __iomem *regs = priv->regs; |
---|
.. | .. |
---|
363 | 592 | u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK); |
---|
364 | 593 | |
---|
365 | 594 | priv->write(reg_ctrl, ®s->ctrl); |
---|
| 595 | +} |
---|
| 596 | + |
---|
| 597 | +static int flexcan_clks_enable(const struct flexcan_priv *priv) |
---|
| 598 | +{ |
---|
| 599 | + int err; |
---|
| 600 | + |
---|
| 601 | + err = clk_prepare_enable(priv->clk_ipg); |
---|
| 602 | + if (err) |
---|
| 603 | + return err; |
---|
| 604 | + |
---|
| 605 | + err = clk_prepare_enable(priv->clk_per); |
---|
| 606 | + if (err) |
---|
| 607 | + clk_disable_unprepare(priv->clk_ipg); |
---|
| 608 | + |
---|
| 609 | + return err; |
---|
| 610 | +} |
---|
| 611 | + |
---|
| 612 | +static void flexcan_clks_disable(const struct flexcan_priv *priv) |
---|
| 613 | +{ |
---|
| 614 | + clk_disable_unprepare(priv->clk_per); |
---|
| 615 | + clk_disable_unprepare(priv->clk_ipg); |
---|
366 | 616 | } |
---|
367 | 617 | |
---|
368 | 618 | static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv) |
---|
.. | .. |
---|
384 | 634 | static int flexcan_chip_enable(struct flexcan_priv *priv) |
---|
385 | 635 | { |
---|
386 | 636 | struct flexcan_regs __iomem *regs = priv->regs; |
---|
387 | | - unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; |
---|
388 | 637 | u32 reg; |
---|
389 | 638 | |
---|
390 | 639 | reg = priv->read(®s->mcr); |
---|
391 | 640 | reg &= ~FLEXCAN_MCR_MDIS; |
---|
392 | 641 | priv->write(reg, ®s->mcr); |
---|
393 | 642 | |
---|
394 | | - while (timeout-- && (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
---|
395 | | - udelay(10); |
---|
396 | | - |
---|
397 | | - if (priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK) |
---|
398 | | - return -ETIMEDOUT; |
---|
399 | | - |
---|
400 | | - return 0; |
---|
| 643 | + return flexcan_low_power_exit_ack(priv); |
---|
401 | 644 | } |
---|
402 | 645 | |
---|
403 | 646 | static int flexcan_chip_disable(struct flexcan_priv *priv) |
---|
404 | 647 | { |
---|
405 | 648 | struct flexcan_regs __iomem *regs = priv->regs; |
---|
406 | | - unsigned int timeout = FLEXCAN_TIMEOUT_US / 10; |
---|
407 | 649 | u32 reg; |
---|
408 | 650 | |
---|
409 | 651 | reg = priv->read(®s->mcr); |
---|
410 | 652 | reg |= FLEXCAN_MCR_MDIS; |
---|
411 | 653 | priv->write(reg, ®s->mcr); |
---|
412 | 654 | |
---|
413 | | - while (timeout-- && !(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
---|
414 | | - udelay(10); |
---|
415 | | - |
---|
416 | | - if (!(priv->read(®s->mcr) & FLEXCAN_MCR_LPM_ACK)) |
---|
417 | | - return -ETIMEDOUT; |
---|
418 | | - |
---|
419 | | - return 0; |
---|
| 655 | + return flexcan_low_power_enter_ack(priv); |
---|
420 | 656 | } |
---|
421 | 657 | |
---|
422 | 658 | static int flexcan_chip_freeze(struct flexcan_priv *priv) |
---|
.. | .. |
---|
497 | 733 | const struct flexcan_priv *priv = netdev_priv(dev); |
---|
498 | 734 | int err; |
---|
499 | 735 | |
---|
500 | | - err = clk_prepare_enable(priv->clk_ipg); |
---|
501 | | - if (err) |
---|
| 736 | + err = pm_runtime_get_sync(priv->dev); |
---|
| 737 | + if (err < 0) { |
---|
| 738 | + pm_runtime_put_noidle(priv->dev); |
---|
502 | 739 | return err; |
---|
503 | | - |
---|
504 | | - err = clk_prepare_enable(priv->clk_per); |
---|
505 | | - if (err) |
---|
506 | | - goto out_disable_ipg; |
---|
| 740 | + } |
---|
507 | 741 | |
---|
508 | 742 | err = __flexcan_get_berr_counter(dev, bec); |
---|
509 | 743 | |
---|
510 | | - clk_disable_unprepare(priv->clk_per); |
---|
511 | | - out_disable_ipg: |
---|
512 | | - clk_disable_unprepare(priv->clk_ipg); |
---|
| 744 | + pm_runtime_put(priv->dev); |
---|
513 | 745 | |
---|
514 | 746 | return err; |
---|
515 | 747 | } |
---|
.. | .. |
---|
517 | 749 | static netdev_tx_t flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev) |
---|
518 | 750 | { |
---|
519 | 751 | const struct flexcan_priv *priv = netdev_priv(dev); |
---|
520 | | - struct flexcan_regs __iomem *regs = priv->regs; |
---|
521 | | - struct can_frame *cf = (struct can_frame *)skb->data; |
---|
| 752 | + struct canfd_frame *cfd = (struct canfd_frame *)skb->data; |
---|
522 | 753 | u32 can_id; |
---|
523 | 754 | u32 data; |
---|
524 | | - u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | (cf->can_dlc << 16); |
---|
| 755 | + u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | ((can_len2dlc(cfd->len)) << 16); |
---|
| 756 | + int i; |
---|
525 | 757 | |
---|
526 | 758 | if (can_dropped_invalid_skb(dev, skb)) |
---|
527 | 759 | return NETDEV_TX_OK; |
---|
528 | 760 | |
---|
529 | 761 | netif_stop_queue(dev); |
---|
530 | 762 | |
---|
531 | | - if (cf->can_id & CAN_EFF_FLAG) { |
---|
532 | | - can_id = cf->can_id & CAN_EFF_MASK; |
---|
| 763 | + if (cfd->can_id & CAN_EFF_FLAG) { |
---|
| 764 | + can_id = cfd->can_id & CAN_EFF_MASK; |
---|
533 | 765 | ctrl |= FLEXCAN_MB_CNT_IDE | FLEXCAN_MB_CNT_SRR; |
---|
534 | 766 | } else { |
---|
535 | | - can_id = (cf->can_id & CAN_SFF_MASK) << 18; |
---|
| 767 | + can_id = (cfd->can_id & CAN_SFF_MASK) << 18; |
---|
536 | 768 | } |
---|
537 | 769 | |
---|
538 | | - if (cf->can_id & CAN_RTR_FLAG) |
---|
| 770 | + if (cfd->can_id & CAN_RTR_FLAG) |
---|
539 | 771 | ctrl |= FLEXCAN_MB_CNT_RTR; |
---|
540 | 772 | |
---|
541 | | - if (cf->can_dlc > 0) { |
---|
542 | | - data = be32_to_cpup((__be32 *)&cf->data[0]); |
---|
543 | | - priv->write(data, ®s->mb[FLEXCAN_TX_MB].data[0]); |
---|
| 773 | + if (can_is_canfd_skb(skb)) { |
---|
| 774 | + ctrl |= FLEXCAN_MB_CNT_EDL; |
---|
| 775 | + |
---|
| 776 | + if (cfd->flags & CANFD_BRS) |
---|
| 777 | + ctrl |= FLEXCAN_MB_CNT_BRS; |
---|
544 | 778 | } |
---|
545 | | - if (cf->can_dlc > 4) { |
---|
546 | | - data = be32_to_cpup((__be32 *)&cf->data[4]); |
---|
547 | | - priv->write(data, ®s->mb[FLEXCAN_TX_MB].data[1]); |
---|
| 779 | + |
---|
| 780 | + for (i = 0; i < cfd->len; i += sizeof(u32)) { |
---|
| 781 | + data = be32_to_cpup((__be32 *)&cfd->data[i]); |
---|
| 782 | + priv->write(data, &priv->tx_mb->data[i / sizeof(u32)]); |
---|
548 | 783 | } |
---|
549 | 784 | |
---|
550 | 785 | can_put_echo_skb(skb, dev, 0); |
---|
551 | 786 | |
---|
552 | | - priv->write(can_id, ®s->mb[FLEXCAN_TX_MB].can_id); |
---|
553 | | - priv->write(ctrl, ®s->mb[FLEXCAN_TX_MB].can_ctrl); |
---|
| 787 | + priv->write(can_id, &priv->tx_mb->can_id); |
---|
| 788 | + priv->write(ctrl, &priv->tx_mb->can_ctrl); |
---|
554 | 789 | |
---|
555 | 790 | /* Errata ERR005829 step8: |
---|
556 | 791 | * Write twice INACTIVE(0x8) code to first MB. |
---|
557 | 792 | */ |
---|
558 | 793 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
---|
559 | | - &priv->tx_mb_reserved->can_ctrl); |
---|
| 794 | + &priv->tx_mb_reserved->can_ctrl); |
---|
560 | 795 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
---|
561 | | - &priv->tx_mb_reserved->can_ctrl); |
---|
| 796 | + &priv->tx_mb_reserved->can_ctrl); |
---|
562 | 797 | |
---|
563 | 798 | return NETDEV_TX_OK; |
---|
564 | 799 | } |
---|
.. | .. |
---|
637 | 872 | u32 timestamp; |
---|
638 | 873 | int err; |
---|
639 | 874 | |
---|
640 | | - timestamp = priv->read(®s->timer) << 16; |
---|
641 | | - |
---|
642 | 875 | flt = reg_esr & FLEXCAN_ESR_FLT_CONF_MASK; |
---|
643 | 876 | if (likely(flt == FLEXCAN_ESR_FLT_CONF_ACTIVE)) { |
---|
644 | 877 | tx_state = unlikely(reg_esr & FLEXCAN_ESR_TX_WRN) ? |
---|
.. | .. |
---|
658 | 891 | if (likely(new_state == priv->can.state)) |
---|
659 | 892 | return; |
---|
660 | 893 | |
---|
| 894 | + timestamp = priv->read(®s->timer) << 16; |
---|
| 895 | + |
---|
661 | 896 | skb = alloc_can_err_skb(dev, &cf); |
---|
662 | 897 | if (unlikely(!skb)) |
---|
663 | 898 | return; |
---|
.. | .. |
---|
672 | 907 | dev->stats.rx_fifo_errors++; |
---|
673 | 908 | } |
---|
674 | 909 | |
---|
| 910 | +static inline u64 flexcan_read64_mask(struct flexcan_priv *priv, void __iomem *addr, u64 mask) |
---|
| 911 | +{ |
---|
| 912 | + u64 reg = 0; |
---|
| 913 | + |
---|
| 914 | + if (upper_32_bits(mask)) |
---|
| 915 | + reg = (u64)priv->read(addr - 4) << 32; |
---|
| 916 | + if (lower_32_bits(mask)) |
---|
| 917 | + reg |= priv->read(addr); |
---|
| 918 | + |
---|
| 919 | + return reg & mask; |
---|
| 920 | +} |
---|
| 921 | + |
---|
| 922 | +static inline void flexcan_write64(struct flexcan_priv *priv, u64 val, void __iomem *addr) |
---|
| 923 | +{ |
---|
| 924 | + if (upper_32_bits(val)) |
---|
| 925 | + priv->write(upper_32_bits(val), addr - 4); |
---|
| 926 | + if (lower_32_bits(val)) |
---|
| 927 | + priv->write(lower_32_bits(val), addr); |
---|
| 928 | +} |
---|
| 929 | + |
---|
| 930 | +static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv) |
---|
| 931 | +{ |
---|
| 932 | + return flexcan_read64_mask(priv, &priv->regs->iflag1, priv->rx_mask); |
---|
| 933 | +} |
---|
| 934 | + |
---|
| 935 | +static inline u64 flexcan_read_reg_iflag_tx(struct flexcan_priv *priv) |
---|
| 936 | +{ |
---|
| 937 | + return flexcan_read64_mask(priv, &priv->regs->iflag1, priv->tx_mask); |
---|
| 938 | +} |
---|
| 939 | + |
---|
675 | 940 | static inline struct flexcan_priv *rx_offload_to_priv(struct can_rx_offload *offload) |
---|
676 | 941 | { |
---|
677 | 942 | return container_of(offload, struct flexcan_priv, offload); |
---|
678 | 943 | } |
---|
679 | 944 | |
---|
680 | | -static unsigned int flexcan_mailbox_read(struct can_rx_offload *offload, |
---|
681 | | - struct can_frame *cf, |
---|
682 | | - u32 *timestamp, unsigned int n) |
---|
| 945 | +static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload, |
---|
| 946 | + unsigned int n, u32 *timestamp, |
---|
| 947 | + bool drop) |
---|
683 | 948 | { |
---|
684 | 949 | struct flexcan_priv *priv = rx_offload_to_priv(offload); |
---|
685 | 950 | struct flexcan_regs __iomem *regs = priv->regs; |
---|
686 | | - struct flexcan_mb __iomem *mb = ®s->mb[n]; |
---|
| 951 | + struct flexcan_mb __iomem *mb; |
---|
| 952 | + struct sk_buff *skb; |
---|
| 953 | + struct canfd_frame *cfd; |
---|
687 | 954 | u32 reg_ctrl, reg_id, reg_iflag1; |
---|
| 955 | + int i; |
---|
| 956 | + |
---|
| 957 | + mb = flexcan_get_mb(priv, n); |
---|
688 | 958 | |
---|
689 | 959 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
---|
690 | 960 | u32 code; |
---|
.. | .. |
---|
697 | 967 | code = reg_ctrl & FLEXCAN_MB_CODE_MASK; |
---|
698 | 968 | if ((code != FLEXCAN_MB_CODE_RX_FULL) && |
---|
699 | 969 | (code != FLEXCAN_MB_CODE_RX_OVERRUN)) |
---|
700 | | - return 0; |
---|
| 970 | + return NULL; |
---|
701 | 971 | |
---|
702 | 972 | if (code == FLEXCAN_MB_CODE_RX_OVERRUN) { |
---|
703 | 973 | /* This MB was overrun, we lost data */ |
---|
.. | .. |
---|
707 | 977 | } else { |
---|
708 | 978 | reg_iflag1 = priv->read(®s->iflag1); |
---|
709 | 979 | if (!(reg_iflag1 & FLEXCAN_IFLAG_RX_FIFO_AVAILABLE)) |
---|
710 | | - return 0; |
---|
| 980 | + return NULL; |
---|
711 | 981 | |
---|
712 | 982 | reg_ctrl = priv->read(&mb->can_ctrl); |
---|
| 983 | + } |
---|
| 984 | + |
---|
| 985 | + if (unlikely(drop)) { |
---|
| 986 | + skb = ERR_PTR(-ENOBUFS); |
---|
| 987 | + goto mark_as_read; |
---|
| 988 | + } |
---|
| 989 | + |
---|
| 990 | + if (reg_ctrl & FLEXCAN_MB_CNT_EDL) |
---|
| 991 | + skb = alloc_canfd_skb(offload->dev, &cfd); |
---|
| 992 | + else |
---|
| 993 | + skb = alloc_can_skb(offload->dev, (struct can_frame **)&cfd); |
---|
| 994 | + if (unlikely(!skb)) { |
---|
| 995 | + skb = ERR_PTR(-ENOMEM); |
---|
| 996 | + goto mark_as_read; |
---|
713 | 997 | } |
---|
714 | 998 | |
---|
715 | 999 | /* increase timstamp to full 32 bit */ |
---|
.. | .. |
---|
717 | 1001 | |
---|
718 | 1002 | reg_id = priv->read(&mb->can_id); |
---|
719 | 1003 | if (reg_ctrl & FLEXCAN_MB_CNT_IDE) |
---|
720 | | - cf->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG; |
---|
| 1004 | + cfd->can_id = ((reg_id >> 0) & CAN_EFF_MASK) | CAN_EFF_FLAG; |
---|
721 | 1005 | else |
---|
722 | | - cf->can_id = (reg_id >> 18) & CAN_SFF_MASK; |
---|
| 1006 | + cfd->can_id = (reg_id >> 18) & CAN_SFF_MASK; |
---|
723 | 1007 | |
---|
724 | | - if (reg_ctrl & FLEXCAN_MB_CNT_RTR) |
---|
725 | | - cf->can_id |= CAN_RTR_FLAG; |
---|
726 | | - cf->can_dlc = get_can_dlc((reg_ctrl >> 16) & 0xf); |
---|
| 1008 | + if (reg_ctrl & FLEXCAN_MB_CNT_EDL) { |
---|
| 1009 | + cfd->len = can_dlc2len(get_canfd_dlc((reg_ctrl >> 16) & 0xf)); |
---|
727 | 1010 | |
---|
728 | | - *(__be32 *)(cf->data + 0) = cpu_to_be32(priv->read(&mb->data[0])); |
---|
729 | | - *(__be32 *)(cf->data + 4) = cpu_to_be32(priv->read(&mb->data[1])); |
---|
730 | | - |
---|
731 | | - /* mark as read */ |
---|
732 | | - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
---|
733 | | - /* Clear IRQ */ |
---|
734 | | - if (n < 32) |
---|
735 | | - priv->write(BIT(n), ®s->iflag1); |
---|
736 | | - else |
---|
737 | | - priv->write(BIT(n - 32), ®s->iflag2); |
---|
| 1011 | + if (reg_ctrl & FLEXCAN_MB_CNT_BRS) |
---|
| 1012 | + cfd->flags |= CANFD_BRS; |
---|
738 | 1013 | } else { |
---|
739 | | - priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1); |
---|
| 1014 | + cfd->len = get_can_dlc((reg_ctrl >> 16) & 0xf); |
---|
| 1015 | + |
---|
| 1016 | + if (reg_ctrl & FLEXCAN_MB_CNT_RTR) |
---|
| 1017 | + cfd->can_id |= CAN_RTR_FLAG; |
---|
740 | 1018 | } |
---|
| 1019 | + |
---|
| 1020 | + if (reg_ctrl & FLEXCAN_MB_CNT_ESI) |
---|
| 1021 | + cfd->flags |= CANFD_ESI; |
---|
| 1022 | + |
---|
| 1023 | + for (i = 0; i < cfd->len; i += sizeof(u32)) { |
---|
| 1024 | + __be32 data = cpu_to_be32(priv->read(&mb->data[i / sizeof(u32)])); |
---|
| 1025 | + *(__be32 *)(cfd->data + i) = data; |
---|
| 1026 | + } |
---|
| 1027 | + |
---|
| 1028 | + mark_as_read: |
---|
| 1029 | + if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) |
---|
| 1030 | + flexcan_write64(priv, FLEXCAN_IFLAG_MB(n), ®s->iflag1); |
---|
| 1031 | + else |
---|
| 1032 | + priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1); |
---|
741 | 1033 | |
---|
742 | 1034 | /* Read the Free Running Timer. It is optional but recommended |
---|
743 | 1035 | * to unlock Mailbox as soon as possible and make it available |
---|
.. | .. |
---|
745 | 1037 | */ |
---|
746 | 1038 | priv->read(®s->timer); |
---|
747 | 1039 | |
---|
748 | | - return 1; |
---|
749 | | -} |
---|
750 | | - |
---|
751 | | - |
---|
752 | | -static inline u64 flexcan_read_reg_iflag_rx(struct flexcan_priv *priv) |
---|
753 | | -{ |
---|
754 | | - struct flexcan_regs __iomem *regs = priv->regs; |
---|
755 | | - u32 iflag1, iflag2; |
---|
756 | | - |
---|
757 | | - iflag2 = priv->read(®s->iflag2) & priv->reg_imask2_default & |
---|
758 | | - ~FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB); |
---|
759 | | - iflag1 = priv->read(®s->iflag1) & priv->reg_imask1_default; |
---|
760 | | - |
---|
761 | | - return (u64)iflag2 << 32 | iflag1; |
---|
| 1040 | + return skb; |
---|
762 | 1041 | } |
---|
763 | 1042 | |
---|
764 | 1043 | static irqreturn_t flexcan_irq(int irq, void *dev_id) |
---|
.. | .. |
---|
768 | 1047 | struct flexcan_priv *priv = netdev_priv(dev); |
---|
769 | 1048 | struct flexcan_regs __iomem *regs = priv->regs; |
---|
770 | 1049 | irqreturn_t handled = IRQ_NONE; |
---|
771 | | - u32 reg_iflag2, reg_esr; |
---|
| 1050 | + u64 reg_iflag_tx; |
---|
| 1051 | + u32 reg_esr; |
---|
772 | 1052 | enum can_state last_state = priv->can.state; |
---|
773 | 1053 | |
---|
774 | 1054 | /* reception interrupt */ |
---|
775 | 1055 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
---|
776 | | - u64 reg_iflag; |
---|
| 1056 | + u64 reg_iflag_rx; |
---|
777 | 1057 | int ret; |
---|
778 | 1058 | |
---|
779 | | - while ((reg_iflag = flexcan_read_reg_iflag_rx(priv))) { |
---|
| 1059 | + while ((reg_iflag_rx = flexcan_read_reg_iflag_rx(priv))) { |
---|
780 | 1060 | handled = IRQ_HANDLED; |
---|
781 | 1061 | ret = can_rx_offload_irq_offload_timestamp(&priv->offload, |
---|
782 | | - reg_iflag); |
---|
| 1062 | + reg_iflag_rx); |
---|
783 | 1063 | if (!ret) |
---|
784 | 1064 | break; |
---|
785 | 1065 | } |
---|
.. | .. |
---|
802 | 1082 | } |
---|
803 | 1083 | } |
---|
804 | 1084 | |
---|
805 | | - reg_iflag2 = priv->read(®s->iflag2); |
---|
| 1085 | + reg_iflag_tx = flexcan_read_reg_iflag_tx(priv); |
---|
806 | 1086 | |
---|
807 | 1087 | /* transmission complete interrupt */ |
---|
808 | | - if (reg_iflag2 & FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB)) { |
---|
809 | | - u32 reg_ctrl = priv->read(®s->mb[FLEXCAN_TX_MB].can_ctrl); |
---|
| 1088 | + if (reg_iflag_tx & priv->tx_mask) { |
---|
| 1089 | + u32 reg_ctrl = priv->read(&priv->tx_mb->can_ctrl); |
---|
810 | 1090 | |
---|
811 | 1091 | handled = IRQ_HANDLED; |
---|
812 | 1092 | stats->tx_bytes += can_rx_offload_get_echo_skb(&priv->offload, |
---|
.. | .. |
---|
816 | 1096 | |
---|
817 | 1097 | /* after sending a RTR frame MB is in RX mode */ |
---|
818 | 1098 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
---|
819 | | - ®s->mb[FLEXCAN_TX_MB].can_ctrl); |
---|
820 | | - priv->write(FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB), ®s->iflag2); |
---|
| 1099 | + &priv->tx_mb->can_ctrl); |
---|
| 1100 | + flexcan_write64(priv, priv->tx_mask, ®s->iflag1); |
---|
821 | 1101 | netif_wake_queue(dev); |
---|
822 | 1102 | } |
---|
823 | 1103 | |
---|
824 | 1104 | reg_esr = priv->read(®s->esr); |
---|
825 | 1105 | |
---|
826 | | - /* ACK all bus error and state change IRQ sources */ |
---|
827 | | - if (reg_esr & FLEXCAN_ESR_ALL_INT) { |
---|
| 1106 | + /* ACK all bus error, state change and wake IRQ sources */ |
---|
| 1107 | + if (reg_esr & (FLEXCAN_ESR_ALL_INT | FLEXCAN_ESR_WAK_INT)) { |
---|
828 | 1108 | handled = IRQ_HANDLED; |
---|
829 | | - priv->write(reg_esr & FLEXCAN_ESR_ALL_INT, ®s->esr); |
---|
| 1109 | + priv->write(reg_esr & (FLEXCAN_ESR_ALL_INT | FLEXCAN_ESR_WAK_INT), ®s->esr); |
---|
830 | 1110 | } |
---|
831 | 1111 | |
---|
832 | 1112 | /* state change interrupt or broken error state quirk fix is enabled */ |
---|
833 | 1113 | if ((reg_esr & FLEXCAN_ESR_ERR_STATE) || |
---|
834 | 1114 | (priv->devtype_data->quirks & (FLEXCAN_QUIRK_BROKEN_WERR_STATE | |
---|
835 | | - FLEXCAN_QUIRK_BROKEN_PERR_STATE))) |
---|
| 1115 | + FLEXCAN_QUIRK_BROKEN_PERR_STATE))) |
---|
836 | 1116 | flexcan_irq_state(dev, reg_esr); |
---|
837 | 1117 | |
---|
838 | 1118 | /* bus error IRQ - handle if bus error reporting is activated */ |
---|
.. | .. |
---|
881 | 1161 | return handled; |
---|
882 | 1162 | } |
---|
883 | 1163 | |
---|
884 | | -static void flexcan_set_bittiming(struct net_device *dev) |
---|
| 1164 | +static void flexcan_set_bittiming_ctrl(const struct net_device *dev) |
---|
885 | 1165 | { |
---|
886 | 1166 | const struct flexcan_priv *priv = netdev_priv(dev); |
---|
887 | 1167 | const struct can_bittiming *bt = &priv->can.bittiming; |
---|
.. | .. |
---|
893 | 1173 | FLEXCAN_CTRL_RJW(0x3) | |
---|
894 | 1174 | FLEXCAN_CTRL_PSEG1(0x7) | |
---|
895 | 1175 | FLEXCAN_CTRL_PSEG2(0x7) | |
---|
896 | | - FLEXCAN_CTRL_PROPSEG(0x7) | |
---|
897 | | - FLEXCAN_CTRL_LPB | |
---|
898 | | - FLEXCAN_CTRL_SMP | |
---|
899 | | - FLEXCAN_CTRL_LOM); |
---|
| 1176 | + FLEXCAN_CTRL_PROPSEG(0x7)); |
---|
900 | 1177 | |
---|
901 | 1178 | reg |= FLEXCAN_CTRL_PRESDIV(bt->brp - 1) | |
---|
902 | 1179 | FLEXCAN_CTRL_PSEG1(bt->phase_seg1 - 1) | |
---|
903 | 1180 | FLEXCAN_CTRL_PSEG2(bt->phase_seg2 - 1) | |
---|
904 | 1181 | FLEXCAN_CTRL_RJW(bt->sjw - 1) | |
---|
905 | 1182 | FLEXCAN_CTRL_PROPSEG(bt->prop_seg - 1); |
---|
| 1183 | + |
---|
| 1184 | + netdev_dbg(dev, "writing ctrl=0x%08x\n", reg); |
---|
| 1185 | + priv->write(reg, ®s->ctrl); |
---|
| 1186 | + |
---|
| 1187 | + /* print chip status */ |
---|
| 1188 | + netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__, |
---|
| 1189 | + priv->read(®s->mcr), priv->read(®s->ctrl)); |
---|
| 1190 | +} |
---|
| 1191 | + |
---|
| 1192 | +static void flexcan_set_bittiming_cbt(const struct net_device *dev) |
---|
| 1193 | +{ |
---|
| 1194 | + struct flexcan_priv *priv = netdev_priv(dev); |
---|
| 1195 | + struct can_bittiming *bt = &priv->can.bittiming; |
---|
| 1196 | + struct can_bittiming *dbt = &priv->can.data_bittiming; |
---|
| 1197 | + struct flexcan_regs __iomem *regs = priv->regs; |
---|
| 1198 | + u32 reg_cbt, reg_fdctrl; |
---|
| 1199 | + |
---|
| 1200 | + /* CBT */ |
---|
| 1201 | + /* CBT[EPSEG1] is 5 bit long and CBT[EPROPSEG] is 6 bit |
---|
| 1202 | + * long. The can_calc_bittiming() tries to divide the tseg1 |
---|
| 1203 | + * equally between phase_seg1 and prop_seg, which may not fit |
---|
| 1204 | + * in CBT register. Therefore, if phase_seg1 is more than |
---|
| 1205 | + * possible value, increase prop_seg and decrease phase_seg1. |
---|
| 1206 | + */ |
---|
| 1207 | + if (bt->phase_seg1 > 0x20) { |
---|
| 1208 | + bt->prop_seg += (bt->phase_seg1 - 0x20); |
---|
| 1209 | + bt->phase_seg1 = 0x20; |
---|
| 1210 | + } |
---|
| 1211 | + |
---|
| 1212 | + reg_cbt = FLEXCAN_CBT_BTF | |
---|
| 1213 | + FIELD_PREP(FLEXCAN_CBT_EPRESDIV_MASK, bt->brp - 1) | |
---|
| 1214 | + FIELD_PREP(FLEXCAN_CBT_ERJW_MASK, bt->sjw - 1) | |
---|
| 1215 | + FIELD_PREP(FLEXCAN_CBT_EPROPSEG_MASK, bt->prop_seg - 1) | |
---|
| 1216 | + FIELD_PREP(FLEXCAN_CBT_EPSEG1_MASK, bt->phase_seg1 - 1) | |
---|
| 1217 | + FIELD_PREP(FLEXCAN_CBT_EPSEG2_MASK, bt->phase_seg2 - 1); |
---|
| 1218 | + |
---|
| 1219 | + netdev_dbg(dev, "writing cbt=0x%08x\n", reg_cbt); |
---|
| 1220 | + priv->write(reg_cbt, ®s->cbt); |
---|
| 1221 | + |
---|
| 1222 | + if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { |
---|
| 1223 | + u32 reg_fdcbt, reg_ctrl2; |
---|
| 1224 | + |
---|
| 1225 | + if (bt->brp != dbt->brp) |
---|
| 1226 | + netdev_warn(dev, "Data brp=%d and brp=%d don't match, this may result in a phase error. Consider using different bitrate and/or data bitrate.\n", |
---|
| 1227 | + dbt->brp, bt->brp); |
---|
| 1228 | + |
---|
| 1229 | + /* FDCBT */ |
---|
| 1230 | + /* FDCBT[FPSEG1] is 3 bit long and FDCBT[FPROPSEG] is |
---|
| 1231 | + * 5 bit long. The can_calc_bittiming tries to divide |
---|
| 1232 | + * the tseg1 equally between phase_seg1 and prop_seg, |
---|
| 1233 | + * which may not fit in FDCBT register. Therefore, if |
---|
| 1234 | + * phase_seg1 is more than possible value, increase |
---|
| 1235 | + * prop_seg and decrease phase_seg1 |
---|
| 1236 | + */ |
---|
| 1237 | + if (dbt->phase_seg1 > 0x8) { |
---|
| 1238 | + dbt->prop_seg += (dbt->phase_seg1 - 0x8); |
---|
| 1239 | + dbt->phase_seg1 = 0x8; |
---|
| 1240 | + } |
---|
| 1241 | + |
---|
| 1242 | + reg_fdcbt = priv->read(®s->fdcbt); |
---|
| 1243 | + reg_fdcbt &= ~(FIELD_PREP(FLEXCAN_FDCBT_FPRESDIV_MASK, 0x3ff) | |
---|
| 1244 | + FIELD_PREP(FLEXCAN_FDCBT_FRJW_MASK, 0x7) | |
---|
| 1245 | + FIELD_PREP(FLEXCAN_FDCBT_FPROPSEG_MASK, 0x1f) | |
---|
| 1246 | + FIELD_PREP(FLEXCAN_FDCBT_FPSEG1_MASK, 0x7) | |
---|
| 1247 | + FIELD_PREP(FLEXCAN_FDCBT_FPSEG2_MASK, 0x7)); |
---|
| 1248 | + |
---|
| 1249 | + reg_fdcbt |= FIELD_PREP(FLEXCAN_FDCBT_FPRESDIV_MASK, dbt->brp - 1) | |
---|
| 1250 | + FIELD_PREP(FLEXCAN_FDCBT_FRJW_MASK, dbt->sjw - 1) | |
---|
| 1251 | + FIELD_PREP(FLEXCAN_FDCBT_FPROPSEG_MASK, dbt->prop_seg) | |
---|
| 1252 | + FIELD_PREP(FLEXCAN_FDCBT_FPSEG1_MASK, dbt->phase_seg1 - 1) | |
---|
| 1253 | + FIELD_PREP(FLEXCAN_FDCBT_FPSEG2_MASK, dbt->phase_seg2 - 1); |
---|
| 1254 | + |
---|
| 1255 | + netdev_dbg(dev, "writing fdcbt=0x%08x\n", reg_fdcbt); |
---|
| 1256 | + priv->write(reg_fdcbt, ®s->fdcbt); |
---|
| 1257 | + |
---|
| 1258 | + /* CTRL2 */ |
---|
| 1259 | + reg_ctrl2 = priv->read(®s->ctrl2); |
---|
| 1260 | + reg_ctrl2 &= ~FLEXCAN_CTRL2_ISOCANFDEN; |
---|
| 1261 | + if (!(priv->can.ctrlmode & CAN_CTRLMODE_FD_NON_ISO)) |
---|
| 1262 | + reg_ctrl2 |= FLEXCAN_CTRL2_ISOCANFDEN; |
---|
| 1263 | + |
---|
| 1264 | + netdev_dbg(dev, "writing ctrl2=0x%08x\n", reg_ctrl2); |
---|
| 1265 | + priv->write(reg_ctrl2, ®s->ctrl2); |
---|
| 1266 | + } |
---|
| 1267 | + |
---|
| 1268 | + /* FDCTRL */ |
---|
| 1269 | + reg_fdctrl = priv->read(®s->fdctrl); |
---|
| 1270 | + reg_fdctrl &= ~(FLEXCAN_FDCTRL_FDRATE | |
---|
| 1271 | + FIELD_PREP(FLEXCAN_FDCTRL_TDCOFF, 0x1f)); |
---|
| 1272 | + |
---|
| 1273 | + if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { |
---|
| 1274 | + reg_fdctrl |= FLEXCAN_FDCTRL_FDRATE; |
---|
| 1275 | + |
---|
| 1276 | + if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { |
---|
| 1277 | + /* TDC must be disabled for Loop Back mode */ |
---|
| 1278 | + reg_fdctrl &= ~FLEXCAN_FDCTRL_TDCEN; |
---|
| 1279 | + } else { |
---|
| 1280 | + reg_fdctrl |= FLEXCAN_FDCTRL_TDCEN | |
---|
| 1281 | + FIELD_PREP(FLEXCAN_FDCTRL_TDCOFF, |
---|
| 1282 | + ((dbt->phase_seg1 - 1) + |
---|
| 1283 | + dbt->prop_seg + 2) * |
---|
| 1284 | + ((dbt->brp - 1 ) + 1)); |
---|
| 1285 | + } |
---|
| 1286 | + } |
---|
| 1287 | + |
---|
| 1288 | + netdev_dbg(dev, "writing fdctrl=0x%08x\n", reg_fdctrl); |
---|
| 1289 | + priv->write(reg_fdctrl, ®s->fdctrl); |
---|
| 1290 | + |
---|
| 1291 | + netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x ctrl2=0x%08x fdctrl=0x%08x cbt=0x%08x fdcbt=0x%08x\n", |
---|
| 1292 | + __func__, |
---|
| 1293 | + priv->read(®s->mcr), priv->read(®s->ctrl), |
---|
| 1294 | + priv->read(®s->ctrl2), priv->read(®s->fdctrl), |
---|
| 1295 | + priv->read(®s->cbt), priv->read(®s->fdcbt)); |
---|
| 1296 | +} |
---|
| 1297 | + |
---|
| 1298 | +static void flexcan_set_bittiming(struct net_device *dev) |
---|
| 1299 | +{ |
---|
| 1300 | + const struct flexcan_priv *priv = netdev_priv(dev); |
---|
| 1301 | + struct flexcan_regs __iomem *regs = priv->regs; |
---|
| 1302 | + u32 reg; |
---|
| 1303 | + |
---|
| 1304 | + reg = priv->read(®s->ctrl); |
---|
| 1305 | + reg &= ~(FLEXCAN_CTRL_LPB | FLEXCAN_CTRL_SMP | |
---|
| 1306 | + FLEXCAN_CTRL_LOM); |
---|
906 | 1307 | |
---|
907 | 1308 | if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) |
---|
908 | 1309 | reg |= FLEXCAN_CTRL_LPB; |
---|
.. | .. |
---|
914 | 1315 | netdev_dbg(dev, "writing ctrl=0x%08x\n", reg); |
---|
915 | 1316 | priv->write(reg, ®s->ctrl); |
---|
916 | 1317 | |
---|
917 | | - /* print chip status */ |
---|
918 | | - netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__, |
---|
919 | | - priv->read(®s->mcr), priv->read(®s->ctrl)); |
---|
| 1318 | + if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) |
---|
| 1319 | + return flexcan_set_bittiming_cbt(dev); |
---|
| 1320 | + else |
---|
| 1321 | + return flexcan_set_bittiming_ctrl(dev); |
---|
| 1322 | +} |
---|
| 1323 | + |
---|
| 1324 | +static void flexcan_ram_init(struct net_device *dev) |
---|
| 1325 | +{ |
---|
| 1326 | + struct flexcan_priv *priv = netdev_priv(dev); |
---|
| 1327 | + struct flexcan_regs __iomem *regs = priv->regs; |
---|
| 1328 | + u32 reg_ctrl2; |
---|
| 1329 | + |
---|
| 1330 | + /* 11.8.3.13 Detection and correction of memory errors: |
---|
| 1331 | + * CTRL2[WRMFRZ] grants write access to all memory positions |
---|
| 1332 | + * that require initialization, ranging from 0x080 to 0xADF |
---|
| 1333 | + * and from 0xF28 to 0xFFF when the CAN FD feature is enabled. |
---|
| 1334 | + * The RXMGMASK, RX14MASK, RX15MASK, and RXFGMASK registers |
---|
| 1335 | + * need to be initialized as well. MCR[RFEN] must not be set |
---|
| 1336 | + * during memory initialization. |
---|
| 1337 | + */ |
---|
| 1338 | + reg_ctrl2 = priv->read(®s->ctrl2); |
---|
| 1339 | + reg_ctrl2 |= FLEXCAN_CTRL2_WRMFRZ; |
---|
| 1340 | + priv->write(reg_ctrl2, ®s->ctrl2); |
---|
| 1341 | + |
---|
| 1342 | + memset_io(®s->mb[0][0], 0, |
---|
| 1343 | + offsetof(struct flexcan_regs, rx_smb1[3]) - |
---|
| 1344 | + offsetof(struct flexcan_regs, mb[0][0]) + 0x4); |
---|
| 1345 | + |
---|
| 1346 | + if (priv->can.ctrlmode & CAN_CTRLMODE_FD) |
---|
| 1347 | + memset_io(®s->tx_smb_fd[0], 0, |
---|
| 1348 | + offsetof(struct flexcan_regs, rx_smb1_fd[17]) - |
---|
| 1349 | + offsetof(struct flexcan_regs, tx_smb_fd[0]) + 0x4); |
---|
| 1350 | + |
---|
| 1351 | + reg_ctrl2 &= ~FLEXCAN_CTRL2_WRMFRZ; |
---|
| 1352 | + priv->write(reg_ctrl2, ®s->ctrl2); |
---|
920 | 1353 | } |
---|
921 | 1354 | |
---|
922 | 1355 | /* flexcan_chip_start |
---|
.. | .. |
---|
929 | 1362 | struct flexcan_priv *priv = netdev_priv(dev); |
---|
930 | 1363 | struct flexcan_regs __iomem *regs = priv->regs; |
---|
931 | 1364 | u32 reg_mcr, reg_ctrl, reg_ctrl2, reg_mecr; |
---|
| 1365 | + u64 reg_imask; |
---|
932 | 1366 | int err, i; |
---|
| 1367 | + struct flexcan_mb __iomem *mb; |
---|
933 | 1368 | |
---|
934 | 1369 | /* enable module */ |
---|
935 | 1370 | err = flexcan_chip_enable(priv); |
---|
.. | .. |
---|
941 | 1376 | if (err) |
---|
942 | 1377 | goto out_chip_disable; |
---|
943 | 1378 | |
---|
| 1379 | + if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SUPPORT_ECC) |
---|
| 1380 | + flexcan_ram_init(dev); |
---|
| 1381 | + |
---|
944 | 1382 | flexcan_set_bittiming(dev); |
---|
| 1383 | + |
---|
| 1384 | + /* set freeze, halt */ |
---|
| 1385 | + err = flexcan_chip_freeze(priv); |
---|
| 1386 | + if (err) |
---|
| 1387 | + goto out_chip_disable; |
---|
945 | 1388 | |
---|
946 | 1389 | /* MCR |
---|
947 | 1390 | * |
---|
948 | | - * enable freeze |
---|
949 | | - * enable fifo |
---|
950 | | - * halt now |
---|
951 | 1391 | * only supervisor access |
---|
952 | 1392 | * enable warning int |
---|
953 | | - * disable local echo |
---|
954 | 1393 | * enable individual RX masking |
---|
955 | 1394 | * choose format C |
---|
956 | 1395 | * set max mailbox number |
---|
957 | 1396 | */ |
---|
958 | 1397 | reg_mcr = priv->read(®s->mcr); |
---|
959 | 1398 | reg_mcr &= ~FLEXCAN_MCR_MAXMB(0xff); |
---|
960 | | - reg_mcr |= FLEXCAN_MCR_FRZ | FLEXCAN_MCR_HALT | FLEXCAN_MCR_SUPV | |
---|
961 | | - FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_SRX_DIS | FLEXCAN_MCR_IRMQ | |
---|
962 | | - FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(FLEXCAN_TX_MB); |
---|
| 1399 | + reg_mcr |= FLEXCAN_MCR_SUPV | FLEXCAN_MCR_WRN_EN | FLEXCAN_MCR_IRMQ | |
---|
| 1400 | + FLEXCAN_MCR_IDAM_C | FLEXCAN_MCR_MAXMB(priv->tx_mb_idx); |
---|
963 | 1401 | |
---|
| 1402 | + /* MCR |
---|
| 1403 | + * |
---|
| 1404 | + * FIFO: |
---|
| 1405 | + * - disable for timestamp mode |
---|
| 1406 | + * - enable for FIFO mode |
---|
| 1407 | + */ |
---|
964 | 1408 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) |
---|
965 | 1409 | reg_mcr &= ~FLEXCAN_MCR_FEN; |
---|
966 | 1410 | else |
---|
967 | 1411 | reg_mcr |= FLEXCAN_MCR_FEN; |
---|
| 1412 | + |
---|
| 1413 | + /* MCR |
---|
| 1414 | + * |
---|
| 1415 | + * NOTE: In loopback mode, the CAN_MCR[SRXDIS] cannot be |
---|
| 1416 | + * asserted because this will impede the self reception |
---|
| 1417 | + * of a transmitted message. This is not documented in |
---|
| 1418 | + * earlier versions of flexcan block guide. |
---|
| 1419 | + * |
---|
| 1420 | + * Self Reception: |
---|
| 1421 | + * - enable Self Reception for loopback mode |
---|
| 1422 | + * (by clearing "Self Reception Disable" bit) |
---|
| 1423 | + * - disable for normal operation |
---|
| 1424 | + */ |
---|
| 1425 | + if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) |
---|
| 1426 | + reg_mcr &= ~FLEXCAN_MCR_SRX_DIS; |
---|
| 1427 | + else |
---|
| 1428 | + reg_mcr |= FLEXCAN_MCR_SRX_DIS; |
---|
| 1429 | + |
---|
| 1430 | + /* MCR - CAN-FD */ |
---|
| 1431 | + if (priv->can.ctrlmode & CAN_CTRLMODE_FD) |
---|
| 1432 | + reg_mcr |= FLEXCAN_MCR_FDEN; |
---|
| 1433 | + else |
---|
| 1434 | + reg_mcr &= ~FLEXCAN_MCR_FDEN; |
---|
968 | 1435 | |
---|
969 | 1436 | netdev_dbg(dev, "%s: writing mcr=0x%08x", __func__, reg_mcr); |
---|
970 | 1437 | priv->write(reg_mcr, ®s->mcr); |
---|
.. | .. |
---|
1008 | 1475 | priv->write(reg_ctrl2, ®s->ctrl2); |
---|
1009 | 1476 | } |
---|
1010 | 1477 | |
---|
| 1478 | + if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) { |
---|
| 1479 | + u32 reg_fdctrl; |
---|
| 1480 | + |
---|
| 1481 | + reg_fdctrl = priv->read(®s->fdctrl); |
---|
| 1482 | + reg_fdctrl &= ~(FIELD_PREP(FLEXCAN_FDCTRL_MBDSR1, 0x3) | |
---|
| 1483 | + FIELD_PREP(FLEXCAN_FDCTRL_MBDSR0, 0x3)); |
---|
| 1484 | + |
---|
| 1485 | + if (priv->can.ctrlmode & CAN_CTRLMODE_FD) { |
---|
| 1486 | + reg_fdctrl |= |
---|
| 1487 | + FIELD_PREP(FLEXCAN_FDCTRL_MBDSR1, |
---|
| 1488 | + FLEXCAN_FDCTRL_MBDSR_64) | |
---|
| 1489 | + FIELD_PREP(FLEXCAN_FDCTRL_MBDSR0, |
---|
| 1490 | + FLEXCAN_FDCTRL_MBDSR_64); |
---|
| 1491 | + } else { |
---|
| 1492 | + reg_fdctrl |= |
---|
| 1493 | + FIELD_PREP(FLEXCAN_FDCTRL_MBDSR1, |
---|
| 1494 | + FLEXCAN_FDCTRL_MBDSR_8) | |
---|
| 1495 | + FIELD_PREP(FLEXCAN_FDCTRL_MBDSR0, |
---|
| 1496 | + FLEXCAN_FDCTRL_MBDSR_8); |
---|
| 1497 | + } |
---|
| 1498 | + |
---|
| 1499 | + netdev_dbg(dev, "%s: writing fdctrl=0x%08x", |
---|
| 1500 | + __func__, reg_fdctrl); |
---|
| 1501 | + priv->write(reg_fdctrl, ®s->fdctrl); |
---|
| 1502 | + } |
---|
| 1503 | + |
---|
1011 | 1504 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
---|
1012 | 1505 | for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) { |
---|
| 1506 | + mb = flexcan_get_mb(priv, i); |
---|
1013 | 1507 | priv->write(FLEXCAN_MB_CODE_RX_EMPTY, |
---|
1014 | | - ®s->mb[i].can_ctrl); |
---|
| 1508 | + &mb->can_ctrl); |
---|
1015 | 1509 | } |
---|
1016 | 1510 | } else { |
---|
1017 | 1511 | /* clear and invalidate unused mailboxes first */ |
---|
1018 | | - for (i = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; i < ARRAY_SIZE(regs->mb); i++) { |
---|
| 1512 | + for (i = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; i < priv->mb_count; i++) { |
---|
| 1513 | + mb = flexcan_get_mb(priv, i); |
---|
1019 | 1514 | priv->write(FLEXCAN_MB_CODE_RX_INACTIVE, |
---|
1020 | | - ®s->mb[i].can_ctrl); |
---|
| 1515 | + &mb->can_ctrl); |
---|
1021 | 1516 | } |
---|
1022 | 1517 | } |
---|
1023 | 1518 | |
---|
.. | .. |
---|
1027 | 1522 | |
---|
1028 | 1523 | /* mark TX mailbox as INACTIVE */ |
---|
1029 | 1524 | priv->write(FLEXCAN_MB_CODE_TX_INACTIVE, |
---|
1030 | | - ®s->mb[FLEXCAN_TX_MB].can_ctrl); |
---|
| 1525 | + &priv->tx_mb->can_ctrl); |
---|
1031 | 1526 | |
---|
1032 | 1527 | /* acceptance mask/acceptance code (accept everything) */ |
---|
1033 | 1528 | priv->write(0x0, ®s->rxgmask); |
---|
.. | .. |
---|
1038 | 1533 | priv->write(0x0, ®s->rxfgmask); |
---|
1039 | 1534 | |
---|
1040 | 1535 | /* clear acceptance filters */ |
---|
1041 | | - for (i = 0; i < ARRAY_SIZE(regs->mb); i++) |
---|
| 1536 | + for (i = 0; i < priv->mb_count; i++) |
---|
1042 | 1537 | priv->write(0, ®s->rximr[i]); |
---|
1043 | 1538 | |
---|
1044 | | - /* On Vybrid, disable memory error detection interrupts |
---|
1045 | | - * and freeze mode. |
---|
1046 | | - * This also works around errata e5295 which generates |
---|
1047 | | - * false positive memory errors and put the device in |
---|
1048 | | - * freeze mode. |
---|
| 1539 | + /* On Vybrid, disable non-correctable errors interrupt and |
---|
| 1540 | + * freeze mode. It still can correct the correctable errors |
---|
| 1541 | + * when HW supports ECC. |
---|
| 1542 | + * |
---|
| 1543 | + * This also works around errata e5295 which generates false |
---|
| 1544 | + * positive memory errors and put the device in freeze mode. |
---|
1049 | 1545 | */ |
---|
1050 | 1546 | if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_MECR) { |
---|
1051 | 1547 | /* Follow the protocol as described in "Detection |
---|
1052 | 1548 | * and Correction of Memory Errors" to write to |
---|
1053 | | - * MECR register |
---|
| 1549 | + * MECR register (step 1 - 5) |
---|
| 1550 | + * |
---|
| 1551 | + * 1. By default, CTRL2[ECRWRE] = 0, MECR[ECRWRDIS] = 1 |
---|
| 1552 | + * 2. set CTRL2[ECRWRE] |
---|
1054 | 1553 | */ |
---|
1055 | 1554 | reg_ctrl2 = priv->read(®s->ctrl2); |
---|
1056 | 1555 | reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE; |
---|
1057 | 1556 | priv->write(reg_ctrl2, ®s->ctrl2); |
---|
1058 | 1557 | |
---|
| 1558 | + /* 3. clear MECR[ECRWRDIS] */ |
---|
1059 | 1559 | reg_mecr = priv->read(®s->mecr); |
---|
1060 | 1560 | reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS; |
---|
1061 | 1561 | priv->write(reg_mecr, ®s->mecr); |
---|
1062 | | - reg_mecr |= FLEXCAN_MECR_ECCDIS; |
---|
| 1562 | + |
---|
| 1563 | + /* 4. all writes to MECR must keep MECR[ECRWRDIS] cleared */ |
---|
1063 | 1564 | reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK | |
---|
1064 | 1565 | FLEXCAN_MECR_FANCEI_MSK); |
---|
1065 | 1566 | priv->write(reg_mecr, ®s->mecr); |
---|
1066 | | - } |
---|
1067 | 1567 | |
---|
1068 | | - err = flexcan_transceiver_enable(priv); |
---|
1069 | | - if (err) |
---|
1070 | | - goto out_chip_disable; |
---|
| 1568 | + /* 5. after configuration done, lock MECR by either |
---|
| 1569 | + * setting MECR[ECRWRDIS] or clearing CTRL2[ECRWRE] |
---|
| 1570 | + */ |
---|
| 1571 | + reg_mecr |= FLEXCAN_MECR_ECRWRDIS; |
---|
| 1572 | + priv->write(reg_mecr, ®s->mecr); |
---|
| 1573 | + |
---|
| 1574 | + reg_ctrl2 &= ~FLEXCAN_CTRL2_ECRWRE; |
---|
| 1575 | + priv->write(reg_ctrl2, ®s->ctrl2); |
---|
| 1576 | + } |
---|
1071 | 1577 | |
---|
1072 | 1578 | /* synchronize with the can bus */ |
---|
1073 | 1579 | err = flexcan_chip_unfreeze(priv); |
---|
1074 | 1580 | if (err) |
---|
1075 | | - goto out_transceiver_disable; |
---|
| 1581 | + goto out_chip_disable; |
---|
1076 | 1582 | |
---|
1077 | 1583 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
---|
1078 | 1584 | |
---|
1079 | 1585 | /* enable interrupts atomically */ |
---|
1080 | 1586 | disable_irq(dev->irq); |
---|
1081 | 1587 | priv->write(priv->reg_ctrl_default, ®s->ctrl); |
---|
1082 | | - priv->write(priv->reg_imask1_default, ®s->imask1); |
---|
1083 | | - priv->write(priv->reg_imask2_default, ®s->imask2); |
---|
| 1588 | + reg_imask = priv->rx_mask | priv->tx_mask; |
---|
| 1589 | + priv->write(upper_32_bits(reg_imask), ®s->imask2); |
---|
| 1590 | + priv->write(lower_32_bits(reg_imask), ®s->imask1); |
---|
1084 | 1591 | enable_irq(dev->irq); |
---|
1085 | 1592 | |
---|
1086 | 1593 | /* print chip status */ |
---|
.. | .. |
---|
1089 | 1596 | |
---|
1090 | 1597 | return 0; |
---|
1091 | 1598 | |
---|
1092 | | - out_transceiver_disable: |
---|
1093 | | - flexcan_transceiver_disable(priv); |
---|
1094 | 1599 | out_chip_disable: |
---|
1095 | 1600 | flexcan_chip_disable(priv); |
---|
1096 | 1601 | return err; |
---|
.. | .. |
---|
1120 | 1625 | priv->write(priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_ALL, |
---|
1121 | 1626 | ®s->ctrl); |
---|
1122 | 1627 | |
---|
1123 | | - flexcan_transceiver_disable(priv); |
---|
1124 | 1628 | priv->can.state = CAN_STATE_STOPPED; |
---|
1125 | 1629 | |
---|
1126 | 1630 | return 0; |
---|
.. | .. |
---|
1146 | 1650 | struct flexcan_priv *priv = netdev_priv(dev); |
---|
1147 | 1651 | int err; |
---|
1148 | 1652 | |
---|
1149 | | - err = clk_prepare_enable(priv->clk_ipg); |
---|
1150 | | - if (err) |
---|
1151 | | - return err; |
---|
| 1653 | + if ((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) && |
---|
| 1654 | + (priv->can.ctrlmode & CAN_CTRLMODE_FD)) { |
---|
| 1655 | + netdev_err(dev, "Three Samples mode and CAN-FD mode can't be used together\n"); |
---|
| 1656 | + return -EINVAL; |
---|
| 1657 | + } |
---|
1152 | 1658 | |
---|
1153 | | - err = clk_prepare_enable(priv->clk_per); |
---|
1154 | | - if (err) |
---|
1155 | | - goto out_disable_ipg; |
---|
| 1659 | + err = pm_runtime_get_sync(priv->dev); |
---|
| 1660 | + if (err < 0) { |
---|
| 1661 | + pm_runtime_put_noidle(priv->dev); |
---|
| 1662 | + return err; |
---|
| 1663 | + } |
---|
1156 | 1664 | |
---|
1157 | 1665 | err = open_candev(dev); |
---|
1158 | 1666 | if (err) |
---|
1159 | | - goto out_disable_per; |
---|
| 1667 | + goto out_runtime_put; |
---|
| 1668 | + |
---|
| 1669 | + err = flexcan_transceiver_enable(priv); |
---|
| 1670 | + if (err) |
---|
| 1671 | + goto out_close; |
---|
1160 | 1672 | |
---|
1161 | 1673 | err = request_irq(dev->irq, flexcan_irq, IRQF_SHARED, dev->name, dev); |
---|
1162 | 1674 | if (err) |
---|
1163 | | - goto out_close; |
---|
| 1675 | + goto out_transceiver_disable; |
---|
| 1676 | + |
---|
| 1677 | + if (priv->can.ctrlmode & CAN_CTRLMODE_FD) |
---|
| 1678 | + priv->mb_size = sizeof(struct flexcan_mb) + CANFD_MAX_DLEN; |
---|
| 1679 | + else |
---|
| 1680 | + priv->mb_size = sizeof(struct flexcan_mb) + CAN_MAX_DLEN; |
---|
| 1681 | + priv->mb_count = (sizeof(priv->regs->mb[0]) / priv->mb_size) + |
---|
| 1682 | + (sizeof(priv->regs->mb[1]) / priv->mb_size); |
---|
| 1683 | + |
---|
| 1684 | + if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) |
---|
| 1685 | + priv->tx_mb_reserved = |
---|
| 1686 | + flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP); |
---|
| 1687 | + else |
---|
| 1688 | + priv->tx_mb_reserved = |
---|
| 1689 | + flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_FIFO); |
---|
| 1690 | + priv->tx_mb_idx = priv->mb_count - 1; |
---|
| 1691 | + priv->tx_mb = flexcan_get_mb(priv, priv->tx_mb_idx); |
---|
| 1692 | + priv->tx_mask = FLEXCAN_IFLAG_MB(priv->tx_mb_idx); |
---|
| 1693 | + |
---|
| 1694 | + priv->offload.mailbox_read = flexcan_mailbox_read; |
---|
| 1695 | + |
---|
| 1696 | + if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
---|
| 1697 | + priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST; |
---|
| 1698 | + priv->offload.mb_last = priv->mb_count - 2; |
---|
| 1699 | + |
---|
| 1700 | + priv->rx_mask = GENMASK_ULL(priv->offload.mb_last, |
---|
| 1701 | + priv->offload.mb_first); |
---|
| 1702 | + err = can_rx_offload_add_timestamp(dev, &priv->offload); |
---|
| 1703 | + } else { |
---|
| 1704 | + priv->rx_mask = FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | |
---|
| 1705 | + FLEXCAN_IFLAG_RX_FIFO_AVAILABLE; |
---|
| 1706 | + err = can_rx_offload_add_fifo(dev, &priv->offload, |
---|
| 1707 | + FLEXCAN_NAPI_WEIGHT); |
---|
| 1708 | + } |
---|
| 1709 | + if (err) |
---|
| 1710 | + goto out_free_irq; |
---|
1164 | 1711 | |
---|
1165 | 1712 | /* start chip and queuing */ |
---|
1166 | 1713 | err = flexcan_chip_start(dev); |
---|
1167 | 1714 | if (err) |
---|
1168 | | - goto out_free_irq; |
---|
| 1715 | + goto out_offload_del; |
---|
1169 | 1716 | |
---|
1170 | 1717 | can_led_event(dev, CAN_LED_EVENT_OPEN); |
---|
1171 | 1718 | |
---|
.. | .. |
---|
1174 | 1721 | |
---|
1175 | 1722 | return 0; |
---|
1176 | 1723 | |
---|
| 1724 | + out_offload_del: |
---|
| 1725 | + can_rx_offload_del(&priv->offload); |
---|
1177 | 1726 | out_free_irq: |
---|
1178 | 1727 | free_irq(dev->irq, dev); |
---|
| 1728 | + out_transceiver_disable: |
---|
| 1729 | + flexcan_transceiver_disable(priv); |
---|
1179 | 1730 | out_close: |
---|
1180 | 1731 | close_candev(dev); |
---|
1181 | | - out_disable_per: |
---|
1182 | | - clk_disable_unprepare(priv->clk_per); |
---|
1183 | | - out_disable_ipg: |
---|
1184 | | - clk_disable_unprepare(priv->clk_ipg); |
---|
| 1732 | + out_runtime_put: |
---|
| 1733 | + pm_runtime_put(priv->dev); |
---|
1185 | 1734 | |
---|
1186 | 1735 | return err; |
---|
1187 | 1736 | } |
---|
.. | .. |
---|
1194 | 1743 | can_rx_offload_disable(&priv->offload); |
---|
1195 | 1744 | flexcan_chip_stop_disable_on_error(dev); |
---|
1196 | 1745 | |
---|
| 1746 | + can_rx_offload_del(&priv->offload); |
---|
1197 | 1747 | free_irq(dev->irq, dev); |
---|
1198 | | - clk_disable_unprepare(priv->clk_per); |
---|
1199 | | - clk_disable_unprepare(priv->clk_ipg); |
---|
| 1748 | + flexcan_transceiver_disable(priv); |
---|
1200 | 1749 | |
---|
1201 | 1750 | close_candev(dev); |
---|
| 1751 | + pm_runtime_put(priv->dev); |
---|
1202 | 1752 | |
---|
1203 | 1753 | can_led_event(dev, CAN_LED_EVENT_STOP); |
---|
1204 | 1754 | |
---|
.. | .. |
---|
1238 | 1788 | struct flexcan_regs __iomem *regs = priv->regs; |
---|
1239 | 1789 | u32 reg, err; |
---|
1240 | 1790 | |
---|
1241 | | - err = clk_prepare_enable(priv->clk_ipg); |
---|
| 1791 | + err = flexcan_clks_enable(priv); |
---|
1242 | 1792 | if (err) |
---|
1243 | 1793 | return err; |
---|
1244 | | - |
---|
1245 | | - err = clk_prepare_enable(priv->clk_per); |
---|
1246 | | - if (err) |
---|
1247 | | - goto out_disable_ipg; |
---|
1248 | 1794 | |
---|
1249 | 1795 | /* select "bus clock", chip must be disabled */ |
---|
1250 | 1796 | err = flexcan_chip_disable(priv); |
---|
1251 | 1797 | if (err) |
---|
1252 | | - goto out_disable_per; |
---|
| 1798 | + goto out_clks_disable; |
---|
| 1799 | + |
---|
1253 | 1800 | reg = priv->read(®s->ctrl); |
---|
1254 | | - reg |= FLEXCAN_CTRL_CLK_SRC; |
---|
| 1801 | + if (priv->clk_src) |
---|
| 1802 | + reg |= FLEXCAN_CTRL_CLK_SRC; |
---|
| 1803 | + else |
---|
| 1804 | + reg &= ~FLEXCAN_CTRL_CLK_SRC; |
---|
1255 | 1805 | priv->write(reg, ®s->ctrl); |
---|
1256 | 1806 | |
---|
1257 | 1807 | err = flexcan_chip_enable(priv); |
---|
.. | .. |
---|
1281 | 1831 | } |
---|
1282 | 1832 | |
---|
1283 | 1833 | err = register_candev(dev); |
---|
| 1834 | + if (err) |
---|
| 1835 | + goto out_chip_disable; |
---|
1284 | 1836 | |
---|
1285 | | - /* disable core and turn off clocks */ |
---|
| 1837 | + /* Disable core and let pm_runtime_put() disable the clocks. |
---|
| 1838 | + * If CONFIG_PM is not enabled, the clocks will stay powered. |
---|
| 1839 | + */ |
---|
| 1840 | + flexcan_chip_disable(priv); |
---|
| 1841 | + pm_runtime_put(priv->dev); |
---|
| 1842 | + |
---|
| 1843 | + return 0; |
---|
| 1844 | + |
---|
1286 | 1845 | out_chip_disable: |
---|
1287 | 1846 | flexcan_chip_disable(priv); |
---|
1288 | | - out_disable_per: |
---|
1289 | | - clk_disable_unprepare(priv->clk_per); |
---|
1290 | | - out_disable_ipg: |
---|
1291 | | - clk_disable_unprepare(priv->clk_ipg); |
---|
1292 | | - |
---|
| 1847 | + out_clks_disable: |
---|
| 1848 | + flexcan_clks_disable(priv); |
---|
1293 | 1849 | return err; |
---|
1294 | 1850 | } |
---|
1295 | 1851 | |
---|
.. | .. |
---|
1298 | 1854 | unregister_candev(dev); |
---|
1299 | 1855 | } |
---|
1300 | 1856 | |
---|
| 1857 | +static int flexcan_setup_stop_mode(struct platform_device *pdev) |
---|
| 1858 | +{ |
---|
| 1859 | + struct net_device *dev = platform_get_drvdata(pdev); |
---|
| 1860 | + struct device_node *np = pdev->dev.of_node; |
---|
| 1861 | + struct device_node *gpr_np; |
---|
| 1862 | + struct flexcan_priv *priv; |
---|
| 1863 | + phandle phandle; |
---|
| 1864 | + u32 out_val[3]; |
---|
| 1865 | + int ret; |
---|
| 1866 | + |
---|
| 1867 | + if (!np) |
---|
| 1868 | + return -EINVAL; |
---|
| 1869 | + |
---|
| 1870 | + /* stop mode property format is: |
---|
| 1871 | + * <&gpr req_gpr req_bit>. |
---|
| 1872 | + */ |
---|
| 1873 | + ret = of_property_read_u32_array(np, "fsl,stop-mode", out_val, |
---|
| 1874 | + ARRAY_SIZE(out_val)); |
---|
| 1875 | + if (ret) { |
---|
| 1876 | + dev_dbg(&pdev->dev, "no stop-mode property\n"); |
---|
| 1877 | + return ret; |
---|
| 1878 | + } |
---|
| 1879 | + phandle = *out_val; |
---|
| 1880 | + |
---|
| 1881 | + gpr_np = of_find_node_by_phandle(phandle); |
---|
| 1882 | + if (!gpr_np) { |
---|
| 1883 | + dev_dbg(&pdev->dev, "could not find gpr node by phandle\n"); |
---|
| 1884 | + return -ENODEV; |
---|
| 1885 | + } |
---|
| 1886 | + |
---|
| 1887 | + priv = netdev_priv(dev); |
---|
| 1888 | + priv->stm.gpr = syscon_node_to_regmap(gpr_np); |
---|
| 1889 | + if (IS_ERR(priv->stm.gpr)) { |
---|
| 1890 | + dev_dbg(&pdev->dev, "could not find gpr regmap\n"); |
---|
| 1891 | + ret = PTR_ERR(priv->stm.gpr); |
---|
| 1892 | + goto out_put_node; |
---|
| 1893 | + } |
---|
| 1894 | + |
---|
| 1895 | + priv->stm.req_gpr = out_val[1]; |
---|
| 1896 | + priv->stm.req_bit = out_val[2]; |
---|
| 1897 | + |
---|
| 1898 | + dev_dbg(&pdev->dev, |
---|
| 1899 | + "gpr %s req_gpr=0x02%x req_bit=%u\n", |
---|
| 1900 | + gpr_np->full_name, priv->stm.req_gpr, priv->stm.req_bit); |
---|
| 1901 | + |
---|
| 1902 | + device_set_wakeup_capable(&pdev->dev, true); |
---|
| 1903 | + |
---|
| 1904 | + if (of_property_read_bool(np, "wakeup-source")) |
---|
| 1905 | + device_set_wakeup_enable(&pdev->dev, true); |
---|
| 1906 | + |
---|
| 1907 | + return 0; |
---|
| 1908 | + |
---|
| 1909 | +out_put_node: |
---|
| 1910 | + of_node_put(gpr_np); |
---|
| 1911 | + return ret; |
---|
| 1912 | +} |
---|
| 1913 | + |
---|
1301 | 1914 | static const struct of_device_id flexcan_of_match[] = { |
---|
| 1915 | + { .compatible = "fsl,imx8qm-flexcan", .data = &fsl_imx8qm_devtype_data, }, |
---|
| 1916 | + { .compatible = "fsl,imx8mp-flexcan", .data = &fsl_imx8mp_devtype_data, }, |
---|
1302 | 1917 | { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, |
---|
1303 | 1918 | { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, |
---|
1304 | 1919 | { .compatible = "fsl,imx53-flexcan", .data = &fsl_imx25_devtype_data, }, |
---|
.. | .. |
---|
1307 | 1922 | { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, |
---|
1308 | 1923 | { .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, }, |
---|
1309 | 1924 | { .compatible = "fsl,ls1021ar2-flexcan", .data = &fsl_ls1021a_r2_devtype_data, }, |
---|
| 1925 | + { .compatible = "fsl,lx2160ar1-flexcan", .data = &fsl_lx2160a_r1_devtype_data, }, |
---|
1310 | 1926 | { /* sentinel */ }, |
---|
1311 | 1927 | }; |
---|
1312 | 1928 | MODULE_DEVICE_TABLE(of, flexcan_of_match); |
---|
.. | .. |
---|
1324 | 1940 | struct net_device *dev; |
---|
1325 | 1941 | struct flexcan_priv *priv; |
---|
1326 | 1942 | struct regulator *reg_xceiver; |
---|
1327 | | - struct resource *mem; |
---|
1328 | 1943 | struct clk *clk_ipg = NULL, *clk_per = NULL; |
---|
1329 | 1944 | struct flexcan_regs __iomem *regs; |
---|
1330 | 1945 | int err, irq; |
---|
| 1946 | + u8 clk_src = 1; |
---|
1331 | 1947 | u32 clock_freq = 0; |
---|
1332 | 1948 | |
---|
1333 | | - reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver"); |
---|
| 1949 | + reg_xceiver = devm_regulator_get_optional(&pdev->dev, "xceiver"); |
---|
1334 | 1950 | if (PTR_ERR(reg_xceiver) == -EPROBE_DEFER) |
---|
1335 | 1951 | return -EPROBE_DEFER; |
---|
1336 | | - else if (IS_ERR(reg_xceiver)) |
---|
| 1952 | + else if (PTR_ERR(reg_xceiver) == -ENODEV) |
---|
1337 | 1953 | reg_xceiver = NULL; |
---|
| 1954 | + else if (IS_ERR(reg_xceiver)) |
---|
| 1955 | + return PTR_ERR(reg_xceiver); |
---|
1338 | 1956 | |
---|
1339 | | - if (pdev->dev.of_node) |
---|
| 1957 | + if (pdev->dev.of_node) { |
---|
1340 | 1958 | of_property_read_u32(pdev->dev.of_node, |
---|
1341 | 1959 | "clock-frequency", &clock_freq); |
---|
| 1960 | + of_property_read_u8(pdev->dev.of_node, |
---|
| 1961 | + "fsl,clk-source", &clk_src); |
---|
| 1962 | + } |
---|
1342 | 1963 | |
---|
1343 | 1964 | if (!clock_freq) { |
---|
1344 | 1965 | clk_ipg = devm_clk_get(&pdev->dev, "ipg"); |
---|
.. | .. |
---|
1355 | 1976 | clock_freq = clk_get_rate(clk_per); |
---|
1356 | 1977 | } |
---|
1357 | 1978 | |
---|
1358 | | - mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
1359 | 1979 | irq = platform_get_irq(pdev, 0); |
---|
1360 | 1980 | if (irq <= 0) |
---|
1361 | 1981 | return -ENODEV; |
---|
1362 | 1982 | |
---|
1363 | | - regs = devm_ioremap_resource(&pdev->dev, mem); |
---|
| 1983 | + regs = devm_platform_ioremap_resource(pdev, 0); |
---|
1364 | 1984 | if (IS_ERR(regs)) |
---|
1365 | 1985 | return PTR_ERR(regs); |
---|
1366 | 1986 | |
---|
.. | .. |
---|
1372 | 1992 | platform_get_device_id(pdev)->driver_data; |
---|
1373 | 1993 | } else { |
---|
1374 | 1994 | return -ENODEV; |
---|
| 1995 | + } |
---|
| 1996 | + |
---|
| 1997 | + if ((devtype_data->quirks & FLEXCAN_QUIRK_SUPPORT_FD) && |
---|
| 1998 | + !(devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP)) { |
---|
| 1999 | + dev_err(&pdev->dev, "CAN-FD mode doesn't work with FIFO mode!\n"); |
---|
| 2000 | + return -EINVAL; |
---|
1375 | 2001 | } |
---|
1376 | 2002 | |
---|
1377 | 2003 | dev = alloc_candev(sizeof(struct flexcan_priv), 1); |
---|
.. | .. |
---|
1396 | 2022 | priv->write = flexcan_write_le; |
---|
1397 | 2023 | } |
---|
1398 | 2024 | |
---|
| 2025 | + priv->dev = &pdev->dev; |
---|
1399 | 2026 | priv->can.clock.freq = clock_freq; |
---|
1400 | | - priv->can.bittiming_const = &flexcan_bittiming_const; |
---|
1401 | 2027 | priv->can.do_set_mode = flexcan_set_mode; |
---|
1402 | 2028 | priv->can.do_get_berr_counter = flexcan_get_berr_counter; |
---|
1403 | 2029 | priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK | |
---|
.. | .. |
---|
1406 | 2032 | priv->regs = regs; |
---|
1407 | 2033 | priv->clk_ipg = clk_ipg; |
---|
1408 | 2034 | priv->clk_per = clk_per; |
---|
| 2035 | + priv->clk_src = clk_src; |
---|
1409 | 2036 | priv->devtype_data = devtype_data; |
---|
1410 | 2037 | priv->reg_xceiver = reg_xceiver; |
---|
1411 | 2038 | |
---|
1412 | | - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) |
---|
1413 | | - priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP]; |
---|
1414 | | - else |
---|
1415 | | - priv->tx_mb_reserved = ®s->mb[FLEXCAN_TX_MB_RESERVED_OFF_FIFO]; |
---|
1416 | | - |
---|
1417 | | - priv->reg_imask1_default = 0; |
---|
1418 | | - priv->reg_imask2_default = FLEXCAN_IFLAG_MB(FLEXCAN_TX_MB); |
---|
1419 | | - |
---|
1420 | | - priv->offload.mailbox_read = flexcan_mailbox_read; |
---|
1421 | | - |
---|
1422 | | - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
---|
1423 | | - u64 imask; |
---|
1424 | | - |
---|
1425 | | - priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST; |
---|
1426 | | - priv->offload.mb_last = FLEXCAN_RX_MB_OFF_TIMESTAMP_LAST; |
---|
1427 | | - |
---|
1428 | | - imask = GENMASK_ULL(priv->offload.mb_last, priv->offload.mb_first); |
---|
1429 | | - priv->reg_imask1_default |= imask; |
---|
1430 | | - priv->reg_imask2_default |= imask >> 32; |
---|
1431 | | - |
---|
1432 | | - err = can_rx_offload_add_timestamp(dev, &priv->offload); |
---|
| 2039 | + if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SUPPORT_FD) { |
---|
| 2040 | + priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD | |
---|
| 2041 | + CAN_CTRLMODE_FD_NON_ISO; |
---|
| 2042 | + priv->can.bittiming_const = &flexcan_fd_bittiming_const; |
---|
| 2043 | + priv->can.data_bittiming_const = |
---|
| 2044 | + &flexcan_fd_data_bittiming_const; |
---|
1433 | 2045 | } else { |
---|
1434 | | - priv->reg_imask1_default |= FLEXCAN_IFLAG_RX_FIFO_OVERFLOW | |
---|
1435 | | - FLEXCAN_IFLAG_RX_FIFO_AVAILABLE; |
---|
1436 | | - err = can_rx_offload_add_fifo(dev, &priv->offload, FLEXCAN_NAPI_WEIGHT); |
---|
| 2046 | + priv->can.bittiming_const = &flexcan_bittiming_const; |
---|
1437 | 2047 | } |
---|
1438 | | - if (err) |
---|
1439 | | - goto failed_offload; |
---|
| 2048 | + |
---|
| 2049 | + pm_runtime_get_noresume(&pdev->dev); |
---|
| 2050 | + pm_runtime_set_active(&pdev->dev); |
---|
| 2051 | + pm_runtime_enable(&pdev->dev); |
---|
1440 | 2052 | |
---|
1441 | 2053 | err = register_flexcandev(dev); |
---|
1442 | 2054 | if (err) { |
---|
.. | .. |
---|
1444 | 2056 | goto failed_register; |
---|
1445 | 2057 | } |
---|
1446 | 2058 | |
---|
| 2059 | + of_can_transceiver(dev); |
---|
1447 | 2060 | devm_can_led_init(dev); |
---|
1448 | 2061 | |
---|
1449 | | - dev_info(&pdev->dev, "device registered (reg_base=%p, irq=%d)\n", |
---|
1450 | | - priv->regs, dev->irq); |
---|
| 2062 | + if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE) { |
---|
| 2063 | + err = flexcan_setup_stop_mode(pdev); |
---|
| 2064 | + if (err) |
---|
| 2065 | + dev_dbg(&pdev->dev, "failed to setup stop-mode\n"); |
---|
| 2066 | + } |
---|
1451 | 2067 | |
---|
1452 | 2068 | return 0; |
---|
1453 | 2069 | |
---|
1454 | | - failed_offload: |
---|
1455 | 2070 | failed_register: |
---|
| 2071 | + pm_runtime_put_noidle(&pdev->dev); |
---|
| 2072 | + pm_runtime_disable(&pdev->dev); |
---|
1456 | 2073 | free_candev(dev); |
---|
1457 | 2074 | return err; |
---|
1458 | 2075 | } |
---|
.. | .. |
---|
1460 | 2077 | static int flexcan_remove(struct platform_device *pdev) |
---|
1461 | 2078 | { |
---|
1462 | 2079 | struct net_device *dev = platform_get_drvdata(pdev); |
---|
1463 | | - struct flexcan_priv *priv = netdev_priv(dev); |
---|
1464 | 2080 | |
---|
| 2081 | + device_set_wakeup_enable(&pdev->dev, false); |
---|
| 2082 | + device_set_wakeup_capable(&pdev->dev, false); |
---|
1465 | 2083 | unregister_flexcandev(dev); |
---|
1466 | | - can_rx_offload_del(&priv->offload); |
---|
| 2084 | + pm_runtime_disable(&pdev->dev); |
---|
1467 | 2085 | free_candev(dev); |
---|
1468 | 2086 | |
---|
1469 | 2087 | return 0; |
---|
.. | .. |
---|
1476 | 2094 | int err; |
---|
1477 | 2095 | |
---|
1478 | 2096 | if (netif_running(dev)) { |
---|
1479 | | - err = flexcan_chip_disable(priv); |
---|
1480 | | - if (err) |
---|
1481 | | - return err; |
---|
| 2097 | + /* if wakeup is enabled, enter stop mode |
---|
| 2098 | + * else enter disabled mode. |
---|
| 2099 | + */ |
---|
| 2100 | + if (device_may_wakeup(device)) { |
---|
| 2101 | + enable_irq_wake(dev->irq); |
---|
| 2102 | + err = flexcan_enter_stop_mode(priv); |
---|
| 2103 | + if (err) |
---|
| 2104 | + return err; |
---|
| 2105 | + } else { |
---|
| 2106 | + err = flexcan_chip_stop(dev); |
---|
| 2107 | + if (err) |
---|
| 2108 | + return err; |
---|
| 2109 | + |
---|
| 2110 | + err = pinctrl_pm_select_sleep_state(device); |
---|
| 2111 | + if (err) |
---|
| 2112 | + return err; |
---|
| 2113 | + } |
---|
1482 | 2114 | netif_stop_queue(dev); |
---|
1483 | 2115 | netif_device_detach(dev); |
---|
1484 | 2116 | } |
---|
.. | .. |
---|
1497 | 2129 | if (netif_running(dev)) { |
---|
1498 | 2130 | netif_device_attach(dev); |
---|
1499 | 2131 | netif_start_queue(dev); |
---|
1500 | | - err = flexcan_chip_enable(priv); |
---|
1501 | | - if (err) |
---|
1502 | | - return err; |
---|
| 2132 | + if (device_may_wakeup(device)) { |
---|
| 2133 | + disable_irq_wake(dev->irq); |
---|
| 2134 | + err = flexcan_exit_stop_mode(priv); |
---|
| 2135 | + if (err) |
---|
| 2136 | + return err; |
---|
| 2137 | + } else { |
---|
| 2138 | + err = pinctrl_pm_select_default_state(device); |
---|
| 2139 | + if (err) |
---|
| 2140 | + return err; |
---|
| 2141 | + |
---|
| 2142 | + err = flexcan_chip_start(dev); |
---|
| 2143 | + if (err) |
---|
| 2144 | + return err; |
---|
| 2145 | + } |
---|
1503 | 2146 | } |
---|
| 2147 | + |
---|
1504 | 2148 | return 0; |
---|
1505 | 2149 | } |
---|
1506 | 2150 | |
---|
1507 | | -static SIMPLE_DEV_PM_OPS(flexcan_pm_ops, flexcan_suspend, flexcan_resume); |
---|
| 2151 | +static int __maybe_unused flexcan_runtime_suspend(struct device *device) |
---|
| 2152 | +{ |
---|
| 2153 | + struct net_device *dev = dev_get_drvdata(device); |
---|
| 2154 | + struct flexcan_priv *priv = netdev_priv(dev); |
---|
| 2155 | + |
---|
| 2156 | + flexcan_clks_disable(priv); |
---|
| 2157 | + |
---|
| 2158 | + return 0; |
---|
| 2159 | +} |
---|
| 2160 | + |
---|
| 2161 | +static int __maybe_unused flexcan_runtime_resume(struct device *device) |
---|
| 2162 | +{ |
---|
| 2163 | + struct net_device *dev = dev_get_drvdata(device); |
---|
| 2164 | + struct flexcan_priv *priv = netdev_priv(dev); |
---|
| 2165 | + |
---|
| 2166 | + return flexcan_clks_enable(priv); |
---|
| 2167 | +} |
---|
| 2168 | + |
---|
| 2169 | +static int __maybe_unused flexcan_noirq_suspend(struct device *device) |
---|
| 2170 | +{ |
---|
| 2171 | + struct net_device *dev = dev_get_drvdata(device); |
---|
| 2172 | + struct flexcan_priv *priv = netdev_priv(dev); |
---|
| 2173 | + |
---|
| 2174 | + if (netif_running(dev)) { |
---|
| 2175 | + int err; |
---|
| 2176 | + |
---|
| 2177 | + if (device_may_wakeup(device)) |
---|
| 2178 | + flexcan_enable_wakeup_irq(priv, true); |
---|
| 2179 | + |
---|
| 2180 | + err = pm_runtime_force_suspend(device); |
---|
| 2181 | + if (err) |
---|
| 2182 | + return err; |
---|
| 2183 | + } |
---|
| 2184 | + |
---|
| 2185 | + return 0; |
---|
| 2186 | +} |
---|
| 2187 | + |
---|
| 2188 | +static int __maybe_unused flexcan_noirq_resume(struct device *device) |
---|
| 2189 | +{ |
---|
| 2190 | + struct net_device *dev = dev_get_drvdata(device); |
---|
| 2191 | + struct flexcan_priv *priv = netdev_priv(dev); |
---|
| 2192 | + |
---|
| 2193 | + if (netif_running(dev)) { |
---|
| 2194 | + int err; |
---|
| 2195 | + |
---|
| 2196 | + err = pm_runtime_force_resume(device); |
---|
| 2197 | + if (err) |
---|
| 2198 | + return err; |
---|
| 2199 | + |
---|
| 2200 | + if (device_may_wakeup(device)) |
---|
| 2201 | + flexcan_enable_wakeup_irq(priv, false); |
---|
| 2202 | + } |
---|
| 2203 | + |
---|
| 2204 | + return 0; |
---|
| 2205 | +} |
---|
| 2206 | + |
---|
| 2207 | +static const struct dev_pm_ops flexcan_pm_ops = { |
---|
| 2208 | + SET_SYSTEM_SLEEP_PM_OPS(flexcan_suspend, flexcan_resume) |
---|
| 2209 | + SET_RUNTIME_PM_OPS(flexcan_runtime_suspend, flexcan_runtime_resume, NULL) |
---|
| 2210 | + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(flexcan_noirq_suspend, flexcan_noirq_resume) |
---|
| 2211 | +}; |
---|
1508 | 2212 | |
---|
1509 | 2213 | static struct platform_driver flexcan_driver = { |
---|
1510 | 2214 | .driver = { |
---|