ath79/mikrotik: use routerbootpart partitions
[oweals/openwrt.git] / target / linux / layerscape / patches-5.4 / 802-can-0019-can-flexcan-add-CAN-FD-mode-support.patch
1 From 2aea13a107090d05e968d7d2aa3f72380a3f1b4c Mon Sep 17 00:00:00 2001
2 From: Joakim Zhang <qiangqing.zhang@nxp.com>
3 Date: Fri, 12 Jul 2019 08:02:44 +0000
4 Subject: [PATCH] can: flexcan: add CAN FD mode support
5
6 This patch intends to add CAN FD mode support in driver, it means that
7 payload size can extend up to 64 bytes.
8
9 Bit timing always set in CBT register other than CTRL1 register when
10 CANFD supports BRS, it will extend the range of all CAN bit timing
11 variables (PRESDIV, PROPSEG, PSEG1, PSEG2 and RJW), which will improve
12 the bit timing accuracy.
13
14 Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
15 Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
16 ---
17  drivers/net/can/flexcan.c | 247 ++++++++++++++++++++++++++++++++++++++++------
18  1 file changed, 218 insertions(+), 29 deletions(-)
19
20 --- a/drivers/net/can/flexcan.c
21 +++ b/drivers/net/can/flexcan.c
22 @@ -52,6 +52,7 @@
23  #define FLEXCAN_MCR_IRMQ               BIT(16)
24  #define FLEXCAN_MCR_LPRIO_EN           BIT(13)
25  #define FLEXCAN_MCR_AEN                        BIT(12)
26 +#define FLEXCAN_MCR_FDEN               BIT(11)
27  /* MCR_MAXMB: maximum used MBs is MAXMB + 1 */
28  #define FLEXCAN_MCR_MAXMB(x)           ((x) & 0x7f)
29  #define FLEXCAN_MCR_IDAM_A             (0x0 << 8)
30 @@ -137,6 +138,26 @@
31          FLEXCAN_ESR_BOFF_INT | FLEXCAN_ESR_ERR_INT | \
32          FLEXCAN_ESR_WAK_INT)
33  
34 +/* FLEXCAN Bit Timing register (CBT) bits */
35 +#define FLEXCAN_CBT_BTF                        BIT(31)
36 +#define FLEXCAN_CBT_EPRESDIV(x)                (((x) & 0x3ff) << 21)
37 +#define FLEXCAN_CBT_ERJW(x)            (((x) & 0x0f) << 16)
38 +#define FLEXCAN_CBT_EPROPSEG(x)                (((x) & 0x3f) << 10)
39 +#define FLEXCAN_CBT_EPSEG1(x)          (((x) & 0x1f) << 5)
40 +#define FLEXCAN_CBT_EPSEG2(x)          ((x) & 0x1f)
41 +
42 +/* FLEXCAN FD control register (FDCTRL) bits */
43 +#define FLEXCAN_FDCTRL_FDRATE          BIT(31)
44 +#define FLEXCAN_FDCTRL_MBDSR1(x)       (((x) & 0x3) << 19)
45 +#define FLEXCAN_FDCTRL_MBDSR0(x)       (((x) & 0x3) << 16)
46 +
47 +/* FLEXCAN FD Bit Timing register (FDCBT) bits */
48 +#define FLEXCAN_FDCBT_FPRESDIV(x)      (((x) & 0x3ff) << 20)
49 +#define FLEXCAN_FDCBT_FRJW(x)          (((x) & 0x07) << 16)
50 +#define FLEXCAN_FDCBT_FPROPSEG(x)      (((x) & 0x1f) << 10)
51 +#define FLEXCAN_FDCBT_FPSEG1(x)                (((x) & 0x07) << 5)
52 +#define FLEXCAN_FDCBT_FPSEG2(x)                ((x) & 0x07)
53 +
54  /* FLEXCAN interrupt flag register (IFLAG) bits */
55  /* Errata ERR005829 step7: Reserve first valid MB */
56  #define FLEXCAN_TX_MB_RESERVED_OFF_FIFO                8
57 @@ -161,6 +182,9 @@
58  #define FLEXCAN_MB_CODE_TX_DATA                (0xc << 24)
59  #define FLEXCAN_MB_CODE_TX_TANSWER     (0xe << 24)
60  
61 +#define FLEXCAN_MB_CNT_EDL             BIT(31)
62 +#define FLEXCAN_MB_CNT_BRS             BIT(30)
63 +#define FLEXCAN_MB_CNT_ESI             BIT(29)
64  #define FLEXCAN_MB_CNT_SRR             BIT(22)
65  #define FLEXCAN_MB_CNT_IDE             BIT(21)
66  #define FLEXCAN_MB_CNT_RTR             BIT(20)
67 @@ -192,6 +216,7 @@
68  #define FLEXCAN_QUIRK_BROKEN_PERR_STATE        BIT(6) /* No interrupt for error passive */
69  #define FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN       BIT(7) /* default to BE register access */
70  #define FLEXCAN_QUIRK_SETUP_STOP_MODE          BIT(8) /* Setup stop mode to support wakeup */
71 +#define FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD     BIT(9) /* Use timestamp then support can fd mode */
72  
73  /* Structure of the message buffer */
74  struct flexcan_mb {
75 @@ -225,7 +250,8 @@ struct flexcan_regs {
76         u32 crcr;               /* 0x44 */
77         u32 rxfgmask;           /* 0x48 */
78         u32 rxfir;              /* 0x4c */
79 -       u32 _reserved3[12];     /* 0x50 */
80 +       u32 cbt;                /* 0x50 */
81 +       u32 _reserved3[11];     /* 0x54 */
82         u8 mb[2][512];          /* 0x80 */
83         /* FIFO-mode:
84          *                      MB
85 @@ -250,6 +276,10 @@ struct flexcan_regs {
86         u32 rerrdr;             /* 0xaf4 */
87         u32 rerrsynr;           /* 0xaf8 */
88         u32 errsr;              /* 0xafc */
89 +       u32 _reserved7[64];     /* 0xb00 */
90 +       u32 fdctrl;             /* 0xc00 */
91 +       u32 fdcbt;              /* 0xc04 */
92 +       u32 fdcrc;              /* 0xc08 */
93  };
94  
95  struct flexcan_devtype_data {
96 @@ -337,6 +367,30 @@ static const struct can_bittiming_const
97         .brp_inc = 1,
98  };
99  
100 +static const struct can_bittiming_const flexcan_fd_bittiming_const = {
101 +       .name = DRV_NAME,
102 +       .tseg1_min = 2,
103 +       .tseg1_max = 96,
104 +       .tseg2_min = 2,
105 +       .tseg2_max = 32,
106 +       .sjw_max = 16,
107 +       .brp_min = 1,
108 +       .brp_max = 1024,
109 +       .brp_inc = 1,
110 +};
111 +
112 +static const struct can_bittiming_const flexcan_fd_data_bittiming_const = {
113 +       .name = DRV_NAME,
114 +       .tseg1_min = 2,
115 +       .tseg1_max = 39,
116 +       .tseg2_min = 2,
117 +       .tseg2_max = 8,
118 +       .sjw_max = 4,
119 +       .brp_min = 1,
120 +       .brp_max = 1024,
121 +       .brp_inc = 1,
122 +};
123 +
124  /* FlexCAN module is essentially modelled as a little-endian IP in most
125   * SoCs, i.e the registers as well as the message buffer areas are
126   * implemented in a little-endian fashion.
127 @@ -631,7 +685,7 @@ static netdev_tx_t flexcan_start_xmit(st
128         struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
129         u32 can_id;
130         u32 data;
131 -       u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | (cfd->len << 16);
132 +       u32 ctrl = FLEXCAN_MB_CODE_TX_DATA | ((can_len2dlc(cfd->len)) << 16);
133         int i;
134  
135         if (can_dropped_invalid_skb(dev, skb))
136 @@ -649,6 +703,9 @@ static netdev_tx_t flexcan_start_xmit(st
137         if (cfd->can_id & CAN_RTR_FLAG)
138                 ctrl |= FLEXCAN_MB_CNT_RTR;
139  
140 +       if (can_is_canfd_skb(skb))
141 +               ctrl |= FLEXCAN_MB_CNT_EDL;
142 +
143         for (i = 0; i < cfd->len; i += sizeof(u32)) {
144                 data = be32_to_cpup((__be32 *)&cfd->data[i]);
145                 priv->write(data, &priv->tx_mb->data[i / sizeof(u32)]);
146 @@ -859,7 +916,10 @@ static struct sk_buff *flexcan_mailbox_r
147                 reg_ctrl = priv->read(&mb->can_ctrl);
148         }
149  
150 -       skb = alloc_can_skb(offload->dev, (struct can_frame **)&cfd);
151 +       if (reg_ctrl & FLEXCAN_MB_CNT_EDL)
152 +               skb = alloc_canfd_skb(offload->dev, &cfd);
153 +       else
154 +               skb = alloc_can_skb(offload->dev, (struct can_frame **)&cfd);
155         if (unlikely(!skb)) {
156                 skb = ERR_PTR(-ENOMEM);
157                 goto mark_as_read;
158 @@ -874,9 +934,17 @@ static struct sk_buff *flexcan_mailbox_r
159         else
160                 cfd->can_id = (reg_id >> 18) & CAN_SFF_MASK;
161  
162 -       if (reg_ctrl & FLEXCAN_MB_CNT_RTR)
163 -               cfd->can_id |= CAN_RTR_FLAG;
164 -       cfd->len = get_can_dlc((reg_ctrl >> 16) & 0xf);
165 +       if (reg_ctrl & FLEXCAN_MB_CNT_EDL) {
166 +               cfd->len = can_dlc2len(get_canfd_dlc((reg_ctrl >> 16) & 0xf));
167 +       } else {
168 +               cfd->len = get_can_dlc((reg_ctrl >> 16) & 0xf);
169 +
170 +               if (reg_ctrl & FLEXCAN_MB_CNT_RTR)
171 +                       cfd->can_id |= CAN_RTR_FLAG;
172 +       }
173 +
174 +       if (reg_ctrl & FLEXCAN_MB_CNT_ESI)
175 +               cfd->flags |= CANFD_ESI;
176  
177         for (i = 0; i < cfd->len; i += sizeof(u32)) {
178                 __be32 data = cpu_to_be32(priv->read(&mb->data[i / sizeof(u32)]));
179 @@ -1021,27 +1089,14 @@ static irqreturn_t flexcan_irq(int irq,
180  
181  static void flexcan_set_bittiming(struct net_device *dev)
182  {
183 -       const struct flexcan_priv *priv = netdev_priv(dev);
184 -       const struct can_bittiming *bt = &priv->can.bittiming;
185 +       struct flexcan_priv *priv = netdev_priv(dev);
186 +       struct can_bittiming *bt = &priv->can.bittiming;
187 +       struct can_bittiming *dbt = &priv->can.data_bittiming;
188         struct flexcan_regs __iomem *regs = priv->regs;
189 -       u32 reg;
190 +       u32 reg, reg_cbt, reg_fdcbt;
191  
192         reg = priv->read(&regs->ctrl);
193 -       reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
194 -                FLEXCAN_CTRL_RJW(0x3) |
195 -                FLEXCAN_CTRL_PSEG1(0x7) |
196 -                FLEXCAN_CTRL_PSEG2(0x7) |
197 -                FLEXCAN_CTRL_PROPSEG(0x7) |
198 -                FLEXCAN_CTRL_LPB |
199 -                FLEXCAN_CTRL_SMP |
200 -                FLEXCAN_CTRL_LOM);
201 -
202 -       reg |= FLEXCAN_CTRL_PRESDIV(bt->brp - 1) |
203 -               FLEXCAN_CTRL_PSEG1(bt->phase_seg1 - 1) |
204 -               FLEXCAN_CTRL_PSEG2(bt->phase_seg2 - 1) |
205 -               FLEXCAN_CTRL_RJW(bt->sjw - 1) |
206 -               FLEXCAN_CTRL_PROPSEG(bt->prop_seg - 1);
207 -
208 +       reg &= ~(FLEXCAN_CTRL_LPB | FLEXCAN_CTRL_SMP | FLEXCAN_CTRL_LOM);
209         if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)
210                 reg |= FLEXCAN_CTRL_LPB;
211         if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY)
212 @@ -1052,9 +1107,102 @@ static void flexcan_set_bittiming(struct
213         netdev_dbg(dev, "writing ctrl=0x%08x\n", reg);
214         priv->write(reg, &regs->ctrl);
215  
216 -       /* print chip status */
217 -       netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
218 -                  priv->read(&regs->mcr), priv->read(&regs->ctrl));
219 +       if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) {
220 +               reg_cbt = priv->read(&regs->cbt);
221 +               reg_cbt &= ~(FLEXCAN_CBT_EPRESDIV(0x3ff) |
222 +                            FLEXCAN_CBT_EPSEG1(0x1f) |
223 +                            FLEXCAN_CBT_EPSEG2(0x1f) |
224 +                            FLEXCAN_CBT_ERJW(0x1f) |
225 +                            FLEXCAN_CBT_EPROPSEG(0x3f) |
226 +                            FLEXCAN_CBT_BTF);
227 +
228 +               /* CBT[EPSEG1] is 5 bit long and CBT[EPROPSEG] is 6 bit long.
229 +                * The can_calc_bittiming tries to divide the tseg1 equally
230 +                * between phase_seg1 and prop_seg, which may not fit in CBT
231 +                * register. Therefore, if phase_seg1 is more than possible
232 +                * value, increase prop_seg and decrease phase_seg1
233 +                */
234 +               if (bt->phase_seg1 > 0x20) {
235 +                       bt->prop_seg += (bt->phase_seg1 - 0x20);
236 +                       bt->phase_seg1 = 0x20;
237 +               }
238 +
239 +               reg_cbt = FLEXCAN_CBT_EPRESDIV(bt->brp - 1) |
240 +                               FLEXCAN_CBT_EPSEG1(bt->phase_seg1 - 1) |
241 +                               FLEXCAN_CBT_EPSEG2(bt->phase_seg2 - 1) |
242 +                               FLEXCAN_CBT_ERJW(bt->sjw - 1) |
243 +                               FLEXCAN_CBT_EPROPSEG(bt->prop_seg - 1) |
244 +                               FLEXCAN_CBT_BTF;
245 +               priv->write(reg_cbt, &regs->cbt);
246 +
247 +               netdev_dbg(dev, "bt: prediv %d seg1 %d seg2 %d rjw %d propseg %d\n",
248 +                          bt->brp - 1, bt->phase_seg1 - 1, bt->phase_seg2 - 1,
249 +                          bt->sjw - 1, bt->prop_seg - 1);
250 +
251 +               if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
252 +                       reg_fdcbt = priv->read(&regs->fdcbt);
253 +                       reg_fdcbt &= ~(FLEXCAN_FDCBT_FPRESDIV(0x3ff) |
254 +                                      FLEXCAN_FDCBT_FPSEG1(0x07) |
255 +                                      FLEXCAN_FDCBT_FPSEG2(0x07) |
256 +                                      FLEXCAN_FDCBT_FRJW(0x07) |
257 +                                      FLEXCAN_FDCBT_FPROPSEG(0x1f));
258 +
259 +                       /* FDCBT[FPSEG1] is 3 bit long and FDCBT[FPROPSEG] is 5 bit long.
260 +                        * The can_calc_bittiming tries to divide the tseg1 equally
261 +                        * between phase_seg1 and prop_seg, which may not fit in FDCBT
262 +                        * register. Therefore, if phase_seg1 is more than possible
263 +                        * value, increase prop_seg and decrease phase_seg1
264 +                        */
265 +                       if (dbt->phase_seg1 > 0x8) {
266 +                               dbt->prop_seg += (dbt->phase_seg1 - 0x8);
267 +                               dbt->phase_seg1 = 0x8;
268 +                       }
269 +
270 +                       reg_fdcbt = FLEXCAN_FDCBT_FPRESDIV(dbt->brp - 1) |
271 +                                       FLEXCAN_FDCBT_FPSEG1(dbt->phase_seg1 - 1) |
272 +                                       FLEXCAN_FDCBT_FPSEG2(dbt->phase_seg2 - 1) |
273 +                                       FLEXCAN_FDCBT_FRJW(dbt->sjw - 1) |
274 +                                       FLEXCAN_FDCBT_FPROPSEG(dbt->prop_seg);
275 +                       priv->write(reg_fdcbt, &regs->fdcbt);
276 +
277 +                       if (bt->brp != dbt->brp)
278 +                               netdev_warn(dev, "Warning!! data brp = %d and brp = %d don't match.\n"
279 +                                           "flexcan may not work. consider using different bitrate or data bitrate\n",
280 +                                           dbt->brp, bt->brp);
281 +
282 +                       netdev_dbg(dev, "fdbt: prediv %d seg1 %d seg2 %d rjw %d propseg %d\n",
283 +                                  dbt->brp - 1, dbt->phase_seg1 - 1, dbt->phase_seg2 - 1,
284 +                                  dbt->sjw - 1, dbt->prop_seg);
285 +
286 +                       netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x cbt=0x%08x fdcbt=0x%08x\n",
287 +                                  __func__, priv->read(&regs->mcr),
288 +                                  priv->read(&regs->ctrl),
289 +                                  priv->read(&regs->cbt),
290 +                                  priv->read(&regs->fdcbt));
291 +               }
292 +       } else {
293 +               reg = priv->read(&regs->ctrl);
294 +               reg &= ~(FLEXCAN_CTRL_PRESDIV(0xff) |
295 +                        FLEXCAN_CTRL_RJW(0x3) |
296 +                        FLEXCAN_CTRL_PSEG1(0x7) |
297 +                        FLEXCAN_CTRL_PSEG2(0x7) |
298 +                        FLEXCAN_CTRL_PROPSEG(0x7));
299 +
300 +               reg |= FLEXCAN_CTRL_PRESDIV(bt->brp - 1) |
301 +                       FLEXCAN_CTRL_PSEG1(bt->phase_seg1 - 1) |
302 +                       FLEXCAN_CTRL_PSEG2(bt->phase_seg2 - 1) |
303 +                       FLEXCAN_CTRL_RJW(bt->sjw - 1) |
304 +                       FLEXCAN_CTRL_PROPSEG(bt->prop_seg - 1);
305 +               priv->write(reg, &regs->ctrl);
306 +
307 +               netdev_dbg(dev, "bt: prediv %d seg1 %d seg2 %d rjw %d propseg %d\n",
308 +                          bt->brp - 1, bt->phase_seg1 - 1, bt->phase_seg2 - 1,
309 +                          bt->sjw - 1, bt->prop_seg - 1);
310 +
311 +               /* print chip status */
312 +               netdev_dbg(dev, "%s: mcr=0x%08x ctrl=0x%08x\n", __func__,
313 +                          priv->read(&regs->mcr), priv->read(&regs->ctrl));
314 +       }
315  }
316  
317  /* flexcan_chip_start
318 @@ -1066,7 +1214,7 @@ static int flexcan_chip_start(struct net
319  {
320         struct flexcan_priv *priv = netdev_priv(dev);
321         struct flexcan_regs __iomem *regs = priv->regs;
322 -       u32 reg_mcr, reg_ctrl, reg_ctrl2, reg_mecr;
323 +       u32 reg_mcr, reg_ctrl, reg_ctrl2, reg_mecr, reg_fdctrl;
324         u64 reg_imask;
325         int err, i;
326         struct flexcan_mb __iomem *mb;
327 @@ -1163,6 +1311,26 @@ static int flexcan_chip_start(struct net
328         netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl);
329         priv->write(reg_ctrl, &regs->ctrl);
330  
331 +       /* FDCTRL */
332 +       if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) {
333 +               reg_fdctrl = priv->read(&regs->fdctrl) & ~FLEXCAN_FDCTRL_FDRATE;
334 +               reg_fdctrl &= ~(FLEXCAN_FDCTRL_MBDSR1(0x3) | FLEXCAN_FDCTRL_MBDSR0(0x3));
335 +               reg_mcr = priv->read(&regs->mcr) & ~FLEXCAN_MCR_FDEN;
336 +
337 +               /* support BRS when set CAN FD mode
338 +                * 64 bytes payload per MB and 7 MBs per RAM block by default
339 +                * enable CAN FD mode
340 +                */
341 +               if (priv->can.ctrlmode & CAN_CTRLMODE_FD) {
342 +                       reg_fdctrl |= FLEXCAN_FDCTRL_FDRATE;
343 +                       reg_fdctrl |= FLEXCAN_FDCTRL_MBDSR1(0x3) | FLEXCAN_FDCTRL_MBDSR0(0x3);
344 +                       reg_mcr |= FLEXCAN_MCR_FDEN;
345 +               }
346 +
347 +               priv->write(reg_fdctrl, &regs->fdctrl);
348 +               priv->write(reg_mcr, &regs->mcr);
349 +       }
350 +
351         if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) {
352                 reg_ctrl2 = priv->read(&regs->ctrl2);
353                 reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS;
354 @@ -1288,6 +1456,12 @@ static int flexcan_open(struct net_devic
355         struct flexcan_priv *priv = netdev_priv(dev);
356         int err;
357  
358 +       if ((priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) &&
359 +           (priv->can.ctrlmode & CAN_CTRLMODE_FD)) {
360 +               netdev_err(dev, "three samples mode and fd mode can't be used together\n");
361 +               return -EINVAL;
362 +       }
363 +
364         err = pm_runtime_get_sync(priv->dev);
365         if (err < 0)
366                 return err;
367 @@ -1300,7 +1474,10 @@ static int flexcan_open(struct net_devic
368         if (err)
369                 goto out_close;
370  
371 -       priv->mb_size = sizeof(struct flexcan_mb) + CAN_MAX_DLEN;
372 +       if (priv->can.ctrlmode & CAN_CTRLMODE_FD)
373 +               priv->mb_size = sizeof(struct flexcan_mb) + CANFD_MAX_DLEN;
374 +       else
375 +               priv->mb_size = sizeof(struct flexcan_mb) + CAN_MAX_DLEN;
376         priv->mb_count = (sizeof(priv->regs->mb[0]) / priv->mb_size) +
377                          (sizeof(priv->regs->mb[1]) / priv->mb_size);
378  
379 @@ -1645,6 +1822,18 @@ static int flexcan_probe(struct platform
380         priv->devtype_data = devtype_data;
381         priv->reg_xceiver = reg_xceiver;
382  
383 +       if (priv->devtype_data->quirks & FLEXCAN_QUIRK_TIMESTAMP_SUPPORT_FD) {
384 +               if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) {
385 +                       priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD;
386 +                       priv->can.bittiming_const = &flexcan_fd_bittiming_const;
387 +                       priv->can.data_bittiming_const = &flexcan_fd_data_bittiming_const;
388 +               } else {
389 +                       dev_err(&pdev->dev, "can fd mode can't work on fifo mode\n");
390 +                       err = -EINVAL;
391 +                       goto failed_register;
392 +               }
393 +       }
394 +
395         pm_runtime_get_noresume(&pdev->dev);
396         pm_runtime_set_active(&pdev->dev);
397         pm_runtime_enable(&pdev->dev);