#define FLEXCAN_CTRL_ERR_ALL \
        (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE)
 
+/* FLEXCAN control register 2 (CTRL2) bits */
+#define FLEXCAN_CRL2_ECRWRE            BIT(29)
+#define FLEXCAN_CRL2_WRMFRZ            BIT(28)
+#define FLEXCAN_CRL2_RFFN(x)           (((x) & 0x0f) << 24)
+#define FLEXCAN_CRL2_TASD(x)           (((x) & 0x1f) << 19)
+#define FLEXCAN_CRL2_MRP               BIT(18)
+#define FLEXCAN_CRL2_RRS               BIT(17)
+#define FLEXCAN_CRL2_EACEN             BIT(16)
+
+/* FLEXCAN memory error control register (MECR) bits */
+#define FLEXCAN_MECR_ECRWRDIS          BIT(31)
+#define FLEXCAN_MECR_HANCEI_MSK                BIT(19)
+#define FLEXCAN_MECR_FANCEI_MSK                BIT(18)
+#define FLEXCAN_MECR_CEI_MSK           BIT(16)
+#define FLEXCAN_MECR_HAERRIE           BIT(15)
+#define FLEXCAN_MECR_FAERRIE           BIT(14)
+#define FLEXCAN_MECR_EXTERRIE          BIT(13)
+#define FLEXCAN_MECR_RERRDIS           BIT(9)
+#define FLEXCAN_MECR_ECCDIS            BIT(8)
+#define FLEXCAN_MECR_NCEFAFRZ          BIT(7)
+
 /* FLEXCAN error and status register (ESR) bits */
 #define FLEXCAN_ESR_TWRN_INT           BIT(17)
 #define FLEXCAN_ESR_RWRN_INT           BIT(16)
  * FLEXCAN hardware feature flags
  *
  * Below is some version info we got:
- *    SOC   Version   IP-Version  Glitch-  [TR]WRN_INT
- *                                Filter?   connected?
- *   MX25  FlexCAN2  03.00.00.00     no         no
- *   MX28  FlexCAN2  03.00.04.00    yes        yes
- *   MX35  FlexCAN2  03.00.00.00     no         no
- *   MX53  FlexCAN2  03.00.00.00    yes         no
- *   MX6s  FlexCAN3  10.00.12.00    yes        yes
+ *    SOC   Version   IP-Version  Glitch-  [TR]WRN_INT  Memory err
+ *                                Filter?   connected?  detection
+ *   MX25  FlexCAN2  03.00.00.00     no         no         no
+ *   MX28  FlexCAN2  03.00.04.00    yes        yes         no
+ *   MX35  FlexCAN2  03.00.00.00     no         no         no
+ *   MX53  FlexCAN2  03.00.00.00    yes         no         no
+ *   MX6s  FlexCAN3  10.00.12.00    yes        yes         no
+ *   VF610 FlexCAN3  ?               no        yes        yes
  *
  * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
  */
 #define FLEXCAN_HAS_V10_FEATURES       BIT(1) /* For core version >= 10 */
 #define FLEXCAN_HAS_BROKEN_ERR_STATE   BIT(2) /* [TR]WRN_INT not connected */
+#define FLEXCAN_HAS_MECR_FEATURES      BIT(3) /* Memory error detection */
 
 /* Structure of the message buffer */
 struct flexcan_mb {
        u32 crcr;               /* 0x44 */
        u32 rxfgmask;           /* 0x48 */
        u32 rxfir;              /* 0x4c */
-       u32 _reserved3[12];
-       struct flexcan_mb cantxfg[64];
+       u32 _reserved3[12];     /* 0x50 */
+       struct flexcan_mb cantxfg[64];  /* 0x80 */
+       u32 _reserved4[408];
+       u32 mecr;               /* 0xae0 */
+       u32 erriar;             /* 0xae4 */
+       u32 erridpr;            /* 0xae8 */
+       u32 errippr;            /* 0xaec */
+       u32 rerrar;             /* 0xaf0 */
+       u32 rerrdr;             /* 0xaf4 */
+       u32 rerrsynr;           /* 0xaf8 */
+       u32 errsr;              /* 0xafc */
 };
 
 struct flexcan_devtype_data {
 static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
        .features = FLEXCAN_HAS_V10_FEATURES,
 };
+static struct flexcan_devtype_data fsl_vf610_devtype_data = {
+       .features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_MECR_FEATURES,
+};
 
 static const struct can_bittiming_const flexcan_bittiming_const = {
        .name = DRV_NAME,
        struct flexcan_priv *priv = netdev_priv(dev);
        struct flexcan_regs __iomem *regs = priv->base;
        int err;
-       u32 reg_mcr, reg_ctrl;
+       u32 reg_mcr, reg_ctrl, reg_crl2, reg_mecr;
 
        /* enable module */
        err = flexcan_chip_enable(priv);
        if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES)
                flexcan_write(0x0, ®s->rxfgmask);
 
+       /*
+        * On Vybrid, disable memory error detection interrupts
+        * and freeze mode.
+        * This also works around errata e5295 which generates
+        * false positive memory errors and put the device in
+        * freeze mode.
+        */
+       if (priv->devtype_data->features & FLEXCAN_HAS_MECR_FEATURES) {
+               /*
+                * Follow the protocol as described in "Detection
+                * and Correction of Memory Errors" to write to
+                * MECR register
+                */
+               reg_crl2 = flexcan_read(®s->crl2);
+               reg_crl2 |= FLEXCAN_CRL2_ECRWRE;
+               flexcan_write(reg_crl2, ®s->crl2);
+
+               reg_mecr = flexcan_read(®s->mecr);
+               reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
+               flexcan_write(reg_mecr, ®s->mecr);
+               reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
+                               FLEXCAN_MECR_FANCEI_MSK);
+               flexcan_write(reg_mecr, ®s->mecr);
+       }
+
        err = flexcan_transceiver_enable(priv);
        if (err)
                goto out_chip_disable;
        { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
        { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
        { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
+       { .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, },
        { /* sentinel */ },
 };
 MODULE_DEVICE_TABLE(of, flexcan_of_match);