From: Biju Das biju.das.jz@bp.renesas.com
The commit 5cff263606a1 ("can: rcar_canfd: Fix controller mode setting") has aligned with the flow mentioned in the hardware manual for all SoCs except R-Car Gen3 and RZ/G2L SoCs. On R-Car Gen4 and RZ/G3E SoCs, due to the wrong logic in the commit[1] sets the default mode to FD-Only mode instead of CAN-FD mode.
This patch sets the CAN-FD mode as the default for all SoCs by dropping the rcar_canfd_set_mode() as some SoC requires mode setting in global reset mode, and the rest of the SoCs in channel reset mode and update the rcar_canfd_reset_controller() to take care of these constraints. Moreover, the RZ/G3E and R-Car Gen4 SoCs support 3 modes compared to 2 modes on the R-Car Gen3. Use inverted logic in rcar_canfd_reset_controller() to simplify the code later to support FD-only mode.
[1] commit 45721c406dcf ("can: rcar_canfd: Add support for r8a779a0 SoC")
Fixes: 5cff263606a1 ("can: rcar_canfd: Fix controller mode setting") Cc: stable@vger.kernel.org Signed-off-by: Biju Das biju.das.jz@bp.renesas.com --- drivers/net/can/rcar/rcar_canfd.c | 53 ++++++++++++++++++------------- 1 file changed, 31 insertions(+), 22 deletions(-)
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c index 49ab65274b51..05dbdf46dd6f 100644 --- a/drivers/net/can/rcar/rcar_canfd.c +++ b/drivers/net/can/rcar/rcar_canfd.c @@ -709,6 +709,11 @@ static void rcar_canfd_set_bit_reg(void __iomem *addr, u32 val) rcar_canfd_update(val, val, addr); }
+static void rcar_canfd_clear_bit_reg(void __iomem *addr, u32 val) +{ + rcar_canfd_update(val, 0, addr); +} + static void rcar_canfd_update_bit_reg(void __iomem *addr, u32 mask, u32 val) { rcar_canfd_update(mask, val, addr); @@ -755,25 +760,6 @@ static void rcar_canfd_set_rnc(struct rcar_canfd_global *gpriv, unsigned int ch, rcar_canfd_set_bit(gpriv->base, RCANFD_GAFLCFG(w), rnc); }
-static void rcar_canfd_set_mode(struct rcar_canfd_global *gpriv) -{ - if (gpriv->info->ch_interface_mode) { - u32 ch, val = gpriv->fdmode ? RCANFD_GEN4_FDCFG_FDOE - : RCANFD_GEN4_FDCFG_CLOE; - - for_each_set_bit(ch, &gpriv->channels_mask, - gpriv->info->max_channels) - rcar_canfd_set_bit_reg(&gpriv->fcbase[ch].cfdcfg, val); - } else { - if (gpriv->fdmode) - rcar_canfd_set_bit(gpriv->base, RCANFD_GRMCFG, - RCANFD_GRMCFG_RCMC); - else - rcar_canfd_clear_bit(gpriv->base, RCANFD_GRMCFG, - RCANFD_GRMCFG_RCMC); - } -} - static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) { struct device *dev = &gpriv->pdev->dev; @@ -806,6 +792,16 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) /* Reset Global error flags */ rcar_canfd_write(gpriv->base, RCANFD_GERFL, 0x0);
+ /* Set the controller into appropriate mode */ + if (!gpriv->info->ch_interface_mode) { + if (gpriv->fdmode) + rcar_canfd_set_bit(gpriv->base, RCANFD_GRMCFG, + RCANFD_GRMCFG_RCMC); + else + rcar_canfd_clear_bit(gpriv->base, RCANFD_GRMCFG, + RCANFD_GRMCFG_RCMC); + } + /* Transition all Channels to reset mode */ for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) { rcar_canfd_clear_bit(gpriv->base, @@ -823,10 +819,23 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) dev_dbg(dev, "channel %u reset failed\n", ch); return err; } - }
- /* Set the controller into appropriate mode */ - rcar_canfd_set_mode(gpriv); + /* Set the controller into appropriate mode */ + if (gpriv->info->ch_interface_mode) { + /* Do not set CLOE and FDOE simultaneously */ + if (!gpriv->fdmode) { + rcar_canfd_clear_bit_reg(&gpriv->fcbase[ch].cfdcfg, + RCANFD_GEN4_FDCFG_FDOE); + rcar_canfd_set_bit_reg(&gpriv->fcbase[ch].cfdcfg, + RCANFD_GEN4_FDCFG_CLOE); + } else { + rcar_canfd_clear_bit_reg(&gpriv->fcbase[ch].cfdcfg, + RCANFD_GEN4_FDCFG_FDOE); + rcar_canfd_clear_bit_reg(&gpriv->fcbase[ch].cfdcfg, + RCANFD_GEN4_FDCFG_CLOE); + } + } + }
return 0; }
Hello Biju,
is this patch ready to go to linux-can?
regards, Marc
On 18.11.2025 12:39:25, Biju wrote:
From: Biju Das biju.das.jz@bp.renesas.com
The commit 5cff263606a1 ("can: rcar_canfd: Fix controller mode setting") has aligned with the flow mentioned in the hardware manual for all SoCs except R-Car Gen3 and RZ/G2L SoCs. On R-Car Gen4 and RZ/G3E SoCs, due to the wrong logic in the commit[1] sets the default mode to FD-Only mode instead of CAN-FD mode.
This patch sets the CAN-FD mode as the default for all SoCs by dropping the rcar_canfd_set_mode() as some SoC requires mode setting in global reset mode, and the rest of the SoCs in channel reset mode and update the rcar_canfd_reset_controller() to take care of these constraints. Moreover, the RZ/G3E and R-Car Gen4 SoCs support 3 modes compared to 2 modes on the R-Car Gen3. Use inverted logic in rcar_canfd_reset_controller() to simplify the code later to support FD-only mode.
[1] commit 45721c406dcf ("can: rcar_canfd: Add support for r8a779a0 SoC")
Fixes: 5cff263606a1 ("can: rcar_canfd: Fix controller mode setting") Cc: stable@vger.kernel.org Signed-off-by: Biju Das biju.das.jz@bp.renesas.com
drivers/net/can/rcar/rcar_canfd.c | 53 ++++++++++++++++++------------- 1 file changed, 31 insertions(+), 22 deletions(-)
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c index 49ab65274b51..05dbdf46dd6f 100644 --- a/drivers/net/can/rcar/rcar_canfd.c +++ b/drivers/net/can/rcar/rcar_canfd.c @@ -709,6 +709,11 @@ static void rcar_canfd_set_bit_reg(void __iomem *addr, u32 val) rcar_canfd_update(val, val, addr); }
+static void rcar_canfd_clear_bit_reg(void __iomem *addr, u32 val) +{
- rcar_canfd_update(val, 0, addr);
+}
static void rcar_canfd_update_bit_reg(void __iomem *addr, u32 mask, u32 val) { rcar_canfd_update(mask, val, addr); @@ -755,25 +760,6 @@ static void rcar_canfd_set_rnc(struct rcar_canfd_global *gpriv, unsigned int ch, rcar_canfd_set_bit(gpriv->base, RCANFD_GAFLCFG(w), rnc); }
-static void rcar_canfd_set_mode(struct rcar_canfd_global *gpriv) -{
- if (gpriv->info->ch_interface_mode) {
u32 ch, val = gpriv->fdmode ? RCANFD_GEN4_FDCFG_FDOE: RCANFD_GEN4_FDCFG_CLOE;for_each_set_bit(ch, &gpriv->channels_mask,gpriv->info->max_channels)rcar_canfd_set_bit_reg(&gpriv->fcbase[ch].cfdcfg, val);- } else {
if (gpriv->fdmode)rcar_canfd_set_bit(gpriv->base, RCANFD_GRMCFG,RCANFD_GRMCFG_RCMC);elsercar_canfd_clear_bit(gpriv->base, RCANFD_GRMCFG,RCANFD_GRMCFG_RCMC);- }
-}
static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) { struct device *dev = &gpriv->pdev->dev; @@ -806,6 +792,16 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) /* Reset Global error flags */ rcar_canfd_write(gpriv->base, RCANFD_GERFL, 0x0);
- /* Set the controller into appropriate mode */
- if (!gpriv->info->ch_interface_mode) {
if (gpriv->fdmode)rcar_canfd_set_bit(gpriv->base, RCANFD_GRMCFG,RCANFD_GRMCFG_RCMC);elsercar_canfd_clear_bit(gpriv->base, RCANFD_GRMCFG,RCANFD_GRMCFG_RCMC);- }
- /* Transition all Channels to reset mode */ for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) { rcar_canfd_clear_bit(gpriv->base,
@@ -823,10 +819,23 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) dev_dbg(dev, "channel %u reset failed\n", ch); return err; }
}
/* Set the controller into appropriate mode */
rcar_canfd_set_mode(gpriv);
/* Set the controller into appropriate mode */if (gpriv->info->ch_interface_mode) {/* Do not set CLOE and FDOE simultaneously */if (!gpriv->fdmode) {rcar_canfd_clear_bit_reg(&gpriv->fcbase[ch].cfdcfg,RCANFD_GEN4_FDCFG_FDOE);rcar_canfd_set_bit_reg(&gpriv->fcbase[ch].cfdcfg,RCANFD_GEN4_FDCFG_CLOE);} else {rcar_canfd_clear_bit_reg(&gpriv->fcbase[ch].cfdcfg,RCANFD_GEN4_FDCFG_FDOE);rcar_canfd_clear_bit_reg(&gpriv->fcbase[ch].cfdcfg,RCANFD_GEN4_FDCFG_CLOE);}}}
return 0;
}
2.43.0
-- Pengutronix e.K. | Marc Kleine-Budde | Embedded Linux | https://www.pengutronix.de | Vertretung Nürnberg | Phone: +49-5121-206917-129 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
Hi Marc,
-----Original Message----- From: Marc Kleine-Budde mkl@pengutronix.de Sent: 26 November 2025 10:28 Subject: Re: [PATCH] can: rcar_canfd: Fix CAN-FD mode as default
Hello Biju,
is this patch ready to go to linux-can?
Yes.
Cheers, Biju
regards, Marc
On 18.11.2025 12:39:25, Biju wrote:
From: Biju Das biju.das.jz@bp.renesas.com
The commit 5cff263606a1 ("can: rcar_canfd: Fix controller mode setting") has aligned with the flow mentioned in the hardware manual for all SoCs except R-Car Gen3 and RZ/G2L SoCs. On R-Car Gen4 and RZ/G3E SoCs, due to the wrong logic in the commit[1] sets the default mode to FD-Only mode instead of CAN-FD mode.
This patch sets the CAN-FD mode as the default for all SoCs by dropping the rcar_canfd_set_mode() as some SoC requires mode setting in global reset mode, and the rest of the SoCs in channel reset mode and update the rcar_canfd_reset_controller() to take care of these constraints. Moreover, the RZ/G3E and R-Car Gen4 SoCs support 3 modes compared to 2 modes on the R-Car Gen3. Use inverted logic in rcar_canfd_reset_controller() to simplify the code later to support FD-only mode.
[1] commit 45721c406dcf ("can: rcar_canfd: Add support for r8a779a0 SoC")
Fixes: 5cff263606a1 ("can: rcar_canfd: Fix controller mode setting") Cc: stable@vger.kernel.org Signed-off-by: Biju Das biju.das.jz@bp.renesas.com
drivers/net/can/rcar/rcar_canfd.c | 53 ++++++++++++++++++------------- 1 file changed, 31 insertions(+), 22 deletions(-)
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c index 49ab65274b51..05dbdf46dd6f 100644 --- a/drivers/net/can/rcar/rcar_canfd.c +++ b/drivers/net/can/rcar/rcar_canfd.c @@ -709,6 +709,11 @@ static void rcar_canfd_set_bit_reg(void __iomem *addr, u32 val) rcar_canfd_update(val, val, addr); }
+static void rcar_canfd_clear_bit_reg(void __iomem *addr, u32 val) {
- rcar_canfd_update(val, 0, addr);
+}
static void rcar_canfd_update_bit_reg(void __iomem *addr, u32 mask, u32 val) { rcar_canfd_update(mask, val, addr); @@ -755,25 +760,6 @@ static void rcar_canfd_set_rnc(struct rcar_canfd_global *gpriv, unsigned int
ch,
rcar_canfd_set_bit(gpriv->base, RCANFD_GAFLCFG(w), rnc); }
-static void rcar_canfd_set_mode(struct rcar_canfd_global *gpriv) -{
- if (gpriv->info->ch_interface_mode) {
u32 ch, val = gpriv->fdmode ? RCANFD_GEN4_FDCFG_FDOE: RCANFD_GEN4_FDCFG_CLOE;for_each_set_bit(ch, &gpriv->channels_mask,gpriv->info->max_channels)rcar_canfd_set_bit_reg(&gpriv->fcbase[ch].cfdcfg, val);- } else {
if (gpriv->fdmode)rcar_canfd_set_bit(gpriv->base, RCANFD_GRMCFG,RCANFD_GRMCFG_RCMC);elsercar_canfd_clear_bit(gpriv->base, RCANFD_GRMCFG,RCANFD_GRMCFG_RCMC);- }
-}
static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) { struct device *dev = &gpriv->pdev->dev; @@ -806,6 +792,16 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) /* Reset Global error flags */ rcar_canfd_write(gpriv->base, RCANFD_GERFL, 0x0);
- /* Set the controller into appropriate mode */
- if (!gpriv->info->ch_interface_mode) {
if (gpriv->fdmode)rcar_canfd_set_bit(gpriv->base, RCANFD_GRMCFG,RCANFD_GRMCFG_RCMC);elsercar_canfd_clear_bit(gpriv->base, RCANFD_GRMCFG,RCANFD_GRMCFG_RCMC);- }
- /* Transition all Channels to reset mode */ for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) { rcar_canfd_clear_bit(gpriv->base,
@@ -823,10 +819,23 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) dev_dbg(dev, "channel %u reset failed\n", ch); return err; }
}
/* Set the controller into appropriate mode */
rcar_canfd_set_mode(gpriv);
/* Set the controller into appropriate mode */if (gpriv->info->ch_interface_mode) {/* Do not set CLOE and FDOE simultaneously */if (!gpriv->fdmode) {rcar_canfd_clear_bit_reg(&gpriv->fcbase[ch].cfdcfg,RCANFD_GEN4_FDCFG_FDOE);rcar_canfd_set_bit_reg(&gpriv->fcbase[ch].cfdcfg,RCANFD_GEN4_FDCFG_CLOE);} else {rcar_canfd_clear_bit_reg(&gpriv->fcbase[ch].cfdcfg,RCANFD_GEN4_FDCFG_FDOE);rcar_canfd_clear_bit_reg(&gpriv->fcbase[ch].cfdcfg,RCANFD_GEN4_FDCFG_CLOE);}}}
return 0;
}
2.43.0
-- Pengutronix e.K. | Marc Kleine-Budde | Embedded Linux | https://www.pengutronix.de | Vertretung Nürnberg | Phone: +49-5121-206917-129 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-9 |
On 18.11.2025 12:39:25, Biju wrote:
From: Biju Das biju.das.jz@bp.renesas.com
The commit 5cff263606a1 ("can: rcar_canfd: Fix controller mode setting") has aligned with the flow mentioned in the hardware manual for all SoCs except R-Car Gen3 and RZ/G2L SoCs. On R-Car Gen4 and RZ/G3E SoCs, due to the wrong logic in the commit[1] sets the default mode to FD-Only mode instead of CAN-FD mode.
This patch sets the CAN-FD mode as the default for all SoCs by dropping the rcar_canfd_set_mode() as some SoC requires mode setting in global reset mode, and the rest of the SoCs in channel reset mode and update the rcar_canfd_reset_controller() to take care of these constraints. Moreover, the RZ/G3E and R-Car Gen4 SoCs support 3 modes compared to 2 modes on the R-Car Gen3. Use inverted logic in rcar_canfd_reset_controller() to simplify the code later to support FD-only mode.
Applied to linux-can
regards, Marc
linux-stable-mirror@lists.linaro.org