From: Marc Kleine-Budde <mkl@pengutronix.de>
To: Stefan Agner <stefan@agner.ch>
Cc: wg@grandegger.com, shawn.guo@freescale.com,
kernel@pengutronix.de, linux-arm-kernel@lists.infradead.org,
linux-can@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH] can: flexcan: add vf61x support for flexcan
Date: Fri, 11 Jul 2014 14:09:37 +0200 [thread overview]
Message-ID: <53BFD401.8030101@pengutronix.de> (raw)
In-Reply-To: <1405075933-22317-1-git-send-email-stefan@agner.ch>
[-- Attachment #1: Type: text/plain, Size: 10098 bytes --]
On 07/11/2014 12:52 PM, Stefan Agner wrote:
> 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.
>
> Also extend the clock control for FlexCAN to enable the clocks
> in the Clock Divider (CCM_CSCDR2) register too.
>
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
> Marc, this patch requires your patch regarding clock enable
> for reading the ECR register:
> http://marc.info/?l=linux-can&m=136861025221160&w=2
> So I also tested that patch and it proved solving that issue
> hence
Feel free to pick up that patch (and add the mising return value check
for clock_prepare_enable().
> Tested-By <stefan@agner.ch>
>
> I'm not sure whether its ok to include the device tree and
> clock changes in one patch, let me know if you prefer that
> splitted patches.
IMHO it should be 4 seperate patches:
- dt
- clocks
- flexcan_get_berr_counter fixes
- your flexcan enhancements
The first two patches go probably via Shawn's tree, while the latter two
go via linux-can-next.
> --
> Stefan
>
> arch/arm/boot/dts/vf610.dtsi | 25 ++++++++++++++-
> arch/arm/mach-imx/clk-vf610.c | 6 ++--
> drivers/net/can/flexcan.c | 73 +++++++++++++++++++++++++++++++++++++------
> 3 files changed, 92 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
> index 3fb127a..f38d8d8 100644
> --- a/arch/arm/boot/dts/vf610.dtsi
> +++ b/arch/arm/boot/dts/vf610.dtsi
> @@ -14,6 +14,8 @@
>
> / {
> aliases {
> + can0 = &can0;
> + can1 = &can1;
> serial0 = &uart0;
> serial1 = &uart1;
> serial2 = &uart2;
> @@ -103,6 +105,16 @@
> <&clks VF610_CLK_DMAMUX1>;
> };
>
> + can0: flexcan@40020000 {
> + compatible = "fsl,vf610-flexcan";
> + reg = <0x40020000 0x4000>;
> + interrupts = <0 58 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&clks VF610_CLK_FLEXCAN0>,
> + <&clks VF610_CLK_FLEXCAN0>;
> + clock-names = "ipg", "per";
> + status = "disabled";
> + };
> +
> uart0: serial@40027000 {
> compatible = "fsl,vf610-lpuart";
> reg = <0x40027000 0x1000>;
> @@ -362,7 +374,7 @@
>
> esdhc1: esdhc@400b2000 {
> compatible = "fsl,imx53-esdhc";
> - reg = <0x400b2000 0x4000>;
> + reg = <0x400b2000 0x1000>;
What's that doing here? :)
> interrupts = <0 28 0x04>;
> clocks = <&clks VF610_CLK_IPG_BUS>,
> <&clks VF610_CLK_PLATFORM_BUS>,
> @@ -414,6 +426,17 @@
> clock-names = "nfc";
> status = "disabled";
> };
> +
> + can1: flexcan@400d4000 {
> + compatible = "fsl,vf610-flexcan";
> + reg = <0x400d4000 0x4000>;
> + interrupts = <0 59 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&clks VF610_CLK_FLEXCAN1>,
> + <&clks VF610_CLK_FLEXCAN1>;
> + clock-names = "ipg", "per";
> + status = "disabled";
> + };
> +
> };
> };
> };
> diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c
> index 22dc3ee..b12b888 100644
> --- a/arch/arm/mach-imx/clk-vf610.c
> +++ b/arch/arm/mach-imx/clk-vf610.c
> @@ -295,8 +295,10 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
>
> clk[VF610_CLK_ASRC] = imx_clk_gate2("asrc", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(1));
>
> - clk[VF610_CLK_FLEXCAN0] = imx_clk_gate2("flexcan0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(0));
> - clk[VF610_CLK_FLEXCAN1] = imx_clk_gate2("flexcan1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(4));
> + clk[VF610_CLK_FLEXCAN0] = imx_clk_gate("flexcan0_en", "ipg_bus", CCM_CSCDR2, 11);
> + clk[VF610_CLK_FLEXCAN0] = imx_clk_gate2("flexcan0", "flexcan0_en", CCM_CCGR0, CCM_CCGRx_CGn(0));
> + clk[VF610_CLK_FLEXCAN1] = imx_clk_gate("flexcan1_en", "ipg_bus", CCM_CSCDR2, 12);
> + clk[VF610_CLK_FLEXCAN1] = imx_clk_gate2("flexcan1", "flexcan1_en", CCM_CCGR9, CCM_CCGRx_CGn(4));
>
> clk[VF610_CLK_DMAMUX0] = imx_clk_gate2("dmamux0", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(4));
> clk[VF610_CLK_DMAMUX1] = imx_clk_gate2("dmamux1", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(5));
> diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
> index f425ec2..1601247 100644
> --- a/drivers/net/can/flexcan.c
> +++ b/drivers/net/can/flexcan.c
> @@ -92,6 +92,27 @@
> #define FLEXCAN_CTRL_ERR_ALL \
> (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE)
>
> +/* FLEXCAN control register 2 (CTRL2) bits */
> +#define FLEXCAN_CRL2_ECRWRE BIT(29)
> +#define FLEXCAN_CRL2_WRMFRZ BIT(28)
> +#define FLEXCAN_CRL2_RFFN(x) (((x) & 0x0f) << 24)
> +#define FLEXCAN_CRL2_TASD(x) (((x) & 0x1f) << 19)
> +#define FLEXCAN_CRL2_MRP BIT(18)
> +#define FLEXCAN_CRL2_RRS BIT(17)
> +#define FLEXCAN_CRL2_EACEN BIT(16)
> +
> +/* FLEXCAN memory error control register (MECR) bits */
> +#define FLEXCAN_MECR_ECRWRDIS BIT(31)
> +#define FLEXCAN_MECR_HANCEI_MSK BIT(19)
> +#define FLEXCAN_MECR_FANCEI_MSK BIT(18)
> +#define FLEXCAN_MECR_CEI_MSK BIT(16)
> +#define FLEXCAN_MECR_HAERRIE BIT(15)
> +#define FLEXCAN_MECR_FAERRIE BIT(14)
> +#define FLEXCAN_MECR_EXTERRIE BIT(13)
> +#define FLEXCAN_MECR_RERRDIS BIT(9)
> +#define FLEXCAN_MECR_ECCDIS BIT(8)
> +#define FLEXCAN_MECR_NCEFAFRZ BIT(7)
> +
> /* FLEXCAN error and status register (ESR) bits */
> #define FLEXCAN_ESR_TWRN_INT BIT(17)
> #define FLEXCAN_ESR_RWRN_INT BIT(16)
> @@ -150,18 +171,20 @@
> * FLEXCAN hardware feature flags
> *
> * Below is some version info we got:
> - * SOC Version IP-Version Glitch- [TR]WRN_INT
> - * Filter? connected?
> - * MX25 FlexCAN2 03.00.00.00 no no
> - * MX28 FlexCAN2 03.00.04.00 yes yes
> - * MX35 FlexCAN2 03.00.00.00 no no
> - * MX53 FlexCAN2 03.00.00.00 yes no
> - * MX6s FlexCAN3 10.00.12.00 yes yes
> + * SOC Version IP-Version Glitch- [TR]WRN_INT Memory err
> + * Filter? connected? detection
> + * MX25 FlexCAN2 03.00.00.00 no no no
> + * MX28 FlexCAN2 03.00.04.00 yes yes no
> + * MX35 FlexCAN2 03.00.00.00 no no no
> + * MX53 FlexCAN2 03.00.00.00 yes no no
> + * MX6s FlexCAN3 10.00.12.00 yes yes no
> + * VFxx FlexCAN3 ? no no yes
Please use either tabs or space to indent in this table.
> *
> * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
> */
> #define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */
> #define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */
> +#define FLEXCAN_HAS_MECR_FEATURES BIT(3) /* Memory error detection */
>
> /* Structure of the message buffer */
> struct flexcan_mb {
> @@ -192,8 +215,11 @@ struct flexcan_regs {
> u32 crcr; /* 0x44 */
> u32 rxfgmask; /* 0x48 */
> u32 rxfir; /* 0x4c */
> - u32 _reserved3[12];
> + u32 _reserved3[12]; /* 0x50 */
> struct flexcan_mb cantxfg[64];
> + u32 _reserved4[408];
> + u32 mecr; /* 0xae0 */
> + u32 erriar; /* 0xae4 */
> };
>
> struct flexcan_devtype_data {
> @@ -223,6 +249,9 @@ static struct flexcan_devtype_data fsl_imx28_devtype_data;
> static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
> .features = FLEXCAN_HAS_V10_FEATURES,
> };
> +static struct flexcan_devtype_data fsl_vf610_devtype_data = {
> + .features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_MECR_FEATURES,
> +};
>
> static const struct can_bittiming_const flexcan_bittiming_const = {
> .name = DRV_NAME,
> @@ -793,7 +822,7 @@ static int flexcan_chip_start(struct net_device *dev)
> struct flexcan_priv *priv = netdev_priv(dev);
> struct flexcan_regs __iomem *regs = priv->base;
> int err;
> - u32 reg_mcr, reg_ctrl;
> + u32 reg_mcr, reg_ctrl, reg_crl2, reg_mecr;
>
> /* enable module */
> err = flexcan_chip_enable(priv);
> @@ -870,6 +899,31 @@ static int flexcan_chip_start(struct net_device *dev)
> if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES)
> flexcan_write(0x0, ®s->rxfgmask);
>
> + /*
> + * On Vybrid, disable memory error detection interrupts
> + * and freeze mode.
> + * This also works around errata e5295 which generates
> + * false positive memory errors and put the device in
> + * freeze mode.
> + */
> + if (priv->devtype_data->features & FLEXCAN_HAS_MECR_FEATURES) {
> + /*
> + * Follow the protocol as described in "Detection
> + * and Correction of Memory Errors" to write to
> + * MECR register
> + */
> + reg_crl2 = flexcan_read(®s->crl2);
> + reg_crl2 |= FLEXCAN_CRL2_ECRWRE;
> + flexcan_write(reg_crl2, ®s->crl2);
> +
> + reg_mecr = flexcan_read(®s->mecr);
> + reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
> + flexcan_write(reg_mecr, ®s->mecr);
> + reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
> + FLEXCAN_MECR_FANCEI_MSK);
> + flexcan_write(reg_mecr, ®s->mecr);
> + }
> +
> err = flexcan_transceiver_enable(priv);
> if (err)
> goto out_chip_disable;
> @@ -1080,6 +1134,7 @@ static const struct of_device_id flexcan_of_match[] = {
> { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
> { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
> { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
> + { .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, },
> { /* sentinel */ },
> };
> MODULE_DEVICE_TABLE(of, flexcan_of_match);
>
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 242 bytes --]
WARNING: multiple messages have this Message-ID (diff)
From: mkl@pengutronix.de (Marc Kleine-Budde)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] can: flexcan: add vf61x support for flexcan
Date: Fri, 11 Jul 2014 14:09:37 +0200 [thread overview]
Message-ID: <53BFD401.8030101@pengutronix.de> (raw)
In-Reply-To: <1405075933-22317-1-git-send-email-stefan@agner.ch>
On 07/11/2014 12:52 PM, Stefan Agner wrote:
> 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.
>
> Also extend the clock control for FlexCAN to enable the clocks
> in the Clock Divider (CCM_CSCDR2) register too.
>
> Signed-off-by: Stefan Agner <stefan@agner.ch>
> ---
> Marc, this patch requires your patch regarding clock enable
> for reading the ECR register:
> http://marc.info/?l=linux-can&m=136861025221160&w=2
> So I also tested that patch and it proved solving that issue
> hence
Feel free to pick up that patch (and add the mising return value check
for clock_prepare_enable().
> Tested-By <stefan@agner.ch>
>
> I'm not sure whether its ok to include the device tree and
> clock changes in one patch, let me know if you prefer that
> splitted patches.
IMHO it should be 4 seperate patches:
- dt
- clocks
- flexcan_get_berr_counter fixes
- your flexcan enhancements
The first two patches go probably via Shawn's tree, while the latter two
go via linux-can-next.
> --
> Stefan
>
> arch/arm/boot/dts/vf610.dtsi | 25 ++++++++++++++-
> arch/arm/mach-imx/clk-vf610.c | 6 ++--
> drivers/net/can/flexcan.c | 73 +++++++++++++++++++++++++++++++++++++------
> 3 files changed, 92 insertions(+), 12 deletions(-)
>
> diff --git a/arch/arm/boot/dts/vf610.dtsi b/arch/arm/boot/dts/vf610.dtsi
> index 3fb127a..f38d8d8 100644
> --- a/arch/arm/boot/dts/vf610.dtsi
> +++ b/arch/arm/boot/dts/vf610.dtsi
> @@ -14,6 +14,8 @@
>
> / {
> aliases {
> + can0 = &can0;
> + can1 = &can1;
> serial0 = &uart0;
> serial1 = &uart1;
> serial2 = &uart2;
> @@ -103,6 +105,16 @@
> <&clks VF610_CLK_DMAMUX1>;
> };
>
> + can0: flexcan at 40020000 {
> + compatible = "fsl,vf610-flexcan";
> + reg = <0x40020000 0x4000>;
> + interrupts = <0 58 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&clks VF610_CLK_FLEXCAN0>,
> + <&clks VF610_CLK_FLEXCAN0>;
> + clock-names = "ipg", "per";
> + status = "disabled";
> + };
> +
> uart0: serial at 40027000 {
> compatible = "fsl,vf610-lpuart";
> reg = <0x40027000 0x1000>;
> @@ -362,7 +374,7 @@
>
> esdhc1: esdhc at 400b2000 {
> compatible = "fsl,imx53-esdhc";
> - reg = <0x400b2000 0x4000>;
> + reg = <0x400b2000 0x1000>;
What's that doing here? :)
> interrupts = <0 28 0x04>;
> clocks = <&clks VF610_CLK_IPG_BUS>,
> <&clks VF610_CLK_PLATFORM_BUS>,
> @@ -414,6 +426,17 @@
> clock-names = "nfc";
> status = "disabled";
> };
> +
> + can1: flexcan at 400d4000 {
> + compatible = "fsl,vf610-flexcan";
> + reg = <0x400d4000 0x4000>;
> + interrupts = <0 59 IRQ_TYPE_LEVEL_HIGH>;
> + clocks = <&clks VF610_CLK_FLEXCAN1>,
> + <&clks VF610_CLK_FLEXCAN1>;
> + clock-names = "ipg", "per";
> + status = "disabled";
> + };
> +
> };
> };
> };
> diff --git a/arch/arm/mach-imx/clk-vf610.c b/arch/arm/mach-imx/clk-vf610.c
> index 22dc3ee..b12b888 100644
> --- a/arch/arm/mach-imx/clk-vf610.c
> +++ b/arch/arm/mach-imx/clk-vf610.c
> @@ -295,8 +295,10 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
>
> clk[VF610_CLK_ASRC] = imx_clk_gate2("asrc", "ipg_bus", CCM_CCGR4, CCM_CCGRx_CGn(1));
>
> - clk[VF610_CLK_FLEXCAN0] = imx_clk_gate2("flexcan0", "ipg_bus", CCM_CCGR0, CCM_CCGRx_CGn(0));
> - clk[VF610_CLK_FLEXCAN1] = imx_clk_gate2("flexcan1", "ipg_bus", CCM_CCGR9, CCM_CCGRx_CGn(4));
> + clk[VF610_CLK_FLEXCAN0] = imx_clk_gate("flexcan0_en", "ipg_bus", CCM_CSCDR2, 11);
> + clk[VF610_CLK_FLEXCAN0] = imx_clk_gate2("flexcan0", "flexcan0_en", CCM_CCGR0, CCM_CCGRx_CGn(0));
> + clk[VF610_CLK_FLEXCAN1] = imx_clk_gate("flexcan1_en", "ipg_bus", CCM_CSCDR2, 12);
> + clk[VF610_CLK_FLEXCAN1] = imx_clk_gate2("flexcan1", "flexcan1_en", CCM_CCGR9, CCM_CCGRx_CGn(4));
>
> clk[VF610_CLK_DMAMUX0] = imx_clk_gate2("dmamux0", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(4));
> clk[VF610_CLK_DMAMUX1] = imx_clk_gate2("dmamux1", "platform_bus", CCM_CCGR0, CCM_CCGRx_CGn(5));
> diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
> index f425ec2..1601247 100644
> --- a/drivers/net/can/flexcan.c
> +++ b/drivers/net/can/flexcan.c
> @@ -92,6 +92,27 @@
> #define FLEXCAN_CTRL_ERR_ALL \
> (FLEXCAN_CTRL_ERR_BUS | FLEXCAN_CTRL_ERR_STATE)
>
> +/* FLEXCAN control register 2 (CTRL2) bits */
> +#define FLEXCAN_CRL2_ECRWRE BIT(29)
> +#define FLEXCAN_CRL2_WRMFRZ BIT(28)
> +#define FLEXCAN_CRL2_RFFN(x) (((x) & 0x0f) << 24)
> +#define FLEXCAN_CRL2_TASD(x) (((x) & 0x1f) << 19)
> +#define FLEXCAN_CRL2_MRP BIT(18)
> +#define FLEXCAN_CRL2_RRS BIT(17)
> +#define FLEXCAN_CRL2_EACEN BIT(16)
> +
> +/* FLEXCAN memory error control register (MECR) bits */
> +#define FLEXCAN_MECR_ECRWRDIS BIT(31)
> +#define FLEXCAN_MECR_HANCEI_MSK BIT(19)
> +#define FLEXCAN_MECR_FANCEI_MSK BIT(18)
> +#define FLEXCAN_MECR_CEI_MSK BIT(16)
> +#define FLEXCAN_MECR_HAERRIE BIT(15)
> +#define FLEXCAN_MECR_FAERRIE BIT(14)
> +#define FLEXCAN_MECR_EXTERRIE BIT(13)
> +#define FLEXCAN_MECR_RERRDIS BIT(9)
> +#define FLEXCAN_MECR_ECCDIS BIT(8)
> +#define FLEXCAN_MECR_NCEFAFRZ BIT(7)
> +
> /* FLEXCAN error and status register (ESR) bits */
> #define FLEXCAN_ESR_TWRN_INT BIT(17)
> #define FLEXCAN_ESR_RWRN_INT BIT(16)
> @@ -150,18 +171,20 @@
> * FLEXCAN hardware feature flags
> *
> * Below is some version info we got:
> - * SOC Version IP-Version Glitch- [TR]WRN_INT
> - * Filter? connected?
> - * MX25 FlexCAN2 03.00.00.00 no no
> - * MX28 FlexCAN2 03.00.04.00 yes yes
> - * MX35 FlexCAN2 03.00.00.00 no no
> - * MX53 FlexCAN2 03.00.00.00 yes no
> - * MX6s FlexCAN3 10.00.12.00 yes yes
> + * SOC Version IP-Version Glitch- [TR]WRN_INT Memory err
> + * Filter? connected? detection
> + * MX25 FlexCAN2 03.00.00.00 no no no
> + * MX28 FlexCAN2 03.00.04.00 yes yes no
> + * MX35 FlexCAN2 03.00.00.00 no no no
> + * MX53 FlexCAN2 03.00.00.00 yes no no
> + * MX6s FlexCAN3 10.00.12.00 yes yes no
> + * VFxx FlexCAN3 ? no no yes
Please use either tabs or space to indent in this table.
> *
> * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected.
> */
> #define FLEXCAN_HAS_V10_FEATURES BIT(1) /* For core version >= 10 */
> #define FLEXCAN_HAS_BROKEN_ERR_STATE BIT(2) /* [TR]WRN_INT not connected */
> +#define FLEXCAN_HAS_MECR_FEATURES BIT(3) /* Memory error detection */
>
> /* Structure of the message buffer */
> struct flexcan_mb {
> @@ -192,8 +215,11 @@ struct flexcan_regs {
> u32 crcr; /* 0x44 */
> u32 rxfgmask; /* 0x48 */
> u32 rxfir; /* 0x4c */
> - u32 _reserved3[12];
> + u32 _reserved3[12]; /* 0x50 */
> struct flexcan_mb cantxfg[64];
> + u32 _reserved4[408];
> + u32 mecr; /* 0xae0 */
> + u32 erriar; /* 0xae4 */
> };
>
> struct flexcan_devtype_data {
> @@ -223,6 +249,9 @@ static struct flexcan_devtype_data fsl_imx28_devtype_data;
> static struct flexcan_devtype_data fsl_imx6q_devtype_data = {
> .features = FLEXCAN_HAS_V10_FEATURES,
> };
> +static struct flexcan_devtype_data fsl_vf610_devtype_data = {
> + .features = FLEXCAN_HAS_V10_FEATURES | FLEXCAN_HAS_MECR_FEATURES,
> +};
>
> static const struct can_bittiming_const flexcan_bittiming_const = {
> .name = DRV_NAME,
> @@ -793,7 +822,7 @@ static int flexcan_chip_start(struct net_device *dev)
> struct flexcan_priv *priv = netdev_priv(dev);
> struct flexcan_regs __iomem *regs = priv->base;
> int err;
> - u32 reg_mcr, reg_ctrl;
> + u32 reg_mcr, reg_ctrl, reg_crl2, reg_mecr;
>
> /* enable module */
> err = flexcan_chip_enable(priv);
> @@ -870,6 +899,31 @@ static int flexcan_chip_start(struct net_device *dev)
> if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES)
> flexcan_write(0x0, ®s->rxfgmask);
>
> + /*
> + * On Vybrid, disable memory error detection interrupts
> + * and freeze mode.
> + * This also works around errata e5295 which generates
> + * false positive memory errors and put the device in
> + * freeze mode.
> + */
> + if (priv->devtype_data->features & FLEXCAN_HAS_MECR_FEATURES) {
> + /*
> + * Follow the protocol as described in "Detection
> + * and Correction of Memory Errors" to write to
> + * MECR register
> + */
> + reg_crl2 = flexcan_read(®s->crl2);
> + reg_crl2 |= FLEXCAN_CRL2_ECRWRE;
> + flexcan_write(reg_crl2, ®s->crl2);
> +
> + reg_mecr = flexcan_read(®s->mecr);
> + reg_mecr &= ~FLEXCAN_MECR_ECRWRDIS;
> + flexcan_write(reg_mecr, ®s->mecr);
> + reg_mecr &= ~(FLEXCAN_MECR_NCEFAFRZ | FLEXCAN_MECR_HANCEI_MSK |
> + FLEXCAN_MECR_FANCEI_MSK);
> + flexcan_write(reg_mecr, ®s->mecr);
> + }
> +
> err = flexcan_transceiver_enable(priv);
> if (err)
> goto out_chip_disable;
> @@ -1080,6 +1134,7 @@ static const struct of_device_id flexcan_of_match[] = {
> { .compatible = "fsl,imx6q-flexcan", .data = &fsl_imx6q_devtype_data, },
> { .compatible = "fsl,imx28-flexcan", .data = &fsl_imx28_devtype_data, },
> { .compatible = "fsl,p1010-flexcan", .data = &fsl_p1010_devtype_data, },
> + { .compatible = "fsl,vf610-flexcan", .data = &fsl_vf610_devtype_data, },
> { /* sentinel */ },
> };
> MODULE_DEVICE_TABLE(of, flexcan_of_match);
>
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 242 bytes
Desc: OpenPGP digital signature
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140711/eb322b56/attachment-0001.sig>
next prev parent reply other threads:[~2014-07-11 12:09 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-11 10:52 [PATCH] can: flexcan: add vf61x support for flexcan Stefan Agner
2014-07-11 10:52 ` Stefan Agner
2014-07-11 10:52 ` Stefan Agner
2014-07-11 12:09 ` Marc Kleine-Budde [this message]
2014-07-11 12:09 ` Marc Kleine-Budde
2014-07-11 13:58 ` Stefan Agner
2014-07-11 13:58 ` Stefan Agner
2014-07-11 14:00 ` Lucas Stach
2014-07-11 14:00 ` Lucas Stach
2014-07-11 17:53 ` Marc Kleine-Budde
2014-07-11 17:53 ` Marc Kleine-Budde
2014-07-14 6:04 ` Shawn Guo
2014-07-14 6:04 ` Shawn Guo
2014-07-14 6:04 ` Shawn Guo
2014-07-14 7:06 ` Stefan Agner
2014-07-14 7:06 ` Stefan Agner
2014-07-14 7:10 ` Stefan Agner
2014-07-14 7:10 ` Stefan Agner
2014-07-14 7:32 ` Shawn Guo
2014-07-14 7:32 ` Shawn Guo
2014-07-14 7:32 ` Shawn Guo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=53BFD401.8030101@pengutronix.de \
--to=mkl@pengutronix.de \
--cc=kernel@pengutronix.de \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-can@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=shawn.guo@freescale.com \
--cc=stefan@agner.ch \
--cc=wg@grandegger.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.