1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Copyright (c) 2020 Rockchip Electronics Co. Ltd.
4*4882a593Smuzhiyun * Rockchip CANFD driver
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun
7*4882a593Smuzhiyun #include <linux/delay.h>
8*4882a593Smuzhiyun #include <linux/iopoll.h>
9*4882a593Smuzhiyun #include <linux/pinctrl/consumer.h>
10*4882a593Smuzhiyun #include <linux/clk.h>
11*4882a593Smuzhiyun #include <linux/errno.h>
12*4882a593Smuzhiyun #include <linux/init.h>
13*4882a593Smuzhiyun #include <linux/interrupt.h>
14*4882a593Smuzhiyun #include <linux/io.h>
15*4882a593Smuzhiyun #include <linux/kernel.h>
16*4882a593Smuzhiyun #include <linux/module.h>
17*4882a593Smuzhiyun #include <linux/netdevice.h>
18*4882a593Smuzhiyun #include <linux/of.h>
19*4882a593Smuzhiyun #include <linux/of_device.h>
20*4882a593Smuzhiyun #include <linux/platform_device.h>
21*4882a593Smuzhiyun #include <linux/skbuff.h>
22*4882a593Smuzhiyun #include <linux/spinlock.h>
23*4882a593Smuzhiyun #include <linux/string.h>
24*4882a593Smuzhiyun #include <linux/types.h>
25*4882a593Smuzhiyun #include <linux/can/dev.h>
26*4882a593Smuzhiyun #include <linux/can/error.h>
27*4882a593Smuzhiyun #include <linux/can/led.h>
28*4882a593Smuzhiyun #include <linux/reset.h>
29*4882a593Smuzhiyun #include <linux/pm_runtime.h>
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun /* registers definition */
32*4882a593Smuzhiyun enum rockchip_canfd_reg {
33*4882a593Smuzhiyun CAN_MODE = 0x00,
34*4882a593Smuzhiyun CAN_CMD = 0x04,
35*4882a593Smuzhiyun CAN_STATE = 0x08,
36*4882a593Smuzhiyun CAN_INT = 0x0c,
37*4882a593Smuzhiyun CAN_INT_MASK = 0x10,
38*4882a593Smuzhiyun CAN_LOSTARB_CODE = 0x28,
39*4882a593Smuzhiyun CAN_ERR_CODE = 0x2c,
40*4882a593Smuzhiyun CAN_RX_ERR_CNT = 0x34,
41*4882a593Smuzhiyun CAN_TX_ERR_CNT = 0x38,
42*4882a593Smuzhiyun CAN_IDCODE = 0x3c,
43*4882a593Smuzhiyun CAN_IDMASK = 0x40,
44*4882a593Smuzhiyun CAN_TX_CHECK_FIC = 0x50,
45*4882a593Smuzhiyun CAN_NBTP = 0x100,
46*4882a593Smuzhiyun CAN_DBTP = 0x104,
47*4882a593Smuzhiyun CAN_TDCR = 0x108,
48*4882a593Smuzhiyun CAN_TSCC = 0x10c,
49*4882a593Smuzhiyun CAN_TSCV = 0x110,
50*4882a593Smuzhiyun CAN_TXEFC = 0x114,
51*4882a593Smuzhiyun CAN_RXFC = 0x118,
52*4882a593Smuzhiyun CAN_AFC = 0x11c,
53*4882a593Smuzhiyun CAN_IDCODE0 = 0x120,
54*4882a593Smuzhiyun CAN_IDMASK0 = 0x124,
55*4882a593Smuzhiyun CAN_IDCODE1 = 0x128,
56*4882a593Smuzhiyun CAN_IDMASK1 = 0x12c,
57*4882a593Smuzhiyun CAN_IDCODE2 = 0x130,
58*4882a593Smuzhiyun CAN_IDMASK2 = 0x134,
59*4882a593Smuzhiyun CAN_IDCODE3 = 0x138,
60*4882a593Smuzhiyun CAN_IDMASK3 = 0x13c,
61*4882a593Smuzhiyun CAN_IDCODE4 = 0x140,
62*4882a593Smuzhiyun CAN_IDMASK4 = 0x144,
63*4882a593Smuzhiyun CAN_TXFIC = 0x200,
64*4882a593Smuzhiyun CAN_TXID = 0x204,
65*4882a593Smuzhiyun CAN_TXDAT0 = 0x208,
66*4882a593Smuzhiyun CAN_TXDAT1 = 0x20c,
67*4882a593Smuzhiyun CAN_TXDAT2 = 0x210,
68*4882a593Smuzhiyun CAN_TXDAT3 = 0x214,
69*4882a593Smuzhiyun CAN_TXDAT4 = 0x218,
70*4882a593Smuzhiyun CAN_TXDAT5 = 0x21c,
71*4882a593Smuzhiyun CAN_TXDAT6 = 0x220,
72*4882a593Smuzhiyun CAN_TXDAT7 = 0x224,
73*4882a593Smuzhiyun CAN_TXDAT8 = 0x228,
74*4882a593Smuzhiyun CAN_TXDAT9 = 0x22c,
75*4882a593Smuzhiyun CAN_TXDAT10 = 0x230,
76*4882a593Smuzhiyun CAN_TXDAT11 = 0x234,
77*4882a593Smuzhiyun CAN_TXDAT12 = 0x238,
78*4882a593Smuzhiyun CAN_TXDAT13 = 0x23c,
79*4882a593Smuzhiyun CAN_TXDAT14 = 0x240,
80*4882a593Smuzhiyun CAN_TXDAT15 = 0x244,
81*4882a593Smuzhiyun CAN_RXFIC = 0x300,
82*4882a593Smuzhiyun CAN_RXID = 0x304,
83*4882a593Smuzhiyun CAN_RXTS = 0x308,
84*4882a593Smuzhiyun CAN_RXDAT0 = 0x30c,
85*4882a593Smuzhiyun CAN_RXDAT1 = 0x310,
86*4882a593Smuzhiyun CAN_RXDAT2 = 0x314,
87*4882a593Smuzhiyun CAN_RXDAT3 = 0x318,
88*4882a593Smuzhiyun CAN_RXDAT4 = 0x31c,
89*4882a593Smuzhiyun CAN_RXDAT5 = 0x320,
90*4882a593Smuzhiyun CAN_RXDAT6 = 0x324,
91*4882a593Smuzhiyun CAN_RXDAT7 = 0x328,
92*4882a593Smuzhiyun CAN_RXDAT8 = 0x32c,
93*4882a593Smuzhiyun CAN_RXDAT9 = 0x330,
94*4882a593Smuzhiyun CAN_RXDAT10 = 0x334,
95*4882a593Smuzhiyun CAN_RXDAT11 = 0x338,
96*4882a593Smuzhiyun CAN_RXDAT12 = 0x33c,
97*4882a593Smuzhiyun CAN_RXDAT13 = 0x340,
98*4882a593Smuzhiyun CAN_RXDAT14 = 0x344,
99*4882a593Smuzhiyun CAN_RXDAT15 = 0x348,
100*4882a593Smuzhiyun CAN_RXFRD = 0x400,
101*4882a593Smuzhiyun CAN_TXEFRD = 0x500,
102*4882a593Smuzhiyun };
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun enum {
105*4882a593Smuzhiyun ROCKCHIP_CANFD_MODE = 0,
106*4882a593Smuzhiyun ROCKCHIP_CAN_MODE,
107*4882a593Smuzhiyun ROCKCHIP_RK3568_CAN_MODE,
108*4882a593Smuzhiyun };
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun #define DATE_LENGTH_12_BYTE (0x9)
111*4882a593Smuzhiyun #define DATE_LENGTH_16_BYTE (0xa)
112*4882a593Smuzhiyun #define DATE_LENGTH_20_BYTE (0xb)
113*4882a593Smuzhiyun #define DATE_LENGTH_24_BYTE (0xc)
114*4882a593Smuzhiyun #define DATE_LENGTH_32_BYTE (0xd)
115*4882a593Smuzhiyun #define DATE_LENGTH_48_BYTE (0xe)
116*4882a593Smuzhiyun #define DATE_LENGTH_64_BYTE (0xf)
117*4882a593Smuzhiyun
118*4882a593Smuzhiyun #define CAN_TX0_REQ BIT(0)
119*4882a593Smuzhiyun #define CAN_TX1_REQ BIT(1)
120*4882a593Smuzhiyun #define CAN_TX_REQ_FULL ((CAN_TX0_REQ) | (CAN_TX1_REQ))
121*4882a593Smuzhiyun
122*4882a593Smuzhiyun #define MODE_FDOE BIT(15)
123*4882a593Smuzhiyun #define MODE_BRSD BIT(13)
124*4882a593Smuzhiyun #define MODE_SPACE_RX BIT(12)
125*4882a593Smuzhiyun #define MODE_AUTO_RETX BIT(10)
126*4882a593Smuzhiyun #define MODE_RXSORT BIT(7)
127*4882a593Smuzhiyun #define MODE_TXORDER BIT(6)
128*4882a593Smuzhiyun #define MODE_RXSTX BIT(5)
129*4882a593Smuzhiyun #define MODE_LBACK BIT(4)
130*4882a593Smuzhiyun #define MODE_SILENT BIT(3)
131*4882a593Smuzhiyun #define MODE_SELF_TEST BIT(2)
132*4882a593Smuzhiyun #define MODE_SLEEP BIT(1)
133*4882a593Smuzhiyun #define RESET_MODE 0
134*4882a593Smuzhiyun #define WORK_MODE BIT(0)
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun #define RX_FINISH_INT BIT(0)
137*4882a593Smuzhiyun #define TX_FINISH_INT BIT(1)
138*4882a593Smuzhiyun #define ERR_WARN_INT BIT(2)
139*4882a593Smuzhiyun #define RX_BUF_OV_INT BIT(3)
140*4882a593Smuzhiyun #define PASSIVE_ERR_INT BIT(4)
141*4882a593Smuzhiyun #define TX_LOSTARB_INT BIT(5)
142*4882a593Smuzhiyun #define BUS_ERR_INT BIT(6)
143*4882a593Smuzhiyun #define RX_FIFO_FULL_INT BIT(7)
144*4882a593Smuzhiyun #define RX_FIFO_OV_INT BIT(8)
145*4882a593Smuzhiyun #define BUS_OFF_INT BIT(9)
146*4882a593Smuzhiyun #define BUS_OFF_RECOVERY_INT BIT(10)
147*4882a593Smuzhiyun #define TSC_OV_INT BIT(11)
148*4882a593Smuzhiyun #define TXE_FIFO_OV_INT BIT(12)
149*4882a593Smuzhiyun #define TXE_FIFO_FULL_INT BIT(13)
150*4882a593Smuzhiyun #define WAKEUP_INT BIT(14)
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun #define ERR_TYPE_MASK GENMASK(28, 26)
153*4882a593Smuzhiyun #define ERR_TYPE_SHIFT 26
154*4882a593Smuzhiyun #define BIT_ERR 0
155*4882a593Smuzhiyun #define STUFF_ERR 1
156*4882a593Smuzhiyun #define FORM_ERR 2
157*4882a593Smuzhiyun #define ACK_ERR 3
158*4882a593Smuzhiyun #define CRC_ERR 4
159*4882a593Smuzhiyun #define ERR_DIR_RX BIT(25)
160*4882a593Smuzhiyun #define ERR_LOC_MASK GENMASK(15, 0)
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun /* Nominal Bit Timing & Prescaler Register (NBTP) */
163*4882a593Smuzhiyun #define NBTP_MODE_3_SAMPLES BIT(31)
164*4882a593Smuzhiyun #define NBTP_NSJW_SHIFT 24
165*4882a593Smuzhiyun #define NBTP_NSJW_MASK (0x7f << NBTP_NSJW_SHIFT)
166*4882a593Smuzhiyun #define NBTP_NBRP_SHIFT 16
167*4882a593Smuzhiyun #define NBTP_NBRP_MASK (0xff << NBTP_NBRP_SHIFT)
168*4882a593Smuzhiyun #define NBTP_NTSEG2_SHIFT 8
169*4882a593Smuzhiyun #define NBTP_NTSEG2_MASK (0x7f << NBTP_NTSEG2_SHIFT)
170*4882a593Smuzhiyun #define NBTP_NTSEG1_SHIFT 0
171*4882a593Smuzhiyun #define NBTP_NTSEG1_MASK (0x7f << NBTP_NTSEG1_SHIFT)
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun /* Data Bit Timing & Prescaler Register (DBTP) */
174*4882a593Smuzhiyun #define DBTP_MODE_3_SAMPLES BIT(21)
175*4882a593Smuzhiyun #define DBTP_DSJW_SHIFT 17
176*4882a593Smuzhiyun #define DBTP_DSJW_MASK (0xf << DBTP_DSJW_SHIFT)
177*4882a593Smuzhiyun #define DBTP_DBRP_SHIFT 9
178*4882a593Smuzhiyun #define DBTP_DBRP_MASK (0xff << DBTP_DBRP_SHIFT)
179*4882a593Smuzhiyun #define DBTP_DTSEG2_SHIFT 5
180*4882a593Smuzhiyun #define DBTP_DTSEG2_MASK (0xf << DBTP_DTSEG2_SHIFT)
181*4882a593Smuzhiyun #define DBTP_DTSEG1_SHIFT 0
182*4882a593Smuzhiyun #define DBTP_DTSEG1_MASK (0x1f << DBTP_DTSEG1_SHIFT)
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun /* Transmitter Delay Compensation Register (TDCR) */
185*4882a593Smuzhiyun #define TDCR_TDCO_SHIFT 1
186*4882a593Smuzhiyun #define TDCR_TDCO_MASK (0x3f << TDCR_TDCO_SHIFT)
187*4882a593Smuzhiyun #define TDCR_TDC_ENABLE BIT(0)
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun #define TX_FD_ENABLE BIT(5)
190*4882a593Smuzhiyun #define TX_FD_BRS_ENABLE BIT(4)
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun #define FIFO_ENABLE BIT(0)
193*4882a593Smuzhiyun #define RX_FIFO_CNT0_SHIFT 4
194*4882a593Smuzhiyun #define RX_FIFO_CNT0_MASK (0x7 << RX_FIFO_CNT0_SHIFT)
195*4882a593Smuzhiyun #define RX_FIFO_CNT1_SHIFT 5
196*4882a593Smuzhiyun #define RX_FIFO_CNT1_MASK (0x7 << RX_FIFO_CNT1_SHIFT)
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun #define FORMAT_SHIFT 7
199*4882a593Smuzhiyun #define FORMAT_MASK (0x1 << FORMAT_SHIFT)
200*4882a593Smuzhiyun #define RTR_SHIFT 6
201*4882a593Smuzhiyun #define RTR_MASK (0x1 << RTR_SHIFT)
202*4882a593Smuzhiyun #define FDF_SHIFT 5
203*4882a593Smuzhiyun #define FDF_MASK (0x1 << FDF_SHIFT)
204*4882a593Smuzhiyun #define BRS_SHIFT 4
205*4882a593Smuzhiyun #define BRS_MASK (0x1 << BRS_SHIFT)
206*4882a593Smuzhiyun #define DLC_SHIFT 0
207*4882a593Smuzhiyun #define DLC_MASK (0xF << DLC_SHIFT)
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun #define CAN_RF_SIZE 0x48
210*4882a593Smuzhiyun #define CAN_TEF_SIZE 0x8
211*4882a593Smuzhiyun #define CAN_TXEFRD_OFFSET(n) (CAN_TXEFRD + CAN_TEF_SIZE * (n))
212*4882a593Smuzhiyun #define CAN_RXFRD_OFFSET(n) (CAN_RXFRD + CAN_RF_SIZE * (n))
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun #define CAN_RX_FILTER_MASK 0x1fffffff
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun #define DRV_NAME "forlinx_canfd"
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun /* rockchip_canfd private data structure */
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun struct rockchip_canfd {
221*4882a593Smuzhiyun struct can_priv can;
222*4882a593Smuzhiyun struct device *dev;
223*4882a593Smuzhiyun struct clk_bulk_data *clks;
224*4882a593Smuzhiyun int num_clks;
225*4882a593Smuzhiyun struct reset_control *reset;
226*4882a593Smuzhiyun void __iomem *base;
227*4882a593Smuzhiyun u32 irqstatus;
228*4882a593Smuzhiyun unsigned long mode;
229*4882a593Smuzhiyun int rx_fifo_shift;
230*4882a593Smuzhiyun u32 rx_fifo_mask;
231*4882a593Smuzhiyun bool txtorx;
232*4882a593Smuzhiyun u32 tx_invalid[4];
233*4882a593Smuzhiyun struct delayed_work tx_err_work;
234*4882a593Smuzhiyun };
235*4882a593Smuzhiyun
rockchip_canfd_read(const struct rockchip_canfd * priv,enum rockchip_canfd_reg reg)236*4882a593Smuzhiyun static inline u32 rockchip_canfd_read(const struct rockchip_canfd *priv,
237*4882a593Smuzhiyun enum rockchip_canfd_reg reg)
238*4882a593Smuzhiyun {
239*4882a593Smuzhiyun return readl(priv->base + reg);
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun
rockchip_canfd_write(const struct rockchip_canfd * priv,enum rockchip_canfd_reg reg,u32 val)242*4882a593Smuzhiyun static inline void rockchip_canfd_write(const struct rockchip_canfd *priv,
243*4882a593Smuzhiyun enum rockchip_canfd_reg reg, u32 val)
244*4882a593Smuzhiyun {
245*4882a593Smuzhiyun writel(val, priv->base + reg);
246*4882a593Smuzhiyun }
247*4882a593Smuzhiyun
248*4882a593Smuzhiyun static const struct can_bittiming_const rockchip_canfd_bittiming_const = {
249*4882a593Smuzhiyun .name = DRV_NAME,
250*4882a593Smuzhiyun .tseg1_min = 1,
251*4882a593Smuzhiyun .tseg1_max = 128,
252*4882a593Smuzhiyun .tseg2_min = 1,
253*4882a593Smuzhiyun .tseg2_max = 128,
254*4882a593Smuzhiyun .sjw_max = 128,
255*4882a593Smuzhiyun .brp_min = 1,
256*4882a593Smuzhiyun .brp_max = 256,
257*4882a593Smuzhiyun .brp_inc = 2,
258*4882a593Smuzhiyun };
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun static const struct can_bittiming_const rockchip_canfd_data_bittiming_const = {
261*4882a593Smuzhiyun .name = DRV_NAME,
262*4882a593Smuzhiyun .tseg1_min = 1,
263*4882a593Smuzhiyun .tseg1_max = 32,
264*4882a593Smuzhiyun .tseg2_min = 1,
265*4882a593Smuzhiyun .tseg2_max = 16,
266*4882a593Smuzhiyun .sjw_max = 16,
267*4882a593Smuzhiyun .brp_min = 1,
268*4882a593Smuzhiyun .brp_max = 256,
269*4882a593Smuzhiyun .brp_inc = 2,
270*4882a593Smuzhiyun };
271*4882a593Smuzhiyun
set_reset_mode(struct net_device * ndev)272*4882a593Smuzhiyun static int set_reset_mode(struct net_device *ndev)
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun struct rockchip_canfd *rcan = netdev_priv(ndev);
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun reset_control_assert(rcan->reset);
277*4882a593Smuzhiyun udelay(2);
278*4882a593Smuzhiyun reset_control_deassert(rcan->reset);
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_MODE, 0);
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun netdev_dbg(ndev, "%s MODE=0x%08x\n", __func__,
283*4882a593Smuzhiyun rockchip_canfd_read(rcan, CAN_MODE));
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun return 0;
286*4882a593Smuzhiyun }
287*4882a593Smuzhiyun
set_normal_mode(struct net_device * ndev)288*4882a593Smuzhiyun static int set_normal_mode(struct net_device *ndev)
289*4882a593Smuzhiyun {
290*4882a593Smuzhiyun struct rockchip_canfd *rcan = netdev_priv(ndev);
291*4882a593Smuzhiyun u32 val;
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun val = rockchip_canfd_read(rcan, CAN_MODE);
294*4882a593Smuzhiyun val |= WORK_MODE;
295*4882a593Smuzhiyun if (rcan->mode >= ROCKCHIP_CAN_MODE && rcan->txtorx)
296*4882a593Smuzhiyun val |= MODE_RXSTX;
297*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_MODE, val);
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun netdev_dbg(ndev, "%s MODE=0x%08x\n", __func__,
300*4882a593Smuzhiyun rockchip_canfd_read(rcan, CAN_MODE));
301*4882a593Smuzhiyun return 0;
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun /* bittiming is called in reset_mode only */
rockchip_canfd_set_bittiming(struct net_device * ndev)305*4882a593Smuzhiyun static int rockchip_canfd_set_bittiming(struct net_device *ndev)
306*4882a593Smuzhiyun {
307*4882a593Smuzhiyun struct rockchip_canfd *rcan = netdev_priv(ndev);
308*4882a593Smuzhiyun const struct can_bittiming *bt = &rcan->can.bittiming;
309*4882a593Smuzhiyun const struct can_bittiming *dbt = &rcan->can.data_bittiming;
310*4882a593Smuzhiyun u16 brp, sjw, tseg1, tseg2;
311*4882a593Smuzhiyun u32 reg_btp;
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun brp = (bt->brp >> 1) - 1;
314*4882a593Smuzhiyun sjw = bt->sjw - 1;
315*4882a593Smuzhiyun tseg1 = bt->prop_seg + bt->phase_seg1 - 1;
316*4882a593Smuzhiyun tseg2 = bt->phase_seg2 - 1;
317*4882a593Smuzhiyun reg_btp = (brp << NBTP_NBRP_SHIFT) | (sjw << NBTP_NSJW_SHIFT) |
318*4882a593Smuzhiyun (tseg1 << NBTP_NTSEG1_SHIFT) |
319*4882a593Smuzhiyun (tseg2 << NBTP_NTSEG2_SHIFT);
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun if (rcan->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
322*4882a593Smuzhiyun reg_btp |= NBTP_MODE_3_SAMPLES;
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_NBTP, reg_btp);
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun if (rcan->can.ctrlmode & CAN_CTRLMODE_FD) {
327*4882a593Smuzhiyun reg_btp = 0;
328*4882a593Smuzhiyun brp = (dbt->brp >> 1) - 1;
329*4882a593Smuzhiyun sjw = dbt->sjw - 1;
330*4882a593Smuzhiyun tseg1 = dbt->prop_seg + dbt->phase_seg1 - 1;
331*4882a593Smuzhiyun tseg2 = dbt->phase_seg2 - 1;
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun if (dbt->bitrate > 2200000) {
334*4882a593Smuzhiyun u32 tdco;
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun /* Equation based on Bosch's ROCKCHIP_CAN User Manual's
337*4882a593Smuzhiyun * Transmitter Delay Compensation Section
338*4882a593Smuzhiyun */
339*4882a593Smuzhiyun tdco = (rcan->can.clock.freq / dbt->bitrate) * 2 / 3;
340*4882a593Smuzhiyun /* Max valid TDCO value is 63 */
341*4882a593Smuzhiyun if (tdco > 63)
342*4882a593Smuzhiyun tdco = 63;
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_TDCR,
345*4882a593Smuzhiyun (tdco << TDCR_TDCO_SHIFT) |
346*4882a593Smuzhiyun TDCR_TDC_ENABLE);
347*4882a593Smuzhiyun }
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun reg_btp |= (brp << DBTP_DBRP_SHIFT) |
350*4882a593Smuzhiyun (sjw << DBTP_DSJW_SHIFT) |
351*4882a593Smuzhiyun (tseg1 << DBTP_DTSEG1_SHIFT) |
352*4882a593Smuzhiyun (tseg2 << DBTP_DTSEG2_SHIFT);
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun if (rcan->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
355*4882a593Smuzhiyun reg_btp |= DBTP_MODE_3_SAMPLES;
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_DBTP, reg_btp);
358*4882a593Smuzhiyun }
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun netdev_dbg(ndev, "%s NBTP=0x%08x, DBTP=0x%08x, TDCR=0x%08x\n", __func__,
361*4882a593Smuzhiyun rockchip_canfd_read(rcan, CAN_NBTP),
362*4882a593Smuzhiyun rockchip_canfd_read(rcan, CAN_DBTP),
363*4882a593Smuzhiyun rockchip_canfd_read(rcan, CAN_TDCR));
364*4882a593Smuzhiyun return 0;
365*4882a593Smuzhiyun }
366*4882a593Smuzhiyun
rockchip_canfd_get_berr_counter(const struct net_device * ndev,struct can_berr_counter * bec)367*4882a593Smuzhiyun static int rockchip_canfd_get_berr_counter(const struct net_device *ndev,
368*4882a593Smuzhiyun struct can_berr_counter *bec)
369*4882a593Smuzhiyun {
370*4882a593Smuzhiyun struct rockchip_canfd *rcan = netdev_priv(ndev);
371*4882a593Smuzhiyun int err;
372*4882a593Smuzhiyun
373*4882a593Smuzhiyun err = pm_runtime_get_sync(rcan->dev);
374*4882a593Smuzhiyun if (err < 0) {
375*4882a593Smuzhiyun netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n",
376*4882a593Smuzhiyun __func__, err);
377*4882a593Smuzhiyun return err;
378*4882a593Smuzhiyun }
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun bec->rxerr = rockchip_canfd_read(rcan, CAN_RX_ERR_CNT);
381*4882a593Smuzhiyun bec->txerr = rockchip_canfd_read(rcan, CAN_TX_ERR_CNT);
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun pm_runtime_put(rcan->dev);
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun netdev_dbg(ndev, "%s RX_ERR_CNT=0x%08x, TX_ERR_CNT=0x%08x\n", __func__,
386*4882a593Smuzhiyun rockchip_canfd_read(rcan, CAN_RX_ERR_CNT),
387*4882a593Smuzhiyun rockchip_canfd_read(rcan, CAN_TX_ERR_CNT));
388*4882a593Smuzhiyun
389*4882a593Smuzhiyun return 0;
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
rockchip_canfd_start(struct net_device * ndev)392*4882a593Smuzhiyun static int rockchip_canfd_start(struct net_device *ndev)
393*4882a593Smuzhiyun {
394*4882a593Smuzhiyun struct rockchip_canfd *rcan = netdev_priv(ndev);
395*4882a593Smuzhiyun u32 val;
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun /* we need to enter the reset mode */
398*4882a593Smuzhiyun set_reset_mode(ndev);
399*4882a593Smuzhiyun
400*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_INT_MASK, 0);
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun /* RECEIVING FILTER, accept all */
403*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_IDCODE, 0);
404*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_IDMASK, CAN_RX_FILTER_MASK);
405*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_IDCODE0, 0);
406*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_IDMASK0, CAN_RX_FILTER_MASK);
407*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_IDCODE1, 0);
408*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_IDMASK1, CAN_RX_FILTER_MASK);
409*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_IDCODE2, 0);
410*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_IDMASK2, CAN_RX_FILTER_MASK);
411*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_IDCODE3, 0);
412*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_IDMASK3, CAN_RX_FILTER_MASK);
413*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_IDCODE4, 0);
414*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_IDMASK4, CAN_RX_FILTER_MASK);
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun /* set mode */
417*4882a593Smuzhiyun val = rockchip_canfd_read(rcan, CAN_MODE);
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun /* rx fifo enable */
420*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_RXFC,
421*4882a593Smuzhiyun rockchip_canfd_read(rcan, CAN_RXFC) | FIFO_ENABLE);
422*4882a593Smuzhiyun
423*4882a593Smuzhiyun /* Mode */
424*4882a593Smuzhiyun val |= MODE_FDOE;
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun /* Loopback Mode */
427*4882a593Smuzhiyun if (rcan->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
428*4882a593Smuzhiyun val |= MODE_SELF_TEST | MODE_LBACK;
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun val |= MODE_AUTO_RETX;
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_MODE, val);
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun rockchip_canfd_set_bittiming(ndev);
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun set_normal_mode(ndev);
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun rcan->can.state = CAN_STATE_ERROR_ACTIVE;
439*4882a593Smuzhiyun
440*4882a593Smuzhiyun netdev_dbg(ndev, "%s MODE=0x%08x, INT_MASK=0x%08x\n", __func__,
441*4882a593Smuzhiyun rockchip_canfd_read(rcan, CAN_MODE),
442*4882a593Smuzhiyun rockchip_canfd_read(rcan, CAN_INT_MASK));
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun return 0;
445*4882a593Smuzhiyun }
446*4882a593Smuzhiyun
rockchip_canfd_stop(struct net_device * ndev)447*4882a593Smuzhiyun static int rockchip_canfd_stop(struct net_device *ndev)
448*4882a593Smuzhiyun {
449*4882a593Smuzhiyun struct rockchip_canfd *rcan = netdev_priv(ndev);
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun rcan->can.state = CAN_STATE_STOPPED;
452*4882a593Smuzhiyun /* we need to enter reset mode */
453*4882a593Smuzhiyun set_reset_mode(ndev);
454*4882a593Smuzhiyun
455*4882a593Smuzhiyun /* disable all interrupts */
456*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_INT_MASK, 0xffff);
457*4882a593Smuzhiyun
458*4882a593Smuzhiyun netdev_dbg(ndev, "%s MODE=0x%08x, INT_MASK=0x%08x\n", __func__,
459*4882a593Smuzhiyun rockchip_canfd_read(rcan, CAN_MODE),
460*4882a593Smuzhiyun rockchip_canfd_read(rcan, CAN_INT_MASK));
461*4882a593Smuzhiyun return 0;
462*4882a593Smuzhiyun }
463*4882a593Smuzhiyun
rockchip_canfd_set_mode(struct net_device * ndev,enum can_mode mode)464*4882a593Smuzhiyun static int rockchip_canfd_set_mode(struct net_device *ndev,
465*4882a593Smuzhiyun enum can_mode mode)
466*4882a593Smuzhiyun {
467*4882a593Smuzhiyun int err;
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun switch (mode) {
470*4882a593Smuzhiyun case CAN_MODE_START:
471*4882a593Smuzhiyun err = rockchip_canfd_start(ndev);
472*4882a593Smuzhiyun if (err) {
473*4882a593Smuzhiyun netdev_err(ndev, "starting CAN controller failed!\n");
474*4882a593Smuzhiyun return err;
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun if (netif_queue_stopped(ndev))
477*4882a593Smuzhiyun netif_wake_queue(ndev);
478*4882a593Smuzhiyun break;
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun default:
481*4882a593Smuzhiyun return -EOPNOTSUPP;
482*4882a593Smuzhiyun }
483*4882a593Smuzhiyun
484*4882a593Smuzhiyun return 0;
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun
rockchip_canfd_tx_err_delay_work(struct work_struct * work)487*4882a593Smuzhiyun static void rockchip_canfd_tx_err_delay_work(struct work_struct *work)
488*4882a593Smuzhiyun {
489*4882a593Smuzhiyun struct rockchip_canfd *rcan =
490*4882a593Smuzhiyun container_of(work, struct rockchip_canfd, tx_err_work.work);
491*4882a593Smuzhiyun u32 mode, err_code, id;
492*4882a593Smuzhiyun
493*4882a593Smuzhiyun id = rockchip_canfd_read(rcan, CAN_TXID);
494*4882a593Smuzhiyun err_code = rockchip_canfd_read(rcan, CAN_ERR_CODE);
495*4882a593Smuzhiyun if (err_code & 0x1fe0000) {
496*4882a593Smuzhiyun mode = rockchip_canfd_read(rcan, CAN_MODE);
497*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_MODE, 0);
498*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_MODE, mode);
499*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_CMD, CAN_TX0_REQ);
500*4882a593Smuzhiyun schedule_delayed_work(&rcan->tx_err_work, 1);
501*4882a593Smuzhiyun } else if (rcan->txtorx && rcan->mode >= ROCKCHIP_CAN_MODE && id & CAN_EFF_FLAG) {
502*4882a593Smuzhiyun schedule_delayed_work(&rcan->tx_err_work, 1);
503*4882a593Smuzhiyun }
504*4882a593Smuzhiyun }
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun /* transmit a CAN message
507*4882a593Smuzhiyun * message layout in the sk_buff should be like this:
508*4882a593Smuzhiyun * xx xx xx xx ff ll 00 11 22 33 44 55 66 77
509*4882a593Smuzhiyun * [ can_id ] [flags] [len] [can data (up to 8 bytes]
510*4882a593Smuzhiyun */
rockchip_canfd_start_xmit(struct sk_buff * skb,struct net_device * ndev)511*4882a593Smuzhiyun static int rockchip_canfd_start_xmit(struct sk_buff *skb,
512*4882a593Smuzhiyun struct net_device *ndev)
513*4882a593Smuzhiyun {
514*4882a593Smuzhiyun struct rockchip_canfd *rcan = netdev_priv(ndev);
515*4882a593Smuzhiyun struct canfd_frame *cf = (struct canfd_frame *)skb->data;
516*4882a593Smuzhiyun u32 id, dlc;
517*4882a593Smuzhiyun u32 cmd = CAN_TX0_REQ;
518*4882a593Smuzhiyun int i;
519*4882a593Smuzhiyun unsigned long flags;
520*4882a593Smuzhiyun
521*4882a593Smuzhiyun if (can_dropped_invalid_skb(ndev, skb))
522*4882a593Smuzhiyun return NETDEV_TX_OK;
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun netif_stop_queue(ndev);
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun if (rockchip_canfd_read(rcan, CAN_CMD) & CAN_TX0_REQ)
527*4882a593Smuzhiyun cmd = CAN_TX1_REQ;
528*4882a593Smuzhiyun
529*4882a593Smuzhiyun /* Watch carefully on the bit sequence */
530*4882a593Smuzhiyun if (cf->can_id & CAN_EFF_FLAG) {
531*4882a593Smuzhiyun /* Extended CAN ID format */
532*4882a593Smuzhiyun id = cf->can_id & CAN_EFF_MASK;
533*4882a593Smuzhiyun dlc = can_len2dlc(cf->len) & DLC_MASK;
534*4882a593Smuzhiyun dlc |= FORMAT_MASK;
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun /* Extended frames remote TX request */
537*4882a593Smuzhiyun if (cf->can_id & CAN_RTR_FLAG)
538*4882a593Smuzhiyun dlc |= RTR_MASK;
539*4882a593Smuzhiyun } else {
540*4882a593Smuzhiyun /* Standard CAN ID format */
541*4882a593Smuzhiyun id = cf->can_id & CAN_SFF_MASK;
542*4882a593Smuzhiyun dlc = can_len2dlc(cf->len) & DLC_MASK;
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun /* Standard frames remote TX request */
545*4882a593Smuzhiyun if (cf->can_id & CAN_RTR_FLAG)
546*4882a593Smuzhiyun dlc |= RTR_MASK;
547*4882a593Smuzhiyun }
548*4882a593Smuzhiyun
549*4882a593Smuzhiyun if ((rcan->can.ctrlmode & CAN_CTRLMODE_FD) && can_is_canfd_skb(skb)) {
550*4882a593Smuzhiyun dlc |= TX_FD_ENABLE;
551*4882a593Smuzhiyun if (cf->flags & CANFD_BRS)
552*4882a593Smuzhiyun dlc |= TX_FD_BRS_ENABLE;
553*4882a593Smuzhiyun }
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun if (!rcan->txtorx && rcan->mode >= ROCKCHIP_CAN_MODE && cf->can_id & CAN_EFF_FLAG) {
556*4882a593Smuzhiyun /* Two frames are sent consecutively.
557*4882a593Smuzhiyun * Before the first frame is tx finished,
558*4882a593Smuzhiyun * the register of the second frame is configured.
559*4882a593Smuzhiyun * Don't be interrupted in the middle.
560*4882a593Smuzhiyun */
561*4882a593Smuzhiyun local_irq_save(flags);
562*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_TXID, rcan->tx_invalid[1]);
563*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_TXFIC, rcan->tx_invalid[0]);
564*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_TXDAT0, rcan->tx_invalid[2]);
565*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_TXDAT1, rcan->tx_invalid[3]);
566*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_CMD, CAN_TX0_REQ);
567*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_TXID, id);
568*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_TXFIC, dlc);
569*4882a593Smuzhiyun for (i = 0; i < cf->len; i += 4)
570*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_TXDAT0 + i,
571*4882a593Smuzhiyun *(u32 *)(cf->data + i));
572*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_CMD, CAN_TX1_REQ);
573*4882a593Smuzhiyun local_irq_restore(flags);
574*4882a593Smuzhiyun can_put_echo_skb(skb, ndev, 0);
575*4882a593Smuzhiyun
576*4882a593Smuzhiyun return NETDEV_TX_OK;
577*4882a593Smuzhiyun }
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_TXID, id);
580*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_TXFIC, dlc);
581*4882a593Smuzhiyun
582*4882a593Smuzhiyun for (i = 0; i < cf->len; i += 4)
583*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_TXDAT0 + i,
584*4882a593Smuzhiyun *(u32 *)(cf->data + i));
585*4882a593Smuzhiyun
586*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_CMD, CAN_TX1_REQ);
587*4882a593Smuzhiyun
588*4882a593Smuzhiyun if (rcan->txtorx && rcan->mode >= ROCKCHIP_CAN_MODE && cf->can_id & CAN_EFF_FLAG)
589*4882a593Smuzhiyun schedule_delayed_work(&rcan->tx_err_work, 1);
590*4882a593Smuzhiyun
591*4882a593Smuzhiyun can_put_echo_skb(skb, ndev, 0);
592*4882a593Smuzhiyun
593*4882a593Smuzhiyun return NETDEV_TX_OK;
594*4882a593Smuzhiyun }
595*4882a593Smuzhiyun
rockchip_canfd_rx(struct net_device * ndev)596*4882a593Smuzhiyun static int rockchip_canfd_rx(struct net_device *ndev)
597*4882a593Smuzhiyun {
598*4882a593Smuzhiyun struct rockchip_canfd *rcan = netdev_priv(ndev);
599*4882a593Smuzhiyun struct net_device_stats *stats = &ndev->stats;
600*4882a593Smuzhiyun struct canfd_frame *cf;
601*4882a593Smuzhiyun struct sk_buff *skb;
602*4882a593Smuzhiyun u32 id_rockchip_canfd, dlc;
603*4882a593Smuzhiyun int i = 0;
604*4882a593Smuzhiyun u32 __maybe_unused ts, ret;
605*4882a593Smuzhiyun u32 data[16] = {0};
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun dlc = rockchip_canfd_read(rcan, CAN_RXFRD);
608*4882a593Smuzhiyun id_rockchip_canfd = rockchip_canfd_read(rcan, CAN_RXFRD);
609*4882a593Smuzhiyun ts = rockchip_canfd_read(rcan, CAN_RXFRD);
610*4882a593Smuzhiyun for (i = 0; i < 16; i++)
611*4882a593Smuzhiyun data[i] = rockchip_canfd_read(rcan, CAN_RXFRD);
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun if (rcan->mode >= ROCKCHIP_CAN_MODE) {
614*4882a593Smuzhiyun /* may be an empty frame */
615*4882a593Smuzhiyun if (!dlc && !id_rockchip_canfd)
616*4882a593Smuzhiyun return 1;
617*4882a593Smuzhiyun
618*4882a593Smuzhiyun if (rcan->txtorx) {
619*4882a593Smuzhiyun if (rockchip_canfd_read(rcan, CAN_TX_CHECK_FIC) & FORMAT_MASK) {
620*4882a593Smuzhiyun ret = rockchip_canfd_read(rcan, CAN_TXID) & CAN_SFF_MASK;
621*4882a593Smuzhiyun if (id_rockchip_canfd == ret) {
622*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_TX_CHECK_FIC,
623*4882a593Smuzhiyun ts | CAN_TX0_REQ);
624*4882a593Smuzhiyun return 1;
625*4882a593Smuzhiyun }
626*4882a593Smuzhiyun }
627*4882a593Smuzhiyun }
628*4882a593Smuzhiyun }
629*4882a593Smuzhiyun
630*4882a593Smuzhiyun /* create zero'ed CAN frame buffer */
631*4882a593Smuzhiyun if (dlc & FDF_MASK)
632*4882a593Smuzhiyun skb = alloc_canfd_skb(ndev, &cf);
633*4882a593Smuzhiyun else
634*4882a593Smuzhiyun skb = alloc_can_skb(ndev, (struct can_frame **)&cf);
635*4882a593Smuzhiyun if (!skb) {
636*4882a593Smuzhiyun stats->rx_dropped++;
637*4882a593Smuzhiyun return 1;
638*4882a593Smuzhiyun }
639*4882a593Smuzhiyun
640*4882a593Smuzhiyun /* Change CAN data length format to socketCAN data format */
641*4882a593Smuzhiyun if (dlc & FDF_MASK)
642*4882a593Smuzhiyun cf->len = can_dlc2len(dlc & DLC_MASK);
643*4882a593Smuzhiyun else
644*4882a593Smuzhiyun cf->len = get_can_dlc(dlc & DLC_MASK);
645*4882a593Smuzhiyun
646*4882a593Smuzhiyun /* Change CAN ID format to socketCAN ID format */
647*4882a593Smuzhiyun if (dlc & FORMAT_MASK) {
648*4882a593Smuzhiyun /* The received frame is an Extended format frame */
649*4882a593Smuzhiyun cf->can_id = id_rockchip_canfd;
650*4882a593Smuzhiyun cf->can_id |= CAN_EFF_FLAG;
651*4882a593Smuzhiyun if (dlc & RTR_MASK)
652*4882a593Smuzhiyun cf->can_id |= CAN_RTR_FLAG;
653*4882a593Smuzhiyun } else {
654*4882a593Smuzhiyun /* The received frame is a standard format frame */
655*4882a593Smuzhiyun cf->can_id = id_rockchip_canfd;
656*4882a593Smuzhiyun if (dlc & RTR_MASK)
657*4882a593Smuzhiyun cf->can_id |= CAN_RTR_FLAG;
658*4882a593Smuzhiyun }
659*4882a593Smuzhiyun
660*4882a593Smuzhiyun if (dlc & BRS_MASK)
661*4882a593Smuzhiyun cf->flags |= CANFD_BRS;
662*4882a593Smuzhiyun
663*4882a593Smuzhiyun if (!(cf->can_id & CAN_RTR_FLAG)) {
664*4882a593Smuzhiyun /* Change CAN data format to socketCAN data format */
665*4882a593Smuzhiyun for (i = 0; i < cf->len; i += 4)
666*4882a593Smuzhiyun *(u32 *)(cf->data + i) = data[i / 4];
667*4882a593Smuzhiyun }
668*4882a593Smuzhiyun
669*4882a593Smuzhiyun stats->rx_packets++;
670*4882a593Smuzhiyun stats->rx_bytes += cf->len;
671*4882a593Smuzhiyun netif_rx(skb);
672*4882a593Smuzhiyun
673*4882a593Smuzhiyun can_led_event(ndev, CAN_LED_EVENT_RX);
674*4882a593Smuzhiyun
675*4882a593Smuzhiyun return 1;
676*4882a593Smuzhiyun }
677*4882a593Smuzhiyun
rockchip_canfd_err(struct net_device * ndev,u32 isr)678*4882a593Smuzhiyun static int rockchip_canfd_err(struct net_device *ndev, u32 isr)
679*4882a593Smuzhiyun {
680*4882a593Smuzhiyun struct rockchip_canfd *rcan = netdev_priv(ndev);
681*4882a593Smuzhiyun struct net_device_stats *stats = &ndev->stats;
682*4882a593Smuzhiyun struct can_frame *cf;
683*4882a593Smuzhiyun struct sk_buff *skb;
684*4882a593Smuzhiyun unsigned int rxerr, txerr;
685*4882a593Smuzhiyun u32 sta_reg;
686*4882a593Smuzhiyun
687*4882a593Smuzhiyun skb = alloc_can_err_skb(ndev, &cf);
688*4882a593Smuzhiyun
689*4882a593Smuzhiyun rxerr = rockchip_canfd_read(rcan, CAN_RX_ERR_CNT);
690*4882a593Smuzhiyun txerr = rockchip_canfd_read(rcan, CAN_TX_ERR_CNT);
691*4882a593Smuzhiyun sta_reg = rockchip_canfd_read(rcan, CAN_STATE);
692*4882a593Smuzhiyun
693*4882a593Smuzhiyun if (skb) {
694*4882a593Smuzhiyun cf->data[6] = txerr;
695*4882a593Smuzhiyun cf->data[7] = rxerr;
696*4882a593Smuzhiyun }
697*4882a593Smuzhiyun
698*4882a593Smuzhiyun if (isr & BUS_OFF_INT) {
699*4882a593Smuzhiyun rcan->can.state = CAN_STATE_BUS_OFF;
700*4882a593Smuzhiyun rcan->can.can_stats.bus_off++;
701*4882a593Smuzhiyun cf->can_id |= CAN_ERR_BUSOFF;
702*4882a593Smuzhiyun } else if (isr & ERR_WARN_INT) {
703*4882a593Smuzhiyun rcan->can.can_stats.error_warning++;
704*4882a593Smuzhiyun rcan->can.state = CAN_STATE_ERROR_WARNING;
705*4882a593Smuzhiyun /* error warning state */
706*4882a593Smuzhiyun if (likely(skb)) {
707*4882a593Smuzhiyun cf->can_id |= CAN_ERR_CRTL;
708*4882a593Smuzhiyun cf->data[1] = (txerr > rxerr) ?
709*4882a593Smuzhiyun CAN_ERR_CRTL_TX_WARNING :
710*4882a593Smuzhiyun CAN_ERR_CRTL_RX_WARNING;
711*4882a593Smuzhiyun cf->data[6] = txerr;
712*4882a593Smuzhiyun cf->data[7] = rxerr;
713*4882a593Smuzhiyun }
714*4882a593Smuzhiyun } else if (isr & PASSIVE_ERR_INT) {
715*4882a593Smuzhiyun rcan->can.can_stats.error_passive++;
716*4882a593Smuzhiyun rcan->can.state = CAN_STATE_ERROR_PASSIVE;
717*4882a593Smuzhiyun /* error passive state */
718*4882a593Smuzhiyun cf->can_id |= CAN_ERR_CRTL;
719*4882a593Smuzhiyun cf->data[1] = (txerr > rxerr) ?
720*4882a593Smuzhiyun CAN_ERR_CRTL_TX_WARNING :
721*4882a593Smuzhiyun CAN_ERR_CRTL_RX_WARNING;
722*4882a593Smuzhiyun cf->data[6] = txerr;
723*4882a593Smuzhiyun cf->data[7] = rxerr;
724*4882a593Smuzhiyun }
725*4882a593Smuzhiyun
726*4882a593Smuzhiyun if (rcan->can.state >= CAN_STATE_BUS_OFF ||
727*4882a593Smuzhiyun ((sta_reg & 0x20) == 0x20))
728*4882a593Smuzhiyun can_bus_off(ndev);
729*4882a593Smuzhiyun
730*4882a593Smuzhiyun stats->rx_packets++;
731*4882a593Smuzhiyun stats->rx_bytes += cf->can_dlc;
732*4882a593Smuzhiyun netif_rx(skb);
733*4882a593Smuzhiyun
734*4882a593Smuzhiyun return 0;
735*4882a593Smuzhiyun }
736*4882a593Smuzhiyun
rockchip_canfd_interrupt(int irq,void * dev_id)737*4882a593Smuzhiyun static irqreturn_t rockchip_canfd_interrupt(int irq, void *dev_id)
738*4882a593Smuzhiyun {
739*4882a593Smuzhiyun struct net_device *ndev = (struct net_device *)dev_id;
740*4882a593Smuzhiyun struct rockchip_canfd *rcan = netdev_priv(ndev);
741*4882a593Smuzhiyun struct net_device_stats *stats = &ndev->stats;
742*4882a593Smuzhiyun u32 err_int = ERR_WARN_INT | RX_BUF_OV_INT | PASSIVE_ERR_INT |
743*4882a593Smuzhiyun TX_LOSTARB_INT | BUS_ERR_INT | BUS_OFF_INT;
744*4882a593Smuzhiyun u32 isr;
745*4882a593Smuzhiyun u32 dlc = 0;
746*4882a593Smuzhiyun u32 quota, work_done = 0;
747*4882a593Smuzhiyun
748*4882a593Smuzhiyun isr = rockchip_canfd_read(rcan, CAN_INT);
749*4882a593Smuzhiyun if (isr & TX_FINISH_INT) {
750*4882a593Smuzhiyun //Check whether the interrupt is triggered by TX1
751*4882a593Smuzhiyun //Avoid frame ID misalignment
752*4882a593Smuzhiyun //by forlinx-manic
753*4882a593Smuzhiyun if ((rockchip_canfd_read(rcan, CAN_CMD) & CAN_TX0_REQ) || (rockchip_canfd_read(rcan, CAN_CMD) & CAN_TX1_REQ))
754*4882a593Smuzhiyun {
755*4882a593Smuzhiyun return IRQ_HANDLED;
756*4882a593Smuzhiyun }
757*4882a593Smuzhiyun
758*4882a593Smuzhiyun dlc = rockchip_canfd_read(rcan, CAN_TXFIC);
759*4882a593Smuzhiyun /* transmission complete interrupt */
760*4882a593Smuzhiyun if (dlc & FDF_MASK)
761*4882a593Smuzhiyun stats->tx_bytes += can_dlc2len(dlc & DLC_MASK);
762*4882a593Smuzhiyun else
763*4882a593Smuzhiyun stats->tx_bytes += (dlc & DLC_MASK);
764*4882a593Smuzhiyun stats->tx_packets++;
765*4882a593Smuzhiyun if (rcan->txtorx && rcan->mode >= ROCKCHIP_CAN_MODE && dlc & FORMAT_MASK) {
766*4882a593Smuzhiyun cancel_delayed_work(&rcan->tx_err_work);
767*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_TX_CHECK_FIC, FORMAT_MASK);
768*4882a593Smuzhiyun quota = (rockchip_canfd_read(rcan, CAN_RXFC) &
769*4882a593Smuzhiyun rcan->rx_fifo_mask) >>
770*4882a593Smuzhiyun rcan->rx_fifo_shift;
771*4882a593Smuzhiyun if (quota) {
772*4882a593Smuzhiyun while (work_done < quota)
773*4882a593Smuzhiyun work_done += rockchip_canfd_rx(ndev);
774*4882a593Smuzhiyun }
775*4882a593Smuzhiyun if (rockchip_canfd_read(rcan, CAN_TX_CHECK_FIC) & CAN_TX0_REQ)
776*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_CMD, CAN_TX1_REQ);
777*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_TX_CHECK_FIC, 0);
778*4882a593Smuzhiyun }
779*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_CMD, 0);
780*4882a593Smuzhiyun can_get_echo_skb(ndev, 0);
781*4882a593Smuzhiyun netif_wake_queue(ndev);
782*4882a593Smuzhiyun can_led_event(ndev, CAN_LED_EVENT_TX);
783*4882a593Smuzhiyun }
784*4882a593Smuzhiyun
785*4882a593Smuzhiyun if (isr & RX_FINISH_INT) {
786*4882a593Smuzhiyun quota = (rockchip_canfd_read(rcan, CAN_RXFC) & rcan->rx_fifo_mask) >>
787*4882a593Smuzhiyun rcan->rx_fifo_shift;
788*4882a593Smuzhiyun if (quota) {
789*4882a593Smuzhiyun while (work_done < quota)
790*4882a593Smuzhiyun work_done += rockchip_canfd_rx(ndev);
791*4882a593Smuzhiyun }
792*4882a593Smuzhiyun }
793*4882a593Smuzhiyun
794*4882a593Smuzhiyun if (isr & err_int) {
795*4882a593Smuzhiyun /* error interrupt */
796*4882a593Smuzhiyun if (rockchip_canfd_err(ndev, isr))
797*4882a593Smuzhiyun netdev_err(ndev, "can't allocate buffer - clearing pending interrupts\n");
798*4882a593Smuzhiyun }
799*4882a593Smuzhiyun
800*4882a593Smuzhiyun rockchip_canfd_write(rcan, CAN_INT, isr);
801*4882a593Smuzhiyun return IRQ_HANDLED;
802*4882a593Smuzhiyun }
803*4882a593Smuzhiyun
rockchip_canfd_open(struct net_device * ndev)804*4882a593Smuzhiyun static int rockchip_canfd_open(struct net_device *ndev)
805*4882a593Smuzhiyun {
806*4882a593Smuzhiyun struct rockchip_canfd *rcan = netdev_priv(ndev);
807*4882a593Smuzhiyun int err;
808*4882a593Smuzhiyun
809*4882a593Smuzhiyun /* common open */
810*4882a593Smuzhiyun err = open_candev(ndev);
811*4882a593Smuzhiyun if (err)
812*4882a593Smuzhiyun return err;
813*4882a593Smuzhiyun
814*4882a593Smuzhiyun err = pm_runtime_get_sync(rcan->dev);
815*4882a593Smuzhiyun if (err < 0) {
816*4882a593Smuzhiyun netdev_err(ndev, "%s: pm_runtime_get failed(%d)\n",
817*4882a593Smuzhiyun __func__, err);
818*4882a593Smuzhiyun goto exit;
819*4882a593Smuzhiyun }
820*4882a593Smuzhiyun
821*4882a593Smuzhiyun err = rockchip_canfd_start(ndev);
822*4882a593Smuzhiyun if (err) {
823*4882a593Smuzhiyun netdev_err(ndev, "could not start CAN peripheral\n");
824*4882a593Smuzhiyun goto exit_can_start;
825*4882a593Smuzhiyun }
826*4882a593Smuzhiyun
827*4882a593Smuzhiyun can_led_event(ndev, CAN_LED_EVENT_OPEN);
828*4882a593Smuzhiyun netif_start_queue(ndev);
829*4882a593Smuzhiyun
830*4882a593Smuzhiyun netdev_dbg(ndev, "%s\n", __func__);
831*4882a593Smuzhiyun return 0;
832*4882a593Smuzhiyun
833*4882a593Smuzhiyun exit_can_start:
834*4882a593Smuzhiyun pm_runtime_put(rcan->dev);
835*4882a593Smuzhiyun exit:
836*4882a593Smuzhiyun close_candev(ndev);
837*4882a593Smuzhiyun return err;
838*4882a593Smuzhiyun }
839*4882a593Smuzhiyun
rockchip_canfd_close(struct net_device * ndev)840*4882a593Smuzhiyun static int rockchip_canfd_close(struct net_device *ndev)
841*4882a593Smuzhiyun {
842*4882a593Smuzhiyun struct rockchip_canfd *rcan = netdev_priv(ndev);
843*4882a593Smuzhiyun
844*4882a593Smuzhiyun netif_stop_queue(ndev);
845*4882a593Smuzhiyun rockchip_canfd_stop(ndev);
846*4882a593Smuzhiyun close_candev(ndev);
847*4882a593Smuzhiyun can_led_event(ndev, CAN_LED_EVENT_STOP);
848*4882a593Smuzhiyun pm_runtime_put(rcan->dev);
849*4882a593Smuzhiyun cancel_delayed_work_sync(&rcan->tx_err_work);
850*4882a593Smuzhiyun
851*4882a593Smuzhiyun netdev_dbg(ndev, "%s\n", __func__);
852*4882a593Smuzhiyun return 0;
853*4882a593Smuzhiyun }
854*4882a593Smuzhiyun
855*4882a593Smuzhiyun static const struct net_device_ops rockchip_canfd_netdev_ops = {
856*4882a593Smuzhiyun .ndo_open = rockchip_canfd_open,
857*4882a593Smuzhiyun .ndo_stop = rockchip_canfd_close,
858*4882a593Smuzhiyun .ndo_start_xmit = rockchip_canfd_start_xmit,
859*4882a593Smuzhiyun .ndo_change_mtu = can_change_mtu,
860*4882a593Smuzhiyun };
861*4882a593Smuzhiyun
862*4882a593Smuzhiyun /**
863*4882a593Smuzhiyun * rockchip_canfd_suspend - Suspend method for the driver
864*4882a593Smuzhiyun * @dev: Address of the device structure
865*4882a593Smuzhiyun *
866*4882a593Smuzhiyun * Put the driver into low power mode.
867*4882a593Smuzhiyun * Return: 0 on success and failure value on error
868*4882a593Smuzhiyun */
rockchip_canfd_suspend(struct device * dev)869*4882a593Smuzhiyun static int __maybe_unused rockchip_canfd_suspend(struct device *dev)
870*4882a593Smuzhiyun {
871*4882a593Smuzhiyun struct net_device *ndev = dev_get_drvdata(dev);
872*4882a593Smuzhiyun
873*4882a593Smuzhiyun if (netif_running(ndev)) {
874*4882a593Smuzhiyun netif_stop_queue(ndev);
875*4882a593Smuzhiyun netif_device_detach(ndev);
876*4882a593Smuzhiyun rockchip_canfd_stop(ndev);
877*4882a593Smuzhiyun }
878*4882a593Smuzhiyun
879*4882a593Smuzhiyun return pm_runtime_force_suspend(dev);
880*4882a593Smuzhiyun }
881*4882a593Smuzhiyun
882*4882a593Smuzhiyun /**
883*4882a593Smuzhiyun * rockchip_canfd_resume - Resume from suspend
884*4882a593Smuzhiyun * @dev: Address of the device structure
885*4882a593Smuzhiyun *
886*4882a593Smuzhiyun * Resume operation after suspend.
887*4882a593Smuzhiyun * Return: 0 on success and failure value on error
888*4882a593Smuzhiyun */
rockchip_canfd_resume(struct device * dev)889*4882a593Smuzhiyun static int __maybe_unused rockchip_canfd_resume(struct device *dev)
890*4882a593Smuzhiyun {
891*4882a593Smuzhiyun struct net_device *ndev = dev_get_drvdata(dev);
892*4882a593Smuzhiyun int ret;
893*4882a593Smuzhiyun
894*4882a593Smuzhiyun ret = pm_runtime_force_resume(dev);
895*4882a593Smuzhiyun if (ret) {
896*4882a593Smuzhiyun dev_err(dev, "pm_runtime_force_resume failed on resume\n");
897*4882a593Smuzhiyun return ret;
898*4882a593Smuzhiyun }
899*4882a593Smuzhiyun
900*4882a593Smuzhiyun if (netif_running(ndev)) {
901*4882a593Smuzhiyun ret = rockchip_canfd_start(ndev);
902*4882a593Smuzhiyun if (ret) {
903*4882a593Smuzhiyun dev_err(dev, "rockchip_canfd_chip_start failed on resume\n");
904*4882a593Smuzhiyun return ret;
905*4882a593Smuzhiyun }
906*4882a593Smuzhiyun
907*4882a593Smuzhiyun netif_device_attach(ndev);
908*4882a593Smuzhiyun netif_start_queue(ndev);
909*4882a593Smuzhiyun }
910*4882a593Smuzhiyun
911*4882a593Smuzhiyun return 0;
912*4882a593Smuzhiyun }
913*4882a593Smuzhiyun
914*4882a593Smuzhiyun /**
915*4882a593Smuzhiyun * rockchip_canfd_runtime_suspend - Runtime suspend method for the driver
916*4882a593Smuzhiyun * @dev: Address of the device structure
917*4882a593Smuzhiyun *
918*4882a593Smuzhiyun * Put the driver into low power mode.
919*4882a593Smuzhiyun * Return: 0 always
920*4882a593Smuzhiyun */
rockchip_canfd_runtime_suspend(struct device * dev)921*4882a593Smuzhiyun static int __maybe_unused rockchip_canfd_runtime_suspend(struct device *dev)
922*4882a593Smuzhiyun {
923*4882a593Smuzhiyun struct net_device *ndev = dev_get_drvdata(dev);
924*4882a593Smuzhiyun struct rockchip_canfd *rcan = netdev_priv(ndev);
925*4882a593Smuzhiyun
926*4882a593Smuzhiyun clk_bulk_disable_unprepare(rcan->num_clks, rcan->clks);
927*4882a593Smuzhiyun
928*4882a593Smuzhiyun return 0;
929*4882a593Smuzhiyun }
930*4882a593Smuzhiyun
931*4882a593Smuzhiyun /**
932*4882a593Smuzhiyun * rockchip_canfd_runtime_resume - Runtime resume from suspend
933*4882a593Smuzhiyun * @dev: Address of the device structure
934*4882a593Smuzhiyun *
935*4882a593Smuzhiyun * Resume operation after suspend.
936*4882a593Smuzhiyun * Return: 0 on success and failure value on error
937*4882a593Smuzhiyun */
rockchip_canfd_runtime_resume(struct device * dev)938*4882a593Smuzhiyun static int __maybe_unused rockchip_canfd_runtime_resume(struct device *dev)
939*4882a593Smuzhiyun {
940*4882a593Smuzhiyun struct net_device *ndev = dev_get_drvdata(dev);
941*4882a593Smuzhiyun struct rockchip_canfd *rcan = netdev_priv(ndev);
942*4882a593Smuzhiyun int ret;
943*4882a593Smuzhiyun
944*4882a593Smuzhiyun ret = clk_bulk_prepare_enable(rcan->num_clks, rcan->clks);
945*4882a593Smuzhiyun if (ret) {
946*4882a593Smuzhiyun dev_err(dev, "Cannot enable clock.\n");
947*4882a593Smuzhiyun return ret;
948*4882a593Smuzhiyun }
949*4882a593Smuzhiyun
950*4882a593Smuzhiyun return 0;
951*4882a593Smuzhiyun }
952*4882a593Smuzhiyun
953*4882a593Smuzhiyun static const struct dev_pm_ops rockchip_canfd_dev_pm_ops = {
954*4882a593Smuzhiyun SET_SYSTEM_SLEEP_PM_OPS(rockchip_canfd_suspend, rockchip_canfd_resume)
955*4882a593Smuzhiyun SET_RUNTIME_PM_OPS(rockchip_canfd_runtime_suspend,
956*4882a593Smuzhiyun rockchip_canfd_runtime_resume, NULL)
957*4882a593Smuzhiyun };
958*4882a593Smuzhiyun
959*4882a593Smuzhiyun static const struct of_device_id rockchip_canfd_of_match[] = {
960*4882a593Smuzhiyun {
961*4882a593Smuzhiyun .compatible = "forlinx,rk3568-can-2.0",
962*4882a593Smuzhiyun .data = (void *)ROCKCHIP_RK3568_CAN_MODE
963*4882a593Smuzhiyun },
964*4882a593Smuzhiyun };
965*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, rockchip_canfd_of_match);
966*4882a593Smuzhiyun
rockchip_canfd_probe(struct platform_device * pdev)967*4882a593Smuzhiyun static int rockchip_canfd_probe(struct platform_device *pdev)
968*4882a593Smuzhiyun {
969*4882a593Smuzhiyun struct net_device *ndev;
970*4882a593Smuzhiyun struct rockchip_canfd *rcan;
971*4882a593Smuzhiyun struct resource *res;
972*4882a593Smuzhiyun void __iomem *addr;
973*4882a593Smuzhiyun int err, irq;
974*4882a593Smuzhiyun
975*4882a593Smuzhiyun irq = platform_get_irq(pdev, 0);
976*4882a593Smuzhiyun if (irq < 0) {
977*4882a593Smuzhiyun dev_err(&pdev->dev, "could not get a valid irq\n");
978*4882a593Smuzhiyun return -ENODEV;
979*4882a593Smuzhiyun }
980*4882a593Smuzhiyun
981*4882a593Smuzhiyun res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
982*4882a593Smuzhiyun addr = devm_ioremap_resource(&pdev->dev, res);
983*4882a593Smuzhiyun if (IS_ERR(addr))
984*4882a593Smuzhiyun return -EBUSY;
985*4882a593Smuzhiyun
986*4882a593Smuzhiyun ndev = alloc_candev(sizeof(struct rockchip_canfd), 1);
987*4882a593Smuzhiyun if (!ndev) {
988*4882a593Smuzhiyun dev_err(&pdev->dev, "could not allocate memory for CANFD device\n");
989*4882a593Smuzhiyun return -ENOMEM;
990*4882a593Smuzhiyun }
991*4882a593Smuzhiyun rcan = netdev_priv(ndev);
992*4882a593Smuzhiyun
993*4882a593Smuzhiyun /* register interrupt handler */
994*4882a593Smuzhiyun err = devm_request_irq(&pdev->dev, irq, rockchip_canfd_interrupt,
995*4882a593Smuzhiyun 0, ndev->name, ndev);
996*4882a593Smuzhiyun if (err) {
997*4882a593Smuzhiyun dev_err(&pdev->dev, "request_irq err: %d\n", err);
998*4882a593Smuzhiyun return err;
999*4882a593Smuzhiyun }
1000*4882a593Smuzhiyun
1001*4882a593Smuzhiyun rcan->reset = devm_reset_control_array_get(&pdev->dev, false, false);
1002*4882a593Smuzhiyun if (IS_ERR(rcan->reset)) {
1003*4882a593Smuzhiyun if (PTR_ERR(rcan->reset) != -EPROBE_DEFER)
1004*4882a593Smuzhiyun dev_err(&pdev->dev, "failed to get canfd reset lines\n");
1005*4882a593Smuzhiyun return PTR_ERR(rcan->reset);
1006*4882a593Smuzhiyun }
1007*4882a593Smuzhiyun rcan->num_clks = devm_clk_bulk_get_all(&pdev->dev, &rcan->clks);
1008*4882a593Smuzhiyun if (rcan->num_clks < 1)
1009*4882a593Smuzhiyun return -ENODEV;
1010*4882a593Smuzhiyun
1011*4882a593Smuzhiyun rcan->mode = (unsigned long)of_device_get_match_data(&pdev->dev);
1012*4882a593Smuzhiyun
1013*4882a593Smuzhiyun rcan->base = addr;
1014*4882a593Smuzhiyun rcan->can.clock.freq = clk_get_rate(rcan->clks[0].clk);
1015*4882a593Smuzhiyun rcan->dev = &pdev->dev;
1016*4882a593Smuzhiyun rcan->can.state = CAN_STATE_STOPPED;
1017*4882a593Smuzhiyun switch (rcan->mode) {
1018*4882a593Smuzhiyun case ROCKCHIP_CANFD_MODE:
1019*4882a593Smuzhiyun rcan->can.bittiming_const = &rockchip_canfd_bittiming_const;
1020*4882a593Smuzhiyun rcan->can.data_bittiming_const = &rockchip_canfd_data_bittiming_const;
1021*4882a593Smuzhiyun rcan->can.do_set_mode = rockchip_canfd_set_mode;
1022*4882a593Smuzhiyun rcan->can.do_get_berr_counter = rockchip_canfd_get_berr_counter;
1023*4882a593Smuzhiyun rcan->can.do_set_bittiming = rockchip_canfd_set_bittiming;
1024*4882a593Smuzhiyun rcan->can.do_set_data_bittiming = rockchip_canfd_set_bittiming;
1025*4882a593Smuzhiyun rcan->can.ctrlmode = CAN_CTRLMODE_FD;
1026*4882a593Smuzhiyun /* IFI CANFD can do both Bosch FD and ISO FD */
1027*4882a593Smuzhiyun rcan->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
1028*4882a593Smuzhiyun CAN_CTRLMODE_FD;
1029*4882a593Smuzhiyun rcan->rx_fifo_shift = RX_FIFO_CNT0_SHIFT;
1030*4882a593Smuzhiyun rcan->rx_fifo_mask = RX_FIFO_CNT0_MASK;
1031*4882a593Smuzhiyun break;
1032*4882a593Smuzhiyun case ROCKCHIP_CAN_MODE:
1033*4882a593Smuzhiyun case ROCKCHIP_RK3568_CAN_MODE:
1034*4882a593Smuzhiyun rcan->can.bittiming_const = &rockchip_canfd_bittiming_const;
1035*4882a593Smuzhiyun rcan->can.do_set_mode = rockchip_canfd_set_mode;
1036*4882a593Smuzhiyun rcan->can.do_get_berr_counter = rockchip_canfd_get_berr_counter;
1037*4882a593Smuzhiyun rcan->can.ctrlmode_supported = CAN_CTRLMODE_BERR_REPORTING |
1038*4882a593Smuzhiyun CAN_CTRLMODE_LISTENONLY |
1039*4882a593Smuzhiyun CAN_CTRLMODE_LOOPBACK |
1040*4882a593Smuzhiyun CAN_CTRLMODE_3_SAMPLES;
1041*4882a593Smuzhiyun rcan->rx_fifo_shift = RX_FIFO_CNT0_SHIFT;
1042*4882a593Smuzhiyun rcan->rx_fifo_mask = RX_FIFO_CNT0_MASK;
1043*4882a593Smuzhiyun break;
1044*4882a593Smuzhiyun default:
1045*4882a593Smuzhiyun return -EINVAL;
1046*4882a593Smuzhiyun }
1047*4882a593Smuzhiyun
1048*4882a593Smuzhiyun if (rcan->mode == ROCKCHIP_CAN_MODE) {
1049*4882a593Smuzhiyun rcan->rx_fifo_shift = RX_FIFO_CNT1_SHIFT;
1050*4882a593Smuzhiyun rcan->rx_fifo_mask = RX_FIFO_CNT1_MASK;
1051*4882a593Smuzhiyun }
1052*4882a593Smuzhiyun
1053*4882a593Smuzhiyun if (device_property_read_u32_array(&pdev->dev,
1054*4882a593Smuzhiyun "rockchip,tx-invalid-info",
1055*4882a593Smuzhiyun rcan->tx_invalid, 4))
1056*4882a593Smuzhiyun rcan->txtorx = 1;
1057*4882a593Smuzhiyun
1058*4882a593Smuzhiyun ndev->netdev_ops = &rockchip_canfd_netdev_ops;
1059*4882a593Smuzhiyun ndev->irq = irq;
1060*4882a593Smuzhiyun ndev->flags |= IFF_ECHO;
1061*4882a593Smuzhiyun rcan->can.restart_ms = 1;
1062*4882a593Smuzhiyun
1063*4882a593Smuzhiyun INIT_DELAYED_WORK(&rcan->tx_err_work, rockchip_canfd_tx_err_delay_work);
1064*4882a593Smuzhiyun
1065*4882a593Smuzhiyun platform_set_drvdata(pdev, ndev);
1066*4882a593Smuzhiyun SET_NETDEV_DEV(ndev, &pdev->dev);
1067*4882a593Smuzhiyun
1068*4882a593Smuzhiyun pm_runtime_enable(&pdev->dev);
1069*4882a593Smuzhiyun err = pm_runtime_get_sync(&pdev->dev);
1070*4882a593Smuzhiyun if (err < 0) {
1071*4882a593Smuzhiyun dev_err(&pdev->dev, "%s: pm_runtime_get failed(%d)\n",
1072*4882a593Smuzhiyun __func__, err);
1073*4882a593Smuzhiyun goto err_pmdisable;
1074*4882a593Smuzhiyun }
1075*4882a593Smuzhiyun
1076*4882a593Smuzhiyun err = register_candev(ndev);
1077*4882a593Smuzhiyun if (err) {
1078*4882a593Smuzhiyun dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
1079*4882a593Smuzhiyun DRV_NAME, err);
1080*4882a593Smuzhiyun goto err_disableclks;
1081*4882a593Smuzhiyun }
1082*4882a593Smuzhiyun
1083*4882a593Smuzhiyun devm_can_led_init(ndev);
1084*4882a593Smuzhiyun
1085*4882a593Smuzhiyun return 0;
1086*4882a593Smuzhiyun
1087*4882a593Smuzhiyun err_disableclks:
1088*4882a593Smuzhiyun pm_runtime_put(&pdev->dev);
1089*4882a593Smuzhiyun err_pmdisable:
1090*4882a593Smuzhiyun pm_runtime_disable(&pdev->dev);
1091*4882a593Smuzhiyun free_candev(ndev);
1092*4882a593Smuzhiyun
1093*4882a593Smuzhiyun return err;
1094*4882a593Smuzhiyun }
1095*4882a593Smuzhiyun
rockchip_canfd_remove(struct platform_device * pdev)1096*4882a593Smuzhiyun static int rockchip_canfd_remove(struct platform_device *pdev)
1097*4882a593Smuzhiyun {
1098*4882a593Smuzhiyun struct net_device *ndev = platform_get_drvdata(pdev);
1099*4882a593Smuzhiyun
1100*4882a593Smuzhiyun unregister_netdev(ndev);
1101*4882a593Smuzhiyun pm_runtime_disable(&pdev->dev);
1102*4882a593Smuzhiyun free_candev(ndev);
1103*4882a593Smuzhiyun
1104*4882a593Smuzhiyun return 0;
1105*4882a593Smuzhiyun }
1106*4882a593Smuzhiyun
1107*4882a593Smuzhiyun static struct platform_driver rockchip_canfd_driver = {
1108*4882a593Smuzhiyun .driver = {
1109*4882a593Smuzhiyun .name = DRV_NAME,
1110*4882a593Smuzhiyun .pm = &rockchip_canfd_dev_pm_ops,
1111*4882a593Smuzhiyun .of_match_table = rockchip_canfd_of_match,
1112*4882a593Smuzhiyun },
1113*4882a593Smuzhiyun .probe = rockchip_canfd_probe,
1114*4882a593Smuzhiyun .remove = rockchip_canfd_remove,
1115*4882a593Smuzhiyun };
1116*4882a593Smuzhiyun module_platform_driver(rockchip_canfd_driver);
1117*4882a593Smuzhiyun
1118*4882a593Smuzhiyun MODULE_AUTHOR("Elaine Zhang <zhangqing@rock-chips.com>");
1119*4882a593Smuzhiyun MODULE_LICENSE("GPL");
1120*4882a593Smuzhiyun MODULE_DESCRIPTION("Rockchip CANFD Drivers");
1121