|
92 | 92 | #define FLEXCAN_CTRL_ERR_ALL \
|
93 | 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 | 116 | /* FLEXCAN error and status register (ESR) bits */
|
96 | 117 | #define FLEXCAN_ESR_TWRN_INT BIT(17)
|
97 | 118 | #define FLEXCAN_ESR_RWRN_INT BIT(16)
|
|
150 | 171 | * FLEXCAN hardware feature flags
|
151 | 172 | *
|
152 | 173 | * 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 |
160 | 182 | *
|
161 | 183 | * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
|
162 | 184 | */
|
163 | 185 | #define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */
|
164 | 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 | 189 | /* Structure of the message buffer */
|
167 | 190 | struct flexcan_mb {
|
@@ -192,8 +215,17 @@ struct flexcan_regs {
|
192 | 215 | u32 crcr; /* 0x44 */
|
193 | 216 | u32 rxfgmask; /* 0x48 */
|
194 | 217 | 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 */ |
197 | 229 | };
|
198 | 230 |
|
199 | 231 | struct flexcan_devtype_data {
|
@@ -223,6 +255,9 @@ static struct flexcan_devtype_data fsl_imx28_devtype_data;
|
223 | 255 | static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
|
224 | 256 | .features = FLEXCAN_HAS_V10_FEATURES,
|
225 | 257 | };
|
| 258 | +static struct flexcan_devtype_data fsl_vf610_devtype_data = { |
| 259 | + .features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_MECR_FEATURES, |
| 260 | +}; |
226 | 261 |
|
227 | 262 | static const struct can_bittiming_const flexcan_bittiming_const = {
|
228 | 263 | .name = DRV_NAME,
|
@@ -817,7 +852,7 @@ static int flexcan_chip_start(struct net_device *dev)
|
817 | 852 | struct flexcan_priv *priv = netdev_priv(dev);
|
818 | 853 | struct flexcan_regs __iomem *regs = priv->base;
|
819 | 854 | int err;
|
820 |
| - u32 reg_mcr, reg_ctrl; |
| 855 | + u32 reg_mcr, reg_ctrl, reg_crl2, reg_mecr; |
821 | 856 |
|
822 | 857 | /* enable module */
|
823 | 858 | err = flexcan_chip_enable(priv);
|
@@ -894,6 +929,31 @@ static int flexcan_chip_start(struct net_device *dev)
|
894 | 929 | if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES)
|
895 | 930 | flexcan_write(0x0, ®s->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(®s->crl2); |
| 946 | + reg_crl2 |= FLEXCAN_CRL2_ECRWRE; |
| 947 | + flexcan_write(reg_crl2, ®s->crl2); |
| 948 | + |
| 949 | + reg_mecr = flexcan_read(®s->mecr); |
| 950 | + reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS; |
| 951 | + flexcan_write(reg_mecr, ®s->mecr); |
| 952 | + reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK | |
| 953 | + FLEXCAN_MECR_FANCEI_MSK); |
| 954 | + flexcan_write(reg_mecr, ®s->mecr); |
| 955 | + } |
| 956 | + |
897 | 957 | err = flexcan_transceiver_enable(priv);
|
898 | 958 | if (err)
|
899 | 959 | goto out_chip_disable;
|
@@ -1104,6 +1164,7 @@ static const struct of_device_id flexcan_of_match[] = {
|
1104 | 1164 | { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
|
1105 | 1165 | { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
|
1106 | 1166 | { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
|
| 1167 | + { .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, }, |
1107 | 1168 | { /* sentinel */ },
|
1108 | 1169 | };
|
1109 | 1170 | MODULE_DEVICE_TABLE(of, flexcan_of_match);
|
|
0 commit comments