aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/can/flexcan.c81
1 files changed, 71 insertions, 10 deletions
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
index 6bfe24aefea0..ff1beb92a985 100644
--- a/drivers/net/can/flexcan.c
+++ b/drivers/net/can/flexcan.c
@@ -92,6 +92,27 @@
92#define FLEXCAN_CTRL_ERR_ALL \ 92#define FLEXCAN_CTRL_ERR_ALL \
93 (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE) 93 (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE)
94 94
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
95/* FLEXCAN error and status register (ESR) bits */ 116/* FLEXCAN error and status register (ESR) bits */
96#define FLEXCAN_ESR_TWRN_INT BIT(17) 117#define FLEXCAN_ESR_TWRN_INT BIT(17)
97#define FLEXCAN_ESR_RWRN_INT BIT(16) 118#define FLEXCAN_ESR_RWRN_INT BIT(16)
@@ -150,18 +171,20 @@
150 * FLEXCAN hardware feature flags 171 * FLEXCAN hardware feature flags
151 * 172 *
152 * Below is some version info we got: 173 * Below is some version info we got:
153 * SOC Version IP-Version Glitch- [TR]WRN_INT 174 * SOC Version IP-Version Glitch- [TR]WRN_INT Memory err
154 * Filter? connected? 175 * Filter? connected? detection
155 * MX25 FlexCAN2 03.00.00.00 no no 176 * MX25 FlexCAN2 03.00.00.00 no no no
156 * MX28 FlexCAN2 03.00.04.00 yes yes 177 * MX28 FlexCAN2 03.00.04.00 yes yes no
157 * MX35 FlexCAN2 03.00.00.00 no no 178 * MX35 FlexCAN2 03.00.00.00 no no no
158 * MX53 FlexCAN2 03.00.00.00 yes no 179 * MX53 FlexCAN2 03.00.00.00 yes no no
159 * MX6s FlexCAN3 10.00.12.00 yes yes 180 * MX6s FlexCAN3 10.00.12.00 yes yes no
181 * VF610 FlexCAN3 ? no yes yes
160 * 182 *
161 * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. 183 * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
162 */ 184 */
163#define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */ 185#define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */
164#define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */ 186#define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */
187#define FLEXCAN_HAS_MECR_FEATURES BIT(3) /* Memory error detection */
165 188
166/* Structure of the message buffer */ 189/* Structure of the message buffer */
167struct flexcan_mb { 190struct flexcan_mb {
@@ -192,8 +215,17 @@ struct flexcan_regs {
192 u32 crcr; /* 0x44 */ 215 u32 crcr; /* 0x44 */
193 u32 rxfgmask; /* 0x48 */ 216 u32 rxfgmask; /* 0x48 */
194 u32 rxfir; /* 0x4c */ 217 u32 rxfir; /* 0x4c */
195 u32 _reserved3[12]; 218 u32 _reserved3[12]; /* 0x50 */
196 struct flexcan_mb cantxfg[64]; 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 */
197}; 229};
198 230
199struct flexcan_devtype_data { 231struct flexcan_devtype_data {
@@ -223,6 +255,9 @@ static struct flexcan_devtype_data fsl_imx28_devtype_data;
223static struct flexcan_devtype_data fsl_imx6q_devtype_data = { 255static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
224 .features = FLEXCAN_HAS_V10_FEATURES, 256 .features = FLEXCAN_HAS_V10_FEATURES,
225}; 257};
258static struct flexcan_devtype_data fsl_vf610_devtype_data = {
259 .features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_MECR_FEATURES,
260};
226 261
227static const struct can_bittiming_const flexcan_bittiming_const = { 262static const struct can_bittiming_const flexcan_bittiming_const = {
228 .name = DRV_NAME, 263 .name = DRV_NAME,
@@ -817,7 +852,7 @@ static int flexcan_chip_start(struct net_device *dev)
817 struct flexcan_priv *priv = netdev_priv(dev); 852 struct flexcan_priv *priv = netdev_priv(dev);
818 struct flexcan_regs __iomem *regs = priv->base; 853 struct flexcan_regs __iomem *regs = priv->base;
819 int err; 854 int err;
820 u32 reg_mcr, reg_ctrl; 855 u32 reg_mcr, reg_ctrl, reg_crl2, reg_mecr;
821 856
822 /* enable module */ 857 /* enable module */
823 err = flexcan_chip_enable(priv); 858 err = flexcan_chip_enable(priv);
@@ -894,6 +929,31 @@ static int flexcan_chip_start(struct net_device *dev)
894 if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES) 929 if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES)
895 flexcan_write(0x0, &regs->rxfgmask); 930 flexcan_write(0x0, &regs->rxfgmask);
896 931
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
897 err = flexcan_transceiver_enable(priv); 957 err = flexcan_transceiver_enable(priv);
898 if (err) 958 if (err)
899 goto out_chip_disable; 959 goto out_chip_disable;
@@ -1104,6 +1164,7 @@ static const struct of_device_id flexcan_of_match[] = {
1104 { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, }, 1164 { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
1105 { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, }, 1165 { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
1106 { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, }, 1166 { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
1167 { .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, },
1107 { /* sentinel */ }, 1168 { /* sentinel */ },
1108}; 1169};
1109MODULE_DEVICE_TABLE(of, flexcan_of_match); 1170MODULE_DEVICE_TABLE(of, flexcan_of_match);