aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/can/flexcan.c
diff options
context:
space:
mode:
authorStefan Agner <stefan@agner.ch>2014-07-15 08:56:21 -0400
committerMarc Kleine-Budde <mkl@pengutronix.de>2014-08-17 19:03:39 -0400
commitcdce844865bea6869b34bacc98af3711774f5bb5 (patch)
treef661a13e9f5f503a0cdbfb45723181c63bcbb45e /drivers/net/can/flexcan.c
parentec56acfef2af184ca485ffeba16adbd56c110c94 (diff)
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>
Diffstat (limited to 'drivers/net/can/flexcan.c')
-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);