 
            From: Biju Das biju.das.jz@bp.renesas.com
The commit 5cff263606a1 ("can: rcar_canfd: Fix controller mode setting") applies to all SoCs except the RZ/G2L family of SoCs. As per RZ/G2L hardware manual "Figure 28.16 CAN Setting Procedure after the MCU is Reset" CAN mode needs to be set before channel reset. Add the mode_before_ch_rst variable to struct rcar_canfd_hw_info to handle this difference.
The above commit also breaks CANFD functionality on RZ/G3E. Adapt this change to RZ/G3E, as well as it works ok by following the initialisation sequence of RZ/G2L.
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 | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c index 49ab65274b51..1724fa5dace6 100644 --- a/drivers/net/can/rcar/rcar_canfd.c +++ b/drivers/net/can/rcar/rcar_canfd.c @@ -444,6 +444,7 @@ struct rcar_canfd_hw_info { unsigned ch_interface_mode:1; /* Has channel interface mode */ unsigned shared_can_regs:1; /* Has shared classical can registers */ unsigned external_clk:1; /* Has external clock */ + unsigned mode_before_ch_rst:1; /* Has set mode before channel reset */ };
/* Channel priv data */ @@ -615,6 +616,7 @@ static const struct rcar_canfd_hw_info rcar_gen3_hw_info = { .ch_interface_mode = 0, .shared_can_regs = 0, .external_clk = 1, + .mode_before_ch_rst = 0, };
static const struct rcar_canfd_hw_info rcar_gen4_hw_info = { @@ -632,6 +634,7 @@ static const struct rcar_canfd_hw_info rcar_gen4_hw_info = { .ch_interface_mode = 1, .shared_can_regs = 1, .external_clk = 1, + .mode_before_ch_rst = 0, };
static const struct rcar_canfd_hw_info rzg2l_hw_info = { @@ -649,6 +652,7 @@ static const struct rcar_canfd_hw_info rzg2l_hw_info = { .ch_interface_mode = 0, .shared_can_regs = 0, .external_clk = 1, + .mode_before_ch_rst = 1, };
static const struct rcar_canfd_hw_info r9a09g047_hw_info = { @@ -666,6 +670,7 @@ static const struct rcar_canfd_hw_info r9a09g047_hw_info = { .ch_interface_mode = 1, .shared_can_regs = 1, .external_clk = 0, + .mode_before_ch_rst = 1, };
/* Helper functions */ @@ -806,6 +811,10 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) /* Reset Global error flags */ rcar_canfd_write(gpriv->base, RCANFD_GERFL, 0x0);
+ /* RZ/G2L SoC needs setting the mode before channel reset */ + if (gpriv->info->mode_before_ch_rst) + rcar_canfd_set_mode(gpriv); + /* Transition all Channels to reset mode */ for_each_set_bit(ch, &gpriv->channels_mask, gpriv->info->max_channels) { rcar_canfd_clear_bit(gpriv->base, @@ -826,7 +835,8 @@ static int rcar_canfd_reset_controller(struct rcar_canfd_global *gpriv) }
/* Set the controller into appropriate mode */ - rcar_canfd_set_mode(gpriv); + if (!gpriv->info->mode_before_ch_rst) + rcar_canfd_set_mode(gpriv);
return 0; }
linux-stable-mirror@lists.linaro.org
