Skip to content

Commit cdce844

Browse files
agnersmarckleinebudde
authored andcommitted
can: flexcan: add vf610 support for FlexCAN
Extend FlexCAN driver to support Vybrid. Vybrids variant of the IP has ECC support which is controlled through the memory error control register (MECR). There is also an errata which leads to false positive error detections (ID e5295). This patch disables the memory error detection completely. Signed-off-by: Stefan Agner <stefan@agner.ch> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
1 parent ec56acf commit cdce844

File tree

1 file changed

+71
-10
lines changed

1 file changed

+71
-10
lines changed

drivers/net/can/flexcan.c

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,27 @@
9292
#define FLEXCAN_CTRL_ERR_ALL \
9393
(FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE)
9494

95+
/* FLEXCAN control register 2 (CTRL2) bits */
96+
#define FLEXCAN_CRL2_ECRWRE BIT(29)
97+
#define FLEXCAN_CRL2_WRMFRZ BIT(28)
98+
#define FLEXCAN_CRL2_RFFN(x) (((x) & 0x0f) << 24)
99+
#define FLEXCAN_CRL2_TASD(x) (((x) & 0x1f) << 19)
100+
#define FLEXCAN_CRL2_MRP BIT(18)
101+
#define FLEXCAN_CRL2_RRS BIT(17)
102+
#define FLEXCAN_CRL2_EACEN BIT(16)
103+
104+
/* FLEXCAN memory error control register (MECR) bits */
105+
#define FLEXCAN_MECR_ECRWRDIS BIT(31)
106+
#define FLEXCAN_MECR_HANCEI_MSK BIT(19)
107+
#define FLEXCAN_MECR_FANCEI_MSK BIT(18)
108+
#define FLEXCAN_MECR_CEI_MSK BIT(16)
109+
#define FLEXCAN_MECR_HAERRIE BIT(15)
110+
#define FLEXCAN_MECR_FAERRIE BIT(14)
111+
#define FLEXCAN_MECR_EXTERRIE BIT(13)
112+
#define FLEXCAN_MECR_RERRDIS BIT(9)
113+
#define FLEXCAN_MECR_ECCDIS BIT(8)
114+
#define FLEXCAN_MECR_NCEFAFRZ BIT(7)
115+
95116
/* FLEXCAN error and status register (ESR) bits */
96117
#define FLEXCAN_ESR_TWRN_INT BIT(17)
97118
#define FLEXCAN_ESR_RWRN_INT BIT(16)
@@ -150,18 +171,20 @@
150171
* FLEXCAN hardware feature flags
151172
*
152173
* Below is some version info we got:
153-
* SOC Version IP-Version Glitch- [TR]WRN_INT
154-
* Filter? connected?
155-
* MX25 FlexCAN2 03.00.00.00 no no
156-
* MX28 FlexCAN2 03.00.04.00 yes yes
157-
* MX35 FlexCAN2 03.00.00.00 no no
158-
* MX53 FlexCAN2 03.00.00.00 yes no
159-
* MX6s FlexCAN3 10.00.12.00 yes yes
174+
* SOC Version IP-Version Glitch- [TR]WRN_INT Memory err
175+
* Filter? connected? detection
176+
* MX25 FlexCAN2 03.00.00.00 no no no
177+
* MX28 FlexCAN2 03.00.04.00 yes yes no
178+
* MX35 FlexCAN2 03.00.00.00 no no no
179+
* MX53 FlexCAN2 03.00.00.00 yes no no
180+
* MX6s FlexCAN3 10.00.12.00 yes yes no
181+
* VF610 FlexCAN3 ? no yes yes
160182
*
161183
* Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
162184
*/
163185
#define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */
164186
#define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */
187+
#define FLEXCAN_HAS_MECR_FEATURES BIT(3) /* Memory error detection */
165188

166189
/* Structure of the message buffer */
167190
struct flexcan_mb {
@@ -192,8 +215,17 @@ struct flexcan_regs {
192215
u32 crcr; /* 0x44 */
193216
u32 rxfgmask; /* 0x48 */
194217
u32 rxfir; /* 0x4c */
195-
u32 _reserved3[12];
196-
struct flexcan_mb cantxfg[64];
218+
u32 _reserved3[12]; /* 0x50 */
219+
struct flexcan_mb cantxfg[64]; /* 0x80 */
220+
u32 _reserved4[408];
221+
u32 mecr; /* 0xae0 */
222+
u32 erriar; /* 0xae4 */
223+
u32 erridpr; /* 0xae8 */
224+
u32 errippr; /* 0xaec */
225+
u32 rerrar; /* 0xaf0 */
226+
u32 rerrdr; /* 0xaf4 */
227+
u32 rerrsynr; /* 0xaf8 */
228+
u32 errsr; /* 0xafc */
197229
};
198230

199231
struct flexcan_devtype_data {
@@ -223,6 +255,9 @@ static struct flexcan_devtype_data fsl_imx28_devtype_data;
223255
static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
224256
.features = FLEXCAN_HAS_V10_FEATURES,
225257
};
258+
static struct flexcan_devtype_data fsl_vf610_devtype_data = {
259+
.features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_MECR_FEATURES,
260+
};
226261

227262
static const struct can_bittiming_const flexcan_bittiming_const = {
228263
.name = DRV_NAME,
@@ -817,7 +852,7 @@ static int flexcan_chip_start(struct net_device *dev)
817852
struct flexcan_priv *priv = netdev_priv(dev);
818853
struct flexcan_regs __iomem *regs = priv->base;
819854
int err;
820-
u32 reg_mcr, reg_ctrl;
855+
u32 reg_mcr, reg_ctrl, reg_crl2, reg_mecr;
821856

822857
/* enable module */
823858
err = flexcan_chip_enable(priv);
@@ -894,6 +929,31 @@ static int flexcan_chip_start(struct net_device *dev)
894929
if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES)
895930
flexcan_write(0x0, &regs->rxfgmask);
896931

932+
/*
933+
* On Vybrid, disable memory error detection interrupts
934+
* and freeze mode.
935+
* This also works around errata e5295 which generates
936+
* false positive memory errors and put the device in
937+
* freeze mode.
938+
*/
939+
if (priv->devtype_data->features & FLEXCAN_HAS_MECR_FEATURES) {
940+
/*
941+
* Follow the protocol as described in "Detection
942+
* and Correction of Memory Errors" to write to
943+
* MECR register
944+
*/
945+
reg_crl2 = flexcan_read(&regs->crl2);
946+
reg_crl2 |= FLEXCAN_CRL2_ECRWRE;
947+
flexcan_write(reg_crl2, &regs->crl2);
948+
949+
reg_mecr = flexcan_read(&regs->mecr);
950+
reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
951+
flexcan_write(reg_mecr, &regs->mecr);
952+
reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
953+
FLEXCAN_MECR_FANCEI_MSK);
954+
flexcan_write(reg_mecr, &regs->mecr);
955+
}
956+
897957
err = flexcan_transceiver_enable(priv);
898958
if (err)
899959
goto out_chip_disable;
@@ -1104,6 +1164,7 @@ static const struct of_device_id flexcan_of_match[] = {
11041164
{ .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
11051165
{ .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
11061166
{ .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
1167+
{ .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, },
11071168
{ /* sentinel */ },
11081169
};
11091170
MODULE_DEVICE_TABLE(of, flexcan_of_match);

0 commit comments

Comments
 (0)