[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <DB7PR04MB4618848506D2B1B4ECF00D0CE6FC0@DB7PR04MB4618.eurprd04.prod.outlook.com>
Date: Wed, 11 Mar 2020 08:50:55 +0000
From: Joakim Zhang <qiangqing.zhang@....com>
To: "mkl@...gutronix.de" <mkl@...gutronix.de>,
"linux-can@...r.kernel.org" <linux-can@...r.kernel.org>
CC: dl-linux-imx <linux-imx@....com>,
"netdev@...r.kernel.org" <netdev@...r.kernel.org>
Subject: RE: [PATCH linux-can-next] can: flexcan: add correctable errors
correction when HW supports ECC
Kindly Ping...
Best Regards,
Joakim Zhang
> -----Original Message-----
> From: Joakim Zhang <qiangqing.zhang@....com>
> Sent: 2020年2月12日 19:46
> To: mkl@...gutronix.de; linux-can@...r.kernel.org
> Cc: dl-linux-imx <linux-imx@....com>; netdev@...r.kernel.org
> Subject: [PATCH linux-can-next] can: flexcan: add correctable errors correction
> when HW supports ECC
>
> commit cdce844865be ("can: flexcan: add vf610 support for FlexCAN") From
> above commit by Stefan Agner, the patch just disables non-correctable errors
> interrupt and freeze mode. It still can correct the correctable errors since ECC
> enabled by default after reset (MECR[ECCDIS]=0, enable memory error correct)
> if HW supports ECC.
>
> commit 5e269324db5a ("can: flexcan: disable completely the ECC mechanism")
> From above commit by Joakim Zhang, the patch disables ECC completely
> (assert
> MECR[ECCDIS]) according to the explanation of
> FLEXCAN_QUIRK_DISABLE_MECR that disable memory error detection. This
> cause correctable errors cannot be corrected even HW supports ECC.
>
> The error correction mechanism ensures that in this 13-bit word, errors in one
> bit can be corrected (correctable errors) and errors in two bits can be detected
> but not corrected (non-correctable errors). Errors in more than two bits may
> not be detected.
>
> If HW supports ECC, we can use this to correct the correctable errors detected
> from FlexCAN memory. Then disable non-correctable errors interrupt and
> freeze mode to avoid that put FlexCAN in freeze mode.
>
> This patch adds correctable errors correction when HW supports ECC, and
> modify explanation for FLEXCAN_QUIRK_DISABLE_MECR.
>
> Signed-off-by: Joakim Zhang <qiangqing.zhang@....com>
> ---
> drivers/net/can/flexcan.c | 23 ++++++++++++++++++-----
> 1 file changed, 18 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c index
> 3a754355ebe6..aa871953003a 100644
> --- a/drivers/net/can/flexcan.c
> +++ b/drivers/net/can/flexcan.c
> @@ -187,7 +187,7 @@
> #define FLEXCAN_QUIRK_BROKEN_WERR_STATE BIT(1) /* [TR]WRN_INT
> not connected */
> #define FLEXCAN_QUIRK_DISABLE_RXFG BIT(2) /* Disable RX FIFO Global
> mask */
> #define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) /* Enable EACEN and
> RRS bit in ctrl2 */
> -#define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) /* Disable Memory error
> detection */
> +#define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) /* Disable non-correctable
> errors interrupt and freeze mode */
> #define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) /* Use timestamp
> based offloading */
> #define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) /* No interrupt for
> error passive */
> #define FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN BIT(7) /* default to BE
> register access */
> @@ -1203,8 +1203,8 @@ static int flexcan_chip_start(struct net_device *dev)
> for (i = 0; i < priv->mb_count; i++)
> priv->write(0, ®s->rximr[i]);
>
> - /* On Vybrid, disable memory error detection interrupts
> - * and freeze mode.
> + /* On Vybrid, disable non-correctable errors interrupt and freeze
> + * mode. It still can correct the correctable errors when HW supports
> ECC.
> * This also works around errata e5295 which generates
> * false positive memory errors and put the device in
> * freeze mode.
> @@ -1212,19 +1212,32 @@ static int flexcan_chip_start(struct net_device
> *dev)
> if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_MECR) {
> /* Follow the protocol as described in "Detection
> * and Correction of Memory Errors" to write to
> - * MECR register
> + * MECR register (step 1 - 5)
> + * 1. By default, CTRL2[ECRWRE] = 0, MECR[ECRWRDIS] = 1
> + * 2. set CTRL2[ECRWRE]
> */
> reg_ctrl2 = priv->read(®s->ctrl2);
> reg_ctrl2 |= FLEXCAN_CTRL2_ECRWRE;
> priv->write(reg_ctrl2, ®s->ctrl2);
>
> + /* 3. clear MECR[ECRWRDIS] */
> reg_mecr = priv->read(®s->mecr);
> reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
> priv->write(reg_mecr, ®s->mecr);
> - reg_mecr |= FLEXCAN_MECR_ECCDIS;
> +
> + /* 4. all writes to MECR must keep MECR[ECRWRDIS] cleared */
> reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ |
> FLEXCAN_MECR_HANCEI_MSK |
> FLEXCAN_MECR_FANCEI_MSK);
> priv->write(reg_mecr, ®s->mecr);
> +
> + /* 5. after configuration done, lock MECR by either setting
> + * MECR[ECRWRDIS] or clearing CTRL2[ECRWRE]
> + */
> + reg_mecr |= FLEXCAN_MECR_ECRWRDIS;
> + priv->write(reg_mecr, ®s->mecr);
> + reg_ctrl2 &= ~FLEXCAN_CTRL2_ECRWRE;
> + priv->write(reg_ctrl2, ®s->ctrl2);
> +
> }
>
> err = flexcan_transceiver_enable(priv);
> --
> 2.17.1
Powered by blists - more mailing lists